300英雄吧 关注:1,182,260贴子:77,577,328

【计算机知识科普】网游中常见的作弊原理

取消只看楼主收藏回复

看到很多人缺少编程概念的知识,这个贴来讲讲对300英雄做出修改潜在的可能实现
先套个盾,只是觉得贴吧无意义的争吵太多需要科普一下相关知识来告诉大家背后一点的原理。隔壁策划的贴子看了,不知道这么低的水平是怎么入职的,说起话来像个某种疾病晚期,也难怪银狐浮屠人才辈出,ty内部可真是个风水宝地


IP属地:湖北1楼2023-10-13 12:26回复
    首先我们要明白一件事情:游戏体验与反作弊不可兼得,而网络游戏的制作方一定选择前者。任何有及时的反应要素的游戏,总是无法把所有的内容都放在服务器上运算。很多东西在本地运算这件事,不是广传的ty程序员偷懒(虽然确实很偷懒)而导致的。延迟物理性的存在,对于50ms的延迟来说,如果一个技能能否释放这种事情通过朴素的逻辑:发送服务器尝试施法 -> 服务器验证cd正确 -> 返回并释放表现,这几乎意味着任何动作任何内容都要承担0.1s的延迟,这对体验的影响是不可接受的。对于moba而言或许可能有一些容忍,而放到fps类上是根本不能接受的,这也是为什么cs,吃鸡永远无法完全反作弊的原因:击中判定一定是本地验算的,否则玩家体验会非常差,而一旦是本地运算则意味着这些信息可以在本地中抓取,进而做出各种伪造:抓获目标位置的锁头,或是伪造发包的命中(吃鸡里动手就能杀人的那类)。300不会例外,这些手法都是通用的,尽管对于moba一些延迟不敏感的东西可以放到服务器进行验证,但是最核心体验部分依旧要本地运算,完全放到服务器验算是不可能的。


    IP属地:湖北3楼2023-10-13 12:35
    收起回复
      以一个例子来切入:机械臂
      为什么赛博亚丝娜可以q的这么快?为什么神赵云可以跟飞一样?隔壁那个1000块都给不起的2000分高手楪祈小丑虽然在一直扣脚本的字眼,但不得不说它混沌的脑子里隐隐约约还是有点分别的概念。脚本始终只是模拟人在已知已给的交互界面进行的操作,所以人无法做到的脚本也无法做到。但从已有的录像出发,这些神英雄显然已经超过了脚本的范畴,已经是进行了一些其他的修改来做到的,贴吧将这些说不清捉摸不透的东西统称“CE”,这是很多人最多接触到的修改工具的名字,但我相信显然大部分有脑子的人不会觉得这真的是他们用来修改单机游戏的那个CE的同款,但具体是什么又实在超出认知说不清楚,只能含糊的统称一句“CE”


      IP属地:湖北5楼2023-10-13 12:40
      收起回复
        这里回到前面提到的延迟问题,显然“发送服务器尝试施法 -> 服务器验证cd正确 -> 返回并释放表现”这个粗暴实现是绝对正确且愚蠢的,这让用户获得返回信息的时间相对于延迟翻倍。300里的技能施法这一动作是需要经过服务器验证的,很难想象完全不验证技能CD会导致多么严重的本地作弊行为。因此有没有什么好办法可以降低延迟带来的负面体验呢?有,虽然代价就是朴素做法的绝对正确性的丢失,但是正常情况下几乎不会让玩家有所感受,这就是客户端的预输入支持和服务端的延迟补偿结算。


        IP属地:湖北7楼2023-10-13 12:46
        回复
          这里引入两个时间轴概念:客户端时间轴和服务端时间轴,我们称之为CTime和STime,这里以毫秒作为单位。具体时间则书写为C0, C50, S0, S100这样。在朴素表现中,所有客户端都要两倍延迟于服务端,而我们可以通过一种设计这样时间差降低到一倍。依旧假设延迟为50ms,那么此时在一倍延迟的设计下,所有客户端落后服务端50ms,也就是S50=C0,S100=C50,那么在这种情况下,两端要分别进行如何的处理才能让游戏表现相对的一致呢?


          IP属地:湖北13楼2023-10-13 12:57
          回复
            先来讨论客户端的状况。假设现在真实时间线为1000,S1000=C950,此时我们知道,客户端的玩家“我”这一刻看到的,其实是50ms前服务器的状况,这包括了所有人物的位置信息,状态等等。此刻你的折纸瞄准了敌人发出了q,而在C950时刻发出的技能指令,要等到C1000=S1050的时候才能到达服务器,相比于发出技能时的C950时刻足足有100ms的延迟。要知道在打起来500/s移速的情况下,100ms可以跑出50的距离,在加上人脑的延迟,这足以让你折纸的q狠狠的无限空,因为你打的位置足足偏出了一大截。


            IP属地:湖北15楼2023-10-13 13:02
            回复
              为了补偿这种情况,我们将允许位置预测补偿和客户端预输入,而后者就是机械臂关键的一环。尽管此刻仍然是C950,但是玩家移动的改变往往是有规律与轨迹的,我们可以根据过往的移动轨迹提前预测所有其他单位的移动轨迹50ms,使得它在C950时看起来和1000时刻,也就是服务器现在时刻的位置近似的相同。可以看出位置预测是一个技术活,因为玩家可能移动轨迹飘忽不定,但总的来说可以降低延迟带来的影响。ty大概率是有用到位置预测的,从偶尔有时候其他角色的奇怪漂移与闪回就可见一斑,但根据游戏具体情况来看,它这个可能非常粗暴,简单来说就是水平不好效果差。


              IP属地:湖北18楼2023-10-13 13:07
              回复
                接下来说预输入的问题。如果我们允许本地提前一个延迟的时间可以执行输入指令呢?回到刚才的例子,作为折纸的你希望Q冷却的第一时间按下下一个Q来持续线上压制,你的下一个Q将在服务器时间S950时转好。不幸的是,在朴素逻辑下你必须等到C1000=S950时才能释放技能,然后等到S1000=C1050时验证确认,在C1100=S1050时看到结果。尽管我们已经执行了位置预测机制,让你在C1000释放技能时“正确的”看到了S1000时敌人的位置,但你本应S950立刻使用并无缝转好的技能,却不得不在S1050时才输入,这意味着你的冷却时间实际上多了100ms,这是两倍延迟的时间。


                IP属地:湖北25楼2023-10-13 13:26
                回复
                  这里预输入支持的作用就体现出来了:让你真的能无缝的在准确冷却好的时间放出下一个Q。如果在即将冷却的提前100ms按下了Q键,也就是C850=S900时按下了Q,此时客户端表面的预输入逻辑检测到本地剩余冷却时间CCD100=SCD50,因此允许你执行预输入Q的指令并将信息发送服务器(这里假设预输入程序判断在两倍期望延迟内的预输入是合法的并构造发包);50ms后也就是S950=C900时,服务器收到了使用Q键的数据包,并进行服务器校验,此时SCD0=CCD50,刚好通过验证允许使用技能,然后50ms后也就是现在时刻C950=S1000时,玩家收到了回包,你完美的续上了这个技能,并且没有浪费一点冷却时间!


                  IP属地:湖北26楼2023-10-13 13:29
                  回复
                    这样的实现真的就完爆了朴素实现么?当然不是。如同在就业的实践面前你才发现学校的理论如同白纸一样,以上的逻辑是假定了稳定的延迟的。而实际上,游戏普遍使用UDP发包,在QOS遍地的情况下让连接稳定性愈发艰难,因此在平衡漏洞和优化体验上的抉择变得更难进行。让我们回到古代真神:冻墟,来揣度一下他的作案手法


                    IP属地:湖北29楼2023-10-13 13:33
                    回复
                      直接给出结论:ty在远古时期甚至是没有进行服务器验证,或者只进行了很弱的验证的。一切华丽呼哨的无限剑制背后都是纯粹的通信数据结构,无论如何都绕不过使用了某种方式构造服务器可辨认的纯数据发包来通讯的。烂设计可能充满漏洞,我们先排除秘钥被发现或没有秘钥的可能毕竟这太烂了(当然ty的水平可能就这么烂,如果知道加密方式可以直接伪造包体了),游戏与服务器的通讯对我们来说是看不懂的天文。索性电脑在我们手上我们就是天然的中间人,虽然看不懂天文但我们可以捕获每个包观察特征。如果最初的发包设计不谨慎缺少一些独特的特征(加盐),可能导致每次释放技能都能被捕获到一部分完整的特定包体(从机械臂现状来看大概率是这样的)。这部分倒是有些类似吧友天天叫喊的CE了,不过看内存改为了看发包:放个技能,看看发包,寻找规律。


                      IP属地:湖北31楼2023-10-13 13:42
                      回复
                        总而言之,我认为ty的数据设计不够严谨,可以抓到等效于“使用一个技能”逻辑的包,这点在后续的神仙里也是通用的。而早期游戏的服务端可能完全没有做限制,导致冻墟可以随意的发送使用技能的包,等于绕过了客户端本身的限制直接发送信息告诉服务器释放技能,而服务器真的就信了(或者验证很粗糙容易被蒙骗)。随着捞一笔就跑的垃圾游戏居然还没倒闭,ty混日子的程序员慢慢加了服务器验证,pass掉了大部分这样粗暴的使用技能发包骗术。但是为什么不改底层结构让“使用一个技能”等效的包体无法被简单的单独发送,我只能认为是祖传屎山不可动了。从游戏开发来看,设计两端通讯协议是很早期的事情,很可能是非常早期的设计现在真的没法轻易修改了。


                        IP属地:湖北34楼2023-10-13 13:47
                        回复
                          此时我们知道了作弊者除了单纯的脚本以外的另一种武器:伪造发包。虽然现在直接的伪造发包可能也太蠢了,ty也可能修复了很多,但通过某些方法hook掉客户端内验证逻辑,来让黑盒的客户端自己发非法的技能使用包也是可以起到相同作用的。那么服务端对大部分机制已经有所验证了,就算是非法发的包服务器判定冷却没有好也不让用了,机械臂又是怎么实现的呢?这就不得不提到先前的优化手段了。


                          IP属地:湖北35楼2023-10-13 13:52
                          收起回复
                            为了让本地的体验更好,我们加入了指令预输入,它确实可以看似完美的将两倍延迟降低到一倍。但是现实的世界网络波动常在,什么校园网长城宽带ping数飙上500都是常见的事情,这该如何是好呢?同样地,信息往返时间也可能不一致,比如你到服务器是50ms,但服务器到你是500ms,有心的朋友可以自行带入去算一下这种情况,我们依旧无法完美的续上下一个Q的cd。此时另一种补偿方式就出炉了,也就是服务器延迟补偿。这里就不展开描述了,简单来说就是服务器的冷却时间允许一定程度的提前接受(或者简单的预扣cd,比如2s冷却的技能服务器那边用完时就立刻是1.9s,来预补偿延迟),与客户端预输入是对称的功效。如果二者都各自启动一半的功效,就能比较好的平衡现实中网络波动的情况,我相信ty多半也是有这些逻辑的。


                            IP属地:湖北36楼2023-10-13 14:01
                            回复
                              无论这些补偿存在于那一端,如何比例的实现,有一点是无疑的:补偿一定要照顾最差情况。我的延迟是50ms,卡比的延迟是500ms,那卡比就不配玩游戏了?在朴素情况下,我的实际延迟是100ms,卡比是1000ms,依旧是十倍;而在刚才的那种理想优化情况下,我的延迟是50ms,卡比的延迟是950ms,差距高达19倍。所以延迟补偿一定是要以比较卡的玩家作为下限的,因为一倍ping是物理延迟无法优化,但你不能让比较卡的人卡的更严重。在实际中还要考虑波动的情况,500ms的玩家可能波动到1000ms,设置相对大一点总是好的,毕竟都是绿色玩家的情况下没有人会从中获得超过游戏绿色限制的好处,只是太大的预输入和延迟补偿会让人比较违和初玩难以习惯,比如FF14中的预输入和延迟补偿宽容到了极点,读条滑步都是日常操作。


                              IP属地:湖北38楼2023-10-13 14:07
                              收起回复