关于代码
我已将此标记为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想出这个可能性,从而提醒我这个重要方面。
答案 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在客户端上计算并发送给主机。
2)以不人道的速度反应,有效消除人为延迟。 你的游戏不是问题,除非更快地提供更多动作,但这是在程序之间所以...它们可能总是比人类更快。
3)自动定位确保不人道的高命中率。
示例:射手游戏XXX
4)使用其他外部助手程序
示例:在线国际象棋游戏,骗子使用国际象棋程序来帮助进行移动。
5)多拳击,一些玩家可能有多台计算机合作取胜
示例:可能发生在射击游戏中?
6)预先计算所有游戏状态,以便作弊者可以使用最佳策略。
示例:tic-tac-toe
7)创建新的身份以击败评级。
8)赢得交易
示例:魔兽战场
断开连接以避免在未与右对手配对的情况下进行注册。即使没有作弊也不会发生断线(如果你想减少这种情况,请不要播放无线或移动设备)。
检测2个Mac地址是否以不同的身份播放,每个Mac上只有一个获胜。
9)失败时断开连接。
X)未知的未知(与已知的已知,未知的已知,未知的已知)
示例:逃税
总是存在循环漏洞,收入缺失或错误报告,欺诈性新扣除等。
幸运的是,总有办法找出某人是否在欺骗最高职位,你可以查看他们提交给该计划的算法并将其视为作弊。请注意,你将被检索到的程序可能是假的,但如果能够赢得这么多的测试可能是微不足道的。
答案 2 :(得分:1)
这很大程度上取决于你打算限制的内容。算法可以询问用户输入吗?是否应该限制算法可以访问哪些信息?使用java / c ++代码使算法能够执行几乎任何操作。您可以设置一个窗口来选择蛇跟随的路径,允许它们以人类智能操作,但机器精度。您可以选择在不同的算法之间进行交换,这些算法可能会激活“转义”模式以摆脱棘手的情况,或者可以选择攻击模式来专门尝试捕获您注意到处于不良位置的玩家。如果这是你想要避免的,我的推荐是提供脚本语言(如Lua或Javascript)。这些可以轻松定制,以限制其功能,并防止用户访问您不希望他们访问的任何内容。做得不错,你可以安全地将这些脚本发送到所有的客户端/服务器,他们都可以安全地运行模拟并比较步骤/结果。
如果你对这些事情没有问题,那么我可能遇到的其他问题只会涉及主机使用已被提及的被黑客户端。
答案 3 :(得分:0)
主要问题是服务器。它具有游戏状态并且需要被信任。您的案例中的客户端可以被修改,因为允许客户端做任何事情来确定下一步。如果服务器在远程计算机上执行,您无法以任何方式真正信任该服务器。它可能会操纵所有校验和和数字签名,因为机器不受信任。
我可以想到你可以做的三件事让服务器受信任: