Example #1
0
    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;
    }
Example #2
0
 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();
 }
Example #3
0
 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;
 }
Example #4
0
        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(); }
        }
Example #5
0
        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
            );
        }
Example #6
0
        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;
            }
        }
Example #7
0
    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;
    }
Example #8
0
        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;
        }
Example #9
0
        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
                );
            }
        }
Example #10
0
        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() };
                }
            }
        }
Example #11
0
        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;
        }