How to take into account differences in delays when checking location differences with timestamps (anti-fraud)?

When you have a multiplayer game in which the server receives information about the movement (location) from the client, you want to check this information as a measure of protection against fraud.

This can be done as follows:

maxPlayerSpeed = 300; // = 300 pixels every 1 second if ((1000 / (getTime() - oldTimestamp) * (newPosX - oldPosX)) > maxPlayerSpeed) { disconnect(player); //this is illegal! } 

This is a simple example, taking only X considerations into account. The problem here is that oldTimestamp is stored as soon as the latest location update is received by the server. This means that if lag decline occurs at this time, the old timestamp will be received much later than the new location update by the server. This means that the time difference will be inaccurate.

Example:

  • The client says: I am now in 5x10 position
  • Lag spike: the server receives this message in timestamp 500 (it should usually be 30)
  • .... 1 second of movement ...
  • The client says: I'm in position 20x15 now
  • No lag: the server receives a message in timestamp 1530

Now the server will think that the time difference between the two locations is 1030. However, the real-time difference is 1500. This may cause the anti-cheat detection to think that 1030 is not long enough, thus kicking the client.

Possible solution: let the client send a timestamp when sending, so that the server can use these timestamps instead

Problem: The problem with this solution is that the player could manipulate the client to send a timestamp that is not legal, so the anti-cheat system will not start. This is a bad decision.

You can also simply enable the speed maxPlayerSpeed ​​* 2 (for example), however this basically allows you to quickly crack the speed twice as fast as usual. This is also a bad decision.

So: do you have any suggestions to remove this “server time and latency timestamp” to make my anti-fraud actions useful?

+4
source share
3 answers

No, no, with all due respect, this is all wrong, and how NOT to do it.

The security tool does not trust your customers . Do not force customers to send their positions, make them send their button states! The button view is declared as a request where customers say: "I am moving forward if you do not mind." If the client sends a “move forward” message and cannot move forward, the server can ignore it or do whatever it likes to ensure consistency. In this case, the client is only deceiving himself.

For fast hacks caused by packet flow, keep a packet counter. Retrieve clients that send more packets in a given amount of time than the allowed settings. Clients must send one packet per time / frame / world. It is convenient to name packets by time throughout the entire time. Excessive packets of the same time can then be identified and ignored. Please note that sending the same packet multiple times is a good idea when using UDP to prevent packet loss.

Again, never trust a customer. This cannot be stressed enough.

+4
source

Smooth lagging spikes by filtering. Or, to put it another way, instead of always comparing your new position with a previous position, compare it with the position of several updates back. Thus, any short-term jitter is averaged. In your example, the server can look at the position before the peak of the lag and see that in general the player is moving at a reasonable speed.

For each player, you can simply hold the last X positions, or you can hold many last positions plus a few old positions (for example, 2, 3, 5, 10 seconds ago).

As a rule, you perform interpolation / extrapolation on the server in any case within the normal speed of movement in order to hide trembling from other players - everything that you do also extends to your cheat checking mechanism. All legitimate accelerations will come after an apparent slowdown, and interpolation helps to cover such an error.

+2
source

Regardless of the opinions regarding the approach, what you are looking for is a threshold of speed, which is considered a "hoax". Given the distance and the increment of time, you can trivially see if they have moved "too far" based on your fraud threshold.

 time = thisTime - lastTime; speed = distance / time; If (speed > threshold) dudeIsCheating(); 

The time used for measurement is the time the packet was received. Although this seems trivial, it calculates the distance for each character movement, which can be very costly. The best route is to calculate the server location based on speed, and this is the character position. The client never associates a position or absolute speed; instead, the client sends a "percentage of maximum" speed.


To clarify: This was only for checking fraud. Your code has the ability to delay or lengthy processing on the server, affecting your result. The formula should be:

 maxPlayerSpeed = 300; // = 300 pixels every 1 second if (maxPlayerSpeed < (distanceTraveled(oldPos, newPos) / (receiveNewest() - receiveLast())) { disconnect(player); //this is illegal! } 

This compares the speed of the players with the maximum speed. Timestamps are determined when a packet is received, and not during data processing. You can use any method that you want to determine to send updates to clients, but for the threshold method that you want to determine fraud, the above will not be affected by the lag.

Receive packet 1 with second 1: character at position 1

Get package 2 with second 100: character at position 3000

distance traveled = 2999

time = 99

rate = 30

Nothing has happened.

Get package 3 with second 101: Character at 3301

distance traveled = 301

time = 1

rate = 301

Cheating detected.

What you call a “lagging spike” is really a high delay in packet delivery. But it does not matter, since you do not pass when the data is processed, you pass when each packet was received. If you save time calculations regardless of the processing of the tick of your game (as it should be the way it happened during this checkmark), high and low latency only affect how confident the server is in the position of the character that you use for interpolation + extrapolation for resolution.

If the client is not synchronized enough with the one where it has not received any corrections to its position and is not strongly synchronized with the server, there is a significant loss of packets and high latency that your fraud check will not be able to take into account. You should consider this at a lower level with the handling of actual network messages.

For any game data, the ideal method is designed for all systems, except that the server runs for 100-200 ms. Let's say you have a supposed update every 50 ms. The client receives the first and second. The client has no data to display until it receives a second update. Over the next 50 ms, it shows the progression of the changes, as it has already happened (i.e. with very weak slow-motion playback). The client sends its button states to the server. The local client also predicts motion, effects, etc. Based on these button presses, it only sends the “button state” to the server (since there are a finite number of buttons, there are a finite number of bits necessary to represent each state, which allows using a more compact packet format).

The server is an authoritarian simulator that determines the actual results. The server sends updates to each client, say, 50 ms. Instead of interpolating between two known frames, the server instead extrapolates the positions, etc. For any missing data. The server knows what was the last real position. When it receives an update, the next package sent to each client includes updated information. Then the client must receive this information before reaching this point in time, and the players react to it as it is, without seeing any strange jumps, because they never displayed the wrong position.

Perhaps the client should be authoritarian for some things or make the client act as an authoritative server. The key determines the impact of trust on the client.


The client should regularly send updates, say, every 50 ms. This means that the 500-second “delayed burst” (packet reception delay), or all packets sent during the delay period, will be delayed by the same amount, or the packets will be received out of order. The underlying network must correctly handle these delays (discarding packets that have too much delay, delivering packets, etc.). The end result is that with proper packet processing, the expected problems should not arise. In addition, do not receive explicit symbol addresses from the client and instead the server explicitly fixes the client and receives only control states from the client, this will prevent this problem.

+2
source

All Articles