Example #1
0
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;
		}
	}
}