public static Tileset Read(BinaryReader reader) { var name = reader.ReadFixedString(); var imagePath = reader.ReadFixedString(); var tileset = new Tileset(name, imagePath) { Margin = reader.ReadInt32(), Spacing = reader.ReadInt32(), TileCount = reader.ReadInt32(), TileWidth = reader.ReadInt32(), TileHeight = reader.ReadInt32(), FirstGid = reader.ReadInt32() }; var propertyCount = reader.ReadInt32(); for (var i = 0; i < propertyCount; i++) tileset.PropertyEntries.Add(TilePropertyEntry.Read(reader)); return tileset; }
void ISerializable.Deserialize(BinaryReader reader) { if (reader.ReadUInt32() != Magic) throw new FormatException(); this.Command = reader.ReadFixedString(12); uint length = reader.ReadUInt32(); if (length > 0x02000000) throw new FormatException(); this.Checksum = reader.ReadUInt32(); this.Payload = reader.ReadBytes((int)length); if (Payload.Checksum() != Checksum) throw new FormatException(); }
public static async Task<Message> DeserializeFromStreamAsync(Stream stream) { byte[] buffer = new byte[sizeof(uint) + 12 + sizeof(uint) + sizeof(uint)]; await stream.ReadAsync(buffer, 0, buffer.Length); Message message = new Message(); using (MemoryStream ms = new MemoryStream(buffer, false)) using (BinaryReader reader = new BinaryReader(ms)) { if (reader.ReadUInt32() != Magic) throw new FormatException(); message.Command = reader.ReadFixedString(12); uint length = reader.ReadUInt32(); if (length > 0x02000000) throw new FormatException(); message.Checksum = reader.ReadUInt32(); message.Payload = new byte[length]; } await stream.ReadAsync(message.Payload, 0, message.Payload.Length); return message; }
void ReadTableOfContents() { Stream stream = null; try { stream = mappedFile.CreateViewStream(0, 0, MemoryMappedFileAccess.Read); using (var reader = new BinaryReader(stream, Encoding.ASCII)) { stream = null; var entryCount = reader.ReadUInt32() - 1; for (int i = 0; i < entryCount; i++) { var index = i; var startAddress = reader.ReadUInt32(); var name = reader.ReadFixedString(NameLength).Trim(); var size = reader.ReadInt32() - startAddress; reader.BaseStream.Position -= sizeof(uint); var entry = new FileArchiveEntry { Index = index, Name = name, Offset = startAddress, Size = size }; entries[name] = entry; } } } finally { stream?.Dispose(); } }
public static Message DecodeMessage(BinaryReader reader) { var magic = reader.ReadUInt32(); var command = reader.ReadFixedString(12); var payloadSize = reader.ReadUInt32(); var payloadChecksum = reader.ReadUInt32(); var payload = reader.ReadExactly(payloadSize.ToIntChecked()).ToImmutableArray(); return new Message ( Magic: magic, Command: command, PayloadSize: payloadSize, PayloadChecksum: payloadChecksum, Payload: payload ); }
static void ReadMODS(BinaryReader br, WMORoot wmo) { wmo.DoodadSets = new DoodadSet[wmo.Header.DoodadSetCount]; for (int i = 0; i < wmo.Header.DoodadSetCount; i++) { var d = new DoodadSet { SetName = br.ReadFixedString(20), FirstInstanceIndex = br.ReadUInt32(), InstanceCount = br.ReadUInt32() }; br.ReadInt32(); // padding wmo.DoodadSets[i] = d; } }
public static TilePropertyEntry Read(BinaryReader reader) { var tile = new TilePropertyEntry { Id = reader.ReadInt32() }; var propertyCount = reader.ReadInt32(); for (var i = 0; i < propertyCount; i++) { var key = reader.ReadFixedString(); var value = reader.ReadFixedString(); tile.Properties.Add(key, value); } return tile; }
private Message WireDecodeMessage(UInt32 magic, Stream stream) { byte[] payload; Message message; using (var reader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true)) { var command = reader.ReadFixedString(12); var payloadSize = reader.ReadUInt32(); var payloadChecksum = reader.ReadUInt32(); payload = reader.ReadBytes(payloadSize.ToIntChecked()); if (!Messaging.VerifyPayloadChecksum(payloadChecksum, payload)) throw new Exception($"Checksum failed for {command}"); message = new Message ( Magic: magic, Command: command, PayloadSize: payloadSize, PayloadChecksum: payloadChecksum, Payload: payload.ToImmutableArray() ); } switch (message.Command) { case "addr": { var addressPayload = NodeEncoder.DecodeAddressPayload(payload); this.OnReceivedAddresses?.Invoke(addressPayload.NetworkAddresses); } break; case "alert": { var alertPayload = NodeEncoder.DecodeAlertPayload(payload); } break; case "block": { var block = DataEncoder.DecodeBlock(payload); this.OnBlock?.Invoke(this.owner, block); } break; case "getblocks": { var getBlocksPayload = NodeEncoder.DecodeGetBlocksPayload(payload); this.OnGetBlocks?.Invoke(getBlocksPayload); } break; case "getheaders": { var getHeadersPayload = NodeEncoder.DecodeGetBlocksPayload(payload); this.OnGetHeaders?.Invoke(getHeadersPayload); } break; case "getdata": { var invPayload = NodeEncoder.DecodeInventoryPayload(payload); this.OnGetData?.Invoke(invPayload); } break; case "headers": { var blockHeaders = ImmutableList.CreateBuilder<BlockHeader>(); using (var headerStream = new MemoryStream(payload)) using (var reader = new BinaryReader(headerStream)) { var headerCount = reader.ReadVarInt().ToIntChecked(); for (var i = 0; i < headerCount; i++) { var blockHeader = DataEncoder.DecodeBlockHeader(reader); //TODO wiki says this is a byte and a var int, which is it? var txCount = reader.ReadVarInt(); blockHeaders.Add(blockHeader); } } this.OnBlockHeaders?.Invoke(this.owner, blockHeaders.ToImmutable()); } break; case "inv": { var invPayload = NodeEncoder.DecodeInventoryPayload(payload); this.OnInventoryVectors?.Invoke(invPayload.InventoryVectors); } break; case "notfound": { var invPayload = NodeEncoder.DecodeInventoryPayload(payload); this.OnNotFound?.Invoke(invPayload.InventoryVectors); } break; case "ping": { this.OnPing?.Invoke(payload.ToImmutableArray()); } break; case "tx": { var tx = DataEncoder.DecodeTransaction(payload); this.OnTransaction?.Invoke(tx); } break; case "version": { var versionPayload = NodeEncoder.DecodeVersionPayload(payload, payload.Length); this.OnVersion?.Invoke(versionPayload); } break; case "verack": { this.OnVersionAcknowledged?.Invoke(); } break; default: { logger.Warn($"Unhandled incoming message: {message.Command}"); } break; } //TODO //if (payloadStream.Position != payloadStream.Length) //{ // var exMessage = $"Wrong number of bytes read for {message.Command}, parser error: read {payloadStream.Position} bytes from a {payloadStream.Length} byte payload"; // Debug.WriteLine(exMessage); // throw new Exception(exMessage); //} return message; }
public static Message DecodeMessage(Stream stream) { using (var reader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true)) { var magic = reader.Read4Bytes(); var command = reader.ReadFixedString(12); var payloadSize = reader.Read4Bytes(); var payloadChecksum = reader.Read4Bytes(); var payload = reader.ReadBytes(payloadSize.ToIntChecked()).ToImmutableArray(); return new Message ( Magic: magic, Command: command, PayloadSize: payloadSize, PayloadChecksum: payloadChecksum, Payload: payload ); } }
public MapStream(string filename) : base(filename, FileMode.Open, FileAccess.Read, FileShare.Read) { this.MemoryBlocks = new MemoryMappedAddress[2]; //HEADER BinaryReader bin = new BinaryReader(this, Encoding.UTF8); this.Lock(0, 2048); this.Seek(0, SeekOrigin.Begin); if (bin.ReadTagClass() != (TagClass)"head") throw new InvalidDataException("Not a halo-map file"); //this.Seek(36, SeekOrigin.Begin); //var version = bin.ReadInt32(); //switch (version) //{ // case 0: // BuildVersion = Version.XBOX_RETAIL; // break; // case -1: // BuildVersion = Version.PC_RETAIL; // break; // default: //} BuildVersion = Version.PC_RETAIL; this.Seek(16, SeekOrigin.Begin); int indexAddress = bin.ReadInt32(); int indexLength = bin.ReadInt32(); int tagCacheLength = bin.ReadInt32(); if (BuildVersion == Version.PC_RETAIL) this.Seek(12, SeekOrigin.Current); this.Seek(332, SeekOrigin.Current); int stringTableLength = bin.ReadInt32(); this.Seek(4, SeekOrigin.Current); int stringTableAddress = bin.ReadInt32(); this.Seek(36, SeekOrigin.Current); MapName = bin.ReadFixedString(32); this.Seek(4, SeekOrigin.Current); Scenario = bin.ReadFixedString(256); this.Seek(4, SeekOrigin.Current); int pathsCount = bin.ReadInt32(); int pathsTableAddress = bin.ReadInt32(); int pathsTableLength = bin.ReadInt32(); this.Unlock(0, 2048); this.Seek(pathsTableAddress, SeekOrigin.Begin); var Paths = Encoding.UTF8.GetString(bin.ReadBytes(pathsTableLength - 1)).Split(char.MinValue); //STRINGS this.Seek(stringTableAddress, SeekOrigin.Begin); Strings = Encoding.UTF8.GetString(bin.ReadBytes(stringTableLength - 1)).Split(char.MinValue); // INDEX /* * Vista doesn't use memory addresses for the following address-values. (they are instead 0-based from the index-address) * * 0x00 Address to Classes array * 0x04 Classes array length * 0x08 Address to Tags array * 0x0C Scenario tag_id * 0x10 Match-Globals tag_id * 0x14 ~ * 0x18 Tags array length * 0xC0 'sgat' four_cc * * */ this.Seek(indexAddress, SeekOrigin.Begin); int tagClassTableVirtualAddress = bin.ReadInt32(); this.IndexVirtualAddress = tagClassTableVirtualAddress - 32; this.Seek(4, SeekOrigin.Current); int tagDatumTableVirtualAddress = bin.ReadInt32(); var ScenarioID = bin.ReadTagID(); var GlobalsID = bin.ReadTagID(); int tagDatumTableOffset = tagDatumTableVirtualAddress - tagClassTableVirtualAddress; this.Seek(4, SeekOrigin.Current); int tagDatumCount = bin.ReadInt32(); this.Seek(4 + tagDatumTableOffset, SeekOrigin.Current); Tags = new Tag[tagDatumCount]; for (int i = 0; i < tagDatumCount; i++) { Tags[i] = new Tag() { Type = bin.ReadTagType(), Identifier = bin.ReadInt32(), VirtualAddress = bin.ReadInt32(), Length = bin.ReadInt32() }; if (i == 0) { SecondaryMagic = Tags[0].VirtualAddress - (indexAddress + indexLength); } //Borky vista fix - broken paths are broken //if (Tags[i].VirtualAddress == 0) continue; //var tag = Tags[i]; //Tags[i].Path = Paths[Tags[i].Identifier.SaltedIndex]; } this.MemoryBlocks[1] = new MemoryMappedAddress() { Address = Tags[0].VirtualAddress, Length = tagCacheLength, Magic = SecondaryMagic, }; /* Intent: read the sbsp and lightmap address and lengths from the scenario tag * and store them in the Tags array. */ if (BuildVersion == Version.XBOX_RETAIL) { this.Seek(Tags[ScenarioID.Index].VirtualAddress - SecondaryMagic + 528, SeekOrigin.Begin); var count = bin.ReadInt32(); var address = bin.ReadInt32(); for (int i = 0; i < count; ++i) { this.Seek(address - SecondaryMagic + i * 68, SeekOrigin.Begin); var sbsp_offset = bin.ReadInt32(); var sbsp_length = bin.ReadInt32(); var sbsp_virtual_address = bin.ReadInt32(); if (i == 0) { this.PrimaryMagic = sbsp_virtual_address - sbsp_offset; this.MemoryBlocks[0].Address = sbsp_virtual_address; this.MemoryBlocks[0].Magic = this.PrimaryMagic; } this.MemoryBlocks[0].Length += sbsp_length; Seek(8, SeekOrigin.Current); var sbsp_identifier = bin.ReadTagID(); Seek(4, SeekOrigin.Current); var ltmp_identifier = bin.ReadTagID(); var ltmp_offset = bin.ReadInt32(); var ltmp_length = sbsp_offset + sbsp_length - ltmp_offset; Tags[sbsp_identifier.Index].VirtualAddress = sbsp_virtual_address; Tags[sbsp_identifier.Index].Length = sbsp_length - ltmp_length; if (ltmp_identifier != TagIdentifier.null_identifier) { Tags[ltmp_identifier.Index].VirtualAddress = sbsp_virtual_address + ltmp_offset; Tags[ltmp_identifier.Index].Length = ltmp_length; } } //UNICODE this.Seek(Tags[GlobalsID.Index].VirtualAddress - SecondaryMagic + 400, SeekOrigin.Begin); int unicodeCount = bin.ReadInt32(); int unicodeTableLength = bin.ReadInt32(); int unicodeIndexAddress = bin.ReadInt32(); int unicodeTableAddress = bin.ReadInt32(); Unicode = new UnicodeValueNamePair[unicodeCount]; StringID[] strRefs = new StringID[unicodeCount]; int[] strOffsets = new int[unicodeCount]; this.Seek(unicodeIndexAddress, SeekOrigin.Begin); for (int i = 0; i < unicodeCount; i++) { strRefs[i] = (StringID)bin.ReadInt32(); strOffsets[i] = bin.ReadInt32(); } for (int i = 0; i < unicodeCount; i++) { this.Seek(unicodeTableAddress + strOffsets[i], SeekOrigin.Begin); StringBuilder unicodeString = new StringBuilder(byte.MaxValue); while (bin.PeekChar() != char.MinValue) unicodeString.Append(bin.ReadChar()); Unicode[i] = new UnicodeValueNamePair { Name = strRefs[i], Value = unicodeString.ToString() }; } } }
private Message WireDecodeMessage(UInt32 magic, Stream stream) { byte[] payload; Message message; using (var reader = new BinaryReader(stream, Encoding.ASCII, leaveOpen: true)) { var command = reader.ReadFixedString(12); var payloadSize = reader.Read4Bytes(); var payloadChecksum = reader.Read4Bytes(); payload = reader.ReadBytes(payloadSize.ToIntChecked()); if (!Messaging.VerifyPayloadChecksum(payloadChecksum, payload)) throw new Exception(string.Format("Checksum failed for {0}", command)); message = new Message ( Magic: magic, Command: command, PayloadSize: payloadSize, PayloadChecksum: payloadChecksum, Payload: payload.ToImmutableArray() ); } switch (message.Command) { case "addr": { var addressPayload = NetworkEncoder.DecodeAddressPayload(payload.ToMemoryStream()); var handler = this.OnReceivedAddresses; if (handler != null) handler(addressPayload.NetworkAddresses); } break; case "alert": { var alertPayload = NetworkEncoder.DecodeAlertPayload(payload.ToMemoryStream()); } break; case "block": { var block = NetworkEncoder.DecodeBlock(payload.ToMemoryStream()); var handler = this.OnBlock; if (handler != null) handler(block); } break; case "getblocks": { var getBlocksPayload = NetworkEncoder.DecodeGetBlocksPayload(payload.ToMemoryStream()); var handler = this.OnGetBlocks; if (handler != null) handler(getBlocksPayload); } break; case "getheaders": { var getHeadersPayload = NetworkEncoder.DecodeGetBlocksPayload(payload.ToMemoryStream()); var handler = this.OnGetHeaders; if (handler != null) handler(getHeadersPayload); } break; case "headers": { var headerStream = payload.ToMemoryStream(); using (var reader = new BinaryReader(headerStream)) { var headerCount = reader.ReadVarInt().ToIntChecked(); for (var i = 0; i < headerCount; i++) { var blockHeader = NetworkEncoder.DecodeBlockHeader(headerStream); //TODO wiki says this is a byte and a var int, which is it? var txCount = reader.ReadVarInt(); var handler = this.OnBlockHeader; if (handler != null) handler(blockHeader); } } } break; case "inv": { var invPayload = NetworkEncoder.DecodeInventoryPayload(payload.ToMemoryStream()); var handler = this.OnInventoryVectors; if (handler != null) handler(invPayload.InventoryVectors); } break; case "notfound": { var invPayload = NetworkEncoder.DecodeInventoryPayload(payload.ToMemoryStream()); var handler = this.OnNotFound; if (handler != null) handler(invPayload.InventoryVectors); } break; case "ping": { var handler = this.OnPing; if (handler != null) handler(payload.ToImmutableArray()); } break; case "tx": { var tx = NetworkEncoder.DecodeTransaction(payload.ToMemoryStream()); var handler = this.OnTransaction; if (handler != null) handler(tx); } break; case "version": { var versionPayload = NetworkEncoder.DecodeVersionPayload(payload.ToMemoryStream(), payload.Length); //Debug.WriteLine(string.Format("{0}, {1}", versionPayload.RemoteAddress.ToIPEndPoint(), this.socket.RemoteEndPoint)); var handler = this.OnVersion; if (handler != null) handler(versionPayload); } break; case "verack": { var handler = this.OnVersionAcknowledged; if (handler != null) handler(); } break; default: { Debug.WriteLine("Unhandled incoming message: {0}".Format2(message.Command)); } break; } //TODO //if (payloadStream.Position != payloadStream.Length) //{ // var exMessage = string.Format("Wrong number of bytes read for {0}, parser error: read {1} bytes from a {2} byte payload", message.Command, payloadStream.Position, payloadStream.Length); // Debug.WriteLine(exMessage); // throw new Exception(exMessage); //} return message; }