diff --git a/Source/ModCompendium/GameConfigWindow.xaml.cs b/Source/ModCompendium/GameConfigWindow.xaml.cs index 5f95ae8..0781eb7 100644 --- a/Source/ModCompendium/GameConfigWindow.xaml.cs +++ b/Source/ModCompendium/GameConfigWindow.xaml.cs @@ -136,78 +136,54 @@ public GameConfigWindow(GameConfig config) else if (config is ModCpkGameConfig) { var ppConfig = (ModCpkGameConfig)config; - } - else if (config is PKGGameConfig) - { - var pkgConfig = (PKGGameConfig)config; // Add extra row ConfigPropertyGrid.RowDefinitions.Add(new RowDefinition()); - // Cpk root directory path label + // PC Mode checkbox label + var pcLabel = new Label() { - var pkgPathLabel = new Label() - { - Content = "App PKG Path", - ToolTip = $"Path to the unencrypted {config.Game.ToString()} full game PKG", - HorizontalContentAlignment = HorizontalAlignment.Center, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Height = 25, - Width = 120 - }; - - Grid.SetRow(pkgPathLabel, 2); - Grid.SetColumn(pkgPathLabel, 0); - ConfigPropertyGrid.Children.Add(pkgPathLabel); - } + Content = "PC Mode", + ToolTip = "Outputs files for use with the P4G PC Mod Loader", + HorizontalContentAlignment = HorizontalAlignment.Center, + VerticalContentAlignment = VerticalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Height = 35, + Width = 120, + Visibility = Visibility.Hidden + }; + Grid.SetRow(pcLabel, 2); + Grid.SetColumn(pcLabel, 0); + ConfigPropertyGrid.Children.Add(pcLabel); - // PKG path text box - TextBox pkgPathTextBox; + // PC Mode Checkbox + CheckBox pc; { - pkgPathTextBox = new TextBox() + pc = new CheckBox() { VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Center, + HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center, - Height = 20, - TextWrapping = TextWrapping.Wrap, - Width = 291, + Height = 35, + Visibility = Visibility.Hidden }; - - pkgPathTextBox.SetBinding(TextBox.TextProperty, new Binding(nameof(Persona5RoyalGameConfig.PKGPath))); - - Grid.SetRow(pkgPathTextBox, 2); - Grid.SetColumn(pkgPathTextBox, 1); - ConfigPropertyGrid.Children.Add(pkgPathTextBox); + Grid.SetRow(pc, 2); + Grid.SetColumn(pc, 1); + ConfigPropertyGrid.Children.Add(pc); } - // PKG Path text box button + if (config.Game == Game.Persona4Golden) { - var pkgPathTextBoxButton = new Button() - { - Content = "...", - HorizontalAlignment = HorizontalAlignment.Right, - VerticalAlignment = VerticalAlignment.Center, - Width = 20, - Height = 20 - }; - - pkgPathTextBoxButton.Click += (s, e) => - { - var file = SelectFile(new CommonFileDialogFilter("PKG file", ".pkg")); - if (file != null) - { - pkgConfig.PKGPath = file; - pkgPathTextBox.GetBindingExpression(TextBox.TextProperty).UpdateTarget(); - } - }; - - Grid.SetRow(pkgPathTextBoxButton, 2); - Grid.SetColumn(pkgPathTextBoxButton, 1); - ConfigPropertyGrid.Children.Add(pkgPathTextBoxButton); + pc.Visibility = Visibility.Visible; + pcLabel.Visibility = Visibility.Visible; + } + else + { + pc.IsChecked = false; } + + pc.SetBinding(CheckBox.IsCheckedProperty, new Binding(nameof(ModCpkGameConfig.PC))); } else { @@ -320,53 +296,6 @@ public GameConfigWindow(GameConfig config) Grid.SetColumn(cpkExtract, 1); ConfigPropertyGrid.Children.Add(cpkExtract); } - - // Add extra row - ConfigPropertyGrid.RowDefinitions.Add(new RowDefinition()); - - // PC Mode checkbox label - var pcLabel = new Label() - { - Content = "PC Mode", - ToolTip = "Outputs files for use with the P4G PC Mod Loader", - HorizontalContentAlignment = HorizontalAlignment.Center, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Height = 35, - Width = 120, - Visibility = Visibility.Hidden - }; - - Grid.SetRow(pcLabel, 5); - Grid.SetColumn(pcLabel, 0); - ConfigPropertyGrid.Children.Add(pcLabel); - - // PC Mode Checkbox - CheckBox pc; - { - pc = new CheckBox() - { - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Center, - Height = 35, - Visibility = Visibility.Hidden - }; - - pc.SetBinding(CheckBox.IsCheckedProperty, new Binding(nameof(PersonaPortableGameConfig.PC))); - - Grid.SetRow(pc, 5); - Grid.SetColumn(pc, 1); - ConfigPropertyGrid.Children.Add(pc); - } - if (config.Game == Game.Persona4Golden) - { - pc.Visibility = Visibility.Visible; - pcLabel.Visibility = Visibility.Visible; - } - else - pc.IsChecked = false; } if (config.Game != Game.Persona3 && config.Game != Game.Persona4) { @@ -410,52 +339,6 @@ public GameConfigWindow(GameConfig config) ConfigPropertyGrid.Children.Add(cpkCompression); } } - if (config.Game == Game.Persona5Royal) - { - // Add extra row - ConfigPropertyGrid.RowDefinitions.Add(new RowDefinition()); - - // Region label - { - var regionLabel = new Label() - { - Content = "Region", - ToolTip = "ID must match your installed version of " + config.Game.ToString(), - HorizontalContentAlignment = HorizontalAlignment.Center, - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Center, - VerticalAlignment = VerticalAlignment.Center, - Height = 35, - Width = 120 - }; - - Grid.SetRow(regionLabel, 4); - Grid.SetColumn(regionLabel, 0); - ConfigPropertyGrid.Children.Add(regionLabel); - } - - // Region combobox - ComboBox region; - { - region = new ComboBox() - { - VerticalContentAlignment = VerticalAlignment.Center, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Center, - Height = 35, - }; - region.Items.Add("UP0177-CUSA17416"); - region.Items.Add("EP0177-CUSA17419"); - region.Items.Add("JP0005-CUSA08644"); - //region.Items.Add("HP0177-CUSA17544"); - - region.SetBinding(ComboBox.SelectedValueProperty, new Binding(nameof(Persona5RoyalGameConfig.Region))); - - Grid.SetRow(region, 4); - Grid.SetColumn(region, 1); - ConfigPropertyGrid.Children.Add(region); - } - } } private void ButtonOk_Click( object sender, RoutedEventArgs e ) diff --git a/Source/ModCompendium/MainWindow.xaml.cs b/Source/ModCompendium/MainWindow.xaml.cs index e17059d..da18773 100644 --- a/Source/ModCompendium/MainWindow.xaml.cs +++ b/Source/ModCompendium/MainWindow.xaml.cs @@ -457,7 +457,13 @@ private void NewButton_Click( object sender, RoutedEventArgs e ) return; // Get unique directory - string modPath = Path.Combine( ModDatabase.ModDirectory, SelectedGame.ToString(), newMod.ModTitle ); + string folderPath = Path.Combine( ModDatabase.ModDirectory, SelectedGame.ToString() ); + string[] gamePath = Directory.GetDirectories( folderPath, "*", SearchOption.AllDirectories ); + if ( FolderComboBox.SelectedItem.ToString() != "All Folders" ) + foreach ( string folder in gamePath ) + if ( Path.GetFileName(folder) == FolderComboBox.SelectedItem.ToString() ) + folderPath = folder; + string modPath = Path.Combine( folderPath, newMod.ModTitle ); if ( Directory.Exists( modPath ) ) { var newModPath = modPath; @@ -488,6 +494,7 @@ private void NewButton_Click( object sender, RoutedEventArgs e ) // Reload RefreshModDatabase(); + RefreshMods(); } private void DeleteButton_Click( object sender, RoutedEventArgs e ) diff --git a/Source/ModCompendium/Properties/AssemblyInfo.cs b/Source/ModCompendium/Properties/AssemblyInfo.cs index 51d1d03..819c791 100644 --- a/Source/ModCompendium/Properties/AssemblyInfo.cs +++ b/Source/ModCompendium/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion( "1.6.0.1" )] -[assembly: AssemblyFileVersion( "1.6.0.1" )] +[assembly: AssemblyVersion( "1.7.0.0" )] +[assembly: AssemblyFileVersion( "1.7.0.0" )] diff --git a/Source/ModCompendiumLibrary/Configuration/GameConfigs/ModCpkGameConfig.cs b/Source/ModCompendiumLibrary/Configuration/GameConfigs/ModCpkGameConfig.cs index a3827dd..08589a6 100644 --- a/Source/ModCompendiumLibrary/Configuration/GameConfigs/ModCpkGameConfig.cs +++ b/Source/ModCompendiumLibrary/Configuration/GameConfigs/ModCpkGameConfig.cs @@ -9,16 +9,25 @@ namespace ModCompendiumLibrary.Configuration { public abstract class ModCpkGameConfig : GameConfig { + protected ModCpkGameConfig() + { + Compression = "True"; + PC = "False"; + } + public string Compression { get; set; } + public string PC { get; set; } protected override void DeserializeCore(XElement element) { Compression = element.GetElementValueOrEmpty(nameof(Compression)); + PC = element.GetElementValueOrEmpty(nameof(PC)); } protected override void SerializeCore(XElement element) { element.AddNameValuePair(nameof(Compression), Compression); + element.AddNameValuePair(nameof(PC), PC); } } @@ -36,4 +45,14 @@ public class Persona5GameConfig : ModCpkGameConfig { public override Game Game => Game.Persona5; } + + public class Persona5RoyalGameConfig : ModCpkGameConfig + { + public override Game Game => Game.Persona5Royal; + } + + public class Persona4GoldenGameConfig : ModCpkGameConfig + { + public override Game Game => Game.Persona4Golden; + } } diff --git a/Source/ModCompendiumLibrary/Configuration/GameConfigs/PKGGameConfig.cs b/Source/ModCompendiumLibrary/Configuration/GameConfigs/PKGGameConfig.cs deleted file mode 100644 index 43105d2..0000000 --- a/Source/ModCompendiumLibrary/Configuration/GameConfigs/PKGGameConfig.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Xml.Linq; - -namespace ModCompendiumLibrary.Configuration -{ - public abstract class PKGGameConfig : GameConfig - { - protected PKGGameConfig() - { - PKGPath = string.Empty; - Compression = "True"; - Region = "UP0177-CUSA17416"; - } - - public string PKGPath { get; set; } - public string Compression { get; set; } - public string Region { get; set; } - - protected override void DeserializeCore(XElement element) - { - PKGPath = element.GetElementValueOrEmpty(nameof(PKGPath)); - Compression = element.GetElementValueOrEmpty(nameof(Compression)); - Region = element.GetElementValueOrEmpty(nameof(Region)); - } - - protected override void SerializeCore(XElement element) - { - element.AddNameValuePair(nameof(PKGPath), PKGPath); - element.AddNameValuePair(nameof(Compression), Compression); - element.AddNameValuePair(nameof(Region), Region); - } - - public class Persona5RoyalGameConfig : PKGGameConfig - { - public override Game Game => Game.Persona5Royal; - } - } -} \ No newline at end of file diff --git a/Source/ModCompendiumLibrary/Configuration/GameConfigs/Persona4GoldenGameConfig.cs b/Source/ModCompendiumLibrary/Configuration/GameConfigs/Persona4GoldenGameConfig.cs deleted file mode 100644 index 7992b13..0000000 --- a/Source/ModCompendiumLibrary/Configuration/GameConfigs/Persona4GoldenGameConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Xml.Linq; - -namespace ModCompendiumLibrary.Configuration -{ - public class Persona4GoldenConfig : PersonaPortableGameConfig - { - public override Game Game => Game.Persona4Golden; - } -} diff --git a/Source/ModCompendiumLibrary/Configuration/GameConfigs/Persona5RoyalGameConfig.cs b/Source/ModCompendiumLibrary/Configuration/GameConfigs/Persona5RoyalGameConfig.cs deleted file mode 100644 index 0b267c0..0000000 --- a/Source/ModCompendiumLibrary/Configuration/GameConfigs/Persona5RoyalGameConfig.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Xml.Linq; - -namespace ModCompendiumLibrary.Configuration -{ - public class Persona5RoyalGameConfig : PKGGameConfig - { - public override Game Game => Game.Persona5Royal; - - } -} diff --git a/Source/ModCompendiumLibrary/Configuration/GameConfigs/PersonaPortableGameConfig.cs b/Source/ModCompendiumLibrary/Configuration/GameConfigs/PersonaPortableGameConfig.cs index 2c73335..d938735 100644 --- a/Source/ModCompendiumLibrary/Configuration/GameConfigs/PersonaPortableGameConfig.cs +++ b/Source/ModCompendiumLibrary/Configuration/GameConfigs/PersonaPortableGameConfig.cs @@ -9,7 +9,6 @@ protected PersonaPortableGameConfig() CpkRootOrPath = string.Empty; Compression = "True"; Extract = "True"; - PC = "False"; } /// @@ -18,14 +17,12 @@ protected PersonaPortableGameConfig() public string CpkRootOrPath { get; set; } public string Compression { get; set; } public string Extract { get; set; } - public string PC { get; set; } protected override void DeserializeCore(XElement element) { CpkRootOrPath = element.GetElementValueOrEmpty(nameof(CpkRootOrPath)); Compression = element.GetElementValueOrEmpty(nameof(Compression)); Extract = element.GetElementValueOrEmpty(nameof(Extract)); - PC = element.GetElementValueOrEmpty(nameof(PC)); } protected override void SerializeCore( XElement element ) @@ -33,7 +30,6 @@ protected override void SerializeCore( XElement element ) element.AddNameValuePair(nameof(CpkRootOrPath), CpkRootOrPath); element.AddNameValuePair(nameof(Compression), Compression); element.AddNameValuePair(nameof(Extract), Extract); - element.AddNameValuePair(nameof(PC), PC); } } } \ No newline at end of file diff --git a/Source/ModCompendiumLibrary/ModCompendiumLibrary.csproj b/Source/ModCompendiumLibrary/ModCompendiumLibrary.csproj index f2756b7..9880a61 100644 --- a/Source/ModCompendiumLibrary/ModCompendiumLibrary.csproj +++ b/Source/ModCompendiumLibrary/ModCompendiumLibrary.csproj @@ -50,9 +50,6 @@ - - - @@ -80,7 +77,6 @@ - diff --git a/Source/ModCompendiumLibrary/ModSystem/Builders/CpkModBuilder.cs b/Source/ModCompendiumLibrary/ModSystem/Builders/CpkModBuilder.cs index 5c18a09..b826200 100644 --- a/Source/ModCompendiumLibrary/ModSystem/Builders/CpkModBuilder.cs +++ b/Source/ModCompendiumLibrary/ModSystem/Builders/CpkModBuilder.cs @@ -106,9 +106,11 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods cpkFile = new VirtualFile(null, cpkPath, cpkName); } - // Delete temp directory + // Delete temp directories Log.Builder.Trace($"Deleting temp directory: {tempDirectoryPath}"); Directory.Delete(tempDirectoryPath, true); + Log.Builder.Trace($"Deleting csv directory: {Path.GetDirectoryName(csvPath)}"); + Directory.Delete(Path.GetDirectoryName(csvPath), true); return cpkFile; } diff --git a/Source/ModCompendiumLibrary/ModSystem/Builders/ModCpkModBuilder.cs b/Source/ModCompendiumLibrary/ModSystem/Builders/ModCpkModBuilder.cs index f2181b8..0ab4f95 100644 --- a/Source/ModCompendiumLibrary/ModSystem/Builders/ModCpkModBuilder.cs +++ b/Source/ModCompendiumLibrary/ModSystem/Builders/ModCpkModBuilder.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Threading; namespace ModCompendiumLibrary.ModSystem.Builders @@ -30,7 +31,13 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods Log.Builder.Info($"Building {gameName} Mod"); Log.Builder.Info("Processing mod files"); - var modFilesDirectory = new VirtualDirectory(null, "mod"); + 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) @@ -70,27 +77,47 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods 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, enabledMods, cpkFileBuildPath, gameName, useCompression); - - if (cpkFileBuildPath != cpkFilePath) + // If PC Mode is enabled, clear and replace contents + if (pc) { - File.Copy(cpkFileBuildPath, cpkFilePath, true); - File.Delete(cpkFileBuildPath); - cpkFile = VirtualFile.FromHostFile(cpkFilePath); + 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(); - Log.Builder.Info("Done!"); + if (hostOutputPath != null) Directory.CreateDirectory(hostOutputPath); - return cpkFile; + 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; + } } private void LogModFilesInDirectory(VirtualDirectory directory) @@ -122,4 +149,16 @@ public class P5ModCpkBuilder : ModCpkModBuilder { protected override Game Game => Game.Persona5; } + + [ModBuilder("P5R Mod Builder", Game = Game.Persona5Royal)] + public class P5RModCpkBuilder : ModCpkModBuilder + { + protected override Game Game => Game.Persona5Royal; + } + + [ModBuilder("P4G Mod Builder", Game = Game.Persona4Golden)] + public class P4GModCpkBuilder : ModCpkModBuilder + { + protected override Game Game => Game.Persona4Golden; + } } diff --git a/Source/ModCompendiumLibrary/ModSystem/Builders/PS4PKGModBuilder.cs b/Source/ModCompendiumLibrary/ModSystem/Builders/PS4PKGModBuilder.cs deleted file mode 100644 index 04b1780..0000000 --- a/Source/ModCompendiumLibrary/ModSystem/Builders/PS4PKGModBuilder.cs +++ /dev/null @@ -1,227 +0,0 @@ -using ModCompendiumLibrary.Configuration; -using ModCompendiumLibrary.IO; -using ModCompendiumLibrary.Logging; -using ModCompendiumLibrary.VirtualFileSystem; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Threading; - -namespace ModCompendiumLibrary.ModSystem.Builders -{ - public abstract class PS4PKGModBuilder : IModBuilder - { - protected abstract Game Game { get; } - - /// - public VirtualFileSystemEntry Build(VirtualDirectory root, List 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 PKGGameConfig ?? throw new InvalidOperationException("Game config is missing."); - //Set cpk name - string cpkName = "patch1R"; - if (config.Region.Split('-')[1] == "CUSA17416") - { - cpkName = "mod"; - } - - Log.Builder.Info($"Building {gameName} Mod"); - Log.Builder.Info("Processing mod files"); - - var modFilesDirectory = new VirtualDirectory(null, cpkName); - 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 {cpkName}.cpk"); - entry.CopyTo(modFilesDirectory); - break; - } - } - else - { - // Move file to 'mod' directory - Log.Builder.Trace($"Adding file {entry.FullName} to {cpkName}.cpk"); - entry.CopyTo(modFilesDirectory); - } - } - - bool.TryParse(config.Compression, out useCompression); - - // Build mod cpk - Log.Builder.Info($"Building {cpkName}.cpk"); - var cpkModCompiler = new CpkModBuilder(); - - if (hostOutputPath != null) Directory.CreateDirectory(hostOutputPath); - - var cpkFilePath = hostOutputPath != null ? Path.Combine(hostOutputPath, $"{cpkName}.cpk") : null; - var cpkNotWritable = File.Exists(cpkFilePath) && FileHelper.IsFileInUse(cpkFilePath); - var cpkFileBuildPath = hostOutputPath != null ? cpkNotWritable ? Path.Combine(Path.GetTempPath(), $"{cpkName}.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); - } - - //Build update pkg - if (File.Exists(cpkFilePath)) - { - string programPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); - string moddedCpk = $"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch\\USRDIR\\{cpkName}.cpk"; - string outputPKG = $"{programPath}\\Output\\Persona5Royal\\{config.Region}_00-PERSONA5R0000000-A0101-V0100.pkg"; - - Log.Builder.Info($"Building update .pkg"); - if (string.IsNullOrWhiteSpace(config.PKGPath)) - throw new InvalidConfigException("Original game .pkg not specified."); - if (!File.Exists(config.PKGPath)) - throw new InvalidConfigException("Original game .pkg not found at specified location."); - //Copy to patch folder - if (File.Exists(moddedCpk)) - File.Delete(moddedCpk); - File.Copy(cpkFilePath, moddedCpk); - using (WaitForFile(moddedCpk, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { }; - //Edit XML/SFO - string mods = ""; - foreach (var mod in enabledMods) - mods += $"{mod.Title} v{mod.Version} by {mod.Author}\n"; - File.WriteAllText($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch\\sce_sys\\changeinfo\\changeinfo.xml", $"\n\n \n \n \n"); - //Create GP4 - RunCMD($"{programPath}\\Dependencies\\GenGP4\\gengp4.exe", $"\"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch\""); - //Edit GP4 with path to PKG - using (WaitForFile($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch.gp4", FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { }; - string[] gp4Lines = File.ReadAllLines($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch.gp4"); - for (int i = 0; i < gp4Lines.Length; i++) - { - gp4Lines[i] = gp4Lines[i].Replace("Dependencies\\GenGP4\\", "").Replace(programPath + "\\", ""); - if (gp4Lines[i].Contains("package content_id")) - gp4Lines[i] = $" "; - } - string gp4Text = string.Join("\n", gp4Lines); - File.WriteAllText($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch-2.gp4", gp4Text); - Thread.Sleep(1000); - using (WaitForFile($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch-2.gp4", FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { }; - if (File.Exists($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch-2.gp4")) - { - if (File.Exists($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch.gp4")) - File.Delete($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch.gp4"); - File.Move($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch-2.gp4", $"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch.gp4"); - } - Thread.Sleep(1000); - using (WaitForFile($"{programPath}\\Dependencies\\GenGP4\\{config.Region.Split('-')[1]}-patch.gp4", FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { }; - Thread.Sleep(1000); - if (File.Exists(outputPKG)) - File.Delete(outputPKG); - //Create PKG from GP4 - RunCMD($"{programPath}\\Dependencies\\GenGP4\\orbis-pub-cmd.exe", $"img_create --oformat pkg --tmp_path ../../Output/Persona5Royal {config.Region.Split('-')[1]}-patch.gp4 ../../Output/Persona5Royal"); - //Rename PKG after finished - while (!File.Exists(outputPKG) || new FileInfo(outputPKG).Length <= 0) { Thread.Sleep(1000); } - using (WaitForFile(outputPKG, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { }; - while (true) - { - if (File.ReadAllBytes(outputPKG)[0] == 0x7F) - break; - } - foreach (Process proc in Process.GetProcessesByName("orbis-pub-cmd")) - proc.Kill(); - foreach (Process proc in Process.GetProcessesByName("cmd")) - proc.Kill(); - string newOutputPKG = outputPKG.Replace($"{config.Region}_00-PERSONA5R0000000-A0101-V0100", $"{config.Region.Split('-')[1]}_00-PERSONA5R-MOD"); - if (File.Exists(newOutputPKG)) - File.Delete(newOutputPKG); - File.Move(outputPKG, newOutputPKG); - Directory.Delete($"{programPath}\\Output\\Persona5Royal\\ps4pub", true); - } - - Log.Builder.Info("Done!"); - - return cpkFile; - } - - private void LogModFilesInDirectory(VirtualDirectory directory) - { - foreach (var entry in directory) - { - if (entry.EntryType == VirtualFileSystemEntryType.File) - Log.Builder.Trace($"Adding mod file: {entry.FullName}"); - else - LogModFilesInDirectory((VirtualDirectory)entry); - } - } - - private void RunCMD(string filename, string args) - { - ProcessStartInfo start = new ProcessStartInfo(); - start.FileName = "cmd"; - start.WorkingDirectory = Path.GetDirectoryName(filename); - start.Arguments = $"/K {Path.GetFileName(filename)} {args}"; - start.UseShellExecute = true; - start.RedirectStandardOutput = false; - //start.WindowStyle = ProcessWindowStyle.Hidden; - - using (Process process = Process.Start(start)) - { - - } - } - - FileStream WaitForFile(string fullPath, FileMode mode, FileAccess access, FileShare share) - { - for (int numTries = 0; numTries < 10; numTries++) - { - FileStream fs = null; - try - { - fs = new FileStream(fullPath, mode, access, share); - return fs; - } - catch (System.IO.IOException) - { - if (fs != null) - { - fs.Dispose(); - } - Thread.Sleep(100); - } - } - - return null; - } - } - - [ModBuilder("P5R Mod Builder", Game = Game.Persona5Royal)] - public class Persona5RoyalModBuilder : PS4PKGModBuilder - { - protected override Game Game => Game.Persona5Royal; - } -} diff --git a/Source/ModCompendiumLibrary/ModSystem/Builders/PersonaPortableModBuilder.cs b/Source/ModCompendiumLibrary/ModSystem/Builders/PersonaPortableModBuilder.cs index 0457a9d..ab64701 100644 --- a/Source/ModCompendiumLibrary/ModSystem/Builders/PersonaPortableModBuilder.cs +++ b/Source/ModCompendiumLibrary/ModSystem/Builders/PersonaPortableModBuilder.cs @@ -33,24 +33,6 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods throw new InvalidOperationException("Game config is missing."); } - bool pc = Convert.ToBoolean(config.PC); - if (!pc && string.IsNullOrWhiteSpace(config.CpkRootOrPath)) - { - throw new InvalidConfigException("CPK path is not specified."); - } - - // If PC Mode is enabled, clear contents - if (pc) - { - if (Directory.Exists(hostOutputPath)) - foreach (var directory in Directory.GetDirectories(hostOutputPath)) - { - string[] stringArray = { "data00000", "data00001", "data00002", "data00003", "data00004", "data00005", "data00006", "movie00000", "movie00001", "movie00002", "snd" }; - if (stringArray.Any(Path.GetFileName(directory).ToLower().Equals)) - Directory.Delete(directory, true); - } - } - // Create temp folder var cpkRootDirectoryPath = Path.Combine(Path.GetTempPath(), $"{Game}ModCompilerTemp_" + Path.GetRandomFileName()); Log.Builder.Trace($"Creating temp output directory: {cpkRootDirectoryPath}"); @@ -60,48 +42,40 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods VirtualDirectory cpkRootDirectory; Log.Builder.Trace($"{nameof(config.CpkRootOrPath)} = {config.CpkRootOrPath}"); - - if (!pc) + if (config.CpkRootOrPath.EndsWith(".cpk")) { - if (config.CpkRootOrPath.EndsWith(".cpk")) + // If extraction is enabled, use files from CPK path + useExtracted = Convert.ToBoolean(config.Extract); + if (useExtracted) { - // If extraction is enabled, use files from CPK path - useExtracted = Convert.ToBoolean(config.Extract); - if (useExtracted) - { - Log.Builder.Info($"Extracting CPK: {config.CpkRootOrPath}"); + 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)) + if (!File.Exists(config.CpkRootOrPath)) { - throw new InvalidConfigException($"CPK root path references a directory that does not exist: {config.CpkRootOrPath}."); + throw new InvalidConfigException($"CPK root path references a CPK file 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); + 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 { - cpkRootDirectory = new VirtualDirectory(); - } + 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) { @@ -110,47 +84,41 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods var directory = (VirtualDirectory)entry; var name = directory.Name.ToLowerInvariant(); - // Skip recompiling CVMs if HostFS Mode - if (pc) - entry.MoveTo(cpkRootDirectory, true); - else + switch (name) { - switch (name) - { - case "mod": - case "cache": - case "umd0": - case "umd1": - case "vita": - case "patch": - case "memst": - case "data00000": - case "data00001": - case "data00002": - case "data00003": - case "data00004": - case "data00005": - case "data00006": - case "data_c": - case "data_e": - case "data_k": + case "mod": + case "cache": + case "umd0": + case "umd1": + case "vita": + case "patch": + case "memst": + case "data00000": + case "data00001": + case "data00002": + case "data00003": + case "data00004": + case "data00005": + case "data00006": + case "data_c": + case "data_e": + case "data_k": + { + // Move files in 'cpk' directory to 'mod' directory + LogModFilesInDirectory(directory); + + foreach (var modFileEntry in directory) { - // Move files in 'cpk' directory to 'mod' directory - LogModFilesInDirectory(directory); - - foreach (var modFileEntry in directory) - { - modFileEntry.CopyTo(cpkRootDirectory); - } + 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; - } + } + break; + + default: + // Move directory to 'mod' directory + Log.Builder.Trace($"Adding directory {entry.FullName} to {cpkRootDirectory.Name}.cpk"); + entry.CopyTo(cpkRootDirectory); + break; } } else @@ -164,22 +132,11 @@ public VirtualFileSystemEntry Build(VirtualDirectory root, List enabledMods useCompression = Convert.ToBoolean(config.Compression); // Build mod cpk - if (!pc) - { - var cpkModCompiler = new CpkModBuilder(); - var cpkFilePath = hostOutputPath != null ? Path.Combine(hostOutputPath, $"{cpkRootDirectory.Name}.cpk") : null; - var cpkFile = cpkModCompiler.Build(cpkRootDirectory, enabledMods, cpkFilePath, gameName, useCompression); - Log.Builder.Info("Done!"); - return cpkFile; - } - else - { - Directory.CreateDirectory(Path.GetFullPath(hostOutputPath)); - cpkRootDirectory.SaveToHost(hostOutputPath); - Log.Builder.Info("Done!"); - return cpkRootDirectory; - } - + var cpkModCompiler = new CpkModBuilder(); + var cpkFilePath = hostOutputPath != null ? Path.Combine(hostOutputPath, $"{cpkRootDirectory.Name}.cpk") : null; + var cpkFile = cpkModCompiler.Build(cpkRootDirectory, enabledMods, cpkFilePath, gameName, useCompression); + Log.Builder.Info("Done!"); + return cpkFile; } private void LogModFilesInDirectory(VirtualDirectory directory)