public MPQHeader([NotNull] byte[] data) { using var dataStream = new MemoryStream(data); using var br = new BinaryReader(dataStream); var dataSignature = new string(br.ReadChars(4)); if (dataSignature != ArchiveSignature) { throw new FileLoadException("The provided file was not an MPQ file."); } HeaderSize = br.ReadUInt32(); _basicArchiveSize = br.ReadUInt32(); _format = (MPQFormat)br.ReadUInt16(); _sectorSizeExponent = br.ReadUInt16(); _hashTableOffset = br.ReadUInt32(); _blockTableOffset = br.ReadUInt32(); HashTableEntryCount = br.ReadUInt32(); BlockTableEntryCount = br.ReadUInt32(); if (_format < MPQFormat.ExtendedV1) { return; } _extendedBlockTableOffset = br.ReadUInt64(); _extendedFormatHashTableOffsetBits = br.ReadUInt16(); _extendedFormatBlockTableOffsetBits = br.ReadUInt16(); }
/// <summary> /// Initializes a new instance of the <see cref="Warcraft.MPQ.MPQHeader"/> class. /// </summary> /// <param name="data">A byte array containing the header data of the archive.</param> /// <exception cref="FileLoadException">A FileLoadException may be thrown if the archive was not /// an MPQ file starting with the string "MPQ\x1a".</exception> /// <summary> /// Initializes a new instance of the <see cref="MPQHeader"/> class. /// </summary> /// <param name="data">The binary data.</param> public MPQHeader(byte[] data) { using (MemoryStream dataStream = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(dataStream)) { string dataSignature = new string(br.ReadChars(4)); if (dataSignature != ArchiveSignature) { throw new FileLoadException("The provided file was not an MPQ file."); } HeaderSize = br.ReadUInt32(); BasicArchiveSize = br.ReadUInt32(); Format = (MPQFormat)br.ReadUInt16(); SectorSizeExponent = br.ReadUInt16(); HashTableOffset = br.ReadUInt32(); BlockTableOffset = br.ReadUInt32(); HashTableEntryCount = br.ReadUInt32(); BlockTableEntryCount = br.ReadUInt32(); if (Format >= MPQFormat.ExtendedV1) { ExtendedBlockTableOffset = br.ReadUInt64(); ExtendedFormatHashTableOffsetBits = br.ReadUInt16(); ExtendedFormatBlockTableOffsetBits = br.ReadUInt16(); } if (Format >= MPQFormat.ExtendedV2) { LongArchiveSize = br.ReadUInt64(); BETTableOffset = br.ReadUInt64(); HETTableOffset = br.ReadUInt64(); } if (Format >= MPQFormat.ExtendedV3) { CompressedHashTableSize = br.ReadUInt64(); CompressedBlockTableSize = br.ReadUInt64(); CompressedExtendedBlockTableSize = br.ReadUInt64(); CompressedHETTableSize = br.ReadUInt64(); CompressedBETTableSize = br.ReadUInt64(); ChunkSizeForHashing = br.ReadUInt32(); MD5BlockTable = BitConverter.ToString(br.ReadBytes(16)); MD5HashTable = BitConverter.ToString(br.ReadBytes(16)); MD5ExtendedBlockTable = BitConverter.ToString(br.ReadBytes(16)); MD5BETTable = BitConverter.ToString(br.ReadBytes(16)); MD5HETTable = BitConverter.ToString(br.ReadBytes(16)); MD5Header = BitConverter.ToString(br.ReadBytes(16)); } } } }
/// <summary> /// Initializes a new instance of the <see cref="Warcraft.MPQ.MPQ"/> class. /// This constructor creates an empty archive. /// </summary> /// <param name="inFormat">In format.</param> public MPQ(MPQFormat inFormat) { if (inFormat > MPQFormat.ExtendedV1) { throw new NotImplementedException(); } this.Header = new MPQHeader(inFormat); this.ArchiveHashTable = new HashTable(); this.ArchiveBlockTable = new BlockTable(); }
// The MD5_Header is calculated from the start of the signature to the end of the MD5_HETTable /// <summary> /// Initializes a new instance of the <see cref="Warcraft.MPQ.MPQHeader"/> class. /// This creates a default header for an empty archive. /// </summary> public MPQHeader(MPQFormat inFormat) { if (inFormat == MPQFormat.Basic) { HeaderSize = 32; } else if (inFormat == MPQFormat.ExtendedV1) { HeaderSize = 44; } else { throw new NotImplementedException(); } BasicArchiveSize = HeaderSize; Format = inFormat; SectorSizeExponent = 3; if (Format > MPQFormat.ExtendedV1) { LongArchiveSize = HeaderSize; } }