浏览器/ HTML5游戏的反作弊Javascript


35

我打算冒险在js / html5中制作单个玩家动作rpg,并且我想防止作弊。我不需要100%保护,因为它不会成为多人游戏,但是我需要某种程度的保护。

那么,除了缩小和混淆之外,您建议采取什么策略?

我不会费心地对服务器端进行一些简单的检查,但是我不想走Diablo 3路径将所有游戏状态更改都保留在服务器端。

由于这将是一种rpg,因此我想到了让统计检查员检查其值的突然变化的想法,但是我不确定它的一致性和可信赖性。

那么变量和函数范围呢?只要有可能,在较小的望远镜上工作都是比较安全的,但是值得付出努力吗?

无论如何,javascript都可以像校验和一样自我检查其文本?

有针对浏览器的解决方案?我不会只在早期版本中就为Chrome限制它。


您的数据保存在哪里,数据如何保存?
DogDog 2012年

有趣的是,您谈论Diable 3,“暗黑破坏神1方式”就是这样,信任客户。如果您还太年轻,不记得那件事发生了什么,那就用谷歌搜索!
Valmond 2012年


Apoc,现在我只有一个概念证明,还没有实现任何持久性-但是我计划在首次构建和/或本地存储中实现一些数据库持久性,以使玩家无法继续从他们离开的地方开始比赛。是的,Valdmond那时我扮演了暗黑破坏神。但是我没有在开发一款具有竞争力的多人游戏,也不是一款完整的AAA标记。Byte56,我不担心窃取我的代码(到底是谁想要那个垃圾?)
Billy Ninja

不幸的是,如果您真的很担心黑客/作弊,则必须走暗黑破坏神3的道路
Noob Game Developer 2012年

Answers:


46

简短的答案是你做不到。可以修改运行客户端的任何内容,尤其是从源代码运行的内容,以轻而易举地击败您的策略。如果您放置了一个客户端检查器以查找突然的更改,则用户只需禁用该检查器即可。

好消息是,一般来说,单人游戏几乎没有作弊行为。唯一的主要例外是对于拥有大型“ YouTube高分”社区(例如Line Rider)的游戏,玩家可以在YouTube上相互竞争。

如果您打算这样做,或者太顽固而不能接受人们可能在游戏中作弊,或者自己保持高分(这是多人游戏的一种形式),那么您必须做的就是服务器端的所有计算。是的,所有重要的事情。您甚至无法重复计算客户端来尝试给用户评分,然后通过服务器“验证”评分,因为用户随后可以仅禁用检查并禁用任何可确保进行检查的系统。

我希望有一个更好的答案,但是没有。

也就是说,您可以采取一些措施使作弊变得更加困难。他们不会阻止任何认真的人这样做并发布工具箱以作弊,但是这会使他们放慢速度:

  • 缩小并模糊化您的JS,这绝对会使代码更难阅读。您可以缩小和消除混淆,但是您永远无法找回正确的变量和函数名称,也不能注释。
  • 用其他语言烘烤值。在这种情况下,您可以使用PHP或其他服务器端语言来处理静态设置变量。如果跳跃距离始终应为2个空格,则通常需要为玩家对象定义一个跳跃距离。不要用PHP来处理它,以使JS源代码在2百万个地方的代码末尾贴上2s。这还具有能够加快JS速度的其他好处。
  • 通过一些练习,您将精通混音,甚至可以为每个玩家自定义构建JS。这是防止作弊的另一种方法。如果每个玩家的代码有所不同,那么编写作弊工具包中的作弊就变得更加困难。
  • 最后,您可以根据播放器的身份对源进行校验和。说出他们的IP地址和/或用户名。您知道JS特定于播放器的版本是什么,您可以烘烤校验和并要求另一端的校验和相同。像任何客户端JS一样易于禁用,但是再次使制作工具包变得更加困难。

所以。如您所见,走这条路线可能不值得。很难。需要做很多非常愚蠢的编码实践,并且最终还是比较容易失败的。您需要在服务器端进行所有计算,以防止作弊。或放手,接受作弊行为的发生。


通过让用户上载他/她绘制的地图并计算分数,行车手示例实际上在服务器端非常简单。但是如果没有大量的工作,像街机这样的游戏几乎不可能在服务器端计算分数。
orlp 2012年

@nightcracker你是正确的,但是即使使用Line Rider之类的东西,如果仅在游戏完成后检查,视频已制作且YouTube已被复制,就可以了。当用户去玩游戏时,您应该上传地图,计算出微不足道的路径,然后将其发送回去。游戏不应该能够计算路径。(如果我们
要说的

14

我已经在这里回答了这样的问题,很抱歉告诉您:

我不会费心地对服务器端进行一些简单的检查,但是我不想走Diablo 3路径将所有游戏状态更改都保留在服务器端。

这是你最讨厌的事情。如果您想使用“反作弊”引擎,则必须这样做。您可以添加任何希望在客户端进行的操作,以方便服务器端的工作,但是您绝不能信任客户端。您拥有的所有逻辑必须至少在服务器端。您可以根据需要在客户端复制它,但是没有客户端专用的解决方案可以做到。

顺便说一句,如果您想发现程序的弱点,请不要混淆,让人们看到您的代码并告诉您“这里,您有问题”。

这对您,您的代码,用户和社区都有利。


3
+1授予服务器权限,如果您尝试信任客户端,它就不起作用...
Valmond 2012年

在客户端复制内容很危险。甚至要特别小心,因为如果所有内容都是在客户端复制的,则用户可以通过断开与服务器的支票来作弊。然后,他们可以玩游戏,录制视频并成为YouTube明星。这仅适用于该游戏将是的单人游戏。
DampeS8N 2012年

当我谈论客户端时,它是用于“运动计算”,“碰撞”等。即使对于多人游戏,这也可以在两侧进行。必须始终将服务器端计算视为优先级,但这在存在服务器延迟并使其在客户端时可以有所帮助。但是对于所有“检查作弊”逻辑来说,我同意所有内容都应在服务器端进行。
dievardump 2012年

是的,我明白了。但是我在业余时间做项目是我的业余爱好。进行这种服务器检查会大大增加项目的复杂性,使其不可行。好吧,我将继续了解该项目,并且如果它开始变得越来越庞大和严重,那么我可能会提出一些严肃的服务器端控制(可能是使用Node.js)。
Billy Ninja 2012年

这是对OP的更合适的答案
Noob Game Developer 2012年

3

好吧,一个不错的起点是使用Object.freeze函数(该函数可以防止对象修补)。

“防止添加新属性”,“防止删除现有属性”,“防止更改现有属性或其可枚举性,可配置性或可写性”;内部状态的任何更改都应通过访问器完成。以下示例适用于chrome(应该适用于firefox,尽管我不了解IE ...):

var b = {}
// Fill your object with whatever you want
b.a = "ewq"
// Freeze all changes
Object.freeze(b)
// Try to put new value. This wont throw any error, put wont work either, 
// as we shall see ...
b.b = "qwe"

// Values 
console.log(b.a); // outputs "eqw"
console.log(b.b); // outputs  undefined

5
即使这样,也只会使坚定的作弊者放慢脚步。如果没有其他东西,他可以窃取源代码,将其托管在自己的计算机上,然后删除冻结代码,然后使用其hosts文件诱使他的浏览器认为新页面是旧页面,然后将其与服务器重新连接。
DampeS8N 2012年

@ DampeS8N是的,我想你是对的。
寓言2012年

就像我在OP中所说的,我只想要某种程度的保护。
Billy Ninja 2012年

这根本没有帮助!用户只需在要执行的第一个JS函数中设置调试器断点,然后输入Object.freeze = function(o) {};JS控制台即可。
菲利普

2

不幸的是,如果您确实担心黑客/作弊行为,则必须走暗黑破坏神3的道路。如果不是,则必须进行基本检查或强烈建议进行检查。

  • 买支票-如果我要买东西,我应该有足够的黄金
  • sellchecks-如果我要卖东西,我需要在库存贸易支票中包含该物品-与Sell武器相同
  • 装备检查-如果我正在装备武器,我是否拥有武器?
  • 损坏检查-如果我正在攻击某物(敌人),则我所受到的伤害不会超过我的武器所能达到的最大伤害(在此,您不应指望客户告诉他使用了哪种武器,因为该武器应该更早地保留下来)
  • 手工检查-如果我手工制作了东西,我是否需要所有成分/成分?

... 等等

英雄的位置是1分,有点棘手,因为您不太担心可以离开它,但是最好还是这样做,至少要进行下面的检查

  • 我在地点1 @ T1,在地点2 T2,从地点1到地点2所花的最短时间是多少,它与我的T2-T1相匹配。您可以根据地图大小从小到大进行映射。您应该至少列出主要区域的清单,例如NPC-头目,NPC-敌人产卵区域(不一定是确切位置)

希望这会有所帮助,这听起来很困难,但您需要学习制作真实的游戏


好答案!我在写一个有关如何实施服务器检查的问题,只是大致衡量实施服务器检查的难度。您看到的,我不想浪费数十个小时来实现类似MMO的主干网,总之,只要覆盖一些客户端请求参数或类似内容,它仍然很容易被欺骗。或者只是夸大了本来应该是一个简单有趣的游戏-浪费精力在安全性上,而不是提供更酷的功能或改进功能。
Billy Ninja 2012年

1

它基本上是不可能的。解决您放置的任何内容以防止作弊将非常容易。

问题是您分发的任何软件都可以轻松地在内存中对其进行修改。

此外,如果他们想作弊,就让他们。他们只是在破坏游戏本身。在这种情况下作弊并没有实际的用途,您只是自己破坏游戏玩法。


1

我有一个想法,您可以采取一些措施来防止/减少作弊(除了其他答案)。您可以进行设置,以便一次不给客户提供所有源代码,而是每次客户想要在商店中购买新商品时,客户都必须将某些信息发送给服务器,并且仅在信息与预期的信息完全匹配时才接收所有信息。如果不是,则服务器将其IP或其他内容列入黑名单。

您可以将其与Dampes8n关于使用不同源版本的说法结合使用,如果您能找到一种方法来生成许多不同版本,以便每个用户每次都运行完全不同的源版本,则将失败。还要检查该源版本的黑名单,使其永远不会再给出该源版本的正确商品信息。

之所以如此有效,主要是因为如果黑客第一次没有正确地使用hack,这将使他们更难修改hack,因为每次hack不能正常运行时,他们都必须更改其IP并为新的源版本重新编写该hack。


我会注意的 您要做的最后一件事是意外地永久禁止付费客户。
约翰·麦当劳

@JohnMcDonald确实如此。也许只是杀死该源代码版本。这样,如果他们不小心触发了陷阱,他们只需要刷新浏览器,同时仍然可以使黑客重新编码所有黑客代码。
AJMansfield

0

是的,它不能完全完成。始终检查服务器。任何对游戏有影响的东西都需要获得服务器的授权。

这就是我将重复其他答案的范围。

但是,在防止作弊的最后阶段,我们可以做更多的工作,而不仅仅是检查服务器。好吧,我们可能必须添加一些特殊的服务器检查。但是,请注意,客户端检查并非一文不值,当不涉及作弊者时,它们可以节省带宽和服务器工作。

照这样说:

  • 缓解粗糙客户端:通过HTTPS服务,使用跨域资源共享(CORS),仅允许相同的起源,使用子资源完整性。我建议实现一个服务人员,以对所有请求强制执行它,这也意味着该游戏无法通过将其简单地移动到HTTP而起作用(因为如果没有HTTPS,就没有服务人员,那么服务器工作人员就是在做客户端的一部分) CORS,并且服务器需要CORS),如果它们通过HTTPS提供服务,它将无法正常工作,因为服务器将拒绝其他来源。
  • 缓解脚本编写:使用身份验证并需要令牌才能执行任何操作。服务器应该在每个更新周期为客户端提供一个新的令牌,并且通过执行任何操作来消耗该令牌...做任何事情都需要有效的令牌,令牌始终在变化,因此无法猜测,如果客户端发送两次相同的令牌或发送错误的令牌,服务器就会知道出现问题。为了提供额外的保护:使用密钥创建令牌的消息身份验证代码(MAC),并将其添加到cookie中。修改cookie将终止会话(他们需要猜测密钥),而修改令牌将使MAC检查失败。
  • 修改代码:减少子资源的完整性(现代浏览器还将在运行时检入),将变量保持在有限范围内(使用let,自执行匿名函数和javascript模块)。另外,不要依赖DOM(如果您需要附加属性,则将DOM对象包装并将其添加到包装器中,DOM仅用于IO,而不是用于存储)。这样,无论您在控制台上使用什么工具,都将无法达到游戏逻辑(除非您利用某些浏览器漏洞)。您可能还会考虑使用技术来检测开发人员工具(这些工具对于每个浏览器都是特定的,并且可能无法在所有情况下都起作用或将来不再起作用……因此,这是一场军备竞赛)。
  • 有事吗?会议休息了吗?从当前比赛中踢出球员,要求再次登录。考虑一个验证码……它还具有告诉用户“我们知道发生了一件罕见的事情”的好处(这不是随机服务器故障),是的,这是一种缓解措施。哦,不要急着记录这些。您需要能够验证它们为何会发生,既可以防止出现假阳性,也可以回答支持请求。

是的,这都是缓解措施。我们仍然可以拥有一个定制的浏览器,该浏览器将不检查完整性,并让您访问并破坏本地范围内的变量……然后游戏代码将使用正确的令牌发送修改后的数据,这就是服务器检查的地方玩。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.