void EXT_FUNC MSG_ReadUsercmd_api(usercmd_t *to, usercmd_t *from) { MSG_ReadUsercmd(to, from); }
/* =================== SV_ExecuteClientMessage The current net_message is parsed for the given client =================== */ void SV_ExecuteClientMessage (client_t *cl) { int c; const char *s; usercmd_t oldest, oldcmd, newcmd; client_frame_t *frame; vec3_t o; // calc ping time frame = &cl->frames[cl->netchan.incoming_acknowledged & UPDATE_MASK]; frame->ping_time = realtime - frame->senttime; // make sure the reply sequence number matches the incoming // sequence number if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence) cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence; else cl->send_message = false; // don't reply, sequences have slipped // save time for ping calculations cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].senttime = realtime; cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].ping_time = -1; host_client = cl; sv_player = host_client->edict; // mark time so clients will know how much to predict // other players cl->localtime = sv.time; cl->delta_sequence = -1; // no delta unless requested while (1) { if (msg_badread) { Con_Printf ("%s: badread\n", __thisfunc__); SV_DropClient (cl); return; } c = MSG_ReadByte (); if (c == -1) break; switch (c) { default: Con_Printf ("%s: unknown command char\n", __thisfunc__); SV_DropClient (cl); return; case clc_nop: break; case clc_delta: cl->delta_sequence = MSG_ReadByte (); break; case clc_move: MSG_ReadUsercmd (&oldest, false); MSG_ReadUsercmd (&oldcmd, false); MSG_ReadUsercmd (&newcmd, true); if ( cl->state != cs_spawned ) break; SV_PreRunCmd(); if (net_drop < 20) { while (net_drop > 2) { SV_RunCmd (&cl->lastcmd); net_drop--; } if (net_drop > 1) SV_RunCmd (&oldest); if (net_drop > 0) SV_RunCmd (&oldcmd); } SV_RunCmd (&newcmd); SV_PostRunCmd(); cl->lastcmd = newcmd; cl->lastcmd.buttons = 0; // avoid multiple fires on lag break; case clc_stringcmd: s = MSG_ReadString (); SV_ExecuteUserCommand (s); break; case clc_tmove: o[0] = MSG_ReadCoord(); o[1] = MSG_ReadCoord(); o[2] = MSG_ReadCoord(); // only allowed by spectators if (host_client->spectator) { VectorCopy(o, sv_player->v.origin); SV_LinkEdict(sv_player, false); } break; case clc_inv_select: cl->edict->v.inventory = MSG_ReadByte(); break; case clc_get_effect: c = MSG_ReadByte(); if (sv.Effects[c].type) { Con_Printf("Getting effect %d\n",(int)c); SV_SendEffect(&host_client->netchan.message, c); } break; } } }