1.Client sends a message with protocol "clc_move" (#define clc_move 2) to tell server that he has to run movement code.
2.the server-side engine will call SV_ParseMove, SV_ParseMove will call SV_RunCmd for multiple times.
3.SV_RunCmd will call itself recusive recursively for multiple times.
4.SV_RunCmd will call FM_CmdStart, FM_PlayerPreThink, FM_PlayerPostThink and call "PM_Move" to run PlayerMove code then finally call FM_CmdEnd in SV_RunCmd.
5.if it's called from SV_ParseMove for more than once, or recursively, the gpGlobals->time will be the same in the later. so you can compare the current gpGlobals->time with last saved gpGlobals->time and wait until gpGlobals->time changed.
example:
PHP Code:
new Float:g_PlayerCmdTime[33];
new Float:g_PlayerUpdateRate[33];
public FM_CmdStart(index)
{
new Float:curtime = get_gametime();
if(curtime > g_PlayerCmdTime[player_index])
{
g_PlayerUpdateRate[player_index] = curtime - g_PlayerCmdTime[player_index]
g_PlayerCmdTime[player_index] = curtime;
}
}
if g_PlayerUpdateRate[player_index] is less than 10.0 / 1000.0 (10ms) for more than 5 secs, this player is likely to be a cheater who is changing the game speed.