public static void SV_ExecuteClientMessage(client_t cl) { Int32 c; String s; usercmd_t nullcmd = new usercmd_t(); usercmd_t oldest = new usercmd_t(), oldcmd = new usercmd_t(), newcmd = new usercmd_t(); Int32 net_drop; Int32 stringCmdCount; Int32 checksum, calculatedChecksum; Int32 checksumIndex; Boolean move_issued; Int32 lastframe; SV_MAIN.sv_client = cl; SV_USER.sv_player = SV_MAIN.sv_client.edict; move_issued = false; stringCmdCount = 0; while (true) { if (Globals.net_message.readcount > Globals.net_message.cursize) { Com.Printf("SV_ReadClientMessage: bad read:\\n"); Com.Printf(Lib.HexDump(Globals.net_message.data, 32, false)); SV_MAIN.SV_DropClient(cl); return; } c = MSG.ReadByte(Globals.net_message); if (c == -1) { break; } switch (c) { default: Com.Printf("SV_ReadClientMessage: unknown command char\\n"); SV_MAIN.SV_DropClient(cl); return; case Defines.clc_nop: break; case Defines.clc_userinfo: cl.userinfo = MSG.ReadString(Globals.net_message); SV_MAIN.SV_UserinfoChanged(cl); break; case Defines.clc_move: if (move_issued) { return; } move_issued = true; checksumIndex = Globals.net_message.readcount; checksum = MSG.ReadByte(Globals.net_message); lastframe = MSG.ReadLong(Globals.net_message); if (lastframe != cl.lastframe) { cl.lastframe = lastframe; if (cl.lastframe > 0) { cl.frame_latency[cl.lastframe & (Defines.LATENCY_COUNTS - 1)] = SV_INIT.svs.realtime - cl.frames[cl.lastframe & Defines.UPDATE_MASK].senttime; } } nullcmd = new usercmd_t(); MSG.ReadDeltaUsercmd(Globals.net_message, nullcmd, oldest); MSG.ReadDeltaUsercmd(Globals.net_message, oldest, oldcmd); MSG.ReadDeltaUsercmd(Globals.net_message, oldcmd, newcmd); if (cl.state != Defines.cs_spawned) { cl.lastframe = -1; break; } calculatedChecksum = Com.BlockSequenceCRCByte(Globals.net_message.data, checksumIndex + 1, Globals.net_message.readcount - checksumIndex - 1, cl.netchan.incoming_sequence); if ((calculatedChecksum & 0xff) != checksum) { Com.DPrintf("Failed command checksum for " + cl.name + " (" + calculatedChecksum + " != " + checksum + ")/" + cl.netchan.incoming_sequence + "\\n"); return; } if (0 == SV_MAIN.sv_paused.value) { net_drop = cl.netchan.dropped; if (net_drop < 20) { while (net_drop > 2) { SV_ClientThink(cl, cl.lastcmd); net_drop--; } if (net_drop > 1) { SV_ClientThink(cl, oldest); } if (net_drop > 0) { SV_ClientThink(cl, oldcmd); } } SV_ClientThink(cl, newcmd); } cl.lastcmd.Set(newcmd); break; case Defines.clc_stringcmd: s = MSG.ReadString(Globals.net_message); if (++stringCmdCount < SV_USER.MAX_STRINGCMDS) { SV_ExecuteUserCommand(s); } if (cl.state == Defines.cs_zombie) { return; } break; } } }