public void MessageDeltaDescription() { String structureName = bitBuffer.ReadString(); if (demo.NetworkProtocol == 43) { bitBuffer.Endian = BitBuffer.EndianType.Big; } UInt32 nEntries = bitBuffer.ReadUnsignedBits(16); HalfLifeDeltaStructure newDeltaStructure = new HalfLifeDeltaStructure(structureName); AddDeltaStructure(newDeltaStructure); HalfLifeDeltaStructure deltaDescription = GetDeltaStructure("delta_description_t"); for (UInt16 i = 0; i < nEntries; i++) { HalfLifeDelta newDelta = deltaDescription.CreateDelta(); deltaDescription.ReadDelta(bitBuffer, newDelta); newDeltaStructure.AddEntry(newDelta); } bitBuffer.SkipRemainingBits(); bitBuffer.Endian = BitBuffer.EndianType.Little; }
public Byte[] CreateDeltaBitmask(HalfLifeDelta delta) { UInt32 nBitmaskBytes = (UInt32)((entryList.Count / 8) + (entryList.Count % 8 > 0 ? 1 : 0)); Byte[] bitmaskBytes = new Byte[nBitmaskBytes]; for (Int32 i = 0; i < bitmaskBytes.Length; i++) { for (Int32 j = 0; j < 8; j++) { Int32 index = j + i * 8; if (index >= entryList.Count) { break; } if (delta.FindEntryValue(entryList[index].Name) != null) { bitmaskBytes[i] |= (Byte)(1 << j); } } } return(bitmaskBytes); }
public void WriteDelta(BitWriter bitWriter, HalfLifeDelta delta, Byte[] bitmaskBytes) { if (bitmaskBytes == null) // no bitmask bytes { bitWriter.WriteUnsignedBits(0, 3); return; } bitWriter.WriteUnsignedBits((UInt32)bitmaskBytes.Length, 3); for (Int32 i = 0; i < bitmaskBytes.Length; i++) { bitWriter.WriteByte(bitmaskBytes[i]); } for (Int32 i = 0; i < bitmaskBytes.Length; i++) { for (Int32 j = 0; j < 8; j++) { Int32 index = j + i * 8; if (index == entryList.Count) { return; } if ((bitmaskBytes[i] & (1 << j)) != 0) { WriteEntry(delta, bitWriter, entryList[index]); } } } }
/// <summary> /// Adds an entry. Delta is assumed to be delta_description_t. Should only need to be called when parsing svc_deltadescription. /// </summary> /// <param name="delta"></param> public void AddEntry(HalfLifeDelta delta) { String name = (String)delta.FindEntryValue("name"); UInt32 nBits = (UInt32)delta.FindEntryValue("nBits"); Single divisor = (Single)delta.FindEntryValue("divisor"); EntryFlags flags = (EntryFlags)((UInt32)delta.FindEntryValue("flags")); //Single preMultiplier = (Single)delta.FindEntryValue("preMultiplier"); AddEntry(name, nBits, divisor, flags); }
public HalfLifeDelta CreateDelta() { HalfLifeDelta delta = new HalfLifeDelta(entryList.Count); // create delta structure with the same entries as the delta decoder, but no data foreach (Entry e in entryList) { delta.AddEntry(e.Name); } return(delta); }
private void MessageDeltaDescription() { if (!demo.ConvertNetworkProtocol() || demo.NetworkProtocol > 43) { parser.MessageDeltaDescription(); return; } Int32 messageStartOffset = parser.BitBuffer.CurrentByte; parser.BitBuffer.Endian = BitBuffer.EndianType.Big; BitWriter bitWriter = new BitWriter(); // read/write message String structureName = parser.BitBuffer.ReadString(); bitWriter.WriteString(structureName); UInt32 nEntries = parser.BitBuffer.ReadUnsignedBits(16); bitWriter.WriteUnsignedBits(nEntries, 16); HalfLifeDeltaStructure newDeltaStructure = new HalfLifeDeltaStructure(structureName); parser.AddDeltaStructure(newDeltaStructure); HalfLifeDeltaStructure deltaDescription = parser.GetDeltaStructure("delta_description_t"); for (UInt16 i = 0; i < nEntries; i++) { HalfLifeDelta delta = deltaDescription.CreateDelta(); Byte[] bitmaskBytes; deltaDescription.ReadDelta(parser.BitBuffer, delta, out bitmaskBytes); if (demo.Game != null) { demo.Game.ConvertDeltaDescriptionCallback(demo.GameVersion, structureName, delta); } deltaDescription.WriteDelta(bitWriter, delta, bitmaskBytes); newDeltaStructure.AddEntry(delta); } parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
public void ReadDelta(BitBuffer bitBuffer, HalfLifeDelta delta, out Byte[] bitmaskBytes) { // read bitmask UInt32 nBitmaskBytes = bitBuffer.ReadUnsignedBits(3); // TODO: error check nBitmaskBytes against nEntries if (nBitmaskBytes == 0) { bitmaskBytes = null; return; } bitmaskBytes = new Byte[nBitmaskBytes]; for (Int32 i = 0; i < nBitmaskBytes; i++) { bitmaskBytes[i] = bitBuffer.ReadByte(); } for (Int32 i = 0; i < nBitmaskBytes; i++) { for (Int32 j = 0; j < 8; j++) { Int32 index = j + i * 8; if (index == entryList.Count) { return; } if ((bitmaskBytes[i] & (1 << j)) != 0) { Object value = ParseEntry(bitBuffer, entryList[index]); if (delta != null) { delta.SetEntryValue(index, value); } } } } }
public virtual void ConvertPacketEntititiesCallback(HalfLifeDelta delta, String entityType, Int32 gameVersion) { }
public void ReadDelta(BitBuffer bitBuffer, HalfLifeDelta delta) { Byte[] bitmaskBytes; ReadDelta(bitBuffer, delta, out bitmaskBytes); }
private void WriteEntry(HalfLifeDelta delta, BitWriter bitWriter, Entry e) { Boolean signed = ((e.Flags & EntryFlags.Signed) != 0); Object value = delta.FindEntryValue(e.Name); if ((e.Flags & EntryFlags.Byte) != 0) { if (signed) { SByte writeValue = (SByte)value; WriteInt(bitWriter, e, (Int32)writeValue); } else { Byte writeValue = (Byte)value; WriteUnsignedInt(bitWriter, e, (UInt32)writeValue); } } else if ((e.Flags & EntryFlags.Short) != 0) { if (signed) { Int16 writeValue = (Int16)value; WriteInt(bitWriter, e, (Int32)writeValue); } else { UInt16 writeValue = (UInt16)value; WriteUnsignedInt(bitWriter, e, (UInt32)writeValue); } } else if ((e.Flags & EntryFlags.Integer) != 0) { if (signed) { WriteInt(bitWriter, e, (Int32)value); } else { WriteUnsignedInt(bitWriter, e, (UInt32)value); } } else if ((e.Flags & EntryFlags.Angle) != 0) { bitWriter.WriteUnsignedBits((UInt32)((Single)value / (360.0f / (Single)(1 << (Int32)e.nBits))), (Int32)e.nBits); } else if ((e.Flags & EntryFlags.String) != 0) { bitWriter.WriteString((String)value); } else if ((e.Flags & EntryFlags.Float) != 0 || (e.Flags & EntryFlags.TimeWindow8) != 0 || (e.Flags & EntryFlags.TimeWindowBig) != 0) { Single writeValue = (Single)value; Int32 bitsToWrite = (Int32)e.nBits; if (signed) { bitWriter.WriteBoolean(writeValue < 0); bitsToWrite--; } bitWriter.WriteUnsignedBits((UInt32)(Math.Abs(writeValue) * e.Divisor), bitsToWrite); } else { throw new ApplicationException(String.Format("Unknown delta entry type {0}.", e.Flags)); } }
private void MessageEvent() { if (!demo.ConvertNetworkProtocol()) { parser.MessageEvent(); return; } Int32 messageStartOffset = parser.BitBuffer.CurrentByte; // read message if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } BitWriter bitWriter = new BitWriter(); HalfLifeDeltaStructure eventStructure = parser.GetDeltaStructure("event_t"); UInt32 nEvents = parser.BitBuffer.ReadUnsignedBits(5); bitWriter.WriteUnsignedBits(nEvents, 5); for (Int32 i = 0; i < nEvents; i++) { UInt32 eventIndex = parser.BitBuffer.ReadUnsignedBits(10); bitWriter.WriteUnsignedBits(eventIndex, 10); // event index Boolean packetIndexBit = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(packetIndexBit); if (packetIndexBit) { bitWriter.WriteUnsignedBits(parser.BitBuffer.ReadUnsignedBits(11), 11); // packet index Boolean deltaBit = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(deltaBit); if (deltaBit) { HalfLifeDelta delta = eventStructure.CreateDelta(); Byte[] bitmaskBytes; eventStructure.ReadDelta(parser.BitBuffer, delta, out bitmaskBytes); if (demo.Game != null) { demo.Game.ConvertEventCallback(demo, delta, eventIndex); } eventStructure.WriteDelta(bitWriter, delta, bitmaskBytes); } } Boolean fireTimeBit = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(fireTimeBit); if (fireTimeBit) { bitWriter.WriteUnsignedBits(parser.BitBuffer.ReadUnsignedBits(16), 16); // fire time } } parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
public virtual void ConvertEventCallback(Demo demo, HalfLifeDelta delta, UInt32 eventIndex) { }
private void MessageClientData() { if (demo.Perspective == Demo.Perspectives.Hltv) { return; } if (!demo.ConvertNetworkProtocol() || demo.IsBetaSteam()) { parser.MessageClientData(); return; } // read message Int32 messageStartOffset = parser.BitBuffer.CurrentByte; if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } BitWriter bitWriter = new BitWriter(); HalfLifeDeltaStructure clientDataStructure = parser.GetDeltaStructure("clientdata_t"); HalfLifeDeltaStructure weaponDataStructure = parser.GetDeltaStructure("weapon_data_t"); Boolean deltaSequence = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(deltaSequence); UInt32 deltaSequenceNumber = 0; if (deltaSequence) { deltaSequenceNumber = parser.BitBuffer.ReadUnsignedBits(8); bitWriter.WriteUnsignedBits(deltaSequenceNumber, 8); } HalfLifeDelta clientData = clientDataStructure.CreateDelta(); Byte[] clientDataBitmaskBytes; clientDataStructure.ReadDelta(parser.BitBuffer, clientData, out clientDataBitmaskBytes); clientDataStructure.WriteDelta(bitWriter, clientData, clientDataBitmaskBytes); while (parser.BitBuffer.ReadBoolean()) { bitWriter.WriteBoolean(true); if (demo.NetworkProtocol < 47 && !demo.IsBetaSteam()) { bitWriter.WriteUnsignedBits(parser.BitBuffer.ReadUnsignedBits(5), 6); } else { bitWriter.WriteUnsignedBits(parser.BitBuffer.ReadUnsignedBits(6), 6); } HalfLifeDelta weaponData = weaponDataStructure.CreateDelta(); Byte[] bitmaskBytes; weaponDataStructure.ReadDelta(parser.BitBuffer, weaponData, out bitmaskBytes); weaponDataStructure.WriteDelta(bitWriter, weaponData, bitmaskBytes); } bitWriter.WriteBoolean(false); parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
private void MessageDeltaPacketEntities() { if (!demo.ConvertNetworkProtocol() || demo.IsBetaSteam()) { parser.MessageDeltaPacketEntities(); return; } Int32 messageStartOffset = parser.BitBuffer.CurrentByte; BitWriter bitWriter = new BitWriter(); // read message bitWriter.WriteUInt16(parser.BitBuffer.ReadUInt16()); // nEntities/maxEntities if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } bitWriter.WriteByte(parser.BitBuffer.ReadByte()); // delta sequence number UInt32 entityNumber = 0; while (true) { // check for footer UInt16 footer = parser.BitBuffer.ReadUInt16(); if (footer == 0) { bitWriter.WriteUInt16(footer); break; } parser.BitBuffer.SeekBits(-16); // option bits Boolean removeEntity = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(removeEntity); Boolean absoluteEntityNumber = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(absoluteEntityNumber); // entity number if (absoluteEntityNumber) { entityNumber = parser.BitBuffer.ReadUnsignedBits(11); bitWriter.WriteUnsignedBits(entityNumber, 11); } else { UInt32 deltaEntityNumber = parser.BitBuffer.ReadUnsignedBits(6); bitWriter.WriteUnsignedBits(deltaEntityNumber, 6); entityNumber += deltaEntityNumber; } if (!removeEntity) { // entity type Boolean custom = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(custom); if (demo.NetworkProtocol <= 43) { parser.BitBuffer.SeekBits(1); // unknown, always 0 } String entityType = "entity_state_t"; if (entityNumber > 0 && entityNumber <= demo.MaxClients) { entityType = "entity_state_player_t"; } else if (custom) { entityType = "custom_entity_state_t"; } // delta compressed data Byte[] bitmaskBytes; HalfLifeDeltaStructure deltaDecoder = parser.GetDeltaStructure(entityType); HalfLifeDelta deltaEntity = deltaDecoder.CreateDelta(); deltaDecoder.ReadDelta(parser.BitBuffer, deltaEntity, out bitmaskBytes); if (demo.Game != null) { demo.Game.ConvertPacketEntititiesCallback(deltaEntity, entityType, demo.GameVersion); } deltaDecoder.WriteDelta(bitWriter, deltaEntity, bitmaskBytes); } } parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
private void MessagePacketEntities() { if (!demo.ConvertNetworkProtocol()) { parser.MessagePacketEntities(); return; } Int32 messageStartOffset = parser.BitBuffer.CurrentByte; BitWriter bitWriter = new BitWriter(); // read message into new message bitWriter.WriteUInt16(parser.BitBuffer.ReadUInt16()); // nEntities/maxEntities if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } UInt32 entityNumber = 0; while (true) { UInt16 footer = parser.BitBuffer.ReadUInt16(); if (footer == 0) { bitWriter.WriteUInt16(footer); break; } else { parser.BitBuffer.SeekBits(-16); } if (!parser.BitBuffer.ReadBoolean()) // entity number isn't last entity number + 1, need to read it in { bitWriter.WriteBoolean(false); // is the following entity number absolute, or relative from the last one? if (parser.BitBuffer.ReadBoolean()) { bitWriter.WriteBoolean(true); entityNumber = parser.BitBuffer.ReadUnsignedBits(11); bitWriter.WriteUnsignedBits(entityNumber, 11); } else { bitWriter.WriteBoolean(false); UInt32 entityNumberDelta = parser.BitBuffer.ReadUnsignedBits(6); bitWriter.WriteUnsignedBits(entityNumberDelta, 6); entityNumber += entityNumberDelta; } } else { bitWriter.WriteBoolean(true); entityNumber++; } Boolean custom = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(custom); Boolean baseline = parser.BitBuffer.ReadBoolean(); bitWriter.WriteBoolean(baseline); if (baseline) { bitWriter.WriteUnsignedBits(parser.BitBuffer.ReadUnsignedBits(6), 6); // baseline index } String entityType = "entity_state_t"; if (entityNumber > 0 && entityNumber <= demo.MaxClients) { entityType = "entity_state_player_t"; } else if (custom) { entityType = "custom_entity_state_t"; } HalfLifeDeltaStructure entityStateStructure = parser.GetDeltaStructure(entityType); HalfLifeDelta delta = entityStateStructure.CreateDelta(); Byte[] bitmaskBytes; entityStateStructure.ReadDelta(parser.BitBuffer, delta, out bitmaskBytes); if (demo.Game != null) { demo.Game.ConvertPacketEntititiesCallback(delta, entityType, demo.GameVersion); } entityStateStructure.WriteDelta(bitWriter, delta, bitmaskBytes); } parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
private void MessageSpawnBaseline() { if (!demo.ConvertNetworkProtocol()) { parser.MessageSpawnBaseline(); return; } Int32 messageStartOffset = parser.BitBuffer.CurrentByte; BitWriter bitWriter = new BitWriter(); // read message into new message if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } while (true) { UInt32 entityIndex = parser.BitBuffer.ReadUnsignedBits(11); bitWriter.WriteUnsignedBits(entityIndex, 11); if (entityIndex == (1 << 11) - 1) // all 1's { break; } UInt32 entityType = parser.BitBuffer.ReadUnsignedBits(2); bitWriter.WriteUnsignedBits(entityType, 2); String entityTypeString; if ((entityType & 1) != 0) { if (entityIndex > 0 && entityIndex <= demo.MaxClients) { entityTypeString = "entity_state_player_t"; } else { entityTypeString = "entity_state_t"; } } else { entityTypeString = "custom_entity_state_t"; } HalfLifeDeltaStructure deltaStructure = parser.GetDeltaStructure(entityTypeString); HalfLifeDelta delta = deltaStructure.CreateDelta(); Byte[] bitmaskBytes; deltaStructure.ReadDelta(parser.BitBuffer, delta, out bitmaskBytes); if (demo.Game != null) { demo.Game.ConvertPacketEntititiesCallback(delta, entityTypeString, demo.GameVersion); } deltaStructure.WriteDelta(bitWriter, delta, bitmaskBytes); } UInt32 footer = parser.BitBuffer.ReadUnsignedBits(5); // should be all 1's bitWriter.WriteUnsignedBits(footer, 5); if (footer != (1 << 5) - 1) { throw new ApplicationException("Bad svc_spawnbaseline footer."); } UInt32 nExtraData = parser.BitBuffer.ReadUnsignedBits(6); bitWriter.WriteUnsignedBits(nExtraData, 6); HalfLifeDeltaStructure entityStateStructure = parser.GetDeltaStructure("entity_state_t"); for (Int32 i = 0; i < nExtraData; i++) { HalfLifeDelta delta = entityStateStructure.CreateDelta(); Byte[] bitmaskBytes; entityStateStructure.ReadDelta(parser.BitBuffer, delta, out bitmaskBytes); entityStateStructure.WriteDelta(bitWriter, delta, bitmaskBytes); } parser.BitBuffer.Endian = BitBuffer.EndianType.Little; parser.BitBuffer.SkipRemainingBits(); // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
public HalfLifeDelta CreateDelta() { HalfLifeDelta delta = new HalfLifeDelta(entryList.Count); // create delta structure with the same entries as the delta decoder, but no data foreach (Entry e in entryList) { delta.AddEntry(e.Name); } return delta; }
public Byte[] CreateDeltaBitmask(HalfLifeDelta delta) { UInt32 nBitmaskBytes = (UInt32)((entryList.Count / 8) + (entryList.Count % 8 > 0 ? 1 : 0)); Byte[] bitmaskBytes = new Byte[nBitmaskBytes]; for (Int32 i = 0; i < bitmaskBytes.Length; i++) { for (Int32 j = 0; j < 8; j++) { Int32 index = j + i * 8; if (index >= entryList.Count) { break; } if (delta.FindEntryValue(entryList[index].Name) != null) { bitmaskBytes[i] |= (Byte)(1 << j); } } } return bitmaskBytes; }
public virtual void ConvertDeltaDescriptionCallback(Int32 gameVersion, String deltaStructureName, HalfLifeDelta delta) { }