/// <inheritdoc /> public VirtualFileSystemEntry Build(VirtualDirectory root, string hostOutputPath = null, string gameName = null, bool useCompression = false, bool useExtracted = false) { gameName = Game.ToString(); if (root == null) { throw new ArgumentNullException(nameof(root)); } //Get game config var config = ConfigStore.Get(Game) as ModCpkGameConfig ?? throw new InvalidOperationException("Game config is missing."); Log.Builder.Info($"Building {gameName} Mod"); Log.Builder.Info("Processing mod files"); var modFilesDirectory = new VirtualDirectory(null, "mod"); foreach (var entry in root) { if (entry.EntryType == VirtualFileSystemEntryType.Directory) { var directory = (VirtualDirectory)entry; var name = directory.Name.ToLowerInvariant(); switch (name) { case "mod": case "data": { // Move files in 'cpk' directory to 'mod' directory LogModFilesInDirectory(directory); foreach (var modFileEntry in directory) { modFileEntry.CopyTo(modFilesDirectory); } } break; default: // Move directory to 'mod' directory Log.Builder.Trace($"Adding directory {entry.FullName} to mod.cpk"); entry.CopyTo(modFilesDirectory); break; } } else { // Move file to 'mod' directory Log.Builder.Trace($"Adding file {entry.FullName} to mod.cpk"); entry.CopyTo(modFilesDirectory); } } bool.TryParse(config.Compression, out useCompression); // Build mod cpk Log.Builder.Info("Building mod.cpk"); var cpkModCompiler = new CpkModBuilder(); if (hostOutputPath != null) { Directory.CreateDirectory(hostOutputPath); } var cpkFilePath = hostOutputPath != null?Path.Combine(hostOutputPath, "mod.cpk") : null; var cpkNotWritable = File.Exists(cpkFilePath) && FileHelper.IsFileInUse(cpkFilePath); var cpkFileBuildPath = hostOutputPath != null?cpkNotWritable?Path.Combine(Path.GetTempPath(), "mod.cpk") : cpkFilePath : null; var cpkFile = cpkModCompiler.Build(modFilesDirectory, cpkFileBuildPath, gameName, useCompression); if (cpkFileBuildPath != cpkFilePath) { File.Copy(cpkFileBuildPath, cpkFilePath, true); File.Delete(cpkFileBuildPath); cpkFile = VirtualFile.FromHostFile(cpkFilePath); } Log.Builder.Info("Done!"); return(cpkFile); }
/// <inheritdoc /> public VirtualFileSystemEntry Build(VirtualDirectory root, string hostOutputPath = null, string gameName = null, bool useCompression = false, bool useExtracted = false) { gameName = Game.ToString(); if (root == null) { throw new ArgumentNullException(nameof(root)); } // Get game config var config = ConfigStore.Get(Game) as CatherineFullBodyGameConfig; if (config == null) { // Unlikely throw new InvalidOperationException("Game config is missing."); } if (string.IsNullOrWhiteSpace(config.CpkRootOrPath)) { throw new InvalidConfigException("CPK path is not specified."); } // Create temp folder var cpkRootDirectoryPath = Path.Combine(Path.GetTempPath(), $"{Game}ModCompilerTemp_" + Path.GetRandomFileName()); Log.Builder.Trace($"Creating temp output directory: {cpkRootDirectoryPath}"); Directory.CreateDirectory(cpkRootDirectoryPath); // Get files from CPK VirtualDirectory cpkRootDirectory; Log.Builder.Trace($"{nameof(config.CpkRootOrPath)} = {config.CpkRootOrPath}"); if (config.CpkRootOrPath.EndsWith(".cpk")) { // If extraction is enabled, use files from CPK path useExtracted = Convert.ToBoolean(config.Extract); if (useExtracted) { Log.Builder.Info($"Extracting CPK: {config.CpkRootOrPath}"); if (!File.Exists(config.CpkRootOrPath)) { throw new InvalidConfigException($"CPK root path references a CPK file that does not exist: {config.CpkRootOrPath}."); } string[] args = { "-x", "-i", config.CpkRootOrPath, "-d", cpkRootDirectoryPath }; CriPakTools.Program.Main(args); } // Cpk file found & extracted, convert it to our virtual file system cpkRootDirectory = VirtualDirectory.FromHostDirectory(cpkRootDirectoryPath); cpkRootDirectory.Name = Path.GetFileNameWithoutExtension(config.CpkRootOrPath); } else { Log.Builder.Info($"Mounting directory: {config.CpkRootOrPath}"); if (!Directory.Exists(config.CpkRootOrPath)) { throw new InvalidConfigException($"CPK root path references a directory that does not exist: {config.CpkRootOrPath}."); } // No CPK file found, assume files are extracted cpkRootDirectory = VirtualDirectory.FromHostDirectory(config.CpkRootOrPath); cpkRootDirectory.Name = Path.GetDirectoryName(config.CpkRootOrPath); } Log.Builder.Info("Processing mod files"); foreach (var entry in root) { if (entry.EntryType == VirtualFileSystemEntryType.Directory) { var directory = (VirtualDirectory)entry; var name = directory.Name.ToLowerInvariant(); switch (name) { case "mod": case "cache": case "umd0": case "umd1": case "vita": case "patch": case "memst": { // Move files in 'cpk' directory to 'mod' directory LogModFilesInDirectory(directory); foreach (var modFileEntry in directory) { modFileEntry.CopyTo(cpkRootDirectory); } } break; default: // Move directory to 'mod' directory Log.Builder.Trace($"Adding directory {entry.FullName} to {cpkRootDirectory.Name}.cpk"); entry.CopyTo(cpkRootDirectory); break; } } else { // Move file to 'mod' directory Log.Builder.Trace($"Adding file {entry.FullName} to {cpkRootDirectory.Name}.cpk"); entry.CopyTo(cpkRootDirectory); } } useCompression = Convert.ToBoolean(config.Compression); // Build mod cpk var cpkModCompiler = new CpkModBuilder(); var cpkFilePath = hostOutputPath != null?Path.Combine(hostOutputPath, $"{cpkRootDirectory.Name}.cpk") : null; var cpkFile = cpkModCompiler.Build(cpkRootDirectory, cpkFilePath, gameName, useCompression); Log.Builder.Info("Done!"); return(cpkFile); }
/// <inheritdoc /> public VirtualFileSystemEntry Build(VirtualDirectory root, List <Mod> enabledMods, string hostOutputPath = null, string gameName = null, bool useCompression = false, bool useExtracted = false) { gameName = Game.ToString(); if (root == null) { throw new ArgumentNullException(nameof(root)); } //Get game config var config = ConfigStore.Get(Game) as ModCpkGameConfig ?? throw new InvalidOperationException("Game config is missing."); Log.Builder.Info($"Building {gameName} Mod"); Log.Builder.Info("Processing mod files"); bool pc = Convert.ToBoolean(config.PC); var modFilesDirectory = new VirtualDirectory(); if (!pc) { modFilesDirectory = new VirtualDirectory(null, "mod"); } else { modFilesDirectory = new VirtualDirectory(null, ""); } foreach (var entry in root) { if (entry.EntryType == VirtualFileSystemEntryType.Directory) { var directory = (VirtualDirectory)entry; var name = directory.Name.ToLowerInvariant(); switch (name) { case "mod": case "data": { // Move files in 'cpk' directory to 'mod' directory LogModFilesInDirectory(directory); foreach (var modFileEntry in directory) { modFileEntry.CopyTo(modFilesDirectory); } } break; default: // Move directory to 'mod' directory Log.Builder.Trace($"Adding directory {entry.FullName} to mod.cpk"); entry.CopyTo(modFilesDirectory); break; } } else { // Move file to 'mod' directory Log.Builder.Trace($"Adding file {entry.FullName} to mod.cpk"); entry.CopyTo(modFilesDirectory); } } bool.TryParse(config.Compression, out useCompression); // If PC Mode is enabled, clear and replace contents if (pc) { if (Directory.Exists(hostOutputPath)) { foreach (var directory in Directory.GetDirectories(hostOutputPath)) { Log.Builder.Info($"Replacing Output Path contents"); string[] stringArray = { "data00000", "data00001", "data00002", "data00003", "data00004", "data00005", "data00006", "movie00000", "movie00001", "movie00002", "snd", "data_e" }; if (stringArray.Any(Path.GetFileName(directory).ToLower().Equals)) { Directory.Delete(directory, true); } } } Directory.CreateDirectory(Path.GetFullPath(hostOutputPath)); modFilesDirectory.SaveToHost(hostOutputPath); Log.Builder.Info("Done!"); return(modFilesDirectory); } else { // Build mod cpk Log.Builder.Info($"Building mod.cpk"); var cpkModCompiler = new CpkModBuilder(); if (hostOutputPath != null) { Directory.CreateDirectory(hostOutputPath); } var cpkFilePath = hostOutputPath != null?Path.Combine(hostOutputPath, "mod.cpk") : null; var cpkNotWritable = File.Exists(cpkFilePath) && FileHelper.IsFileInUse(cpkFilePath); var cpkFileBuildPath = hostOutputPath != null?cpkNotWritable?Path.Combine(Path.GetTempPath(), "mod.cpk") : cpkFilePath : null; var cpkFile = cpkModCompiler.Build(modFilesDirectory, enabledMods, cpkFileBuildPath, gameName, useCompression); if (cpkFileBuildPath != cpkFilePath) { File.Copy(cpkFileBuildPath, cpkFilePath, true); File.Delete(cpkFileBuildPath); cpkFile = VirtualFile.FromHostFile(cpkFilePath); } Log.Builder.Info("Done!"); return(cpkFile); } }
/// <inheritdoc /> public VirtualFileSystemEntry Build(VirtualDirectory root, string hostOutputPath = null, string gameName = null, bool useCompression = false, bool useExtracted = false) { gameName = Game.Persona5.ToString(); if (root == null) { throw new ArgumentNullException(nameof(root)); } //Get game config var config = ConfigStore.Get <Persona5GameConfig>() ?? throw new InvalidOperationException("Game config is missing."); Log.Builder.Info("Building Persona 5 Mod"); Log.Builder.Info("Processing mod files"); var modFilesDirectory = new VirtualDirectory(null, "mod"); foreach (var entry in root) { if (entry.EntryType == VirtualFileSystemEntryType.Directory) { var directory = ( VirtualDirectory )entry; var name = directory.Name.ToLowerInvariant(); switch (name) { case "mod": case "cache": case "data": case "ps3": case "ps3sndjp": case "patch1ps3": case "patch3ps3": case "ps4": case "ps4sndjp": { // Move files in 'cpk' directory to 'mod' directory LogModFilesInDirectory(directory); foreach (var modFileEntry in directory) { modFileEntry.CopyTo(modFilesDirectory); } } break; default: // Move directory to 'mod' directory Log.Builder.Trace($"Adding directory {entry.FullName} to mod.cpk"); entry.CopyTo(modFilesDirectory); break; } } else { // Move file to 'mod' directory Log.Builder.Trace($"Adding file {entry.FullName} to mod.cpk"); entry.CopyTo(modFilesDirectory); } } useCompression = config.Compression == "true"; // Build mod cpk Log.Builder.Info("Building mod.cpk"); var cpkModCompiler = new CpkModBuilder(); var cpkFilePath = hostOutputPath != null?Path.Combine(hostOutputPath, "mod.cpk") : null; var cpkFile = cpkModCompiler.Build(modFilesDirectory, cpkFilePath, gameName, useCompression); Log.Builder.Info("Done!"); return(cpkFile); }