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); }
/// <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); }