Example #1
0
        internal static Dictionary <string, GrfEntry> ReadEntries(string grfFilePath, GrfHeader header, LoadingMode loadingMode)
        {
            var entries = new Dictionary <string, GrfEntry>();

            using (var fileStream = File.OpenRead(grfFilePath))
                using (var bodyStream = new ZlibStream(fileStream, CompressionMode.Decompress))
                    using (var bodyReader = new BinaryReader(bodyStream))
                    {
                        // skip 4 byte compressed body size
                        // skip 4 byte uncompressed body size
                        fileStream.Seek(header.FileTablePosition + 8, SeekOrigin.Begin);

                        for (int i = 0; i < header.FileCount; i++)
                        {
                            var  fileName = string.Empty;
                            char currentChar;
                            while ((currentChar = (char)bodyReader.ReadByte()) != 0)
                            {
                                fileName += currentChar;
                            }

                            var compressedFileSize        = bodyReader.ReadUInt32();
                            var compressedFileSizeAligned = bodyReader.ReadUInt32();
                            var uncompressedFileSize      = bodyReader.ReadUInt32();
                            var fileFlags      = (FileFlag)bodyReader.ReadByte();
                            var fileDataOffset = bodyReader.ReadUInt32();

                            // skip directories and files with zero size
                            if (!fileFlags.HasFlag(FileFlag.File) || uncompressedFileSize == 0)
                            {
                                continue;
                            }

                            entries.Add(
                                fileName,
                                new GrfEntry(
                                    fileName,
                                    (uint)header.Size + fileDataOffset,
                                    compressedFileSize,
                                    compressedFileSizeAligned,
                                    uncompressedFileSize,
                                    fileFlags,
                                    null));
                        }
                    }

            return(entries);
        }
Example #2
0
        internal static Dictionary <string, GrfEntry> ReadEntries(string grfFilePath, GrfHeader header, LoadingMode loadingMode)
        {
            var entries = new Dictionary <string, GrfEntry>();

            using (var fileStream = File.OpenRead(grfFilePath))
                using (var binaryReader = new BinaryReader(fileStream))
                {
                    binaryReader.BaseStream.Seek(header.FileTablePosition, SeekOrigin.Begin);

                    int currentEntryOffset = 0;
                    for (int i = 0; i < header.FileCount; i++)
                    {
                        binaryReader.BaseStream.Seek(header.FileTablePosition + currentEntryOffset, SeekOrigin.Begin);
                        int nameLength  = binaryReader.PeekChar() - 6;
                        int entryOffset = currentEntryOffset + binaryReader.ReadInt32() + 4;

                        binaryReader.ReadBytes(2);
                        var encodedName = binaryReader.ReadBytes(nameLength);
                        var fileName    = DecodeFileName(encodedName.AsSpan());

                        binaryReader.BaseStream.Seek(header.FileTablePosition + entryOffset, SeekOrigin.Begin);
                        uint compressedFileSizeBase    = binaryReader.ReadUInt32();
                        uint compressedFileSizeAligned = binaryReader.ReadUInt32() - 37579;
                        uint uncompressedFileSize      = binaryReader.ReadUInt32();
                        uint compressedFileSize        = compressedFileSizeBase - uncompressedFileSize - 715;
                        var  fileFlags = (FileFlag)binaryReader.ReadByte();
                        fileFlags |= IsFullEncrypted(fileName)
                        ? FileFlag.Mixed
                        : FileFlag.DES;
                        uint fileDataOffset = binaryReader.ReadUInt32() + (uint)header.Size;

                        // skip directories and files with zero size
                        if (!fileFlags.HasFlag(FileFlag.File) || uncompressedFileSize == 0)
                        {
                            continue;
                        }

                        entries.Add(
                            fileName,
                            new GrfEntry(
                                fileName,
                                fileDataOffset,
                                compressedFileSize,
                                compressedFileSizeAligned,
                                uncompressedFileSize,
                                fileFlags,
                                null));

                        currentEntryOffset = entryOffset + 17;
                    }
                }

            return(entries);
        }
Example #3
0
        internal static Dictionary <string, GrfEntry> ReadEntries(string grfFilePath, GrfHeader header, LoadingMode loadingMode)
        {
            switch (header.Version)
            {
            case GrfFormat.Version102:
            case GrfFormat.Version103:
                return(Grf1xxFileReader.ReadEntries(grfFilePath, header, loadingMode));

            case GrfFormat.Version200:
                return(Grf2xxFileReader.ReadEntries(grfFilePath, header, loadingMode));

            default:
                throw new NotImplementedException($"Version {header.Version} of GRF files is currently not supported.");
            }
        }