当您有一个服务器从客户端接收移动(位置)信息的多人游戏时,您希望验证此信息作为反作弊措施。
这可以像这样完成:
maxPlayerSpeed = 300; // = 300 pixels every 1 second
if ((1000 / (getTime() - oldTimestamp) * (newPosX - oldPosX)) > maxPlayerSpeed)
{
disconnect(player); //this is illegal!
}
这是一个简单的例子,只考虑了 X 坐标。这里的问题是,只要服务器收到 上次位置更新,就会存储 oldTimestamp。这意味着,如果当时存在滞后峰值,则旧时间戳将比服务器接收到的新位置更新晚得多。这意味着时差将不准确。
例子:
服务端现在会认为这两个位置的时差是1030,而实际时差是1500。这可能会导致反作弊检测认为1030不够长,从而踢客户端。
可能的解决方案:让客户端在发送时发送时间戳,以便服务器可以使用这些时间戳代替
问题:该解决方案的问题在于玩家可以操纵客户端发送不合法的时间戳,因此反作弊系统不会启动。这不是一个好的解决方案。
也可以简单地允许 maxPlayerSpeed * 2 速度(例如),但这基本上允许速度比正常速度提高两倍。这也不是一个好的解决方案。
那么:您对如何解决这个“服务器时间戳和延迟”问题有什么建议,以使我的反作弊措施值得吗?
最佳答案
不不不......恕我直言,这都是错误的,以及如何不这样做。
补救措施是 不信任您的客户 。不要让客户发送他们的位置,让他们发送他们的按钮状态!将按钮状态视为客户说“我正在前进,除非您反对”的请求。如果客户端发送“向前移动”消息并且无法向前移动,则服务器可以忽略该消息或做任何它喜欢的事情以确保一致性。在这种情况下,客户只会自欺欺人。
至于通过数据包泛洪实现的速度黑客,请保留数据包计数器。弹出在特定时间范围内发送超过允许设置的数据包的客户端。客户端应该在每个滴答/帧/世界时间步长发送一个数据包。在整个时间步长增量中根据时间命名数据包是很方便的。然后可以识别并忽略相同时间步长的过多数据包。请注意,在使用 UDP 时,多次发送相同的数据包是一个好主意,以防止数据包丢失。
再次,永远不要相信客户。这一点怎么强调都不为过。
关于client-server - 使用时间戳验证位置差异时如何考虑延迟差异(反作弊)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1657057/