コード例 #1
0
ファイル: MPQ.cs プロジェクト: datphL/libwarcraft
        /// <summary>
        /// Gets the file info of the provided path.
        /// </summary>
        /// <returns>The file info, or null if the file doesn't exist in the archive.</returns>
        /// <param name="filePath">File path.</param>
        public MPQFileInfo GetFileInfo(string filePath)
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(ToString(), "Cannot use a disposed archive.");
            }

            if (ContainsFile(filePath))
            {
                HashTableEntry  hashEntry  = this.ArchiveHashTable.FindEntry(filePath);
                BlockTableEntry blockEntry = this.ArchiveBlockTable.GetEntry((int)hashEntry.GetBlockEntryIndex());

                if (HasFileAttributes())
                {
                    return(new MPQFileInfo(filePath, hashEntry, blockEntry));
                }
                else
                {
                    return(new MPQFileInfo(filePath, hashEntry, blockEntry, this.FileAttributes.FileAttributes[(int)hashEntry.GetBlockEntryIndex()]));
                }
            }
            else
            {
                return(null);
            }
        }
コード例 #2
0
 public MPQFileInfo
 (
     [NotNull] string inPath,
     [NotNull] HashTableEntry inHashEntry,
     [NotNull] BlockTableEntry inBlockEntry
 )
 {
     Path       = inPath;
     HashEntry  = inHashEntry;
     BlockEntry = inBlockEntry;
 }
コード例 #3
0
 public MPQFileInfo
 (
     [NotNull] string inPath,
     [NotNull] HashTableEntry inHashEntry,
     [NotNull] BlockTableEntry inBlockEntry,
     [NotNull] FileAttributes inAttributes
 )
     : this(inPath, inHashEntry, inBlockEntry)
 {
     Attributes = inAttributes;
 }
コード例 #4
0
        private List <uint> ReadFileSectorOffsetTable
        (
            [NotNull] BlockTableEntry fileBlockEntry,
            uint fileKey = 0
        )
        {
            var sectorOffsets = new List <uint>();

            if (fileBlockEntry.IsEncrypted())
            {
                MPQCrypt.DecryptSectorOffsetTable(_archiveReader, ref sectorOffsets, fileBlockEntry.GetBlockSize(), fileKey - 1);
            }
            else
            {
                // As protection against corrupt or maliciously zeroed blocks or corrupt blocks,
                // reading will be escaped early if the sector offset table is not consistent.
                // Should the total size as predicted by the sector offset table go beyond the total
                // block size, or if an offset is not unique, no file will be read and the function will
                // escape early.
                uint sectorOffset = 0;
                while (sectorOffset != fileBlockEntry.GetBlockSize())
                {
                    sectorOffset = _archiveReader.ReadUInt32();

                    // Should the resulting sector offset be less than the previous data, then the data is inconsistent
                    // and no table should be returned.
                    if (sectorOffsets.LastOrDefault() > sectorOffset)
                    {
                        throw new InvalidFileSectorTableException(
                                  "The read offset in the sector table was less than the previous offset.");
                    }

                    // Should the resulting sector offset be greater than the total block size, then the data is
                    // inconsistent and no file should be returned.
                    if (sectorOffset > fileBlockEntry.GetBlockSize())
                    {
                        throw new InvalidFileSectorTableException(
                                  "The read offset in the sector table was greater than the total size of the data block.");
                    }

                    // Should the resulting sector not be unique, something is wrong and no table should be returned.
                    if (sectorOffsets.Contains(sectorOffset))
                    {
                        throw new InvalidFileSectorTableException(
                                  "The read offset in the sector table was not unique to the whole table.");
                    }

                    // The offset should be valid, so add it to the table.
                    sectorOffsets.Add(sectorOffset);
                }
            }

            return(sectorOffsets);
        }
コード例 #5
0
ファイル: MpqArchive.Parsing.cs プロジェクト: Rockdtben/nmpq
        private byte[] ReadMultiUnitFile(BlockTableEntry blockEntry)
        {
            var sectorCount = blockEntry.FileSize / SectorSize;

            if (blockEntry.FileSize % SectorSize > 0)
            {
                sectorCount++;
            }

            var sectorTable = new int[sectorCount + 1];

            for (var i = 0; i < sectorTable.Length; i++)
            {
                sectorTable[i] = _reader.ReadInt32();
            }

            var result         = new byte[blockEntry.FileSize];
            var resultPosition = 0;

            for (var i = 0; i < sectorCount; i++)
            {
                var position = sectorTable[i];
                var length   = sectorTable[i + 1] - position;

                SeekToArchiveOffset(position + blockEntry.BlockOffset);
                var sectorData = _reader.ReadBytes(length);

                if (blockEntry.IsCompressed && length < SectorSize)
                {
                    var compressionFlags = (CompressionFlags)sectorData[0];

                    if (compressionFlags == CompressionFlags.Bzip2)
                    {
                        sectorData = Compression.BZip2Decompress(sectorData, 1);
                    }
                    else if (compressionFlags == CompressionFlags.Deflated)
                    {
                        sectorData = Compression.Deflate(sectorData, 1);
                    }
                    else
                    {
                        throw new NotSupportedException(
                                  "Currenlty only Bzip2 and Deflate compression is supported by Nmpq.");
                    }
                }

                Array.ConstrainedCopy(sectorData, 0, result, resultPosition, sectorData.Length);
                resultPosition += sectorData.Length;
            }

            return(result);
        }
コード例 #6
0
        private byte[] ExtractUncompressedSectoredFile
        (
            [NotNull] BlockTableEntry fileBlockEntry,
            uint fileKey
        )
        {
            // This file uses sectoring, but is not compressed. It may be encrypted.
            var finalSectorSize = fileBlockEntry.GetFileSize() % GetMaxSectorSize();

            // All the even sectors you can fit into the file size
            var sectorCount = (fileBlockEntry.GetFileSize() - finalSectorSize) / GetMaxSectorSize();

            var rawSectors = new List <byte[]>();

            for (var i = 0; i < sectorCount; ++i)
            {
                // Read a normal sector (usually 4096 bytes)
                rawSectors.Add(_archiveReader.ReadBytes((int)GetMaxSectorSize()));
            }

            // And finally, if there's an uneven sector at the end, read that one too
            if (finalSectorSize > 0)
            {
                rawSectors.Add(_archiveReader.ReadBytes((int)finalSectorSize));
            }

            uint sectorIndex  = 0;
            var  finalSectors = new List <byte[]>();

            foreach (var rawSector in rawSectors)
            {
                var pendingSector = rawSector;
                if (fileBlockEntry.IsEncrypted())
                {
                    // Decrypt the block
                    pendingSector = MPQCrypt.DecryptData(rawSector, fileKey + sectorIndex);
                }

                finalSectors.Add(pendingSector);
                ++sectorIndex;
            }

            return(StitchSectors(finalSectors));
        }
コード例 #7
0
ファイル: MPQ.cs プロジェクト: qyh214/libwarcraft
        /// <inheritdoc />
        /// <exception cref="ObjectDisposedException">Thrown if the archive has been disposed.</exception>
        /// <exception cref="FileNotFoundException">Thrown if the archive does not contain a file at the given path.</exception>
        public MPQFileInfo GetFileInfo(string filePath)
        {
            ThrowIfDisposed();

            if (!ContainsFile(filePath))
            {
                throw new FileNotFoundException("The given file was not present in the archive.", filePath);
            }

            HashTableEntry  hashEntry  = ArchiveHashTable.FindEntry(filePath);
            BlockTableEntry blockEntry = ArchiveBlockTable.GetEntry((int)hashEntry.GetBlockEntryIndex());

            if (HasFileAttributes())
            {
                return(new MPQFileInfo(filePath, hashEntry, blockEntry));
            }

            return(new MPQFileInfo(filePath, hashEntry, blockEntry, FileAttributes.FileAttributes[(int)hashEntry.GetBlockEntryIndex()]));
        }
コード例 #8
0
ファイル: MPQ.cs プロジェクト: datphL/libwarcraft
        /// <summary>
        /// Extracts a file which is stored as a single unit in the archive.
        /// </summary>
        /// <param name="fileBlockEntry">The block entry of the file.</param>
        /// <param name="fileKey">The encryption key of the file.</param>
        /// <returns>The complete file data.</returns>
        private byte[] ExtractSingleUnitFile(BlockTableEntry fileBlockEntry, uint fileKey)
        {
            // This file does not use sectoring, but may still be encrypted or compressed.
            byte[] fileData = this.ArchiveReader.ReadBytes((int)fileBlockEntry.GetBlockSize());

            if (fileBlockEntry.IsEncrypted())
            {
                // Decrypt the block
                fileData = MPQCrypt.DecryptData(fileData, fileKey);
            }

            // Decompress the sector if neccesary
            if (fileBlockEntry.IsCompressed())
            {
                fileData = Compression.DecompressSector(fileData, fileBlockEntry.Flags);
            }

            return(fileData);
        }
コード例 #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="inPath">In path.</param>
 /// <param name="inHashEntry">In hash entry.</param>
 /// <param name="inBlockEntry">In block entry.</param>
 public MPQFileInfo(string inPath, HashTableEntry inHashEntry, BlockTableEntry inBlockEntry)
 {
     Path       = inPath;
     HashEntry  = inHashEntry;
     BlockEntry = inBlockEntry;
 }
コード例 #10
0
ファイル: MPQ.cs プロジェクト: datphL/libwarcraft
        // TODO: Filter files based on language and platform
        /// <summary>
        /// Extract the file at <paramref name="filePath"/> from the archive.
        /// </summary>
        /// <returns>The file as a byte array, or null if the file could not be found.</returns>
        /// <param name="filePath">Path to the file in the archive.</param>
        public byte[] ExtractFile(string filePath)
        {
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(ToString(), "Cannot use a disposed archive.");
            }

            // Reset all positions to be safe
            this.ArchiveReader.BaseStream.Position = 0;

            HashTableEntry fileHashEntry = this.ArchiveHashTable.FindEntry(filePath);

            if (fileHashEntry == null)
            {
                return(null);
            }

            BlockTableEntry fileBlockEntry = this.ArchiveBlockTable.GetEntry((int)fileHashEntry.GetBlockEntryIndex());

            // Drop out if the file is not actually a file
            if (!fileBlockEntry.HasData())
            {
                return(null);
            }

            // Seek to the beginning of the file's sectors
            long adjustedBlockOffset;

            if (this.Header.GetFormat() >= MPQFormat.ExtendedV1 && RequiresExtendedFormat())
            {
                ushort upperOffsetBits = this.ExtendedBlockTable[(int)fileHashEntry.GetBlockEntryIndex()];
                adjustedBlockOffset = (long)fileBlockEntry.GetExtendedBlockOffset(upperOffsetBits);
            }
            else
            {
                adjustedBlockOffset = fileBlockEntry.GetBlockOffset();
            }
            this.ArchiveReader.BaseStream.Position = adjustedBlockOffset;

            // Calculate the decryption key if neccesary
            uint fileKey = MPQCrypt.CreateFileEncryptionKey
                           (
                filePath,
                fileBlockEntry.ShouldEncryptionKeyBeAdjusted(),
                adjustedBlockOffset,
                fileBlockEntry.GetFileSize()
                           );

            // Examine the file storage types and extract as neccesary
            if (fileBlockEntry.IsSingleUnit())
            {
                return(ExtractSingleUnitFile(fileBlockEntry, fileKey));
            }

            if (fileBlockEntry.IsCompressed())
            {
                return(ExtractCompressedSectoredFile(fileBlockEntry, fileKey, adjustedBlockOffset));
            }

            return(ExtractUncompressedSectoredFile(fileBlockEntry, fileKey));
        }
コード例 #11
0
ファイル: MPQ.cs プロジェクト: datphL/libwarcraft
        /// <summary>
        /// Extracts a file which is divided into a set of compressed sectors.
        /// </summary>
        /// <param name="fileBlockEntry">The block entry of the file.</param>
        /// <param name="fileKey">The encryption key of the file.</param>
        /// <param name="adjustedBlockOffset">The offset to where the file sectors begin.</param>
        /// <returns>The complete file data.</returns>
        /// <exception cref="InvalidFileSectorTableException">Thrown if the sector table is found to be inconsistent in any way.</exception>
        private byte[] ExtractCompressedSectoredFile(BlockTableEntry fileBlockEntry, uint fileKey, long adjustedBlockOffset)
        {
            // This file uses sectoring, and is compressed. It may be encrypted.
            //Retrieve the offsets for each sector - these are relative to the beginning of the data.
            List <uint> sectorOffsets = ReadFileSectorOffsetTable(fileBlockEntry, fileKey);

            // Read all of the raw file sectors.
            List <byte[]> compressedSectors = new List <byte[]>();

            for (int i = 0; i < sectorOffsets.Count - 1; ++i)
            {
                long sectorStartPosition = adjustedBlockOffset + sectorOffsets[i];
                this.ArchiveReader.BaseStream.Position = sectorStartPosition;

                uint sectorLength = sectorOffsets[i + 1] - sectorOffsets[i];
                compressedSectors.Add(this.ArchiveReader.ReadBytes((int)sectorLength));
            }

            // Begin decompressing and decrypting the sectors
            // TODO: If Checksums are present (check the flags), treat the last sector as a checksum sector
            // TODO: Check "backup.MPQ/realmlist.wtf" for a weird file with checksums that is not working correctly.
            // It has a single sector with a single checksum after it, and none of the hashing functions seem to
            // produce a valid hash. CRC32, Adler32, CRC32B, nothing.
            // Some flags (listfiles mostly) are flagged as having checksums but don't have a checksum sector.
            // Perhaps related to attributes file?
            List <byte[]> decompressedSectors = new List <byte[]>();

            /*	List<uint> SectorChecksums = new List<uint>();
             *              if (fileBlockEntry.Flags.HasFlag(BlockFlags.BLF_HasChecksums))
             *              {
             *                      byte[] compressedChecksums = compressedSectors.Last();
             *                      byte[] decompressedChecksums = Compression.DecompressSector(compressedChecksums, fileBlockEntry.Flags);
             *
             *                      // Lift out the last sector and treat it as a checksum sector
             *                      using (MemoryStream ms = new MemoryStream(decompressedChecksums))
             *                      {
             *                              using (BinaryReader br = new BinaryReader(ms))
             *                              {
             *                                      // Drop the checksum sector from the file sectors
             *                                      compressedSectors.RemoveAt(compressedSectors.Count - 1);
             *
             *                                      for (int i = 0; i < compressedSectors.Count; ++i)
             *                                      {
             *                                              SectorChecksums.Add(br.ReadUInt32());
             *                                      }
             *                              }
             *                      }
             *              }*/

            uint sectorIndex = 0;

            foreach (byte[] compressedSector in compressedSectors)
            {
                byte[] pendingSector = compressedSector;
                if (fileBlockEntry.IsEncrypted())
                {
                    // Decrypt the block
                    pendingSector = MPQCrypt.DecryptData(compressedSector, fileKey + sectorIndex);
                }

                /*if (fileBlockEntry.Flags.HasFlag(BlockFlags.HasCRCChecksums))
                 *              {
                 *                      // Verify the sector
                 *                      bool isSectorIntact = MPQCrypt.VerifySectorChecksum(pendingSector, SectorChecksums[(int)sectorIndex]);
                 *                      if (!isSectorIntact)
                 *                      {
                 *                              using (MemoryStream ms = new MemoryStream(pendingSector))
                 *                              {
                 *                                      //DEBUG
                 *
                 *                                      uint sectorChecksum = (uint)Adler32.ComputeChecksum(ms);
                 *
                 *                                      string exceptionMessage = String.Format("The decrypted sector failed its integrity checking. \n" +
                 *                                                                        "The sector had a checksum of \"{0}\", and the expected one was \"{1}\".",
                 *                                                                        sectorChecksum, SectorChecksums[(int)sectorIndex]);
                 *
                 *                                      throw new InvalidDataException(exceptionMessage);
                 *                              }
                 *                      }
                 *              }*/

                // Decompress the sector if neccesary
                if (pendingSector.Length < GetMaxSectorSize())
                {
                    int  currentFileSize       = CountBytesInSectors(decompressedSectors);
                    bool canSectorCompleteFile = currentFileSize + pendingSector.Length == fileBlockEntry.GetFileSize();

                    if (!canSectorCompleteFile && currentFileSize != fileBlockEntry.GetFileSize())
                    {
                        pendingSector = Compression.DecompressSector(pendingSector, fileBlockEntry.Flags);
                    }
                }

                decompressedSectors.Add(pendingSector);
                ++sectorIndex;
            }

            return(StitchSectors(decompressedSectors));
        }
コード例 #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="InPath">In path.</param>
 /// <param name="InHashEntry">In hash entry.</param>
 /// <param name="InBlockEntry">In block entry.</param>
 /// <param name="InAttributes">In attributes.</param>
 public MPQFileInfo(string InPath, HashTableEntry InHashEntry, BlockTableEntry InBlockEntry, FileAttributes InAttributes)
     : this(InPath, InHashEntry, InBlockEntry)
 {
     this.Attributes = InAttributes;
 }
コード例 #13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="InPath">In path.</param>
 /// <param name="InHashEntry">In hash entry.</param>
 /// <param name="InBlockEntry">In block entry.</param>
 public MPQFileInfo(string InPath, HashTableEntry InHashEntry, BlockTableEntry InBlockEntry)
 {
     this.Path       = InPath;
     this.HashEntry  = InHashEntry;
     this.BlockEntry = InBlockEntry;
 }
コード例 #14
0
ファイル: MPQFileInfo.cs プロジェクト: datphL/libwarcraft
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="inPath">In path.</param>
 /// <param name="inHashEntry">In hash entry.</param>
 /// <param name="inBlockEntry">In block entry.</param>
 /// <param name="inAttributes">In attributes.</param>
 public MPQFileInfo(string inPath, HashTableEntry inHashEntry, BlockTableEntry inBlockEntry, FileAttributes inAttributes)
     : this(inPath, inHashEntry, inBlockEntry)
 {
     this.Attributes = inAttributes;
 }
コード例 #15
0
ファイル: MPQ.cs プロジェクト: qyh214/libwarcraft
        /// <inheritdoc />
        /// <exception cref="ObjectDisposedException">Thrown if the archive has been disposed.</exception>
        /// <exception cref="FileNotFoundException">Thrown if the archive does not contain a file at the given path.</exception>
        /// <exception cref="FileDeletedException">Thrown if the file is deleted in the archive.</exception>
        public byte[] ExtractFile(string filePath)
        {
            ThrowIfDisposed();

            // Reset all positions to be safe
            ArchiveReader.BaseStream.Position = 0;

            HashTableEntry fileHashEntry;

            try
            {
                fileHashEntry = ArchiveHashTable.FindEntry(filePath);
            }
            catch (FileNotFoundException fex)
            {
                throw new FileNotFoundException("No file found at the given path.", filePath, fex);
            }

            BlockTableEntry fileBlockEntry = ArchiveBlockTable.GetEntry((int)fileHashEntry.GetBlockEntryIndex());

            // Drop out if the file has been deleted
            if (fileBlockEntry.IsDeleted())
            {
                throw new FileDeletedException("The given file is deleted.", filePath);
            }

            // Seek to the beginning of the file's sectors
            long adjustedBlockOffset;

            if (Header.GetFormat() >= MPQFormat.ExtendedV1 && RequiresExtendedFormat())
            {
                ushort upperOffsetBits = ExtendedBlockTable[(int)fileHashEntry.GetBlockEntryIndex()];
                adjustedBlockOffset = (long)fileBlockEntry.GetExtendedBlockOffset(upperOffsetBits);
            }
            else
            {
                adjustedBlockOffset = fileBlockEntry.GetBlockOffset();
            }
            ArchiveReader.BaseStream.Position = adjustedBlockOffset;

            // Calculate the decryption key if neccesary
            uint fileKey = MPQCrypt.CreateFileEncryptionKey
                           (
                filePath,
                fileBlockEntry.ShouldEncryptionKeyBeAdjusted(),
                adjustedBlockOffset,
                fileBlockEntry.GetFileSize()
                           );

            // Examine the file storage types and extract as neccesary
            if (fileBlockEntry.IsSingleUnit())
            {
                return(ExtractSingleUnitFile(fileBlockEntry, fileKey));
            }

            if (fileBlockEntry.IsCompressed())
            {
                return(ExtractCompressedSectoredFile(fileBlockEntry, fileKey, adjustedBlockOffset));
            }

            return(ExtractUncompressedSectoredFile(fileBlockEntry, fileKey));
        }
コード例 #16
0
ファイル: MPQFileInfo.cs プロジェクト: datphL/libwarcraft
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="inPath">In path.</param>
 /// <param name="inHashEntry">In hash entry.</param>
 /// <param name="inBlockEntry">In block entry.</param>
 public MPQFileInfo(string inPath, HashTableEntry inHashEntry, BlockTableEntry inBlockEntry)
 {
     this.Path       = inPath;
     this.HashEntry  = inHashEntry;
     this.BlockEntry = inBlockEntry;
 }
コード例 #17
0
        private int ReadMultiUnitFile(byte[] buffer, BlockTableEntry blockEntry)
        {
            var sectorCount = blockEntry.FileSize / SectorSize + 1;

            //if (blockEntry.FileSize%SectorSize > 0)
            //sectorCount++;

            var hasCRC = (blockEntry.Flags & BlockFlags.HasChecksums) != 0;

            if (hasCRC)
            {
                sectorCount++;
            }

            var sectorTable = new int[sectorCount + 1];

            for (var i = 0; i < sectorTable.Length; i++)
            {
                sectorTable[i] = _reader.ReadInt32();
            }

            var resultPosition = 0;

            long left = blockEntry.FileSize;

            for (var i = 0; i < sectorCount - (hasCRC ? 1 : 0); i++)
            {
                var position = sectorTable[i];
                var length   = sectorTable[i + 1] - position;

                SeekToArchiveOffset(position + blockEntry.BlockOffset);
                var tempBuffer = ArrayPool <byte> .Shared.Rent(length);

                var decompressedBuffer = tempBuffer;
                int decompressedLength = length;
                var sectorData         = _reader.Read(tempBuffer, 0, length);
                Debug.Assert(sectorData == length);

                if (blockEntry.IsCompressed && left > length)
                {
                    var compressionFlags = (CompressionFlags)tempBuffer[0];

                    if (compressionFlags == CompressionFlags.Bzip2)
                    {
                        decompressedBuffer = Compression.BZip2Decompress(tempBuffer, 1, length - 1);
                        decompressedLength = decompressedBuffer.Length;
                        Array.Copy(decompressedBuffer, 0, buffer, resultPosition, decompressedLength);
                    }
                    else if (compressionFlags == CompressionFlags.Deflated)
                    {
                        decompressedLength = Compression.DeflateTo(tempBuffer, 1, length - 1, buffer.AsSpan(resultPosition));
                    }
                    else
                    {
                        throw new NotSupportedException(
                                  "Currenlty only Bzip2 and Deflate compression is supported by Nmpq. Compression flags: " + compressionFlags);
                    }
                }
                else
                {
                    Array.Copy(decompressedBuffer, 0, buffer, resultPosition, decompressedLength);
                }

                ArrayPool <byte> .Shared.Return(tempBuffer);

                resultPosition += decompressedLength;
                left           -= decompressedLength;
            }

            return((int)blockEntry.FileSize);
        }
コード例 #18
0
ファイル: MPQFileInfo.cs プロジェクト: Nihlus/libwarcraft
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="InPath">In path.</param>
 /// <param name="InHashEntry">In hash entry.</param>
 /// <param name="InBlockEntry">In block entry.</param>
 /// <param name="InAttributes">In attributes.</param>
 public MPQFileInfo(string InPath, HashTableEntry InHashEntry, BlockTableEntry InBlockEntry, FileAttributes InAttributes)
     : this(InPath, InHashEntry, InBlockEntry)
 {
     this.Attributes = InAttributes;
 }
コード例 #19
0
ファイル: MPQHeader.cs プロジェクト: qyh214/libwarcraft
 /// <summary>
 /// Gets the size of the block table.
 /// </summary>
 /// <returns>The block table size.</returns>
 public ulong GetBlockTableSize()
 {
     return((ulong)(BlockTableEntryCount * BlockTableEntry.GetSize()));
 }
コード例 #20
0
ファイル: MPQFileInfo.cs プロジェクト: Nihlus/libwarcraft
 /// <summary>
 /// Initializes a new instance of the <see cref="Warcraft.MPQ.FileInfo.MPQFileInfo"/> class.
 /// </summary>
 /// <param name="InPath">In path.</param>
 /// <param name="InHashEntry">In hash entry.</param>
 /// <param name="InBlockEntry">In block entry.</param>
 public MPQFileInfo(string InPath, HashTableEntry InHashEntry, BlockTableEntry InBlockEntry)
 {
     this.Path = InPath;
     this.HashEntry = InHashEntry;
     this.BlockEntry = InBlockEntry;
 }