From 48cc7d73007e1af022a596e475d922299564a850 Mon Sep 17 00:00:00 2001 From: divverent Date: Tue, 27 Jan 2009 21:47:55 +0000 Subject: [PATCH] attempt to fix csqc entity networking by not sending empty entity frames if no csqc entity was sent git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8676 d7cf8633-e32d-0410-b094-e92efae38249 --- protocol.c | 17 +++++++++++++---- protocol.h | 4 ++-- sv_main.c | 5 +++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/protocol.c b/protocol.c index d4931797..f57ff66a 100644 --- a/protocol.c +++ b/protocol.c @@ -430,7 +430,7 @@ static void EntityFrameCSQC_DeallocFrame(client_t *client, int framenum) //[515]: we use only one array per-client for SendEntity feature // TODO: add some handling for entity send priorities, to better deal with huge // amounts of csqc networked entities -void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, const entity_state_t *states, int framenum) +qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, const entity_state_t *states, int framenum) { int num, number, end, sendflags; qboolean sectionstarted = false; @@ -445,12 +445,12 @@ void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, con // if this server progs is not CSQC-aware, return early if(prog->fieldoffsets.SendEntity < 0 || prog->fieldoffsets.Version < 0) - return; + return false; // make sure there is enough room to store the svc_csqcentities byte, // the terminator (0x0000) and at least one entity update if (msg->cursize + 32 >= maxsize) - return; + return false; if (client->csqcnumedicts < prog->num_edicts) client->csqcnumedicts = prog->num_edicts; @@ -597,6 +597,8 @@ void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, con // if no single ent got added, remove the frame from the DB again, to allow // for a larger history EntityFrameCSQC_DeallocFrame(client, framenum); + + return sectionstarted; } void Protocol_UpdateClientStats(const int *stats) @@ -2495,7 +2497,7 @@ void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum) d->packetlog[i].packetnumber = 0; } -void EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int movesequence) +void EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int movesequence, qboolean need_empty) { const entity_state_t *n; int i, num, l, framenum, packetlognumber, priority; @@ -2618,16 +2620,23 @@ void EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_ MSG_WriteByte(msg, svc_updatestatubyte); MSG_WriteByte(msg, i); MSG_WriteByte(msg, host_client->stats[i]); + l = 1; } else { MSG_WriteByte(msg, svc_updatestat); MSG_WriteByte(msg, i); MSG_WriteLong(msg, host_client->stats[i]); + l = 1; } } } } + + // only send empty svc_entities frame if needed + if(!l && !need_empty) + return; + // write state updates if (developer_networkentities.integer >= 10) Con_Printf("send: svc_entities %i\n", framenum); diff --git a/protocol.h b/protocol.h index 2729eb57..1dd989b0 100644 --- a/protocol.h +++ b/protocol.h @@ -788,7 +788,7 @@ int EntityState5_DeltaBitsForState(entity_state_t *o, entity_state_t *n); void EntityFrame5_CL_ReadFrame(void); void EntityFrame5_LostFrame(entityframe5_database_t *d, int framenum); void EntityFrame5_AckFrame(entityframe5_database_t *d, int framenum); -void EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int movesequence); +void EntityFrame5_WriteFrame(sizebuf_t *msg, int maxsize, entityframe5_database_t *d, int numstates, const entity_state_t *states, int viewentnum, int movesequence, qboolean need_empty); extern cvar_t developer_networkentities; @@ -969,7 +969,7 @@ void EntityFrameQW_CL_ReadFrame(qboolean delta); struct client_s; void EntityFrameCSQC_LostFrame(struct client_s *client, int framenum); -void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, const entity_state_t *states, int framenum); +qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, const entity_state_t *states, int framenum); #endif diff --git a/sv_main.c b/sv_main.c index c35976fe..36f25a63 100644 --- a/sv_main.c +++ b/sv_main.c @@ -1401,6 +1401,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s) void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t *msg, int maxsize) { + qboolean need_empty = false; int i, numsendstates; entity_state_t *s; prvm_edict_t *camera; @@ -1448,12 +1449,12 @@ void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t * Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv.writeentitiestoclient_stats_totalentities, sv.writeentitiestoclient_stats_visibleentities, sv.writeentitiestoclient_stats_culled_pvs + sv.writeentitiestoclient_stats_culled_trace, sv.writeentitiestoclient_stats_culled_pvs, sv.writeentitiestoclient_stats_culled_trace); if(client->entitydatabase5) - EntityFrameCSQC_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates, client->entitydatabase5->latestframenum + 1); + need_empty = EntityFrameCSQC_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates, client->entitydatabase5->latestframenum + 1); else EntityFrameCSQC_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates, 0); if (client->entitydatabase5) - EntityFrame5_WriteFrame(msg, maxsize, client->entitydatabase5, numsendstates, sv.writeentitiestoclient_sendstates, client - svs.clients + 1, client->movesequence); + EntityFrame5_WriteFrame(msg, maxsize, client->entitydatabase5, numsendstates, sv.writeentitiestoclient_sendstates, client - svs.clients + 1, client->movesequence, need_empty); else if (client->entitydatabase4) { EntityFrame4_WriteFrame(msg, maxsize, client->entitydatabase4, numsendstates, sv.writeentitiestoclient_sendstates); -- 2.39.2