X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=sv_user.c;h=966c0551366c965cbe14d2089912485f51449531;hb=b84125ed0d5fc6922a9ea18b7762b489e377175d;hp=2525785abb91d432e9f601a18e815d85fd633e60;hpb=c3001ce26f2c2fd69caa6af345ccca1d4376f4e5;p=xonotic%2Fdarkplaces.git diff --git a/sv_user.c b/sv_user.c index 2525785a..966c0551 100644 --- a/sv_user.c +++ b/sv_user.c @@ -602,14 +602,19 @@ void SV_ClientThink(void) SV_ReadClientMove =================== */ -void SV_ReadClientMove (void) +qboolean SV_ReadClientMove (void) { + qboolean kickplayer = false; int i; double oldmovetime; usercmd_t *move = &host_client->cmd; oldmovetime = move->time; + // if this move has been applied, clear it, and start accumulating new data + if (move->applied) + memset(move, 0, sizeof(*move)); + if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__); // read ping time @@ -649,7 +654,9 @@ void SV_ReadClientMove (void) if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__); // read impulse - move->impulse = MSG_ReadByte (); + i = MSG_ReadByte (); + if (i) + move->impulse = i; if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__); // PRYDON_CLIENTCURSOR @@ -679,21 +686,33 @@ void SV_ReadClientMove (void) if (!host_client->spawned) memset(move, 0, sizeof(*move)); + else if (move->time > (float)sv.time + 0.001f) // add a little fuzz factor due to float precision issues + { + Con_DPrintf("client move->time %f > sv.time %f, kicking\n", move->time, sv.time); + // if the client is lying about time, we have definitively detected a + // speed cheat attempt of the worst sort, and we can immediately kick + // the offending player off. + // this fixes the timestamp to prevent a speed cheat from working + move->time = sv.time; + // but we kick the player for good measure + kickplayer = true; + } else { // apply the latest accepted move to the entity fields host_client->movesequence = move->sequence; if (host_client->movesequence) { - double frametime = move->time - oldmovetime; + double frametime = bound(0, move->time - oldmovetime, 0.1); double oldframetime = prog->globals.server->frametime; - if (frametime > 0.1) - frametime = 0.1; + //if (move->time - oldmovetime >= 0.1001) + // Con_DPrintf("client move exceeds 100ms! (time %f -> time %f)\n", oldmovetime, move->time); prog->globals.server->frametime = frametime; SV_Physics_ClientEntity(host_client->edict); prog->globals.server->frametime = oldframetime; } } + return kickplayer; } void SV_ApplyClientMove (void) @@ -705,9 +724,11 @@ void SV_ApplyClientMove (void) prvm_eval_t *val; usercmd_t *move = &host_client->cmd; - if (!move->receivetime) + if (!move->receivetime || move->applied) return; + move->applied = true; + // calculate average ping time host_client->ping = move->receivetime - move->time; #ifdef NUM_PING_TIMES @@ -747,8 +768,6 @@ void SV_ApplyClientMove (void) if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector); if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_cursor_trace_ent))) val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(move->cursor_entitynumber)); if ((val = PRVM_GETEDICTFIELDVALUE(host_client->edict, eval_ping))) val->_float = host_client->ping * 1000.0; - - memset(move, 0, sizeof(*move)); } void SV_FrameLost(int framenum) @@ -852,7 +871,9 @@ void SV_ReadClientMessage(void) return; case clc_move: - SV_ReadClientMove (); + // if ReadClientMove returns true, the client tried to speed cheat + if (SV_ReadClientMove ()) + SV_DropClient (false); break; case clc_ackframe: