예제 #1
0
        public override void FromBinary(byte[] value)
        {
            if (value.Length > Pointer.Length)
            {
                throw new IndexOutOfRangeException();
            }

            byte[] val = new byte[Pointer.Length];
            Array.Copy(value, val, value.Length);

            this.value = FastBitConverter.ToInt64(val, 0);
        }
예제 #2
0
        /// <summary>
        /// Parses a compressed resource data file
        /// </summary>
        /// <param name="filename">resource data file name</param>
        /// <returns>a Dictionary indexed by the resource filename's hashcode</returns>
        public static Dictionary <ulong, ResourceDataEntry> Parse(string filename)
        {
            Dictionary <ulong, ResourceDataEntry> resourceData;

            // The data should be compressed, read the whole file into memory first and decompress it
            // Compressed with Oodle Kraken, level 4
            var resourceDataFileBytes = File.ReadAllBytes(filename);
            var compressedData        = new byte[resourceDataFileBytes.Length - 8];

            Buffer.BlockCopy(resourceDataFileBytes, 8, compressedData, 0, compressedData.Length);

            long decompressedSize = FastBitConverter.ToInt64(resourceDataFileBytes, 0);
            var  decompressedData = OodleWrapper.Decompress(compressedData, decompressedSize);

            // Parse the binary data now
            using (var memoryStream = new MemoryStream(decompressedData))
            {
                using (var binaryReader = new BinaryReader(memoryStream, Encoding.Default, true))
                {
                    // Amount of entries
                    ulong amount = binaryReader.ReadUInt64();
                    resourceData = new Dictionary <ulong, ResourceDataEntry>((int)amount);

                    // Read each entry
                    for (ulong i = 0; i < amount; i++)
                    {
                        ulong  fileNameHash    = binaryReader.ReadUInt64();
                        ulong  streamDbHash    = binaryReader.ReadUInt64();
                        byte   version         = binaryReader.ReadByte();
                        byte   specialByte1    = binaryReader.ReadByte();
                        byte   specialByte2    = binaryReader.ReadByte();
                        byte   specialByte3    = binaryReader.ReadByte();
                        ushort typeNameLength  = binaryReader.ReadUInt16();
                        string typeName        = Encoding.Default.GetString(binaryReader.ReadBytes(typeNameLength));
                        ushort assetTypeLength = binaryReader.ReadUInt16();
                        string assetType       = typeName;
                        string assetName       = string.Empty;

                        if (assetTypeLength > 0)
                        {
                            assetType = Encoding.Default.GetString(binaryReader.ReadBytes(assetTypeLength));
                            ushort assetNameLength = binaryReader.ReadUInt16();
                            assetName = Encoding.Default.GetString(binaryReader.ReadBytes(assetNameLength));
                        }

                        resourceData.Add(fileNameHash, new ResourceDataEntry()
                        {
                            StreamDbHash    = streamDbHash,
                            Version         = version,
                            SpecialByte1    = specialByte1,
                            SpecialByte2    = specialByte2,
                            SpecialByte3    = specialByte3,
                            ResourceType    = typeName,
                            MapResourceName = assetName,
                            MapResourceType = assetType
                        });
                    }
                }
            }

            return(resourceData);
        }
        /// <summary>
        /// Creates a MapResources object from a byte array
        /// </summary>
        /// <param name="rawData">raw map resources file data</param>
        /// <returns>the parsed MapResources object</returns>
        public static MapResourcesFile Parse(byte[] rawData)
        {
            MapResourcesFile mapResourcesFile = new MapResourcesFile();

            using (var memoryStream = new MemoryStream(rawData))
            {
                using (var binaryReader = new BinaryReader(memoryStream, Encoding.Default, true))
                {
                    // Read the magic
                    mapResourcesFile.Magic = binaryReader.ReadInt32();

                    // Read layer count (big-endian)
                    var layerCountBytes = binaryReader.ReadBytes(4);
                    int layerCount      = FastBitConverter.ToInt32(layerCountBytes, 0, true);

                    // Read layers
                    for (int i = 0; i < layerCount; i++)
                    {
                        int stringLength = binaryReader.ReadInt32();
                        mapResourcesFile.Layers.Add(Encoding.UTF8.GetString(binaryReader.ReadBytes(stringLength)));
                    }

                    // Read asset type count (big-endian)
                    var  assetTypeCountBytes = binaryReader.ReadBytes(8);
                    long assetTypeCount      = FastBitConverter.ToInt64(assetTypeCountBytes, 0, true);

                    // Read asset types
                    for (int i = 0; i < assetTypeCount; i++)
                    {
                        int stringLength = binaryReader.ReadInt32();
                        mapResourcesFile.AssetTypes.Add(Encoding.UTF8.GetString(binaryReader.ReadBytes(stringLength)));
                    }

                    // Read assets count (big-endian)
                    var assetCountBytes = binaryReader.ReadBytes(4);
                    int assetCount      = FastBitConverter.ToInt32(assetCountBytes, 0, true);

                    // Read assets
                    for (int i = 0; i < assetCount; i++)
                    {
                        var mapAsset            = new MapAsset();
                        var assetTypeIndexBytes = binaryReader.ReadBytes(4);
                        mapAsset.AssetTypeIndex = FastBitConverter.ToInt32(assetTypeIndexBytes, 0, true);

                        int stringLength = binaryReader.ReadInt32();
                        mapAsset.Name = Encoding.UTF8.GetString(binaryReader.ReadBytes(stringLength));

                        // Read unknown data
                        mapAsset.UnknownData1 = binaryReader.ReadInt32();

                        // Read the remaining unknown data (big-endian)
                        var unknownData2Bytes = binaryReader.ReadBytes(4);
                        mapAsset.UnknownData2 = FastBitConverter.ToInt32(unknownData2Bytes, 0, true);

                        var unknownData3Bytes = binaryReader.ReadBytes(8);
                        mapAsset.UnknownData3 = FastBitConverter.ToInt64(unknownData3Bytes, 0, true);

                        var unknownData4Bytes = binaryReader.ReadBytes(8);
                        mapAsset.UnknownData4 = FastBitConverter.ToInt64(unknownData4Bytes, 0, true);

                        mapResourcesFile.Assets.Add(mapAsset);
                    }

                    // Read map count (big-endian)
                    var mapCountBytes = binaryReader.ReadBytes(4);
                    int mapCount      = FastBitConverter.ToInt32(mapCountBytes, 0, true);

                    // Read asset types
                    for (int i = 0; i < mapCount; i++)
                    {
                        int stringLength = binaryReader.ReadInt32();
                        mapResourcesFile.Maps.Add(Encoding.UTF8.GetString(binaryReader.ReadBytes(stringLength)));
                    }
                }
            }

            return(mapResourcesFile);
        }