//[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;
// 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;
// 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)
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;
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);
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;
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
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;
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);