network-programminglatencyexploitanti-cheat

Find out latency in a reliable way


Background: I am developing a small game and use the player's latency to do lag compensation. The game is open sourced, so at the moment it is a very easy task to reverse engineer the system and delay ones response time to artificially increment ones reported delay, resulting in possibly unfair advantages.


My current strategy for latency retrieval is:


In pseudo code

Server:

function now() {
    return current UTC time in millis
}

i = 0
function nextSequence() {
    return i++
}

sendingTimestamps = []
function onPingEvent() {
    id = nextSequence()
    sendingTimestamps[id] = now()
    sendPingMessage(id)
}

function onPongReceived(id) {
    received = now()
    sent = sendingTimestamps[id]
    rtt = received - sent
    latency = rtt / 2
}

Client:

function onPingReceived(id) {
    sendPongMessage(id)
}

As you can see, it's very easy for the client to just add a delay in his code to inflate his reported latency.

Is there a better way to get a clients latency in order to leave them less room for cheating?


Solution

  • Answer below is a summary of topics discussed in comments to have them all in one place.

    Lag compensation should rely on precise time stamp of event rather than average packet delay

    Transition time may drastically vary even for two successive packets. Suggested approach with measuring average latency and assuming, that each received packet was sent "latency" ms ago for lag compensation is way too inaccurate. The following scheme should be applied instead:

    Server starts emulating world on its side and sends command START to all clients. Clients initiate emulating world and count ticks from its creation. Whenever any event occurs on client side, client sends it with timestamp to server. Like "user pressed fire at tick #183". Server's emulation of game is far ahead due to packet transition time, but server can "go back in time" to handle user's order and resolve consequences.

    Time stamps and events still can be faked

    AFAIU problem of verifying client input is generally unsolvable. Any algorithm implemented in client can be recreated to fake events/timestamps/packets. Closed code can be reversed, so it is not an answer. Even world wide spread games like Counter-Strike or OverWatch have cheaters, despite they are developed by large companies, which, I bet, have separate department focused solely on game security. Some companies develop antivirus like modules, which check game file integrity or hash of parts of RAM snapshot, but it still can be bypassed.

    The question is amount of efforts required to fake algorithm. The more efforts needed the less fakers will be. Trivial timestamp verifycation is the following:

    1. If you receive event#2 in TCP stream after event#1, but its time stamp is before event#1, then it's faked.

    2. If time stamp is far behind server's time, then warn and kick player for enormously bad delay. If it's a real player, the game anyway is unplayable for him, otherwise you kicked hacker. CS servers do this if I'm not mistaken.