从本质上讲,我想了解行业标准以及防止玩家散布运动包的正确做法。
为了证明我当前的困境,我使用https://www.gabrielgambetta.com/client-server-game-architecture.html中的关键概念(插值除外)做了一个一维示例。这样,我的移动消息包括方向(-1或1)和客户的时间戳(用于对帐)。
// 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
});
}
由于服务器只是为发送的每个运动包添加了指向玩家位置的方向,因此可以发送大量运动信息以加快运动速度。
...
// 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 = [];
}
我最初以为我可以根据客户端的帧率或数据包速率基于他们发送的数据包数量。但是,我很快意识到,如果客户端发送2个数据包,并不意味着它们具有2 FPS。他们可以只是静止不动,然后移动2帧。
意识到这一点之后,我发现即使玩家不移动,我也可以发送移动包-更像是一个输入包。这样,客户端可以在不移动时以0的方向发送移动消息。
这消除了播放器的潜在恶意,因为如果播放器发送1000个数据包,服务器可以推断出播放器仅具有1000 FPS,并以此限制移动。
现在,我不确定这是否是处理此问题的最佳方法,或者每帧发送消息是否过于密集。如果有更好的方法可以,请告诉我:)。
谢谢
答案 0 :(得分:0)
我已经通过发送输入片段(以使数据包保持压缩状态-我以20 tps的速率)解决了这一问题。当玩家不移动以执行准确的验证时,输入数据包还包含。如果您想了解有关我如何解决此问题的更多信息,请告诉我:)。