private IReadOnlyDictionary <string, GameFile> ReadIndexLegacy(bool caseInsensitive) { Ar.Position = Info.IndexOffset; var index = new FByteArchive($"{Name} - Index", ReadAndDecrypt((int)Info.IndexSize)); string mountPoint; try { mountPoint = index.ReadFString(); } catch (Exception e) { throw new InvalidAesKeyException($"Given aes key '{AesKey?.KeyString}'is not working with '{Name}'", e); } ValidateMountPoint(ref mountPoint); MountPoint = mountPoint; var fileCount = index.Read <int>(); var files = new Dictionary <string, GameFile>(fileCount); for (var i = 0; i < fileCount; i++) { var path = string.Concat(mountPoint, index.ReadFString()); var entry = new FPakEntry(this, path, index); if (entry.IsDeleted && entry.Size == 0) { continue; } if (entry.IsEncrypted) { EncryptedFileCount++; } if (caseInsensitive) { files[path.ToLowerInvariant()] = entry; } else { files[path] = entry; } } return(Files = files); }
private IReadOnlyDictionary <string, GameFile> ReadIndexUpdated(bool caseInsensitive) { // Prepare primary index and decrypt if necessary Ar.Position = Info.IndexOffset; FArchive primaryIndex = new FByteArchive($"{Name} - Primary Index", ReadAndDecrypt((int)Info.IndexSize)); string mountPoint; try { mountPoint = primaryIndex.ReadFString(); } catch (Exception e) { throw new InvalidAesKeyException($"Given aes key '{AesKey?.KeyString}'is not working with '{Name}'", e); } ValidateMountPoint(ref mountPoint); MountPoint = mountPoint; var fileCount = primaryIndex.Read <int>(); EncryptedFileCount = 0; primaryIndex.Position += 8; // PathHashSeed if (!primaryIndex.ReadBoolean()) { throw new ParserException(primaryIndex, "No path hash index"); } primaryIndex.Position += 36; // PathHashIndexOffset (long) + PathHashIndexSize (long) + PathHashIndexHash (20 bytes) if (!primaryIndex.ReadBoolean()) { throw new ParserException(primaryIndex, "No directory index"); } var directoryIndexOffset = primaryIndex.Read <long>(); var directoryIndexSize = primaryIndex.Read <long>(); primaryIndex.Position += 20; // Directory Index hash var encodedPakEntriesSize = primaryIndex.Read <int>(); var encodedPakEntries = primaryIndex.ReadBytes(encodedPakEntriesSize); if (primaryIndex.Read <int>() < 0) { throw new ParserException("Corrupt pak PrimaryIndex detected"); } // Read FDirectoryIndex Ar.Position = directoryIndexOffset; var directoryIndex = new FByteArchive($"{Name} - Directory Index", ReadAndDecrypt((int)directoryIndexSize)); unsafe { fixed(byte *ptr = encodedPakEntries) { var directoryIndexLength = directoryIndex.Read <int>(); var files = new Dictionary <string, GameFile>(fileCount); for (var i = 0; i < directoryIndexLength; i++) { var dir = directoryIndex.ReadFString(); var dirDictLength = directoryIndex.Read <int>(); for (var j = 0; j < dirDictLength; j++) { var name = directoryIndex.ReadFString(); var path = string.Concat(mountPoint, dir, name); var entry = new FPakEntry(this, path, ptr + directoryIndex.Read <int>()); if (entry.IsEncrypted) { EncryptedFileCount++; } if (caseInsensitive) { files[path.ToLowerInvariant()] = entry; } else { files[path] = entry; } } } Files = files; return(files); } } }