简体   繁体   中英

How do i prevent players from spamming move messages (Node.js)?

Essentially, i want to learn of the industry standard, and proper practices of preventing players from spamming movement packets.

To demonstrate my current dilemma, i have made a 1-dimensional example, using the key concepts from https://www.gabrielgambetta.com/client-server-game-architecture.html except for interpolation. As such, my movement messages consist of the direction (-1 or 1) and the client's timestamp (used for reconciliation).

// Client move function, dir = -1 or 1
function move (dir, dt) {
    localxPos += dir;
    last_ts_local = Date.now();

    socket.emit('move', {
        ts: last_ts_local,
        dir: dir
    });
}

Since the server simply adds the direction to the players position for EVERY movement packet sent, a flurry of movement messages can be sent to move faster.

 ...

// Server receive move
socket.on('move', function(msg) {
        clients[socket.id].process_queue_moves.push(msg);
});

 ...

// Server processes movement queue (run every 1 seconds - very slow for example purposes)
for (var i = 0; i < clientIDs.length; i++) {
      clientID = clientIDs[i];

      // process movement queue
      for (var j = 0; j < clients[clientID].process_queue_moves.length; j++) {
          clients[clientID].xPos += (clients[clientID].process_queue_moves[j].dir)/Math.abs(clients[clientID].process_queue_moves[j].dir);
      }
      if (clients[clientID].process_queue_moves.length > 0) {
          clients[clientID].last_ts = clients[clientID].process_queue_moves[clients[clientID].process_queue_moves.length-1].ts;
      } else {
          clients[clientID].last_ts == -1;
      }
      // clear movement queue
      clients[clientID].process_queue_moves = [];

}

I initially thought that i could base the client's framerate - or packet rate on the amount of packets they send. However, i quickly realised that if a client sends 2 packets out, it doesn't mean they have 2 FPS. They could simply be standing still, and moved for 2 frames.

After this realisation, i discovered that i could send the move packet even when the player is not moving - more like an input packet. This way, the client could send the move message with a direction of 0 when not moving.

This eliminates the malicious potential for players, since, if the player sends 1000 packets, the server can infer that the player simply has 1000 FPS, and limit the movement as such.

Now, i'm not sure if this is the best way to handle this, or if sending a message every frame is too intensive. If there is a better way to do this, could you please let me know :).

Thanks

I have solved this by sending fragments of input (to keep the packets down - i have it at 20 tps). The input packets also contain when the player is not moving to perform accurate validation. If you'd like to know more info on how i solved this, pm me :).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM