예제 #1
0
        /*
        ==================
        CL_DeltaEntity

        Parses deltas from the given base and adds the resulting entity
        to the current frame
        ==================
        */
        void DeltaEntity(NetBuffer msg, clSnapshot_t frame, int newnum, Common.entityState_t old, bool unchanged)
        {
            // save the parsed entity state into the big circular buffer so
            // it can be used as the source for a later delta
            Common.entityState_t state = cl.parseEntities[cl.parseEntitiesNum & 2047];
            if (unchanged)
                state = old;
            else
                Net.Instance.MSG_ReadDeltaEntity(msg, ref old, ref state, newnum);

            cl.parseEntities[cl.parseEntitiesNum & 2047] = state;

            if (state.number == 1023)
                return; // entity was delta removed

            cl.parseEntitiesNum++;
            frame.numEntities++;
        }
예제 #2
0
 public clientActive()
 {
     gamestate = new gameState_t();
     gamestate.data = new Dictionary<int, string>();
     for (int i = 0; i < parseEntities.Length; i++)
     {
         parseEntities[i] = new Common.entityState_t();
     }
     for (int i = 0; i < entityBaselines.Length; i++)
     {
         entityBaselines[i] = new Common.entityState_t();
     }
     for (int i = 0; i < snapshots.Length; i++)
     {
         snapshots[i] = new clSnapshot_t();
     }
 }
예제 #3
0
        /*
        ================
        CL_ParseSnapshot

        If the snapshot is parsed properly, it will be copied to
        cl.snap and saved in cl.snapshots[].  If the snapshot is invalid
        for any reason, no changes to the state will be made at all.
        ================
        */
        void ParseSnapshot(NetBuffer msg)
        {
            // read in the new snapshot to a temporary buffer
            // we will only copy to cl.snap if it is valid
            clSnapshot_t newsnap = new clSnapshot_t();
            clSnapshot_t old;

            // we will have read any new server commands in this
            // message before we got to svc_snapshot
            newsnap.ServerCommandNum = clc.serverCommandSequence;
            newsnap.serverTime = msg.ReadInt32();
            newsnap.messageNum = clc.serverMessageSequence;

            int deltaNum = msg.ReadByte();

            if (deltaNum <= 0)
            {
                newsnap.deltaNum = -1;
            }
            else
                newsnap.deltaNum = newsnap.messageNum - deltaNum;
            newsnap.snapFlags = msg.ReadByte();

            // If the frame is delta compressed from data that we
            // no longer have available, we must suck up the rest of
            // the frame, but not use it, then ask for a non-compressed
            // message
            if (newsnap.deltaNum <= 0)
            {
                newsnap.valid = true;   // uncompressed frame
                old = null;
            }
            else
            {
                old = cl.snapshots[newsnap.deltaNum & 31];
                if (!old.valid)
                {
                    // should never happen
                    Common.Instance.WriteLine("ParseSnapshot: Delta from invalid frame (not supposed to happen!).");
                }
                else if (old.messageNum != newsnap.deltaNum)
                {
                    // The frame that the server did the delta from
                    // is too old, so we can't reconstruct it properly.
                    Common.Instance.WriteLine("ParseSnapshot: Delta frame too old.");
                }
                else if (cl.parseEntitiesNum - old.parseEntitiesNum > 2048 - 128)
                {
                    Common.Instance.WriteLine("ParseSnapshot: Delta parseEntitiesNum too old");
                }
                else
                    newsnap.valid = true;   // valid delta parse
            }

            // read areamask
            int len = msg.ReadByte();
            newsnap.areamask = msg.ReadBytes(32);
            // read playerinfo
            if (old != null)
            {
                Net.ReadDeltaPlayerstate(msg, old.ps, newsnap.ps);
            }
            else
                Net.ReadDeltaPlayerstate(msg, null, newsnap.ps);

            // read packet entities
            ParsePacketEntities(msg, old, newsnap);

            // if not valid, dump the entire thing now that it has
            // been properly read
            if (!newsnap.valid)
                return;

            // clear the valid flags of any snapshots between the last
            // received and this one, so if there was a dropped packet
            // it won't look like something valid to delta from next
            // time we wrap around in the buffer
            int oldMessageNum = cl.snap.messageNum + 1;
            if (newsnap.messageNum - oldMessageNum >= 32)
            {
                oldMessageNum = newsnap.messageNum - 31;
            }
            for (; oldMessageNum < newsnap.messageNum; oldMessageNum++ )
            {
                cl.snapshots[oldMessageNum & 31].valid = false;
            }

            // copy to the current good spot
            cl.snap = newsnap;
            cl.snap.ping = 999;
            // calculate ping time
            for (int i = 0; i < 32; i++)
            {
                int packetNum = (clc.netchan.outgoingSequence - 1 - i) & 31;
                if (cl.snap.ps.commandTime >= cl.outPackets[packetNum].p_serverTime)
                {
                    cl.snap.ping = realtime - cl.outPackets[packetNum].p_realtime;
                    break;
                }
            }

            // save the frame off in the backup array for later delta comparisons
            cl.snapshots[cl.snap.messageNum & 31] = cl.snap;

            //Common.Instance.WriteLine("   Snapshot:{0} delta:{1} ping:{2}", cl.snap.messageNum, cl.snap.deltaNum, cl.snap.ping);
            cl.newSnapshots = true;
        }
예제 #4
0
        void ParsePacketEntities(NetBuffer msg, clSnapshot_t oldframe, clSnapshot_t newframe)
        {
            newframe.parseEntitiesNum = cl.parseEntitiesNum;
            newframe.numEntities = 0;

            // delta from the entities present in oldframe
            int oldindex = 0, oldnum = 0;
            Common.entityState_t oldstate = null;
            if (oldframe == null)
                oldnum = 99999;
            else
            {
                if (oldnum >= oldframe.numEntities)
                    oldnum = 99999;
                else
                {
                    oldstate = cl.parseEntities[(oldframe.parseEntitiesNum + oldindex) & 2047];
                    oldnum = oldstate.number;
                }
            }

            while (true)
            {
                // read the entity index number
                int newnum = msg.ReadInt32();

                if (newnum == 1023)
                    break;

                while (oldnum < newnum)
                {
                    // one or more entities from the old packet are unchanged
                    DeltaEntity(msg, newframe, oldnum, oldstate, true);
                    oldindex++;

                    if (oldindex >= oldframe.numEntities)
                        oldnum = 99999;
                    else
                    {
                        oldstate = cl.parseEntities[(oldframe.parseEntitiesNum + oldindex) & 2047];
                        oldnum = oldstate.number;
                    }
                }
                if (oldnum == newnum)
                {
                    // delta from previous state
                    DeltaEntity(msg, newframe, newnum, oldstate, false);

                    oldindex++;

                    if (oldindex >= oldframe.numEntities)
                        oldnum = 99999;
                    else
                    {
                        oldstate = cl.parseEntities[(oldframe.parseEntitiesNum + oldindex) & 2047];
                        oldnum = oldstate.number;
                    }
                    continue;
                }

                if (oldnum > newnum)
                {
                    // delta from baseline
                    DeltaEntity(msg, newframe, newnum, cl.entityBaselines[newnum], false);
                    continue;
                }
            }

            // any remaining entities in the old frame are copied over
            while (oldnum != 99999)
            {
                // one or more entities from the old packet are unchanged
                DeltaEntity(msg, newframe, oldnum, oldstate, true);

                oldindex++;

                if (oldindex >= oldframe.numEntities)
                    oldnum = 99999;
                else
                {
                    oldstate = cl.parseEntities[(oldframe.parseEntitiesNum + oldindex) & 2047];
                    oldnum = oldstate.number;
                }
            }
        }