From 44183090e05490dd3affc22e0ec70d9fe0a1c05f Mon Sep 17 00:00:00 2001 From: pizzaboxer <41478239+pizzaboxer@users.noreply.github.com> Date: Fri, 27 Jan 2023 13:22:02 +0000 Subject: [PATCH 1/7] Initialize stock WPF application --- Bloxstrap/Bloxstrap.csproj | 61 - Bloxstrap/Bloxstrap.ico | Bin 123254 -> 0 bytes Bloxstrap.sln => Bloxstrap/Bloxstrap.sln | 14 +- Bloxstrap/Bloxstrap/App.xaml | 9 + Bloxstrap/Bloxstrap/App.xaml.cs | 17 + Bloxstrap/Bloxstrap/AssemblyInfo.cs | 10 + Bloxstrap/Bloxstrap/Bloxstrap.csproj | 10 + Bloxstrap/Bloxstrap/MainWindow.xaml | 12 + Bloxstrap/Bloxstrap/MainWindow.xaml.cs | 28 + Bloxstrap/Bootstrapper.cs | 794 --- .../BootstrapperDialogForm.cs | 159 - .../IBootstrapperDialog.cs | 18 - .../LegacyDialog2009.Designer.cs | 94 - .../BootstrapperDialogs/LegacyDialog2009.cs | 47 - .../BootstrapperDialogs/LegacyDialog2009.resx | 60 - .../LegacyDialog2011.Designer.cs | 109 - .../BootstrapperDialogs/LegacyDialog2011.cs | 51 - .../BootstrapperDialogs/LegacyDialog2011.resx | 60 - .../ProgressDialog.Designer.cs | 128 - .../BootstrapperDialogs/ProgressDialog.cs | 81 - .../BootstrapperDialogs/ProgressDialog.resx | 60 - .../VistaDialog.Designer.cs | 51 - .../BootstrapperDialogs/VistaDialog.cs | 165 - .../BootstrapperDialogs/VistaDialog.resx | 60 - Bloxstrap/Dialogs/Menu/ModHelp.xaml | 39 - Bloxstrap/Dialogs/Menu/ModHelp.xaml.cs | 33 - Bloxstrap/Dialogs/Menu/Preferences.xaml | 177 - Bloxstrap/Dialogs/Menu/Preferences.xaml.cs | 422 -- Bloxstrap/Dialogs/Menu/ReShadeHelp.xaml | 54 - Bloxstrap/Dialogs/Menu/ReShadeHelp.xaml.cs | 33 - .../Menu/Themes/ColourfulDarkTheme.xaml | 4505 ---------------- .../Menu/Themes/ColourfulDarkTheme.xaml.cs | 43 - .../Menu/Themes/ColourfulLightTheme.xaml | 4555 ---------------- .../Menu/Themes/ColourfulLightTheme.xaml.cs | 43 - Bloxstrap/Dialogs/Menu/Themes/DarkTheme.xaml | 4644 ----------------- .../Dialogs/Menu/Themes/DarkTheme.xaml.cs | 43 - Bloxstrap/Dialogs/Menu/Themes/LightTheme.xaml | 4461 ---------------- .../Dialogs/Menu/Themes/LightTheme.xaml.cs | 43 - Bloxstrap/Enums/BootstrapperIcon.cs | 79 - Bloxstrap/Enums/BootstrapperStyle.cs | 49 - Bloxstrap/Enums/Theme.cs | 32 - Bloxstrap/Helpers/DeployManager.cs | 89 - Bloxstrap/Helpers/Directories.cs | 38 - .../Integrations/DiscordRichPresence.cs | 205 - .../Helpers/Integrations/RbxFpsUnlocker.cs | 109 - Bloxstrap/Helpers/Integrations/ReShade.cs | 398 -- Bloxstrap/Helpers/Protocol.cs | 109 - Bloxstrap/Helpers/RSMM/Package.cs | 17 - Bloxstrap/Helpers/RSMM/PackageManifest.cs | 57 - Bloxstrap/Helpers/RSMM/SystemEvent.cs | 39 - Bloxstrap/Helpers/ResourceHelper.cs | 25 - Bloxstrap/Helpers/Updater.cs | 63 - Bloxstrap/Helpers/Utilities.cs | 81 - Bloxstrap/Helpers/WindowScaling.cs | 37 - Bloxstrap/Models/ClientVersion.cs | 18 - Bloxstrap/Models/GithubRelease.cs | 31 - Bloxstrap/Models/ReShadeVersionManifest.cs | 9 - Bloxstrap/Models/RobloxAsset.cs | 13 - Bloxstrap/Models/RobloxThumbnails.cs | 16 - Bloxstrap/Models/SettingsFormat.cs | 41 - Bloxstrap/Program.cs | 172 - Bloxstrap/Properties/Resources.Designer.cs | 263 - Bloxstrap/Properties/Resources.resx | 181 - Bloxstrap/Properties/Settings.Designer.cs | 26 - Bloxstrap/Properties/Settings.settings | 6 - Bloxstrap/Resources/CancelButton.png | Bin 768 -> 0 bytes Bloxstrap/Resources/CancelButtonHover.png | Bin 944 -> 0 bytes Bloxstrap/Resources/DarkCancelButton.png | Bin 1134 -> 0 bytes Bloxstrap/Resources/DarkCancelButtonHover.png | Bin 1175 -> 0 bytes Bloxstrap/Resources/Icon2009-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/Icon2009-png.png | Bin 16441 -> 0 bytes Bloxstrap/Resources/Icon2011-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/Icon2011-png.png | Bin 7754 -> 0 bytes Bloxstrap/Resources/Icon2017-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/Icon2017-png.png | Bin 5563 -> 0 bytes Bloxstrap/Resources/Icon2019-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/Icon2019-png.png | Bin 13984 -> 0 bytes Bloxstrap/Resources/Icon2022-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/Icon2022-png.png | Bin 5968 -> 0 bytes Bloxstrap/Resources/IconBloxstrap-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/IconBloxstrap-png.png | Bin 4034 -> 0 bytes Bloxstrap/Resources/IconEarly2015-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/IconEarly2015-png.png | Bin 5941 -> 0 bytes Bloxstrap/Resources/IconLate2015-ico.ico | Bin 16958 -> 0 bytes Bloxstrap/Resources/IconLate2015-png.png | Bin 10100 -> 0 bytes Bloxstrap/Resources/Mods/OldCursor.png | Bin 232 -> 0 bytes Bloxstrap/Resources/Mods/OldDeath.ogg | Bin 6271 -> 0 bytes Bloxstrap/Resources/Mods/OldFarCursor.png | Bin 235 -> 0 bytes Bloxstrap/SettingsManager.cs | 81 - 89 files changed, 93 insertions(+), 23384 deletions(-) delete mode 100644 Bloxstrap/Bloxstrap.csproj delete mode 100644 Bloxstrap/Bloxstrap.ico rename Bloxstrap.sln => Bloxstrap/Bloxstrap.sln (56%) create mode 100644 Bloxstrap/Bloxstrap/App.xaml create mode 100644 Bloxstrap/Bloxstrap/App.xaml.cs create mode 100644 Bloxstrap/Bloxstrap/AssemblyInfo.cs create mode 100644 Bloxstrap/Bloxstrap/Bloxstrap.csproj create mode 100644 Bloxstrap/Bloxstrap/MainWindow.xaml create mode 100644 Bloxstrap/Bloxstrap/MainWindow.xaml.cs delete mode 100644 Bloxstrap/Bootstrapper.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/BootstrapperDialogForm.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/IBootstrapperDialog.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.Designer.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.resx delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.Designer.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.resx delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.Designer.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.resx delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.Designer.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.cs delete mode 100644 Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.resx delete mode 100644 Bloxstrap/Dialogs/Menu/ModHelp.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/ModHelp.xaml.cs delete mode 100644 Bloxstrap/Dialogs/Menu/Preferences.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/Preferences.xaml.cs delete mode 100644 Bloxstrap/Dialogs/Menu/ReShadeHelp.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/ReShadeHelp.xaml.cs delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/ColourfulDarkTheme.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/ColourfulDarkTheme.xaml.cs delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/ColourfulLightTheme.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/ColourfulLightTheme.xaml.cs delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/DarkTheme.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/DarkTheme.xaml.cs delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/LightTheme.xaml delete mode 100644 Bloxstrap/Dialogs/Menu/Themes/LightTheme.xaml.cs delete mode 100644 Bloxstrap/Enums/BootstrapperIcon.cs delete mode 100644 Bloxstrap/Enums/BootstrapperStyle.cs delete mode 100644 Bloxstrap/Enums/Theme.cs delete mode 100644 Bloxstrap/Helpers/DeployManager.cs delete mode 100644 Bloxstrap/Helpers/Directories.cs delete mode 100644 Bloxstrap/Helpers/Integrations/DiscordRichPresence.cs delete mode 100644 Bloxstrap/Helpers/Integrations/RbxFpsUnlocker.cs delete mode 100644 Bloxstrap/Helpers/Integrations/ReShade.cs delete mode 100644 Bloxstrap/Helpers/Protocol.cs delete mode 100644 Bloxstrap/Helpers/RSMM/Package.cs delete mode 100644 Bloxstrap/Helpers/RSMM/PackageManifest.cs delete mode 100644 Bloxstrap/Helpers/RSMM/SystemEvent.cs delete mode 100644 Bloxstrap/Helpers/ResourceHelper.cs delete mode 100644 Bloxstrap/Helpers/Updater.cs delete mode 100644 Bloxstrap/Helpers/Utilities.cs delete mode 100644 Bloxstrap/Helpers/WindowScaling.cs delete mode 100644 Bloxstrap/Models/ClientVersion.cs delete mode 100644 Bloxstrap/Models/GithubRelease.cs delete mode 100644 Bloxstrap/Models/ReShadeVersionManifest.cs delete mode 100644 Bloxstrap/Models/RobloxAsset.cs delete mode 100644 Bloxstrap/Models/RobloxThumbnails.cs delete mode 100644 Bloxstrap/Models/SettingsFormat.cs delete mode 100644 Bloxstrap/Program.cs delete mode 100644 Bloxstrap/Properties/Resources.Designer.cs delete mode 100644 Bloxstrap/Properties/Resources.resx delete mode 100644 Bloxstrap/Properties/Settings.Designer.cs delete mode 100644 Bloxstrap/Properties/Settings.settings delete mode 100644 Bloxstrap/Resources/CancelButton.png delete mode 100644 Bloxstrap/Resources/CancelButtonHover.png delete mode 100644 Bloxstrap/Resources/DarkCancelButton.png delete mode 100644 Bloxstrap/Resources/DarkCancelButtonHover.png delete mode 100644 Bloxstrap/Resources/Icon2009-ico.ico delete mode 100644 Bloxstrap/Resources/Icon2009-png.png delete mode 100644 Bloxstrap/Resources/Icon2011-ico.ico delete mode 100644 Bloxstrap/Resources/Icon2011-png.png delete mode 100644 Bloxstrap/Resources/Icon2017-ico.ico delete mode 100644 Bloxstrap/Resources/Icon2017-png.png delete mode 100644 Bloxstrap/Resources/Icon2019-ico.ico delete mode 100644 Bloxstrap/Resources/Icon2019-png.png delete mode 100644 Bloxstrap/Resources/Icon2022-ico.ico delete mode 100644 Bloxstrap/Resources/Icon2022-png.png delete mode 100644 Bloxstrap/Resources/IconBloxstrap-ico.ico delete mode 100644 Bloxstrap/Resources/IconBloxstrap-png.png delete mode 100644 Bloxstrap/Resources/IconEarly2015-ico.ico delete mode 100644 Bloxstrap/Resources/IconEarly2015-png.png delete mode 100644 Bloxstrap/Resources/IconLate2015-ico.ico delete mode 100644 Bloxstrap/Resources/IconLate2015-png.png delete mode 100644 Bloxstrap/Resources/Mods/OldCursor.png delete mode 100644 Bloxstrap/Resources/Mods/OldDeath.ogg delete mode 100644 Bloxstrap/Resources/Mods/OldFarCursor.png delete mode 100644 Bloxstrap/SettingsManager.cs diff --git a/Bloxstrap/Bloxstrap.csproj b/Bloxstrap/Bloxstrap.csproj deleted file mode 100644 index ba22c11..0000000 --- a/Bloxstrap/Bloxstrap.csproj +++ /dev/null @@ -1,61 +0,0 @@ - - - - WinExe - net6.0-windows - enable - true - true - enable - AnyCPU - AnyCPU;x86 - Bloxstrap.ico - 1.7.0 - 1.7.0.0 - - - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - True - True - Settings.settings - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - \ No newline at end of file diff --git a/Bloxstrap/Bloxstrap.ico b/Bloxstrap/Bloxstrap.ico deleted file mode 100644 index 93904fb8b943e6451a9eb2a4fdb1262882464c16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123254 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 k$NOb(b2zKsQ0=m|*>tyc*ljT9Wp4+K`yz>9{> + + + + diff --git a/Bloxstrap/Bloxstrap/App.xaml.cs b/Bloxstrap/Bloxstrap/App.xaml.cs new file mode 100644 index 0000000..c27cc75 --- /dev/null +++ b/Bloxstrap/Bloxstrap/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace Bloxstrap +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/Bloxstrap/Bloxstrap/AssemblyInfo.cs b/Bloxstrap/Bloxstrap/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/Bloxstrap/Bloxstrap/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/Bloxstrap/Bloxstrap/Bloxstrap.csproj b/Bloxstrap/Bloxstrap/Bloxstrap.csproj new file mode 100644 index 0000000..4106cb0 --- /dev/null +++ b/Bloxstrap/Bloxstrap/Bloxstrap.csproj @@ -0,0 +1,10 @@ + + + + WinExe + net6.0-windows + enable + true + + + diff --git a/Bloxstrap/Bloxstrap/MainWindow.xaml b/Bloxstrap/Bloxstrap/MainWindow.xaml new file mode 100644 index 0000000..af8a6e6 --- /dev/null +++ b/Bloxstrap/Bloxstrap/MainWindow.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/Bloxstrap/Bloxstrap/MainWindow.xaml.cs b/Bloxstrap/Bloxstrap/MainWindow.xaml.cs new file mode 100644 index 0000000..b16887f --- /dev/null +++ b/Bloxstrap/Bloxstrap/MainWindow.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Bloxstrap +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs deleted file mode 100644 index 2768b0d..0000000 --- a/Bloxstrap/Bootstrapper.cs +++ /dev/null @@ -1,794 +0,0 @@ -using System.Diagnostics; -using System.IO; -using System.IO.Compression; -using System.Net.Http; - -using Microsoft.Win32; - -using Bloxstrap.Enums; -using Bloxstrap.Dialogs.BootstrapperDialogs; -using Bloxstrap.Helpers; -using Bloxstrap.Helpers.Integrations; -using Bloxstrap.Helpers.RSMM; -using Bloxstrap.Models; -using System.Net; -using Bloxstrap.Properties; - -namespace Bloxstrap -{ - public partial class Bootstrapper - { - #region Properties - - // https://learn.microsoft.com/en-us/windows/win32/msi/error-codes - public const int ERROR_SUCCESS = 0; - public const int ERROR_INSTALL_USEREXIT = 1602; - public const int ERROR_INSTALL_FAILURE = 1603; - public const int ERROR_PRODUCT_UNINSTALLED = 1614; - - // in case a new package is added, you can find the corresponding directory - // by opening the stock bootstrapper in a hex editor - // TODO - there ideally should be a less static way to do this that's not hardcoded? - private static readonly IReadOnlyDictionary PackageDirectories = new Dictionary() - { - { "RobloxApp.zip", @"" }, - { "shaders.zip", @"shaders\" }, - { "ssl.zip", @"ssl\" }, - - { "content-avatar.zip", @"content\avatar\" }, - { "content-configs.zip", @"content\configs\" }, - { "content-fonts.zip", @"content\fonts\" }, - { "content-sky.zip", @"content\sky\" }, - { "content-sounds.zip", @"content\sounds\" }, - { "content-textures2.zip", @"content\textures\" }, - { "content-models.zip", @"content\models\" }, - - { "content-textures3.zip", @"PlatformContent\pc\textures\" }, - { "content-terrain.zip", @"PlatformContent\pc\terrain\" }, - { "content-platform-fonts.zip", @"PlatformContent\pc\fonts\" }, - - { "extracontent-luapackages.zip", @"ExtraContent\LuaPackages\" }, - { "extracontent-translations.zip", @"ExtraContent\translations\" }, - { "extracontent-models.zip", @"ExtraContent\models\" }, - { "extracontent-textures.zip", @"ExtraContent\textures\" }, - { "extracontent-places.zip", @"ExtraContent\places\" }, - }; - - private static readonly string AppSettings = - "\n" + - "\n" + - " content\n" + - " http://www.roblox.com\n" + - "\n"; - - private string? LaunchCommandLine; - - private string VersionGuid = null!; - private PackageManifest VersionPackageManifest = null!; - private string VersionFolder = null!; - - private readonly bool FreshInstall; - - private double ProgressIncrement; - private long TotalBytes = 0; - private long TotalDownloadedBytes = 0; - private int PackagesExtracted = 0; - private bool CancelFired = false; - - public IBootstrapperDialog Dialog = null!; - #endregion - - #region Core - public Bootstrapper(string? launchCommandLine = null) - { - LaunchCommandLine = launchCommandLine; - FreshInstall = String.IsNullOrEmpty(Program.Settings.VersionGuid); - } - - // this is called from BootstrapperStyleForm.SetupDialog() - public async Task Run() - { - if (Program.IsQuiet) - Dialog.CloseDialog(); - - if (Program.IsUninstall) - { - Uninstall(); - return; - } - -#if !DEBUG - if (!Program.IsFirstRun && Program.Settings.CheckForUpdates) - await CheckForUpdates(); -#endif - - await CheckLatestVersion(); - - // 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) || Program.Settings.VersionGuid != VersionGuid && !CheckIfRunning(false)) - await InstallLatestVersion(); - - await ApplyModifications(); - - if (Program.IsFirstRun) - Program.SettingsManager.ShouldSave = true; - - if (Program.IsFirstRun || FreshInstall) - Register(); - - CheckInstall(); - - await RbxFpsUnlocker.CheckInstall(); - - Program.SettingsManager.Save(); - - if (Program.IsFirstRun && Program.IsNoLaunch) - Dialog.ShowSuccess($"{Program.ProjectName} has successfully installed"); - else if (!Program.IsNoLaunch) - await StartRoblox(); - } - - private async Task CheckForUpdates() - { - string currentVersion = $"Bloxstrap v{Program.Version}"; - - var releaseInfo = await Utilities.GetJson($"https://api.github.com/repos/{Program.ProjectRepository}/releases/latest"); - - if (releaseInfo is null || releaseInfo.Name is null || releaseInfo.Assets is null || currentVersion == releaseInfo.Name) - return; - - Dialog.Message = "Getting the latest Bloxstrap..."; - - // 64-bit is always the first option - GithubReleaseAsset asset = releaseInfo.Assets[Environment.Is64BitOperatingSystem ? 0 : 1]; - string downloadLocation = Path.Combine(Directories.Updates, asset.Name); - - Directory.CreateDirectory(Directories.Updates); - - Debug.WriteLine($"Downloading {releaseInfo.Name}..."); - - if (!File.Exists(downloadLocation)) - { - var response = await Program.HttpClient.GetAsync(asset.BrowserDownloadUrl); - - using (var fileStream = new FileStream(Path.Combine(Directories.Updates, asset.Name), FileMode.CreateNew)) - { - await response.Content.CopyToAsync(fileStream); - } - } - - Debug.WriteLine($"Starting {releaseInfo.Name}..."); - - ProcessStartInfo startInfo = new() - { - FileName = downloadLocation, - }; - - foreach (string arg in Program.LaunchArgs) - startInfo.ArgumentList.Add(arg); - - Program.SettingsManager.Save(); - - Process.Start(startInfo); - - Environment.Exit(0); - } - - private async Task CheckLatestVersion() - { - Dialog.Message = "Connecting to Roblox..."; - - ClientVersion clientVersion = await DeployManager.GetLastDeploy(Program.Settings.Channel); - VersionGuid = clientVersion.VersionGuid; - VersionFolder = Path.Combine(Directories.Versions, VersionGuid); - VersionPackageManifest = await PackageManifest.Get(VersionGuid); - } - - private bool CheckIfRunning(bool shutdown) - { - Process[] processes = Process.GetProcessesByName("RobloxPlayerBeta"); - - if (processes.Length == 0) - return false; - - if (shutdown) - { - Dialog.PromptShutdown(); - - try - { - // try/catch just in case process was closed before prompt was answered - - foreach (Process process in processes) - { - process.CloseMainWindow(); - process.Close(); - } - } - catch (Exception) { } - } - - return true; - } - - private async Task StartRoblox() - { - string startEventName = Program.ProjectName.Replace(" ", "") + "StartEvent"; - - Dialog.Message = "Starting Roblox..."; - - if (LaunchCommandLine == "--app" && Program.Settings.UseDisableAppPatch) - { - Utilities.OpenWebsite("https://www.roblox.com/games"); - return; - } - - // launch time isn't really required for all launches, but it's usually just safest to do this - LaunchCommandLine += " --launchtime=" + DateTimeOffset.Now.ToUnixTimeMilliseconds(); - - if (Program.Settings.Channel.ToLower() != DeployManager.DefaultChannel.ToLower()) - LaunchCommandLine += " -channel " + Program.Settings.Channel.ToLower(); - - LaunchCommandLine += " -startEvent " + startEventName; - - using (SystemEvent startEvent = new(startEventName)) - { - bool shouldWait = false; - - Process gameClient = Process.Start(Path.Combine(VersionFolder, "RobloxPlayerBeta.exe"), LaunchCommandLine); - Process? rbxFpsUnlocker = null; - DiscordRichPresence? richPresence = null; - - bool startEventFired = await startEvent.WaitForEvent(); - - startEvent.Close(); - - if (!startEventFired) - return; - - if (Program.Settings.RFUEnabled && Process.GetProcessesByName("rbxfpsunlocker").Length == 0) - { - ProcessStartInfo startInfo = new() - { - FileName = Path.Combine(Directories.Integrations, @"rbxfpsunlocker\rbxfpsunlocker.exe"), - WorkingDirectory = Path.Combine(Directories.Integrations, "rbxfpsunlocker") - }; - - rbxFpsUnlocker = Process.Start(startInfo); - - if (Program.Settings.RFUAutoclose) - shouldWait = true; - } - - // event fired, wait for 3 seconds then close - await Task.Delay(3000); - - // now we move onto handling rich presence - if (Program.Settings.UseDiscordRichPresence) - { - richPresence = new DiscordRichPresence(); - richPresence.MonitorGameActivity(); - - shouldWait = true; - } - - if (!shouldWait) - return; - - // keep bloxstrap open in the background - Dialog.CloseDialog(); - await gameClient.WaitForExitAsync(); - - if (richPresence is not null) - richPresence.Dispose(); - - if (Program.Settings.RFUAutoclose && rbxFpsUnlocker is not null) - rbxFpsUnlocker.Kill(); - } - } - - public void CancelButtonClicked() - { - if (!Dialog.CancelEnabled) - { - Program.Exit(ERROR_INSTALL_USEREXIT); - return; - } - - CancelFired = true; - - try - { - if (Program.IsFirstRun) - Directory.Delete(Directories.Base, true); - else if (Directory.Exists(VersionFolder)) - Directory.Delete(VersionFolder, true); - } - catch (Exception) { } - - Program.Exit(ERROR_INSTALL_USEREXIT); - } -#endregion - -#region App Install - public static void Register() - { - RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{Program.ProjectName}"); - - // new install location selected, delete old one - string? oldInstallLocation = (string?)applicationKey.GetValue("OldInstallLocation"); - if (!String.IsNullOrEmpty(oldInstallLocation) && oldInstallLocation != Directories.Base) - { - try - { - if (Directory.Exists(oldInstallLocation)) - Directory.Delete(oldInstallLocation, true); - } - catch (Exception) { } - - applicationKey.DeleteValue("OldInstallLocation"); - } - - applicationKey.SetValue("InstallLocation", Directories.Base); - applicationKey.Close(); - - // set uninstall key - RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{Program.ProjectName}"); - uninstallKey.SetValue("DisplayIcon", $"{Directories.App},0"); - uninstallKey.SetValue("DisplayName", Program.ProjectName); - uninstallKey.SetValue("DisplayVersion", Program.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.App}\" -preferences"); - uninstallKey.SetValue("QuietUninstallString", $"\"{Directories.App}\" -uninstall -quiet"); - uninstallKey.SetValue("UninstallString", $"\"{Directories.App}\" -uninstall"); - uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{Program.ProjectRepository}"); - uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{Program.ProjectRepository}/releases/latest"); - uninstallKey.Close(); - } - - public static void CheckInstall() - { - // check if launch uri is set to our bootstrapper - // this doesn't go under register, so we check every launch - // just in case the stock bootstrapper changes it back - - Protocol.Register("roblox", "Roblox", Directories.App); - Protocol.Register("roblox-player", "Roblox", Directories.App); - - // in case the user is reinstalling - if (File.Exists(Directories.App) && Program.IsFirstRun) - File.Delete(Directories.App); - - // check to make sure bootstrapper is in the install folder - if (!File.Exists(Directories.App) && Environment.ProcessPath is not null) - File.Copy(Environment.ProcessPath, Directories.App); - - // this SHOULD go under Register(), - // but then people who have Bloxstrap v1.0.0 installed won't have this without a reinstall - // maybe in a later version? - if (!Directory.Exists(Directories.StartMenu)) - { - Directory.CreateDirectory(Directories.StartMenu); - - ShellLink.Shortcut.CreateShortcut(Directories.App, "", Directories.App, 0) - .WriteToFile(Path.Combine(Directories.StartMenu, "Play Roblox.lnk")); - - ShellLink.Shortcut.CreateShortcut(Directories.App, "-preferences", Directories.App, 0) - .WriteToFile(Path.Combine(Directories.StartMenu, $"Configure {Program.ProjectName}.lnk")); - } - - if (Program.Settings.CreateDesktopIcon && !File.Exists(Path.Combine(Directories.Desktop, "Play Roblox.lnk"))) - { - ShellLink.Shortcut.CreateShortcut(Directories.App, "", Directories.App, 0) - .WriteToFile(Path.Combine(Directories.Desktop, "Play Roblox.lnk")); - } - } - - private void Uninstall() - { - CheckIfRunning(true); - - Dialog.Message = $"Uninstalling {Program.ProjectName}..."; - - Program.SettingsManager.ShouldSave = false; - - // check if stock bootstrapper is still installed - RegistryKey? bootstrapperKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\roblox-player"); - if (bootstrapperKey is null) - { - Protocol.Unregister("roblox"); - Protocol.Unregister("roblox-player"); - } - else - { - // revert launch uri handler to stock bootstrapper - - string bootstrapperLocation = (string?)bootstrapperKey.GetValue("InstallLocation") + "RobloxPlayerLauncher.exe"; - - Protocol.Register("roblox", "Roblox", bootstrapperLocation); - Protocol.Register("roblox-player", "Roblox", bootstrapperLocation); - } - - try - { - // delete application key - Registry.CurrentUser.DeleteSubKey($@"Software\{Program.ProjectName}"); - - // delete start menu folder - Directory.Delete(Directories.StartMenu, true); - - // delete desktop shortcut - File.Delete(Path.Combine(Directories.Desktop, "Play Roblox.lnk")); - - // delete uninstall key - Registry.CurrentUser.DeleteSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{Program.ProjectName}"); - - // delete installation folder - // (should delete everything except bloxstrap itself) - Directory.Delete(Directories.Base, true); - } - catch (Exception e) - { - Debug.WriteLine($"Could not fully uninstall! ({e})"); - } - - Dialog.ShowSuccess($"{Program.ProjectName} has succesfully uninstalled"); - - Program.Exit(); - } -#endregion - -#region Roblox Install - private void UpdateProgressbar() - { - int newProgress = (int)Math.Floor(ProgressIncrement * TotalDownloadedBytes); - Dialog.ProgressValue = newProgress; - } - - private async Task InstallLatestVersion() - { - if (FreshInstall) - Dialog.Message = "Installing Roblox..."; - else - Dialog.Message = "Upgrading Roblox..."; - - // check if we have at least 300 megabytes of free disk space - if (Utilities.GetFreeDiskSpace(Directories.Base) < 1024*1024*300) - { - Program.ShowMessageBox($"{Program.ProjectName} requires at least 300 MB of disk space to install Roblox. Please free up some disk space and try again.", MessageBoxIcon.Error); - Program.Exit(ERROR_INSTALL_FAILURE); - return; - } - - Directory.CreateDirectory(Directories.Base); - - Dialog.CancelEnabled = true; - Dialog.ProgressStyle = ProgressBarStyle.Continuous; - - // compute total bytes to download - - foreach (Package package in VersionPackageManifest) - TotalBytes += package.PackedSize; - - ProgressIncrement = (double)1 / TotalBytes * 100; - - Directory.CreateDirectory(Directories.Downloads); - Directory.CreateDirectory(Directories.Versions); - - foreach (Package package in VersionPackageManifest) - { - // download all the packages synchronously - await DownloadPackage(package); - - // extract the package immediately after download - ExtractPackage(package); - } - - // allow progress bar to 100% before continuing (purely ux reasons lol) - await Task.Delay(1000); - - Dialog.ProgressStyle = ProgressBarStyle.Marquee; - - Dialog.Message = "Configuring Roblox..."; - - // wait for all packages to finish extracting - while (PackagesExtracted < VersionPackageManifest.Count) - { - await Task.Delay(100); - } - - string appSettingsLocation = Path.Combine(VersionFolder, "AppSettings.xml"); - await File.WriteAllTextAsync(appSettingsLocation, AppSettings); - - if (!FreshInstall) - { - ReShade.SynchronizeConfigFile(); - - // let's take this opportunity to delete any packages we don't need anymore - foreach (string filename in Directory.GetFiles(Directories.Downloads)) - { - if (!VersionPackageManifest.Exists(package => filename.Contains(package.Signature))) - File.Delete(filename); - } - - string oldVersionFolder = Path.Combine(Directories.Versions, Program.Settings.VersionGuid); - - if (VersionGuid != Program.Settings.VersionGuid && Directory.Exists(oldVersionFolder)) - { - // and also to delete our old version folder - Directory.Delete(oldVersionFolder, true); - } - } - - Dialog.CancelEnabled = false; - - Program.Settings.VersionGuid = VersionGuid; - } - - private async Task ApplyModifications() - { - Dialog.Message = "Applying Roblox modifications..."; - - string modFolder = Path.Combine(Directories.Modifications); - string manifestFile = Path.Combine(Directories.Base, "ModManifest.txt"); - - List manifestFiles = new(); - List modFolderFiles = new(); - - if (!Directory.Exists(modFolder)) - Directory.CreateDirectory(modFolder); - - await CheckModPreset(Program.Settings.UseOldDeathSound, @"content\sounds\ouch.ogg", "OldDeath.ogg"); - await CheckModPreset(Program.Settings.UseOldMouseCursor, @"content\textures\Cursors\KeyboardMouse\ArrowCursor.png", "OldCursor.png"); - await CheckModPreset(Program.Settings.UseOldMouseCursor, @"content\textures\Cursors\KeyboardMouse\ArrowFarCursor.png", "OldFarCursor.png"); - await CheckModPreset(Program.Settings.UseDisableAppPatch, @"ExtraContent\places\Mobile.rbxl", ""); - - await ReShade.CheckModifications(); - - foreach (string file in Directory.GetFiles(modFolder, "*.*", SearchOption.AllDirectories)) - { - // get relative directory path - string relativeFile = file.Substring(modFolder.Length + 1); - - // v1.7.0 - README has been moved to the preferences menu now - if (relativeFile == "README.txt") - { - File.Delete(file); - continue; - } - - modFolderFiles.Add(relativeFile); - } - - // the manifest is primarily here to keep track of what files have been - // deleted from the modifications folder, so that we know when to restore the - // original files from the downloaded packages - - if (File.Exists(manifestFile)) - manifestFiles = (await File.ReadAllLinesAsync(manifestFile)).ToList(); - else - manifestFiles = modFolderFiles; - - // copy and overwrite - foreach (string file in modFolderFiles) - { - string fileModFolder = Path.Combine(modFolder, file); - string fileVersionFolder = Path.Combine(VersionFolder, file); - - if (File.Exists(fileVersionFolder)) - { - if (Utilities.MD5File(fileModFolder) == Utilities.MD5File(fileVersionFolder)) - continue; - } - - string? directory = Path.GetDirectoryName(fileVersionFolder); - - if (directory is null) - continue; - - Directory.CreateDirectory(directory); - - File.Copy(fileModFolder, fileVersionFolder, true); - File.SetAttributes(fileVersionFolder, File.GetAttributes(fileModFolder) & ~FileAttributes.ReadOnly); - } - - // now check for files that have been deleted from the mod folder according to the manifest - foreach (string fileLocation in manifestFiles) - { - if (modFolderFiles.Contains(fileLocation)) - continue; - - KeyValuePair packageDirectory; - - try - { - packageDirectory = PackageDirectories.First(x => x.Key != "RobloxApp.zip" && fileLocation.StartsWith(x.Value)); - } - catch (InvalidOperationException) - { - // package doesn't exist, likely mistakenly placed file - string versionFileLocation = Path.Combine(VersionFolder, fileLocation); - - File.Delete(versionFileLocation); - - continue; - } - - // restore original file - string fileName = fileLocation.Substring(packageDirectory.Value.Length); - ExtractFileFromPackage(packageDirectory.Key, fileName); - } - - File.WriteAllLines(manifestFile, modFolderFiles); - } - - private static async Task CheckModPreset(bool condition, string location, string name) - { - string modFolderLocation = Path.Combine(Directories.Modifications, location); - byte[] binaryData = string.IsNullOrEmpty(name) ? Array.Empty() : await ResourceHelper.Get(name); - - if (condition) - { - if (!File.Exists(modFolderLocation)) - { - string? directory = Path.GetDirectoryName(modFolderLocation); - - if (directory is null) - return; - - Directory.CreateDirectory(directory); - - await File.WriteAllBytesAsync(modFolderLocation, binaryData); - } - } - else if (File.Exists(modFolderLocation) && Utilities.MD5File(modFolderLocation) == Utilities.MD5Data(binaryData)) - { - File.Delete(modFolderLocation); - } - } - - private async Task DownloadPackage(Package package) - { - string packageUrl = $"{DeployManager.BaseUrl}/{VersionGuid}-{package.Name}"; - string packageLocation = Path.Combine(Directories.Downloads, package.Signature); - string robloxPackageLocation = Path.Combine(Directories.LocalAppData, "Roblox", "Downloads", package.Signature); - - if (File.Exists(packageLocation)) - { - FileInfo file = new(packageLocation); - - string calculatedMD5 = Utilities.MD5File(packageLocation); - if (calculatedMD5 != package.Signature) - { - Debug.WriteLine($"{package.Name} is corrupted ({calculatedMD5} != {package.Signature})! Deleting and re-downloading..."); - file.Delete(); - } - else - { - Debug.WriteLine($"{package.Name} is already downloaded, skipping..."); - TotalDownloadedBytes += package.PackedSize; - UpdateProgressbar(); - return; - } - } - else if (File.Exists(robloxPackageLocation)) - { - // let's cheat! if the stock bootstrapper already previously downloaded the file, - // then we can just copy the one from there - - Debug.WriteLine($"Found existing version of {package.Name} ({robloxPackageLocation})! Copying to Downloads folder..."); - File.Copy(robloxPackageLocation, packageLocation); - TotalDownloadedBytes += package.PackedSize; - UpdateProgressbar(); - return; - } - - if (!File.Exists(packageLocation)) - { - Debug.WriteLine($"Downloading {package.Name}..."); - - if (CancelFired) - return; - - var response = await Program.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead); - - var buffer = new byte[8192]; - - using (var stream = await response.Content.ReadAsStreamAsync()) - using (var fileStream = new FileStream(packageLocation, FileMode.CreateNew)) - { - while (true) - { - var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length); - if (bytesRead == 0) - break; // we're done - - await fileStream.WriteAsync(buffer, 0, bytesRead); - - TotalDownloadedBytes += bytesRead; - UpdateProgressbar(); - } - } - - Debug.WriteLine($"Finished downloading {package.Name}!"); - } - } - - private async void ExtractPackage(Package package) - { - if (CancelFired) - return; - - string packageLocation = Path.Combine(Directories.Downloads, package.Signature); - string packageFolder = Path.Combine(VersionFolder, PackageDirectories[package.Name]); - string extractPath; - string? directory; - - Debug.WriteLine($"Extracting {package.Name} to {packageFolder}..."); - - using (ZipArchive archive = await Task.Run(() => ZipFile.OpenRead(packageLocation))) - { - foreach (ZipArchiveEntry entry in archive.Entries) - { - if (CancelFired) - return; - - if (entry.FullName.EndsWith('\\')) - continue; - - extractPath = Path.Combine(packageFolder, entry.FullName); - - //Debug.WriteLine($"[{package.Name}] Writing {extractPath}..."); - - directory = Path.GetDirectoryName(extractPath); - - if (directory is null) - continue; - - Directory.CreateDirectory(directory); - - await Task.Run(() => entry.ExtractToFile(extractPath, true)); - } - } - - Debug.WriteLine($"Finished extracting {package.Name}"); - - PackagesExtracted += 1; - } - - private void ExtractFileFromPackage(string packageName, string fileName) - { - Package? package = VersionPackageManifest.Find(x => x.Name == packageName); - - if (package is null) - return; - - DownloadPackage(package).GetAwaiter().GetResult(); - - string packageLocation = Path.Combine(Directories.Downloads, package.Signature); - string packageFolder = Path.Combine(VersionFolder, PackageDirectories[package.Name]); - - using (ZipArchive archive = ZipFile.OpenRead(packageLocation)) - { - ZipArchiveEntry? entry = archive.Entries.Where(x => x.FullName == fileName).FirstOrDefault(); - - if (entry is null) - return; - - string fileLocation = Path.Combine(packageFolder, entry.FullName); - - File.Delete(fileLocation); - - entry.ExtractToFile(fileLocation); - } - } -#endregion - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/BootstrapperDialogForm.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/BootstrapperDialogForm.cs deleted file mode 100644 index 963b3b6..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/BootstrapperDialogForm.cs +++ /dev/null @@ -1,159 +0,0 @@ -using Bloxstrap.Enums; -using Bloxstrap.Helpers; - -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - public class BootstrapperDialogForm : Form, IBootstrapperDialog - { - public Bootstrapper? Bootstrapper { get; set; } - - protected virtual string _message { get; set; } = "Please wait..."; - protected virtual ProgressBarStyle _progressStyle { get; set; } - protected virtual int _progressValue { get; set; } - protected virtual bool _cancelEnabled { get; set; } - - public string Message - { - get => _message; - set - { - if (this.InvokeRequired) - this.Invoke(() => _message = value); - else - _message = value; - } - } - - public ProgressBarStyle ProgressStyle - { - get => _progressStyle; - set - { - if (this.InvokeRequired) - this.Invoke(() => _progressStyle = value); - else - _progressStyle = value; - } - } - - public int ProgressValue - { - get => _progressValue; - set - { - if (this.InvokeRequired) - this.Invoke(() => _progressValue = value); - else - _progressValue = value; - } - } - - public bool CancelEnabled - { - get => _cancelEnabled; - set - { - if (this.InvokeRequired) - this.Invoke(() => _cancelEnabled = value); - else - _cancelEnabled = value; - } - } - - public void ScaleWindow() - { - this.Size = this.MinimumSize = this.MaximumSize = WindowScaling.GetScaledSize(this.Size); - - foreach (Control control in this.Controls) - { - control.Size = WindowScaling.GetScaledSize(control.Size); - control.Location = WindowScaling.GetScaledPoint(control.Location); - control.Padding = WindowScaling.GetScaledPadding(control.Padding); - } - } - - public void SetupDialog() - { - if (Program.IsQuiet) - this.Hide(); - - this.Text = Program.ProjectName; - this.Icon = Program.Settings.BootstrapperIcon.GetIcon(); - - if (Bootstrapper is null) - { - Message = "Style Preview - Click Cancel to return"; - CancelEnabled = true; - } - else - { - Bootstrapper.Dialog = this; - Task.Run(() => RunBootstrapper()); - } - } - - - public async void RunBootstrapper() - { - if (Bootstrapper is null) - return; - -#if DEBUG - await Bootstrapper.Run(); -#else - try - { - await Bootstrapper.Run(); - } - catch (Exception ex) - { - // string message = String.Format("{0}: {1}", ex.GetType(), ex.Message); - string message = ex.ToString(); - ShowError(message); - } -#endif - - Program.Exit(); - } - - public virtual void ShowSuccess(string message) - { - Program.ShowMessageBox(message, MessageBoxIcon.Information); - Program.Exit(); - } - - public virtual void ShowError(string message) - { - Program.ShowMessageBox($"An error occurred while starting Roblox\n\nDetails: {message}", MessageBoxIcon.Error); - Program.Exit(Bootstrapper.ERROR_INSTALL_FAILURE); - } - - public virtual void CloseDialog() - { - if (this.InvokeRequired) - this.Invoke(CloseDialog); - else - this.Hide(); - } - - public void PromptShutdown() - { - DialogResult result = Program.ShowMessageBox( - "Roblox is currently running, but needs to close. Would you like close Roblox now?", - MessageBoxIcon.Information, - MessageBoxButtons.OKCancel - ); - - if (result != DialogResult.OK) - Environment.Exit(Bootstrapper.ERROR_INSTALL_USEREXIT); - } - - public void ButtonCancel_Click(object? sender, EventArgs e) - { - if (Bootstrapper is null) - this.Close(); - else - Task.Run(() => Bootstrapper.CancelButtonClicked()); - } - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/IBootstrapperDialog.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/IBootstrapperDialog.cs deleted file mode 100644 index 394056d..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/IBootstrapperDialog.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - public interface IBootstrapperDialog - { - Bootstrapper? Bootstrapper { get; set; } - - string Message { get; set; } - ProgressBarStyle ProgressStyle { get; set; } - int ProgressValue { get; set; } - bool CancelEnabled { get; set; } - - void RunBootstrapper(); - void ShowSuccess(string message); - void ShowError(string message); - void CloseDialog(); - void PromptShutdown(); - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.Designer.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.Designer.cs deleted file mode 100644 index 0f161e2..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.Designer.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - partial class LegacyDialog2009 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.labelMessage = new System.Windows.Forms.Label(); - this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.buttonCancel = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // labelMessage - // - this.labelMessage.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.labelMessage.Location = new System.Drawing.Point(12, 16); - this.labelMessage.Name = "labelMessage"; - this.labelMessage.Size = new System.Drawing.Size(287, 17); - this.labelMessage.TabIndex = 0; - this.labelMessage.Text = "Please wait..."; - // - // ProgressBar - // - this.ProgressBar.Location = new System.Drawing.Point(15, 47); - this.ProgressBar.MarqueeAnimationSpeed = 33; - this.ProgressBar.Name = "ProgressBar"; - this.ProgressBar.Size = new System.Drawing.Size(281, 20); - this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.ProgressBar.TabIndex = 1; - // - // buttonCancel - // - this.buttonCancel.Enabled = false; - this.buttonCancel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.buttonCancel.Location = new System.Drawing.Point(221, 83); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(75, 23); - this.buttonCancel.TabIndex = 3; - this.buttonCancel.Text = "Cancel"; - this.buttonCancel.UseVisualStyleBackColor = true; - this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); - // - // LegacyDialog2009 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(311, 122); - this.Controls.Add(this.buttonCancel); - this.Controls.Add(this.ProgressBar); - this.Controls.Add(this.labelMessage); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(327, 161); - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(327, 161); - this.Name = "LegacyDialog2009"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "LegacyDialog2009"; - this.Load += new System.EventHandler(this.LegacyDialog2009_Load); - this.ResumeLayout(false); - - } - - #endregion - - private Label labelMessage; - private ProgressBar ProgressBar; - private Button buttonCancel; - } -} \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.cs deleted file mode 100644 index 24224d8..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - // windows: https://youtu.be/VpduiruysuM?t=18 - // mac: https://youtu.be/ncHhbcVDRgQ?t=63 - - public partial class LegacyDialog2009 : BootstrapperDialogForm - { - protected override string _message - { - get => labelMessage.Text; - set => labelMessage.Text = value; - } - - protected override ProgressBarStyle _progressStyle - { - get => ProgressBar.Style; - set => ProgressBar.Style = value; - } - - protected override int _progressValue - { - get => ProgressBar.Value; - set => ProgressBar.Value = value; - } - - protected override bool _cancelEnabled - { - get => this.buttonCancel.Enabled; - set => this.buttonCancel.Enabled = value; - } - - public LegacyDialog2009(Bootstrapper? bootstrapper = null) - { - InitializeComponent(); - - Bootstrapper = bootstrapper; - - ScaleWindow(); - SetupDialog(); - } - - private void LegacyDialog2009_Load(object sender, EventArgs e) - { - this.Activate(); - } - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.resx b/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.resx deleted file mode 100644 index f298a7b..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2009.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.Designer.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.Designer.cs deleted file mode 100644 index 10c1a31..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.Designer.cs +++ /dev/null @@ -1,109 +0,0 @@ -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - partial class LegacyDialog2011 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.labelMessage = new System.Windows.Forms.Label(); - this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.IconBox = new System.Windows.Forms.PictureBox(); - this.buttonCancel = new System.Windows.Forms.Button(); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit(); - this.SuspendLayout(); - // - // labelMessage - // - this.labelMessage.Location = new System.Drawing.Point(55, 23); - this.labelMessage.Name = "labelMessage"; - this.labelMessage.Size = new System.Drawing.Size(287, 17); - this.labelMessage.TabIndex = 0; - this.labelMessage.Text = "Please wait..."; - // - // ProgressBar - // - this.ProgressBar.Location = new System.Drawing.Point(58, 51); - this.ProgressBar.MarqueeAnimationSpeed = 33; - this.ProgressBar.Name = "ProgressBar"; - this.ProgressBar.Size = new System.Drawing.Size(287, 26); - this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.ProgressBar.TabIndex = 1; - // - // IconBox - // - this.IconBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.IconBox.ImageLocation = ""; - this.IconBox.Location = new System.Drawing.Point(19, 16); - this.IconBox.Name = "IconBox"; - this.IconBox.Size = new System.Drawing.Size(32, 32); - this.IconBox.TabIndex = 2; - this.IconBox.TabStop = false; - // - // buttonCancel - // - this.buttonCancel.Enabled = false; - this.buttonCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.buttonCancel.Location = new System.Drawing.Point(271, 83); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(75, 23); - this.buttonCancel.TabIndex = 3; - this.buttonCancel.Text = "Cancel"; - this.buttonCancel.UseVisualStyleBackColor = true; - this.buttonCancel.Visible = false; - this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); - // - // LegacyDialog2011 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(362, 131); - this.Controls.Add(this.buttonCancel); - this.Controls.Add(this.IconBox); - this.Controls.Add(this.ProgressBar); - this.Controls.Add(this.labelMessage); - this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(378, 170); - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(378, 170); - this.Name = "LegacyDialog2011"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "LegacyDialog2011"; - this.Load += new System.EventHandler(this.LegacyDialog2011_Load); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private Label labelMessage; - private ProgressBar ProgressBar; - private PictureBox IconBox; - private Button buttonCancel; - } -} \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.cs deleted file mode 100644 index 8b5e8d5..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Bloxstrap.Enums; - -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - // https://youtu.be/3K9oCEMHj2s?t=35 - - public partial class LegacyDialog2011 : BootstrapperDialogForm - { - protected override string _message - { - get => labelMessage.Text; - set => labelMessage.Text = value; - } - - protected override ProgressBarStyle _progressStyle - { - get => ProgressBar.Style; - set => ProgressBar.Style = value; - } - - protected override int _progressValue - { - get => ProgressBar.Value; - set => ProgressBar.Value = value; - } - - protected override bool _cancelEnabled - { - get => this.buttonCancel.Enabled; - set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value; - } - - public LegacyDialog2011(Bootstrapper? bootstrapper = null) - { - InitializeComponent(); - - Bootstrapper = bootstrapper; - - // have to convert icon -> bitmap since winforms scaling is poop - this.IconBox.BackgroundImage = Program.Settings.BootstrapperIcon.GetIcon().ToBitmap(); - - ScaleWindow(); - SetupDialog(); - } - - private void LegacyDialog2011_Load(object sender, EventArgs e) - { - this.Activate(); - } - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.resx b/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.resx deleted file mode 100644 index f298a7b..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/LegacyDialog2011.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.Designer.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.Designer.cs deleted file mode 100644 index 548d731..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.Designer.cs +++ /dev/null @@ -1,128 +0,0 @@ -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - partial class ProgressDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.labelMessage = new System.Windows.Forms.Label(); - this.IconBox = new System.Windows.Forms.PictureBox(); - this.buttonCancel = new System.Windows.Forms.PictureBox(); - this.panel1 = new System.Windows.Forms.Panel(); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).BeginInit(); - this.panel1.SuspendLayout(); - this.SuspendLayout(); - // - // ProgressBar - // - this.ProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProgressBar.Location = new System.Drawing.Point(29, 241); - this.ProgressBar.MarqueeAnimationSpeed = 20; - this.ProgressBar.Name = "ProgressBar"; - this.ProgressBar.Size = new System.Drawing.Size(460, 20); - this.ProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.ProgressBar.TabIndex = 0; - // - // labelMessage - // - this.labelMessage.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.labelMessage.Location = new System.Drawing.Point(29, 199); - this.labelMessage.Name = "labelMessage"; - this.labelMessage.Size = new System.Drawing.Size(460, 18); - this.labelMessage.TabIndex = 1; - this.labelMessage.Text = "Please wait..."; - this.labelMessage.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.labelMessage.UseMnemonic = false; - // - // IconBox - // - this.IconBox.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.IconBox.ImageLocation = ""; - this.IconBox.Location = new System.Drawing.Point(212, 66); - this.IconBox.Name = "IconBox"; - this.IconBox.Size = new System.Drawing.Size(92, 92); - this.IconBox.TabIndex = 2; - this.IconBox.TabStop = false; - // - // buttonCancel - // - this.buttonCancel.Enabled = false; - this.buttonCancel.Image = global::Bloxstrap.Properties.Resources.CancelButton; - this.buttonCancel.Location = new System.Drawing.Point(194, 264); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(130, 44); - this.buttonCancel.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.buttonCancel.TabIndex = 3; - this.buttonCancel.TabStop = false; - this.buttonCancel.Visible = false; - this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); - this.buttonCancel.MouseEnter += new System.EventHandler(this.ButtonCancel_MouseEnter); - this.buttonCancel.MouseLeave += new System.EventHandler(this.ButtonCancel_MouseLeave); - // - // panel1 - // - this.panel1.BackColor = System.Drawing.SystemColors.Window; - this.panel1.Controls.Add(this.labelMessage); - this.panel1.Controls.Add(this.IconBox); - this.panel1.Controls.Add(this.buttonCancel); - this.panel1.Controls.Add(this.ProgressBar); - this.panel1.Location = new System.Drawing.Point(1, 1); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(518, 318); - this.panel1.TabIndex = 4; - // - // ProgressDialog - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.SystemColors.ActiveBorder; - this.ClientSize = new System.Drawing.Size(520, 320); - this.Controls.Add(this.panel1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.MaximumSize = new System.Drawing.Size(520, 320); - this.MinimumSize = new System.Drawing.Size(520, 320); - this.Name = "ProgressDialog"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "ProgressDialog"; - this.Load += new System.EventHandler(this.ProgressDialog_Load); - ((System.ComponentModel.ISupportInitialize)(this.IconBox)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.buttonCancel)).EndInit(); - this.panel1.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - - private ProgressBar ProgressBar; - private Label labelMessage; - private PictureBox IconBox; - private PictureBox buttonCancel; - private Panel panel1; - } -} \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.cs deleted file mode 100644 index fae383c..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Bloxstrap.Enums; - -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - // basically just the modern dialog - - public partial class ProgressDialog : BootstrapperDialogForm - { - protected override string _message - { - get => labelMessage.Text; - set => labelMessage.Text = value; - } - - protected override ProgressBarStyle _progressStyle - { - get => ProgressBar.Style; - set => ProgressBar.Style = value; - } - - protected override int _progressValue - { - get => ProgressBar.Value; - set => ProgressBar.Value = value; - } - - protected override bool _cancelEnabled - { - get => this.buttonCancel.Enabled; - set => this.buttonCancel.Enabled = this.buttonCancel.Visible = value; - } - - public ProgressDialog(Bootstrapper? bootstrapper = null) - { - InitializeComponent(); - - if (Program.Settings.Theme.GetFinal() == Theme.Dark) - { - this.labelMessage.ForeColor = SystemColors.Window; - this.buttonCancel.Image = Properties.Resources.DarkCancelButton; - this.panel1.BackColor = Color.FromArgb(35, 37, 39); - this.BackColor = Color.FromArgb(25, 27, 29); - } - - Bootstrapper = bootstrapper; - - this.IconBox.BackgroundImage = Program.Settings.BootstrapperIcon.GetBitmap(); - - SetupDialog(); - } - - private void ButtonCancel_MouseEnter(object sender, EventArgs e) - { - if (Program.Settings.Theme.GetFinal() == Theme.Dark) - { - this.buttonCancel.Image = Properties.Resources.DarkCancelButtonHover; - } - else - { - this.buttonCancel.Image = Properties.Resources.CancelButtonHover; - } - } - - private void ButtonCancel_MouseLeave(object sender, EventArgs e) - { - if (Program.Settings.Theme.GetFinal() == Theme.Dark) - { - this.buttonCancel.Image = Properties.Resources.DarkCancelButton; - } - else - { - this.buttonCancel.Image = Properties.Resources.CancelButton; - } - } - - private void ProgressDialog_Load(object sender, EventArgs e) - { - this.Activate(); - } - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.resx b/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.resx deleted file mode 100644 index f298a7b..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/ProgressDialog.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.Designer.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.Designer.cs deleted file mode 100644 index e2d27d5..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.Designer.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - partial class VistaDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.SuspendLayout(); - // - // VistaDialog - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(0, 0); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.Name = "VistaDialog"; - this.Opacity = 0D; - this.ShowInTaskbar = false; - this.Text = "VistaDialog"; - this.WindowState = System.Windows.Forms.FormWindowState.Minimized; - this.Load += new System.EventHandler(this.VistaDialog_Load); - this.ResumeLayout(false); - - } - - #endregion - } -} \ No newline at end of file diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.cs b/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.cs deleted file mode 100644 index e1e8e0a..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.cs +++ /dev/null @@ -1,165 +0,0 @@ -using Bloxstrap.Enums; - -namespace Bloxstrap.Dialogs.BootstrapperDialogs -{ - // https://youtu.be/h0_AL95Sc3o?t=48 - - // a bit hacky, but this is actually a hidden form - // since taskdialog is part of winforms, it can't really be properly used without a form - // for example, cross-threaded calls to ui controls can't really be done outside of a form - - public partial class VistaDialog : BootstrapperDialogForm - { - private TaskDialogPage Dialog; - - protected override string _message - { - get => Dialog.Heading ?? ""; - set => Dialog.Heading = value; - } - - protected override ProgressBarStyle _progressStyle - { - set - { - if (Dialog.ProgressBar is null) - return; - - switch (value) - { - case ProgressBarStyle.Continuous: - case ProgressBarStyle.Blocks: - Dialog.ProgressBar.State = TaskDialogProgressBarState.Normal; - break; - - case ProgressBarStyle.Marquee: - Dialog.ProgressBar.State = TaskDialogProgressBarState.Marquee; - break; - } - } - } - - protected override int _progressValue - { - get => Dialog.ProgressBar is null ? 0 : Dialog.ProgressBar.Value; - set - { - if (Dialog.ProgressBar is null) - return; - - Dialog.ProgressBar.Value = value; - } - } - - protected override bool _cancelEnabled - { - get => Dialog.Buttons[0].Enabled; - set => Dialog.Buttons[0].Enabled = value; - } - - public VistaDialog(Bootstrapper? bootstrapper = null) - { - InitializeComponent(); - - Bootstrapper = bootstrapper; - - Dialog = new TaskDialogPage() - { - Icon = new TaskDialogIcon(Program.Settings.BootstrapperIcon.GetIcon()), - Caption = Program.ProjectName, - - Buttons = { TaskDialogButton.Cancel }, - ProgressBar = new TaskDialogProgressBar() - { - State = TaskDialogProgressBarState.Marquee - } - }; - - _message = "Please wait..."; - _cancelEnabled = false; - - Dialog.Buttons[0].Click += (sender, e) => ButtonCancel_Click(sender, e); - - SetupDialog(); - } - - public override void ShowSuccess(string message) - { - if (this.InvokeRequired) - { - this.Invoke(ShowSuccess, message); - } - else - { - TaskDialogPage successDialog = new() - { - Icon = TaskDialogIcon.ShieldSuccessGreenBar, - Caption = Program.ProjectName, - Heading = message, - Buttons = { TaskDialogButton.OK } - }; - - successDialog.Buttons[0].Click += (sender, e) => Program.Exit(); - - if (!Program.IsQuiet) - Dialog.Navigate(successDialog); - - Dialog = successDialog; - } - } - - public override void ShowError(string message) - { - if (this.InvokeRequired) - { - this.Invoke(ShowError, message); - } - else - { - TaskDialogPage errorDialog = new() - { - Icon = TaskDialogIcon.Error, - Caption = Program.ProjectName, - Heading = "An error occurred while starting Roblox", - Buttons = { TaskDialogButton.Close }, - Expander = new TaskDialogExpander() - { - Text = message, - CollapsedButtonText = "See details", - ExpandedButtonText = "Hide details", - Position = TaskDialogExpanderPosition.AfterText - } - }; - - errorDialog.Buttons[0].Click += (sender, e) => Program.Exit(Bootstrapper.ERROR_INSTALL_FAILURE); - - if (!Program.IsQuiet) - Dialog.Navigate(errorDialog); - - Dialog = errorDialog; - } - } - - public override void CloseDialog() - { - if (this.InvokeRequired) - { - this.Invoke(CloseDialog); - } - else - { - if (Dialog.BoundDialog is null) - return; - - Dialog.BoundDialog.Close(); - } - } - - - private void VistaDialog_Load(object sender, EventArgs e) - { - if (!Program.IsQuiet) - TaskDialog.ShowDialog(Dialog); - } - } -} diff --git a/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.resx b/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.resx deleted file mode 100644 index f298a7b..0000000 --- a/Bloxstrap/Dialogs/BootstrapperDialogs/VistaDialog.resx +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Bloxstrap/Dialogs/Menu/ModHelp.xaml b/Bloxstrap/Dialogs/Menu/ModHelp.xaml deleted file mode 100644 index 4775db9..0000000 --- a/Bloxstrap/Dialogs/Menu/ModHelp.xaml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -