示例#1
0
        private void ParseSnapshot(Q3HuffmanStream stream)
        {
            Snapshot old;
            Snapshot newSnap = new Snapshot();
            int      deltaNum;

            newSnap.serverCommandNum = this.incomingCommandSequence;
            newSnap.serverTime       = stream.ReadInt32();
            newSnap.messageNum       = this.incomingSequence;

            if (0 == (deltaNum = stream.ReadByte()))
            {
                newSnap.deltaNum = -1;
            }
            else
            {
                newSnap.deltaNum = newSnap.messageNum - deltaNum;
            }

            newSnap.snapFlags = stream.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;
                //clc.demowaiting = false;	// we can start recording now
            }
            else
            {
                old = this.snapshots [newSnap.deltaNum & PACKET_MASK];

                if (!old.valid)
                {
                    // should never happen
                    // "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.
                    // "Delta frame too old."
                }
                else if (parseEntitiesNum - old.parseEntitiesNum > MAX_PARSE_ENTITIES - 128)
                {
                    // "Delta parseEntitiesNum too old."
                }
                else
                {
                    newSnap.valid = true;                       // valid delta parse
                }
            }

            // read areamask
            int len = stream.ReadByte();

            stream.Read(newSnap.areamask, 0, len);

            // read playerinfo
            if (old != null)
            {
                ReadDeltaPlayerstate(stream, old.ps, ref newSnap.ps);
            }
            else
            {
                ReadDeltaPlayerstate(stream, null, ref newSnap.ps);
            }

            // read packet entities
            ParsePacketEntities(stream, 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 = this.snap.messageNum + 1;

            if (newSnap.messageNum - oldMessageNum >= PACKET_BACKUP)
            {
                oldMessageNum = newSnap.messageNum - (PACKET_BACKUP - 1);
            }

            for ( ; oldMessageNum < newSnap.messageNum; oldMessageNum++)
            {
                this.snapshots [oldMessageNum & PACKET_MASK].valid = false;
            }

            // copy to the current good spot
            this.snap      = newSnap;
            this.snap.ping = 999;

            // calculate ping time
            for (int i = 0; i < PACKET_BACKUP; i++)
            {
                int packetNum = (this.outgoingSequence - 1 - i) & PACKET_MASK;

                if (this.snap.ps.commandTime >= this.outPackets [packetNum].serverTime)
                {
                    this.snap.ping = ( int )(DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - this.outPackets[packetNum].realtime;
                    break;
                }
            }

            // save the frame off in the backup array for later delta comparisons
            this.snapshots [this.snap.messageNum & PACKET_MASK] = this.snap;
            this.newSnapshots = true;
        }