public void ParsePacketMessages(Int32 dataLength) { Int64 packetStartOffset = Position; parsingPacket = true; // read in data block Byte[] frameData = fileReader.ReadBytes(dataLength); bitBuffer = new BitBuffer(frameData); BeginMessageLog(packetStartOffset, frameData); // parse messages while (true) { if (bitBuffer.BitsLeft < 8) { // done break; } Int32 messageFrameOffset = bitBuffer.CurrentBit; Byte messageId = (Byte)bitBuffer.ReadUnsignedBits(demo.NetworkProtocol >= 16 ? 6 : 5); if (demo.Protocol15Hack) { bitBuffer.SeekBits(1); } String messageName = Enum.GetName(typeof(MessageId), messageId); LogMessage(messageId, messageName, messageFrameOffset); MessageHandler messageHandler = FindMessageHandler(messageId); // unknown message if (messageHandler == null) { throw new ApplicationException(String.Format("Cannot find message handler for message id \"[{0}] {1}\"", messageId, messageName)); } // callback takes priority over length if (messageHandler.Callback != null) { messageHandler.Callback(); } else if (messageHandler.Length != -1) { Seek(messageHandler.Length); } else { throw new ApplicationException(String.Format("Unknown message id \"{0}\"", messageId)); } } parsingPacket = false; }
private void CalculateProtocol15Hack(Int32 dataLength) { /* * Valve broke network protocol 15 by changing the protocol without incrementing the protocol number. * * The change adds an extra bit after each message ID, so the only thing that's guaranteed to read correctly with every protocol 15 demo now if the header. * * The first message in the first sigon frame is always svc_print or svc_serverinfo, so if either of those are invalid, odds are that the demo uses the changed protocol. * */ // read in data block Byte[] frameData = parser.Reader.ReadBytes(dataLength); BitBuffer bitBuffer = new BitBuffer(frameData); // parse messages SourceDemoParser.MessageId messageId = (SourceDemoParser.MessageId)bitBuffer.ReadUnsignedBits(5); if (messageId == SourceDemoParser.MessageId.SVC_Print) { String s = bitBuffer.ReadString(); if (s.Contains("Map") || s.Contains("Build") || s.Contains("Players")) { // Looks like a valid svc_print string. return; } Protocol15Hack = true; } else if (messageId == SourceDemoParser.MessageId.SVC_ServerInfo) { UInt32 networkProtocol = bitBuffer.ReadUnsignedBits(16); if (networkProtocol != this.networkProtocol) { // Should match header, must be invalid. Protocol15Hack = true; } } }
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); } } } } }
private void CalculateProtocol15Hack(Int32 dataLength) { /* * Valve broke network protocol 15 by changing the protocol without incrementing the protocol number. * * The change adds an extra bit after each message ID, so the only thing that's guaranteed to read correctly with every protocol 15 demo now if the header. * * The first message in the first sigon frame is always svc_print or svc_serverinfo, so if either of those are invalid, odds are that the demo uses the changed protocol. * */ // read in data block Byte[] frameData = parser.Reader.ReadBytes(dataLength); BitBuffer bitBuffer = new BitBuffer(frameData); // parse messages SourceDemoParser.MessageId messageId = (SourceDemoParser.MessageId)bitBuffer.ReadUnsignedBits(5); if (messageId == SourceDemoParser.MessageId.SVC_Print) { String s = bitBuffer.ReadString(); if (s.Contains("Map") || s.Contains("Build") || s.Contains("Players")) { // Looks like a valid svc_print string. return; } Protocol15Hack = true; } else if (messageId == SourceDemoParser.MessageId.SVC_ServerInfo) { UInt32 networkProtocol = bitBuffer.ReadUnsignedBits(16); if (networkProtocol != this.networkProtocol) { // Should match header, must be invalid. Protocol15Hack = true; } } }
private UInt32 ParseUnsignedInt(BitBuffer bitBuffer, Entry e) { return(bitBuffer.ReadUnsignedBits((Int32)e.nBits) / (UInt32)e.Divisor); }
private Int32 ParseInt(BitBuffer bitBuffer, Entry e) { Boolean negative = bitBuffer.ReadBoolean(); return((Int32)bitBuffer.ReadUnsignedBits((Int32)e.nBits - 1) / (Int32)e.Divisor * (negative ? -1 : 1)); }
private Object ParseEntry(BitBuffer bitBuffer, Entry e) { Boolean signed = ((e.Flags & EntryFlags.Signed) != 0); if ((e.Flags & EntryFlags.Byte) != 0) { if (signed) { return((SByte)ParseInt(bitBuffer, e)); } else { return((Byte)ParseUnsignedInt(bitBuffer, e)); } } if ((e.Flags & EntryFlags.Short) != 0) { if (signed) { return((Int16)ParseInt(bitBuffer, e)); } else { return((UInt16)ParseUnsignedInt(bitBuffer, e)); } } if ((e.Flags & EntryFlags.Integer) != 0) { if (signed) { return((Int32)ParseInt(bitBuffer, e)); } else { return((UInt32)ParseUnsignedInt(bitBuffer, e)); } } if ((e.Flags & EntryFlags.Float) != 0 || (e.Flags & EntryFlags.TimeWindow8) != 0 || (e.Flags & EntryFlags.TimeWindowBig) != 0) { Boolean negative = false; Int32 bitsToRead = (Int32)e.nBits; if (signed) { negative = bitBuffer.ReadBoolean(); bitsToRead--; } return((Single)bitBuffer.ReadUnsignedBits(bitsToRead) / e.Divisor * (negative ? -1.0f : 1.0f)); } if ((e.Flags & EntryFlags.Angle) != 0) { return((Single)(bitBuffer.ReadUnsignedBits((Int32)e.nBits) * (360.0f / (Single)(1 << (Int32)e.nBits)))); } if ((e.Flags & EntryFlags.String) != 0) { return(bitBuffer.ReadString()); } throw new ApplicationException(String.Format("Unknown delta entry type {0}.", e.Flags)); }
private UInt32 ParseUnsignedInt(BitBuffer bitBuffer, Entry e) { return bitBuffer.ReadUnsignedBits((Int32)e.nBits) / (UInt32)e.Divisor; }
private Int32 ParseInt(BitBuffer bitBuffer, Entry e) { Boolean negative = bitBuffer.ReadBoolean(); return (Int32)bitBuffer.ReadUnsignedBits((Int32)e.nBits - 1) / (Int32)e.Divisor * (negative ? -1 : 1); }
private Object ParseEntry(BitBuffer bitBuffer, Entry e) { Boolean signed = ((e.Flags & EntryFlags.Signed) != 0); if ((e.Flags & EntryFlags.Byte) != 0) { if (signed) { return (SByte)ParseInt(bitBuffer, e); } else { return (Byte)ParseUnsignedInt(bitBuffer, e); } } if ((e.Flags & EntryFlags.Short) != 0) { if (signed) { return (Int16)ParseInt(bitBuffer, e); } else { return (UInt16)ParseUnsignedInt(bitBuffer, e); } } if ((e.Flags & EntryFlags.Integer) != 0) { if (signed) { return (Int32)ParseInt(bitBuffer, e); } else { return (UInt32)ParseUnsignedInt(bitBuffer, e); } } if ((e.Flags & EntryFlags.Float) != 0 || (e.Flags & EntryFlags.TimeWindow8) != 0 || (e.Flags & EntryFlags.TimeWindowBig) != 0) { Boolean negative = false; Int32 bitsToRead = (Int32)e.nBits; if (signed) { negative = bitBuffer.ReadBoolean(); bitsToRead--; } return (Single)bitBuffer.ReadUnsignedBits(bitsToRead) / e.Divisor * (negative ? -1.0f : 1.0f); } if ((e.Flags & EntryFlags.Angle) != 0) { return (Single)(bitBuffer.ReadUnsignedBits((Int32)e.nBits) * (360.0f / (Single)(1 << (Int32)e.nBits))); } if ((e.Flags & EntryFlags.String) != 0) { return bitBuffer.ReadString(); } throw new ApplicationException(String.Format("Unknown delta entry type {0}.", e.Flags)); }
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 void MessageEvent() { if (demo.NetworkProtocol <= 43) { bitBuffer.Endian = BitBuffer.EndianType.Big; } UInt32 nEvents = bitBuffer.ReadUnsignedBits(5); for (Int32 i = 0; i < nEvents; i++) { bitBuffer.SeekBits(10); // event index Boolean packetIndexBit = bitBuffer.ReadBoolean(); if (packetIndexBit) { bitBuffer.SeekBits(11); // packet index Boolean deltaBit = bitBuffer.ReadBoolean(); if (deltaBit) { GetDeltaStructure("event_t").ReadDelta(bitBuffer, null); } } Boolean fireTimeBit = bitBuffer.ReadBoolean(); if (fireTimeBit) { bitBuffer.SeekBits(16); // fire time } } bitBuffer.SkipRemainingBits(); bitBuffer.Endian = BitBuffer.EndianType.Little; }
public void MessageCreateStringTable() { bitBuffer.ReadString(); // table name UInt32 maxEntries = bitBuffer.ReadUnsignedBits(16); UInt32 nEntries = bitBuffer.ReadUnsignedBits(Common.LogBase2((Int32)maxEntries) + 1); UInt32 nBits = bitBuffer.ReadUnsignedBits(20); if (bitBuffer.ReadBoolean()) // userdata bit { bitBuffer.SeekBits(12); // "user data size" bitBuffer.SeekBits(4); // "user data bits" } bitBuffer.SeekBits((Int32)nBits); if (demo.NetworkProtocol >= 15) { bitBuffer.SeekBits(1); } }