/* ================= 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)); }
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)); }