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 HalfLifeDeltaStructure GetDeltaStructure(String name) { HalfLifeDeltaStructure structure = (HalfLifeDeltaStructure)deltaDecoderTable[name]; if (structure == null) { throw new ApplicationException("Delta structure \"" + name + "\" not found."); } return(structure); }
// public so svc_deltadescription can be parsed elsewhere public void AddDeltaStructure(HalfLifeDeltaStructure structure) { // remove decoder if it already exists (duplicate svc_deltadescription message) // e.g. GotFrag Demo 6 (rs vs TSO).zip if (deltaDecoderTable[structure.Name] != null) { deltaDecoderTable.Remove(structure.Name); } deltaDecoderTable.Add(structure.Name, structure); }
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); }
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); }
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 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 HalfLifeDemoParser(HalfLifeDemo demo) { this.demo = demo; // message handlers AddMessageHandler((Byte)MessageId.svc_nop, 0); AddMessageHandler((Byte)MessageId.svc_disconnect, MessageDisconnect); AddMessageHandler((Byte)MessageId.svc_event, MessageEvent); AddMessageHandler((Byte)MessageId.svc_version, MessageVersion); AddMessageHandler((Byte)MessageId.svc_setview, 2); AddMessageHandler((Byte)MessageId.svc_sound, MessageSound); AddMessageHandler((Byte)MessageId.svc_time, 4); AddMessageHandler((Byte)MessageId.svc_print, MessagePrint); AddMessageHandler((Byte)MessageId.svc_stufftext, MessageStuffText); AddMessageHandler((Byte)MessageId.svc_setangle, 6); AddMessageHandler((Byte)MessageId.svc_serverinfo, MessageServerInfo); AddMessageHandler((Byte)MessageId.svc_lightstyle, MessageLightStyle); AddMessageHandler((Byte)MessageId.svc_updateuserinfo, MessageUpdateUserInfo); AddMessageHandler((Byte)MessageId.svc_deltadescription, MessageDeltaDescription); AddMessageHandler((Byte)MessageId.svc_clientdata, MessageClientData); AddMessageHandler((Byte)MessageId.svc_stopsound, 2); AddMessageHandler((Byte)MessageId.svc_pings, MessagePings); AddMessageHandler((Byte)MessageId.svc_particle, 11); AddMessageHandler((Byte)MessageId.svc_spawnstatic, MessageSpawnStatic); AddMessageHandler((Byte)MessageId.svc_event_reliable, MessageEventReliable); AddMessageHandler((Byte)MessageId.svc_spawnbaseline, MessageSpawnBaseline); AddMessageHandler((Byte)MessageId.svc_tempentity, MessageTempEntity); AddMessageHandler((Byte)MessageId.svc_setpause, MessageSetPause); AddMessageHandler((Byte)MessageId.svc_signonnum, 1); AddMessageHandler((Byte)MessageId.svc_centerprint, MessageCenterPrint); AddMessageHandler((Byte)MessageId.svc_spawnstaticsound, 14); AddMessageHandler((Byte)MessageId.svc_intermission, 0); AddMessageHandler((Byte)MessageId.svc_finale, 1); AddMessageHandler((Byte)MessageId.svc_cdtrack, 2); AddMessageHandler((Byte)MessageId.svc_weaponanim, 2); AddMessageHandler((Byte)MessageId.svc_roomtype, 2); AddMessageHandler((Byte)MessageId.svc_addangle, 2); AddMessageHandler((Byte)MessageId.svc_newusermsg, MessageNewUserMsg); AddMessageHandler((Byte)MessageId.svc_packetentities, MessagePacketEntities); AddMessageHandler((Byte)MessageId.svc_deltapacketentities, MessageDeltaPacketEntities); AddMessageHandler((Byte)MessageId.svc_choke, 0); AddMessageHandler((Byte)MessageId.svc_resourcelist, MessageResourceList); AddMessageHandler((Byte)MessageId.svc_newmovevars, MessageNewMoveVars); AddMessageHandler((Byte)MessageId.svc_resourcerequest, 8); AddMessageHandler((Byte)MessageId.svc_customization, MessageCustomization); AddMessageHandler((Byte)MessageId.svc_crosshairangle, 2); AddMessageHandler((Byte)MessageId.svc_soundfade, 4); AddMessageHandler((Byte)MessageId.svc_filetxferfailed, MessageFileTransferFailed); AddMessageHandler((Byte)MessageId.svc_hltv, MessageHltv); AddMessageHandler((Byte)MessageId.svc_director, MessageDirector); AddMessageHandler((Byte)MessageId.svc_voiceinit, MessageVoiceInit); AddMessageHandler((Byte)MessageId.svc_voicedata, MessageVoiceData); AddMessageHandler((Byte)MessageId.svc_sendextrainfo, MessageSendExtraInfo); AddMessageHandler((Byte)MessageId.svc_timescale, 4); AddMessageHandler((Byte)MessageId.svc_resourcelocation, MessageResourceLocation); AddMessageHandler((Byte)MessageId.svc_sendcvarvalue, MessageSendCvarValue); AddMessageHandler((Byte)MessageId.svc_sendcvarvalue2, MessageSendCvarValue2); // user messages userMessageTable = new Hashtable(); userMessageCallbackTable = new Hashtable(); // delta descriptions deltaDecoderTable = new Hashtable(); HalfLifeDeltaStructure deltaDescription = new HalfLifeDeltaStructure("delta_description_t"); AddDeltaStructure(deltaDescription); deltaDescription.AddEntry("flags", 32, 1.0f, HalfLifeDeltaStructure.EntryFlags.Integer); deltaDescription.AddEntry("name", 8, 1.0f, HalfLifeDeltaStructure.EntryFlags.String); deltaDescription.AddEntry("offset", 16, 1.0f, HalfLifeDeltaStructure.EntryFlags.Integer); deltaDescription.AddEntry("size", 8, 1.0f, HalfLifeDeltaStructure.EntryFlags.Integer); deltaDescription.AddEntry("nBits", 8, 1.0f, HalfLifeDeltaStructure.EntryFlags.Integer); deltaDescription.AddEntry("divisor", 32, 4000.0f, HalfLifeDeltaStructure.EntryFlags.Float); deltaDescription.AddEntry("preMultiplier", 32, 4000.0f, HalfLifeDeltaStructure.EntryFlags.Float); }