protected override void Parse(ref BitStreamReader bsr) { Name = bsr.ReadNullTerminatedString(); ushort entryCount = bsr.ReadUShort(); if (entryCount > 0) { TableEntries = new List <StringTableEntry>(entryCount); for (int i = 0; i < entryCount; i++) { var entry = new StringTableEntry(DemoRef, this); TableEntries.Add(entry); entry.ParseStream(ref bsr); } } if (bsr.ReadBool()) { ushort classCount = bsr.ReadUShort(); Classes = new List <StringTableClass>(classCount); for (int i = 0; i < classCount; i++) { var @class = new StringTableClass(DemoRef); Classes.Add(@class); @class.ParseStream(ref bsr); } } }
protected override void Parse(ref BitStreamReader bsr) { EngineTick = bsr.ReadUInt(); if (DemoInfo.Game != SourceGame.HL2_OE) { HostFrameTime = bsr.ReadUShort() / NetTickScaleUp; HostFrameTimeStdDev = bsr.ReadUShort() / NetTickScaleUp; } }
// 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) { Duration = bsr.ReadUShort() / (float)(1 << 9); // might be useful: #define SCREENFADE_FRACBITS 9 HoldTime = bsr.ReadUShort(); Flags = (FadeFlags)bsr.ReadUShort(); R = bsr.ReadByte(); G = bsr.ReadByte(); B = bsr.ReadByte(); A = bsr.ReadByte(); }
protected override void Parse(ref BitStreamReader bsr) { PortalEnt = bsr.ReadUShort(); OwnerEnt = bsr.ReadUShort(); Team = bsr.ReadByte(); PortalNum = bsr.ReadByte(); Effect = (PortalFizzleType)bsr.ReadByte(); bsr.ReadVectorCoord(out Origin); bsr.ReadVectorCoord(out Angles); }
protected override void Parse(ref BitStreamReader bsr) { MenuType = bsr.ReadUShort(); uint dataLen = bsr.ReadUInt(); _data = bsr.SplitAndSkip(dataLen); }
protected override void Parse(ref BitStreamReader bsr) { ClassCount = bsr.ReadUShort(); CreateOnClient = bsr.ReadBool(); if (!CreateOnClient) { // if this ever gets used then it should update the mutable tables string s = $"I haven't implemented {GetType().Name} to update the C_string tables."; DemoRef.LogError(s); Debug.WriteLine(s); ServerClasses = new ServerClass[ClassCount]; for (int i = 0; i < ServerClasses.Length; i++) { ServerClasses[i] = new ServerClass(DemoRef, this); ServerClasses[i].ParseStream(ref bsr); // this is an assumption I make in the structure of all the entity stuff, very critical if (i != ServerClasses[i].DataTableId) { throw new ConstraintException("server class ID does not match it's index in the list"); } } } DemoRef.EntBaseLines ??= new EntityBaseLines(DemoRef, ClassCount); }
// I don't think I've seen this in demos yet, I'll just log it for now and deal with it later protected override void Parse(ref BitStreamReader bsr) { NeedsDecoder = bsr.ReadBool(); ushort len = bsr.ReadUShort(); _props = bsr.Split(len); DemoRef.LogError($"unprocessed {GetType().Name} message"); // todo se2007/engine/dt_send_eng.cpp line 800 }
protected override void Parse(ref BitStreamReader bsr) { Name = bsr.ReadNullTerminatedString(); if (bsr.ReadBool()) { ushort dataLen = bsr.ReadUShort(); Data = bsr.ReadStringOfLength(dataLen); } }
protected override void Parse(ref BitStreamReader bsr) { DataTableId = _classInfoRef == null ? bsr.ReadUShort() : (int)bsr.ReadUInt(DemoRef.DataTableParser.ServerClassBits); ClassName = bsr.ReadNullTerminatedString(); DataTableName = bsr.ReadNullTerminatedString(); }
protected override void Parse(ref BitStreamReader bsr) { Name = bsr.ReadNullTerminatedString(); if (bsr.ReadBool()) { ushort byteLen = bsr.ReadUShort(); Debug.Assert(DemoRef.DataTableParser.FlattenedProps != null); EntryData = StringTableEntryDataFactory.CreateEntryData(DemoRef, null, TableRef.Name, Name); EntryData.ParseStream(bsr.SplitAndSkip(byteLen * 8)); } }
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); }
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)); }
protected override void Parse(ref BitStreamReader bsr) { BatteryVal = bsr.ReadUShort(); }