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 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 MessageResourceList() { Int32 startByteIndex = parser.BitBuffer.CurrentByte; // read message if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } UInt32 nEntries = parser.BitBuffer.ReadUnsignedBits(12); List<Resource> resourceList = new List<Resource>((Int32)nEntries); for (Int32 i = 0; i < nEntries; i++) { Resource r = new Resource(); r.type = parser.BitBuffer.ReadUnsignedBits(4); r.name = parser.BitBuffer.ReadString(); r.index = parser.BitBuffer.ReadUnsignedBits(12); r.fileSize = parser.BitBuffer.ReadBits(24); // signed? r.flags = parser.BitBuffer.ReadUnsignedBits(3); if ((r.flags & 4) != 0) // md5 hash (RES_CUSTOM?) { r.md5Hash = parser.BitBuffer.ReadBytes(16); } r.hasReservedData = parser.BitBuffer.ReadBoolean(); if (r.hasReservedData) { r.reservedData = parser.BitBuffer.ReadBytes(32); } if (demo.Game == null || demo.Game.ConvertResourceListCallback(demo, r.type, r.index, ref r.name)) { resourceList.Add(r); } } // consistency list // indices of resources to force consistency upon? if (parser.BitBuffer.ReadBoolean()) { while (parser.BitBuffer.ReadBoolean()) { Int32 nBits = (parser.BitBuffer.ReadBoolean() ? 5 : 10); parser.BitBuffer.SeekBits(nBits); } } parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // stop now if we're not converting network protocols if (!demo.ConvertNetworkProtocol()) { return; } // create new message BitWriter bitWriter = new BitWriter(); bitWriter.WriteUnsignedBits((UInt32)resourceList.Count, 12); foreach (Resource r in resourceList) { bitWriter.WriteUnsignedBits(r.type, 4); bitWriter.WriteString(r.name); bitWriter.WriteUnsignedBits(r.index, 12); bitWriter.WriteBits(r.fileSize, 24); bitWriter.WriteUnsignedBits(r.flags, 3); if ((r.flags & 4) != 0) // md5 hash { bitWriter.WriteBytes(r.md5Hash); } bitWriter.WriteBoolean(r.hasReservedData); if (r.hasReservedData) { bitWriter.WriteBytes(r.reservedData); } } bitWriter.WriteBoolean(false); // consistency list // remove old message Int32 endByteIndex = parser.BitBuffer.CurrentByte; parser.Seek(startByteIndex, SeekOrigin.Begin); parser.BitBuffer.RemoveBytes(endByteIndex - startByteIndex); // insert new message into bitbuffer parser.BitBuffer.InsertBytes(bitWriter.Data); }
private void MessageNewUserMsg() { Int32 messageStartOffset = parser.BitBuffer.CurrentByte; // read message Byte id = parser.BitBuffer.ReadByte(); SByte length = parser.BitBuffer.ReadSByte(); String name = parser.BitBuffer.ReadString(16); parser.AddUserMessage(id, length, name); // FIXME: clean this up if (!demo.ConvertNetworkProtocol() && name != "CDChallenge" && name != "CDSalt") { return; } if (demo.Game == null || demo.Game.UserMessages == null) { return; } Byte newId; if (demo.Game.UserMessages.ContainsKey(name)) { newId = demo.Game.UserMessages[name]; } else { // cheating death // TODO: probably should have a list of "bad" user messages to remove... // TODO: should remove these messages even when not converting network protocols if (name == "CDChallenge" || name == "CDSalt") { // remove message Int32 messageFinishOffset = parser.BitBuffer.CurrentByte; parser.BitBuffer.SeekBytes(messageStartOffset - 1, SeekOrigin.Begin); parser.BitBuffer.RemoveBytes(messageFinishOffset - messageStartOffset + 1); // +1 for message id return; } // user message doesn't exist in CS 1.6. shouldn't happen, but meh... // TODO: use an id unused by compatibleUserMessageTable //newId = (Byte?)id; newId = firstFreeUserMessage; if (firstFreeUserMessage == 255) { throw new NoFreeUserMessageException(); } firstFreeUserMessage++; demo.Game.UserMessages.Add(name, newId); } BitWriter bitWriter = new BitWriter(); bitWriter.WriteByte((Byte)newId); bitWriter.WriteSByte(length); bitWriter.WriteString(name, 16); // insert new message ReWriteMessage(messageStartOffset, bitWriter.Data); }
private void MessageResourceList() { Int32 startByteIndex = parser.BitBuffer.CurrentByte; // read message if (demo.NetworkProtocol <= 43) { parser.BitBuffer.Endian = BitBuffer.EndianType.Big; } UInt32 nEntries = parser.BitBuffer.ReadUnsignedBits(12); List <Resource> resourceList = new List <Resource>((Int32)nEntries); for (Int32 i = 0; i < nEntries; i++) { Resource r = new Resource(); r.type = parser.BitBuffer.ReadUnsignedBits(4); r.name = parser.BitBuffer.ReadString(); r.index = parser.BitBuffer.ReadUnsignedBits(12); r.fileSize = parser.BitBuffer.ReadBits(24); // signed? r.flags = parser.BitBuffer.ReadUnsignedBits(3); if ((r.flags & 4) != 0) // md5 hash (RES_CUSTOM?) { r.md5Hash = parser.BitBuffer.ReadBytes(16); } r.hasReservedData = parser.BitBuffer.ReadBoolean(); if (r.hasReservedData) { r.reservedData = parser.BitBuffer.ReadBytes(32); } if (demo.Game == null || demo.Game.ConvertResourceListCallback(demo, r.type, r.index, ref r.name)) { resourceList.Add(r); } } // consistency list // indices of resources to force consistency upon? if (parser.BitBuffer.ReadBoolean()) { while (parser.BitBuffer.ReadBoolean()) { Int32 nBits = (parser.BitBuffer.ReadBoolean() ? 5 : 10); parser.BitBuffer.SeekBits(nBits); } } parser.BitBuffer.SkipRemainingBits(); parser.BitBuffer.Endian = BitBuffer.EndianType.Little; // stop now if we're not converting network protocols if (!demo.ConvertNetworkProtocol()) { return; } // create new message BitWriter bitWriter = new BitWriter(); bitWriter.WriteUnsignedBits((UInt32)resourceList.Count, 12); foreach (Resource r in resourceList) { bitWriter.WriteUnsignedBits(r.type, 4); bitWriter.WriteString(r.name); bitWriter.WriteUnsignedBits(r.index, 12); bitWriter.WriteBits(r.fileSize, 24); bitWriter.WriteUnsignedBits(r.flags, 3); if ((r.flags & 4) != 0) // md5 hash { bitWriter.WriteBytes(r.md5Hash); } bitWriter.WriteBoolean(r.hasReservedData); if (r.hasReservedData) { bitWriter.WriteBytes(r.reservedData); } } bitWriter.WriteBoolean(false); // consistency list // remove old message Int32 endByteIndex = parser.BitBuffer.CurrentByte; parser.Seek(startByteIndex, SeekOrigin.Begin); parser.BitBuffer.RemoveBytes(endByteIndex - startByteIndex); // insert new message into bitbuffer parser.BitBuffer.InsertBytes(bitWriter.Data); }