protected override void Parse(ref BitStreamReader bsr)
        {
            Cmd = bsr.ReadUInt();
            uint byteSize        = bsr.ReadUInt();
            int  indexBeforeData = bsr.CurrentBitIndex;

            CommandNumber    = bsr.ReadUIntIfExists();
            TickCount        = bsr.ReadUIntIfExists();
            ViewAngleX       = bsr.ReadFloatIfExists();
            ViewAngleY       = bsr.ReadFloatIfExists();
            ViewAngleZ       = bsr.ReadFloatIfExists();
            SidewaysMovement = bsr.ReadFloatIfExists();
            ForwardMovement  = bsr.ReadFloatIfExists();
            VerticalMovement = bsr.ReadFloatIfExists();
            Buttons          = (Buttons?)bsr.ReadUIntIfExists();
            Impulse          = bsr.ReadByteIfExists();
            if (bsr.ReadBool())
            {
                WeaponSelect  = bsr.ReadUInt(11);
                WeaponSubtype = bsr.ReadUIntIfExists(6);
            }
            MouseDx             = (short?)bsr.ReadUShortIfExists();
            MouseDy             = (short?)bsr.ReadUShortIfExists();
            bsr.CurrentBitIndex = indexBeforeData + (int)(byteSize << 3);
        }
Example #2
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            PacketInfo = new CmdInfo[DemoInfo.MaxSplitscreenPlayers];
            for (int i = 0; i < PacketInfo.Length; i++)
            {
                PacketInfo[i] = new CmdInfo(DemoRef);
                PacketInfo[i].ParseStream(ref bsr);
            }
            InSequence    = bsr.ReadUInt();
            OutSequence   = bsr.ReadUInt();
            MessageStream = new MessageStream(DemoRef);
            MessageStream.ParseStream(ref bsr);

            // After we're doing with the packet, we can process all the messages.
            // Most things should be processed during parsing, but any additional checks should be done here.

            var netTickMessages = MessageStream.Where(tuple => tuple.messageType == MessageType.NetTick).ToList();

            if (netTickMessages.Count > 1)
            {
                DemoRef.LogError("there's more than 2 net tick messages in this packet");
            }
            NetTick?tickInfo = (NetTick?)netTickMessages.FirstOrDefault().message;

            if (tickInfo != null)
            {
                if (DemoRef.EntitySnapshot != null)
                {
                    DemoRef.EntitySnapshot.EngineTick = tickInfo.EngineTick;
                }
            }
            // todo fill prop handles with data here
            TimingAdjustment.AdjustFromPacket(this);
        }
        // src_main/common/netmessages.cpp  SVC_ServerInfo::WriteToBuffer
        protected override void Parse(ref BitStreamReader bsr)
        {
            NetworkProtocol = bsr.ReadUShort();
            ServerCount     = bsr.ReadUInt();
            IsHltv          = bsr.ReadBool();
            IsDedicated     = bsr.ReadBool();
            if (DemoInfo.IsLeft4Dead() && DemoInfo.Game >= SourceGame.L4D2_2147)
            {
                UnknownBit = bsr.ReadBool();
            }
            ClientCrc = bsr.ReadSInt();
            if (DemoInfo.NewDemoProtocol)             // unknown field, could be before ClientCrc
            {
                Unknown = bsr.ReadUInt();
            }
            MaxServerClasses = bsr.ReadUShort();
            if (NetworkProtocol == 24)
            {
                MapMD5 = bsr.ReadBytes(16);
            }
            else
            {
                MapCrc = bsr.ReadUInt();                 // network protocol < 18 according to p2 leak, but doesn't add up for l4d2 and p2
            }
            PlayerCount     = bsr.ReadByte();
            MaxClients      = bsr.ReadByte();
            TickInterval    = bsr.ReadFloat();
            Platform        = (char)bsr.ReadByte();
            GameDirBitIndex = bsr.AbsoluteBitIndex;
            GameDir         = bsr.ReadNullTerminatedString();
            MapName         = bsr.ReadNullTerminatedString();
            SkyName         = bsr.ReadNullTerminatedString();
            HostName        = bsr.ReadNullTerminatedString();
            if (DemoInfo.IsLeft4Dead() && DemoInfo.Game >= SourceGame.L4D2_2147)
            {
                MissionName  = bsr.ReadNullTerminatedString();
                MutationName = bsr.ReadNullTerminatedString();
            }
            if (NetworkProtocol == 24)
            {
                HasReplay = bsr.ReadBool();                 // protocol version >= 16
            }
            // there's a good change that the first SvcServerInfo parsed is parsed correctly
            // prevent the interval from being overwritten by subsequent, incorrectly detected, SvcServerInfo messages
            // TODO: check if changing tickrate mid game sends another SvcServerInfo
            if (!DemoInfo.HasParsedTickInterval)
            {
                DemoInfo.TickInterval          = TickInterval;
                DemoInfo.HasParsedTickInterval = true;
            }
            // this packet always(?) appears before the creation of any tables

            DemoRef.StringTablesManager.ClearCurrentTables();

            // init baselines here
            DemoRef.EntBaseLines = new EntityBaseLines(DemoRef, MaxServerClasses);
        }
        protected override void Parse(ref BitStreamReader bsr)
        {
            TableId             = (byte)bsr.ReadUInt(5);
            TableName           = DemoRef.StringTablesManager.TableById(TableId).Name;
            ChangedEntriesCount = bsr.ReadUShortIfExists() ?? 1;
            uint dataLen = bsr.ReadUInt(20);

            TableUpdates = new StringTableUpdates(DemoRef, TableName, ChangedEntriesCount, false);
            TableUpdates.ParseStream(bsr.SplitAndSkip(dataLen));
        }
Example #5
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     bsr.ReadVectorCoord(out Pos);
     DecalTextureIndex = (int)bsr.ReadUInt(9);
     if (bsr.ReadBool())
     {
         EntityIndex = bsr.ReadUInt(DemoInfo.MaxEdictBits);
         ModelIndex  = bsr.ReadUInt(DemoInfo.MaxEdictBits);
     }
     LowPriority = bsr.ReadBool();
 }
Example #6
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            EventCount = (int)bsr.ReadUInt(9);
            int dataLen         = (int)bsr.ReadUInt(20);
            int indexBeforeData = bsr.CurrentBitIndex;

            Descriptors = new List <GameEventDescription>(EventCount);
            for (int i = 0; i < EventCount; i++)
            {
                Descriptors.Add(new GameEventDescription(DemoRef));
                Descriptors[^ 1].ParseStream(ref bsr);
Example #7
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     FileStamp       = bsr.ReadStringOfLength(8);
     DemoProtocol    = bsr.ReadUInt();
     NetworkProtocol = bsr.ReadUInt();
     ServerName      = bsr.ReadStringOfLength(260);
     ClientName      = bsr.ReadStringOfLength(260);
     MapName         = bsr.ReadStringOfLength(260);
     GameDirectory   = bsr.ReadStringOfLength(260);
     PlaybackTime    = bsr.ReadFloat();
     TickCount       = bsr.ReadSInt();
     FrameCount      = bsr.ReadSInt();
     SignOnLength    = bsr.ReadUInt();
 }
        protected override void Parse(ref BitStreamReader bsr)
        {
            MenuType = bsr.ReadUShort();
            uint dataLen = bsr.ReadUInt();

            _data = bsr.SplitAndSkip(dataLen);
        }
        public static unsafe byte[] Decompress(ref BitStreamReader bsr, int compSize)
        {
            uint type       = bsr.ReadUInt();
            int  decompSize = bsr.ReadSInt();

            switch (type)
            {
            case LZSS_ID:
                Span <byte> dataIn = compSize < 100000 ? stackalloc byte[compSize] : new byte[compSize];
                bsr.ReadToSpan(dataIn);
                byte[] arrOut = new byte[decompSize];

                fixed(byte *pDataIn = dataIn)
                fixed(byte *pDataOut = arrOut)
                DecompressLZSS(pDataIn, pDataOut);

                return(arrOut);

            case SNAPPY_ID:
                Debug.Assert(false);
                throw new NotImplementedException("snappy decompression not implemented");

            default:
                throw new InvalidOperationException("unknown compression method");
            }
        }
        protected override void Parse(ref BitStreamReader bsr)
        {
            RemoveUser = bsr.ReadBool();
            uint dataLen = bsr.ReadUInt(11);

            Data = bsr.SplitAndSkip(dataLen);
        }
 protected override void Parse(ref BitStreamReader bsr)
 {
     EngineTick = bsr.ReadUInt();
     if (DemoInfo.Game != SourceGame.HL2_OE)
     {
         HostFrameTime       = bsr.ReadUShort() / NetTickScaleUp;
         HostFrameTimeStdDev = bsr.ReadUShort() / NetTickScaleUp;
     }
 }
Example #12
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     Flags   = (InterpFlags)bsr.ReadUInt();
     _floats = new Vector3[6];
     for (int i = 0; i < _floats.Length; i++)
     {
         bsr.ReadVector3(out _floats[i]);
     }
 }
Example #13
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            DataTableId = _classInfoRef == null
                                ? bsr.ReadUShort()
                                : (int)bsr.ReadUInt(DemoRef.DataTableParser.ServerClassBits);

            ClassName     = bsr.ReadNullTerminatedString();
            DataTableName = bsr.ReadNullTerminatedString();
        }
Example #14
0
        /* Okay, this is pretty wacky. First I read a byte, and based off of that I try to determine the type of
         * user message. If I don't have a lookup list for whatever game this is or the type seems bogus, I log an
         * error. Otherwise, create the message instance, and if it's not empty, try to parse it. If parsing fails,
         * log an error. Finally, if not all bits of the message are parsed, then it's likely that I did something
         * wrong, (since it seems like the user messages use up all the bits in the message) so log an error.
         */
        protected override void Parse(ref BitStreamReader bsr)
        {
            byte typeVal = bsr.ReadByte();

            MessageType = UserMessage.ByteToUserMessageType(DemoInfo, typeVal);
            uint   messageLength = bsr.ReadUInt(DemoInfo.UserMessageLengthBits);
            string?errorStr      = null;

            var uMessageReader = bsr.SplitAndSkip(messageLength);

            switch (MessageType)
            {
            case UserMessageType.Unknown:
                errorStr = $"There is no SvcUserMessage list for this game, type {typeVal} was found";
                break;

            case UserMessageType.Invalid:
                errorStr = $"SvcUserMessage with value {typeVal} is invalid";
                break;

            default:
                UserMessage = SvcUserMessageFactory.CreateUserMessage(DemoRef, MessageType) !;
                if (UserMessage == null)
                {
                    errorStr       = $"Unimplemented SvcUserMessage: {MessageType}";
                    _unimplemented = true;
                }
                else
                {
                    try {                             // empty messages might still have 1-2 bytes, might need to do something 'bout that
                        if (UserMessage.ParseStream(uMessageReader) != 0)
                        {
                            errorStr = $"{GetType().Name} - {MessageType} ({typeVal}) didn't parse all bits";
                        }
                    } catch (Exception e) {
                        errorStr = $"{GetType().Name} - {MessageType} ({typeVal}) " +
                                   $"threw exception during parsing, message: {e.Message}";
                    }
                }
                break;
            }

            #region error logging

            // if parsing fails, just convert to an unknown type - the byte array that it will print is still useful
            if (errorStr != null)
            {
                int rem = uMessageReader.BitsRemaining;
                DemoRef.LogError($"{errorStr}, ({rem} bit{(rem == 1 ? "" : "s")}) - " +
                                 $"{uMessageReader.FromBeginning().ToHexString()}");
                UserMessage = new UnknownUserMessage(DemoRef);
                UserMessage.ParseStream(uMessageReader);
            }

            #endregion
        }
Example #15
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            TableName  = bsr.ReadNullTerminatedString();
            MaxEntries = (short)bsr.ReadUShort();
            NumEntries = (int)bsr.ReadUInt(BitUtils.HighestBitIndex(MaxEntries) + 1);
            uint dataLen = bsr.ReadUInt(DemoInfo.IsLeft4Dead2() ? 21 : 20);

            UserDataFixedSize = bsr.ReadBool();
            UserDataSize      = (int)(UserDataFixedSize ? bsr.ReadUInt(12) : 0);
            UserDataSizeBits  = (int)(UserDataFixedSize ? bsr.ReadUInt(4) : 0);
            if (DemoRef.Header.NetworkProtocol >= 15)
            {
                Flags = (StringTableFlags)bsr.ReadUInt(DemoInfo.NewDemoProtocol ? 2 : 1);
            }

            DemoRef.StringTablesManager.CreateStringTable(this);
            TableUpdates = new StringTableUpdates(DemoRef, TableName, NumEntries, true);
            TableUpdates.ParseStream(bsr.SplitAndSkip(dataLen));
        }
Example #16
0
 // we're reading a player_info_t, so take alignment into account
 protected override void Parse(ref BitStreamReader bsr)
 {
     if (DemoInfo.NewDemoProtocol && !DemoInfo.IsLeft4Dead1())
     {
         SteamId = (CSteamId)bsr.ReadULong();
     }
     Name   = bsr.ReadStringOfLength(MaxPlayerNameLength);
     UserId = bsr.ReadSInt();
     Guid   = bsr.ReadStringOfLength(SignedGuidLen + 1);
     bsr.SkipBytes(3);
     FriendsId   = bsr.ReadUInt();
     FriendsName = bsr.ReadStringOfLength(MaxPlayerNameLength);
     FakePlayer  = bsr.ReadByte() != 0;
     IsHlTv      = bsr.ReadByte() != 0;
     bsr.SkipBytes(2);
     CustomFiles     = new[] { bsr.ReadUInt(), bsr.ReadUInt(), bsr.ReadUInt(), bsr.ReadUInt() };
     FilesDownloaded = bsr.ReadByte();
     bsr.SkipBytes(3);
     // for demo protocol 4 there's 4 additional bytes somewhere for some reason
 }
Example #17
0
        public static void ChangeDemoDir(SourceDemo demo, Stream s, string newDir)
        {
            void Write(byte[] buf) => s.Write(buf, 0, buf.Length);

            string old = demo.Header.GameDirectory;

            if (old == newDir)
            {
                // no difference
                Write(demo.Reader.Data);
                return;
            }
            int             lenDiff = newDir.Length - old.Length;
            BitStreamReader bsr     = demo.Reader;

            byte[] dirBytes = Encoding.ASCII.GetBytes(newDir);

            Write(bsr.ReadBytes(796));
            Write(dirBytes);             // header doesn't matter but I change it anyway
            Write(new byte[260 - newDir.Length]);
            bsr.SkipBytes(260);
            Write(bsr.ReadBytes(12));
            byte[] tmp = BitConverter.GetBytes((uint)(bsr.ReadUInt() + lenDiff));
            if (!BitConverter.IsLittleEndian)
            {
                tmp = tmp.Reverse().ToArray();
            }
            Write(tmp);

            foreach (SignOn signOn in demo.FilterForPacket <SignOn>().Where(signOn => signOn.FilterForMessage <SvcServerInfo>().Any()))
            {
                // catch up to signOn packet
                int byteCount = (signOn.Reader.AbsoluteBitIndex - bsr.AbsoluteBitIndex) / 8;
                Write(bsr.ReadBytes(byteCount));
                bsr.SkipBits(signOn.Reader.BitLength);

                BitStreamWriter bsw          = new BitStreamWriter();
                BitStreamReader signOnReader = signOn.Reader;
                bsw.WriteBits(signOnReader.ReadRemainingBits());
                signOnReader = signOnReader.FromBeginning();
                int bytesToMessageStreamSize = demo.DemoInfo.MaxSplitscreenPlayers * 76 + 8;
                signOnReader.SkipBytes(bytesToMessageStreamSize);
                // edit the message stream length - read uint, and edit at index before the reading of said uint
                bsw.EditIntAtIndex((int)(signOnReader.ReadUInt() + lenDiff), signOnReader.CurrentBitIndex - 32, 32);

                // actually change the game dir
                SvcServerInfo serverInfo = signOn.FilterForMessage <SvcServerInfo>().Single();
                int           editIndex  = serverInfo.GameDirBitIndex - signOn.Reader.AbsoluteBitIndex;
                bsw.RemoveBitsAtIndex(editIndex, old.Length * 8);
                bsw.InsertBitsAtIndex(dirBytes, editIndex, newDir.Length * 8);
                Write(bsw.AsArray);
            }
            Write(bsr.ReadRemainingBits().bytes);
        }
        protected override void Parse(ref BitStreamReader bsr)
        {
            EntryCount = bsr.ReadByte();
            uint bitLen = DemoInfo.Game == SourceGame.PORTAL_1_1910503
                                ? bsr.ReadVarUInt32()
                                : bsr.ReadUInt(DemoInfo.IsLeft4Dead2() ? 18 : 17);

            _data = bsr.SplitAndSkip(bitLen);

            // todo
        }
 protected override void Parse(ref BitStreamReader bsr)
 {
     NeedsDecoder      = bsr.ReadBool();
     Name              = bsr.ReadNullTerminatedString();
     ExpectedPropCount = (int)bsr.ReadUInt(DemoInfo.Game == SourceGame.HL2_OE ? 9 : 10);
     SendProps         = new List <SendTableProp>(ExpectedPropCount);
     for (int i = 0; i < ExpectedPropCount; i++)
     {
         var sendProp = new SendTableProp(DemoRef, this);
         SendProps.Add(sendProp);
         sendProp.ParseStream(ref bsr);
     }
 }
        protected override void Parse(ref BitStreamReader bsr)
        {
            // first, we read the main message info here
            MaxEntries     = (ushort)bsr.ReadUInt(11);
            IsDelta        = bsr.ReadBool();
            DeltaFrom      = IsDelta ? bsr.ReadSInt() : -1;
            BaseLine       = bsr.ReadUInt(1);
            UpdatedEntries = (ushort)bsr.ReadUInt(11);
            uint dataLen = bsr.ReadUInt(20);

            UpdateBaseline = bsr.ReadBool();
            _entBsr        = bsr.SplitAndSkip(dataLen);

#if !FORCE_PROCESS_ENTS
            if ((DemoRef.DemoParseResult & DemoParseResult.EntParsingEnabled) == 0 ||
                (DemoRef.DemoParseResult & DemoParseResult.EntParsingFailed) != 0)
            {
                return;
            }
#endif
            // now, we do some setup for ent parsing
            ref EntitySnapshot?snapshot = ref DemoRef.EntitySnapshot;
        protected override void Parse(ref BitStreamReader bsr)
        {
            DataType = (CustomDataType)bsr.ReadSInt();
            uint size = bsr.ReadUInt();

            DataMessage = CustomDataFactory.CreateCustomDataMessage(DemoRef, DataType);
            try {
                DataMessage.ParseStream(bsr.SplitAndSkip(size * 8));
            } catch (Exception e) {
                DemoRef.LogError($"error while parsing custom data of type: {DataType}... {e.Message}");
                DataMessage = new UnknownCustomDataMessage(DemoRef);
            }
        }
Example #22
0
 protected override void Parse(ref BitStreamReader bsr)
 {
     SignOnState = (SignOnState)bsr.ReadByte();
     SpawnCount  = bsr.ReadSInt();
     if (DemoInfo.NewDemoProtocol)
     {
         NumServerPlayers = bsr.ReadUInt();
         int length = (int)bsr.ReadUInt();
         if (length > 0)
         {
             PlayerNetworkIds = bsr.ReadBytes(length);
         }
         length = (int)bsr.ReadUInt();
         if (length > 0)                 // the string still seams to be null terminated (sometimes?)
         {
             MapName = bsr.ReadStringOfLength(length).Split(new char[] { '\0' }, 2)[0];
         }
     }
     if (SignOnState == SignOnState.PreSpawn)
     {
         DemoRef.ClientSoundSequence = 1;                 // reset sound sequence number after receiving SignOn sounds
     }
 }
        protected override void Parse(ref BitStreamReader bsr)
        {
            SendPropType = DemoInfo.SendPropTypes[(int)bsr.ReadUInt(5)];
            Name         = bsr.ReadNullTerminatedString();
            Flags        = (int)bsr.ReadUInt(DemoInfo.SendPropFlagBits);
            if (DemoInfo.NewDemoProtocol && !DemoInfo.IsLeft4Dead1())
            {
                Priority = bsr.ReadByte();
            }
            if (SendPropType == SendPropType.DataTable || DemoInfo.PropFlagChecker.HasFlag(Flags, PropFlag.Exclude))
            {
                ExcludeDtName = bsr.ReadNullTerminatedString();
            }
            else
            {
                switch (SendPropType)
                {
                case SendPropType.String:
                case SendPropType.Int:
                case SendPropType.Float:
                case SendPropType.Vector3:
                case SendPropType.Vector2:
                    LowValue  = bsr.ReadFloat();
                    HighValue = bsr.ReadFloat();
                    NumBits   = bsr.ReadUInt(DemoInfo.SendPropNumBitsToGetNumBits);
                    break;

                case SendPropType.Array:
                    NumElements = bsr.ReadUInt(10);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(SendPropType),
                                                          $"Invalid prop type: {SendPropType}");
                }
            }
        }
        protected override void Parse(ref BitStreamReader bsr)
        {
            int byteSize        = (int)bsr.ReadUInt();
            int indexBeforeData = bsr.CurrentBitIndex;

            try {
                Tables = new List <SendTable>();
                while (bsr.ReadBool())
                {
                    var table = new SendTable(DemoRef);
                    Tables.Add(table);
                    table.ParseStream(ref bsr);
                }

                ushort classCount = bsr.ReadUShort();
                ServerClasses = new List <ServerClass>(classCount);
                for (int i = 0; i < classCount; i++)
                {
                    var @class = new ServerClass(DemoRef, null);
                    ServerClasses.Add(@class);
                    @class.ParseStream(ref bsr);
                    // I assume in many places that the ID of the table matches its index
                    if (i != ServerClasses[i].DataTableId)
                    {
                        throw new ConstraintException("server class ID does not match its index in the list");
                    }
                }

                // in case SvcServerInfo parsing fails
                DemoRef.EntBaseLines ??= new EntityBaseLines(DemoRef, ServerClasses.Count);

                // re-init the baselines if the count doesn't match (maybe I should just init them from here?)
                if (DemoRef.EntBaseLines !.Baselines.Length != classCount)
                {
                    DemoRef.EntBaseLines.ClearBaseLineState(classCount);
                }

                // create the prop list for each class
                DemoRef.DataTableParser = new DataTableParser(DemoRef, this);
                DemoRef.DataTableParser.FlattenClasses(true);
            } catch (Exception e) {
                DemoRef.LogError($"exception while parsing datatables\n\texception: {e.Message}");
                Debug.WriteLine(e);
            }

            bsr.CurrentBitIndex = indexBeforeData + (byteSize << 3);
        }
Example #25
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            Reliable = bsr.ReadBool();
            int soundCount = Reliable ? 1 : bsr.ReadByte();
            int dataBitLen = (int)bsr.ReadUInt(Reliable ? 8 : 16);

            BitStreamReader soundBsr = bsr.SplitAndSkip(dataBitLen);

            SoundInfo sound = new SoundInfo(DemoRef);
            SoundInfo delta = new SoundInfo(DemoRef);

            delta.SetDefault();

            Exception?e = null;

            try {
                Sounds = new SoundInfo[soundCount];
                for (int i = 0; i < soundCount; i++)
                {
                    sound.ParseDelta(ref soundBsr, delta);
                    delta = sound;
                    if (Reliable)                       // client is incrementing the reliable sequence numbers itself
                    {
                        DemoRef.ClientSoundSequence = ++DemoRef.ClientSoundSequence & SndSeqNumMask;
                        if (sound.SequenceNumber != 0)
                        {
                            throw new ArgumentException($"expected sequence number 0, got: {sound.SequenceNumber}");
                        }
                        sound.SequenceNumber = DemoRef.ClientSoundSequence;
                    }
                    Sounds[i] = new SoundInfo(sound);
                }
            } catch (Exception exp) {
                e = exp;
            }
            if (e != null)
            {
                Sounds = null;
                DemoRef.LogError($"exception while parsing {nameof(SoundInfo)}: {e.Message}");
            }
            else if (soundBsr.BitsRemaining != 0)
            {
                Sounds = null;
                DemoRef.LogError($"exception while parsing {nameof(SoundInfo)}: {soundBsr.BitsRemaining} bits left to read");
            }
        }
        protected override void Parse(ref BitStreamReader bsr)
        {
            var soundIndexBits = DemoInfo.IsLeft4Dead2() ? DemoInfo.Game >= SourceGame.L4D2_2091 ? 15 : 14 : 13;

            SoundIndex = (int)bsr.ReadUInt(soundIndexBits);

            var mgr = DemoRef.StringTablesManager;

            if (mgr.TableReadable.GetValueOrDefault(TableNames.SoundPreCache))
            {
                if (SoundIndex >= mgr.Tables[TableNames.SoundPreCache].Entries.Count)
                {
                    DemoRef.LogError($"{GetType().Name} - sound index out of range: {SoundIndex}");
                }
                else if (SoundIndex != 0)
                {
                    SoundName = mgr.Tables[TableNames.SoundPreCache].Entries[SoundIndex].EntryName;
                }
            }
        }
Example #27
0
        public void WriteUInts()
        {
            var                         random = new Random(0);
            BitStreamWriter             bsw    = new BitStreamWriter();
            List <(uint val, int size)> bits   = new List <(uint val, int size)>();

            for (int _ = 0; _ < Iterations; _++)
            {
                (uint val, int size)r = ((uint)random.Next(), random.Next(1, 33));
                r.val &= uint.MaxValue >> (32 - r.size);
                bits.Add(r);
                bsw.WriteBitsFromUInt(r.val, r.size);
            }
            BitStreamReader bsr = new BitStreamReader(bsw);

            for (int i = 0; i < Iterations; i++)
            {
                Assert.AreEqual(bits[i].val, bsr.ReadUInt(bits[i].size), $"index: {i}");
            }
        }
Example #28
0
        protected override void Parse(ref BitStreamReader bsr)
        {
            byte typeVal = bsr.ReadByte();

            Type = DemoPacket.ByteToPacketType(DemoInfo, typeVal);

            if (Type == PacketType.Unknown)
            {
                throw new ArgumentException("no byte->packet mapper found for this game!");
            }
            else if (Type == PacketType.Invalid)
            {
                throw new ArgumentException($"Illegal packet type: {typeVal}");
            }

            // very last byte is cut off in (all?) demos, copy data from the previous frame if this is the case

            Tick = bsr.BitsRemaining >= 32
                                ? bsr.ReadSInt()
                                : (int)bsr.ReadUInt(24) | (DemoRef.Frames[^ 2].Tick & (0xff << 24));
Example #29
0
        public void SkipBits()
        {
            var             random = new Random(0);
            BitStreamWriter bsw    = new BitStreamWriter();
            List <(int skipCount, uint val)> data = new List <(int skipCount, uint val)>();

            byte[] randArr = new byte[100 / 8 + 1];
            random.NextBytes(randArr);
            for (int _ = 0; _ < Iterations; _++)
            {
                (int skip, uint val)r = (random.Next(0, 100), (uint)random.Next());
                data.Add(r);
                bsw.WriteBits(randArr, r.skip);
                bsw.WriteUInt(r.val);
            }
            BitStreamReader bsr = new BitStreamReader(bsw);

            for (int i = 0; i < Iterations; i++)
            {
                bsr.SkipBits(data[i].skipCount);
                Assert.AreEqual(data[i].val, bsr.ReadUInt(), $"index: {i}");
            }
        }
 protected override void Parse(ref BitStreamReader bsr)
 {
     EntityIndex = bsr.ReadUInt(DemoInfo.MaxEdictBits);
 }