6

I am implementing a basic (just for kiddies) anti-cheat for my game. I've included a timestamp to each of my movement packets and do sanity checks on server side for the time difference between those packets.

I've also included a packet that sends a timestamp every 5 seconds based on process speed. But it seems like this is a problem when the PC lags.

So what should I use to check if the process time is faster due to "speed hack"?

My current loop speed check on client:

this_time = clock();
time_counter += (double)(this_time - last_time);
last_time = this_time;

if (time_counter > (double)(5 * CLOCKS_PER_SEC))
{
    time_counter -= (double)(5 * CLOCKS_PER_SEC);

    milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
    uint64_t curtime = ms.count();

    if (state == WALK) {
        // send the CURTIME to server
    }
}

// other game loop function

The code above works fine if the clients PC doesn't lag maybe because of RAM or CPU issues. They might be running too many applications.

Server side code for reference: (GoLang)

// pktData[3:] packet containing the CURTIME from client
var speed = pickUint64(pktData, 3)
var speedDiff = speed - lastSpeed
if lastSpeed == 0 {
    speedDiff = 5000
}
lastSpeed = speed

if speedDiff < 5000 /* 5000 millisec or 5 sec */ {
    c.hackDetect("speed hack") // hack detect when speed is faster than the 5 second send loop in client
}
majidarif
  • 18,694
  • 16
  • 88
  • 133
  • I'm using VisualStudio2015 – majidarif Mar 28 '16 at 08:43
  • @MikeMB no I have not tried steady_clock – majidarif Mar 28 '16 at 08:44
  • Your code sends the client PC's `system_clock` time - they might not be synchronising their PC to any reference (even if you have), in which case there could be a delta between your server's time and theirs, even without any load-related lag. You'd be better off treating their messages as "heartbeats" - expect each within say 10 seconds of the last. – Tony Delroy Mar 28 '16 at 08:44
  • @TonyD Yes, I'm treating it that way. I'll include some code of the checking on the server side on my question. Give me a few. – majidarif Mar 28 '16 at 08:45
  • Tha server-side checking code just edited into the question is making sure the client packs numbers *purporting* to be at least 5000ms apart, but doesn't do any server-side checks to see how frequently the messages are received, which is what I was talking about above. – Tony Delroy Mar 28 '16 at 09:00
  • @TonyD yah, I just realized. Treat it as heartbeats. I'll try it. – majidarif Mar 28 '16 at 09:01
  • Oh right, one problem arises, if I check how often the client sends the packet, the new problem will be network lag. The heartbeats could be sent all at once when the network resumes. – majidarif Mar 28 '16 at 09:03

1 Answers1

1

Your system has a critical flaw which makes it easy to circumvent for cheaters: It relies on the timestamp provided by the client. Any data you receive from the client can be manipulated by a cheater, so it must not be trusted.

If you want to check for speed hacking on the server:

  1. log the current position of the players avatar at irregular intervals. Store the timestamp of each log according to the server-time.
  2. Measure the speed between two such logs-entries by calculating the distance and divide it by the timestamp-difference.

When the speed is larger than the speed limit of the player, then you might have a cheater. But keep in mind that lags can lead to sudden spikes, so it might be better to take the average speed measurement of multiple samples to detect if the player is speed-hacking. This might make the speedhack-detection less reliable, but that might actually be a good thing, because it makes it harder for hackers to know how reliable any evasion methods they use are working.

To avoid false-positives, remember to keep track of any artificial ways of moving players around which do not obey the speed limit (like teleporting to spawn after being killed). When such an event occurs, the current speed measurement is meaningless and should be discarded.

Philipp
  • 67,764
  • 9
  • 118
  • 153
  • Are there any available source I can reference in a proper way of taking samples? Open source games maybe? – majidarif Mar 28 '16 at 14:54
  • You can just store your results over some time frame (say 30 seconds), and then average what you stored. – Patrick Stephen Mar 28 '16 at 14:58
  • @majidarif All you need to save is a position and a timestamp. That's not really rocket-science. – Philipp Mar 28 '16 at 15:03
  • @Philipp, so I was thinking that in lag, packets are sometimes accumulated and set together, this means that the reading if faster. I checked and it seems like if its too fast, it means the packets got sent as one big chunk. but when on speed hack the packet still gets sent 1 by 1 but is fast. – majidarif Mar 28 '16 at 20:03
  • @majidarif speed = distance divided by delta-time. When you receive a large number of packets at once, their timestamps will be identical which means the delta-time will be 0 which means you get a division by zero which means that the results in such a lag-spike are unusable anyway. – Philipp Mar 28 '16 at 20:48