diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs index 47d8a293..453edfe1 100644 --- a/Bloxstrap/App.xaml.cs +++ b/Bloxstrap/App.xaml.cs @@ -27,6 +27,7 @@ public partial class App : Application public const string ProjectName = "Bloxstrap"; public const string ProjectRepository = "pizzaboxer/bloxstrap"; + // used only for communicating between app and menu - use Directories.Base for anything else public static string BaseDirectory = null!; public static bool ShouldSaveConfigs { get; set; } = false; public static bool IsSetupComplete { get; set; } = true; diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 38e1620a..1eaafbe8 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -67,6 +67,7 @@ public partial class Bootstrapper private readonly CancellationTokenSource _cancelTokenSource = new(); private static bool FreshInstall => String.IsNullOrEmpty(App.State.Prop.VersionGuid); + private static string DesktopShortcutLocation => Path.Combine(Directories.Desktop, "Play Roblox.lnk"); private string? _launchCommandLine; @@ -114,6 +115,8 @@ public async Task Run() await CheckLatestVersion(); + CheckInstallMigration(); + // if bloxstrap is installing for the first time but is running, prompt to close roblox // if roblox needs updating but is running, ignore update for now if (!Directory.Exists(_versionFolder) && CheckIfRunning(true) || App.State.Prop.VersionGuid != _versionGuid && !CheckIfRunning(false)) @@ -199,6 +202,69 @@ private async Task CheckLatestVersion() _versionPackageManifest = await PackageManifest.Get(_versionGuid); } + private void CheckInstallMigration() + { + // check if we've changed our install location since the last time we started + // in which case, we'll have to copy over all our folders so we don't lose any mods and stuff + + using RegistryKey? applicationKey = Registry.CurrentUser.OpenSubKey($@"Software\{App.ProjectName}", true); + + string? oldInstallLocation = (string?)applicationKey?.GetValue("OldInstallLocation"); + + if (applicationKey is null || oldInstallLocation is null || oldInstallLocation == Directories.Base) + return; + + SetStatus("Migrating install location..."); + + if (Directory.Exists(oldInstallLocation)) + { + App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Moving all files in {oldInstallLocation} to {Directories.Base}..."); + + foreach (string oldFileLocation in Directory.GetFiles(oldInstallLocation, "*.*", SearchOption.AllDirectories)) + { + string relativeFile = oldFileLocation.Substring(oldInstallLocation.Length + 1); + string newFileLocation = Path.Combine(Directories.Base, relativeFile); + string? newDirectory = Path.GetDirectoryName(newFileLocation); + + try + { + if (!String.IsNullOrEmpty(newDirectory)) + Directory.CreateDirectory(newDirectory); + + File.Move(oldFileLocation, newFileLocation, true); + } + catch (Exception ex) + { + App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to move {oldFileLocation} to {newFileLocation}! {ex}"); + } + } + + try + { + Directory.Delete(oldInstallLocation, true); + App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Deleted old install location"); + } + catch (Exception ex) + { + App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to delete old install location! {ex}"); + } + } + + applicationKey.DeleteValue("OldInstallLocation"); + + // allow shortcuts to be re-registered + if (Directory.Exists(Directories.StartMenu)) + Directory.Delete(Directories.StartMenu, true); + + if (File.Exists(DesktopShortcutLocation)) + { + File.Delete(DesktopShortcutLocation); + App.Settings.Prop.CreateDesktopIcon = true; + } + + App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Finished migrating install location!"); + } + private bool CheckIfRunning(bool shutdown) { App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Checking if Roblox is running... (shutdown={shutdown})"); @@ -393,48 +459,32 @@ public void CancelInstall() #region App Install public static void Register() { - RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"); + using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}")) + { + applicationKey.SetValue("InstallLocation", Directories.Base); + } - // new install location selected, delete old one - string? oldInstallLocation = (string?)applicationKey.GetValue("OldInstallLocation"); - if (!String.IsNullOrEmpty(oldInstallLocation) && oldInstallLocation != Directories.Base) + // set uninstall key + using (RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}")) { - try - { - if (Directory.Exists(oldInstallLocation)) - Directory.Delete(oldInstallLocation, true); - } - catch (Exception) - { - // ignored - } + uninstallKey.SetValue("DisplayIcon", $"{Directories.Application},0"); + uninstallKey.SetValue("DisplayName", App.ProjectName); + uninstallKey.SetValue("DisplayVersion", App.Version); - applicationKey.DeleteValue("OldInstallLocation"); - } + if (uninstallKey.GetValue("InstallDate") is null) + uninstallKey.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd")); - applicationKey.SetValue("InstallLocation", Directories.Base); - applicationKey.Close(); + uninstallKey.SetValue("InstallLocation", Directories.Base); + uninstallKey.SetValue("NoRepair", 1); + uninstallKey.SetValue("Publisher", "pizzaboxer"); + uninstallKey.SetValue("ModifyPath", $"\"{Directories.Application}\" -menu"); + uninstallKey.SetValue("QuietUninstallString", $"\"{Directories.Application}\" -uninstall -quiet"); + uninstallKey.SetValue("UninstallString", $"\"{Directories.Application}\" -uninstall"); + uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{App.ProjectRepository}"); + uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest"); + } - // set uninstall key - RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{App.ProjectName}"); - uninstallKey.SetValue("DisplayIcon", $"{Directories.Application},0"); - uninstallKey.SetValue("DisplayName", App.ProjectName); - uninstallKey.SetValue("DisplayVersion", App.Version); - - if (uninstallKey.GetValue("InstallDate") is null) - uninstallKey.SetValue("InstallDate", DateTime.Now.ToString("yyyyMMdd")); - - uninstallKey.SetValue("InstallLocation", Directories.Base); - uninstallKey.SetValue("NoRepair", 1); - uninstallKey.SetValue("Publisher", "pizzaboxer"); - uninstallKey.SetValue("ModifyPath", $"\"{Directories.Application}\" -menu"); - uninstallKey.SetValue("QuietUninstallString", $"\"{Directories.Application}\" -uninstall -quiet"); - uninstallKey.SetValue("UninstallString", $"\"{Directories.Application}\" -uninstall"); - uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{App.ProjectRepository}"); - uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest"); - uninstallKey.Close(); - - App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application version"); + App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application"); } public static void CheckInstall() @@ -485,10 +535,10 @@ public static void CheckInstall() if (App.Settings.Prop.CreateDesktopIcon) { - if (!File.Exists(Path.Combine(Directories.Desktop, "Play Roblox.lnk"))) + if (!File.Exists(DesktopShortcutLocation)) { ShellLink.Shortcut.CreateShortcut(Directories.Application, "", Directories.Application, 0) - .WriteToFile(Path.Combine(Directories.Desktop, "Play Roblox.lnk")); + .WriteToFile(DesktopShortcutLocation); } // one-time toggle, set it back to false diff --git a/Bloxstrap/Helpers/Integrations/RbxFpsUnlocker.cs b/Bloxstrap/Helpers/Integrations/RbxFpsUnlocker.cs index 71a72784..ae49afd8 100644 --- a/Bloxstrap/Helpers/Integrations/RbxFpsUnlocker.cs +++ b/Bloxstrap/Helpers/Integrations/RbxFpsUnlocker.cs @@ -41,7 +41,7 @@ public static void CheckIfRunning() if (process.MainModule?.FileName is null) continue; - if (!process.MainModule.FileName.Contains(App.BaseDirectory)) + if (!process.MainModule.FileName.Contains(Directories.Base)) continue; process.Kill(); @@ -56,7 +56,7 @@ public static void CheckIfRunning() public static async Task CheckInstall() { - string folderLocation = Path.Combine(App.BaseDirectory, "Integrations\\rbxfpsunlocker"); + string folderLocation = Path.Combine(Directories.Base, "Integrations\\rbxfpsunlocker"); string fileLocation = Path.Combine(folderLocation, "rbxfpsunlocker.exe"); string settingsLocation = Path.Combine(folderLocation, "settings"); diff --git a/Bloxstrap/Helpers/JsonManager.cs b/Bloxstrap/Helpers/JsonManager.cs index fed021f9..69e86f7b 100644 --- a/Bloxstrap/Helpers/JsonManager.cs +++ b/Bloxstrap/Helpers/JsonManager.cs @@ -15,7 +15,7 @@ namespace Bloxstrap.Helpers { public class JsonManager where T : new() { - public T Prop { get; set; } = new T(); + public T Prop { get; set; } = new(); //public bool ShouldSave { get; set; } = true; public string FileLocation => Path.Combine(Directories.Base, $"{typeof(T).Name}.json"); //public string? FileLocation { get; set; } = null; diff --git a/Bloxstrap/ViewModels/MainWindowViewModel.cs b/Bloxstrap/ViewModels/MainWindowViewModel.cs index d0b9c726..52a3a197 100644 --- a/Bloxstrap/ViewModels/MainWindowViewModel.cs +++ b/Bloxstrap/ViewModels/MainWindowViewModel.cs @@ -2,6 +2,7 @@ using System.IO; using System.Windows; using System.Windows.Input; +using Bloxstrap.Helpers; using Microsoft.Win32; using CommunityToolkit.Mvvm.Input; using Wpf.Ui.Controls.Interfaces; @@ -39,19 +40,11 @@ private void ConfirmSettings() try { // check if we can write to the directory (a bit hacky but eh) + string testFile = Path.Combine(App.BaseDirectory, $"{App.ProjectName}WriteTest.txt"); - string testPath = App.BaseDirectory; - string testFile = Path.Combine(testPath, $"{App.ProjectName}WriteTest.txt"); - bool testPathExists = Directory.Exists(testPath); - - if (!testPathExists) - Directory.CreateDirectory(testPath); - + Directory.CreateDirectory(App.BaseDirectory); File.WriteAllText(testFile, "hi"); File.Delete(testFile); - - if (!testPathExists) - Directory.Delete(testPath); } catch (UnauthorizedAccessException) { @@ -71,22 +64,13 @@ private void ConfirmSettings() if (App.BaseDirectory != _originalBaseDirectory) { + App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}"); App.ShowMessageBox($"{App.ProjectName} will install to the new location you've set the next time it runs.", MessageBoxImage.Information); - App.State.Prop.VersionGuid = ""; - - using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}")) - { - registryKey.SetValue("InstallLocation", App.BaseDirectory); - registryKey.SetValue("OldInstallLocation", _originalBaseDirectory); - registryKey.Close(); - } - - // preserve settings - // we don't need to copy the bootstrapper over since the install process will do that automatically - - // App.Settings.Save(); - // File.Copy(Path.Combine(App.BaseDirectory, "Settings.json"), Path.Combine(App.BaseDirectory, "Settings.json")); + using RegistryKey registryKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"); + registryKey.SetValue("InstallLocation", App.BaseDirectory); + registryKey.SetValue("OldInstallLocation", _originalBaseDirectory); + Directories.Initialize(App.BaseDirectory); } CloseWindow(); diff --git a/Bloxstrap/Views/Pages/BehaviourPage.xaml b/Bloxstrap/Views/Pages/BehaviourPage.xaml index 5e6ba9c9..8b677b7e 100644 --- a/Bloxstrap/Views/Pages/BehaviourPage.xaml +++ b/Bloxstrap/Views/Pages/BehaviourPage.xaml @@ -26,7 +26,7 @@ - + @@ -44,7 +44,7 @@ - +