周末一起联机玩一把文明6是多么快乐的事呀,但是坑爹的网络无情地摧毁了一切
同步回合慢就算了,时不时掉线真的是完全不能忍了
想来想去,咱这网络条件,肯定问题不在这里呀
花钱买了加速器还这么卡,问题八成也不在网络链路上呀
破案了,问题就是官方服务器垃圾垃圾垃圾~~
我们,必须要抗争,同这不合理的网络斗争
首先,咱肯定是要想办法摆脱官方服务器,因为只要网络要走官服,就肯定要卡
搜来搜去,只找到了国内某游戏平台,可惜的是,下载的时候浏览器报毒了
没办法,强烈洁癖忍不了,方案作废
没有路,那就开一条路出来
我们得先想想,我们联机时为什么要走官方服务器
显然是因为需要一个媒介来帮助两个异地小伙伴进行愉快的网络通信
因为 NAT 的流行,导致两个不同局域网的用户很难进行 p2p 通信
即使有着花样繁多的 p2p 方案,也没谁能保证稳定高可用
所以官方选择搭建一个服务器来帮助联机也是可以理解的
但是 !!!
我们还可以选择局域网联机,流量直达,稳定可靠
那么有什么能让异地小伙伴快乐的异地组网呢?
当然是 V ~ P ~ N ~
这里感谢 jintao 在使用 wireguard 搭 vpn 时的巨大贡献 :D
如果问题到此迎刃而解,那本文也未免太水了
接着我们就会遇到游戏联机史上最常见的问题:搜不到房间
其实这个问题以前上学时玩饥荒联机就遇到过,只要关掉多余的网卡就行
但是 wireguard,或者说几乎所有 vpn 软件组网时,都是使用了虚拟网卡
而这个虚拟网卡又干扰了游戏间正常的互相寻找流程
「关掉网卡,我连不上你;开启网卡,我找不到你」
当然我第一反应是把 wireguard 整到路由器上,这样就避免了本地网卡干扰了
但可惜的是,这个方案过于麻烦,并不是特别满意
所以我们就思考呀,为啥找不到房间呢?
找不到房间其实就是两端的进程无法发现对方,也就是「服务发现」失败
任何局域网联机都依赖于自己的服务发现,而且一般不会是 consul 这样复杂的方案
一般软件都会通过广播包来实现自己的简化版服务发现
那么八成就是这个广播包在虚拟网卡的干扰下,没有正确投递到对方机器咯
就没啥好说的,打开 Wireshark 抓个包,得到文明6发的一系列 udp 服务发现包
然后看地址是发到 255.255.255.255 的,查看路由表就一目了然了
默认的 255.255.255.255 地址是路由到了我的物理网卡上
所以对端的小伙伴时无法收到这个包的
接下来有两个办法
- 「路线纠正」修改路由表,让这个地址的广播包走到 wireguard 虚拟网卡上
- 「明确目标」抓包重发,把 udp 包内容修改目的地址后,直接发到小伙伴机器上
感觉方案1有点不太好,因为改路由表还是不靠谱,容易触发未知 bug
这里选择了方案2,简单写了个抓包重发工具
果然成功了~~~
知识改变游戏 ^-^
后记
其实感觉是可以把两地的网络配成真正互通的,这样才是最完美的方案
但是一直没想到比较好的办法,要是有网络大佬指教一下就好了 QAQ
为啥抓包重发后就能成功呢,因为最开始的服务发现包是 udp,是无连接的
也就是说我们可以手动构造发包来源和目的地址
那么,我们把来源端口设置为文明6进程使用的端口,目的地址修改为小伙伴机器的 ip
这个 udp 包自然能被顺利投递过去
而服务发现最重要的就是互相发现,当我们架上了这样一座桥后
对端就知道了这里有个进程在寻找房间,对面就会主动发房间信息过来
然后的然后,一切都刚刚好
1 | # Wirgurad Server Config |
1 | // 抓包重发小工具 |