自动多人游戏中的坑洼,玩家可以使用自己的算法

时间:2014-10-23 04:47:53

标签: java c++ security networking multiplayer

关于代码

我已将此标记为Java C ++问题。这意味着我不会寻找特定于语言的答案。我只标记了C ++和Java,因为我精通它们,并且如果它们是用那些(或类似的)语言编写的话,很可能会理解你的代码样本。

我在找什么?

指针洞察力关于安全措施,在开发软件时我应该考虑,主要是游戏,例如下面描述的那个。安全性我的意思是检查并仔细检查用户是否以的方式行事。这可能意味着诸如将他/她更新的最恶意病毒集合发送到服务器/其他客户端,或者以其他方式破坏其他玩家的用户体验等行为。


预期评论和答案

  

您是否在问如何阻止人们破解您的游戏?

无论如何我的问题,因为它的方式对于这个帖子来说太宽泛了。如果你确实遇到了一个简单的方法来赢得每场比赛(通过作弊),那么请告诉我。

  

这个问题更适合X

我在CodeReview和程序员中问过这个问题;在这两个网络中,这个帖子都很糟糕。在这里也很受欢迎,公平地说(参考ADTC的评论),因此是赏金。放置赏金后,我重写了这篇文章,以更好地达到SO的标准。但是,如果你认为这篇文章并不适合这里,请告诉我原因。我很难确定这是否真的更适合SO或程序员,所以不要认为这只是我在没有考虑它一秒钟后发布的转储。

  

要在两台计算机之间创建连接,您应该使用套接字。谷歌吧。

我不是在寻找这种技术帮助。我知道如何实施该软件,这不是我第一次这样做。请看我问的实际问题。


为什么我要问这个?

有问题的软件

我正在开发一种类似蛇的多人游戏,玩家可以使用他们自己的算法来确定他们的蛇的下一步行动。玩家通过客户端 - 服务器连接相互连接,即一个玩家将充当主机。您可以假设服务器代码将等到所有玩家都转过身来,直到更新所有客户端之间的游戏状态。

关于游戏

我的游戏在文件夹中搜索任何兼容的.jar文件,其主类扩展了特定的抽象类。然后,玩家可以通过直接连接到他们或通过从大厅搜索游戏来连接到网络上的其他玩家。

在玩游戏时,每个玩家都会使用自己的算法来确定他们的蛇的下一步行动。每个游戏的持续时间可能会有很大差异,具体取决于为游戏指定的更新速率,但大部分时间它们都很快,最有可能在不到30秒的时间内结束。

我还没有实施实际的网络多人游戏。


逻辑的模板源文件如下:

package template

import snake.*;

public class TemplateLogic extends SnakeLogic {

    @Override
    public void onLaunch() {
    }

    @Override
    public String getMove() {
        return "UP";
    }

}

因此,从主机播放器的角度来看,我打算做的是通过网络格式(>#34; up&#34 ;, " down"," left"," right"),因此在这方面不会出现任何安全问题。每个客户用来确定下一步行动的实际程序只会在相应客户的计算机上运行。

我希望你到目前为止跟着我。无论如何,我现在关心的是我可能忽略的任何其他坑洼。确定所有这些坑洼可能有点太单调乏味了,所以我不会主要问这个问题。让我深入了解此事是我所期待的。理想情况下,我可以从不同的人的多个答案中获得更大的图片。

浮在其他人之上的问题是可以阻止任何客户在他们的程序上使用会损害其他玩家的用户体验的方法吗?这样的方法可以是例如Thread.sleep():如果玩家让他的算法在每次移动之间等待10分钟,那将是非常烦人的。对于这个特殊的问题,我想我会为每次移动设置一个时间限制,然后将踢出滞后/恶意玩家或分配默认移动,这样游戏就可以正常继续。


关闭音符:

@ Darinth的回答提醒我游戏的一个非常重要的方面:允许用户输入,这意味着蛇的下一步可以由人类玩家决定 - 是的,游戏可以用键盘正常播放。此外,没有什么限制你在纯AI和仅键盘解决方案之间进行选择:你可以将它们混合在一起,例如,自己控制蛇,当AI注意到你将自己带入陷阱时让AI接管。


将其包起来

我忽略了一些大事吗?我已经计划为我和我的朋友们做一个小项目来消磨时间,但我有点喜欢。

无论你的想法多么小,请毫不犹豫地回答。如果您想到更多兴趣点,可以稍后编辑答案以使其更全面。我会定期检查编辑的任何答案。

感谢您的时间。


我从答案或我自己的

收到的相关想法
  • 在每次移动后比较游戏状态与所有客户端的哈希值。除了具有相同哈希值的玩家外,其他所有玩家都将被踢出,并且主机将保留在最低要求游戏(如果有4个玩家,其中2个玩家有一个哈希,而另外2个玩家有另一个哈希,那么不包括主机的组将被踢,等等)。我想出了这个,但感谢@ToYono,所以归功于他。

  • 在游戏开始之前,比较每个玩家的校验和。所有与主持人具有不同校验和的玩家将被踢(或者甚至不在游戏中)。归功于@ToYono。

  • 随机排列任何排名匹配。阻止有效使用来自同一台计算机的多个连接在同一游戏中播放。如果一个玩家在一个游戏中玩多个蛇,他可以有一个算法试图合法地玩游戏,两个算法只是破坏另一个游戏。归功于@Surt。

  • 允许用户输入。这是从一开始就设计成游戏的一部分,但我忘了提及它。感谢@Darinth想出这个可能性,从而提醒我这个重要方面。

4 个答案:

答案 0 :(得分:3)

此回复总结了上述评论部分中的聊天内容。

  • 由于其中一名玩家必须主持游戏,如果作弊者是主持人怎么办?

如果作弊者是主持人,则意味着他运行服务器代码。这意味着他可以影响整个游戏,因为他正在操作核心引擎。

一个好的解决方案是让每个玩家计算校验和,并将其与所有其他玩家进行比较。校验和,从事一场比赛。如果一个校验和不匹配,则取消游戏。此校验和可以是基于String的唯一程序版本。

  • 主持人也可以破解这个系统吗?

当每个玩家进行自己的比较时,所有玩家都必须以相同的方式破解游戏,这是不太可能的。正如@Olavi Mustanoja指出的那样,校验和系统将与更新客户端产生很大的协同作用。

修改

OP的最初想法是在每个回合中比较所有玩家之间的游戏状态。

  

游戏状态存储在一个int数组中,其中0表示可用空间,-1表示一条蛇,-2表示蛇的头部,8表示苹果(或cookie)。在每次转弯之后,游戏将比较所有状态阵列并终止游戏,如果在某些时候某些状态与其他状态不同。这可以通过发送数组的哈希码轻松完成。

这个想法与我的校验和想法不相容,它可能是双重安全性。

答案 1 :(得分:3)

如果玩家可以作弊,一些玩家会作弊。那么最容易欺骗的方法是什么?

1)改变游戏状态,有效撤消之前的动作。

  • 所有其他玩家和/或服务器都应该验证更新,因为它是谨慎的值,您处理它不应该是一个问题。客户端检查可能就足够了,但是一个犀利的黑客可以通过将支票更改为某些内容来破解支票,例如

    bool allowedMove(){   返回true;   ...这里剩下的原始支票代码 }

然后必须通过代码校验和SHA3来解决这个问题? MD5即将结束其安全时代。

示例:WoW teleport hack,x,y,z在客户端上计算并发送给主机。

  • 欺骗客户以获得理想的结果。
  • Bliz在客户端上制作校验和。
  • 骗子刚刚插入了一个新的网络包,其中x,y,z被传送到他们希望的地方。
  • Bliz检查执行此操作的外部程序。
  • 骗子随机化他们的外部程序。
  • Bliz通过服务器端距离检查反击。
  • 骗子反对限制传送到允许的距离,导致人们在空中行走而没有飞行。
  • Bliz反对进一步的服务器端健全性检查显然解决了大部分问题。

2)以不人道的速度反应,有效消除人为延迟。 你的游戏不是问题,除非更快地提供更多动作,但这是在程序之间所以...它们可能总是比人类更快。

  • 如果反应时间通常比人类快,那么骗子就在另一端。回复和ping时间的差异不够大。

3)自动定位确保不人道的高命中率。

  • 该玩家的命中率远高于第二名最佳确认人类玩家。

示例:射手游戏XXX

  • 外部程序通过Windows API捕获玩家坐标并将修正后的定位提供给游戏。

4)使用其他外部助手程序

  • 比其他玩家更好的AI

示例:在线国际象棋游戏,骗子使用国际象棋程序来帮助进行移动。

  • 您的玩家可以创建一个程序来保存游戏状态,并使外部程序处理数据并进行下一步操作,然后由作弊程序加载并作为下一步移动发送。
  • 检查程序中的任何负载,玩家可能合法地想要保存以分析他们的程序效率。
  • 使用优化的多芯片多线程矢量化算法,骗子可以探索大多数或所有游戏状态。
  • 几乎不可能检查外部程序是否有帮助,您可以检查外部窗口事件生成,但会有很多误报。您可以尝试阻止任何加载/保存作弊,但作弊者可以在IP级别进行攻击。
  • 最大的保护是努力使其成为可能超过任何好处。

5)多拳击,一些玩家可能有多台计算机合作取胜

  • 使用多台计算机或程序实例可以增加骗子主实例获胜的机会,因为其他玩家会破坏其他玩家。

示例:可能发生在射击游戏中?

  • 骗子发送诱饵或抑制单位引发射击或阻碍敌人的移动,而真正的玩家射击对方玩家或以其他方式得分。
  • 很难检查,因为2个人可以合法地在同一地点玩。
  • 如果计算机的MAC地址对于多个玩家来说是相同的,则可能表示作弊,因为他们将在同一台PC上进行操作。但即便如此,也不能欺骗,因为它们可能是从封闭的虚拟机中播放的。

6)预先计算所有游戏状态,以便作弊者可以使用最佳策略。

  • 不这样做的球员会选择次优的开始动作。

示例:tic-tac-toe

  • 可以计算所有游戏状态。 (你可以在头脑中做这件事来做tic-tac-toe)。
  • 评分球员应该在这里帮助,但是骗子仍然可以轻松获胜。
  • 例如,
  • 预编译开放序列通常用于国际象棋程序。
  • 唯一能够击败这个的方法是非常随机化的地图和起始位置,其状态非常大,无法预先计算。

7)创建新的身份以击败评级。

  • 作弊者通过获胜来嘲笑,他们将创造新的"球员"为了自己的低评价,以及#34;赢得"试。
  • 即使玩家不作弊也会发生这种情况,他们会创造新的身份,以便他们能够轻易击败受害者。

8)赢得交易

  • 2个骗子互相交易

示例:魔兽战场

  • 使用外部程序增加获得对手的机会。
  • 断开连接以避免在未与对手配对的情况下进行注册。即使没有作弊也不会发生断线(如果你想减少这种情况,请不要播放无线或移动设备)。

  • 检测2个Mac地址是否以不同的身份播放,每个Mac上只有一个获胜。

9)失败时断开连接。

X)未知的未知(与已知的已知,未知的已知,未知的已知)

  • 总会有人发明一些我们没有想到的新作弊方法。

示例:逃税

  • 总是存在循环漏洞,收入缺失或错误报告,欺诈性新扣除等。

  • 幸运的是,总有办法找出某人是否在欺骗最高职位,你可以查看他们提交给该计划的算法并将其视为作弊。请注意,你将被检索到的程序可能是假的,但如果能够赢得这么多的测试可能是微不足道的。

  • 聪明的骗子会比雷达低一点。

答案 2 :(得分:1)

这很大程度上取决于你打算限制的内容。算法可以询问用户输入吗?是否应该限制算法可以访问哪些信息?使用java / c ++代码使算法能够执行几乎任何操作。您可以设置一个窗口来选择蛇跟随的路径,允许它们以人类智能操作,但机器精度。您可以选择在不同的算法之间进行交换,这些算法可能会激活“转义”模式以摆脱棘手的情况,或者可以选择攻击模式来专门尝试捕获您注意到处于不良位置的玩家。如果这是你想要避免的,我的推荐是提供脚本语言(如Lua或Javascript)。这些可以轻松定制,以限制其功能,并防止用户访问您不希望他们访问的任何内容。做得不错,你可以安全地将这些脚本发送到所有的客户端/服务器,他们都可以安全地运行模拟并比较步骤/结果。

如果你对这些事情没有问题,那么我可能遇到的其他问题只会涉及主机使用已被提及的被黑客户端。

答案 3 :(得分:0)

主要问题是服务器。它具有游戏状态并且需要被信任。您的案例中的客户端可以被修改,因为允许客户端做任何事情来确定下一步。如果服务器在远程计算机上执行,您无法以任何方式真正信任该服务器。它可能会操纵所有校验和和数字签名,因为机器不受信任。

我可以想到你可以做的三件事让服务器受信任:

  • 执行服务器一台由您控制的机器 - >游戏客户端连接到服务器。恕我直言,问题的最佳解决方案
  • 在UserA上托管服务器。 UserB和UserC正在使用此服务器进行播放。 UserA和UserD可以在托管@ UserB的服务器上播放。没有人对黑客/修改客户端/服务器代码感兴趣。 =>难以实施,但您不需要任何服务器基础设施(只有游戏大厅......)
  • 所有客户端都有本地服务器。只有两名战斗员就游戏结果达成一致才算数=>你可以发现某人正在做坏事,但不知道究竟是谁。您可以在服务器上创建一个计数器,如果一个用户经常操作匹配,您可以排除它们及其结果