/// <summary> /// Generate an index (.idx) from an existing archive (.bin). /// </summary> /// <param name="archive">Archive handle</param> /// <param name="pathIdMapping">Dictionary that maps path IDs to strings</param> /// <param name="skipUnmappedEntries">Skip entries if the path ID isn't present in the dictionary</param> public static PackfileIndex RebuildFromArchive(Packfile archive, Dictionary <ulong, string> pathIdMapping, bool skipUnmappedEntries) { var index = new PackfileIndex(); foreach (var fileEntry in archive.FileEntries) { if (skipUnmappedEntries && !pathIdMapping.ContainsKey(fileEntry.PathHash)) { continue; } index._entries.Add(new IndexEntry() { FilePath = $"cache:{pathIdMapping[fileEntry.PathHash]}", FileDataHash = new byte[16] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, DecompressedOffset = fileEntry.DecompressedOffset, DecompressedSize = fileEntry.DecompressedSize, }); } index._entries.Sort((x, y) => x.DecompressedOffset.CompareTo(y.DecompressedOffset)); return(index); }
/// <summary> /// Try to gather core file path strings from an archive index file. /// </summary> /// <param name="indexFilePath">Disk path to an .idx file</param> private void TryLoadIndexFileNames(string indexFilePath) { if (!File.Exists(indexFilePath)) { return; } var index = PackfileIndex.FromFile(indexFilePath); // TryAdd will skip over duplicate paths foreach (var entry in index.Entries) { _hashedCorePathToString.TryAdd(Packfile.GetHashForPath(entry.FilePath), entry.FilePath); } }
/// <summary> /// Deserialize a PackfileIndex entry from a BinaryReader. /// </summary> /// <param name="reader">Source stream</param> public static PackfileIndex FromData(BinaryReader reader) { var index = new PackfileIndex(); uint magic = reader.ReadUInt32(); uint entryCount = reader.ReadUInt32(); if (magic != HardcodedMagic) { throw new InvalidDataException("Unknown header magic"); } index._entries = new List <IndexEntry>((int)entryCount); for (uint i = 0; i < entryCount; i++) { index._entries.Add(IndexEntry.FromData(reader)); } return(index); }