Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Warcraft.MPQ.MPQ"/> class.
        /// </summary>
        /// <param name="mpqStream">An open stream to data containing an MPQ archive.</param>
        public MPQ([NotNull] Stream mpqStream)
        {
            _archiveReader = new BinaryReader(mpqStream);

            Header = new MPQHeader(_archiveReader.ReadBytes((int)PeekHeaderSize()));

            // Seek to the hash table and load it
            _archiveReader.BaseStream.Position = (long)Header.GetHashTableOffset();

            var encryptedHashTable = _archiveReader.ReadBytes((int)Header.GetHashTableSize());
            var hashTableData      = MPQCrypt.DecryptData(encryptedHashTable, HashTable.TableKey);

            ArchiveHashTable = new HashTable(hashTableData);

            // Seek to the block table and load it
            _archiveReader.BaseStream.Position = (long)Header.GetBlockTableOffset();

            var encryptedBlockTable = _archiveReader.ReadBytes((int)Header.GetBlockTableSize());
            var blockTableData      = MPQCrypt.DecryptData(encryptedBlockTable, BlockTable.TableKey);

            ArchiveBlockTable = new BlockTable(blockTableData);

            if (Header.GetFormat() != MPQFormat.ExtendedV1)
            {
                return;
            }

            // Seek to the extended block table and load it, if necessary
            if (Header.GetExtendedBlockTableOffset() <= 0)
            {
                return;
            }

            _archiveReader.BaseStream.Position = (long)Header.GetExtendedBlockTableOffset();
            var extendedTable = new List <ushort>();

            for (var i = 0; i < Header.GetBlockTableEntryCount(); ++i)
            {
                extendedTable.Add(_archiveReader.ReadUInt16());
            }

            ExtendedBlockTable = extendedTable;
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Warcraft.MPQ.MPQ"/> class.
        /// </summary>
        /// <param name="mpqStream">An open stream to data containing an MPQ archive.</param>
        public MPQ(Stream mpqStream)
        {
            ArchiveReader = new BinaryReader(mpqStream);

            Header = new MPQHeader(ArchiveReader.ReadBytes((int)PeekHeaderSize()));

            // Seek to the hash table and load it
            ArchiveReader.BaseStream.Position = (long)Header.GetHashTableOffset();

            byte[] hashTableData;
            if (Header.IsHashTableCompressed())
            {
                byte[] encryptedData = ArchiveReader.ReadBytes((int)Header.GetCompressedHashTableSize());
                byte[] decryptedData = MPQCrypt.DecryptData(encryptedData, HashTable.TableKey);

                BlockFlags tableFlags = BlockFlags.IsCompressedMultiple;
                hashTableData = Compression.DecompressSector(decryptedData, tableFlags);
            }
            else
            {
                byte[] encryptedData = ArchiveReader.ReadBytes((int)Header.GetHashTableSize());
                hashTableData = MPQCrypt.DecryptData(encryptedData, HashTable.TableKey);
            }

            ArchiveHashTable = new HashTable(hashTableData);

            // Seek to the block table and load it
            ArchiveReader.BaseStream.Position = (long)Header.GetBlockTableOffset();

            byte[] blockTableData;
            if (Header.IsBlockTableCompressed())
            {
                byte[] encryptedData = ArchiveReader.ReadBytes((int)Header.GetCompressedBlockTableSize());
                byte[] decryptedData = MPQCrypt.DecryptData(encryptedData, BlockTable.TableKey);

                BlockFlags tableFlags = BlockFlags.IsCompressedMultiple;
                blockTableData = Compression.DecompressSector(decryptedData, tableFlags);
            }
            else
            {
                byte[] encryptedData = ArchiveReader.ReadBytes((int)Header.GetBlockTableSize());
                blockTableData = MPQCrypt.DecryptData(encryptedData, BlockTable.TableKey);
            }

            ArchiveBlockTable = new BlockTable(blockTableData);

            // TODO: Seek to the extended hash table and load it
            // TODO: Seek to the extended block table and load it

            if (Header.GetFormat() >= MPQFormat.ExtendedV1)
            {
                // Seek to the extended block table and load it, if neccesary
                if (Header.GetExtendedBlockTableOffset() <= 0)
                {
                    return;
                }

                ArchiveReader.BaseStream.Position = (long)Header.GetExtendedBlockTableOffset();
                for (int i = 0; i < Header.GetBlockTableEntryCount(); ++i)
                {
                    ExtendedBlockTable.Add(ArchiveReader.ReadUInt16());
                }
            }
        }