3
\$\begingroup\$

I'm working on a simple game with an authoritative server. The player can move in 4 directions on a 2D board.

The game samples input at 30hz and sends it to the server. The server also runs at 30hz. One input packet contains basically the current player movement direction (None, Left Right..). When a packet is received, it is buffered and then processed during the next server tick.

It works well, however when a malicious client doubles it's sampling rate, the player speed will double as well and this allows for speed hacking. One solution would be to only process a single update packet every tick. However I am aware that packets do not arrive nicely spaced due to network lag.

Another solution I found is to keep a "allowedInputUpdatePackets" counter for each player and increasing it with every tick. (A Solution from the related question Network jitter, client input to server) This prevents the speedhacking while still allowing for some network jitter. But now the client can just stop sending packets, and after a while send multiple at once, resulting in a teleportation. (well almost) I can limit the maximum number of input updates per tick to e.g. 3-5 but this still allows the players to have a small speed boost every time they start moving.

I don't really see a solution to this problem. How to deal with malicious clients sending multiple input packets?

\$\endgroup\$
2
\$\begingroup\$

Have clients stamp their input packets with the index of the 30 Hz input window to which they correspond.

On the server, keep a bitmask of windows for which you've received input from each client. You can use this as a circular buffer and keep recycling it so you don't need to store input flags going back to the dawn of time.

If you receive an input that's stamped too far in the past (or too far in the future!) discard it. A client who sends many inputs out of time may have too high a ping, so you may need to drop them entirely. A client sending messages from the future is likely a cheater, or a bug in your synchronization.

If you receive an input that's stamped for a window for which you already handled input from this client, that's either a duplicated packet (if the content is identical) or a cheating attempt, so you do not commit it to the game's simulated state.

This way, a cheater cannot have more inputs processed than 30 per second, same as the vanilla client.

This stamping can also be useful for rewinding to handle inputs received late or out of order.

\$\endgroup\$
0
\$\begingroup\$

Send a packet when the player stops or starts or changes direction. Record the direction (or lack of it) and calculate the movement on the server at the end of each tick. The client should check the server for the player position and not calculate it locally.

The player's client can then send an unlimited number of requests, it won't help them move any faster.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.