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); }
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); }
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."); } }