在2000年代末期,我在一家小众的MMO游戏公司工作。我们团队规模很小,资金有限,但拥有一群忠实的玩家。这个游戏以技巧为主,没有那些常见的能力提升或不现实的设计,玩家们享受这种挑战。
有一天,我们听说游戏出现了一个作弊程序,玩家们突然非常愤怒。由于我们只有四个程序员,必须有人去调查这件事,我自告奋勇。玩家们确信那些在游戏中击杀他们的人都是在使用作弊程序。我们试图安抚玩家,告诉他们我们正在调查,但我们并不知道这个作弊程序的影响有多广。
需要说明的是,我在这里讲述的一切今天可能早已过时。我们支持Windows和Mac系统,但Windows是显然的目标;而且只有10%的玩家使用Mac。
我发现这个作弊程序是由一家中国公司出售的,但很快就发现他们并不是原创者;他们似乎是偷了这个作弊程序并转卖的。进一步调查后,我找到了真正出售这个程序的公司,他们也为许多更受欢迎的游戏提供作弊程序。鉴于我们的玩家基数很小,我不明白他们为什么会对我们感兴趣。
于是我回家,买了一份程序。我不希望我们的IP地址与这笔购买相关。我有一台Windows PC,所以可以安装并看看它的功能。当时我对Windows内部并不太熟悉,因为我主要负责Mac版本和跨平台的游戏核心(这是一个基于OpenGL的游戏)。
这个作弊程序包含了一些常见功能:墙壁透视、无限弹药、地图增强以及自动瞄准。作为客户,我还可以进入他们的论坛,看看用户对我们的评价(他们觉得我们太笨,永远抓不到他们等等)。我注意到论坛里发帖的人并不多(可能只有十几个),希望这意味着作弊程序的使用率不高。程序的作者也会在论坛发帖,虽然大多是事实陈述,并没有太多猜测。看起来这家公司只有两个人,一个编写所有作弊程序,另一个负责业务运营。这个作弊程序的月订阅费大约是30美元,甚至比我们游戏的价格还高。
我决定专注于几个方面。首先,我要学会如何在Windows上破解游戏,然后想办法让破解游戏变得更加困难,或者至少让作者的破解速度变慢,最后看看我能否确定究竟是谁在使用这个作弊程序。
老实说,这是我做过的最有趣的“项目”之一,连续两个月与一个聪明的对手斗智斗勇!
我花了几天时间研究如何破解Windows游戏,以及人们常用的技术,忽略了那些针对大公司更复杂游戏的破解方法。通过阅读论坛,我可以看出作者自己也是我们的游戏玩家,但我当时还不知道他是谁。因此,产生这个作弊程序的原因不仅仅是为了赚钱,他自己也想使用它!赚钱只是附带的。相比之下,他们为《使命召唤》或其他大游戏提供的作弊程序显然更有利可图。
在研究破解技巧一段时间后,我开始思考如何让我们的游戏更新作弊程序变得更加麻烦。游戏循环的核心是一组当前可视的人物/载具数据(最多128个)。这个固定的结构包含了大部分的动态游戏元素,所以如果有人要写作弊程序,这部分显然是最容易攻击的。然而,在游戏过程中,如果服务器没有及时收到心跳包,它会在短时间内断开客户端,因此在线调试是不可能的。我们有一个离线模式,玩家可以在里面练习所有内容(游戏中有很多不同的载具和步兵类型)。离线模式使用的是相同的游戏循环,只不过是在一个不需要网络的特殊“地点”。作者是在离线模式下编写他的破解代码。
我们的游戏代码是近十年前用C、C++、Lua和Javascript混杂写成的,代码十分丑陋、让人沮丧,处理起来也很痛苦。不过,C的宏定义为我提供了一些便利。于是我先从载具/步兵数组下手,使用宏定义和访问器函数。我首先将离线和在线模式的数组做了不同的处理,但对程序员来说是透明的。接着,我为常见的数据类型(例如位置)编写了宏定义,以各种方式对内容进行扰乱并偏移数据值。每个版本的偏移值都不同。我还创建了影子值,用不同的偏移值复制重要数据。通常,作弊程序是通过监视游戏中的内存变化编写的。
这些改动不能完全阻止作弊程序,但会大大增加更新作弊程序的时间成本,每次我们发布新版本,现有的作弊程序在修复之前都会变得不太有用。考虑到只有一个作者,这意味着他要浪费大量时间去更新一个几乎不挣钱的程序。我还对OpenGL渲染管线做了足够多的改变,使得更新墙壁透视功能变得更加困难。
我们游戏中有一个特殊的“载具”,是游戏管理员和公司用来观察玩家的。这个载具通常是隐形的,但可以开启以吓唬那些违规的玩家。我在论坛上看到他们总是能看到这个“载具”,因此在它出现时会表现得很正常。我和服务器程序员合作,让这个载具在未被激活时不再出现在载具列表中。然后,论坛上的用户开始抱怨,他们再也不知道什么时候有人在观察他们了。他们仍然觉得我们(其实是我!)很愚蠢。哈哈!
在让程序员感到挫败之后,我开始专注于识别那些使用作弊程序的玩家。我知道这些作弊程序开发者曾经因为他们的程序被盗而恼火,所以他们改变了策略,改为在运行时下载作弊程序。我们的应用有一个启动器,包含各种设置,负责启动游戏,因此作弊程序必须在启动游戏时运行。
所以,我推测他们必然会有一个开放端口来下载作弊程序。我找到了一个Windows API,能让我查看哪些端口是开放的。很简单,我发现了他们使用的IP地址。任何与这些IP地址有开放端口的用户必然在运行作弊程序。如果我发现这种情况,我会在启动数据中设置一个不起眼的位,游戏会在多个地方读取这个位,游戏程序则会在运行时在几个发送到服务器的数据包中设置另一个不起眼的位,服务器代码会检测到这些用户并标记他们为作弊程序用户。
在发布了包含这些代码的新版本后,我们能够识别出哪些用户在使用作弊程序,包括程序员本人(他可能是第一个,因为他需要测试)。结果大约有二十几个人,幸运的是人数不多。然后我们召开了一次有趣的会议,讨论该如何处理这些信息。方案从逐渐降低他们武器的准确性,到将他们变成滑稽的小丑,再到在天空中放置一个巨大的箭头指向作弊用户的位置,但他们自己看不到。最终,我们决定最佳方案是先什么也不做,等几周后以违反服务条款为由直接封禁他们。
之后,这家作弊公司放弃了我们的产品,毕竟他们觉得不值得再继续下去。
这些内容在今天可能已经不再适用。但那几个月我玩得很开心,也很满意自己在这场小小的战斗中取得了胜利。我不明白为什么有些人觉得在游戏中作弊是必要的;我也认为作弊很快就会让人感到无聊,可能大多数人最后都会放弃。一个游戏,尤其是一个基于技巧而非运气的游戏,关键在于挑战;如果你把挑战拿走,乐趣也很快就消失了。这样的作弊还会毁了那些喜欢靠技巧玩游戏的玩家的体验。
像《坦克世界》这样的游戏(我现在仍在玩)是服务器判定的,所以所有基于用户输入的决策都是在服务器的安全环境中做出的,这让通过破解来获得优势变得困难甚至不可能。当然,仍然有一些作弊的方式;在《坦克世界》中,有一个流行的做法是付钱给某些公司,在玩家人数较少的时间段加入游戏,而这些公司会用不参与战斗的坦克填充游戏,然后你可以击毁它们获得大量的伤害值或经验值,来炫耀自己的战绩。这在我看来很愚蠢,而《坦克世界》本应能够识别出这些玩家以及那些用于生成不参战坦克的账号,但他们似乎并没有做太多。鉴于他们对每位玩家、每辆坦克、每张地图都进行分析,这本不该是难事。像许多多人游戏公司一样,关键在于投资和是否在意。
今天的反作弊技术已经成为一门大生意。有时它会破坏那些不作弊的玩家的游戏体验,但它也是必要的,因为那些开发作弊程序的人能从中赚到很多钱,而这会让游戏变得毫无乐趣。就像战争一样,进攻与防守总是在相互较量。
至少在我的案例中,这场战斗很有趣!不久之后,我离开了这家公司,之后的职业生涯都在开发iOS应用,直到我退休。