安全开发之碰撞检测与伤害计算逻辑

发表于2015-06-12
评论0 2.3k浏览

一、什么是碰撞检测逻辑?

用通俗移动的话来说,碰撞检测就是一门检测两部分运动轨迹是否碰到一起的逻辑,在游戏中一般至少包含2方面的碰撞检测逻辑:一、核心玩法的碰撞检测逻辑;二、运动碰撞检测逻辑。

 

关于核心玩法的碰撞检测逻辑,以格斗类游戏攻击逻辑为例,玩家A挥动武器攻击玩家B,那么碰撞检测逻辑就是玩家A的武器运动轨迹范围与玩家B的立体空间是否有交集的检测逻辑。如果它们之间有交集,那么就表明玩家A的攻击成功命名的玩家B,也就是说碰撞检测成功。反之如果它们之间没有交集,那么就表面玩家A攻击玩家B失败,也就是碰撞检测失败。这里虽然以格斗类游戏为例,但并不是说只有格斗类游戏才有碰撞检测逻辑,几乎所有类型的游戏核心玩法都会涉及到碰撞检测逻辑。比如篮球类运动游戏,蓝球的运动轨迹是否能从篮球框中由上而下穿过的检测逻辑就是碰撞检测逻辑。比如足球运动类游戏,足球的运动轨迹是否能穿过球门的检测逻辑就是碰撞检测逻辑。比如枪战类游戏,子弹运动轨迹是否会穿过敌方人体的检测逻辑就是碰撞检测逻辑。类似场景还有很多,比如弓箭射击是否射中、飞刀是否射中等等都是碰撞检测。

 

关于运动相关的碰撞检测逻辑,比如游戏中人物向前移动,而前方刚好有一个障碍物的情况,这时候人物是否可以透过障碍物继续前进也是一种碰撞检测逻辑。以著名的CS游戏为例,如果是前方为一堵墙,那么明显人物不能继续向前移动;而如果前方为一洼水,则角色应该能直接进入水中继续向前前进。角色能否穿过前方障碍物则就是运动碰撞检测逻辑。

 

碰撞检测逻辑是游戏中最重要的逻辑之一,碰撞引擎的好坏直接影响游戏体验的好坏。同时碰撞检测逻辑也是和游戏安全最密切相关的部分之一,就算游戏发展到今天,由碰撞检测和伤害计算2部分逻辑导致的安全风险依然屡见不鲜。

 

二、碰撞检测逻辑依赖哪些基础数据?

1、关于碰撞检测逻辑需要哪些基础数据,这个作为分析游戏的同学们并不需刻意去记,主要是因为这个并没有固定的标准,这个要和游戏策划如何设计的相关。作为游戏分析人员,哪些和碰撞检测逻辑相关可以充分发挥自己的想象力去联想和验证。

 

比如格斗类游戏,A玩家挥动大刀去攻击玩家B,那么玩家A能否攻击中玩家B会依赖哪些信息呢?大家不需要对游戏设计有多么了解,从生活常识方面我们也可以猜测出来。现实世界中A用刀砍B,A能否砍中B依赖攻击瞬间A的位置、B的位置、所有砍刀的长度、A的挥刀角度等几个关键信息。那么游戏中和现实社会也基本一致,A能否攻击中玩家B的检测逻辑也是依赖A的坐标、B的坐标、武器的攻击范围、攻击朝向信息等等。

 

比如射击类游戏,A开枪能否打中B也和开枪瞬间B的位置是否处在子弹的运动轨迹上有关。


 

2、与攻击碰撞检测相对应,移动碰撞检测一般是由游戏的物理引擎处理。现实我们是否能越过前面的障碍物主要和前面障碍物类型相关。如果前面是水,那么我们可以踏入水中走过去;如果前面是一堵并不太坚硬的木板墙,理论上我们也可以借用蛮力穿墙而过;但如果前面是一堵很厚实的大理石墙面,那么现实社会中我们是没法穿墙的。现实中的水、薄木板以及大理石墙面等不同材料在游戏中称之为材质。游戏的物理碰撞引擎会根据不同材质设定不同的处理规则,如果材质为水,那么可以通过且通过之后水材质会还原。如果材质为薄木板那么通过一定力度的撞击可以通过且撞击过后薄木板材质会消失,而如果是大理石墙面则撞击的处理逻辑为弹回等等。

 

三、核心玩法碰撞检测逻辑出现BUG会带来哪些外挂风险?

1、无敌

在格斗类游戏PVE玩法中,如果怪物攻击角色,那么攻击能否成功和攻击者坐标和被攻击者坐标相关,如果能修改玩家坐标那么让攻击者和被攻击者坐标距离大于攻击攻击的攻击长度,那么就可以确保攻击过程的碰撞检测不成功从而实现角色无敌。

碰撞检测还依赖攻击者的攻击范围(或者武器的攻击距离,同一个概念而已),如果能修改攻击者的攻击范围那么也能实现攻击检测不成功从而实现角色无敌。

同理如果攻击方向被修改,依然可能实现无敌功能。关于第二点中碰撞检测依赖的基础数据,修改任意一个理论上都能实现无敌的功能。

 

2、全屏

全屏的概念实际上就是说屏幕范围内的所有对象都能被攻击中。要实现全屏范围内对象都被攻击中理论做法一般有2种:修改全屏范围内对象坐标到攻击者附近;修改攻击者的攻击范围大到足够覆盖整个屏幕。

 

4、移动碰撞检测逻辑出现BUG会带来哪些外挂风险?

1、穿墙

穿墙是指在游戏的过程中玩家可以直接穿过墙面到达墙的另一面,一般出现这种情况的原因是物理引擎把墙的材质当成类似水、光幕等可穿越材质才出现的效果。在现实世界中,不同物质会有不同的物理特性,把这一套搬移到计算机中之后就体现为不同材质的物理特性对应计算机中的不同数据。只要找到材质类型的数据并修改为代表另一种材质的数据那么在引擎处理时就能大刀穿墙效果。就算不修改游戏内的内存数据,之修改材质判断逻辑的函数返回结果依然能达到一样的效果。

 

曾经碰到过一个奇葩游戏,游戏中移动碰撞检测逻辑是在客户端处理的,而游戏内渲染效果不同时引擎的处理逻辑也会稍有变化。游戏的外网玩家发现了一个BUG就是本来有一处障碍物的材质在游戏渲染效果调整到最低时障碍物材质看不到了,从而实现了本来要绕行很远的逻辑通过调低渲染效果直接通行,节省了大量的走路时间。

 

2、遁地

    存在遁地的原因和存在穿墙的原因基本一致。

 

3、高空行走

4、存在高空行走的原因和存在穿墙的原因基本一致。

5、瞬移

    存在瞬移的原因和存在穿墙的原因基本一致。

 

5、如何设计一个可信的碰撞检测逻辑?

要确保逻辑可信一般有2种做法:1、把逻辑放在服务端执行;2、逻辑虽放在客户端但是服务端有比较可靠的检测方式。不管是把逻辑移动到服务端还是在服务端进行可靠的检测,其前提条件就是该逻辑依赖的所有基础数据都放在服务端维护。

 

6、如何快速确认一个游戏会不会存在碰撞检测导致的外挂功能?

作为一个游戏安全从业者,本人也会关注到和游戏安全相关的大部分网站,系统能从这些网站学习到一些外挂实现相关知识,做到知己知彼,更好的为安全服务。但实际上却让人多少有些失望。为什么失望呢?主要是这些网站很多是提供一些外挂的基础数据信息,让其他人可以直接使用,但是缺少数据分析思路的文章。另外就是网站里的文章更多是一个寻找关键数据的操作记录流水却算不上好的教程。为什么我这么说呢?因为我觉得作为一个好的教程,我们首先要授人以渔而不是授人以鱼。我们先要教会一个人这么判断是否存在外挂功能然后在去考虑实现外挂功能。一个功能的实现方式可能会有很多,我们每种方式一个一个实现看效果太笨了,而且结果不可控。如果能做到快速判断功能是否存在,然后在心里有数的去分析可能会效果更好,心里更有谱。这也是我写这篇文章的主要目的。

 

如何快速确认游戏是否有碰撞检测导致的外挂功能存在呢?这个说白了就是分析游戏的碰撞检测实现原理的过程。把逻辑放到服务端或者把可靠检测逻辑放到服务端的方式理论上不会存在外挂功能。如果即没有把对应逻辑放到服务端,也没把检测逻辑放到服务端,那么就可以100%确定外挂功能肯定会存在,接下来就是看看实现外挂功能的难度问题而已。如果逻辑在客户端,那么把数据进行加密,把逻辑进行VMP保护,那么很大程度上可以提升外挂实现难度。但这种做法仅仅是提升难度而已,如果游戏够火,外挂作者有足够的利益驱动去分析游戏,那么这些外挂功能早晚还是会出现的。那么如何分析碰撞检测原理呢?这里给出2种简单的方式。

 

1、断网法。如果碰撞检测在客户端,那么断网之后进行攻击,那么被攻击者可能依然会出现被攻击中的动作。如果断网之后你依然在某个游戏上发现被攻击后有后仰动作,那么恭喜你99%的可能你能实现无敌功能。相反,如果断网后你的攻击动作在UI上完全没有任何表现,那么很可能的做法就是客户端把攻击行为发送到服务端,然后服务端在把攻击后的表现发送到各个玩家的客户端去。碰到这种游戏,那么我建议你直接放弃实现无敌功能。当然这里的仅限碰撞检测BUG引起的无敌功能,后面还会讲到伤害计算导致的无敌则不再此限制之内。


2、协议分析法。协议是客户端与服务端交互的唯一途径,分析了游戏协议那么那部分逻辑在客户端处理,哪部分逻辑在服务端处理一般就一目了然了。安全的碰撞检测逻辑一般过程是:a、攻击者客户端通过协议告知服务器A向某个指定的方向释放某个技能;b、服务端根据攻击者的坐标信息,攻击技能的朝向信息,以及服务维护的该场景内的其它所有玩家坐标信息等计算该次攻击是否攻击成功;c、服务端把计算结果下发给每个客户端告知是否攻击中,如果攻击中则客户端渲染被攻击的后仰动作效果。而有问题的设计一版是碰撞检测直接在客户端进行,客户端告知服务段的不是攻击的行为动作,而是某次攻击的碰撞检测结果信息。还有一些间的的做法就是把碰撞检测和伤害计算全放在客户端处理,如果攻击成功就直接告诉服务器这次攻击对某个玩家造成多少伤害。如果攻击失败则完全没有任何协议知会服务端。如果是后两种不安全的设计方法那么恭喜你,你可以实现该游戏的无敌甚至秒怪的外挂功能。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引