- fixed net_packetlog to use Con_Printf when there's no logfile open,

rather than a stdout hack (which had problems with buffering)
- actually parse net_deltapacketentities
- print offset within net_{,delta}packetentities blocks for each
  entity
- fix indenting in Log_Delta
- fix off-by-one for packet offset printing
- fix a miss-parsing of svc_deltapacketentities
  (MAX_PACKET_ENTITIES does NOT include U_REMOVE entities)
- remove "full update" handling for CL_ParseDeltaPacketEntities, since
  that only happens with svc_packetentities
This commit is contained in:
Adam Olsen 2001-10-29 00:32:16 +00:00
parent 3ce8029f74
commit 36b8256b3a
4 changed files with 151 additions and 145 deletions

View File

@ -185,15 +185,17 @@ typedef struct net_svc_delta_s
typedef struct net_svc_packetentities_s
{
int num;
net_svc_delta_t vars[MAX_PACKET_ENTITIES + 1];
int numwords, numdeltas;
unsigned short words[MAX_EDICTS];
entity_state_t deltas[MAX_PACKET_ENTITIES];
} net_svc_packetentities_t;
typedef struct net_svc_deltapacketentities_s
{
int num;
int numwords, numdeltas;
byte from;
net_svc_delta_t vars[MAX_PACKET_ENTITIES + 1];
unsigned short words[MAX_EDICTS];
entity_state_t deltas[MAX_PACKET_ENTITIES];
} net_svc_deltapacketentities_t;
qboolean NET_SVC_Print_Parse (net_svc_print_t *block, msg_t *msg);

View File

@ -194,11 +194,11 @@ CL_ParsePacketEntities (void)
return;
}
for (index = 0; block.vars[index].word; index++) {
if (block.vars[index].word & U_REMOVE) {
for (index = 0; block.words[index]; index++) {
if (block.words[index] & U_REMOVE) {
cl.validsequence = 0;
Host_NetError ("CL_ParsePacketEntities: WARNING: U_REMOVE "
"on full update\n");
Host_NetError ("CL_ParsePacketEntities: U_REMOVE on full "
"update\n");
return;
}
@ -208,11 +208,11 @@ CL_ParsePacketEntities (void)
return;
}
newp->entities[index] = cl_baselines[block.vars[index].word & 511];
CL_EntityState_Copy (&block.vars[index].state,
newp->entities[index] = cl_baselines[block.words[index] & 511];
CL_EntityState_Copy (&block.deltas[index],
&newp->entities[index],
block.vars[index].state.flags);
newp->entities[index].number = block.vars[index].state.number;
block.deltas[index].flags);
newp->entities[index].number = block.deltas[index].number;
if (newp->entities[index].modelindex >= MAX_MODELS) {
Host_NetError ("CL_ParsePacketEntities: modelindex %i >= "
"MAX_MODELS", newp->entities[index].modelindex);
@ -233,11 +233,11 @@ CL_ParsePacketEntities (void)
void
CL_ParseDeltaPacketEntities ()
{
int i;
byte from;
int oldindex, newindex, newnum, oldnum, oldpacket, newpacket;
packet_entities_t *oldp, *newp, dummy;
qboolean full = false;
int oldindex = 0, newindex = 0;
int wordindex = 0, deltaindex = 0;
int oldnum, newnum;
int oldpacket, newpacket;
packet_entities_t *oldp, *newp;
net_svc_deltapacketentities_t block;
if (NET_SVC_DeltaPacketEntities_Parse (&block, net_message)) {
@ -249,14 +249,16 @@ CL_ParseDeltaPacketEntities ()
newp = &cl.frames[newpacket].packet_entities;
cl.frames[newpacket].invalid = false;
from = block.from;
oldpacket = cl.frames[newpacket].delta_sequence;
if (oldpacket == -1) {
Host_NetError ("Cl_ParseDeltaPacketEntities: invalid "
"delta_sequence\n");
return;
}
if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK))
if ((block.from & UPDATE_MASK) != (oldpacket & UPDATE_MASK))
Con_DPrintf ("CL_ParseDeltaPacketEntities: WARNING: from mismatch\n");
if (oldpacket != -1) {
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
// we can't use this, it is too old
Con_DPrintf ("FlushEntityPacket\n");
@ -265,36 +267,20 @@ CL_ParseDeltaPacketEntities ()
}
cl.validsequence = cls.netchan.incoming_sequence;
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
} else { // a full update that we can start delta compressing from now
oldp = &dummy;
dummy.num_entities = 0;
cl.validsequence = cls.netchan.incoming_sequence;
full = true;
Host_NetError ("Full update in CL_ParseDeltaPacketEntities\n");
return;
}
oldindex = 0;
newindex = 0;
newp->num_entities = 0;
for (i = 0; block.vars[i].word; i++) {
newnum = block.vars[i].word & 511;
for (; block.words[wordindex];) {
newnum = block.words[wordindex] & 511;
oldnum = oldindex >= oldp->num_entities ? 9999 :
oldp->entities[oldindex].number;
while (newnum > oldnum) {
// if (newnum > oldnum) {
if (full) {
Con_Printf ("CL_ParseDeltaPacketEntities: WARNING: "
"oldcopy on full update");
return;
}
while (newnum > oldnum) { // copy one of the old entities
// over to the new packet unchanged
// Con_Printf ("copy %i\n", oldnum);
// copy one of the old entities over to the new packet unchanged
if (newindex >= MAX_PACKET_ENTITIES) {
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
"MAX_PACKET_ENTITIES (2nd)");
"MAX_PACKET_ENTITIES (1st)");
return;
}
newp->entities[newindex] = oldp->entities[oldindex];
@ -306,53 +292,48 @@ CL_ParseDeltaPacketEntities ()
if (newnum < oldnum) { // new from baseline
// Con_Printf ("baseline %i\n", newnum);
if (block.vars[i].word & U_REMOVE) {
if (full) {
cl.validsequence = 0;
Host_NetError ("CL_ParseDeltaPacketEntities: "
"U_REMOVE on full update\n");
return;
}
if (block.words[wordindex] & U_REMOVE) {
wordindex++;
continue;
}
if (newindex >= MAX_PACKET_ENTITIES) {
Host_NetError ("CL_ParseDeltaPacketEntities: newindex >= "
"MAX_PACKET_ENTITIES (3rd)");
"MAX_PACKET_ENTITIES (2nd)");
return;
}
newp->entities[newindex] = cl_baselines[newnum];
CL_EntityState_Copy (&block.vars[i].state,
CL_EntityState_Copy (&block.deltas[deltaindex],
&newp->entities[newindex],
block.vars[i].state.flags);
newp->entities[newindex].number = block.vars[i].state.number;
block.deltas[deltaindex].flags);
newp->entities[newindex].number
= block.deltas[deltaindex].number;
if (newp->entities[newindex].modelindex >= MAX_MODELS) {
Host_NetError ("CL_ParsePacketEntities: modelindex %i >= "
"MAX_MODELS",
newp->entities[newindex].modelindex);
return;
}
wordindex++;
deltaindex++;
newindex++;
continue;
}
if (newnum == oldnum) { // delta from previous
if (full) {
cl.validsequence = 0;
Con_Printf ("WARNING: delta on full update");
}
if (block.vars[i].word & U_REMOVE) { // Clear the entity
entity_t *ent = &cl_packet_ents[newnum];
memset (ent, 0, sizeof (entity_t));
// Con_Printf ("delta %i\n", newnum);
if (block.words[wordindex] & U_REMOVE) { // Clear the entity
memset (&cl_packet_ents[newnum], 0, sizeof (entity_t));
wordindex++;
oldindex++;
continue;
}
// Con_Printf ("delta %i\n", newnum);
newp->entities[newindex] = oldp->entities[oldindex];
CL_EntityState_Copy (&block.vars[i].state,
CL_EntityState_Copy (&block.deltas[deltaindex],
&newp->entities[newindex],
block.vars[i].state.flags);
newp->entities[newindex].number = block.vars[i].state.number;
block.deltas[deltaindex].flags);
newp->entities[newindex].number
= block.deltas[deltaindex].number;
if (newp->entities[newindex].modelindex >= MAX_MODELS) {
Host_NetError ("CL_ParsePacketEntities: modelindex %i >= "
"MAX_MODELS",
@ -360,6 +341,8 @@ CL_ParseDeltaPacketEntities ()
return;
}
wordindex++;
deltaindex++;
newindex++;
oldindex++;
}

View File

@ -171,7 +171,6 @@ const char *clc_string[] = {
#define svc_particle 18 // [vec3] <variable>
#define svc_signonnum 25 // [byte] used for the signon
// sequence
static VFile *_stdout;
static VFile *Net_PacketLog;
static const char **Net_sound_precache;
static sizebuf_t _packet;
@ -193,12 +192,11 @@ Net_LogPrintf (char *fmt, ...)
vsnprintf (text, sizeof (text), fmt, argptr);
va_end (argptr);
if (!Net_PacketLog)
Net_PacketLog = _stdout;
if (Net_PacketLog) {
Qprintf (Net_PacketLog, "%s", text);
Qflush (Net_PacketLog);
if (Net_PacketLog == _stdout)
Net_PacketLog = NULL;
} else
Con_Printf ("%s", text);
}
int
@ -308,30 +306,43 @@ Log_Outgoing_Packet (const char *p, int len)
return;
}
void
qboolean
Log_Delta(int bits)
{
entity_state_t to;
int i;
Net_LogPrintf ("\n\t");
Net_LogPrintf ("\n\t<%06x> ", MSG_GetReadCount (&packet) - 2);
if (!bits) {
Net_LogPrintf ("End");
return 1;
}
// set everything to the state we are delta'ing from
to.number = bits & 511;
bits &= ~511;
Net_LogPrintf ("Ent: %d", to.number);
if (bits & U_REMOVE)
Net_LogPrintf (" U_REMOVE");
if (bits & U_MOREBITS) { // read in the low order bits
i = MSG_ReadByte (&packet);
bits |= i;
Net_LogPrintf (" U_MOREBITS");
}
// LordHavoc: Endy neglected to mark this as being part of the QSG
// version 2 stuff...
if (bits & U_EXTEND1) {
bits |= MSG_ReadByte (&packet) << 16;
if (bits & U_EXTEND2)
Net_LogPrintf (" U_EXTEND1");
if (bits & U_EXTEND2) {
bits |= MSG_ReadByte (&packet) << 24;
Net_LogPrintf (" U_EXTEND2");
}
}
to.flags = bits;
@ -390,7 +401,7 @@ Log_Delta(int bits)
Net_LogPrintf(" Uframe2: %d", ((to.frame & 0xFF) | (MSG_ReadByte (&packet) << 8)));
// Ender (QSG - End)
return;
return 0;
}
@ -438,7 +449,8 @@ Parse_Server_Packet ()
if (c == -1)
break;
// Net_LogPrintf("\n<%ld,%ld> ",seq1 & 0x7FFFFFFF,seq2 & 0x7FFFFFFF);
Net_LogPrintf ("<%06x> [0x%02x] ", MSG_GetReadCount (&packet), c);
Net_LogPrintf ("<%06x> [0x%02x] ",
MSG_GetReadCount (&packet) - 1, c);
if (c < 53)
Net_LogPrintf ("%s: ", svc_string[c]);
@ -794,21 +806,19 @@ Parse_Server_Packet ()
else
Net_LogPrintf ("\n\t*End of sound list*");
break;
case svc_deltapacketentities:
Net_LogPrintf ("from: %d", MSG_ReadByte (&packet));
// intentional fallthrough
case svc_packetentities:
while (1) {
mask1 = (unsigned short) MSG_ReadShort(&packet);
if (packet.badread) {
Net_LogPrintf ("Badread\n");
Net_LogPrintf (" Badread\n");
return;
}
if (!mask1) break;
if (mask1 & U_REMOVE) Net_LogPrintf("UREMOVE ");
Log_Delta(mask1);
}
if (Log_Delta(mask1))
break;
case svc_deltapacketentities:
Net_LogPrintf ("idx: %d", MSG_ReadByte (&packet));
return;
}
break;
case svc_maxspeed:
Net_LogPrintf ("%f", MSG_ReadFloat (&packet));
@ -958,7 +968,7 @@ Net_PacketLog_f (cvar_t *var)
void
Net_PacketLog_Zap_f (void)
{
if (Net_PacketLog && Net_PacketLog != _stdout) {
if (Net_PacketLog) {
Con_Printf ("truncating packet logfile: %s\n", "qfpacket.log");
Qseek (Net_PacketLog, 0, 0);
Qwrite (Net_PacketLog, 0, 0);
@ -976,8 +986,6 @@ Net_Log_Init (const char **sound_precache)
{
Net_sound_precache = sound_precache;
_stdout = Qdopen (1, "wt"); // create a QFile of stdout
net_packetlog = Cvar_Get ("net_packetlog", "0", CVAR_NONE, Net_PacketLog_f,
"enable/disable packet logging");

View File

@ -405,22 +405,13 @@ NET_SVC_Soundlist_Parse (net_svc_soundlist_t *block, msg_t *msg)
}
// this is a sub-block, not a real block
qboolean
NET_SVC_Delta_Parse (net_svc_delta_t *subblock, msg_t *msg)
void
NET_SVC_Delta_Parse (entity_state_t *es, unsigned int bits, msg_t *msg)
{
unsigned int bits; // bytes of bits: [EXT2][EXT1][ORIG][MORE]
entity_state_t *es;
subblock->word = bits = (unsigned short) MSG_ReadShort (msg);
if (!bits || msg->badread)
return true;
es = &subblock->state;
// bytes of bits: [EXT2][EXT1][ORIG][MORE]
es->number = bits & 511;
bits &= ~511;
// if (bits & U_REMOVE)
// return false;
es->frame = 0;
es->effects = 0;
@ -484,22 +475,32 @@ NET_SVC_Delta_Parse (net_svc_delta_t *subblock, msg_t *msg)
if (bits & U_SOLID) {
// FIXME
}
return false;
}
qboolean
NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block, msg_t *msg)
{
int i;
int word, delta;
unsigned short bits;
for (i = 0; i < MAX_PACKET_ENTITIES; i++)
if (NET_SVC_Delta_Parse (&block->vars[i], msg))
for (word = 0, delta = 0; !msg->badread; word++) {
if (word >= MAX_EDICTS)
return 1; // FIXME: differentiate from short packet
bits = (unsigned short) MSG_ReadShort (msg);
block->words[word] = bits;
if (!bits)
break;
if (!(bits & U_REMOVE)) {
if (delta >= MAX_PACKET_ENTITIES)
return 1;
NET_SVC_Delta_Parse (&block->deltas[delta], bits, msg);
delta++;
}
}
block->vars[i].word = 0;
block->num = i;
block->numwords = word;
block->numdeltas = delta;
return msg->badread;
}
@ -508,15 +509,27 @@ qboolean
NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
msg_t *msg)
{
int i;
int word, delta;
unsigned short bits;
block->from = MSG_ReadByte (msg);
for (i = 0; i < MAX_PACKET_ENTITIES; i++)
if (NET_SVC_Delta_Parse (&block->vars[i], msg))
for (word = 0, delta = 0; !msg->badread; word++) {
if (word >= MAX_EDICTS)
return 1; // FIXME: differentiate from short packet
bits = (unsigned short) MSG_ReadShort (msg);
block->words[word] = bits;
if (!bits)
break;
if (!(bits & U_REMOVE)) {
if (delta >= MAX_PACKET_ENTITIES)
return 1;
NET_SVC_Delta_Parse (&block->deltas[delta], bits, msg);
delta++;
}
}
block->vars[i].word = 0;
block->num = i;
block->numwords = word;
block->numdeltas = delta;
return msg->badread;
}