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; }