public void PackFiles(string outrepackDir, string[] filesToRemove, bool packAllAsNew, string customTitleID) { if (FilesToPack.Count == 0 && filesToRemove.Length == 0) { Program.Log("[X] Found no files to pack or remove from volume.", forceConsolePrint: true); Console.WriteLine("[?] Continue? (Y/N)"); if (Console.ReadKey().Key != ConsoleKey.Y) { return; } } // Leftover? if (Directory.Exists($"{outrepackDir}_temp")) { Directory.Delete($"{outrepackDir}_temp", true); } // Create temp to make sure we aren't transfering user leftovers Directory.CreateDirectory($"{outrepackDir}_temp"); Program.Log($"[-] Preparing to pack {FilesToPack.Count} files, and remove {filesToRemove.Length} files"); PackCache newCache = TableOfContents.PackFilesForPatchFileSystem(FilesToPack, _packCache, filesToRemove, outrepackDir, packAllAsNew); if (UsePackingCache) { newCache.Save(".pack_cache"); } // Delete main one if needed if (Directory.Exists(outrepackDir)) { Directory.Delete(outrepackDir, true); } Directory.Move($"{outrepackDir}_temp", outrepackDir); Program.Log($"[-] Verifying and fixing Table of Contents segment sizes if needed"); if (!TableOfContents.TryCheckAndFixInvalidSegmentIndexes()) { Program.Log($"[-] Re-ordered segment indexes."); } else { Program.Log($"[/] Segment sizes are correct."); } if (packAllAsNew) { Program.Log($"[-] Packing as new: New TOC Entry Index is {VolumeHeader.TOCEntryIndex}."); } Program.Log($"[-] Saving Table of Contents ({PDIPFSPathResolver.GetPathFromSeed(VolumeHeader.TOCEntryIndex)})"); TableOfContents.SaveToPatchFileSystem(outrepackDir, out uint compressedSize, out uint uncompressedSize); if (!string.IsNullOrEmpty(customTitleID) && customTitleID.Length <= 128) { VolumeHeader.HasCustomGameID = true; VolumeHeader.TitleID = customTitleID; } VolumeHeader.CompressedTOCSize = compressedSize; VolumeHeader.TOCSize = uncompressedSize; VolumeHeader.TotalVolumeSize = TableOfContents.GetTotalPatchFileSystemSize(compressedSize); Program.Log($"[-] Saving main volume header ({PDIPFSPathResolver.Default})"); byte[] header = VolumeHeader.Serialize(); Span <uint> headerBlocks = MemoryMarshal.Cast <byte, uint>(header); Keyset.EncryptBlocks(headerBlocks, headerBlocks); Keyset.CryptData(header, BASE_VOLUME_ENTRY_INDEX); string headerPath = Path.Combine(outrepackDir, PDIPFSPathResolver.Default); Directory.CreateDirectory(Path.GetDirectoryName(headerPath)); File.WriteAllBytes(headerPath, header); Program.Log($"[/] Done packing.", forceConsolePrint: true); }