游戏的得分基于客户端倒计时.如何防弹呢?

Cin*_*mon 17 javascript php synchronization

我正在开发一款基于JavaScript倒计时得分的游戏:在倒计时到零之前你完成关卡的速度越快,得分就越大.

当我最终从服务器端的客户端收到它时,如何确保它不会以某种方式被更改?

我最初的想法是制作两个检查点:一个在一个级别的开头,另一个在结束时.Checkpoint基本上是通过AJAX发送到服务器端PHP脚本的会话,然后加上时间戳.因此,在客户端完成游戏后,将使用服务器端的分数验证分数.这种保护有什么好处吗?

先感谢您!

编辑:我也愿意接受任何其他方式来实现所需的功能.

Spy*_*ros 8

只需将值存储在数据库的datetime字段中即可.然后,您使用该值为javascript播种.因此,客户端的任何更改都不会对存储的时间产生影响.

但是,如果您依赖客户端获取值,则无法执行任何操作以确保其正确无误.用户仍然可以欺骗ajax请求而没有任何实际问题.它使它有点受伤,但肯定可行.

一旦你的倒计时与客户端有某种关系,就没有逃脱:)


Ksh*_*KJ- 7

您可能面临两种可能的情况.让我从简单的开始:

a)如果Web应用程序的设计使得游戏在页面加载后立即启动,那么您的生活将变得简单.发出游戏的脚本应该将数据库的时间戳记与发送游戏的时间一致.这将是开始时间.当客户端发送"完成级别"消息时,将记录结束时间.由于在两种情况下都在服务器端记录时间,因此您不需要客户端留出时间.然而,有一个问题.请参阅下面的"捕获"部分.

b)如果客户端加载了应用程序,但是当用户点击"播放"等时游戏开始的时间很晚,那么你的生活将会变得更加困难.在这种情况下,您需要一个"级别开始"以及来自客户端的"完成级别"消息.同样,将时间留在服务器而不是客户端会更好.但是,您需要确保客户端在开始游戏之前收到"级别开始"消息的ACK,以确保用户不玩未被服务器记录的游戏.("级别开始"消息可能永远不会到达服务器).

Catch:你需要意识到用户在分数上作弊是不可能的!JS是完全开放的,无论你如何实现对服务器的开始/结束调用,任何用户都可以编写脚本,以便在她希望使用的任何时间间隔向服务器发送类似的调用.即使您使用会话/ cookie,也可以轻松复制这些内容.(例如使用嗅探器).因此,您必须意识到并接受HTML/JS体系结构和代码在这些限制内施加的设计限制.因此,最好的想法是为用户编写代码,而不是阻止黑客发送恶意调用.让你的游戏对玩游戏的人来说很有趣,不要担心黑客会对他们的分数作弊 - 无论如何他们都不会成为你的目标受众.

  • 正如每个人都在说从客户那里读取任何价值都是不值得信任的.如果你真的**想要使用来自客户端的时间也跟踪Crimson提到的服务器上的时间,然后比较两个数量允许delta差异并忽略超出控制限制的那些. (2认同)

Mar*_*one 7

正如其他人所指出的那样,你无法确定时间没有被篡改,但是有办法减轻后果:

如果您有(服务器端)系统怀疑分数已被篡改,您可以将该IP地址或cookie列入黑名单,而不是将这些分数显示给其他用户.不要显示分数给黑客,但.这有几个影响:首先,如果他们认为他们已经打败了你,他们可能会继续前进并留下你的代码.其次,如果你的作弊检测错误地认为忍者玩家是黑客,那么玩家仍然会在正常情况下看到他们的得分(即使其他玩家没有).因此,误报并不重要,您可以使用模糊算法,例如,该玩家的改进率与平均值相比如何?他有一堆糟糕的分数然后突然变得不可思议吗?我的服务器是否看到了这个用户的不寻常的点击模式?等等.

你可以设置它,以便你可以逐步优化你的检测算法,并在你对它们产生怀疑之后将黑名单列入黑名单(以及非黑名单误报).


小智 5

首先,忘记从客户端获取经过的时间.任何恶意用户都可以更改发送的数据.

服务器端必须是存储时间的唯一权限.在级别的开头,将当前时间存储在$ _SESSION中.在级别结束时,从当前时间中减去它,它是该级别的已用时间.

$_SESSION['start_time'] = time();

$elapsed_time = time() - $_SESSION['start_time'];
Run Code Online (Sandbox Code Playgroud)

您仍然可以通过Javascript显示已用时间,以方便用户.对于客户端和服务器之间的时序差异(这是完全可能的),您可以通过在客户端命中服务器时获取elapsed_time来进行同步.

如果多个会话之间的级别完成跨度(如启动级别,离开站点,稍后再返回以完成它),则必须将其存储在持久性数据存储(数据库)中.