예제 #1
0
/*
=================
CL_SendCmd_Async
=================
*/
void CL_SendCmd_Async (void)
{
	sizebuf_t	buf;
	byte		data[128];
	int			i;
	usercmd_t	*cmd, *oldcmd;
	usercmd_t	nullcmd;
	int			checksumIndex;

	// clear buffer
	memset (&buf, 0, sizeof(buf));

	// build a command even if not connected

	// save this command off for prediction
	i = cls.netchan.outgoing_sequence & (CMD_BACKUP-1);
	cmd = &cl.cmds[i];
	cl.cmd_time[i] = cls.realtime;	// for netgraph ping calculation

	CL_FinalizeCmd ();

	cl.cmd = *cmd;

	if (cls.state == ca_disconnected || cls.state == ca_connecting)
		return;

	if (cls.state == ca_connected)
	{
		if (cls.netchan.message.cursize	|| curtime - cls.netchan.last_sent > 1000 )
			Netchan_Transmit (&cls.netchan, 0, buf.data);	
		return;
	}

	// send a userinfo update if needed
	if (userinfo_modified)
	{
		CL_FixUpGender ();
		userinfo_modified = false;
		MSG_WriteByte (&cls.netchan.message, clc_userinfo);
		MSG_WriteString (&cls.netchan.message, Cvar_Userinfo() );
	}

	SZ_Init (&buf, data, sizeof(data));

	// Knightmare- removed this, put ESC-only substitute in keys.c
	/*if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop 
		&& cls.realtime - cl.cinematictime > 1000)
	{	// skip the rest of the cinematic
		SCR_FinishCinematic ();
	}*/

	// begin a client move command
	MSG_WriteByte (&buf, clc_move);

	// save the position for a checksum byte
	checksumIndex = buf.cursize;
	MSG_WriteByte (&buf, 0);

	// let the server know what the last frame we
	// got was, so the next message can be delta compressed
	if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting)
		MSG_WriteLong (&buf, -1);	// no compression
	else
		MSG_WriteLong (&buf, cl.frame.serverframe);

	// send this and the previous cmds in the message, so
	// if the last packet was dropped, it can be recovered
	i = (cls.netchan.outgoing_sequence-2) & (CMD_BACKUP-1);
	cmd = &cl.cmds[i];
	memset (&nullcmd, 0, sizeof(nullcmd));
	MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd);
	oldcmd = cmd;

	i = (cls.netchan.outgoing_sequence-1) & (CMD_BACKUP-1);
	cmd = &cl.cmds[i];
	MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);
	oldcmd = cmd;

	i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP-1);
	cmd = &cl.cmds[i];
	MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);

	// calculate a checksum over the move commands
	buf.data[checksumIndex] = COM_BlockSequenceCRCByte(
		buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
		cls.netchan.outgoing_sequence);

	//
	// deliver the message
	//
	Netchan_Transmit (&cls.netchan, buf.cursize, buf.data);

	// Init the current cmd buffer and clear it
	cmd = &cl.cmds[ cls.netchan.outgoing_sequence & (CMD_BACKUP-1) ];
	memset(cmd, 0, sizeof(*cmd));
}
예제 #2
0
void CL_SendCmd(void)
{
  sizebuf_t buf;
  byte data[128];
  int i;
  usercmd_t *cmd, *oldcmd;
  usercmd_t nullcmd;
  int checksumIndex;

  memset(&buf, 0, sizeof(buf));

  /* save this command off for prediction */
  i = cls.netchan.outgoing_sequence & (CMD_BACKUP - 1);
  cmd = &cl.cmds[i];
  cl.cmd_time[i] = cls.realtime; /* for netgraph ping calculation */

  CL_FinalizeCmd();

  cl.cmd = *cmd;

  if ((cls.state == ca_disconnected) || (cls.state == ca_connecting)) {
    return;
  }

  if (cls.state == ca_connected) {
    if (cls.netchan.message.cursize || (curtime - cls.netchan.last_sent > 1000)) {
      Netchan_Transmit(&cls.netchan, 0, buf.data);
    }

    return;
  }

  /* send a userinfo update if needed */
  if (userinfo_modified) {
    CL_FixUpGender();
    userinfo_modified = false;
    MSG_WriteByte(&cls.netchan.message, clc_userinfo);
    MSG_WriteString(&cls.netchan.message, Cvar_Userinfo());
  }

  SZ_Init(&buf, data, sizeof(data));

  /* begin a client move command */
  MSG_WriteByte(&buf, clc_move);

  /* save the position for a checksum byte */
  checksumIndex = buf.cursize;
  MSG_WriteByte(&buf, 0);

  /* let the server know what the last frame we
     got was, so the next message can be delta
     compressed */
  if (cl_nodelta->value || !cl.frame.valid) {
    MSG_WriteLong(&buf, -1); /* no compression */
  } else {
    MSG_WriteLong(&buf, cl.frame.serverframe);
  }

  /* send this and the previous cmds in the message, so
     if the last packet was dropped, it can be recovered */
  i = (cls.netchan.outgoing_sequence - 2) & (CMD_BACKUP - 1);
  cmd = &cl.cmds[i];
  memset(&nullcmd, 0, sizeof(nullcmd));
  MSG_WriteDeltaUsercmd(&buf, &nullcmd, cmd);
  oldcmd = cmd;

  i = (cls.netchan.outgoing_sequence - 1) & (CMD_BACKUP - 1);
  cmd = &cl.cmds[i];
  MSG_WriteDeltaUsercmd(&buf, oldcmd, cmd);
  oldcmd = cmd;

  i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP - 1);
  cmd = &cl.cmds[i];
  MSG_WriteDeltaUsercmd(&buf, oldcmd, cmd);

  /* calculate a checksum over the move commands */
  buf.data[checksumIndex] = COM_BlockSequenceCRCByte(buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
                                                     cls.netchan.outgoing_sequence);

  /* deliver the message */
  Netchan_Transmit(&cls.netchan, buf.cursize, buf.data);

  /* Reinit the current cmd buffer */
  cmd = &cl.cmds[cls.netchan.outgoing_sequence & (CMD_BACKUP - 1)];
  memset(cmd, 0, sizeof(*cmd));
}