- convert svc_deltapacketentities

- add a Host_NetError that dumps a packet log and disconnects, and use
  it instead of Host_EndGame in most cases
- fix a couple multiply-defined vars
This commit is contained in:
Adam Olsen 2001-10-24 15:23:02 +00:00
parent 743bc5178b
commit dd19f7b500
15 changed files with 229 additions and 155 deletions

View file

@ -87,8 +87,6 @@ qboolean r_fov_greater_than_90;
entity_t r_worldentity;
mplane_t frustum[4];
// view origin
vec3_t vup, base_vup;
vec3_t vpn, base_vpn;

View file

@ -36,7 +36,6 @@ static const char rcsid[] =
#include "QF/model.h"
const int mod_lightmap_bytes = 1;
cvar_t *gl_sky_divide; // not used but needed for linking
void Mod_LoadBrushModel (model_t *mod, void *buffer);

View file

@ -37,7 +37,7 @@ void CL_EmitEntities (void);
void CL_ClearProjectiles (void);
void CL_ParseProjectiles (void);
void CL_ParsePacketEntities (void);
void CL_ParseDeltaPacketEntities (qboolean delta);
void CL_ParseDeltaPacketEntities ();
void CL_SetSolidEntities (void);
void CL_ParsePlayerinfo (void);
void CL_Ents_Init (void);

View file

@ -60,6 +60,7 @@ void Host_InitCommands (void);
void Host_Init (void);
void Host_Shutdown(void);
void Host_Error (const char *error, ...) __attribute__((format(printf,1,2)));
void Host_NetError (const char *error, ...) __attribute((format(printf,1,2)));
void Host_EndGame (const char *message, ...) __attribute__((format(printf,1,2)));
void Host_Frame (float time);
void Host_Quit_f (void);

View file

@ -131,10 +131,12 @@ void Netchan_AckPacket (netchan_t *chan);
qboolean Netchan_CanPacket (netchan_t *chan);
qboolean Netchan_CanReliable (netchan_t *chan);
extern int Net_Log_Init (const char **sound_precache);
extern void Log_Incoming_Packet (const char *p, int len);
extern void Log_Outgoing_Packet (const char *p, int len);
extern void Net_LogStop (void);
int Net_Log_Init (const char **sound_precache);
void Log_Incoming_Packet (const char *p, int len);
void Log_Outgoing_Packet (const char *p, int len);
void Net_LogStop (void);
void Analyze_Server_Packet (const byte *data, int len);
void Analyze_Client_Packet (const byte *data, int len);
extern struct cvar_s *net_packetlog;

View file

@ -177,15 +177,25 @@ typedef struct net_svc_soundlist_s
byte nextsound;
} net_svc_soundlist_t;
typedef struct net_svc_delta_s
{
unsigned short word;
entity_state_t state;
} net_svc_delta_t;
typedef struct net_svc_packetentities_s
{
int num;
struct {
unsigned short word;
entity_state_t state;
} vars[MAX_PACKET_ENTITIES];
net_svc_delta_t vars[MAX_PACKET_ENTITIES + 1];
} net_svc_packetentities_t;
typedef struct net_svc_deltapacketentities_s
{
int num;
byte from;
net_svc_delta_t vars[MAX_PACKET_ENTITIES + 1];
} net_svc_deltapacketentities_t;
qboolean NET_SVC_Print_Parse (net_svc_print_t *block, msg_t *msg);
qboolean NET_SVC_Damage_Parse (net_svc_damage_t *block, msg_t *msg);
qboolean NET_SVC_ServerData_Parse (net_svc_serverdata_t *block, msg_t *msg);
@ -207,5 +217,7 @@ qboolean NET_SVC_Modellist_Parse (net_svc_modellist_t *block, msg_t *msg);
qboolean NET_SVC_Soundlist_Parse (net_svc_soundlist_t *block, msg_t *msg);
qboolean NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block,
msg_t *msg);
qboolean NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
msg_t *msg);
#endif // NET_SVC_H

View file

@ -267,7 +267,7 @@ CL_GetDemoMessage (void)
// Con_Printf("read: %ld bytes\n", net_message->message->cursize);
if (net_message->message->cursize > MAX_MSGLEN)
// Sys_Error ("Demo message > MAX_MSGLEN");
Host_EndGame ("Demo message > MAX_MSGLEN");
Host_NetError ("Demo message > MAX_MSGLEN");
r = Qread (cls.demofile, net_message->message->data,
net_message->message->cursize);
if (r != net_message->message->cursize) {

View file

@ -298,7 +298,7 @@ FlushEntityPacket (void)
while (1) {
word = (unsigned short) MSG_ReadShort (net_message);
if (net_message->badread) { // something didn't parse right...
Host_EndGame ("msg_badread in packetentities");
Host_NetError ("msg_badread in packetentities");
return;
}
@ -325,7 +325,7 @@ CL_ParsePacketEntities (void)
newp->num_entities = 0;
if (NET_SVC_PacketEntities_Parse (&block, net_message)) {
Host_EndGame ("CL_ParsePacketEntities: Bad Read");
Host_NetError ("CL_ParsePacketEntities: Bad Read");
return;
}
@ -338,7 +338,7 @@ CL_ParsePacketEntities (void)
}
if (index >= MAX_PACKET_ENTITIES) {
Host_EndGame ("CL_ParsePacketEntities: index == "
Host_NetError ("CL_ParsePacketEntities: index == "
"MAX_PACKET_ENTITIES");
return;
}
@ -363,26 +363,30 @@ CL_ParsePacketEntities (void)
rest of the data stream.
*/
void
CL_ParseDeltaPacketEntities (qboolean delta)
CL_ParseDeltaPacketEntities ()
{
int i;
byte from;
int oldindex, newindex, newnum, oldnum, oldpacket, newpacket, word;
packet_entities_t *oldp, *newp, dummy;
qboolean full;
net_svc_deltapacketentities_t block;
if (NET_SVC_DeltaPacketEntities_Parse (&block, net_message)) {
Host_NetError ("CL_ParseDeltaPacketEntities: Bad Read");
return;
}
newpacket = cls.netchan.incoming_sequence & UPDATE_MASK;
newp = &cl.frames[newpacket].packet_entities;
cl.frames[newpacket].invalid = false;
if (delta) {
from = MSG_ReadByte (net_message);
from = block.from;
oldpacket = cl.frames[newpacket].delta_sequence;
if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK))
Con_DPrintf ("WARNING: from mismatch\n");
} else
oldpacket = -1;
full = false;
if (oldpacket != -1) {
@ -404,10 +408,10 @@ CL_ParseDeltaPacketEntities (qboolean delta)
newindex = 0;
newp->num_entities = 0;
while (1) {
word = (unsigned short) MSG_ReadShort (net_message);
for (i = 0;; i++) {
word = block.vars[i].word;
if (net_message->badread) { // something didn't parse right...
Host_EndGame ("msg_badread in packetentities");
Host_NetError ("msg_badread in packetentities");
return;
}
@ -415,8 +419,8 @@ CL_ParseDeltaPacketEntities (qboolean delta)
while (oldindex < oldp->num_entities) {
// Con_Printf ("copy %i\n", oldp->entities[oldindex].number);
if (newindex >= MAX_PACKET_ENTITIES) {
Host_EndGame ("CL_ParseDeltaPacketEntities: newindex == "
"MAX_PACKET_ENTITIES");
Host_NetError ("CL_ParseDeltaPacketEntities: newindex == "
"MAX_PACKET_ENTITIES (1st)");
return;
}
newp->entities[newindex] = oldp->entities[oldindex];
@ -430,16 +434,16 @@ CL_ParseDeltaPacketEntities (qboolean delta)
oldp->entities[oldindex].number;
while (newnum > oldnum) {
// if (newnum > oldnum) {
if (full) {
Con_Printf ("WARNING: oldcopy on full update");
FlushEntityPacket ();
return;
}
// Con_Printf ("copy %i\n", oldnum);
// copy one of the old entities over to the new packet unchanged
if (newindex >= MAX_PACKET_ENTITIES) {
Host_EndGame ("CL_ParseDeltaPacketEntities: newindex == "
"MAX_PACKET_ENTITIES");
Host_NetError ("CL_ParseDeltaPacketEntities: newindex == "
"MAX_PACKET_ENTITIES (2nd)");
return;
}
newp->entities[newindex] = oldp->entities[oldindex];
@ -455,19 +459,23 @@ CL_ParseDeltaPacketEntities (qboolean delta)
if (full) {
cl.validsequence = 0;
Con_Printf ("WARNING: U_REMOVE on full update\n");
FlushEntityPacket ();
return;
}
continue;
}
if (newindex >= MAX_PACKET_ENTITIES) {
Host_EndGame ("CL_ParseDeltaPacketEntities: newindex == "
"MAX_PACKET_ENTITIES");
Host_NetError ("CL_ParseDeltaPacketEntities: newindex == "
"MAX_PACKET_ENTITIES (3rd)");
return;
}
CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex],
word);
CL_EntityState_Copy (&cl_baselines[newnum],
&newp->entities[newindex],
~block.vars[i].state.flags);
CL_EntityState_Copy (&block.vars[i].state,
&newp->entities[newindex],
block.vars[i].state.flags);
newp->entities[newindex].number = block.vars[i].state.number;
newindex++;
continue;
}
@ -484,8 +492,13 @@ CL_ParseDeltaPacketEntities (qboolean delta)
continue;
}
// Con_Printf ("delta %i\n", newnum);
CL_ParseDelta (&oldp->entities[oldindex],
&newp->entities[newindex], word);
CL_EntityState_Copy (&oldp->entities[oldindex],
&newp->entities[newindex],
~block.vars[i].state.flags);
CL_EntityState_Copy (&block.vars[i].state,
&newp->entities[newindex],
block.vars[i].state.flags);
newp->entities[newindex].number = block.vars[i].state.number;
newindex++;
oldindex++;
}
@ -733,7 +746,7 @@ CL_ParsePlayerinfo (void)
if (block.playernum > MAX_CLIENTS)
// Sys_Error ("CL_ParsePlayerinfo: bad block.playernum");
Host_EndGame ("CL_ParsePlayerinfo: bad block.playernum");
Host_NetError ("CL_ParsePlayerinfo: bad block.playernum");
state = &cl.frames[parsecountmod].playerstate[block.playernum];

View file

@ -1309,6 +1309,31 @@ Host_EndGame (const char *message, ...)
longjmp (host_abort, 1);
}
/*
Host_NetError
Used for networking errors that disconnect, but don't exit the
client
*/
void
Host_NetError (const char *message, ...)
{
va_list argptr;
int old = 0;
old = net_packetlog->int_val;
if (net_packetlog->int_val)
Cvar_Set (net_packetlog, "0");
Log_Incoming_Packet (net_message->message->data,
net_message->message->cursize);
if (old)
Cvar_SetValue (net_packetlog, old);
va_start (argptr, message);
Host_EndGame (message, argptr);
va_end (argptr);
}
/*
Host_Error

View file

@ -445,7 +445,7 @@ CL_ParseDownload (void)
}
if (download.size <= 0) {
Host_EndGame ("Bad download block, size %d", download.size);
Host_NetError ("Bad download block, size %d", download.size);
}
// open the file if not opened yet
@ -662,7 +662,7 @@ CL_ParseServerData (void)
if (protover != PROTOCOL_VERSION &&
!(cls.demoplayback
&& (protover <= 26 && protover >= 28)))
Host_EndGame ("Server returned version %i, not %i\nYou probably "
Host_NetError ("Server returned version %i, not %i\nYou probably "
"need to upgrade.\nCheck http://www.quakeworld.net/",
protover, PROTOCOL_VERSION);
@ -759,7 +759,7 @@ CL_ParseSoundlist (void)
break;
numsounds++;
if (numsounds == MAX_SOUNDS)
Host_EndGame ("Server sent too many sound_precache");
Host_NetError ("Server sent too many sound_precache");
strcpy (cl.sound_name[numsounds], str);
}
@ -792,7 +792,7 @@ CL_ParseModellist (void)
break;
nummodels++;
if (nummodels == MAX_MODELS)
Host_EndGame ("Server sent too many model_precache");
Host_NetError ("Server sent too many model_precache");
strncpy (cl.model_name[nummodels], str, MAX_QPATH - 1);
cl.model_name[nummodels][MAX_QPATH - 1] = '\0';
@ -867,7 +867,7 @@ CL_ParseStatic (void)
NET_SVC_SpawnStatic_Parse (&block, net_message);
if (cl.num_statics >= MAX_STATIC_ENTITIES)
Host_EndGame ("Too many static entities");
Host_NetError ("Too many static entities");
ent = &cl_static_entities[cl.num_statics++];
CL_Init_Entity (ent);
@ -903,7 +903,7 @@ CL_ParseStartSoundPacket (void)
NET_SVC_Sound_Parse (&sound, net_message);
if (sound.entity > MAX_EDICTS)
Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", sound.entity);
Host_NetError ("CL_ParseStartSoundPacket: ent = %i", sound.entity);
S_StartSound (sound.entity, sound.channel,
cl.sound_precache[sound.sound_num], sound.position,
@ -978,8 +978,8 @@ CL_ParseUpdateUserInfo (void)
NET_SVC_UpdateUserInfo_Parse (&updateuserinfo, net_message);
if (updateuserinfo.slot >= MAX_CLIENTS)
Host_EndGame
("CL_ParseServerMessage: svc_updateuserinfo > MAX_SCOREBOARD");
Host_NetError ("CL_ParseServerMessage: svc_updateuserinfo > "
"MAX_SCOREBOARD");
player = &cl.players[updateuserinfo.slot];
player->userid = updateuserinfo.userid;
@ -999,7 +999,7 @@ CL_SetInfo (void)
NET_SVC_SetInfo_Parse (&setinfo, net_message);
if (setinfo.slot >= MAX_CLIENTS)
Host_EndGame ("CL_ParseServerMessage: svc_setinfo > MAX_SCOREBOARD");
Host_NetError ("CL_ParseServerMessage: svc_setinfo > MAX_SCOREBOARD");
player = &cl.players[setinfo.slot];
@ -1039,7 +1039,7 @@ CL_SetStat (int stat, int value)
if (stat < 0 || stat >= MAX_CL_STATS)
// Sys_Error ("CL_SetStat: %i is invalid", stat);
Host_EndGame ("CL_SetStat: %i is invalid", stat);
Host_NetError ("CL_SetStat: %i is invalid", stat);
Sbar_Changed ();
@ -1116,7 +1116,7 @@ CL_ParseServerMessage (void)
// parse the message
while (1) {
if (net_message->badread) {
Host_EndGame ("CL_ParseServerMessage: Bad server message");
Host_NetError ("CL_ParseServerMessage: Bad server message");
break;
}
@ -1134,8 +1134,8 @@ CL_ParseServerMessage (void)
// other commands
switch (cmd) {
default:
Host_EndGame
("CL_ParseServerMessage: Illegible server message");
Host_NetError ("CL_ParseServerMessage: Illegible "
"server message");
break;
case svc_nop:
@ -1185,7 +1185,7 @@ CL_ParseServerMessage (void)
i = MSG_ReadByte (net_message);
if (i >= MAX_LIGHTSTYLES)
// Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES");
Host_NetError ("svc_lightstyle > MAX_LIGHTSTYLES");
strncpy (r_lightstyle[i].map, MSG_ReadString (net_message),
sizeof (r_lightstyle[i].map) - 1);
r_lightstyle[i].map[sizeof (r_lightstyle[i].map) - 1] = 0;
@ -1205,7 +1205,7 @@ CL_ParseServerMessage (void)
Sbar_Changed ();
i = MSG_ReadByte (net_message);
if (i >= MAX_CLIENTS)
Host_EndGame ("CL_ParseServerMessage: svc_updatefrags > "
Host_NetError ("CL_ParseServerMessage: svc_updatefrags > "
"MAX_SCOREBOARD");
cl.players[i].frags = MSG_ReadShort (net_message);
break;
@ -1213,7 +1213,7 @@ CL_ParseServerMessage (void)
case svc_updateping:
i = MSG_ReadByte (net_message);
if (i >= MAX_CLIENTS)
Host_EndGame ("CL_ParseServerMessage: svc_updateping > "
Host_NetError ("CL_ParseServerMessage: svc_updateping > "
"MAX_SCOREBOARD");
cl.players[i].ping = MSG_ReadShort (net_message);
break;
@ -1221,7 +1221,7 @@ CL_ParseServerMessage (void)
case svc_updatepl:
i = MSG_ReadByte (net_message);
if (i >= MAX_CLIENTS)
Host_EndGame ("CL_ParseServerMessage: svc_updatepl > "
Host_NetError ("CL_ParseServerMessage: svc_updatepl > "
"MAX_SCOREBOARD");
cl.players[i].pl = MSG_ReadByte (net_message);
break;
@ -1230,7 +1230,7 @@ CL_ParseServerMessage (void)
// time is sent over as seconds ago
i = MSG_ReadByte (net_message);
if (i >= MAX_CLIENTS)
Host_EndGame ("CL_ParseServerMessage: svc_updateentertime "
Host_NetError ("CL_ParseServerMessage: svc_updateentertime "
"> MAX_SCOREBOARD");
cl.players[i].entertime = realtime - MSG_ReadFloat
(net_message);
@ -1360,7 +1360,7 @@ CL_ParseServerMessage (void)
break;
case svc_deltapacketentities:
CL_ParseDeltaPacketEntities (true);
CL_ParseDeltaPacketEntities ();
break;
case svc_maxspeed:

View file

@ -199,7 +199,7 @@ CL_NewTranslation (int slot, skin_t *skin)
player_info_t *player;
if (slot > MAX_CLIENTS)
Host_EndGame ("CL_NewTranslation: slot > MAX_CLIENTS");
Host_NetError ("CL_NewTranslation: slot > MAX_CLIENTS");
player = &cl.players[slot];
if (!player->name[0])

View file

@ -67,8 +67,8 @@ extern qboolean is_server;
int Net_LogStart (const char *fname);
void Analyze_Server_Packet (const byte * data, int len);
void Analyze_Client_Packet (const byte * data, int len);
void Analyze_Server_Packet (const byte *data, int len);
void Analyze_Client_Packet (const byte *data, int len);
void Parse_Server_Packet (void);
void Parse_Client_Packet (void);
void Net_LogStop (void);
@ -193,11 +193,13 @@ Net_LogPrintf (char *fmt, ...)
va_start (argptr, fmt);
vsnprintf (text, sizeof (text), fmt, argptr);
va_end (argptr);
if (!Net_PacketLog)
return;
if (!Net_PacketLog)
Net_PacketLog = _stdout;
Qprintf (Net_PacketLog, "%s", text);
Qflush (Net_PacketLog);
if (Net_PacketLog == _stdout)
Net_PacketLog = NULL;
}
int
@ -395,16 +397,12 @@ Log_Delta(int bits)
void
Analyze_Server_Packet (const byte * data, int len)
Analyze_Server_Packet (const byte *data, int len)
{
if (!Net_PacketLog)
Net_PacketLog = _stdout;
packet.message->data = (byte*)data;
packet.message->cursize = len;
MSG_BeginReading (&packet);
Parse_Server_Packet ();
if (Net_PacketLog == _stdout)
Net_PacketLog = NULL;
}
@ -842,16 +840,12 @@ Parse_Server_Packet ()
}
void
Analyze_Client_Packet (const byte * data, int len)
Analyze_Client_Packet (const byte *data, int len)
{
if (!Net_PacketLog)
Net_PacketLog = _stdout;
packet.message->data = (byte*)data;
packet.message->cursize = len;
MSG_BeginReading (&packet);
Parse_Client_Packet ();
if (Net_PacketLog == _stdout)
Net_PacketLog = NULL;
}
void

View file

@ -400,21 +400,23 @@ NET_SVC_Soundlist_Parse (net_svc_soundlist_t *block, msg_t *msg)
return msg->badread;
}
// this is a sub-block, not a real block
qboolean
NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block, msg_t *msg)
NET_SVC_Delta_Parse (net_svc_delta_t *subblock, msg_t *msg)
{
int i;
unsigned int bits; // bytes of bits: [EXT2][EXT1][ORIG][MORE]
entity_state_t *es;
for (i = 0; i < MAX_PACKET_ENTITIES; i++) {
block->vars[i].word = bits = (unsigned short) MSG_ReadShort (msg);
subblock->word = bits = (unsigned short) MSG_ReadShort (msg);
if (!bits || msg->badread)
break;
es = &block->vars[i].state;
return true;
es = &subblock->state;
es->number = bits & 511;
bits &= ~511;
// if (bits & U_REMOVE)
// return false;
es->frame = 0;
es->effects = 0;
@ -478,7 +480,37 @@ NET_SVC_PacketEntities_Parse (net_svc_packetentities_t *block, 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;
for (i = 0; i < MAX_PACKET_ENTITIES; i++)
if (NET_SVC_Delta_Parse (&block->vars[i], msg))
break;
block->vars[i].word = 0;
block->num = i;
return msg->badread;
}
qboolean
NET_SVC_DeltaPacketEntities_Parse (net_svc_deltapacketentities_t *block,
msg_t *msg)
{
int i;
block->from = MSG_ReadByte (msg);
for (i = 0; i < MAX_PACKET_ENTITIES; i++)
if (NET_SVC_Delta_Parse (&block->vars[i], msg))
break;
block->vars[i].word = 0;
block->num = i;

View file

@ -36,7 +36,6 @@ static const char rcsid[] =
#include "QF/model.h"
const int mod_lightmap_bytes = 1;
cvar_t *gl_sky_divide; // not used but needed for linking
void Mod_LoadBrushModel (model_t *mod, void *buffer);

View file

@ -783,7 +783,6 @@ SV_SendClientMessages (void)
// if the reliable message overflowed, drop the client
if (c->netchan.message.overflowed) {
int i;
extern void Analyze_Server_Packet (byte *data, int len);
byte *data = Hunk_TempAlloc (MAX_MSGLEN + 8);
memset (data, 0, 8);