diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 44237db..2efb1cb 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -5,6 +5,7 @@ using System.IO; using System.IO.Compression; using System.Linq; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows; @@ -232,59 +233,64 @@ namespace Bloxstrap LaunchCommandLine += " -startEvent " + startEventName; + bool shouldWait = false; + Process gameClient = Process.Start(Path.Combine(VersionFolder, "RobloxPlayerBeta.exe"), LaunchCommandLine); + Process? rbxFpsUnlocker = null; + DiscordRichPresence? richPresence = null; + Mutex? singletonMutex = null; + 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 (App.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 (App.Settings.RFUAutoclose) - shouldWait = true; - } - - // event fired, wait for 3 seconds then close - await Task.Delay(3000); - - // now we move onto handling rich presence - if (App.Settings.UseDiscordRichPresence) - { - richPresence = new DiscordRichPresence(); - richPresence.MonitorGameActivity(); - - shouldWait = true; - } - - if (!shouldWait) - return; - - // keep bloxstrap open in the background - Dialog.CloseDialog(); - await gameClient.WaitForExitAsync(); - - richPresence?.Dispose(); - - if (App.Settings.RFUAutoclose && rbxFpsUnlocker is not null) - rbxFpsUnlocker.Kill(); } + + if (App.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 (App.Settings.RFUAutoclose) + shouldWait = true; + } + + if (App.Settings.MultiInstanceLaunching) + { + singletonMutex = new Mutex(true, "ROBLOX_singletonMutex"); + shouldWait = true; + } + + // event fired, wait for 3 seconds then close + await Task.Delay(3000); + + if (App.Settings.UseDiscordRichPresence) + { + richPresence = new DiscordRichPresence(); + richPresence.MonitorGameActivity(); + shouldWait = true; + } + + if (!shouldWait) + return; + + // keep bloxstrap open in the background + Dialog.CloseDialog(); + await gameClient.WaitForExitAsync(); + + richPresence?.Dispose(); + singletonMutex?.ReleaseMutex(); + + if (App.Settings.RFUAutoclose && rbxFpsUnlocker is not null) + rbxFpsUnlocker.Kill(); } public void CancelButtonClicked() diff --git a/Bloxstrap/Models/SettingsFormat.cs b/Bloxstrap/Models/SettingsFormat.cs index be00f45..2f8db32 100644 --- a/Bloxstrap/Models/SettingsFormat.cs +++ b/Bloxstrap/Models/SettingsFormat.cs @@ -20,6 +20,7 @@ namespace Bloxstrap.Models public Theme Theme { get; set; } = Theme.Default; public bool CheckForUpdates { get; set; } = true; public bool CreateDesktopIcon { get; set; } = true; + public bool MultiInstanceLaunching { get; set; } = false; // channel configuration public string Channel { get; set; } = DeployManager.DefaultChannel; diff --git a/Bloxstrap/ViewModels/BootstrapperViewModel.cs b/Bloxstrap/ViewModels/BootstrapperViewModel.cs index 5d77c0d..f03bc10 100644 --- a/Bloxstrap/ViewModels/BootstrapperViewModel.cs +++ b/Bloxstrap/ViewModels/BootstrapperViewModel.cs @@ -39,6 +39,12 @@ namespace Bloxstrap.ViewModels set => App.Settings.PromptChannelChange = value; } + public bool MultiInstanceLaunchingEnabled + { + get => App.Settings.MultiInstanceLaunching; + set => App.Settings.MultiInstanceLaunching = value; + } + public IReadOnlyDictionary Themes { get; set; } = new Dictionary() { { "System Default", Enums.Theme.Default }, diff --git a/Bloxstrap/Views/Pages/BootstrapperPage.xaml b/Bloxstrap/Views/Pages/BootstrapperPage.xaml index 177ed9a..b60320a 100644 --- a/Bloxstrap/Views/Pages/BootstrapperPage.xaml +++ b/Bloxstrap/Views/Pages/BootstrapperPage.xaml @@ -23,6 +23,15 @@ + + + + + + + + +