游戏同步游戏开发Unity

防外挂的那些事儿

2017-06-22  本文已影响165人  水风

对于一个要上线的游戏,防外挂是必须的,历史上因为外挂而造成大量玩家流失的游戏数不胜数。随着游戏研发技术的发展,对外挂的预防业内其实做的已经越来越好了。下面总结一下防外挂的基础知识,以及我们的移动模块为防外挂做了哪些工作。
本文是6月23号讲的沙龙的一部分。在这之前的读者有兴趣可以报名参加,之后的读者可以看录像了解更多。http://salon.km.netease.com/salon_detail?salon_id=1930

1 预防外挂的基础知识

在做外挂预防工作之前,我们要先了解外挂有哪些。根据我的了解,市面上常见的外挂主要有以下几种:

防外挂是一个系统工程,需要不同的模块配合实现。而且,对于不同的游戏对外挂的预防要求也是不同的,具体游戏需要具体分析。
常见的外挂预防手段有以下几种:

以上介绍的通用方法并不能解决所有的外挂问题,因此我们在游戏的逻辑实现过程中要需要做对应的防外挂机制。

在游戏逻辑实现中进行防外挂的基本方法是:

在具体的游戏执行逻辑中增加防外挂机制的时候需要秉持一些原则:

下文以玩家在客户端操作自己的单位移动为例,介绍移动模块为了防外挂做了什么工作。
之前写过技能模块的防外挂内容,大家可以阅读:http://km.netease.com/article/209006

2 移动模块如何防外挂

我们游戏的移动同步逻辑的基本原理是:单位在主控端(玩家自己的客户端)根据玩家输入执行移动逻辑,然后将位置点以及时间信息以一定的频率发送给从端,服务端以及其他客户端根据主控端发来的移动同步信息模拟、预测、纠正单位的位置。

基于以上同步机制,移动模块需要考虑三种外挂情况:
1.主控客户端伪造或篡改瞬移消息。
2.主控客户端修改本地内存中的移动速度。
3.主控客户端使用加速器

2.1防止客户端发送非法瞬移消息

由于我们游戏所有的移动都是在主控客户端发起和执行,然后服务端跟随,所以瞬移也是客户端先执行,然后通知服务端。

为了保证客户端不能发送非法瞬移消息,我们将瞬移流程定义为:由服务端发起、客户端执行、服务端再验证。

瞬移逻辑如下图所示:


Paste_Image.png

1.服务端发起瞬移,但是并不将单位移动到对应位置,而是将瞬移信息发送给客户端。
2.客户端收到位移信息后,将单位移动到对应位置。
3.客户端发送一个瞬移消息给服务端,服务端收到后,将单位移动到对应位置。

基于以上瞬移流程,可以比较简单的实现瞬移防外挂功能。

  1. 服务端发送瞬移信息给客户端时,记录下来瞬移目标的位置。
  2. 服务端收到客户端的瞬移消息,进行以下验证:

基于以上流程,可以保证瞬移虽然是客户端执行的,但是仍然由服务端发起和验证。

2.2检测不合理的移动速度

对于移动逻辑,还需要防止一种外挂:改内存中的移动速度。

对于这种外挂的预防,一般有两种:1.在客户端通过一定的加密手段使玩家无法找到移动速度,从而无法改变。2.服务端验证。我们使用的是服务端验证的方式。

服务端验证的基本原理:
当客户端发来一个移动消息时,服务端根据此条消息和上一条消息可以计算出来两消息之间的移动速度,然后根据服务端信息可获得对应时间的服务器认为可以达到的最高速度,比较后即可以验证。

其中服务端如何获得对应时间的允许最高速度是其中的难点。刚开始,我们使用的方式是记录每次移动速度改变的时间和速度值,当收到客户端消息时,根据客户端发送消息的时间去查该时间对应的速度值。

但这里有一个问题:当一个击飞事件移动速度改为300,击飞事件结束前又来了一个普通移动事件速度改为40,其实这时的移动速度其实是300,但根据我们的算法计算出来的是40.

因此,我们实现了一套基于改变移动速度事件的移动速度验证机制。我们并不记录速度改变得值,而是记录速度改变事件的开始&结束时间和速度值,因此每次需要计算某时间对应的速度时,根据速度改变事件的信息可以计算出准确的值。

2.3检测加速器

游戏外挂最常见的就是加速器,在我们的游戏移动机制中,加速器可以让客户端的单位移动速度变快,而我们是将客户端单位位置同步给服务端,若服务端没有任何验证,则服务端就会跟随客户端位置,加速器外挂就会生效。

加速器外挂的原理是加快的客户端的时间流逝,因此,最简单的方式是当服务端收到同步消息时,从同步消息中拿出来客户端发送消息的时间,若客户端发送时间大于服务端当前时间(会加一个阈值),则认为是使用外挂。

游戏中有时间校准机制,当玩家短线重连时,客户端和服务端会重现校准时间,而校准后的时间由于网络延迟和网络波动问题,可能出现各种情况,包括客户端时间快于服务器时间。对于这种情况,会造成误判。

为了解决这个问题,我分析了加速器的特点。加速器会导致客户端时间持续不断的加快,并和服务器的差距越来越大。因此,我们使用以下验证机制,基本可以避免误判:
1.若客户端时间>服务端时间+[阈值],则[阈值] += (客户端时间-服务端时间)
2.第1步重复n次,n是我们给客户端出现异常的机会次数,我们游戏n=2。
3.若客户端时间>服务端时间+[阈值],则认为客户端是外挂。

通过这种方式,我们给客户端一次或者多次机会,对于加速外挂,它会导致客户端时间持续加速,最终使用掉所有的机会。而由于网络波动导致的客户端校准后的时间快于服务端时间的情况,不太会使用掉所有的机会。

当然,这种监测方案理论上仍然存在误判。但因为每次切换场景都会重置,当n=2时,经测试分析出现的误判情况极少。

若把n改成更大,会导致玩家进入一个新场景后,若加速倍率比较小,比如加速0.1倍,可以使用较长一段时间的加速外挂。

因此n的选择和初始阈值的选择都是一个权衡。

附:运维log可以检测加速器外挂的使用,但log更多的是检查,而不是预防。我们这里实现的是预防,保证玩家无法使用加速器获得任何收益。

上一篇下一篇

猜你喜欢

热点阅读