]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - protocol.c
protocol: Stub DP8 protocol
[xonotic/darkplaces.git] / protocol.c
index be3d0d39d49734d19c46a6e0c8dbd67d4fa33d4f..5685675562e0e51096425f306fcbf741129f09f2 100644 (file)
@@ -47,6 +47,7 @@ struct protocolversioninfo_s
 }
 protocolversioninfo[] =
 {
+       { 3505, PROTOCOL_DARKPLACES8 , "DP8"},
        { 3504, PROTOCOL_DARKPLACES7 , "DP7"},
        { 3503, PROTOCOL_DARKPLACES6 , "DP6"},
        { 3502, PROTOCOL_DARKPLACES5 , "DP5"},
@@ -191,375 +192,3 @@ void Protocol_WriteStatsReliable(void)
                }
        }
 }
-
-entity_state_t *EntityFrame4_GetReferenceEntity(entityframe4_database_t *d, int number)
-{
-       if (d->maxreferenceentities <= number)
-       {
-               int oldmax = d->maxreferenceentities;
-               entity_state_t *oldentity = d->referenceentity;
-               d->maxreferenceentities = (number + 15) & ~7;
-               d->referenceentity = (entity_state_t *)Mem_Alloc(d->mempool, d->maxreferenceentities * sizeof(*d->referenceentity));
-               if (oldentity)
-               {
-                       memcpy(d->referenceentity, oldentity, oldmax * sizeof(*d->referenceentity));
-                       Mem_Free(oldentity);
-               }
-               // clear the newly created entities
-               for (;oldmax < d->maxreferenceentities;oldmax++)
-               {
-                       d->referenceentity[oldmax] = defaultstate;
-                       d->referenceentity[oldmax].number = oldmax;
-               }
-       }
-       return d->referenceentity + number;
-}
-
-void EntityFrame4_AddCommitEntity(entityframe4_database_t *d, const entity_state_t *s)
-{
-       // resize commit's entity list if full
-       if (d->currentcommit->maxentities <= d->currentcommit->numentities)
-       {
-               entity_state_t *oldentity = d->currentcommit->entity;
-               d->currentcommit->maxentities += 8;
-               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));
-                       Mem_Free(oldentity);
-               }
-       }
-       d->currentcommit->entity[d->currentcommit->numentities++] = *s;
-}
-
-entityframe4_database_t *EntityFrame4_AllocDatabase(mempool_t *pool)
-{
-       entityframe4_database_t *d;
-       d = (entityframe4_database_t *)Mem_Alloc(pool, sizeof(*d));
-       d->mempool = pool;
-       EntityFrame4_ResetDatabase(d);
-       return d;
-}
-
-void EntityFrame4_FreeDatabase(entityframe4_database_t *d)
-{
-       int i;
-       for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-               if (d->commit[i].entity)
-                       Mem_Free(d->commit[i].entity);
-       if (d->referenceentity)
-               Mem_Free(d->referenceentity);
-       Mem_Free(d);
-}
-
-void EntityFrame4_ResetDatabase(entityframe4_database_t *d)
-{
-       int i;
-       d->referenceframenum = -1;
-       for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-               d->commit[i].numentities = 0;
-       for (i = 0;i < d->maxreferenceentities;i++)
-               d->referenceentity[i] = defaultstate;
-}
-
-int EntityFrame4_AckFrame(entityframe4_database_t *d, int framenum, int servermode)
-{
-       int i, j, found;
-       entity_database4_commit_t *commit;
-       if (framenum == -1)
-       {
-               // reset reference, but leave commits alone
-               d->referenceframenum = -1;
-               for (i = 0;i < d->maxreferenceentities;i++)
-               {
-                       d->referenceentity[i] = defaultstate;
-               // if this is the server, remove commits
-                       for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++)
-                               commit->numentities = 0;
-               }
-               found = true;
-       }
-       else if (d->referenceframenum == framenum)
-               found = true;
-       else
-       {
-               found = false;
-               for (i = 0, commit = d->commit;i < MAX_ENTITY_HISTORY;i++, commit++)
-               {
-                       if (commit->numentities && commit->framenum <= framenum)
-                       {
-                               if (commit->framenum == framenum)
-                               {
-                                       found = true;
-                                       d->referenceframenum = framenum;
-                                       if (developer_networkentities.integer >= 3)
-                                       {
-                                               for (j = 0;j < commit->numentities;j++)
-                                               {
-                                                       entity_state_t *s = EntityFrame4_GetReferenceEntity(d, commit->entity[j].number);
-                                                       if (commit->entity[j].active != s->active)
-                                                       {
-                                                               if (commit->entity[j].active == ACTIVE_NETWORK)
-                                                                       Con_Printf("commit entity %i has become active (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex);
-                                                               else
-                                                                       Con_Printf("commit entity %i has become inactive (modelindex %i)\n", commit->entity[j].number, commit->entity[j].modelindex);
-                                                       }
-                                                       *s = commit->entity[j];
-                                               }
-                                       }
-                                       else
-                                               for (j = 0;j < commit->numentities;j++)
-                                                       *EntityFrame4_GetReferenceEntity(d, commit->entity[j].number) = commit->entity[j];
-                               }
-                               commit->numentities = 0;
-                       }
-               }
-       }
-       if (developer_networkentities.integer >= 1)
-       {
-               Con_Printf("ack ref:%i database updated to: ref:%i commits:", framenum, d->referenceframenum);
-               for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-                       if (d->commit[i].numentities)
-                               Con_Printf(" %i", d->commit[i].framenum);
-               Con_Print("\n");
-       }
-       return found;
-}
-
-void EntityFrame4_CL_ReadFrame(void)
-{
-       int i, n, cnumber, referenceframenum, framenum, enumber, done, stopnumber, skip = false;
-       entity_state_t *s;
-       entityframe4_database_t *d;
-       if (!cl.entitydatabase4)
-               cl.entitydatabase4 = EntityFrame4_AllocDatabase(cls.levelmempool);
-       d = cl.entitydatabase4;
-       // read the number of the frame this refers to
-       referenceframenum = MSG_ReadLong(&cl_message);
-       // read the number of this frame
-       framenum = MSG_ReadLong(&cl_message);
-       CL_NewFrameReceived(framenum);
-       // read the start number
-       enumber = (unsigned short) MSG_ReadShort(&cl_message);
-       if (developer_networkentities.integer >= 10)
-       {
-               Con_Printf("recv svc_entities num:%i ref:%i database: ref:%i commits:", framenum, referenceframenum, d->referenceframenum);
-               for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-                       if (d->commit[i].numentities)
-                               Con_Printf(" %i", d->commit[i].framenum);
-               Con_Print("\n");
-       }
-       if (!EntityFrame4_AckFrame(d, referenceframenum, false))
-       {
-               Con_Print("EntityFrame4_CL_ReadFrame: reference frame invalid (VERY BAD ERROR), this update will be skipped\n");
-               skip = true;
-       }
-       d->currentcommit = NULL;
-       for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-       {
-               if (!d->commit[i].numentities)
-               {
-                       d->currentcommit = d->commit + i;
-                       d->currentcommit->framenum = framenum;
-                       d->currentcommit->numentities = 0;
-               }
-       }
-       if (d->currentcommit == NULL)
-       {
-               Con_Printf("EntityFrame4_CL_ReadFrame: error while decoding frame %i: database full, reading but not storing this update\n", framenum);
-               skip = true;
-       }
-       done = false;
-       while (!done && !cl_message.badread)
-       {
-               // read the number of the modified entity
-               // (gaps will be copied unmodified)
-               n = (unsigned short)MSG_ReadShort(&cl_message);
-               if (n == 0x8000)
-               {
-                       // no more entities in this update, but we still need to copy the
-                       // rest of the reference entities (final gap)
-                       done = true;
-                       // read end of range number, then process normally
-                       n = (unsigned short)MSG_ReadShort(&cl_message);
-               }
-               // high bit means it's a remove message
-               cnumber = n & 0x7FFF;
-               // if this is a live entity we may need to expand the array
-               if (cl.num_entities <= cnumber && !(n & 0x8000))
-               {
-                       cl.num_entities = cnumber + 1;
-                       if (cnumber >= cl.max_entities)
-                               CL_ExpandEntities(cnumber);
-               }
-               // add one (the changed one) if not done
-               stopnumber = cnumber + !done;
-               // process entities in range from the last one to the changed one
-               for (;enumber < stopnumber;enumber++)
-               {
-                       if (skip || enumber >= cl.num_entities)
-                       {
-                               if (enumber == cnumber && (n & 0x8000) == 0)
-                               {
-                                       entity_state_t tempstate;
-                                       EntityState_ReadFields(&tempstate, EntityState_ReadExtendBits());
-                               }
-                               continue;
-                       }
-                       // slide the current into the previous slot
-                       cl.entities[enumber].state_previous = cl.entities[enumber].state_current;
-                       // copy a new current from reference database
-                       cl.entities[enumber].state_current = *EntityFrame4_GetReferenceEntity(d, enumber);
-                       s = &cl.entities[enumber].state_current;
-                       // if this is the one to modify, read more data...
-                       if (enumber == cnumber)
-                       {
-                               if (n & 0x8000)
-                               {
-                                       // simply removed
-                                       if (developer_networkentities.integer >= 2)
-                                               Con_Printf("entity %i: remove\n", enumber);
-                                       *s = defaultstate;
-                               }
-                               else
-                               {
-                                       // read the changes
-                                       if (developer_networkentities.integer >= 2)
-                                               Con_Printf("entity %i: update\n", enumber);
-                                       s->active = ACTIVE_NETWORK;
-                                       EntityState_ReadFields(s, EntityState_ReadExtendBits());
-                               }
-                       }
-                       else if (developer_networkentities.integer >= 4)
-                               Con_Printf("entity %i: copy\n", enumber);
-                       // set the cl.entities_active flag
-                       cl.entities_active[enumber] = (s->active == ACTIVE_NETWORK);
-                       // set the update time
-                       s->time = cl.mtime[0];
-                       // fix the number (it gets wiped occasionally by copying from defaultstate)
-                       s->number = enumber;
-                       // check if we need to update the lerp stuff
-                       if (s->active == ACTIVE_NETWORK)
-                               CL_MoveLerpEntityStates(&cl.entities[enumber]);
-                       // add this to the commit entry whether it is modified or not
-                       if (d->currentcommit)
-                               EntityFrame4_AddCommitEntity(d, &cl.entities[enumber].state_current);
-                       // print extra messages if desired
-                       if (developer_networkentities.integer >= 2 && cl.entities[enumber].state_current.active != cl.entities[enumber].state_previous.active)
-                       {
-                               if (cl.entities[enumber].state_current.active == ACTIVE_NETWORK)
-                                       Con_Printf("entity #%i has become active\n", enumber);
-                               else if (cl.entities[enumber].state_previous.active)
-                                       Con_Printf("entity #%i has become inactive\n", enumber);
-                       }
-               }
-       }
-       d->currentcommit = NULL;
-       if (skip)
-               EntityFrame4_ResetDatabase(d);
-}
-
-qboolean EntityFrame4_WriteFrame(sizebuf_t *msg, int maxsize, entityframe4_database_t *d, int numstates, const entity_state_t **states)
-{
-       prvm_prog_t *prog = SVVM_prog;
-       const entity_state_t *e, *s;
-       entity_state_t inactiveentitystate;
-       int i, n, startnumber;
-       sizebuf_t buf;
-       unsigned char data[128];
-
-       // if there isn't enough space to accomplish anything, skip it
-       if (msg->cursize + 24 > maxsize)
-               return false;
-
-       // prepare the buffer
-       memset(&buf, 0, sizeof(buf));
-       buf.data = data;
-       buf.maxsize = sizeof(data);
-
-       for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-               if (!d->commit[i].numentities)
-                       break;
-       // if commit buffer full, just don't bother writing an update this frame
-       if (i == MAX_ENTITY_HISTORY)
-               return false;
-       d->currentcommit = d->commit + i;
-
-       // this state's number gets played around with later
-       inactiveentitystate = defaultstate;
-
-       d->currentcommit->numentities = 0;
-       d->currentcommit->framenum = ++d->latestframenumber;
-       MSG_WriteByte(msg, svc_entities);
-       MSG_WriteLong(msg, d->referenceframenum);
-       MSG_WriteLong(msg, d->currentcommit->framenum);
-       if (developer_networkentities.integer >= 10)
-       {
-               Con_Printf("send svc_entities num:%i ref:%i (database: ref:%i commits:", d->currentcommit->framenum, d->referenceframenum, d->referenceframenum);
-               for (i = 0;i < MAX_ENTITY_HISTORY;i++)
-                       if (d->commit[i].numentities)
-                               Con_Printf(" %i", d->commit[i].framenum);
-               Con_Print(")\n");
-       }
-       if (d->currententitynumber >= prog->max_edicts)
-               startnumber = 1;
-       else
-               startnumber = bound(1, d->currententitynumber, prog->max_edicts - 1);
-       MSG_WriteShort(msg, startnumber);
-       // reset currententitynumber so if the loop does not break it we will
-       // start at beginning next frame (if it does break, it will set it)
-       d->currententitynumber = 1;
-       for (i = 0, n = startnumber;n < prog->max_edicts;n++)
-       {
-               if (PRVM_serveredictfunction((&prog->edicts[n]), SendEntity))
-                       continue;
-               // find the old state to delta from
-               e = EntityFrame4_GetReferenceEntity(d, n);
-               // prepare the buffer
-               SZ_Clear(&buf);
-               // entity exists, build an update (if empty there is no change)
-               // find the state in the list
-               for (;i < numstates && states[i]->number < n;i++);
-               // make the message
-               s = states[i];
-               if (s->number == n)
-               {
-                       // build the update
-                       EntityState_WriteUpdate(s, &buf, e);
-               }
-               else
-               {
-                       inactiveentitystate.number = n;
-                       s = &inactiveentitystate;
-                       if (e->active == ACTIVE_NETWORK)
-                       {
-                               // entity used to exist but doesn't anymore, send remove
-                               MSG_WriteShort(&buf, n | 0x8000);
-                       }
-               }
-               // if the commit is full, we're done this frame
-               if (msg->cursize + buf.cursize > maxsize - 4)
-               {
-                       // next frame we will continue where we left off
-                       break;
-               }
-               // add the entity to the commit
-               EntityFrame4_AddCommitEntity(d, s);
-               // if the message is empty, skip out now
-               if (buf.cursize)
-               {
-                       // write the message to the packet
-                       SZ_Write(msg, buf.data, buf.cursize);
-               }
-       }
-       d->currententitynumber = n;
-
-       // remove world message (invalid, and thus a good terminator)
-       MSG_WriteShort(msg, 0x8000);
-       // write the number of the end entity
-       MSG_WriteShort(msg, d->currententitynumber);
-       // just to be sure
-       d->currentcommit = NULL;
-
-       return true;
-}