Skip to content

Commit 3089957

Browse files
committed
Multi instance bug fixes and other stuff
1 parent 4e1e8d9 commit 3089957

6 files changed

Lines changed: 225 additions & 225 deletions

File tree

Bloxstrap/Bootstrapper.cs

Lines changed: 41 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,13 @@ public async Task Run()
328328
if (_launchMode != LaunchMode.Player)
329329
await mutex.ReleaseAsync();
330330

331+
if (_launchMode == LaunchMode.Player)
332+
{
333+
// await because some peoples pc are so ass that roblox opens before this finishes causing an error due to the event
334+
if (App.Settings.Prop.MultiInstanceLaunching)
335+
await LaunchMultiInstanceWatcher();
336+
}
337+
331338
if (!App.LaunchSettings.NoLaunchFlag.Active && !_cancelTokenSource.IsCancellationRequested)
332339
{
333340
if (!App.LaunchSettings.QuietFlag.Active)
@@ -716,7 +723,7 @@ private bool IsEligibleForBackgroundUpdate()
716723
}
717724
}
718725

719-
private static void LaunchMultiInstanceWatcher()
726+
private static async Task LaunchMultiInstanceWatcher()
720727
{
721728
const string LOG_IDENT = "Bootstrapper::LaunchMultiInstanceWatcher";
722729

@@ -737,7 +744,7 @@ private static void LaunchMultiInstanceWatcher()
737744
App.Logger.WriteLine(LOG_IDENT, "Mutex ROBLOX_singletonEvent already exists, skipping creation");
738745
}
739746
else
740-
{
747+
{
741748
_multiInstanceMutex2 = new Mutex(true, "ROBLOX_singletonEvent");
742749
App.Logger.WriteLine(LOG_IDENT, "Created multi-instance mutex: ROBLOX_singletonEvent");
743750
}
@@ -780,82 +787,61 @@ private static void LaunchMultiInstanceWatcher()
780787
using EventWaitHandle initEventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "Bloxstrap-MultiInstanceWatcherInitialisationFinished");
781788
Process.Start(Paths.Process, "-multiinstancewatcher");
782789

783-
bool initSuccess = initEventHandle.WaitOne(TimeSpan.FromSeconds(2));
784-
if (initSuccess)
785-
App.Logger.WriteLine(LOG_IDENT, "Initialisation finished signalled, continuing.");
786-
else
787-
App.Logger.WriteLine(LOG_IDENT, "Did not receive the initialisation finished signal, continuing.");
790+
await Task.Run(() => initEventHandle.WaitOne(TimeSpan.FromSeconds(2)));
791+
792+
App.Logger.WriteLine(LOG_IDENT, "Multi-instance watcher initialization completed");
788793
}
789794

790795
// Cleanup starts in watcher not here
791796
public void CleanupMultiInstanceResources()
792797
{
793798
const string LOG_IDENT = "Bootstrapper::CleanupMultiInstanceResources";
794799

795-
bool processesStillRunning = false;
796800
try
797801
{
798-
int robloxProcessCount = Process.GetProcesses().Count(x => x.ProcessName == "RobloxPlayerBeta");
799-
800-
bool bloxstrapMutexExists = false;
801-
try
802-
{
803-
using (var mutex = Mutex.OpenExisting(MutexName))
804-
{
805-
bloxstrapMutexExists = true;
806-
}
807-
}
808-
catch (WaitHandleCannotBeOpenedException)
809-
{
810-
bloxstrapMutexExists = false;
811-
}
812-
catch (Exception mutexEx)
813-
{
814-
App.Logger.WriteLine(LOG_IDENT, $"Error checking for launching mutex: {mutexEx.Message}");
815-
bloxstrapMutexExists = true;
816-
}
802+
int count = Process.GetProcesses().Count(x => x.ProcessName is "RobloxPlayerBeta");
803+
count -= 1;
817804

818-
processesStillRunning = (robloxProcessCount > 0) || bloxstrapMutexExists;
819-
820-
if (processesStillRunning)
821-
{
822-
string reason = bloxstrapMutexExists ? "Launching mutex exists" : $"Roblox processes still running ({robloxProcessCount} instances)";
823-
App.Logger.WriteLine(LOG_IDENT, $"{reason}, skipping mutex disposal");
824-
}
825-
else
805+
if (count > 0)
826806
{
827-
App.Logger.WriteLine(LOG_IDENT, "No Roblox processes running and no launching mutex found, proceeding with mutex disposal");
807+
App.Logger.WriteLine(LOG_IDENT, $"Skipping cleanup - {count} Roblox process(es) still running");
808+
return;
828809
}
829810
}
830811
catch (Exception ex)
831812
{
832-
App.Logger.WriteLine(LOG_IDENT, $"Error checking for running processes: {ex.Message}");
833-
processesStillRunning = true;
813+
App.Logger.WriteException(LOG_IDENT, ex);
814+
return;
834815
}
835816

836-
if (!processesStillRunning)
817+
bool launchingMutex = Utilities.DoesMutexExist(MutexName);
818+
819+
if (launchingMutex)
837820
{
838-
try
839-
{
840-
if (_multiInstanceMutex1 != null)
841-
{
842-
_multiInstanceMutex1.Dispose();
843-
_multiInstanceMutex1 = null;
844-
App.Logger.WriteLine(LOG_IDENT, "Disposed ROBLOX_singletonMutex");
845-
}
821+
App.Logger.WriteLine(LOG_IDENT, "Skipping cleanup, currently launching roblox");
822+
return;
823+
}
846824

847-
if (_multiInstanceMutex2 != null)
848-
{
849-
_multiInstanceMutex2.Dispose();
850-
_multiInstanceMutex2 = null;
851-
App.Logger.WriteLine(LOG_IDENT, "Disposed ROBLOX_singletonEvent");
852-
}
825+
try
826+
{
827+
if (_multiInstanceMutex1 != null)
828+
{
829+
_multiInstanceMutex1.Dispose();
830+
_multiInstanceMutex1 = null;
831+
App.Logger.WriteLine(LOG_IDENT, "Disposed ROBLOX_singletonMutex");
853832
}
854-
catch (Exception ex)
833+
834+
if (_multiInstanceMutex2 != null)
855835
{
856-
App.Logger.WriteLine(LOG_IDENT, $"Error disposing mutexes: {ex.Message}");
836+
_multiInstanceMutex2.Dispose();
837+
_multiInstanceMutex2 = null;
838+
App.Logger.WriteLine(LOG_IDENT, "Disposed ROBLOX_singletonEvent");
857839
}
858840
}
841+
catch (Exception ex)
842+
{
843+
App.Logger.WriteLine(LOG_IDENT, $"Error disposing mutexes: {ex.Message}");
844+
}
859845

860846
if (App.Settings.Prop.Error773Fix)
861847
{
@@ -952,12 +938,6 @@ private async void StartRoblox()
952938

953939
SetStatus(Strings.Bootstrapper_Status_Starting);
954940

955-
if (_launchMode == LaunchMode.Player)
956-
{
957-
if (App.Settings.Prop.MultiInstanceLaunching)
958-
LaunchMultiInstanceWatcher();
959-
}
960-
961941
string[] Names = { App.RobloxPlayerAppName, App.RobloxAnselAppName, App.RobloxStudioAppName };
962942
string ResolvedName = null!;
963943

Bloxstrap/Integrations/ActivityWatcher.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,15 @@ private void ReadLogEntry(string entry)
351351
await Task.Delay(25);
352352
}
353353

354-
if (!isInactivityTimeout)
354+
if (isInactivityTimeout)
355355
{
356-
App.Logger.WriteLine(LOG_IDENT, "No inactivity timeout detected - attempting auto-rejoin");
356+
App.Logger.WriteLine(LOG_IDENT, "Inactivity timeout found, attempting auto-rejoin");
357357
Data.RejoinServer();
358358
OnAutoRejoinTriggered?.Invoke(this, Data);
359359
}
360360
else
361361
{
362-
App.Logger.WriteLine(LOG_IDENT, "Skipping auto-rejoin due to inactivity timeout");
362+
App.Logger.WriteLine(LOG_IDENT, "No inactivity timeout found.");
363363
}
364364
}
365365
catch (Exception ex)

Bloxstrap/UI/Elements/Settings/Pages/FastFlagEditorPage.xaml.cs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ private void DataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
6262
// Let editing TextBox handle Ctrl+C normally
6363
if (DataGrid.CurrentCell.IsValid &&
6464
DataGrid.CurrentCell.Column is DataGridBoundColumn &&
65-
DataGrid.IsKeyboardFocusWithin &&
6665
DataGrid.CurrentColumn.GetCellContent(DataGrid.CurrentItem) is TextBox)
6766
{
6867
return;
@@ -255,7 +254,7 @@ private void ClearSearch(bool refresh = true)
255254
ReloadList();
256255
}
257256

258-
private void ShowAddDialog()
257+
private async void ShowAddDialog()
259258
{
260259
App.FrostRPC?.SetDialog("Add FastFlag");
261260

@@ -268,9 +267,9 @@ private void ShowAddDialog()
268267
return;
269268

270269
if (dialog.Tabs.SelectedIndex == 0)
271-
AddSingle(dialog.FlagNameTextBox.Text.Trim(), dialog.FlagValueComboBox.Text);
270+
await AddSingle(dialog.FlagNameTextBox.Text.Trim(), dialog.FlagValueComboBox.Text);
272271
else if (dialog.Tabs.SelectedIndex == 1)
273-
ImportJSON(dialog.JsonTextBox.Text);
272+
await ImportJSON(dialog.JsonTextBox.Text);
274273
}
275274

276275
private void AdvancedSettings_Click(object sender, RoutedEventArgs e)
@@ -420,7 +419,7 @@ private void ShowProfilesDialog()
420419
ReloadList();
421420
}
422421

423-
private void AddSingle(string name, string value)
422+
private async Task AddSingle(string name, string value)
424423
{
425424
double? val = null;
426425

@@ -471,12 +470,36 @@ private void AddSingle(string name, string value)
471470
entry = _fastFlagList.FirstOrDefault(x => x.Name == name);
472471
}
473472

473+
var remoteManager = new RemoteDataManager();
474+
await remoteManager.LoadData();
475+
var base64Flags = DecodeBase64Flags(remoteManager.Prop.AllowedFastFlags);
476+
477+
if (!base64Flags.Contains(name))
478+
{
479+
if (Frontend.ShowMessageBox($"'{name}' is not in roblox allowlist and won't work.\n\nRemove it now?", MessageBoxImage.Warning, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
480+
{
481+
App.FastFlags.SetValue(name, null);
482+
483+
if (entry != null)
484+
{
485+
_fastFlagList.Remove(entry);
486+
}
487+
else
488+
{
489+
ReloadList();
490+
}
491+
492+
UpdateTotalFlagsCount();
493+
return;
494+
}
495+
}
496+
474497
DataGrid.SelectedItem = entry;
475498
DataGrid.ScrollIntoView(entry);
476499
UpdateTotalFlagsCount();
477500
}
478501

479-
private void ImportJSON(string json)
502+
private async Task ImportJSON(string json)
480503
{
481504
Dictionary<string, object>? list = null;
482505

@@ -576,6 +599,22 @@ private void ImportJSON(string json)
576599

577600
App.FastFlags.suspendUndoSnapshot = false;
578601

602+
var remoteManager = new RemoteDataManager();
603+
await remoteManager.LoadData();
604+
var base64Flags = DecodeBase64Flags(remoteManager.Prop.AllowedFastFlags);
605+
606+
var invalidFlags = list.Keys.Where(flag => !base64Flags.Contains(flag)).ToList();
607+
if (invalidFlags.Any())
608+
{
609+
if (Frontend.ShowMessageBox($"{invalidFlags.Count} imported flags are not in the allowlist and won't work.\n\nRemove them now?", MessageBoxImage.Warning, MessageBoxButton.YesNo) == MessageBoxResult.Yes)
610+
{
611+
foreach (var flagName in invalidFlags)
612+
{
613+
App.FastFlags.SetValue(flagName, null);
614+
}
615+
}
616+
}
617+
579618
ClearSearch();
580619
}
581620

@@ -625,7 +664,7 @@ private void Editor_DragLeave(object sender, DragEventArgs e)
625664
e.Handled = true;
626665
}
627666

628-
private void Editor_Drop(object sender, DragEventArgs e)
667+
private async void Editor_Drop(object sender, DragEventArgs e)
629668
{
630669
DragOverlay.Visibility = Visibility.Collapsed;
631670

@@ -649,7 +688,7 @@ private void Editor_Drop(object sender, DragEventArgs e)
649688
try
650689
{
651690
string content = File.ReadAllText(file);
652-
ImportJSON(content);
691+
await ImportJSON(content);
653692
}
654693
catch (Exception ex)
655694
{

Bloxstrap/UI/Elements/Settings/Pages/IntegrationsPage.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@
140140
</controls:OptionControl>
141141

142142
<controls:OptionControl Description="{x:Static resources:Strings.Menu_Integrations_BlockVideoRecording_Description}" Header="{x:Static resources:Strings.Menu_Integrations_BlockVideoRecording_Title}">
143-
<ui:ToggleSwitch IsChecked="{Binding BlockRobloxRecording, Mode=TwoWay}" />
143+
<ui:ToggleSwitch IsChecked="{Binding DisableRobloxRecording, Mode=TwoWay}" />
144144
</controls:OptionControl>
145145

146146
<controls:OptionControl Description="{x:Static resources:Strings.Menu_Integrations_BlockScreenShots_Description}" Header="{x:Static resources:Strings.Menu_Integrations_BlockScreenShots_Title}">
147-
<ui:ToggleSwitch IsChecked="{Binding BlockRobloxScreenshots, Mode=TwoWay}" />
147+
<ui:ToggleSwitch IsChecked="{Binding DisableRobloxScreenshots, Mode=TwoWay}" />
148148
</controls:OptionControl>
149149

150150
</StackPanel>

0 commit comments

Comments
 (0)