Итак, я пишу эту онлайн-игру, и мне трудно разобраться, как часто мне следует принимать пакет перемещения.Проблема в том, что я не могу заставить это работать , не доверяя клиенту некоторые данные .В основном моя идея была:
Клиент
/**** [game/client] movePlayer ***/
boolean playerCanMove = Date.now() - player.lastMove > 1000;
if(playerCanMove){
player.lastMove = Date.now();
player.move(RIGHT);
client.send(new PacketMove(RIGHT));
}
Сервер:
/**** [server] handle a move packet ****/
/** The only data received from the client is the direction(RIGHT) **/
/** the server has its own player.lastMove **/
let playerCanMove = Date.now() - player.lastMove > 1000;
if(playerCanMove){
player.lastMove = Date.now();
player.move(RIGHT);
}
else{
error = "Player is moving too fast";
}
Проблема в том, чтосервер player.lastMove
не будет одинаковым на клиенте / сервере из-за времени, которое требуется для доставки пакета.
Так что, если клиент отправит 2 пакета перемещения, первый с временем прохождения100ms
, а второй сервер с временем прохождения 99ms
будет думать, что игрок движется слишком быстро. Если проблема не в этом, проблема в том, что время в пути меняется, и сервер экономит player.lastMove
с небольшим опозданием,предел погрешности в этом случае не звучит слишком хорошо.
Есть идеи?
РЕДАКТИРОВАТЬ:Единственные данные, которые отправляются на сервер, - это направление, в котором игрок хочет двигаться ради примера. Это только те же имена переменных.Сервер имеет собственную player.lastMove
переменную
РЕШЕНИЕ Благодаря @Lev M.
Я еще не реализовал это, ноЯ немного подумал об этом, и не могу найти слабости, пожалуйста, не стесняйтесь комментировать, если вы это сделаете!
Я думаю, можно с уверенностью сказать, что единственное, что может сделать клиент, это изменитьотметка времени, ну, он тоже может изменить часы, но это будет иметь тот же эффект, поэтому я подумал об этом, только предполагая, что он меняет отметку времени пакета
добавление дополнительного && packet.timeStamp < server.clock
к
boolean isTimeStampValid = packet.timeStamp >= player.lastMove + 1000 && packet.timeStamp < server.clock
не может пойти не так, и атака # 1 isTimeStampValid
будет помечена как ложная