From b805c70fc29abbea3aebdef306bcf6487db318af Mon Sep 17 00:00:00 2001 From: ShrineFox Date: Fri, 18 Apr 2025 16:37:20 -0400 Subject: [PATCH] Add ability to patch RSTB via commandline When more than one argument is supplied for RSTB editing, the program will assume the 2nd argument is the path to the romFS folder and use that to overwrite the input RSTB with a patched one. If a third argument is supplied, it will assume the 3rd path is the output RSTB and save it there instead of overwriting. To make this work without further user input, I had to add bools for whether or not to show messagebox prompts to the RSTB saving and updating functions. This way, the program assumes that you always want to compress the RSTB and doesn't show the results messagebox when updating via commandline. One issue I've noticed is that occasionally there is a popup about the collection being modified while in a for loop. I assume this is some kind of race condition relating to updating being an async function, but I'm not sure. --- Forms/RSTB/RSTBEditor.cs | 151 ++++++++++++------------ Program.cs | 23 +++- Properties/launchSettings.json | 8 ++ Utility/FileTypes/RSTB/ResourceTable.cs | 6 +- 4 files changed, 109 insertions(+), 79 deletions(-) create mode 100644 Properties/launchSettings.json diff --git a/Forms/RSTB/RSTBEditor.cs b/Forms/RSTB/RSTBEditor.cs index f729062..80e4b40 100644 --- a/Forms/RSTB/RSTBEditor.cs +++ b/Forms/RSTB/RSTBEditor.cs @@ -266,88 +266,107 @@ private async void UpdateFromModdedRomFs_Click(object sender, EventArgs e) if (folderBrowserDialog.ShowDialog() == DialogResult.OK) { - var moddedRomFsPath = folderBrowserDialog.SelectedPath; + CreateUpdatedRSTBFromModdedRomFs(LoadedFile, folderBrowserDialog.SelectedPath); - var allFiles = Directory.GetFiles(moddedRomFsPath, "*", SearchOption.AllDirectories); + TopMenu.Enabled = true; + statusBar.Visible = false; + statusProgressBar.Visible = false; + + PopulateGridView(); - List changedFiles = []; - List addedFiles = []; - int skippedFiles = 0; - int removedFiles = 0; + //foreach (DataGridViewRow row in mainDataGridView.Rows) + //{ + // var name = row.Cells[0].Value.ToString(); - TopMenu.Enabled = false; + // if (changedFiles.Contains(name)) + // row.DefaultCellStyle.BackColor = Color.Yellow; - statusLabel.Text = $""; - statusBar.Visible = true; - statusProgressBar.Visible = true; - statusProgressBar.Maximum = allFiles.Length; - statusProgressBar.Value = 0; + // if (addedFiles.Contains(name)) + // row.DefaultCellStyle.BackColor = Color.Green; + //} + } + } - var progress = new Progress<(int Index, string FileName)>(value => - { - statusLabel.Text = $"Getting file size... {value.FileName} ({value.Index}/{allFiles.Length})"; - statusProgressBar.Value = value.Index; - }); + public async void CreateUpdatedRSTBFromModdedRomFs(ResourceTable rstb, string moddedRomFsPath, bool showResults = true) + { + var allFiles = Directory.GetFiles(moddedRomFsPath, "*", SearchOption.AllDirectories); + + List changedFiles = []; + List addedFiles = []; + int skippedFiles = 0; + int removedFiles = 0; + + TopMenu.Enabled = false; + + statusLabel.Text = $""; + statusBar.Visible = true; + statusProgressBar.Visible = true; + statusProgressBar.Maximum = allFiles.Length; + statusProgressBar.Value = 0; - await Task.Run(() => + var progress = new Progress<(int Index, string FileName)>(value => + { + statusLabel.Text = $"Getting file size... {value.FileName} ({value.Index}/{allFiles.Length})"; + statusProgressBar.Value = value.Index; + }); + + await Task.Run(() => + { + int currentPosition = 1; + + foreach (var originalFile in allFiles) { - int currentPosition = 1; + if (IsDisposed || Disposing) break; - foreach (var originalFile in allFiles) + var path = Path.GetRelativePath(moddedRomFsPath, originalFile).Replace('\\', '/'); + if (path == "System/Resource/ResourceSizeTable.srsizetable" || path == "System/Resource/ResourceSizeTable.rsizetable") { - if (IsDisposed || Disposing) break; - - var path = Path.GetRelativePath(moddedRomFsPath, originalFile).Replace('\\', '/'); - if (path == "System/Resource/ResourceSizeTable.srsizetable" || path == "System/Resource/ResourceSizeTable.rsizetable") - { - skippedFiles++; - continue; - } + skippedFiles++; + continue; + } - if (path.EndsWith(".byml") && path != "EventFlow/Info/EventFlowInfoProduct.byml") - continue; - + if (path.EndsWith(".byml") && path != "EventFlow/Info/EventFlowInfoProduct.byml") + continue; - (progress as IProgress<(int, string)>).Report((currentPosition, path)); - if (path.EndsWith(".zs")) - path = path[..^3]; + (progress as IProgress<(int, string)>).Report((currentPosition, path)); - var fileSize = GetFileSize(originalFile); + if (path.EndsWith(".zs")) + path = path[..^3]; - if (fileSize < 0) - { - // remove unsupported file from rstb - if (fileSize == -2) - Console.WriteLine("Unsupported: {0}", path); + var fileSize = GetFileSize(originalFile); - LoadedFile.Dictionary.Remove(path); - removedFiles++; - } - else if (LoadedFile.Dictionary.TryGetValue(path, out var result) && fileSize >= 0 && fileSize != result.FileSize) - { - result.FileSize = (uint) fileSize; - changedFiles.Add(path); - } + if (fileSize < 0) + { + // remove unsupported file from rstb + if (fileSize == -2) + Console.WriteLine("Unsupported: {0}", path); - else if (!LoadedFile.Dictionary.ContainsKey(path) && fileSize >= 0) - { - LoadedFile.AddEntry(new ResourceTable.ResourceTableEntry(path, (uint) fileSize, 0, false)); + rstb.Dictionary.Remove(path); + removedFiles++; + } + else if (rstb.Dictionary.TryGetValue(path, out var result) && fileSize >= 0 && fileSize != result.FileSize) + { + result.FileSize = (uint)fileSize; + changedFiles.Add(path); + } - addedFiles.Add(path); - } + else if (!rstb.Dictionary.ContainsKey(path) && fileSize >= 0) + { + rstb.AddEntry(new ResourceTable.ResourceTableEntry(path, (uint)fileSize, 0, false)); - currentPosition++; + addedFiles.Add(path); } - if (IsDisposed || Disposing) return; + currentPosition++; + } - }); + if (IsDisposed || Disposing) return; - TopMenu.Enabled = true; - statusBar.Visible = false; - statusProgressBar.Visible = false; + }); + if (showResults) + { if (changedFiles.Count > 0 || addedFiles.Count > 0) { MessageBox.Show($"Successfully updated table values!" + @@ -358,20 +377,6 @@ await Task.Run(() => "\n\nYou need to manually save your file in File > Save as...", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); } - - - PopulateGridView(); - - //foreach (DataGridViewRow row in mainDataGridView.Rows) - //{ - // var name = row.Cells[0].Value.ToString(); - - // if (changedFiles.Contains(name)) - // row.DefaultCellStyle.BackColor = Color.Yellow; - - // if (addedFiles.Contains(name)) - // row.DefaultCellStyle.BackColor = Color.Green; - //} } } diff --git a/Program.cs b/Program.cs index 67b6e51..1c94199 100644 --- a/Program.cs +++ b/Program.cs @@ -1,4 +1,5 @@ using HeavenTool.Forms.RSTB; +using HeavenTool.Utility.FileTypes.RSTB; using HeavenTool.Utility.IO; using Microsoft.Win32.SafeHandles; using System; @@ -103,10 +104,24 @@ public static Form HandleInput(string[] originalArguments) return bcsvEditor; case ".srsizetable": - var rstbEditor = new RSTBEditor(); - rstbEditor.LoadFile(path); - return rstbEditor; - + if (originalArguments.Length >= 2) + { + var rstbEditor = new RSTBEditor(); + rstbEditor.LoadFile(path); + rstbEditor.CreateUpdatedRSTBFromModdedRomFs(rstbEditor.LoadedFile, originalArguments[1], false); + string outPath = path; + if (originalArguments.Length >= 3) + outPath = originalArguments[2]; + rstbEditor.LoadedFile.SaveTo(outPath, false); + Environment.Exit(0); + return null; + } + else + { + var rstbEditor = new RSTBEditor(); + rstbEditor.LoadFile(path); + return rstbEditor; + } default: return null; } diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..3a508a0 --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Heaven Tool": { + "commandName": "Project", + "commandLineArgs": "C:\\Users\\Ryan\\Documents\\GitHub\\ACNH-Tutorial-Skip\\RSTB_OG\\ResourceSizeTableTest.srsizetable C:\\Users\\Ryan\\AppData\\Roaming\\Ryujinx\\mods\\contents\\01006f8002326000\\romfs" + } + } +} \ No newline at end of file diff --git a/Utility/FileTypes/RSTB/ResourceTable.cs b/Utility/FileTypes/RSTB/ResourceTable.cs index 0e51adf..20c5a17 100644 --- a/Utility/FileTypes/RSTB/ResourceTable.cs +++ b/Utility/FileTypes/RSTB/ResourceTable.cs @@ -306,7 +306,7 @@ public void UpdateUniques() /// Save the file /// /// File Location - public void SaveTo(string filePath) + public void SaveTo(string filePath, bool showPrompt = true) { UpdateUniques(); @@ -337,7 +337,9 @@ public void SaveTo(string filePath) memoryStream.Position = 0; memoryStream.Read(array, 0, array.Length); - var wantToCompress = MessageBox.Show("Do you want to compress the file?", "Compress to Yaz0?", MessageBoxButtons.YesNo); + var wantToCompress = DialogResult.Yes; + if (showPrompt) + wantToCompress = MessageBox.Show("Do you want to compress the file?", "Compress to Yaz0?", MessageBoxButtons.YesNo); var result = wantToCompress == DialogResult.Yes ? Yaz0CompressionAlgorithm.Compress(array) : new MemoryStream(array); result.ExportToFile(filePath);