一、网络架构
我们比较熟悉的传统网络游戏,例如英雄联盟、穿越火线、反恐精英等等,都是基于 C/S 架构的,即客户端(Clients)/ 服务器(Server)。
而 GTA5 的线上模式使用的架构是 P2P + C/S,什么是 P2P 呢?P2P 是一种去中心化的网络技术,你可以把传统的 C/S 架构理解为学校老师上课,老师就是 Server,它说什么你们就听什么,当你有什么事情需要举手报告给老师。而 P2P 大概就相当于学生自由讨论,你可以和其他同学交流你自己的东西,每个人都能成为“老师”。
大部分游戏的连接协议都是基于 TCP 协议,GTA5 游戏连接协议的底层是基于 UDP 协议。TCP 和 UDP 有什么区别呢?我们来举个例子,首先 TCP 协议有一个“三次握手”过程,假设你想要连接到服务器并发送信息,步骤是这样的:
- 客户端尝试向服务器发起连接,告知服务器“我是客户端 XXX”
- 服务器收到连接请求后,返回给客户端“我是服务端,我已经收到你的连接请求了”
- 客户端再告诉服务器“我是客户端,我已经收到服务端返回给我的信息,现在可以建立连接了”
- 客户端与服务器的连接就建立成功了,开始发送数据。
而 UDP 是一种无连接的协议,用 UDP 协议想要发送数据的话,步骤是这样的:
- 客户端直接把一大坨数据发给服务器“我是客户端 XXX,这些就是数据,不管你收没收到,我已经发了”
- 服务器收到数据后,再告诉客户端“我收到了,这句话不管你收没收到,我已经发了”
这里可以很明显地看出,TCP 是一种可靠的传输数据方式,而 UDP 相对于前者来说是相对不可靠的,TCP 会对数据进行校验,这样可以避免传输过程产生的数据丢失和损坏,而 UDP 因为是无连接的协议,数据完整性是无法保证的。
二、数据传输
看完上面的介绍,你可能会问,为什么 GTA5 不用 TCP 协议传输数据呢?这样不就可以保证数据完整了吗?
没错,TCP 协议是可以保证数据完整,但是带来的负面影响是非常大的,如果使用 TCP 协议,那么就会:
- 游戏会很容易掉线,各种卡,开车会一卡一顿,走路也是,开枪会很难打中敌人。
- 服务器会承受不了大量的连接而崩溃
而如果使用的是 UDP 协议,卡顿的问题就会好很多了,首先,因为无需建立连接,只需要发送数据,客户端只要把数据发出去就行了,不用管收不收得到,这样的话你在本地玩起来就会感觉很流畅,但是别人看你可能会各种瞬移(在网络不好的情况下),如果使用 TCP,遇到网络不好的情况,你和所有人都会觉得很卡,还可能频繁掉线。
第二,GTA5 使用的 P2P 技术,P2P 是一种“点对点”的数据传输技术,因为 P2P 无需服务器,而是由各个客户端来互相传输数据,即每个人都可以成为“服务器”来为其他客户端提供数据,大大节省了中央服务器的性能开销,这样有什么好处呢?就是客户端不会再因为和服务器的延迟过高而感觉卡顿,因为提供数据的并不是服务器,而是和你在一个战局的其他玩家。
如果你和朋友一起在线上玩过飙车,你可能会见到这种情况:
- 你和你的朋友一起在玩漂移,过一个弯的时候你发现对方的车用一种很不自然的姿态漂过去了
- 你和你的朋友一起开车在山路行驶,过一个弯的时候你发现对方的车突然撞出路面了,过一会你发现他人不见了,而是出现在了另一个位置,车子一点事都没有,好好地在开着。
先来解释第一种情况,当你的朋友开着车在漂移的时候,因为是 P2P 网络,此时是由他的电脑在“告诉”你的电脑,他当前的车辆速度、轮子的角度,以及车子的其他信息,你的电脑收到了以后,在本地模拟进行计算,最终演算出了这个效果,在他电脑上看来他可能做了一个很漂亮的甩尾,而你这边看到就像整辆车横着飞了过去一样。
然后是第二种情况,这种情况通常是网络卡顿,有可能是你的网络卡了,或者他的网络卡了,在游戏的过程中,对方是不断在向你的电脑发送数据的,然后你的电脑再在本地进行计算,而如果发着发着突然网络嗝屁了,你的电脑没有收到对方打了转向的消息,你的电脑就会“认为”对方的车以之前的速度直线撞出去了,但是过了一会,对方的数据包又传过来了,你的电脑就会重新进行计算,然后你就会看到对方的车子又重新出现在了道路上。
三、数据安全
由于没有中央服务器的介入,所有数据都由客户端之间互相发送,这就存在了一定(或者说很大)的安全隐患。
举个例子,你和一个敌对玩家在对枪,你对着他开了一枪,此时你的电脑会发送数据告诉对方的电脑“我朝你开了一枪,方向是 XXX,角度是 XXX”,正常来说,对方的电脑在收到你的数据后,会在本地进行计算,你是不是打中了我,如果打中了,我再返回数据给你。
而如果他开了外挂,外挂通过修改数据包,一直就返回给你“你没打中,你没打中,略略略”这就变成了无敌外挂,你怎么也打不死对方。
还有就是帖子开头提到的刷载具,外挂通过改数据,在本地先刷一辆车出来,接着再“告诉”其他客户端,我这里出现了一辆车,其他客户端收到以后,就会把这辆车显示出来,这样所有人都看得到这辆车了。
刷钱也是一个原理,通常情况你不可能直接修改你的金钱数量(要是能改那岂不是逆天了),因为数据掌握在中央服务器上,你想要获得钱,必须要通过正常的手段或者事件,例如杀了一个 NCP 掉了钱,捡起来就可以获得,或者做任务得到钱。
刷钱的原理,就是在你面前创建一大堆钱袋(GTA5 里面有这么个东西叫钱袋,是一种物品,走过去就可以捡起来,然后就能获得钱)因为创建实体是不会把数据提交给中央服务器的,因此外挂可以在本地创建一堆钱袋,然后走过去捡起来,这时候客户端就可以告诉中央服务器“我捡到了好多钱袋,我现在有 XXXXX 的钱了”。
读到这里可能有人会问,既然需要上报给中央服务器,那中央服务器做个判断不就行了?
没错,是可以通过这样来判断玩家获得的钱是否合法,但是因为 GTA5 的玩家数量实在是太多了,如果每次获得钱后都要进行一次验证,那服务器会炸的,设想一下,你在做一个任务,一阵激烈的枪战后,地上倒了一堆 NPC,你走过去捡他们掉的钱,结果你捡一下就要上报给中央服务器一次数据,那岂不是一卡一卡的?
所以,R 星并没有这么做,其实大部分时候,你的金钱数据都是在你本地储存的,同时通过 P2P 网络与其他玩家同步,本地存一份,中央服务器上存一份,然后定期同步,大概就是这样的。
一个很明显的地方,你在改车、买枪的时候,留意右下角,你会看到一个转圈圈的图标,旁边写着“交易处理中”,这时候其实客户端就在和中央服务器通讯,进行物品购买的操作,此时服务器就会判断你的钱够不够,但是不会判断你的钱来源合不合法,因为无法追溯你获得钱的来源,这就导致了可以刷钱。
四、网络卡顿的原因
在玩 GTAOL 的时候,你可能会发现,和有些玩家玩的时候就很流畅,和另一些玩家玩的时候就看到他们各种瞬移,各种车子撞树撞电线杆,其实这都是和 P2P 有关。
前面已经说了,P2P 是将每个客户端都变成了一台服务器,既能接收数据也能发送数据,如果你和某个玩家比较近(物理上的),你和他的延迟低,那么你们两个一起玩的时候就会很流畅。而如果你和某个玩家距离几千上万公里,不同国家的,那么你们之间的延迟就会很大,玩起来的时候就会感觉很卡。
因此 GTA5 有一个匹配机制,即自动将你附近的玩家(或者和你同一个国家的玩家)匹配到同一个战局。例如我之前挂了一个日本的 SSR 作为加速器来连接游戏,我匹配到的就全是日本玩家。
那么如何避免或者降低卡顿呢?首先你需要确定你和某个玩家之间延迟大不大,例如和他一起飚车,如果他不停瞬移或者各种奇 ♂ 怪的姿势瞎漂、撞车,那么就说明延迟应该不小。
确定了延迟以后,你就应该尽量和这个玩家保持距离,最好是在视野范围之外,这样你的电脑就不会加载来自对方电脑的数据,这也是 B 站玩漂移的大佬 老基 说的,打轮毂的时候尽量找没人的地方打,不然容易把车胎打爆。原因就是游戏数据在由其他玩家发送给你,这中间可能就存在延迟或者其他问题,本来你打的是轮毂,可能就因为网络问题打到轮胎了。
五、心跳机制
前面说了,GTA5 的联机是基于 UDP 协议的,既然 UDP 是一种无状态的协议,为什么偶尔还是能看到游戏提示“连接超时”?答案就是心跳机制。为了确认客户端在线,每个客户端之间都会互相发送一个心跳数据包(heartbeat),时间可以是 5 秒一次,或者 10 秒一次都可以,如果超过指定时间还没收到某个客户端的心跳数据包,那么就认为这个客户端“死了”(连接超时)。
TCP 协议虽然是一种有状态的连接,但是并不是代表客户端与服务器的连接中断后,服务器就能“知道”的。
如果你是通过正常方式断开连接,例如关闭程序、手动中断连接,那么服务器是可以“知道”这一事件的,而如果你通过拔网线、禁用网卡的方式强行断开连接,服务器是无法“知道”的,并且会继续尝试给你发送数据,然后发送失败,再判定你的客户端已经离线。
六、题外话
其实完全使用服务器同步数据的游戏也有,例如坦克世界,在坦克世界这个游戏中,你的任何操作都需要与服务器同步,例如车子前进后退,左转右转,开炮等。在 GTA5 里,你开一炮以后,是由你的电脑告诉其他玩家的电脑,我打了哪里,方向,角度等。而坦克世界里,你开了一炮以后,是由服务器来计算,你的炮弹打到了哪里,打中了没有。
因此坦克世界是我目前见过外挂最少的游戏,虽然也有,不过都是一些纯本地自慰用的挂,比如什么去草丛,无限视野缩放之类的。去草丛其实没啥用,只是让你看的清楚一点,服务器告诉你看不见你就看不见,坦克世界玩家常说的“点亮了”就是指服务器告诉你,你“看见”了对方的坦克。而如果服务器就是不告诉你敌人在哪,你就算把山都变成透明的,你也看不到敌方的坦克。
很早以前见过一个比较牛逼的外挂,可以垂直开上山,卡进别人车里,那个是利用了游戏的 bug,现在早就已经修复了。
请登录后查看评论内容