From f7ad78db35eb344a501d1060fc3248c8ad06f230 Mon Sep 17 00:00:00 2001 From: leogandmars Date: Sun, 5 Sep 2021 18:39:48 -0700 Subject: [PATCH 1/3] Added a prompt to reinstall previously selected mods --- ModAssistant/Pages/Mods.xaml.cs | 84 ++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/ModAssistant/Pages/Mods.xaml.cs b/ModAssistant/Pages/Mods.xaml.cs index c17e452b..a2499c44 100644 --- a/ModAssistant/Pages/Mods.xaml.cs +++ b/ModAssistant/Pages/Mods.xaml.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -31,6 +32,7 @@ public sealed partial class Mods : Page public static List LibsToMatch = new List(); public List CategoryNames = new List(); public CollectionView view; + public static List MissingOldMods = new List(); public bool PendingChanges; private readonly SemaphoreSlim _modsLoadSem = new SemaphoreSlim(1, 1); @@ -124,6 +126,23 @@ public async Task LoadMods() DescriptionColumn.Width = 800; } + string lastModdedVersion = CheckPreviousInstallDirs(); + if (lastModdedVersion != null && + !DirectoryContainsMods(Path.Combine(App.BeatSaberInstallDirectory, "Plugins")) && + !DirectoryContainsMods(Path.Combine(App.BeatSaberInstallDirectory, "IPA/Pending/Plugins"))) + { + var reinstallMods = System.Windows.Forms.MessageBox.Show("The game has updated since you last played, would you like to automatically re-select the mods you had installed previously?", "Reinstall mods?", MessageBoxButtons.OKCancel) == DialogResult.OK; + if (reinstallMods) { + MainWindow.Instance.MainText = $"Checking mods for previous version of the game..."; + await Task.Run(async () => await SelectPreviousMods(lastModdedVersion)); + InstalledColumn.Width = double.NaN; + UninstallColumn.Width = 70; + DescriptionColumn.Width = 750; + + var modsDialog2 = System.Windows.Forms.MessageBox.Show($"The following mods could not be found and weren't selected:\n{string.Join(",\n", MissingOldMods)}\n\nThese mods might not be updated yet.", "Reinstall mods?", MessageBoxButtons.OKCancel) == DialogResult.OK; + } + } + MainWindow.Instance.MainText = $"{FindResource("Mods:LoadingMods")}..."; await Task.Run(async () => await PopulateModsList()); @@ -160,6 +179,15 @@ public async Task CheckInstalledMods() CheckInstallDir("Libs"); } + public async Task SelectPreviousMods(string previousModsDirectory) + { + if(AllModsList == null) await GetAllMods(); + + CheckInstallDir(previousModsDirectory, true); + CheckInstallDir("Libs"); + //CheckPreviousInstallDirs(); + } + public async Task GetAllMods() { var resp = await HttpClient.GetAsync(Utils.Constants.BeatModsAPIUrl + "mod"); @@ -167,7 +195,52 @@ public async Task GetAllMods() AllModsList = JsonSerializer.Deserialize(body); } - private void CheckInstallDir(string directory) + private SemVersion SemverForPluginFolder(string directory) + { + string versionString = directory.Substring(directory.LastIndexOf("Old") + 3, directory.Length - directory.LastIndexOf("Plugins")).Trim(); + SemVersion semver; + if (!SemVersion.TryParse(versionString, out semver)) return null; + return semver; + } + + private int CompareInstallDirs(string a, string b) + { + SemVersion semverA = SemverForPluginFolder(a); + SemVersion semverB = SemverForPluginFolder(b); + if (semverA == null) return 1; + else if(semverB == null) return 0; + + return semverB.CompareTo(semverA); + } + + private bool DirectoryContainsMods(string directory) + { + if (Directory.Exists(directory)) + { + foreach (string file in Directory.GetFileSystemEntries(Path.Combine(App.BeatSaberInstallDirectory, directory))) + { + string fileExtension = Path.GetExtension(file); + + if (File.Exists(file) && (fileExtension == ".dll" || fileExtension == ".manifest")) return true; + } + } + return false; + } + + private string CheckPreviousInstallDirs() + { + if (!Directory.Exists(App.BeatSaberInstallDirectory)) return null; + + string[] directories = Directory.GetDirectories(App.BeatSaberInstallDirectory, "Old*Plugins"); + if (directories.Length == 0) return null; + Array.Sort(directories, CompareInstallDirs); + + foreach(string directory in directories) if (DirectoryContainsMods(directory)) return directory; + + return null; + } + + private void CheckInstallDir(string directory, bool setFailedMods = false) { if (!Directory.Exists(Path.Combine(App.BeatSaberInstallDirectory, directory))) { @@ -199,6 +272,12 @@ private void CheckInstallDir(string directory) AddDetectedMod(mod); } } + else if (setFailedMods) + { + string fileName = Path.GetFileNameWithoutExtension(file); + if (!MissingOldMods.Contains(fileName)) MissingOldMods.Add(fileName); + // maybe hook into the manifest to get the actual name. too lazy for now. + } } } } @@ -229,10 +308,11 @@ public void GetBSIPAVersion() private void AddDetectedMod(Mod mod) { + Console.WriteLine(mod.name); if (!InstalledMods.Contains(mod)) { InstalledMods.Add(mod); - if (App.SelectInstalledMods && !DefaultMods.Contains(mod.name)) + if (!DefaultMods.Contains(mod.name)) { DefaultMods.Add(mod.name); } From 8bc32d6ef465d4eb237ac93ed8686d480e8c08fd Mon Sep 17 00:00:00 2001 From: leogandmars Date: Sun, 5 Sep 2021 18:55:55 -0700 Subject: [PATCH 2/3] Localization strings --- ModAssistant/Localisation/en-DEBUG.xaml | 6 ++++++ ModAssistant/Localisation/en.xaml | 6 ++++++ ModAssistant/Pages/Mods.xaml.cs | 16 ++++++++++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ModAssistant/Localisation/en-DEBUG.xaml b/ModAssistant/Localisation/en-DEBUG.xaml index 2d6c01c1..4868370f 100644 --- a/ModAssistant/Localisation/en-DEBUG.xaml +++ b/ModAssistant/Localisation/en-DEBUG.xaml @@ -60,6 +60,12 @@ Mods:UninstallButton Mods:LoadFailed Mods:CheckingInstalledMods + Mods:GameUpdatedPrompt:Title + Mods:GameUpdatedPrompt:OkCancel + Mods:FailedToSelect:Title + Mods:FailedToSelect:Body1 + Mods:FailedToSelect:Body2 + Mods:CheckingPreviousMods Mods:LoadingMods Mods:FinishedLoadingMods Mods:NoMods diff --git a/ModAssistant/Localisation/en.xaml b/ModAssistant/Localisation/en.xaml index db0d1e68..04281d24 100644 --- a/ModAssistant/Localisation/en.xaml +++ b/ModAssistant/Localisation/en.xaml @@ -91,6 +91,12 @@ Uninstall Could not load mods list Checking installed mods + Reselect mods? + The game has updated since you last modded, would you like to automatically re-select the mods you had installed previously? + Failed to select {0} mods + The following mods could not be found and weren't selected: + These mods might not be updated for the current game version. + Checking previously installed mods Loading Mods Finished loading mods No mods available for this version of Beat Saber diff --git a/ModAssistant/Pages/Mods.xaml.cs b/ModAssistant/Pages/Mods.xaml.cs index a2499c44..03bde285 100644 --- a/ModAssistant/Pages/Mods.xaml.cs +++ b/ModAssistant/Pages/Mods.xaml.cs @@ -131,15 +131,23 @@ public async Task LoadMods() !DirectoryContainsMods(Path.Combine(App.BeatSaberInstallDirectory, "Plugins")) && !DirectoryContainsMods(Path.Combine(App.BeatSaberInstallDirectory, "IPA/Pending/Plugins"))) { - var reinstallMods = System.Windows.Forms.MessageBox.Show("The game has updated since you last played, would you like to automatically re-select the mods you had installed previously?", "Reinstall mods?", MessageBoxButtons.OKCancel) == DialogResult.OK; + string body = (string)FindResource("Mods:GameUpdatedPrompt:OkCancel"); + string title = (string)FindResource("Mods:GameUpdatedPrompt:Title"); + + var reinstallMods = System.Windows.Forms.MessageBox.Show(body, title, MessageBoxButtons.OKCancel) == DialogResult.OK; if (reinstallMods) { - MainWindow.Instance.MainText = $"Checking mods for previous version of the game..."; + MainWindow.Instance.MainText = $"{FindResource("Mods:CheckingPreviousMods")}..."; await Task.Run(async () => await SelectPreviousMods(lastModdedVersion)); InstalledColumn.Width = double.NaN; UninstallColumn.Width = 70; DescriptionColumn.Width = 750; - - var modsDialog2 = System.Windows.Forms.MessageBox.Show($"The following mods could not be found and weren't selected:\n{string.Join(",\n", MissingOldMods)}\n\nThese mods might not be updated yet.", "Reinstall mods?", MessageBoxButtons.OKCancel) == DialogResult.OK; + if (MissingOldMods.Count > 0) { + string notSelectedTitle = string.Format((string)FindResource("Mods:FailedToSelect:Title"), MissingOldMods.Count); + string notSelectedBody1 = (string)FindResource("Mods:FailedToSelect:Body1"); + string notSelectedBody2 = (string)FindResource("Mods:FailedToSelect:Body2"); + + System.Windows.Forms.MessageBox.Show($"{notSelectedBody1}\n{string.Join(",\n", MissingOldMods)}\n\n{notSelectedBody2}", notSelectedTitle, MessageBoxButtons.OK); + } } } From a50b7881af8f95429e12a4bb3042b8a529a2d34e Mon Sep 17 00:00:00 2001 From: leogandmars Date: Sun, 5 Sep 2021 18:58:46 -0700 Subject: [PATCH 3/3] Fixed small logging/formatting errors --- ModAssistant/Pages/Mods.xaml.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ModAssistant/Pages/Mods.xaml.cs b/ModAssistant/Pages/Mods.xaml.cs index 03bde285..fa348c45 100644 --- a/ModAssistant/Pages/Mods.xaml.cs +++ b/ModAssistant/Pages/Mods.xaml.cs @@ -31,8 +31,8 @@ public sealed partial class Mods : Page public static List InstalledMods = new List(); public static List LibsToMatch = new List(); public List CategoryNames = new List(); - public CollectionView view; public static List MissingOldMods = new List(); + public CollectionView view; public bool PendingChanges; private readonly SemaphoreSlim _modsLoadSem = new SemaphoreSlim(1, 1); @@ -316,7 +316,6 @@ public void GetBSIPAVersion() private void AddDetectedMod(Mod mod) { - Console.WriteLine(mod.name); if (!InstalledMods.Contains(mod)) { InstalledMods.Add(mod);