帧同步(LockStep)该如何反外挂
本文首发于知乎专栏:MACK的游戏开发笔记,欢迎各位关注。
在中国的游戏环境下,反挂已经成为了游戏开发的重中之重,甚至能决定一款游戏的生死,吃鸡就是一个典型的案例。
目前参与了了一款动作射击的MOBA类游戏的开发,同步方案上选择了帧同步技术(LockStep而非snapshots以下同)。那么就有很多人担心起来,客户端会跑全部逻辑帧同步该如何反外挂,和状态同步有什么区别呢?
首先我们来分析一下手游的风险和外挂的分类,这里推荐腾讯游戏安全中心的文章,有着非常详细深入的介绍。
手游的风险:
• 静态修改文件:将游戏解包修改资源 ,配置,代码等之后再重新打包
○ 修改资源,例如替换游戏的贴图做广告,修改玩家碰撞资源 或删除部分关键资源使玩家可以作弊等
○ 修改代码,直接修改游戏代码,实现无敌,免CD,无限伤害等等
○ 修改配置,修改策划配表等
• 动态篡改逻辑:通过注入和钩子的方式,在游戏运行时修改游戏代码,修改游戏内存等
○ 修改代码,运行时注入进程直接修改游戏代码或者钩住关键逻辑函数修改逻辑,实现无敌,免CD,无限伤害等等
○ 修改内存,例如烧饼,葫芦侠等修改器,在游戏运行时修改堆栈和全局变量等
• 游戏协议
○ 篡改游戏协议,直接修改协议的内容,修改结算结果,修改伤害数值,修改血量等等
○ 重复游戏协议,例如多次重复伤害协议
• 其他,按键精灵。脚本宏,盗号,恶意发言,打金工作室等,这些和同步技术无关,暂不做详细讨论
外挂的分类 :
摘自腾讯游戏安全实验室
从上文可以看出外挂的主要方式还是修改客户端的资源,代码,和内存。因此反外挂的手段也不外乎以下几种:
• 服务器计算关键逻辑。例如一些MMO战斗逻辑泡在服务端
• 服务器验证客户端逻辑。包括通过完整战斗逻辑验证和数值范围验证,例如早期的酷跑(可能误杀牛逼的玩家)
• 包体加密加签名加验证,防止破解包体。例如一些第三方加固,Unity的MonoDll加密,代码混淆等
• 加密本地保存的一些文件。例如对加密PlayerPrefs文件
• 加密和扰动运行时内存中关键数据(例如血量数据等)。例如崩3等
• 防注入检测(杀死注入进程或者发现注入之后杀死自己)
• 虚拟机加密
• 加速检测,防止修改本地时间的变速齿轮
• 穿墙检测,客户端对关键碰撞做校验
• 集成守护进程以及守护进程的自我加密更新
• 鼠标宏,按键精灵等进程检测,防止玩家使用这些工具
• 增加举报系统查证封号
• 通过暴力机关严厉打击外挂制作者(个人感觉非常有效)
• 其他
但很遗憾,因为理论上再牛逼的客户端也是可以破解的,所以客户端的东西都是不可信任的。就像市面上也有很多第三方的加固工具,反作弊插件等,但不管用什么eye,什么火眼精睛,该作弊的还是作弊。因此反外挂的核心还是在于是否服务器是否计算了关键逻辑,就像Unreal老大说的The Server Is The Man。而和同步技术和客户端是否跑完整逻辑关系不大(严格说是有一点关系)。不管是状态同步还是帧同步,只要做到了服务器有完整逻辑并验证,绝大部分外挂都可以防掉(例如锁血挂,穿墙挂,加速挂等)。
对于状态同步来说关键逻辑在服务器的比重越高反外挂就越完美。最极端的例子就是就是云游戏,服务器计算所有逻辑和画面,客户端只是显示图像,基本上杜绝了所有其他外挂(除了按键精灵,鼠标宏,手速挂等可以模拟玩家操作,捕捉像素计算操作,只能通过进程检测,举报,法律打击等其他方案)。
而对于帧同步来说,我们同样可以在服务器验证完整的战斗逻辑。一般分为两种:
1. 实时验证。例如战斗实时运行战斗逻辑和客户端不断同步验证关键数据的hash,和状态同步类似。但这种方案服务器负载较高,运维成本高昂;
2. 离线验证。这是帧同步的优势,战斗结束后服务器收集整场的操作序列,然后加速播放战斗(几十上百倍),最后校验结果,例如刀塔传奇。这个好处是服务器不用实时跑战斗,只需在结束时花几百ms即可验证一场战斗,大幅降低服务器成本。
如果是这种验证方式帧同步也一样能防掉绝大部分外挂,但是会多一个弱点就是全图挂。因为客户端有了所有玩家的位置信息,所以无法防掉全图挂。
那么如果这么说,只要服务器跑逻辑就行了,为什么外挂还这么泛滥呢?其实因为种种原因很多游戏服务器并没有完整的逻辑和校验,对于绝大部分游戏使用状态同步来说有以下一些原因:
1. 性能问题。服务器运行完整逻辑开销很高(特别是一些复杂运算,例如物理弹道等),因此将部分逻辑放在客户端分布运算
2. 因为开发效率和开发能力的限制。例如开发技能,如果所有逻辑都在客户端开发就会简单很多,响应也非常及时。如果要涉及服务器和客户端同步,就会多很多工作量特别是一些位移技能,很多逻辑可能还要写两份(帧同步更高效更容易实现打击感也是这个原因,很多动作游戏,MOBA游戏也会选择帧同步)
3. 经验问题。一些公司在反外挂上经验不足重视程度不够,特别是国外游戏环境较好法律健全
4. 为了极致的体验。例如为了降低网络延迟,很多游戏会让客户端预表现和加入延迟补偿,在一定范围内信任客户端(特别是FPS游戏,状态同步在延迟感上有较优势)
5. 为了弱网体验。为了让玩家在网络极差甚至断线的情况下也能玩,将绝大部分逻辑都放在客户端
6. 多种原因混合,其他一些个别问题。
但是以上的问题对于帧同步来说不也一样吗?如果为了成本和快速开发,服务器不跑逻辑不也一样抓瞎吗?其实帧同步会更简单一些。对帧同步来说有以下几种情况:
1.基于RelayServer多人PVP。这种会相对简单很多,因为每个客户端都计算了完整逻辑,作弊玩家修改的只是本地数据无法影响其他玩家,只能自嗨。最终结果服务器只要简单的比较投票就可以找到作弊者,除非作弊的玩家多余非作弊的玩家并且作弊玩家还要修改一样的数据(有点比特币算力的意思:),另外也可以在游戏运行时不断生成关键数据的hash码,随时校验;
2.基于P2P的多人PVP。和RS差不多但是无法防主机作弊了,参考魔兽争霸,但网游基本不会使用;
3.双人PVP和单机。这就没办法了,只能服务器做校验;
综上所述,因为天然的客户端强一致性,总体来说帧同步在防外挂上甚至会更简单一些(参考王者荣耀)。但成也萧何败也萧何,正因为这个机制的问题,无法完全防住全图挂,也因此甚至有MOBA游戏,同时使用两种同步机制来保证线上赛和线下赛的公平和体验。