从技术的角度分析为什么 GTA5 的反外挂机制如此之差

KasuganoSoras 发表于 2018-12-21 03:54:21 | 查看:197 | 分享


这两天玩了一下 GTA5 线上模式,一开始挺好玩的,但是加入了一些人比较多的公开战局以后,就遇到了很多“侠盗科学家”,也就是咱们常说的神仙,开外挂作弊的人。

首先是什么刷车的,刷飞机的都有,随意召唤 X80 超跑,坦克,飞机,原地一键改满配的,这都是很常见的。接着是各种锁血的,自瞄爆头的,还带预判位置,无论你跑到哪都能一枪打死。最后是各种传送的,明明看到对方的飞机还离你两个山头远,下一秒就出现在你头顶了,并不是网络延迟,就算是延迟,也不可能一秒瞬移几公里吧。

打了几局下来,游戏体验极差,当然我也承认我自己作弊了,但是只是刷了一点钱,不至于像那些神仙那么变态。。所以我现在看到这些神仙都绕着走,要是被盯上了就开被动模式,但是还有的神仙连被动模式都能秒你,这种就只有退战局了。

话题说回来,为什么 GTA5 的反外挂机制这么烂,导致遍地外挂?目前我玩公开战局,十个战局有五六个都有挂。到底是 RockStar 放任外挂还是科学家们太强大?今天我们就从技术角度来分析 GTA5 的外挂。

一、网络架构

我们比较熟悉的传统网络游戏,例如英雄联盟、穿越火线、反恐精英等等,都是基于 C/S 架构的,即客户端(Clients)/ 服务器(Server)。

而 GTA5 的线上模式使用的架构是 P2P + C/S,什么是 P2P 呢?P2P 是一种去中心化的网络技术,你可以把传统的 C/S 架构理解为学校老师上课,老师就是 Server,它说什么你们就听什么,当你有什么事情需要举手报告给老师。而 P2P 大概就相当于学生自由讨论,你可以和其他同学交流你自己的东西,每个人都能成为“老师”。

大部分游戏的连接协议都是基于 TCP 协议,GTA5 游戏连接协议的底层是基于 UDP 协议。TCP 和 UDP 有什么区别呢?我们来举个例子,首先 TCP 协议有一个“三次握手”过程,假设你想要连接到服务器并发送信息,步骤是这样的:

  1. 客户端尝试向服务器发起连接,告知服务器“我是客户端 XXX”
  2. 服务器收到连接请求后,返回给客户端“我是服务端,我已经收到你的连接请求了”
  3. 客户端再告诉服务器“我是客户端,我已经收到服务端返回给我的信息,现在可以建立连接了”
  4. 客户端与服务器的连接就建立成功了,开始发送数据。

而 UDP 是一种无连接的协议,用 UDP 协议想要发送数据的话,步骤是这样的:

  1. 客户端直接把一大坨数据发给服务器“我是客户端 XXX,这些就是数据,不管你收没收到,我已经发了”
  2. 服务器收到数据后,再告诉客户端“我收到了,这句话不管你收没收到,我已经发了”

这里可以很明显地看出,TCP 是一种可靠的传输数据方式,而 UDP 相对于前者来说是相对不可靠的,TCP 会对数据进行校验,这样可以避免传输过程产生的数据丢失和损坏,而 UDP 因为是无连接的协议,数据完整性是无法保证的。

二、数据传输

看完上面的介绍,你可能会问,为什么 GTA5 不用 TCP 协议传输数据呢?这样不就可以保证数据完整了吗?

没错,TCP 协议是可以保证数据完整,但是带来的负面影响是非常大的,如果使用 TCP 协议,那么就会:

  1. 游戏会很容易掉线,各种卡,开车会一卡一顿,走路也是,开枪会很难打中敌人。
  2. 服务器会承受不了大量的连接而崩溃

而如果使用的是 UDP 协议,卡顿的问题就会好很多了,首先,因为无需建立连接,只需要发送数据,客户端只要把数据发出去就行了,不用管收不收得到,这样的话你在本地玩起来就会感觉很流畅,但是别人看你可能会各种瞬移(在网络不好的情况下),如果使用 TCP,遇到网络不好的情况,你和所有人都会觉得很卡,还可能频繁掉线。

第二,GTA5 使用的 P2P 技术,P2P 是一种“点对点”的数据传输技术,因为 P2P 无需服务器,而是由各个客户端来互相传输数据,即每个人都可以成为“服务器”来为其他客户端提供数据,大大节省了中央服务器的性能开销,这样有什么好处呢?就是客户端不会再因为和服务器的延迟过高而感觉卡顿,因为提供数据的并不是服务器,而是和你在一个战局的其他玩家。

如果你和朋友一起在线上玩过飙车,你可能会见到这种情况:

  1. 你和你的朋友一起在玩漂移,过一个弯的时候你发现对方的车用一种很不自然的姿态漂过去了
  2. 你和你的朋友一起开车在山路行驶,过一个弯的时候你发现对方的车突然撞出路面了,过一会你发现他人不见了,而是出现在了另一个位置,车子一点事都没有,好好地在开着。

先来解释第一种情况,当你的朋友开着车在漂移的时候,因为是 P2P 网络,此时是由他的电脑在“告诉”你的电脑,他当前的车辆速度、轮子的角度,以及车子的其他信息,你的电脑收到了以后,在本地模拟进行计算,最终演算出了这个效果,在他电脑上看来他可能做了一个很漂亮的甩尾,而你这边看到就像整辆车横着飞了过去一样。

然后是第二种情况,这种情况通常是网络卡顿,有可能是你的网络卡了,或者他的网络卡了,在游戏的过程中,对方是不断在向你的电脑发送数据的,然后你的电脑再在本地进行计算,而如果发着发着突然网络嗝屁了,你的电脑没有收到对方打了转向的消息,你的电脑就会“认为”对方的车以之前的速度直线撞出去了,但是过了一会,对方的数据包又传过来了,你的电脑就会重新进行计算,然后你就会看到对方的车子又重新出现在了道路上。

三、数据安全

由于没有中央服务器的介入,所有数据都由客户端之间互相发送,这就存在了一定(或者说很大)的安全隐患。

举个例子,你和一个敌对玩家在对枪,你对着他开了一枪,此时你的电脑会发送数据告诉对方的电脑“我朝你开了一枪,方向是 XXX,角度是 XXX”,正常来说,对方的电脑在收到你的数据后,会在本地进行计算,你是不是打中了我,如果打中了,我再返回数据给你。

而如果他开了外挂,外挂通过修改数据包,一直就返回给你“你没打中,你没打中,略略略”这就变成了无敌外挂,你怎么也打不死对方。

还有就是帖子开头提到的刷载具,外挂通过改数据,在本地先刷一辆车出来,接着再“告诉”其他客户端,我这里出现了一辆车,其他客户端收到以后,就会把这辆车显示出来,这样所有人都看得到这辆车了。

刷钱也是一个原理,通常情况你不可能直接修改你的金钱数量(要是能改那岂不是逆天了),因为数据掌握在中央服务器上,你想要获得钱,必须要通过正常的手段或者事件,例如杀了一个 NCP 掉了钱,捡起来就可以获得,或者做任务得到钱。

刷钱的原理,就是在你面前创建一大堆钱袋(GTA5 里面有这么个东西叫钱袋,是一种物品,走过去就可以捡起来,然后就能获得钱)因为创建实体是不会把数据提交给中央服务器的,因此外挂可以在本地创建一堆钱袋,然后走过去捡起来,这时候客户端就可以告诉中央服务器“我捡到了好多钱袋,我现在有 XXXXX 的钱了”。

读到这里可能有人会问,既然需要上报给中央服务器,那中央服务器做个判断不就行了?

没错,是可以通过这样来判断玩家获得的钱是否合法,但是因为 GTA5 的玩家数量实在是太多了,如果每次获得钱后都要进行一次验证,那服务器会炸的,设想一下,你在做一个任务,一阵激烈的枪战后,地上倒了一堆 NPC,你走过去捡他们掉的钱,结果你捡一下就要上报给中央服务器一次数据,那岂不是一卡一卡的?

所以,R 星并没有这么做,其实大部分时候,你的金钱数据都是在你本地储存的,同时通过 P2P 网络与其他玩家同步,本地存一份,中央服务器上存一份,然后定期同步,大概就是这样的。

一个很明显的地方,你在改车、买枪的时候,留意右下角,你会看到一个转圈圈的图标,旁边写着“交易处理中”,这时候其实客户端就在和中央服务器通讯,进行物品购买的操作,此时服务器就会判断你的钱够不够,但是不会判断你的钱来源合不合法,因为无法追溯你获得钱的来源,这就导致了可以刷钱。

四、网络卡顿的原因

在玩 GTAOL 的时候,你可能会发现,和有些玩家玩的时候就很流畅,和另一些玩家玩的时候就看到他们各种瞬移,各种车子撞树撞电线杆,其实这都是和 P2P 有关。

前面已经说了,P2P 是将每个客户端都变成了一台服务器,既能接收数据也能发送数据 能攻能受(雾),如果你和某个玩家比较近(物理上的),你和他的延迟低,那么你们两个一起玩的时候就会很流畅。而如果你和某个玩家距离几千上万公里,不同国家的,那么你们之间的延迟就会很大,玩起来的时候就会感觉很卡。

因此 GTA5 有一个匹配机制,即自动将你附近的玩家(或者和你同一个国家的玩家)匹配到同一个战局。例如我之前挂了一个日本的 SSR 作为加速器来连接游戏,我匹配到的就全是日本玩家。

那么如何避免或者降低卡顿呢?首先你需要确定你和某个玩家之间延迟大不大,例如和他一起飚车,如果他不停瞬移或者各种奇 ♂ 怪的姿势瞎漂、撞车,那么就说明延迟应该不小。

确定了延迟以后,你就应该尽量和这个玩家保持距离,最好是在视野范围之外,这样你的电脑就不会加载来自对方电脑的数据,这也是 B 站玩漂移的大佬 老基 说的,打轮毂的时候尽量找没人的地方打,不然容易把车胎打爆。原因就是游戏数据在由其他玩家发送给你,这中间可能就存在延迟或者其他问题,本来你打的是轮毂,可能就因为网络问题打到轮胎了。

五、心跳机制

前面说了,GTA5 的联机是基于 UDP 协议的,既然 UDP 是一种无状态的协议,为什么偶尔还是能看到游戏提示“连接超时”?答案就是心跳机制。为了确认客户端在线,每个客户端之间都会互相发送一个心跳数据包(heartbeat),时间可以是 5 秒一次,或者 10 秒一次都可以,如果超过指定时间还没收到某个客户端的心跳数据包,那么就认为这个客户端“死了”(连接超时)。

各位可以按下 F12,转到 Console,你会看到很多的“WebSocket heartbeat received”,这个论坛的评论区是使用 WebSocket 实现评论内容实时更新的,虽然是基于 TCP,但是为了保证客户端在线,还是使用了心跳数据包的机制,每间隔 5 秒发送一个心跳数据包。

TCP 协议虽然是一种有状态的连接,但是并不是代表客户端与服务器的连接中断后,服务器就能“知道”的。
如果你是通过正常方式断开连接,例如关闭程序、手动中断连接,那么服务器是可以“知道”这一事件的,而如果你通过拔网线、禁用网卡的方式强行断开连接,服务器是无法“知道”的,并且会继续尝试给你发送数据,然后发送失败,再判定你的客户端已经离线。

六、题外话

其实完全使用服务器同步数据的游戏也有,例如坦克世界,在坦克世界这个游戏中,你的任何操作都需要与服务器同步,例如车子前进后退,左转右转,开炮等。在 GTA5 里,你开一炮以后,是由你的电脑告诉其他玩家的电脑,我打了哪里,方向,角度等。而坦克世界里,你开了一炮以后,是由服务器来计算,你的炮弹打到了哪里,打中了没有。

因此坦克世界是我目前见过外挂最少的游戏,虽然也有,不过都是一些纯本地自慰用的挂,比如什么去草丛,无限视野缩放之类的。去草丛其实没啥用,只是让你看的清楚一点,服务器告诉你看不见你就看不见,坦克世界玩家常说的“点亮了”就是指服务器告诉你,你“看见”了对方的坦克。而如果服务器就是不告诉你敌人在哪,你就算把山都变成透明的,你也看不到敌方的坦克。

很早以前见过一个比较牛逼的外挂,可以垂直开上山,卡进别人车里,那个是利用了游戏的 bug,现在早就已经修复了。

感谢阅读此文章,本文章由 Akkariin 原创,转载请注明此贴地址。

KasuganoSoras 在 2018-12-21 04:07:40 编辑了帖子


img


帖子评分

评分是对作者的一种鼓励,您可以在评论框输入 /cs score 分数 附言 对帖子进行评分。

最少 1 分,最大 5 分,评分会消耗自己的积分,不能给自己的帖子评分。

暂时没有人评分!


发表你的评论

回帖时请注意遵守论坛发言规定,请勿恶意灌水。

  回帖倒序排列   匿名回复 您还可以输入 2000  


欢迎来到 ZeroDream 论坛!

您还没有登录噢 :P

登陆以后就可以发帖和回复啦~


系统主题选项

在线人数:Loading...