mirror of
https://github.com/logsol/chuck.js.git
synced 2026-05-11 10:37:34 +00:00
Replace cheat-detection teleport with server reconciliation
The old PUNKBUSTER check compared client-reported position to server position and snapped the player back when latency made them diverge, which felt like getting teleported under any real network conditions. Replaces that with proper client-side prediction + reconciliation: client tags each input with a sequence number and keeps an input buffer; server tracks the last processed sequence and reports its authoritative position via a per-user inputAck alongside each worldUpdate. The client only corrects when the actual disagreement exceeds what the unacked input time can explain — so steady-state movement runs purely on local physics, and only genuine unexpected events (collisions, being hit) trigger a smooth blend toward the server state. Includes adaptive threshold scaling so high-latency sessions don't false-positive corrections during normal running.
This commit is contained in:
parent
e6089687ed
commit
71e4b4e847
9 changed files with 162 additions and 149 deletions
|
|
@ -14,6 +14,7 @@ function (Parent, nc, KeyboardAndMouse, Gamepad, pointerLockManager) {
|
|||
|
||||
Parent.call(this, me);
|
||||
|
||||
this._inputSeq = 0;
|
||||
this.keyboardAndMouse = new KeyboardAndMouse(this);
|
||||
this.gamepad = new Gamepad(this);
|
||||
}
|
||||
|
|
@ -26,34 +27,48 @@ function (Parent, nc, KeyboardAndMouse, Gamepad, pointerLockManager) {
|
|||
this.gamepad.update();
|
||||
};
|
||||
|
||||
PlayerController.prototype._recordAndSend = function(command) {
|
||||
this._inputSeq++;
|
||||
if (this.player.doll && this.player.doll.body) {
|
||||
var vel = this.player.doll.body.GetLinearVelocity();
|
||||
this.player.inputBuffer.add({
|
||||
seq: this._inputSeq,
|
||||
timestamp: Date.now(),
|
||||
vx: vel.x,
|
||||
vy: vel.y
|
||||
});
|
||||
}
|
||||
nc.trigger(nc.ns.client.to.server.gameCommand.send, command, {_seq: this._inputSeq});
|
||||
};
|
||||
|
||||
PlayerController.prototype.moveLeft = function () {
|
||||
if (!this.isPlayerInputAllowed()) return;
|
||||
Parent.prototype.moveLeft.call(this);
|
||||
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'moveLeft');
|
||||
this._recordAndSend('moveLeft');
|
||||
}
|
||||
|
||||
PlayerController.prototype.moveRight = function () {
|
||||
if (!this.isPlayerInputAllowed()) return;
|
||||
Parent.prototype.moveRight.call(this);
|
||||
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'moveRight');
|
||||
this._recordAndSend('moveRight');
|
||||
}
|
||||
|
||||
// always allow to stop, to prevent endless running
|
||||
PlayerController.prototype.stop = function () {
|
||||
Parent.prototype.stop.call(this);
|
||||
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'stop');
|
||||
this._recordAndSend('stop');
|
||||
}
|
||||
|
||||
PlayerController.prototype.jump = function () {
|
||||
if (!this.isPlayerInputAllowed()) return;
|
||||
Parent.prototype.jump.call(this);
|
||||
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'jump');
|
||||
this._recordAndSend('jump');
|
||||
}
|
||||
|
||||
// always allow to stop.
|
||||
PlayerController.prototype.jumpStop = function () {
|
||||
Parent.prototype.jumpStop.call(this);
|
||||
nc.trigger(nc.ns.client.to.server.gameCommand.send, 'jumpStop');
|
||||
this._recordAndSend('jumpStop');
|
||||
}
|
||||
|
||||
PlayerController.prototype.setXY = function(x, y) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue