3
\$\begingroup\$

I have read a lot about movement in multiplayer games, but not so much on preventing cheating.

Let's say a client sends moves packets whenever the player press a movement button, then the server checks if that move is valid (that is, if the player is not colliding with anything).

At the same time, there must be some speed check, like dropping packets if the client is sending too many in a short period of time. But the server has no guarantees whether the packets received were sent at the same time or just received at the same time. Client could include a timestamp, but there are 0 guarantees it was crafted by a malicious client.

In short, how can i validate movement speed?

\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

Your client never moves you. The server moves you.

Think about it this way:

A client sends a movement request packet to the server to start moving.

The server says sure you can start moving, there's nothing in the way.

The server begins moving the player in x direction.

The same client ask the server to start moving again. 

The server says, you're already moving stupid.

You always want your client to be requesting things from the server.

Speed hacks are normally achieved by setting the movement speed illegally. For instance, if there's a "speed power up", "mounted on horse", "flying", etc...the hacker sets the movement to one of those states to get faster movement.

A basic anti-speed hack is checking for a maximum velocity that the character can never go over. Figure out how fast they will ever be moving, if a character is ever over it, disconnect them for speed hack.

if (playerSpeed > 10){
  Kill(Player);
} 

You could also check for mount/vehicle pertaining to speed

if (Player!= mounted && playerSpeed > 10){
  Kill(Player);
}

If the player is NOT mounted to increase above maximum walking speed, but yet moving faster, they must be cheating.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ "You're already moving, stupid" Beautiful. \$\endgroup\$
    – anon
    Commented Jan 6, 2015 at 21:01
1
\$\begingroup\$

The server should be authoritative on this matter, the client should never be trusted and each action should be checked by the server.

The typical movement scenario would be:

  1. player wants to move, so it sends a move message (actual position, direction), and immediately starts the move animation.
  2. the server receives the message, it tests if the move was legal (lag compensation here, it considers game state some ms ago depending on latency). If the move was indeed legal then the server computes the new position of the player at current time + latency estimation (when will the player receive the server message). If the move was not legal, the server sends a legal position, or another message.
  3. the player reacts to messages: for example updates its position based on server answer. The new position would be a mix of the player estimation (result of the movement in step 1) and the server answer, the easing between these would not be noticeable in general but in case of speed cheating it would result in a pop back to a legal position.

Regarding packet loss and packet reordering, which both may happen in udp, you consider a queue of messages and ignore old ones. Old message movement are not relevant any more because you already considered a newer one.

Some messages have to be reliable, for example gun firing so some reliability mechanism has to be implemented above udp for these.

If you receive too much packets from a client you could just decide to disconnect him for flood.

Comment about reliability:

There are three degrees of reliability :

  • non reliable : packets may be lost or arrive in different order (UDP). Movement belongs here, you send many of them losing one is not big deal, if you have a sort of msg number you drop old ones. Anyway they are too old now.
  • reliable : packets cannot be lost, but may arrive in different order (UDP + reliability layer). Ex. when you fire a gun you sent this once, you do not want to lose the message.
  • ordered reliable : packets cannot be lost and always arrive in order (TCP). Ex. Chat messages, you want your messages to always arrive in order.
\$\endgroup\$
4
  • \$\begingroup\$ You are right, but what if the server suddenly receives multiple packets from the client? It could happen because the client is cheating or because of lag. How do you compute every move to discern this situation? \$\endgroup\$ Commented Jan 6, 2015 at 15:43
  • \$\begingroup\$ In case of too much packets you, can drop the player, he is flooding. Receiving multiple move packets is not a problem, because the new position is computed from the current one (+/- lag). For reliable events, you have to check for example that a minimum time interval between events is respected. \$\endgroup\$
    – Thelvyn
    Commented Jan 6, 2015 at 15:53
  • \$\begingroup\$ "For reliable events, you have to check for example that a minimum time interval between events is respected." But wouldnt this approeach be cheat-prone? I made a test in tcp where the clients sends a packet every 1/3 of a second, but sometimes it arrives at the server two packets with less time. If i drop the minimum interval time maybe someone could take advantage of it. \$\endgroup\$ Commented Jan 6, 2015 at 18:40
  • \$\begingroup\$ You do not want to drop reliable events, only non reliable ones which loss is acceptable, I added a comment about reliability. With reliable events what you want to avoid is for example players that fire their gun faster that it is allowed to. For non reliable movement you need much more than 3 messages per second, if you do not want to do this then you should consider using ordered reliable messages because you cannot afford to lose one, but the gameplay will suffer. Checkout this blog fabiensanglard.net/quake3/network.php it explains how quake3 network model works. \$\endgroup\$
    – Thelvyn
    Commented Jan 6, 2015 at 19:20
0
\$\begingroup\$

I will keep it short and sweet.

There are two "servers" running. One locally and one remotely online. The user simply operates the mouse and keyboard to control the game. Input is parsed by the client and converted to commands (e.g. move forward / turn left / jump). The client sends these commands to the local server and remote server. They both process these commands. Very often, the remote server sends the correct state to the local server and the local one quickly interpolates it's "predicted" state with the true global state on the remote server. All rendering is done from the model on the local server.

  1. Use two server processes, a local server one (possibly with less data [lacking data of monsters and players outside range of sight]) and a remote server (has all data).
  2. The users uses the input peripherals to control the game (e.g. mouse & keyboard) and the local client software translates user input into game "command" objects (e.g. run forward and shoot).
  3. The clients sends these command objects serialized to the local and remote servers.
  4. Both servers deserialize them and compute the results of the player's actions.
  5. The local server's model (game data) is used for all rendering purposes.
  6. The remote server updates the local server frequently with the true global state of all objects and creatures exposed to the player's senses (line of sight / hearing / psychic).
  7. The local server knows how to smoothly and quickly interpolate to the new updated state.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .