代码之家  ›  专栏  ›  技术社区  ›  Eli Bendersky

一个javascript游戏的服务器端高分

  •  6
  • Eli Bendersky  · 技术社区  · 16 年前

    我正在用javascript实现一个简单的游戏,我对它的在线高分表很感兴趣,这样玩家就可以相互竞争了。我对此有两个顾虑:

    1. 为此,我需要什么是最简单的服务器端程序?我不需要一个完整的“Web应用程序”,只需要一些简单的东西,可以获得高分的帖子请求,更新数据库并发送分数列表。我对姜戈很熟悉。你有什么建议?
    2. 如何使高分表合理安全?我知道,让它防弹,以防有能力和专门的黑客是困难的,但我不希望任何人访问的javascript源代码能够提交虚构的分数太简单。为此目的有什么工具吗?
    7 回复  |  直到 16 年前
        1
  •  1
  •   ento matt    16 年前

    1.)任何可以与数据库对话并理解JSON或您选择的其他格式的CGI脚本都可以完成这项工作。

    但是,如果您熟悉django,那么在django之上构建您的服务器将是最简单的,从您必须学习的内容以及必须编写多少应用程序代码的意义上来说。如果从头开始编写,看起来简单的CGI脚本可能会变得相当复杂。

    我发现 django-piston 作为一个方便的Django应用程序,可以快速编写一个REST风格的API服务器。它支持JSON,因此应该很容易与您的javascript游戏进行交互。

    2.)最随便的饼干是 replay attack 它的变体是:查看页面源代码并执行一个javascript函数,截获HTTP请求并重新发送(使用类似于篡改数据的Firefox插件应该很容易)。

    为了抵消前者,您可以混淆源代码和HTTP主体;

    • 缩小javascript代码
    • 使用base64或其他编码算法对发送到服务器的消息进行编码

    后者可以通过要求所有更新请求在 Wikipedia article )最近从服务器上获取的。

        2
  •  5
  •   Jordan Reiter    16 年前

    要获得高分是很困难的。我的意思是,它不足以确保它来自您的页面,因为如果,比方说,javascript函数是 submitHighScore(n) 然后,他们总是可以在该页面的地址栏中输入javascript:submithighscore(10000000),并让它工作。

    我们想到的可能是某种散列函数,它生成特定的代码来匹配游戏中的特定级别。当提交分数时,它也会提交这个哈希,所以用户必须达到这个级别才能获得相同的分数。

    另一种选择是,游戏将拉入某种只能暂时工作的密钥,因此在进行过程中,密钥将发生变化,然后分数将间歇性地提交给中央服务器。

    请记住,真正有决心的人总是可以跟踪发送给您的数据并对其进行反编译。

    你可以走布罗德邦德的路线,问玩家一些琐碎的问题,这些问题是经过验证的服务器端,以确保他们确实通过了他们所说的等级……比如“上一等级的怪物是什么颜色的?”

        3
  •  2
  •   Kornel    10 年前

    要安全提交分数,请签名(您还需要确保分数在签名和发送之前不会被伪造,但这是另一个问题)。

    在JS代码中隐藏一个秘密,然后发送 highscore + hash(highscore + secret) 到服务器。散列值可以是md5/sha1_,很容易找到JS实现。

    当然,它不会让任何人仔细分析JS代码,但至少有人不能通过篡改HTTP流量提交虚假的高分。

    关于隐藏JS中的内容:

    你不能 真正地 隐藏它(它最终像DRM一样是无用的),但您可以尝试使它变得模糊,并使调试变得痛苦。

    1. 不要在源代码中以文字形式输入机密-在运行时结合多个函数、局部和全局ISH变量的结果进行计算。
    2. 缩小所有代码,删除源映射。
    3. 添加一些不做任何事情但似乎很重要的代码,以使调试更加混乱。
    4. 不要将任何东西放在全局范围内,而是通过传递闭包和数组来依赖共享可变状态。
    5. 依靠 Date 如果代码在调试器中暂停,计时器会导致竞争条件使代码产生错误的结果(只是不要使代码太紧,使其在速度较慢的计算机上运行)。

    如果游戏是确定性的(就像一个拼图游戏),那么用户可以以一个日志的形式提交高分,该日志记录了为赢得(用户的输入)而采取的步骤,您将在服务器上重放以计算分数。

    这将使攻击从寻找/模仿分数提交功能变为智能或黑客攻击游戏本身,使其更容易玩(但仍在其基本规则之内)。

        4
  •  1
  •   ElDoRado1239    12 年前

    我自己也在想这个。对我来说,最合理的解决办法是:

    1)会话,禁止在游戏外篡改记分表。

    2)记录游戏中的每个动作并发送到计分服务器。然后,服务器将计算这些操作是否真的给出了这样的分数。如果你也记录下了玩游戏的时间,你可以进一步减少攻击者打扰自己破坏游戏的机会。这也将使您能够制作一个重播脚本,如具有高分表的街机服务器,并且在出现可疑分数的情况下,您可以观看重播并自行决定分数是否真实。作弊者必须用一个聪明的机器人来玩你的游戏——除非你有一个真正的奖品游戏,否则没有人会那么努力。

    如果作弊者甚至不分析你的代码,会话就会阻止他。如果他读了你的代码,他会很快破解任何类似散列分数、秘密、令牌之类的东西。但是如果你把游戏记录脚本做得足够彻底,他就会放弃。

        5
  •  0
  •   Todd Moses    16 年前

    回答你的问题:

    1.)这取决于您的环境和编码偏好。php、python、asp.net就是其中的几个。感觉您已经了解了python(从您的配置文件中),您可以使用python cgi脚本来完成此操作,或者使用许多python框架中的一个(zope、django、pylons,…)。

    见: http://www.python.org/doc/essays/ppt/sd99east/index.htm 有关python CGI的信息。

    2.)一些安全技巧:(无或完全证明)

    • HTML中带有编码值的隐藏文本框,服务器将检查该值是否与cookie匹配,以确保高分来自您的页面。
    • 服务器脚本只接受特定域中的值
        6
  •  0
  •   Glav    15 年前

    您可以使用上述方法之一的组合,也可以简单地要求注册用户能够发布高分。非注册用户可以查看他们当前的分数与现有的高分相比,但为了在线发布高分,您必须已经使用注册帐户登录,或者在应用程序联机更新分数时提供。

    沿着“你的高分是X,在高分表中排名”这一行的简单信息。若要在线发布此分数,请先向我们注册”。

        7
  •  0
  •   Insomniak    13 年前

    我认为最好是直接将分数计算到django应用程序的python文件中。 而不是在javascript文件中计算它。您发送数据与发布请求的数据基础进行比较,然后计算得分并将其存储在数据基础中。像这样,你不会把分数在网上传到你的服务器上。这是完全安全的,因为你只做当地的事情。