client-server - 使用时间戳验证位置差异时如何考虑延迟差异(反作弊)?

标签 client-server latency anti-cheat

当您有一个服务器从客户端接收移动(位置)信息的多人游戏时,您希望验证此信息作为反作弊措施。

这可以像这样完成:

maxPlayerSpeed = 300; // = 300 pixels every 1 second
if ((1000 / (getTime() - oldTimestamp) * (newPosX - oldPosX)) > maxPlayerSpeed)
{
   disconnect(player); //this is illegal!
}

这是一个简单的例子,只考虑了 X 坐标。这里的问题是,只要服务器收到 上次位置更新,就会存储 oldTimestamp。这意味着,如果当时存在滞后峰值,则旧时间戳将比服务器接收到的新位置更新晚得多。这意味着时差将不准确。

例子:
  • 客户说:我现在在 5x10 的位置
  • 滞后尖峰:服务器在时间戳 500 收到此消息(通常应该在 30 时到达)
  • ....1 秒乐章...
  • 客户说:我现在在 20x15 的位置
  • 无延迟峰值:服务器在时间戳 1530 接收消息

  • 服务端现在会认为这两个位置的时差是1030,而实际时差是1500。这可能会导致反作弊检测认为1030不够长,从而踢客户端。

    可能的解决方案:让客户端在发送时发送时间戳,以便服务器可以使用这些时间戳代替

    问题:该解决方案的问题在于玩家可以操纵客户端发送不合法的时间戳,因此反作弊系统不会启动。这不是一个好的解决方案。

    也可以简单地允许 maxPlayerSpeed * 2 速度(例如),但这基本上允许速度比正常速度提高两倍。这也不是一个好的解决方案。

    那么:您对如何解决这个“服务器时间戳和延迟”问题有什么建议,以使我的反作弊措施值得吗?

    最佳答案

    不不不......恕我直言,这都是错误的,以及如何不这样做。

    补救措施是 不信任您的客户 。不要让客户发送他们的位置,让他们发送他们的按钮状态!将按钮状态视为客户说“我正在前进,除非您反对”的请求。如果客户端发送“向前移动”消息并且无法向前移动,则服务器可以忽略该消息或做任何它喜欢的事情以确保一致性。在这种情况下,客户只会自欺欺人。

    至于通过数据包泛洪实现的速度黑客,请保留数据包计数器。弹出在特定时间范围内发送超过允许设置的数据包的客户端。客户端应该在每个滴答/帧/世界时间步长发送一个数据包。在整个时间步长增量中根据时间命名数据包是很方便的。然后可以识别并忽略相同时间步长的过多数据包。请注意,在使用 UDP 时,多次发送相同的数据包是一个好主意,以防止数据包丢失。

    再次,永远不要相信客户。这一点怎么强调都不为过。

    关于client-server - 使用时间戳验证位置差异时如何考虑延迟差异(反作弊)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1657057/

    相关文章:

    google-cloud-platform - 如何在 stackdriver 中获取负载均衡器的延迟详细信息?

    android - Android NDK音频回调

    android - 如何验证用户没有破解应用程序中的 GPS 位置?

    c# - 我如何查看是否有任何程序正在模拟 key

    java - 聊天客户端/服务器 - 如何指示客户端接受来自控制台或服务器的输入

    java - 如何: Java Server Socket response and Client reading

    c - WSAStringToAddress 错误 10022/从控制台参数读取 IPv6

    google-cloud-platform - 如何指定 Google Cloud Function 的区域?

    php - 在在线游戏中跟踪计算机

    java - 在JAVA客户端/服务器应用程序中,我应该在通信接口(interface)的哪一部分存储实例变量?