36

假设您使用 HTML5/JavaScript 创建了一个在线游戏。所有代码都将下载到用户的浏览器中,然后他们将运行游戏。

你如何阻止某人将游戏复制到他们的计算机上,并注入函数和模块来作弊?例如,他们可以编写一个自动瞄准最近的敌人精灵的函数。

有没有什么基本的方法可以通过以某种方式设计游戏代码来保护人们免于做这种事情?

4

13 回答 13

46

是什么阻止了某人将游戏复制到他们的计算机上,并注入功能和模块来作弊?

没有什么。

有没有什么基本的方法可以通过以某种方式设计游戏代码来保护人们免于做这种事情?

没有。

于 2010-07-02T19:26:25.247 回答
38

这就是为什么大多数 JavaScript 游戏严重依赖服务器状态来防止作弊的原因。

于 2010-07-02T19:28:32.103 回答
12

简而言之,没有。但是,您可以混淆 Javascript以使其更加困难。

对于分数之类的东西,理论上用户可以将任何分数发布到您的处理程序脚本。在这种情况下,您可以使用会话并通过 AJAX 定期发回服务器。

于 2010-07-02T19:28:07.393 回答
9

一些想法

服务器端:

  • 存储游戏内部状态服务器端并检查服务器上客户端发送的输入。

  • 自动瞄准:创建普通玩家看不到的假精灵,如果他们经常被击中,你就有了一个机器人。(并不总是有效,因为机器人可能会更新以检查隐身)

  • 检查客户端对服务器更改的反应时间,检查是否有太多太快的反应。(在做出反应之前必须接受大量快速响应,因为人类可以快速做出反应,并且时间必须考虑到网络延迟才能捕捉到任何东西)。给玩家某种验证码,普通玩家永远看不到它。

客户端:

  • 使用混淆使与您的代码交互变得更加困难

  • 检查您知道的黑客中定义的功能。必须经常修改/更新,因为此类黑客的创建者可以解决这些问题。

  • 游戏设计:减少游戏的重复性,这使得为它编写工具/机器人变得更加困难。

  • 不时更新客户端以更改其结构的一部分。虽然这不会阻止机器人,但需要努力让它们保持运行。要么让它对用户透明,要么用新功能伪装。

重要提示:确保您的服务器界面检查用户输入,混淆和客户端检查不会帮助防止有人编写自己的客户端。

于 2010-07-02T20:50:08.170 回答
8

我喜欢这个问题,虽然可能有更好的答案,但这里有一些可能(或可能不会)有效的方法:

  • 混淆。是的,这并不能保证,最终有人可以做到,但有时处理起来很痛苦。
  • 每次生成带有新临时令牌的 JS。您可以将运行代码的 .js 模板化,并插入一个服务器生成的令牌,每个实例都不同。令牌可能是临时的,它可能是验证代码真实性的一种方式
  • 可能有一些方法可以确定正在运行的脚本的正确位置 - 但这可能是伪造的

总的来说,这很难,上面的所有建议都可以解决。我想关键是让他们很难作弊,但考虑到即使是安全的在线模式游戏也有作弊者,很难防止 JS 游戏也容易受到这种影响。

于 2010-07-02T19:30:46.647 回答
8

有没有什么基本的方法可以通过以某种方式设计游戏代码来保护人们免于做这种事情?

唯一明智的方法是将代码的关键部分保留在您控制的服务器上,并且根本不将其提供给用户的计算机。困难的部分是让游戏保持足够快的速度以使其可玩。

于 2010-07-02T19:31:18.433 回答
5

你正在尝试做不可能的事情。我能给你的最好建议是,如果你打算保留任何数据,如硬币/金钱/黄金、级别等,请确保永远不信任客户端,并尽可能多地支持逻辑服务器。

于 2010-07-02T19:30:43.100 回答
5

我认为要走的路是以一种方式编写客户端,以便您动态更改客户端代码并验证在服务器上使用由此创建的代码。

例如有这样的命名空间

window.mynamespace = {

    foo : function(){
        // some stuff here
    },

    bar : function(){
        // some more stuff here
    } 
}

它包含您的所有客户端代码,并使您的所有服务器方法都需要一个令牌,该令牌是先前对代码库进行动态评估的结果。通过重新定义方法和更改方法名称使这变得更加困难。以下是一些示例挑战(这仅在挑战是动态创建且不可预测的情况下才有意义)。所有这些都首先包含一个任务,然后是一个质询,该质询将用于为下一个请求创建授权令牌。(这些是来自 ajax 调用的响应对象)。基本上,该任务将被评估,而评估挑战的结果将是下一个令牌。

{
    task: "mynamespace.baz=mynamespace.foo;mynamespace.foo=undefined;",
    challenge: "mynamespace[11].toString().substr(10,22)"
            // get part of a well-known functions source code
}

{
    task: "mynamespace.bar=function(){ /* new code here */ }",
    challenge: "var xy=0;mynamespace.each(function(item){xy+=item.toString().lastIndexOf(';')}); xy"
            // accumulate the last index of a semicolon in all elements
            // of the namespace
}

为了克服这个问题并仍然获得有效的授权令牌,客户端必须编写一个完整的 javascript 仿真层。虽然可以做到,但我会尝试经常以基本方式更改服务器代码,以使这种技术几乎不可能实现(因此模拟层不知道要模拟什么)。

于 2010-07-02T23:54:04.640 回答
4

例如,他们可以编写一个自动瞄准最近的敌人精灵的函数。

即使对于大多数处理发生在服务器端的游戏,您也可以这样做!您只需要足够快地分析显示。

您甚至可以重新实现部分游戏 AI 来尝试预测机器人将如何移动。如果您无法访问游戏的源代码,这不是一件容易的事,但如果您记录了大量的游戏时间,您可以应用机器学习技术。

有没有什么基本的方法可以通过以某种方式设计游戏代码来保护人们免于做这种事情?

不要忘记你可以改变游戏本身,而不仅仅是它的实现方式。例如,使用随机生成的关卡而不是静态关卡,使用人类玩家而不是机器人,使您的艺术/精灵更复杂,更多地使用音频,限制光标移动的速度,增加冷却时间武器,添加隐患等等。

于 2010-07-03T11:24:08.680 回答
3

从理论上讲,您正在与黑客进行游戏。你不能赢得这场比赛,但你让它具有挑战性。

我的建议是尽可能多地使用服务器端逻辑,并使用 Javascript 混淆。

Javascript 混淆将使代码难以理解,但更好的是,它可以让您在保持相同代码库的同时发布数千个版本的代码。

我曾经使用过JScrambler来做这件事。黑客不必破解一款游戏的代码,而是必须破解数千个版本的代码!:)

于 2012-09-19T15:07:53.257 回答
2

travian( http://www.travian.us/ ) 是在 DHTML 中运行的大型游戏的一个很好的例子,它存在大量客户端滥用问题。仅仅在 Firefox 中安装油脂猴子就为各种剥削行为打开了一扇相当大的大门。也就是说,它们似乎使游戏保持一定的功能,因为大多数漏洞似乎都围绕着常见的游戏内任务的自动化,而不是直接违反游戏的内部域逻辑。请记住,此示例远非仅使用 JS 运行,而是很大程度上依赖于服务器端控件。

于 2010-07-02T20:44:15.343 回答
2

您可以将代码曾经调用的所有内容放入闭包中:

(function() {
  var cantSeeMe = function() {
    // do some game stuff!
  };

})();

在闭包之外,很难获得“注入黑客”的代码(例如覆盖控制台上的函数)。这不会阻止某人重写你的代码,但是通过打包程序传递东西,甚至闭包编译器都会使你的代码很难阅读/修改......(看看jQuery min

总而言之,任何运行客户端的游戏都是可破解的。

于 2010-07-02T20:05:17.430 回答
1

免责声明:这是一种糟糕的方法,可能付出的努力太多了。

假设您有一种在发送之前处理javascript 代码的方法。

首先,每个方法都有一个ident变量,它附加到每个函数的结果(即每个函数都会返回{ident:"special code",result:"actual useful function result"})。您还有一个testIdent()函数可以接受要调用的函数名称以及“测试数据”来提供它(如果需要的话)。的目的是testIdent()将所述函数返回的身份发送到服务器进行验证(这个想法是服务器可以在您认为合适的时候请求测试)。每个功能的ident在发送前都应该为指定的用户随机并专门记录。

其次,在将代码发送到客户端之前,函数顺序是随机的,函数名称会以某种随机方式进行混淆。这样,黑客就无法在函数x()中查找某个变量ident ,因为它将被随机命名。此外,如果每个变量名称也被随机混淆,这将是另一个加分项,只是为了给......每个人的复杂性和头痛增加一个步骤(我告诉过你这是一种糟糕的方法)。

现在,假设采取了适当的步骤来确保代码始终正确运行,黑客是非常聪明的人,如果黑客足够确定的话,仍然有办法追踪这段代码。至少一种方法是搜索关键代码结构,例如switch具有一定数量元素的语句,或具有x个语句的 for 循环等。虽然这些中的每一个都可以被抵消,例如通过case在在if(true)整个代码中随机切换或几个位,对抗黑客将永远是一场持续的(并且可能是一场失败的)战斗。

希望这可以给你一些想法。我不知道有人会如何准确地实现这一点,但这至少是一个想法。

祝你好运!

于 2010-07-02T19:54:54.323 回答