public void CreateStringTable(CreateStringTable createStringTable) { StringTable stringTable = new StringTable(createStringTable.Name, createStringTable.Flags, createStringTable.MaxEntries); m_Values[stringTable.Name] = stringTable; BitStream bitStream = new BitStream(createStringTable.StringData); Update(bitStream, createStringTable.Name, createStringTable.Flags, createStringTable.NumberOfEntries, createStringTable.MaxEntries, createStringTable.UserDataSize, createStringTable.UserDataSizeInBits, createStringTable.UserDataIsFixedSize); }
public Header(BitStream bitStream) { this.FileType = bitStream.ReadString(); this.DemoProtocol = bitStream.ReadInt32(); this.NetworkProtocol = bitStream.ReadInt32(); this.ServerName = bitStream.ReadString(260); this.ClientName = bitStream.ReadString(260); this.MapName = bitStream.ReadString(260); this.GameDirectory = bitStream.ReadString(260); this.PlaybackTime = bitStream.ReadFloat(); this.PlaybackTicks = bitStream.ReadInt32(); this.PlaybackFrames = bitStream.ReadInt32(); this.SignOnLength = bitStream.ReadInt32(); }
public Demo(string filePath) { using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { m_BitStream = new BitStream(fileStream); } this.DataTables = new DataTableCollection(this); this.Entities = new EntityCollection(this); this.GameEventHandlers = new GameEventHandlers(this); this.GameObservers = new GameObserverCollection(this); this.Header = new Header(m_BitStream); this.PacketHandlers = new PacketHandlers(this); this.ServerClasses = new ServerClassCollection(this); this.StringTables = new StringTableCollection(this); }
public PlayerInfo(byte[] playerInfoData) { BitStream bitStream = new BitStream(playerInfoData); this.Version = bitStream.ReadBigEndianInt64(); this.XUID = bitStream.ReadBigEndianInt64(); this.Name = bitStream.ReadString(128); this.UserID = bitStream.ReadBigEndianInt32(); this.GUID = bitStream.ReadString(33); this.FriendsID = bitStream.ReadBigEndianInt32(); this.FriendsName = bitStream.ReadString(128); this.IsFakePlayer = bitStream.ReadBool(); this.IsHLTV = bitStream.ReadBool(); this.CustomFileCRCs = new int[4]; for (int i = 0; i < CustomFileCRCs.Length; i++) { this.CustomFileCRCs[i] = bitStream.ReadInt32(); } this.FilesDownloaded = bitStream.ReadChar(); }
private float ReadFloat(BitStream bitStream, DataTableProperty dataTableProperty) { float result = 0.0f; if (ReadSpecialFloat(bitStream, dataTableProperty, out result)) { return result; } ulong interp = bitStream.ReadBits(dataTableProperty.NumberOfBits); result = (float)interp / ((1 << dataTableProperty.NumberOfBits) - 1); result = dataTableProperty.LowValue + (dataTableProperty.HighValue - dataTableProperty.LowValue) * result; return result; }
private float ReadBitNormal(BitStream bitStream) { bool isNegative = bitStream.ReadBit(); uint fractionValue = bitStream.ReadBits(HL2SDK.NORMAL_FRACTIONAL_BITS); float value = (float)fractionValue * HL2SDK.NORMAL_RESOLUTION; if (isNegative) { value = -value; } return value; }
private float ReadBitCoordMP(BitStream bitStream, bool isIntegral, bool isLowPrecision) { float value = 0; bool isNegative = false; int integerValue = 0; int fractionValue = 0; bool inBounds = bitStream.ReadBit(); if (isIntegral) { integerValue = bitStream.ReadBit() ? 1 : 0; if (integerValue == 1) { isNegative = bitStream.ReadBit(); if (inBounds) { value = (float)(bitStream.ReadBits(11) + 1); } else { value = (float)(bitStream.ReadBits(14) + 1); } } } else { integerValue = bitStream.ReadBit() ? 1 : 0; isNegative = bitStream.ReadBit(); if (integerValue == 1) { if (inBounds) { value = (float)(bitStream.ReadBits(11) + 1); } else { value = (float)(bitStream.ReadBits(14) + 1); } } fractionValue = (int)bitStream.ReadBits(isLowPrecision ? 3 : 5); value = integerValue + ((float)fractionValue * (isLowPrecision ? HL2SDK.COORD_RESOLUTION_LOWPRECISION : HL2SDK.COORD_RESOLUTION)); } if (isNegative) { value = -value; } return value; }
private float ReadBitCoord(BitStream bitStream) { float value = 0; bool isNegative = false; int integerValue = (int)bitStream.ReadBits(1); int fractionValue = (int)bitStream.ReadBits(1); if ((integerValue | fractionValue) != 0) { isNegative = bitStream.ReadBit(); if (integerValue == 1) { integerValue = (int)bitStream.ReadBits(14) + 1; } if (fractionValue == 1) { fractionValue = (int)bitStream.ReadBits(HL2SDK.COORD_FRACTIONAL_BITS); } value = integerValue + ((float)fractionValue * HL2SDK.COORD_RESOLUTION); } if (isNegative) { value = -value; } return value; }
public ProtoMessage(byte[] protoMessageData) { this.Values = new Dictionary<String, List<Object>>(); BitStream bitStream = new BitStream(protoMessageData); while ((bitStream.PositionInBytes) < bitStream.LengthInBytes) { int key = bitStream.ReadVarint32(); int fieldNumber = key >> 3; int wireType = key & 7; object value = null; switch (wireType) { case 0: { value = bitStream.ReadVarint32(); break; } case 1: { Console.WriteLine("ProtoMessage WireType 1"); bitStream.SeekBytes(0, SeekOrigin.End); break; } case 2: { int length = bitStream.ReadVarint32(); byte[] buffer = bitStream.ReadBytes(length); value = buffer; break; } case 5: { value = bitStream.ReadFloat(); break; } default: { Console.WriteLine("Unknown ProtoMessage WireType: {0}", wireType); bitStream.SeekBytes(0, SeekOrigin.End); return; } } if (value != null) { List<Object> fieldValues; if (this.Values.TryGetValue(fieldNumber.ToString(), out fieldValues)) { fieldValues.Add(value); } else { fieldValues = new List<Object>(); fieldValues.Add(value); this.Values.Add(fieldNumber.ToString(), fieldValues); } } } }
private Vector ReadVector(BitStream bitStream, DataTableProperty dataTableProperty) { Vector result = new Vector(); result.X = ReadFloat(bitStream, dataTableProperty); result.Y = ReadFloat(bitStream, dataTableProperty); if (!dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.Normal)) { result.Z = ReadFloat(bitStream, dataTableProperty); } else { bool isNegative = bitStream.ReadBit(); float absolute = result.X * result.X + result.Y * result.Y; if (absolute < 1.0f) { result.Z = (float)Math.Sqrt(1 - absolute); } else { result.Z = 0f; } if (isNegative) { result.Z *= -1; } } return result; }
private bool ReadSpecialFloat(BitStream bitStream, DataTableProperty dataTableProperty, out float result) { if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.Coord)) { result = ReadBitCoord(bitStream); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.CoordMp)) { result = ReadBitCoordMP(bitStream, false, false); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.CoordMpLowPrecision)) { result = ReadBitCoordMP(bitStream, false, true); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.CoordMpIntegral)) { result = ReadBitCoordMP(bitStream, true, false); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.NoScale)) { result = bitStream.ReadFloat(); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.Normal)) { result = ReadBitNormal(bitStream); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.CellCoord)) { result = ReadBitCellCoord(bitStream, dataTableProperty.NumberOfBits, false, false); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.CellCoordLowPrecision)) { result = ReadBitCellCoord(bitStream, dataTableProperty.NumberOfBits, false, true); return true; } else if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.CellCoordIntegral)) { result = ReadBitCellCoord(bitStream, dataTableProperty.NumberOfBits, true, false); return true; } result = 0; return false; }
private void PacketEntities(byte[] packetBuffer) { PacketEntities packetEntitys = new PacketEntities(packetBuffer); BitStream bitStream = new BitStream(packetEntitys.EntityData); int entityIndex = -1; EntityHeaderFlags entityHeaderFlags = EntityHeaderFlags.FHDR_ZERO; EntityUpdateType entityUpdateType = EntityUpdateType.PreserveEnt; bool isDelta = packetEntitys.IsDelta; int lastEntityIndex = -1; int updatedEntries = packetEntitys.UpdatedEntries; while (entityUpdateType < EntityUpdateType.Finished) { updatedEntries--; bool isEntity = (updatedEntries >= 0) ? true : false; if (isEntity) { entityHeaderFlags = EntityHeaderFlags.FHDR_ZERO; entityIndex = (int)(bitStream.ReadUBitInt() + lastEntityIndex + 1); lastEntityIndex = entityIndex; if (!bitStream.ReadBit()) { if (bitStream.ReadBit()) { entityHeaderFlags |= EntityHeaderFlags.FHDR_ENTERPVS; } } else { entityHeaderFlags |= EntityHeaderFlags.FHDR_LEAVEPVS; if (bitStream.ReadBit()) { entityHeaderFlags |= EntityHeaderFlags.FHDR_DELETE; } } } for (entityUpdateType = EntityUpdateType.PreserveEnt; entityUpdateType == EntityUpdateType.PreserveEnt;) { if (!isEntity || entityIndex > HL2SDK.ENTITY_SENTINEL) { entityUpdateType = EntityUpdateType.Finished; } else { if (entityHeaderFlags.HasFlag(EntityHeaderFlags.FHDR_ENTERPVS)) { entityUpdateType = EntityUpdateType.EnterPVS; } else if (entityHeaderFlags.HasFlag(EntityHeaderFlags.FHDR_LEAVEPVS)) { entityUpdateType = EntityUpdateType.LeavePVS; } else { entityUpdateType = EntityUpdateType.DeltaEnt; } } switch (entityUpdateType) { case EntityUpdateType.DeltaEnt: { Entity entity = m_Demo.Entities.GetEntity(entityIndex); if (entity != null) { entity.Update(bitStream, true); } else { Console.WriteLine("EntityUpdateType.DeltaEnt: entity == null"); throw new Exception("EntityUpdateType.DeltaEnt: entity == null"); } break; } case EntityUpdateType.EnterPVS: { uint serverClassID = bitStream.ReadBits((int)Math.Ceiling(Math.Log(m_Demo.ServerClasses.Count, 2))); uint seiral = bitStream.ReadBits(10); ServerClass serverClass = m_Demo.ServerClasses.GetServerClass((int)serverClassID); Entity entity = new Entity(m_Demo, entityIndex, seiral, serverClass); entity.Update(bitStream, false); m_Demo.Entities.Add(entity); break; } case EntityUpdateType.LeavePVS: { if (!isDelta) { Console.WriteLine("WARNING: EntityUpdateType.LeavePVS on Full Update"); entityUpdateType = EntityUpdateType.Failed; throw new Exception("WARNING: EntityUpdateType.LeavePVS on Full Update"); } else { m_Demo.Entities.Remove(entityIndex); } break; } case EntityUpdateType.PreserveEnt: { if (!isDelta) { Console.WriteLine("WARNING: EntityUpdateType.PreserveEnt on Full Update"); entityUpdateType = EntityUpdateType.Failed; throw new Exception("WARNING: EntityUpdateType.PreserveEnt on Full Update"); } else { if (entityIndex >= HL2SDK.MAX_EDICTS) { Console.WriteLine("EntityUpdateType.PreserveEnt: entityIndex == MAX_EDICTS"); throw new Exception("EntityUpdateType.PreserveEnt: entityIndex == MAX_EDICTS"); } else { } } break; } } } } }
private void Update(BitStream bitStream, string tableName, int tableFlags, int numberOfEntries, int maxEntries, int userDataSize, int userDataSizeInBits, bool userDataIsFixedSize) { bool encodeUsingDictionaries = bitStream.ReadBit(); if (encodeUsingDictionaries) { Console.WriteLine("Cannot Decode StringTable Update"); return; } List<String> entryHistory = new List<String>(); int lastEntriesIndex = -1; for (int i = 0; i < numberOfEntries; i++) { int entryIndex = lastEntriesIndex + 1; int entryLength = (int)Math.Log(maxEntries, 2); if (!bitStream.ReadBit()) { entryIndex = (int)bitStream.ReadBits(entryLength); } lastEntriesIndex = entryIndex; if (entryIndex < 0 || entryIndex >= maxEntries) { Console.WriteLine("Invalid StringTableEntry Index"); return; } string entryName = ""; if (bitStream.ReadBit()) { bool substringCheck = bitStream.ReadBit(); if (substringCheck) { int index = (int)bitStream.ReadBits(5); int bytesToCopy = (int)bitStream.ReadBits(5); entryName = entryHistory[index].Substring(0, bytesToCopy); entryName += bitStream.ReadString(); } else { entryName = bitStream.ReadString(); } } if (entryHistory.Count > 31) { entryHistory.RemoveAt(0); } entryHistory.Add(entryName); byte[] entryData = null; if (bitStream.ReadBit()) { if (userDataIsFixedSize) { entryData = bitStream.ReadBitsToArray(userDataSizeInBits); } else { int bytesToRead = (int)bitStream.ReadBits(14); entryData = bitStream.ReadBytes(bytesToRead); } } StringTableEntry stringTableEntry = new StringTableEntry(entryName, entryIndex, entryData); Add(tableName, stringTableEntry); } }
public void UpdateStringTable(UpdateStringTable updateStringTable) { BitStream bitStream = new BitStream(updateStringTable.StringData); StringTable stringTable = m_Values.Values.ElementAt(updateStringTable.TableID); Update(bitStream, stringTable.Name, stringTable.Flags, updateStringTable.NumberOfEntriesChanged, stringTable.MaxEntries, 0, 0, false); }
private bool ProcessTick() { DemoCommand demoCommand = (DemoCommand)m_BitStream.ReadByte(); int tickNumber = m_BitStream.ReadInt32(); int playerSlot = m_BitStream.ReadByte(); switch (demoCommand) { case DemoCommand.DataTables: { int length = m_BitStream.ReadInt32(); byte[] data = m_BitStream.ReadBytes(length); BitStream bitStream = new BitStream(data); while (true) { int dataTableType = bitStream.ReadVarint32(); int dataTablelength = bitStream.ReadVarint32(); byte[] dataTableData = bitStream.ReadBytes(dataTablelength); DataTable dataTable = new DataTable(this.DataTables.Count, dataTableData); if (dataTable.IsEnd) { break; } else { this.DataTables.Add(dataTable); } } int count = bitStream.ReadShort(); for (int i = 0; i < count; i++) { int serverClassID = bitStream.ReadShort(); string serverClassName = bitStream.ReadString(); string dataTableName = bitStream.ReadString(); DataTable dataTable = this.DataTables.GetDataTable(dataTableName); ServerClass serverClass = new ServerClass(serverClassID, serverClassName, dataTable.ID, dataTable.Name); this.ServerClasses.Add(serverClass); } this.ServerClasses.ProcessAllServerClasses(); break; } case DemoCommand.Packet: case DemoCommand.SignOn: { m_BitStream.SeekBytes(160, SeekOrigin.Current); int length = m_BitStream.ReadInt32(); byte[] data = m_BitStream.ReadBytes(length); BitStream packetReader = new BitStream(data); while (packetReader.PositionInBytes < packetReader.LengthInBytes) { int packetID = packetReader.ReadVarint32(); int packetLength = packetReader.ReadVarint32(); byte[] packetData = packetReader.ReadBytes(packetLength); PacketType packetType; if (!Enum.TryParse<PacketType>(packetID.ToString(), out packetType)) { Console.WriteLine("Unknown Packet Type: {0}", packetID); break; } this.PacketHandlers.OnPacketReceived(packetType, packetData); } break; } case DemoCommand.Stop: { return true; } case DemoCommand.StringTables: { int length = m_BitStream.ReadInt32(); byte[] data = m_BitStream.ReadBytes(length); BitStream bitStream = new BitStream(data); int stringTableCount = bitStream.ReadByte(); for (int i = 0; i < stringTableCount; i++) { string stringTableName = bitStream.ReadString(); int entryCount = bitStream.ReadUShort(); for (int j = 0; j < entryCount; j++) { string entryName = bitStream.ReadString(); bool entryHasData = bitStream.ReadBit(); byte[] entryData = null; if (entryHasData) { int entryDataLength = bitStream.ReadShort(); entryData = bitStream.ReadBytes(entryDataLength); } StringTableEntry stringTableEntry = new StringTableEntry(entryName, entryData); this.StringTables.Add(stringTableName, stringTableEntry); } bool hasExtraTableData = bitStream.ReadBit(); if (hasExtraTableData) { int extraTableDataLength = bitStream.ReadShort(); byte[] extraTableData = bitStream.ReadBytes(extraTableDataLength); } } break; } case DemoCommand.SyncTick: { break; } default: { Console.WriteLine("Unknown Demo Command: {0}", demoCommand); break; } } return false; }
private int ReadInt32(BitStream bitStream, DataTableProperty dataTableProperty) { if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.Varint)) { if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.Unsigned)) { return (int)bitStream.ReadVarint32(); } else { return (int)bitStream.ReadVarint32(); } } else { if (dataTableProperty.Flags.HasFlag(DataTablePropertyFlags.Unsigned)) { return (int)bitStream.ReadBits(dataTableProperty.NumberOfBits); } else { return (int)bitStream.ReadBits(dataTableProperty.NumberOfBits); } } }
private object ReadServerClassProperty(BitStream bitStream, ServerClassProperty serverClassProperty) { DataTableProperty dataTableProperty = serverClassProperty.DataTableProperty; object result = null; switch (dataTableProperty.Type) { case DataTablePropertyType.Int: { result = ReadInt32(bitStream, dataTableProperty); break; } case DataTablePropertyType.Float: { result = ReadFloat(bitStream, dataTableProperty); break; } case DataTablePropertyType.Vector: { result = ReadVector(bitStream, dataTableProperty); break; } case DataTablePropertyType.Array: { result = ReadArray(bitStream, serverClassProperty); break; } case DataTablePropertyType.String: { result = ReadString(bitStream, dataTableProperty); break; } case DataTablePropertyType.VectorXY: { result = ReadVectorXY(bitStream, dataTableProperty); break; } default: { Console.WriteLine("Unable to Decode Property"); break; } } return result; }
public void Update(BitStream bitStream) { object value; switch (this.ServerClassProperty.DataTableProperty.Type) { case DataTablePropertyType.Int: { value = ReadInt32(bitStream, this.ServerClassProperty.DataTableProperty); break; } case DataTablePropertyType.Float: { value = ReadFloat(bitStream, this.ServerClassProperty.DataTableProperty); break; } case DataTablePropertyType.Vector: { value = ReadVector(bitStream, this.ServerClassProperty.DataTableProperty); break; } case DataTablePropertyType.Array: { value = ReadArray(bitStream, this.ServerClassProperty); break; } case DataTablePropertyType.String: { value = ReadString(bitStream, this.ServerClassProperty.DataTableProperty); break; } case DataTablePropertyType.VectorXY: { value = ReadVectorXY(bitStream, this.ServerClassProperty.DataTableProperty); break; } default: { Console.WriteLine("Unable to Decode EntityProperty"); value = null; break; } } this.Value = value; }
private string ReadString(BitStream bitStream, DataTableProperty dataTableProperty) { int length = (int)bitStream.ReadBits(9); string result = bitStream.ReadString(length); return result; }
private object[] ReadArray(BitStream bitStream, ServerClassProperty serverClassProperty) { int numberOfElements = serverClassProperty.DataTableProperty.NumberOfElements; int maxElements = numberOfElements; int numberOfBits = 1; while ((maxElements >>= 1) != 0) { numberOfBits++; } int count = (int)bitStream.ReadBits(numberOfBits); object[] result = new object[count]; ServerClassProperty intermediaryServerClassProperty = new ServerClassProperty("", serverClassProperty.ArrayElementProperty, null); for (int i = 0; i < count; i++) { result[i] = ReadServerClassProperty(bitStream, intermediaryServerClassProperty); } return result; }
private Vector ReadVectorXY(BitStream bitStream, DataTableProperty dataTableProperty) { Vector result = new Vector(); result.X = ReadFloat(bitStream, dataTableProperty); result.Y = ReadFloat(bitStream, dataTableProperty); return result; }
private float ReadBitCellCoord(BitStream bitStream, int numberOfBits, bool isIntegral, bool isLowPrecision) { float value = 0.0f; int integerValue = 0; int fractionValue = 0; if (isIntegral) { value = (float)bitStream.ReadBits(numberOfBits); } else { integerValue = (int)bitStream.ReadBits(numberOfBits); fractionValue = (int)bitStream.ReadBits(isLowPrecision ? HL2SDK.COORD_FRACTIONAL_BITS_MP_LOWPRECISION : HL2SDK.COORD_FRACTIONAL_BITS); value = integerValue + ((float)fractionValue * (isLowPrecision ? HL2SDK.COORD_RESOLUTION_LOWPRECISION : HL2SDK.COORD_RESOLUTION)); } return value; }