阅读视图

发现新文章,点击刷新页面。

vivaldi 同步失败

自从 opera 被 360 收了之后,期间用了一段时间的chrome。然而由于 google 的服务稳定性一直不怎么样,数据在不同设备间同步就成了一件痛苦的事情。知道后来发现opera 的原创团队又出了个 vivaldi 浏览器,顺其自然就切到了 vivaldi 上面。

后来,在某年某月的某一天,vivaldi 的同步服务变得和 google 一样了。直接同步是无法同步的,其实手机上的同步倒是没那么重要,关键是不同的电脑设备间的同步就变得异常痛苦。在一台电脑上注册了,记住密码,到另外一台电脑上还得重新输入账号密码登录。

在这种状态下再怎么重试也没任何的意义。其实对于这种屏蔽,个人感觉应该不会做的太彻底,毕竟就是一个数据同步服务而已。

首先找到同步服务的域名,打开 clashx,查看链接,最后发现了这么一个域名,感觉应该就是了:

当然,也可以用 tcpdump,wireshark 之类的抓包,不过命令行不直观,鲨鱼没装,就地取材就完了。至于为什么是这个域名不是其他的,问就是直觉,我觉得它是。

去 itdog 查询域名解析,别选国内的 dns,选了会返回一堆没用的:

去掉国内的服务器,此时就只剩下一个了:

修改本地 hosts 文件,或者去路由器添加 dns 解析,或者直接修改自己的 dns 服务器的解析等,以上的方法都 ok,添加下面的解析:

31.209.137.10 bifrost.vivaldi.com

此时,就不需要什么魔法就能愉快的同步数据了:

The post vivaldi 同步失败 appeared first on obaby@mars.

FreeFileSync 开源文件同步与备份利器

在数字化时代,文件管理和备份是每个用户都必须面对的重要任务。今天,向大家介绍一款开源的文件同步和备份软件 FreeFileSync。以其高效、免费和跨平台特点,成为众多用户在文件管理方面的首选工具。

写在前面

杜老师一直想自组个 NAS 主机,但苦于没有找到合适的系统,纠结于 Unraid 还是飞牛。Unraid 要收费,飞牛虽然免费,但很多功能的实现都是依托开源工具。就比如文件同步的功能,如需实现,还要借助第三方工具的。FreeFileSync 是非常好的选择,不仅开源免费,而且功能强大,可以帮助用户轻松完成各种文件同步任务:

什么是 FreeFileSync

FreeFileSync 是款功能强大的文件夹比较和同步软件,旨在帮助用户高效创建和管理重要文件的备份副本。与传统的备份工具不同,FreeFileSync 并不是简单地复制每一个文件,而是通过智能算法,确定源文件夹和目标文件夹之间差异,仅传输必要的数据。这种方法不仅节省了时间和带宽,还大大提高了同步效率:

开源与跨平台优势

FreeFileSync 是一款开源软件,这意味着它的代码是完全开放的,用户和开发者可以自由查看、修改、分发。开源优势在于,社区的力量可以不断优化和改进软件,使其更稳定和安全。此外,FreeFileSync 支持 Windows、macOS 和 Linux 三大主流的操作系统,无论桌面用户还是服务器管理员,都可以在自己的设备上无缝使用:

功能亮点

智能同步:FreeFileSync 的核心功能是其智能同步机制。它能够快速比较两个文件夹内容,识别出哪些文件被修改、删除、新增。用户可根据自己的需求选择同步模式,如单向同步或双向同步。这种灵活性使得 FreeFileSync 适用各种场景,从简单个人文件备份到复杂的多设备同步。

高效备份:对于备份任务,FreeFileSync 提供了多种选项。用户可以设置定时备份计划,确保重要文件定期自动备份。此外,软件支持增量备份,这意味着它只会备份自上次备份以来发生变化部分,从而节省存储空间。这种高效的备份方式对于那些需要频繁备份大量数据的用户来说非常实用。

易于使用:尽管 FreeFileSync 的功能强大,但它界面设计简洁直观,即使是新手用户也可以轻松上手。软件提供详细的教程和帮助文档,帮助用户快速掌握核心功能。此外,FreeFileSync 还支持拖放操作,用户可通过简单的拖放文件夹来设置同步任务,极大地提高了操作效率。

社区支持:作为开源软件,FreeFileSync 拥有一个活跃的社区。用户可以在社区论坛中寻求帮助、分享经验、参与开发。这种社区支持不仅为用户提供及时的技术支持,还为软件的持续改进提供了动力。许多用户反馈的功能和建议都被纳入后续版本的开发中。

适用场景

FreeFileSync 适用各种文件管理和备份场景。对于个人用户来说,它可用来备份重要文件,例如照片、文档、视频。对于企业用户,FreeFileSync 可帮助他们实现服务器之间的数据同步,确保数据的一致性和安全性。此外,FreeFileSync 还可以用于多设备之间的文件共享,例如在家庭网络中同步不同设备上的文件:

下载地址

杜老师为了方便小伙伴下载,已经打包好 14 版本的软件包。下面是 Windows、macOS 和 Linux 三大主流操作系统安装包:

下载地址

基于 rsync+inotifywait 实现文件的实时同步

之前有透露过,杜老师的去不图床使用三点备份,除本地备份外,还有内网存储备份,以及云上备份。而内网存储备份是通过 rsync 实现的,同步周期为每半个小时。近期打算配合 inotifywait 实现文件的实时同步!

工具介绍

rsync 是一个用于文件同步和备份的工具,inotifywait 是一种文件系统事件通知机制。

通过结合用 rsyncinotifywait,可实现文件的实时同步。

工具安装

安装 rsync 软件包:

1
sudo apt -y install rsync

安装 inotify-tools 软件包:

1
sudo apt -y install inotify-tools

服务配置

在源服务器上,创建一个 rsync 的配置文件,如/etc/rsyncd.conf,指定要同步的文件或目录及其它相关设置。

安装并配置 inotifywait,确保 inotifywait 模块已加载。使用 inotifywait 命令监视源目录事件。

编写同步脚本,使用 inotifywait 输出触发 rsync 命令,将更改的文件同步到目标服务器。

设置定时任务或者守护进程,使用 cron 或其它合适的工具定期执行同步脚本以实现实时同步。

示例脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
# 定义源目录和目标目录
SRC_DIR=/path/to/source
DEST_DIR=/path/to/destination
# rsync 的命令
RSYNC_CMD="rsync -avz --delete $SRC_DIR $DEST_DIR"
# inotifywait 的命令
INotify_CMD="inotifywait -mre modify,create,delete,move $SRC_DIR"
# 主题循环
while true; do
# 执行 inotifywait 并捕获输出
output="$(eval $INotify_CMD)"
# 如有事件发生
if [ -n "$output" ]; then
# 则执行 rsync 进行同步
echo "Syncing files..."
eval $RSYNC_CMD
fi
# 等待一段时间(例如 1 秒)
sleep 1
done

注意:这只是一个简要的概述,实际实现可能会因具体需求和环境而有所不同。在这个示例中,inotifywait 命令监视源目录修改、创建、删除、移动事件。当事件发生时,rsync 命令会执行,将源目录中的更改同步到目标目录中。

在网游中进行位置同步的那些事儿

计划赶不上变化,前天与Unity小伙伴发过邮件,今天就有机会来做专题分享了。思来想去想去也没想到什么好主题,那就将之前发的一些文章整理下做一个专题。
本期专题就叫《在网游中进行位置同步的那些事儿》希望对准备做多端同步的小伙伴以及正在做的小伙伴一点启发。
行文匆忙,定有不周。如有错漏指出还请您不吝指出,必当认真对待。话说到这,下面开始我们的正文吧。

基于条件进行位置同步

在网游的移动同步中,我们需要思考同步的频率,是固定周期好还是根据条件判定好? 如果只是开发一个demo这当然是固定频率去同步比较简单。
但是在正式的产品开发中,面对大用户的接入,就需要严格控制乃至减少现在数据包的 大小以及频率。
这时候就要结合周期同步以及条件同步进行优化,让客户端的发包量进一步的降低。

假设我们现在就在开发一款MMO,我们先列一下几种位置同步的【条件】:

1
2
角度是否变更
位置是否变更

在固定的周期内(如15hz)会检测两个条件是否超出一定的阈值,如果超过定量则在该周期内同步一次。
服务器则根据当前同步的角度预测计算帧当前角色可能的位置,通常的计算方式如下:

1
预测玩家当前位置 = 上个包的位置 + (服务器当前时间 - 上个包的时间) * 上个包的移速 * 上个包移动朝向

如果是这种做法,当前移动速度为6m/s :

1
2
3
4
客户端刷新周期250ms,延迟为200ms,服务器得到当位置的最大误差为: (0.25s + 0.2s) * 6m = 2.7m   每秒4个包
客户端刷新周期100ms,延迟为200ms,服务器得到当位置的最大误差为: (0.1s + 0.2s) * 6m = 1.8m 每秒10个包
客户端刷新周期50ms,延迟为200ms,服务器得到当位置的最大误差为: (0.05s + 0.2s) * 6m = 1.5m 每秒20个包
...

以此类推,稍微优化一下也用不了那么多包,如果【条件】没有变更的话是不需要持续在周期内同步。
也就变成了每帧判定【条件】是否变更,如果没有变更则无需同步。
否则走默认的周期检测,检测周期也就可以改为更长时间,如 1s 同步一次当前位置,这样相应的发包也会减少。

条件的改变频率

在此基础上可以知道延迟固定的最大误差为 0.2s * 6m = 1.2m ,那么现在基于此应该去尽量少的发送数据包,也尽量少降低误差。
如果【条件】改变的频繁会大幅增加发包的数量,甚至可能每帧都产生一个包,如玩家在原地绕圈的时候会更多。
就比如我,玩游戏就有闲着没事手原地搓摇杆的习惯,顺便一问你也有这种习惯吗?还有就是原地切个枪什么的。

此时增加【条件】的冗余可以减少当前发包的数量,如 增加 角度/距离 变更的判定范围。
实际上这样做的效果并不好,原因是【条件】太容易满足。

基于误差累计替换【条件】(航位推算法DR)

前面有说到服务器预测当前物体,在计算帧的坐标是基于 运动朝向 + 物体坐标

那么在我们的检测代码中可以做两次计算,在客户端先预测服务器使用的当前物体预测位置。

1
2
客户端代码:
服务器的预测点 = 上次同步给服务器的坐标 + 运动方向 * 同步结束后累计的时间(当前时间 - 上次发包时间)

然后计算当前物体实际距离与 预测服务器得到的当前物体位置 之间的距离大于一定的值,如同步的精度为0.2m那就是

1
需要需要同步 = Vector3.Distance(服务器的预测点,当前的实时位置) > 0.2m

如果当前位置与服务器预测的位置误差控制在一定的范围内则不需要同步,否则的话就立即同步一次。
这里需要注意一下,如果玩家从静止状态第一次进入运动状态是需要立即告知的,反之亦然。
没有立即同步的话,你的好兄弟与你联机时候只会看到你全屏漂移,然后问你一句,你飞够了吗?

上面的做法,好处是误差可以控制在一定的范围内并且尽量的少发送同步包;比如误差控制在0.2m范围,如果发送的包超量再适当的增加此范围。

弱网多人联机表现优化

这里讲一下我的思路,收到服务器同步包的时候,用包里的位置与现在的实时位置做一个向量的减法,这样就能得到一个误差值。
这个误差值,我们在后续的x帧内给他缓慢的补上,让画面减少抖动。
除此之外,还可以用一个同步的误差值进行容错,后续的x帧内并没有完全消除误差的情况下,等下一次的移动中继续补上他的误差。
当然如果这个误差值过大,则还需要立即将其拉到消除误差的点位。毕竟我们不能因为要画面而去牺牲手感。
可能你也遇到过在射击游戏中明明看到敌人了,却射不中,大概就是此类问题的表现了。

言归正传,下面用代码做个演示。玩家每次收到的Pack结构如下:
position是此刻当前物体处在位置,angle为运动方向,speed为0则物体进入idle。

1
2
3
4
5
6
public class PlayerStatePack
{
public float speed;
public Vector3 position;
public int angle_deg;
}

下面是模拟服务端延迟的实现,fluctuation用来模拟网络抖动:

currentTime = Time.time + Ping / 1000f * 2 + Random.Range(-fluctuation * 2/1000f , fluctuation * 2/1000f );

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Update()
{
for (int i = 0; i < packLst.Count; i++)
{
if (packLst[i].BeSend)
continue;

if (packLst[i].currentTime <= Time.time)
{
packLst[i].BeSend = true;
ReceivePack?.Invoke(packLst[i]);
}
}
}

客户端接收消息实现如下:通过ReceivePack函数订阅模拟服务器下发的Pack, 在该函数内做一个向量的减法,获取当前客户端所处与服务器同步过来的位置之间的误差,
有了此向量,那后面就可以通过插值逐渐修正到一个趋近正确的位置,一定程度上抹平网络波动引起的误差。
在 ApplyPoint 函数我做了一个当前误差的差值与角度差值,这样效果会好一些。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public void OnMove(float passTime,float step,Vector3 pos,float angle)
{
...
}


private void ReceivePack(PlayerStatePack item)
{
Debug.Log("其他玩家收到同步包");

modifyOffset = item.position - transform.position;
localPositon = transform.position;
localAnlge = transform.eulerAngles.y;
...
}

public float timeTakenDuringLerp = .2f;

private void Update()
{
....
var passTime = Time.time - currentPack.CurrentTime;

OnMove(passTime,step,pos,angle);

ApplyPoint(passTime);
}

private void ApplyPoint(float passTime)
{
float percentageComplete = passTime / timeTakenDuringLerp;

if(percentageComplete >= 1.0f)
{
transform.position = RuntimePos + modifyOffset;
return;
}

var offset = Vector3.Lerp(Vector3.zero, modifyOffset,percentageComplete);
transform.position = RuntimePos + offset;

if(percentageComplete*2 >= 1.0f)
{
return;
}
var yoffset = Mathf.LerpAngle(localAnlge, currentPack.angle_deg,percentageComplete*2);
transform.eulerAngles = new Vector3(transform.transform.eulerAngles.x,yoffset,transform.transform.eulerAngles.z);
}

最终效果如下:

移动同步过程中载具平台旋转问题

假设你已经做好的上述的全部工作,现在要追加一个新的功能,让玩家可以在移动的船上游戏,其他的玩家也在不同的船上。
关键是船是有自身旋转的,这时候你会发现前面我们做的功能出现了新的问题。由于船或者移动的平台,他会产生自身旋转。
也就带着玩家一起移动,玩家的坐标在不断的变更。这时候同步的位置也不断的出现变化。
对于这种状态该如何比较好的检出玩家的位移变化呢 ?

刚开始我们可能会认为这个检出的过程应该这样:
需要综合 上一次同步点 与 上一次同步的载具旋转角度与当前载具的旋转角度差值,然后三角函数计算出预测下一个落点。再将这个落点与当前要同步的点进行匹配。如果是一个点就不进行同步。

这个判定的计算非常繁琐,还需要额外记录载具的角度变化,那么有什么办法不看载具信息吗 ?

我们再分析下这个需求,载具平台旋转,子物体跟转,相对静止。
有句话是这样说的,当你不知道解题思路,你把题干抄下来,也是能得分的。
没错,答案就是 相对静止


由于是相对静止(船心坐标O),向量 OA蓝色 与 OA红色 他们的长度是没有变化的。
也就意味着,只需要计算上一次同步的相对位置与当前位置的长度差值。就可以判断玩家是否在载具平台上有位移。

1
bool isMove = Mathf.Abs( lastSyncRelPosition.magnitude - currentRelPosition.magnitude) > 0.01f

当然也可以优化成下面这样,不开方更省一些性能:

1
bool isMove = Mathf.Abs( lastSyncRelPosition.sqrMagnitude - currentRelPosition.sqrMagnitude) > 0.01f

结束语

本期的分享就到这里,朋友们欢迎评论区留言,我们下期再会。

❌