Game'的分数是基于客户端倒计时.如何防弹

Game's score is based on a client-side countdown. How to bulletproof it?

本文关键字:倒计时 客户端 何防弹 防弹 Game      更新时间:2023-09-26

我正在制作一款基于JavaScript倒计时的游戏:你在倒计时为零之前越快完成关卡,你的分数就越高。

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

我最初的想法是设置两个检查点:一个在关卡开始,另一个在关卡结束。检查点基本上是通过AJAX发送到服务器端PHP脚本的会话,然后加上时间戳。因此,在客户端完成游戏后,将与服务器端的分数进行验证。这种保护好吗?

提前感谢!

编辑:我也愿意采用任何其他方法来实现所需的功能。

简单地说,您将值存储在数据库中的datetime字段中。然后,使用该值为javascript提供种子。因此,客户端的任何更改都不会对存储的时间产生影响。

但是,如果您依赖于客户端来获取值,则无法做任何事情来确保它是正确的。用户仍然可以欺骗ajax请求,而不会出现任何实际问题。这有点难,但肯定是可行的。

一旦你的倒计时在某种程度上与客户端相关,就没有办法逃避了:)

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

如果你有一个(服务器端)系统,怀疑的分数被篡改,你可以将该IP地址或cookie列入黑名单,并且不向其他用户显示这些分数。但是,向黑客显示分数。这有几个影响:首先,如果他们认为他们已经打败了你,他们可能会离开你,不去管你的代码。其次,如果你的作弊检测错误地认为忍者玩家在作弊,玩家仍然会在表格中看到他们的分数(即使其他玩家不这么认为)。因此,误报并不那么重要,你可以使用模糊算法,例如,这个玩家的进步速度与平均水平相比如何?他以前成绩很差,然后突然得到了一个惊人的成绩吗?我的服务器是否看到该用户的异常点击模式?等。

你可以这样设置,这样你就可以逐步完善你的检测算法,并在你对玩家产生怀疑后将他们列入黑名单(并取消黑名单误报)。

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

a)如果web应用程序的设计使游戏在页面加载后立即开始,那么你的生活将变得简单。发送游戏的脚本应该在数据库中添加游戏发送时间的时间戳。这是开始时间。当客户端发送"级别完成"消息时,将记录结束时间。在这两种情况下,时间都是在服务器端记录的,因此不需要客户端保存时间。然而,这里有一个陷阱。参见下面的 Catch小节。

b)如果客户端加载应用程序,但当用户点击"播放"等按钮时,游戏开始的时间要晚得多,你的生活就会变得更加困难。在这种情况下,您将需要来自客户机的"级别开始"answers"级别完成"消息。同样,将时间保存在服务器而不是客户机上会是一个更好的主意。然而,你需要确保客户端在开始游戏之前收到一个ACK到"level began"消息,以确保用户不会玩一个没有被服务器记录的游戏。("level began"消息可能从未到达服务器)。

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

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

服务器端必须是存储时间的唯一权限。在关卡开始时,将当前时间存储在$_SESSION中。在关卡结束时,从当前时间中减去它,它就是关卡的运行时间。

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

为了方便用户,您仍然可以通过Javascript显示经过的时间。对于客户机和服务器之间的时间差异(这是完全可能的),您可以通过在客户机访问服务器时获取elapsed_time来进行同步。

如果关卡完成跨越多个会话(如你开始关卡,离开网站,然后回来完成它),你必须将其存储在一个持久的数据存储(数据库)中。

你可以在会话中使用时间戳来存储开始日期,然后在玩家完成时发送使JavaScript执行请求(但第二个时间戳也应该来自PHP或其他服务器端语言)。唯一真正防弹的方法是不向用户展示任何内容,让他告诉你每一个动作,与服务器核对,然后发回他所知道的内容。但这意味着拖延。

您可以发出一个唯一的令牌,该令牌存储在用户会话中,可用于Javascript代码。在启动AJAX请求时,将此令牌作为附加参数传递,以便服务器可以区分合法请求和虚假请求。

这个令牌当然应该只对单个请求有效。结合上述解决方案(基于服务器的时间检查等),你应该能够构建一个可靠的评分系统。

思考这个问题给了我两个想法:

  1. 攻击自己的服务器。我的意思是,每1秒发送一个请求,这将保存分数。这样,"黑客"就不能发送开始/结束时间和作弊。

  2. 以特定的时间差发出请求。假设我们开始玩游戏,你可以在特定的时间间隔(3.4秒?)如果请求不在这个时间范围内,那么用户就是在作弊?或者至少被标记为可能的作弊者。

  3. 使用一个简单的字符串。XD对于发送到服务器的开始/结束时间,脱机加密。

因为其他人说,它不是完全的失败证明(因为我们正在谈论客户端脚本),但至少它会使它更难作弊。不知道,这只是我的意见。

这是不可能使它100%防弹,你只能使它更难以破解,如果它是基于客户端

你可以生成一个GUID当页面呈现。您可以将此GUID、开始日期时间刻度、会话ID连接起来,并计算它们的散列,以便在用户返回时验证数据。