So im writing this online game and im kinda having a hard time dealing with how often I should accept a move packet. The problem is that I can't get this to work without trusting the client with some data. Basically my idea was:
Client
/**** [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:
/**** [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";
}
The problem with this is that server player.lastMove
won't be the same in the client/server because of the time it takes for the packet to arrive.
So if the client send 2 move packets, the first one with a travel time of 100ms
and the second one with a travel time of 99ms
server will think the player is moving too fast, when that's not the problem, problem is that the travel time varies and server is saving the player.lastMove
a bit late, a margin of error doesn't sound too good in this case neither.
Any ideas?
EDIT: The only data that's being sent to the server is the direction the player wants to move for the sake of the example,It only happens to be the same variable names. The server has its own player.lastMove
variable
SOLUTION Thanks to @Lev M.
I havent implemented this yet, but I have thought about this quit a bit, and I can't find any weakness, please feel free to comment if you do!
I think is safe to say that the only thing the client can do is change the timestamp, well he can change the clock too but that will have the same effect, so I thought about this only assuming he's changing the packet timestamp
adding an extra && packet.timeStamp < server.clock
to
boolean isTimeStampValid = packet.timeStamp >= player.lastMove + 1000 && packet.timeStamp < server.clock
can't go wrong and it will mark attack #1 isTimeStampValid
as false