Beispiel #1
0
        private void ReadPacket(Q3HuffmanStream stream)
        {
            List <string> cmdLog  = new List <string> ();
            PacketKind    pktKind = stream.BeginRead();

            this.reliableAcknowledge = stream.ReadInt32();
            ServerCommandType cmd;

            while (ServerCommandType.EOF != (cmd = ( ServerCommandType )stream.ReadByte()))
            {
                switch (cmd)
                {
                case ServerCommandType.Nop:
                    cmdLog.Add("Nop");
                    break;

                case ServerCommandType.ServerCommand:
                    this.ParseCommandString(stream);
                    cmdLog.Add("ServerCommand");
                    break;

                case ServerCommandType.GameState:
                    this.ParseGamestate(stream);
                    cmdLog.Add("GameState");
                    break;

                case ServerCommandType.Snapshot:
                    this.ParseSnapshot(stream);
                    cmdLog.Add("Snapshot");
                    break;

                case ServerCommandType.Download:
                    // We never download ;)
                    return;

                default:
                    // Unknown command
                    return;
                }
            }

            stream.EndRead();
        }
Beispiel #2
0
        private void ParseGamestate(Q3HuffmanStream stream)
        {
            this.gameState.Clear();
            this.incomingCommandSequence = stream.ReadInt32();
            EntityState nullstate = new EntityState();

            ServerCommandType cmd;

            entityBaselinesEvent.WaitOne();

            while (ServerCommandType.EOF != (cmd = ( ServerCommandType )stream.ReadByte()))
            {
                switch (cmd)
                {
                case ServerCommandType.ConfigString:
                    int i = stream.ReadInt16();
                    gameState [i] = stream.ReadString();
                    break;

                case ServerCommandType.BaseLine:
                    int newnum = stream.ReadBits(10);

                    ReadDeltaEntity(stream, nullstate, ref entityBaselines [newnum], newnum);
                    break;

                default:
                    // Unknown command
                    break;
                }
            }

            entityBaselinesEvent.Set();

            this.clientNum    = stream.ReadInt32();
            this.checksumFeed = stream.ReadInt32();

            SystemInfoChanged();
            this.connState = ConnectionState.Primed;

            //SendPureChecksums ();
        }
Beispiel #3
0
        private void ReadDeltaPlayerstate(Q3HuffmanStream stream, PlayerState from, ref PlayerState to)
        {
            int i;

            if (from == null)
            {
                from = new PlayerState();
            }

            from.CopyTo(to);

            int      lc = stream.ReadByte();
            NetField field;
            int      trunc;

            for (i = 0, field = PlayerState.fields [i]; i < lc; i++)
            {
                field = PlayerState.fields [i];

                if (stream.ReadBits(1) == 0)
                {
                    // no change
                    KeyValueCoder.TrySetFieldValue(to, field.name,
                                                   KeyValueCoder.TryGetFieldValue(from, field.name));
                }
                else
                {
                    if (field.bits == 0)
                    {
                        // float
                        if (stream.ReadBits(1) == 0)
                        {
                            // integral float
                            trunc = stream.ReadBits(NetField.FLOAT_INT_BITS);
                            // bias to allow equal parts positive and negative
                            trunc -= NetField.FLOAT_INT_BIAS;
                            KeyValueCoder.TrySetFieldValue(to, field.name, trunc);
                        }
                        else
                        {
                            // full floating point value
                            // FIXIT: wrong conversion from 32 bits to floating point value
                            KeyValueCoder.TrySetFieldValue(to, field.name, stream.ReadInt32());
                        }
                    }
                    else
                    {
                        // integer
                        KeyValueCoder.TrySetFieldValue(to, field.name, stream.ReadBits(( int )field.bits));
                    }
                }
            }

            for (i = lc, field = PlayerState.fields [lc]; i < PlayerState.fields.Length; i++)
            {
                field = PlayerState.fields [i];

                // no change
                KeyValueCoder.TrySetFieldValue(to, field.name,
                                               KeyValueCoder.TryGetFieldValue(from, field.name));
            }

            short bits;

            // read the arrays
            if (0 != stream.ReadBits(1))
            {
                // parse stats
                if (0 != stream.ReadBits(1))
                {
                    bits = stream.ReadInt16();

                    for (i = 0; i < 16; i++)
                    {
                        if (0 != (bits & (1 << i)))
                        {
                            to.stats [i] = stream.ReadInt16();
                        }
                    }
                }

                // parse persistant stats
                if (0 != stream.ReadBits(1))
                {
                    bits = stream.ReadInt16();

                    for (i = 0; i < 16; i++)
                    {
                        if (0 != (bits & (1 << i)))
                        {
                            to.persistant [i] = stream.ReadInt16();
                        }
                    }
                }

                // parse ammo
                if (0 != stream.ReadBits(1))
                {
                    bits = stream.ReadInt16();

                    for (i = 0; i < 16; i++)
                    {
                        if (0 != (bits & (1 << i)))
                        {
                            to.ammo [i] = stream.ReadInt16();
                        }
                    }
                }

                // parse powerups
                if (0 != stream.ReadBits(1))
                {
                    bits = stream.ReadInt16();

                    for (i = 0; i < 16; i++)
                    {
                        if (0 != (bits & (1 << i)))
                        {
                            to.powerups [i] = stream.ReadInt32();
                        }
                    }
                }
            }
        }
Beispiel #4
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;
        }
Beispiel #5
0
        private void ReadDeltaEntity(Q3HuffmanStream stream, EntityState from, ref EntityState to, int number)
        {
            // check for a remove
            if (stream.ReadBits(1) == 1)
            {
                new EntityState().CopyTo(to);
                to.number = MAX_GENTITIES - 1;

                return;
            }

            // check for no delta
            if (stream.ReadBits(1) == 0)
            {
                from.CopyTo(to);
                to.number = number;

                return;
            }

            int lc = stream.ReadByte();

            to.number = number;
            int      i;
            NetField field;
            int      trunc;

            for (i = 0, field = EntityState.fields [i]; i < lc && i < EntityState.fields.Length; i++)
            {
                field = EntityState.fields [i];

                if (stream.ReadBits(1) == 0)
                {
                    // no change
                    KeyValueCoder.TrySetFieldValue(to, field.name,
                                                   KeyValueCoder.TryGetFieldValue(from, field.name));
                }
                else
                {
                    if (field.bits == 0)
                    {
                        // float
                        if (stream.ReadBits(1) == 0)
                        {
                            KeyValueCoder.TrySetFieldValue(to, field.name, 0);
                        }
                        else
                        {
                            if (stream.ReadBits(1) == 0)
                            {
                                // integral float
                                trunc = stream.ReadBits(NetField.FLOAT_INT_BITS);
                                // bias to allow equal parts positive and negative
                                trunc -= NetField.FLOAT_INT_BIAS;
                                KeyValueCoder.TrySetFieldValue(to, field.name, trunc);
                            }
                            else
                            {
                                // full floating point value
                                // FIXIT: wrong conversion from 32 bits to floating point value
                                KeyValueCoder.TrySetFieldValue(to, field.name, stream.ReadInt32());
                            }
                        }
                    }
                    else
                    {
                        if (stream.ReadBits(1) == 0)
                        {
                            KeyValueCoder.TrySetFieldValue(to, field.name, 0);
                        }
                        else
                        {
                            // integer
                            KeyValueCoder.TrySetFieldValue(to, field.name, stream.ReadBits(( int )field.bits));
                        }
                    }
                }
            }

            for (i = lc; i < EntityState.fields.Length; i++)
            {
                field = EntityState.fields [i];

                // no change
                KeyValueCoder.TrySetFieldValue(to, field.name,
                                               KeyValueCoder.TryGetFieldValue(from, field.name));
            }
        }