private static Entity ReadEnterPVS(IBitStream reader, int id, DemoParser parser)
        {
            int serverClassID = (int)reader.ReadInt(parser.SendTableParser.ClassBits);

            ServerClass entityClass = parser.SendTableParser.ServerClasses[serverClassID];

            reader.ReadInt(10); //Entity serial.

            Entity newEntity = new Entity(id, entityClass);

            newEntity.ServerClass.AnnounceNewEntity(newEntity);

            object[] fastBaseline;
            if (parser.PreprocessedBaselines.TryGetValue(serverClassID, out fastBaseline))
            {
                PropertyEntry.Emit(newEntity, fastBaseline);
            }
            else
            {
                var preprocessedBaseline = new List <object>();
                if (parser.instanceBaseline.ContainsKey(serverClassID))
                {
                    using (var collector = new PropertyCollector(newEntity, preprocessedBaseline))
                        using (var bitStream = BitStreamUtil.Create(parser.instanceBaseline[serverClassID]))
                            newEntity.ApplyUpdate(bitStream);
                }

                parser.PreprocessedBaselines.Add(serverClassID, preprocessedBaseline.ToArray());
            }

            return(newEntity);
        }
        private uint PeekInt(int numBits, bool mayOverflow = false)
        {
            BitStreamUtil.AssertMaxBits(32, numBits);
            Debug.Assert(mayOverflow || ((Offset + numBits) <= (BitsInBuffer + (SLED * 8))), "gg", "This code just fell apart. We're all dead. Offset={0} numBits={1} BitsInBuffer={2}", Offset, numBits, BitsInBuffer);

            return((uint)(((*(ulong *)(PBuffer + ((Offset >> 3) & ~3))) << ((8 * 8) - ((Offset & ((8 * 4) - 1))) - numBits)) >> ((8 * 8) - numBits)));
        }
示例#3
0
        public int ReadSignedInt(int numBits)
        {
            BitStreamUtil.AssertMaxBits(32, numBits);

            // Just like PeekInt, but we cast to signed long before the shr because we need to sext
            var result = (int)(((long)(BitConverter.ToUInt64(Buffer, (Offset / 8) & ~3) << ((8 * 8) - (Offset % (8 * 4)) - numBits))) >> ((8 * 8) - numBits));

            Advance(numBits);
            return(result);
        }
        public byte ReadByte(int bits)
        {
            BitStreamUtil.AssertMaxBits(8, bits);
            var ret = (byte)PeekInt(bits);

            if (TryAdvance(bits))
            {
                RefillBuffer();
            }
            return(ret);
        }
        public int ReadSignedInt(int numBits)
        {
            // Just like PeekInt, but we cast to signed long before the shr because we need to sext
            BitStreamUtil.AssertMaxBits(32, numBits);
            var result = (int)(((long)((*(ulong *)(PBuffer + ((Offset >> 3) & ~3))) << ((8 * 8) - (Offset & ((8 * 4) - 1)) - numBits))) >> ((8 * 8) - numBits));

            if (TryAdvance(numBits))
            {
                RefillBuffer();
            }
            return(result);
        }
        public int ReadProtobufVarInt()
        {
            var availableBits = BitsInBuffer + (SLED * 8) - Offset;
            // Start by overflowingly reading 32 bits.
            // Reading beyond the buffer contents is safe in this case,
            // because the sled ensures that we stay inside of the buffer.
            uint buf = PeekInt(32, true);

            // always take the first bytes; others if necessary
            uint result = buf & MSK_1;

            BitStreamUtil.AssertMaxBits(availableBits, 1 * 8);
            if ((buf & MSB_1) != 0)
            {
                result |= (buf & MSK_2) >> 1;
                BitStreamUtil.AssertMaxBits(availableBits, 1 * 8);
                if ((buf & MSB_2) != 0)
                {
                    result |= (buf & MSK_3) >> 2;
                    BitStreamUtil.AssertMaxBits(availableBits, 2 * 8);
                    if ((buf & MSB_3) != 0)
                    {
                        result |= (buf & MSK_4) >> 3;
                        BitStreamUtil.AssertMaxBits(availableBits, 3 * 8);
                        if ((buf & MSB_4) != 0)
                        {
                            // dammit, it's too large (probably negative)
                            // fall back to the slow implementation, that's rare
                            return(BitStreamUtil.ReadProtobufVarIntStub(this));
                        }
                        else if (TryAdvance(4 * 8))
                        {
                            RefillBuffer();
                        }
                    }
                    else if (TryAdvance(3 * 8))
                    {
                        RefillBuffer();
                    }
                }
                else if (TryAdvance(2 * 8))
                {
                    RefillBuffer();
                }
            }
            else if (TryAdvance(1 * 8))
            {
                RefillBuffer();
            }

            return(unchecked ((int)result));
        }
示例#7
0
        public bool TryApplyMessage(ProtoBuf.IExtensible message, DemoParser parser)
        {
            CSVCMsg_PacketEntities packetEntities = message as CSVCMsg_PacketEntities;

            if (packetEntities == null)
            {
                return(false);
            }

            // TODO check
            // In official C++ source code, loop is from last to first entities in packetEntities -> impact ?
            using (IBitStream reader = BitStreamUtil.Create(packetEntities.entity_data)) {
                int currentEntity = -1;

                for (int i = 0; i < packetEntities.updated_entries; i++)
                {
                    currentEntity += 1 + (int)reader.ReadUBitInt();

                    if (!reader.ReadBit())
                    {
                        Entity entity;

                        if (reader.ReadBit())
                        {
                            // EnterPVS = add entity
                            entity = EnterPVS(reader, currentEntity, parser);
                        }
                        else
                        {
                            // DeltaEnt = update entity
                            entity = parser.entities[currentEntity];
                        }

                        entity.ApplyUpdate(reader);

                        UpdateModel(entity, parser);

                        Debug.WriteLine("Entity #" + entity.ID + ": " + entity.ServerClass.Name);
                    }
                    else
                    {
                        // LeavePVS
                        if (reader.ReadBit())
                        {
                            parser.entities.Remove(currentEntity);
                        }
                    }
                }
            }

            return(true);
        }
示例#8
0
        private uint PeekInt(int numBits, bool mayOverflow = false)
        {
            BitStreamUtil.AssertMaxBits(32, numBits);
            Debug.Assert(mayOverflow || ((Offset + numBits) <= (BitsInBuffer + (SLED * 8))), "gg", "This code just fell apart. We're all dead. Offset={0} numBits={1} BitsInBuffer={2}", Offset, numBits, BitsInBuffer);


            // _      xxxnno      _
            // _   xxxnno         _
            // _    xxxnno


            return((uint)((BitConverter.ToUInt64(Buffer, (Offset / 8) & ~3) << ((8 * 8) - (Offset % (8 * 4)) - numBits)) >> ((8 * 8) - numBits)));
        }
示例#9
0
        public void ParsePacket(Stream stream, DemoParser parser)
        {
            using (IBitStream reader = BitStreamUtil.Create(stream))
            {
                int numTables = reader.ReadByte();

                for (int i = 0; i < numTables; i++)
                {
                    string tableName = reader.ReadString();

                    ParseStringTable(reader, tableName, parser);
                }
            }
        }
示例#10
0
        /// <summary>
        /// Reads an update that occures when a new edict enters the PVS (potentially visible system)
        /// </summary>
        /// <returns>The new Entity.</returns>
        private static Entity ReadEnterPVS(IBitStream reader, int id, DemoParser parser)
        {
            //What kind of entity?
            int serverClassID = (int)reader.ReadInt(parser.SendTableParser.ClassBits);

            //So find the correct server class
            ServerClass entityClass = parser.SendTableParser.ServerClasses[serverClassID];

            reader.ReadInt(10); //Entity serial.
            //Never used anywhere I guess. Every parser just skips this


            Entity newEntity = new Entity(id, entityClass);

            //give people the chance to subscribe to events for this
            newEntity.ServerClass.AnnounceNewEntity(newEntity);

            //And then parse the instancebaseline.
            //basically you could call
            //newEntity.ApplyUpdate(parser.instanceBaseline[entityClass];
            //This code below is just faster, since it only parses stuff once
            //which is faster.

            object[] fastBaseline;
            if (parser.PreprocessedBaselines.TryGetValue(serverClassID, out fastBaseline))
            {
                PropertyEntry.Emit(newEntity, fastBaseline);
            }
            else
            {
                var preprocessedBaseline = new List <object>();
                if (parser.instanceBaseline.ContainsKey(serverClassID))
                {
                    using (var collector = new PropertyCollector(newEntity, preprocessedBaseline))
                        using (var bitStream = BitStreamUtil.Create(parser.instanceBaseline[serverClassID]))
                            newEntity.ApplyUpdate(bitStream);
                }

                parser.PreprocessedBaselines.Add(serverClassID, preprocessedBaseline.ToArray());
            }

            return(newEntity);
        }
示例#11
0
 public byte ReadByte(int bits)
 {
     BitStreamUtil.AssertMaxBits(8, bits);
     return((byte)ReadInt(bits));
 }
示例#12
0
 public int ReadProtobufVarInt()
 {
     return(BitStreamUtil.ReadProtobufVarIntStub(this));
 }
示例#13
0
        private static void ProcessPacket(byte[] bytes)
        {
            var  length = bytes.Length;
            uint seq, ack;
            byte flags;

            using (var stream = BitStreamUtil.Create(bytes))
            {
                seq = stream.ReadInt(32);
                ack = stream.ReadInt(32);

                flags = stream.ReadByte();
                ushort checksum = (ushort)stream.ReadInt(16);

                stream.BeginChunk((length - 11) * 8);
                ushort computed = CrcUtils.Compute16(stream);
                stream.EndChunk();

                if (checksum != computed)
                {
                    //Console.WriteLine(
                    //    "failed checksum:"
                    //        + "recv seq {0} ack {1} flags {2:x} checksum {3:x} computed {4:x}",
                    //    seq, ack, flags, checksum, computed);
                    return;
                }
            }

            var remaining = new byte[length - 11];

            Array.Copy(bytes, 11, remaining, 0, length - 11);

            using (var stream = BitStreamUtil.Create(remaining))
            {
                byte reliableState = stream.ReadByte();

                if ((flags & 0x10) == 0x10)
                {
                    //Console.WriteLine(
                    //    "choke {0}: recv seq {1} ack {2} flags {3:x}",
                    //    stream.ReadByte(), seq, ack, flags);

                    return;
                }

                if (seq < sequenceIn)
                {
                    // We no longer care.
                    //Console.WriteLine("dropped: recv seq {0} ack {1}", seq, ack);
                    return;
                }

                if ((flags & (uint)PacketFlags.IsReliable) != 0)
                {
                    return;
                }

                //filter2++;
                //Console.WriteLine($"filter2: {filter2}");

                try
                {
                    stream.BeginChunk((remaining.Length - 1) * 8);
                    DemoPacketParser.ParsePacket(stream, demoParser);
                    stream.EndChunk();

                    demoParser.ForceTick(true);
                }
                catch { }

                lastAckRecv = ack;
                sequenceIn  = seq;
            }
        }
示例#14
0
 public byte ReadByte(int bits)
 {
     BitStreamUtil.AssertMaxBits(8, bits);
     return(ReadBits(bits)[0]);
 }
示例#15
0
        public void ParseStringTableMessage(CSVCMsg_CreateStringTable table, DemoParser parser)
        {
            using (IBitStream reader = BitStreamUtil.Create(table.string_data))
            {
                if (reader.ReadBit())
                {
                    throw new NotImplementedException("Encoded with dictionaries, unable to decode");
                }

                int nTemp      = table.max_entries;
                int nEntryBits = 0;
                while ((nTemp >>= 1) != 0)
                {
                    ++nEntryBits;
                }


                List <string> history = new List <string>();

                int lastEntry = -1;

                for (int i = 0; i < table.num_entries; i++)
                {
                    int entryIndex = lastEntry + 1;
                    // read in the entity-index
                    if (!reader.ReadBit())
                    {
                        entryIndex = (int)reader.ReadInt(nEntryBits);
                    }

                    lastEntry = entryIndex;

                    // Read the name of the string into entry.
                    string entry = "";
                    if (entryIndex < 0 || entryIndex >= table.max_entries)
                    {
                        throw new InvalidDataException("bogus string index");
                    }

                    if (reader.ReadBit())
                    {
                        bool substringcheck = reader.ReadBit();

                        if (substringcheck)
                        {
                            int index       = (int)reader.ReadInt(5);
                            int bytestocopy = (int)reader.ReadInt(5);

                            entry = history[index].Substring(0, bytestocopy);

                            entry += reader.ReadString(1024);
                        }
                        else
                        {
                            entry = reader.ReadString(1024);
                        }
                    }

                    if (entry == null)
                    {
                        entry = "";
                    }

                    if (history.Count > 31)
                    {
                        history.RemoveAt(0);
                    }

                    // Read in the user data.
                    byte[] userdata = new byte[0];
                    if (reader.ReadBit())
                    {
                        if (table.user_data_fixed_size)
                        {
                            userdata = reader.ReadBits(table.user_data_size_bits);
                        }
                        else
                        {
                            int bytesToRead = (int)reader.ReadInt(14);

                            userdata = reader.ReadBytes(bytesToRead);
                        }
                    }

                    if (userdata.Length == 0)
                    {
                        break;
                    }

                    // Now we'll parse the players out of it.
                    BinaryReader playerReader = new BinaryReader(new MemoryStream(userdata));
                    PlayerInfo   info         = PlayerInfo.ParseFrom(playerReader);

                    UpdatePlayer(info, parser);
                }
            }
        }