X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=protocol.c;h=ba7cb8122b1d04e9101cefa4f600a1fffc0df05a;hb=f792149bc8fc42556c2fcf2f9c8521de9d735468;hp=7ae6db28d62ee4b4a34a9b365538f5bea4a73455;hpb=a2335e296b76dd3477a80f8beeeedaf3e042c876;p=xonotic%2Fdarkplaces.git diff --git a/protocol.c b/protocol.c index 7ae6db28..ba7cb812 100644 --- a/protocol.c +++ b/protocol.c @@ -1,7 +1,7 @@ #include "quakedef.h" -// this is 80 bytes +// this is 88 bytes (must match entity_state_t in protocol.h) entity_state_t defaultstate = { // ! means this is not sent to client @@ -10,6 +10,7 @@ entity_state_t defaultstate = {0,0,0},//float angles[3]; 0,//int number; // entity number this state is for 0,//int effects; + 0,//unsigned int customizeentityforclient; // ! 0,//unsigned short modelindex; 0,//unsigned short frame; 0,//unsigned short tagentity; @@ -32,12 +33,12 @@ entity_state_t defaultstate = 0,//unsigned char tagindex; {32, 32, 32},//unsigned char colormod[3]; // padding to a multiple of 8 bytes (to align the double time) - {0,0}//unsigned char unused[2]; // ! + {0,0,0,0,0,0}//unsigned char unused[6]; // ! }; // LordHavoc: I own protocol ranges 96, 97, 3500-3599 -struct +struct protocolversioninfo_s { int number; const char *name; @@ -63,7 +64,7 @@ protocolversion_t Protocol_EnumForName(const char *s) int i; for (i = 1;protocolversioninfo[i].name;i++) if (!strcasecmp(s, protocolversioninfo[i].name)) - return i; + return (protocolversion_t)i; return PROTOCOL_UNKNOWN; } @@ -77,7 +78,7 @@ protocolversion_t Protocol_EnumForNumber(int n) int i; for (i = 1;protocolversioninfo[i].name;i++) if (protocolversioninfo[i].number == n) - return i; + return (protocolversion_t)i; return PROTOCOL_UNKNOWN; } @@ -102,7 +103,7 @@ void Protocol_Names(char *buffer, size_t buffersize) // keep track of quake entities because they need to be killed if they get stale int cl_lastquakeentity = 0; -qbyte cl_isquakeentity[MAX_EDICTS]; +unsigned char cl_isquakeentity[MAX_EDICTS]; void EntityFrameQuake_ReadEntity(int bits) { @@ -125,9 +126,9 @@ void EntityFrameQuake_ReadEntity(int bits) num = MSG_ReadByte (); if (num >= MAX_EDICTS) - Host_Error("EntityFrameQuake_ReadEntity: entity number (%i) >= MAX_EDICTS (%i)\n", num, MAX_EDICTS); + Host_Error("EntityFrameQuake_ReadEntity: entity number (%i) >= MAX_EDICTS (%i)", num, MAX_EDICTS); if (num < 1) - Host_Error("EntityFrameQuake_ReadEntity: invalid entity number (%i)\n", num); + Host_Error("EntityFrameQuake_ReadEntity: invalid entity number (%i)", num); if (cl_num_entities <= num) { @@ -172,7 +173,7 @@ void EntityFrameQuake_ReadEntity(int bits) if (bits & U_EFFECTS2) s.effects = (s.effects & 0x00FF) | (MSG_ReadByte() << 8); if (bits & U_GLOWSIZE) s.glowsize = MSG_ReadByte(); if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte(); - if (bits & U_COLORMOD) {int c = MSG_ReadByte();s.colormod[0] = (qbyte)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (qbyte)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (qbyte)((c & 3) * (32.0f / 3.0f));} + if (bits & U_COLORMOD) {int c = MSG_ReadByte();s.colormod[0] = (unsigned char)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (unsigned char)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (unsigned char)((c & 3) * (32.0f / 3.0f));} if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL; if (bits & U_FRAME2) s.frame = (s.frame & 0x00FF) | (MSG_ReadByte() << 8); if (bits & U_MODEL2) s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte() << 8); @@ -208,7 +209,7 @@ void EntityFrameQuake_ReadEntity(int bits) } if (msg_badread) - Host_Error("EntityFrameQuake_ReadEntity: read error\n"); + Host_Error("EntityFrameQuake_ReadEntity: read error"); } void EntityFrameQuake_ISeeDeadEntities(void) @@ -238,13 +239,145 @@ void EntityFrameQuake_ISeeDeadEntities(void) } } +static mempool_t *sv2csqc = NULL; +int csqc_clent = 0; +sizebuf_t *sv2csqcbuf = NULL; +static unsigned char *sv2csqcents_version[64]; + +void EntityFrameCSQC_ClearVersions (void) +{ + if(sv2csqc) + { + Mem_FreePool(&sv2csqc); + sv2csqc = NULL; + } + memset(sv2csqcents_version, 0, 64*sizeof(unsigned char *)); +} + +void EntityFrameCSQC_InitClientVersions (int client, qboolean clear) +{ + if(!sv2csqc) + sv2csqc = Mem_AllocPool("SV2CSQC", 0, NULL); + if(sv2csqcents_version[client]) + { + Mem_Free(sv2csqcents_version[client]); + sv2csqcents_version[client] = NULL; + } + sv2csqcents_version[client] = Mem_Alloc(sv2csqc, MAX_EDICTS); + memset(sv2csqcents_version[client], 0, MAX_EDICTS); +} + +//[515]: we use only one array per-client for SendEntity feature +void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int numstates, const entity_state_t *states) +{ + sizebuf_t buf; + unsigned char data[2048]; + const entity_state_t *s; + unsigned short i, t, t2, t0; + prvm_eval_t *val, *val2; + int csqcents = 0; + + if(!eval_SendEntity || !eval_Version) + return; + --csqc_clent; + if(!sv2csqcents_version[csqc_clent]) + EntityFrameCSQC_InitClientVersions(csqc_clent, false); + + for (csqcents = i = 0, s = states;i < numstates;i++, s++) + { + //[515]: entities remove + if(i+1 >= numstates) + t2 = prog->num_edicts; + else + t2 = states[i+1].number; + if(!i) + { + t0 = 1; + t2 = s->number; + } + else + t0 = s->number+1; + for(t=t0; tactive) +// continue; + val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_SendEntity); + if(val->function) + { + val2 = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_Version); + if(sv2csqcents_version[csqc_clent][s->number] == (unsigned char)val2->_float) + continue; + if(!csqcents) + { + csqcents = 1; + memset(&buf, 0, sizeof(buf)); + buf.data = data; + buf.maxsize = sizeof(data); + sv2csqcbuf = &buf; + SZ_Clear(&buf); + MSG_WriteByte(&buf, svc_csqcentities); + } + if((unsigned char)val2->_float == 0) + val2->_float = 1; + MSG_WriteShort(&buf, s->number); + ((int *)prog->globals.generic)[OFS_PARM0] = csqc_clent+1; + prog->globals.server->self = s->number; + PRVM_ExecuteProgram(val->function, "Null SendEntity\n"); + if(!prog->globals.generic[OFS_RETURN]) + { + buf.cursize -= 2; + if(sv2csqcents_version[csqc_clent][s->number]) + { + sv2csqcents_version[csqc_clent][s->number] = 0; + MSG_WriteShort(&buf, (unsigned short)s->number | 0x8000); + csqcents++; + } + } + else + { + sv2csqcents_version[csqc_clent][s->number] = (unsigned char)val2->_float; + csqcents++; + } + if (msg->cursize + buf.cursize > msg->maxsize) + break; + } + } + if(csqcents) + { + if(csqcents > 1) + { + MSG_WriteShort(&buf, 0); + SZ_Write(msg, buf.data, buf.cursize); + } + sv2csqcbuf = NULL; + } +} + void EntityFrameQuake_WriteFrame(sizebuf_t *msg, int numstates, const entity_state_t *states) { const entity_state_t *s; entity_state_t baseline; int i, bits; sizebuf_t buf; - qbyte data[128]; + unsigned char data[128]; + prvm_eval_t *val; // prepare the buffer memset(&buf, 0, sizeof(buf)); @@ -253,6 +386,10 @@ void EntityFrameQuake_WriteFrame(sizebuf_t *msg, int numstates, const entity_sta for (i = 0, s = states;i < numstates;i++, s++) { + val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_SendEntity); + if(val && val->function) + continue; + // prepare the buffer SZ_Clear(&buf); @@ -397,11 +534,11 @@ int EntityState_DeltaBits(const entity_state_t *o, const entity_state_t *n) bits |= E_ORIGIN2; if (fabs(n->origin[2] - o->origin[2]) > (1.0f / 256.0f)) bits |= E_ORIGIN3; - if ((qbyte) (n->angles[0] * (256.0f / 360.0f)) != (qbyte) (o->angles[0] * (256.0f / 360.0f))) + if ((unsigned char) (n->angles[0] * (256.0f / 360.0f)) != (unsigned char) (o->angles[0] * (256.0f / 360.0f))) bits |= E_ANGLE1; - if ((qbyte) (n->angles[1] * (256.0f / 360.0f)) != (qbyte) (o->angles[1] * (256.0f / 360.0f))) + if ((unsigned char) (n->angles[1] * (256.0f / 360.0f)) != (unsigned char) (o->angles[1] * (256.0f / 360.0f))) bits |= E_ANGLE2; - if ((qbyte) (n->angles[2] * (256.0f / 360.0f)) != (qbyte) (o->angles[2] * (256.0f / 360.0f))) + if ((unsigned char) (n->angles[2] * (256.0f / 360.0f)) != (unsigned char) (o->angles[2] * (256.0f / 360.0f))) bits |= E_ANGLE3; if ((n->modelindex ^ o->modelindex) & 0x00FF) bits |= E_MODEL1; @@ -754,7 +891,7 @@ void EntityState_ReadFields(entity_state_t *e, unsigned int bits) // (client and server) allocates a new empty database entityframe_database_t *EntityFrame_AllocDatabase(mempool_t *mempool) { - return Mem_Alloc(mempool, sizeof(entityframe_database_t)); + return (entityframe_database_t *)Mem_Alloc(mempool, sizeof(entityframe_database_t)); } // (client and server) frees the database @@ -876,6 +1013,7 @@ void EntityFrame_WriteFrame(sizebuf_t *msg, entityframe_database_t *d, int numst entity_frame_t *o = &deltaframe; const entity_state_t *ent, *delta; vec3_t eye; + prvm_eval_t *val; d->latestframenum++; @@ -905,6 +1043,10 @@ void EntityFrame_WriteFrame(sizebuf_t *msg, entityframe_database_t *d, int numst { ent = states + i; number = ent->number; + + val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[number]), eval_SendEntity); + if(val && val->function) + continue; for (;onum < o->numentities && o->entitydata[onum].number < number;onum++) { // write remove message @@ -964,17 +1106,17 @@ void EntityFrame_CL_ReadFrame(void) while ((number = (unsigned short) MSG_ReadShort()) != 0xFFFF && !msg_badread) { if (msg_badread) - Host_Error("EntityFrame_Read: read error\n"); + Host_Error("EntityFrame_Read: read error"); removed = number & 0x8000; number &= 0x7FFF; if (number >= MAX_EDICTS) - Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)\n", number, MAX_EDICTS); + Host_Error("EntityFrame_Read: number (%i) >= MAX_EDICTS (%i)", number, MAX_EDICTS); // seek to entity, while copying any skipped entities (assume unchanged) while (old < oldend && old->number < number) { if (f->numentities >= MAX_ENTITY_DATABASE) - Host_Error("EntityFrame_Read: entity list too big\n"); + Host_Error("EntityFrame_Read: entity list too big"); f->entitydata[f->numentities] = *old++; f->entitydata[f->numentities++].time = cl.mtime[0]; } @@ -988,7 +1130,7 @@ void EntityFrame_CL_ReadFrame(void) else { if (f->numentities >= MAX_ENTITY_DATABASE) - Host_Error("EntityFrame_Read: entity list too big\n"); + Host_Error("EntityFrame_Read: entity list too big"); // reserve this slot e = f->entitydata + f->numentities++; @@ -1020,13 +1162,13 @@ void EntityFrame_CL_ReadFrame(void) while (old < oldend) { if (f->numentities >= MAX_ENTITY_DATABASE) - Host_Error("EntityFrame_Read: entity list too big\n"); + Host_Error("EntityFrame_Read: entity list too big"); f->entitydata[f->numentities] = *old++; f->entitydata[f->numentities++].time = cl.mtime[0]; } EntityFrame_AddFrame(d, f->eye, f->framenum, f->numentities, f->entitydata); - memset(cl_entities_active, 0, cl_num_entities * sizeof(qbyte)); + memset(cl_entities_active, 0, cl_num_entities * sizeof(unsigned char)); number = 1; for (i = 0;i < f->numentities;i++) { @@ -1081,7 +1223,7 @@ entity_state_t *EntityFrame4_GetReferenceEntity(entityframe4_database_t *d, int int oldmax = d->maxreferenceentities; entity_state_t *oldentity = d->referenceentity; d->maxreferenceentities = (number + 15) & ~7; - d->referenceentity = Mem_Alloc(d->mempool, d->maxreferenceentities * sizeof(*d->referenceentity)); + d->referenceentity = (entity_state_t *)Mem_Alloc(d->mempool, d->maxreferenceentities * sizeof(*d->referenceentity)); if (oldentity) { memcpy(d->referenceentity, oldentity, oldmax * sizeof(*d->referenceentity)); @@ -1104,7 +1246,7 @@ void EntityFrame4_AddCommitEntity(entityframe4_database_t *d, const entity_state { entity_state_t *oldentity = d->currentcommit->entity; d->currentcommit->maxentities += 8; - d->currentcommit->entity = Mem_Alloc(d->mempool, d->currentcommit->maxentities * sizeof(*d->currentcommit->entity)); + d->currentcommit->entity = (entity_state_t *)Mem_Alloc(d->mempool, d->currentcommit->maxentities * sizeof(*d->currentcommit->entity)); if (oldentity) { memcpy(d->currentcommit->entity, oldentity, d->currentcommit->numentities * sizeof(*d->currentcommit->entity)); @@ -1117,7 +1259,7 @@ void EntityFrame4_AddCommitEntity(entityframe4_database_t *d, const entity_state entityframe4_database_t *EntityFrame4_AllocDatabase(mempool_t *pool) { entityframe4_database_t *d; - d = Mem_Alloc(pool, sizeof(*d)); + d = (entityframe4_database_t *)Mem_Alloc(pool, sizeof(*d)); d->mempool = pool; EntityFrame4_ResetDatabase(d); return d; @@ -1346,7 +1488,8 @@ void EntityFrame4_WriteFrame(sizebuf_t *msg, entityframe4_database_t *d, int num entity_state_t inactiveentitystate; int i, n, startnumber; sizebuf_t buf; - qbyte data[128]; + unsigned char data[128]; + prvm_eval_t *val; // if there isn't enough space to accomplish anything, skip it if (msg->cursize + 24 > msg->maxsize) @@ -1391,6 +1534,9 @@ void EntityFrame4_WriteFrame(sizebuf_t *msg, entityframe4_database_t *d, int num d->currententitynumber = 1; for (i = 0, n = startnumber;n < prog->max_edicts;n++) { + val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[n]), eval_SendEntity); + if(val && val->function) + continue; // find the old state to delta from e = EntityFrame4_GetReferenceEntity(d, n); // prepare the buffer @@ -1448,7 +1594,7 @@ void EntityFrame4_WriteFrame(sizebuf_t *msg, entityframe4_database_t *d, int num entityframe5_database_t *EntityFrame5_AllocDatabase(mempool_t *pool) { entityframe5_database_t *d; - d = Mem_Alloc(pool, sizeof(*d)); + d = (entityframe5_database_t *)Mem_Alloc(pool, sizeof(*d)); EntityFrame5_ResetDatabase(d); return d; } @@ -1475,27 +1621,27 @@ void EntityFrame5_ExpandEdicts(entityframe5_database_t *d, int newmax) { if (d->maxedicts < newmax) { - qbyte *data; + unsigned char *data; int oldmaxedicts = d->maxedicts; int *olddeltabits = d->deltabits; - qbyte *oldpriorities = d->priorities; + unsigned char *oldpriorities = d->priorities; int *oldupdateframenum = d->updateframenum; entity_state_t *oldstates = d->states; - qbyte *oldvisiblebits = d->visiblebits; + unsigned char *oldvisiblebits = d->visiblebits; d->maxedicts = newmax; - data = Mem_Alloc(sv_mempool, d->maxedicts * sizeof(int) + d->maxedicts * sizeof(qbyte) + d->maxedicts * sizeof(int) + d->maxedicts * sizeof(entity_state_t) + (d->maxedicts+7)/8 * sizeof(qbyte)); - d->deltabits = (void *)data;data += d->maxedicts * sizeof(int); - d->priorities = (void *)data;data += d->maxedicts * sizeof(qbyte); - d->updateframenum = (void *)data;data += d->maxedicts * sizeof(int); - d->states = (void *)data;data += d->maxedicts * sizeof(entity_state_t); - d->visiblebits = (void *)data;data += (d->maxedicts+7)/8 * sizeof(qbyte); + data = (unsigned char *)Mem_Alloc(sv_mempool, d->maxedicts * sizeof(int) + d->maxedicts * sizeof(unsigned char) + d->maxedicts * sizeof(int) + d->maxedicts * sizeof(entity_state_t) + (d->maxedicts+7)/8 * sizeof(unsigned char)); + d->deltabits = (int *)data;data += d->maxedicts * sizeof(int); + d->priorities = (unsigned char *)data;data += d->maxedicts * sizeof(unsigned char); + d->updateframenum = (int *)data;data += d->maxedicts * sizeof(int); + d->states = (entity_state_t *)data;data += d->maxedicts * sizeof(entity_state_t); + d->visiblebits = (unsigned char *)data;data += (d->maxedicts+7)/8 * sizeof(unsigned char); if (oldmaxedicts) { memcpy(d->deltabits, olddeltabits, oldmaxedicts * sizeof(int)); - memcpy(d->priorities, oldpriorities, oldmaxedicts * sizeof(qbyte)); + memcpy(d->priorities, oldpriorities, oldmaxedicts * sizeof(unsigned char)); memcpy(d->updateframenum, oldupdateframenum, oldmaxedicts * sizeof(int)); memcpy(d->states, oldstates, oldmaxedicts * sizeof(entity_state_t)); - memcpy(d->visiblebits, oldvisiblebits, (oldmaxedicts+7)/8 * sizeof(qbyte)); + memcpy(d->visiblebits, oldvisiblebits, (oldmaxedicts+7)/8 * sizeof(unsigned char)); // the previous buffers were a single allocation, so just one free Mem_Free(olddeltabits); } @@ -1557,6 +1703,12 @@ int EntityState5_Priority(entityframe5_database_t *d, int stateindex) void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbits, sizebuf_t *msg) { unsigned int bits = 0; + + prvm_eval_t *val; + val = PRVM_GETEDICTFIELDVALUE((&prog->edicts[s->number]), eval_SendEntity); + if(val && val->function) + return; + if (!s->active) MSG_WriteShort(msg, number | 0x8000); else @@ -1953,7 +2105,7 @@ void EntityFrame5_LostFrame(entityframe5_database_t *d, int framenum) int i, j, k, l, bits; entityframe5_changestate_t *s, *s2; entityframe5_packetlog_t *p, *p2; - qbyte statsdeltabits[(MAX_CL_STATS+7)/8]; + unsigned char statsdeltabits[(MAX_CL_STATS+7)/8]; // scan for packets that were lost for (i = 0, p = d->packetlog;i < ENTITYFRAME5_MAXPACKETLOGS;i++, p++) { @@ -2022,7 +2174,7 @@ void EntityFrame5_WriteFrame(sizebuf_t *msg, entityframe5_database_t *d, int num const entity_state_t *n; int i, num, l, framenum, packetlognumber, priority; sizebuf_t buf; - qbyte data[128]; + unsigned char data[128]; entityframe5_packetlog_t *packetlog; if (prog->max_edicts > d->maxedicts)