mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-05-13 03:34:42 -07:00
Add custom integration support (#76)
This commit is contained in:
parent
8a4cc67893
commit
6cb72a8038
@ -201,28 +201,41 @@ namespace Bloxstrap
|
||||
|
||||
private bool CheckIfRunning(bool shutdown)
|
||||
{
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Checking if Roblox is running... (shutdown={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) { }
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Roblox is not running");
|
||||
return false;
|
||||
}
|
||||
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Roblox is running, found {processes.Length} process(es)");
|
||||
|
||||
if (!shutdown)
|
||||
return true;
|
||||
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Attempting to shutdown Roblox...");
|
||||
|
||||
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 e)
|
||||
{
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Failed to close process! {e}");
|
||||
}
|
||||
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] All Roblox processes closed");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -246,12 +259,15 @@ namespace Bloxstrap
|
||||
|
||||
_launchCommandLine += " -startEvent " + startEventName;
|
||||
|
||||
// whether we should wait for roblox to exit to handle stuff in the background or clean up after roblox closes
|
||||
bool shouldWait = false;
|
||||
Process gameClient = Process.Start(Path.Combine(_versionFolder, "RobloxPlayerBeta.exe"), _launchCommandLine);
|
||||
Process? rbxFpsUnlocker = null;
|
||||
List<Process> autocloseProcesses = new();
|
||||
DiscordRichPresence? richPresence = null;
|
||||
Mutex? singletonMutex = null;
|
||||
|
||||
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Started Roblox (PID {gameClient.Id})");
|
||||
|
||||
using (SystemEvent startEvent = new(startEventName))
|
||||
{
|
||||
bool startEventFired = await startEvent.WaitForEvent();
|
||||
@ -262,7 +278,7 @@ namespace Bloxstrap
|
||||
return;
|
||||
}
|
||||
|
||||
if (App.Settings.Prop.RFUEnabled && Process.GetProcessesByName("rbxfpsunlocker").Length == 0)
|
||||
if (App.Settings.Prop.RFUEnabled && Process.GetProcessesByName(RbxFpsUnlocker.ApplicationName).Length == 0)
|
||||
{
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Using rbxfpsunlocker");
|
||||
|
||||
@ -272,10 +288,13 @@ namespace Bloxstrap
|
||||
FileName = Path.Combine(Directories.Integrations, @"rbxfpsunlocker\rbxfpsunlocker.exe")
|
||||
};
|
||||
|
||||
rbxFpsUnlocker = Process.Start(startInfo);
|
||||
Process process = Process.Start(startInfo)!;
|
||||
|
||||
if (App.Settings.Prop.RFUAutoclose)
|
||||
{
|
||||
shouldWait = true;
|
||||
autocloseProcesses.Add(process);
|
||||
}
|
||||
}
|
||||
|
||||
if (App.Settings.Prop.UseDiscordRichPresence)
|
||||
@ -293,6 +312,19 @@ namespace Bloxstrap
|
||||
shouldWait = true;
|
||||
}
|
||||
|
||||
// launch custom integrations now
|
||||
foreach (CustomIntegration integration in App.Settings.Prop.CustomIntegrations)
|
||||
{
|
||||
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Launching custom integration '{integration.Name}' ({integration.Location} {integration.LaunchArgs} - autoclose is {integration.AutoClose})");
|
||||
Process process = Process.Start(integration.Location, integration.LaunchArgs);
|
||||
|
||||
if (integration.AutoClose)
|
||||
{
|
||||
shouldWait = true;
|
||||
autocloseProcesses.Add(process);
|
||||
}
|
||||
}
|
||||
|
||||
// event fired, wait for 3 seconds then close
|
||||
await Task.Delay(3000);
|
||||
Dialog?.CloseBootstrapper();
|
||||
@ -305,11 +337,15 @@ namespace Bloxstrap
|
||||
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Waiting for Roblox to close");
|
||||
await gameClient.WaitForExitAsync();
|
||||
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Roblox exited with code {gameClient.ExitCode}");
|
||||
|
||||
richPresence?.Dispose();
|
||||
|
||||
if (App.Settings.Prop.RFUAutoclose)
|
||||
rbxFpsUnlocker?.Kill();
|
||||
foreach (Process process in autocloseProcesses)
|
||||
{
|
||||
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Autoclosing process '{process.ProcessName}' (PID {process.Id})");
|
||||
process.Kill();
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelInstall()
|
||||
|
@ -39,11 +39,11 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Updated presence");
|
||||
|
||||
RichPresence.OnConnectionEstablished += (_, e) =>
|
||||
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Established connection with Discord RPC!");
|
||||
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Established connection with Discord RPC");
|
||||
|
||||
//spams log as it tries to connect every ~15 sec when discord is closed so not now
|
||||
//RichPresence.OnConnectionFailed += (_, e) =>
|
||||
// App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Failed to establish connection with Discord RPC!");
|
||||
// App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Failed to establish connection with Discord RPC");
|
||||
|
||||
RichPresence.OnClose += (_, e) =>
|
||||
App.Logger.WriteLine($"[DiscordRichPresence::DiscordRichPresence] Lost connection to Discord RPC - {e.Reason} ({e.Code})");
|
||||
@ -219,6 +219,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
App.Logger.WriteLine("[DiscordRichPresence::Dispose] Cleaning up Discord RPC and Presence");
|
||||
RichPresence.ClearPresence();
|
||||
RichPresence.Dispose();
|
||||
}
|
||||
|
@ -32,13 +32,13 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
if (processes.Length == 0)
|
||||
return;
|
||||
|
||||
App.Logger.WriteLine("[RbxFpsUnlocker::CheckIfRunning] Closing currently running rbxfpsunlocker processes...");
|
||||
|
||||
try
|
||||
{
|
||||
// try/catch just in case process was closed before prompt was answered
|
||||
|
||||
foreach (Process process in processes)
|
||||
{
|
||||
if (process.MainModule is null || process.MainModule.FileName is null)
|
||||
if (process.MainModule?.FileName is null)
|
||||
continue;
|
||||
|
||||
if (!process.MainModule.FileName.Contains(App.BaseDirectory))
|
||||
@ -48,7 +48,10 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
process.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception e)
|
||||
{
|
||||
App.Logger.WriteLine($"[RbxFpsUnlocker::CheckIfRunning] Could not close rbxfpsunlocker process! {e}");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task CheckInstall()
|
||||
|
@ -303,7 +303,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
if (!Directory.Exists(PresetsFolder))
|
||||
return;
|
||||
|
||||
App.Logger.WriteLine("[ReShade::UninstallExtraviPresets] Uninstalling Extravi's presets...");
|
||||
App.Logger.WriteLine("[ReShade::UninstallExtraviPresets] Uninstalling Extravi's ReShade presets...");
|
||||
|
||||
FileInfo[] presets = new DirectoryInfo(PresetsFolder).GetFiles();
|
||||
|
||||
@ -319,32 +319,39 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public static async Task CheckModifications()
|
||||
{
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] Checking ReShade modifications... ");
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] Checking ReShade modifications...");
|
||||
|
||||
string injectorLocation = Path.Combine(Directories.Modifications, "dxgi.dll");
|
||||
|
||||
if (!App.Settings.Prop.UseReShadeExtraviPresets)
|
||||
if (!App.Settings.Prop.UseReShadeExtraviPresets && !String.IsNullOrEmpty(App.State.Prop.ExtraviReShadePresetsVersion))
|
||||
{
|
||||
UninstallExtraviPresets();
|
||||
|
||||
App.State.Prop.ExtraviReShadePresetsVersion = "";
|
||||
App.State.Save();
|
||||
}
|
||||
|
||||
if (!App.Settings.Prop.UseReShade)
|
||||
{
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] ReShade is not enabled");
|
||||
|
||||
// we should already be uninstalled
|
||||
// we want to ensure this is done one-time only as this could possibly interfere with other rendering hooks using dxgi.dll
|
||||
if (String.IsNullOrEmpty(App.State.Prop.ReShadeConfigVersion))
|
||||
return;
|
||||
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] Uninstalling ReShade...");
|
||||
|
||||
// delete any stock config files
|
||||
File.Delete(injectorLocation);
|
||||
File.Delete(ConfigLocation);
|
||||
|
||||
App.State.Prop.ReShadeConfigVersion = "";
|
||||
App.State.Save();
|
||||
|
||||
//DeleteShaders("Stock");
|
||||
if (Directory.Exists(BaseDirectory))
|
||||
Directory.Delete(BaseDirectory, true);
|
||||
|
||||
App.State.Prop.ReShadeConfigVersion = "";
|
||||
App.State.Save();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
22
Bloxstrap/Models/CustomIntegration.cs
Normal file
22
Bloxstrap/Models/CustomIntegration.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bloxstrap.Models
|
||||
{
|
||||
public class CustomIntegration
|
||||
{
|
||||
public string Name { get; set; } = null!;
|
||||
public string Location { get; set; } = null!;
|
||||
public string LaunchArgs { get; set; } = null!;
|
||||
public bool AutoClose { get; set; } = false;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using Bloxstrap.Enums;
|
||||
using System.Collections.Generic;
|
||||
using Bloxstrap.Enums;
|
||||
using Bloxstrap.Helpers;
|
||||
|
||||
namespace Bloxstrap.Models
|
||||
@ -24,6 +25,7 @@ namespace Bloxstrap.Models
|
||||
public bool RFUAutoclose { get; set; } = false;
|
||||
public bool UseReShade { get; set; } = false;
|
||||
public bool UseReShadeExtraviPresets { get; set; } = false;
|
||||
public List<CustomIntegration> CustomIntegrations { get; set; } = new();
|
||||
|
||||
// mod preset configuration
|
||||
public bool UseOldDeathSound { get; set; } = true;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
@ -8,6 +9,7 @@ using CommunityToolkit.Mvvm.Input;
|
||||
using Wpf.Ui.Mvvm.Contracts;
|
||||
|
||||
using Bloxstrap.Helpers;
|
||||
using Bloxstrap.Models;
|
||||
using Bloxstrap.Views.Pages;
|
||||
|
||||
namespace Bloxstrap.ViewModels
|
||||
@ -27,6 +29,12 @@ namespace Bloxstrap.ViewModels
|
||||
public IntegrationsViewModel(Page page)
|
||||
{
|
||||
_page = page;
|
||||
|
||||
if (CustomIntegrations.Count > 0)
|
||||
{
|
||||
CustomIntegrationsVisibility = Visibility.Visible;
|
||||
OnPropertyChanged(nameof(CustomIntegrationsVisibility));
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenReShadeFolder()
|
||||
@ -93,5 +101,15 @@ namespace Bloxstrap.ViewModels
|
||||
get => App.Settings.Prop.RFUAutoclose;
|
||||
set => App.Settings.Prop.RFUAutoclose = value;
|
||||
}
|
||||
|
||||
public Visibility CustomIntegrationsVisibility { get; set; } = Visibility.Collapsed;
|
||||
|
||||
public List<CustomIntegration> CustomIntegrations
|
||||
{
|
||||
get => App.Settings.Prop.CustomIntegrations;
|
||||
set => App.Settings.Prop.CustomIntegrations = value;
|
||||
}
|
||||
|
||||
public CustomIntegration SelectedCustomIntegration { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
mc:Ignorable="d"
|
||||
Title="Bloxstrap Menu"
|
||||
MinWidth="880"
|
||||
Width="920"
|
||||
Width="960"
|
||||
Height="580"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
@ -58,9 +58,9 @@
|
||||
|
||||
<ui:NavigationFluent x:Name="RootNavigation" Grid.Row="1" Grid.Column="0" Margin="0,0,12,0" Frame="{Binding ElementName=RootFrame}" SelectedPageIndex="0">
|
||||
<ui:NavigationFluent.Items>
|
||||
<ui:NavigationItem Content="Integrations" PageType="{x:Type pages:IntegrationsPage}" Icon="AddSquareMultiple20" Tag="integrations" />
|
||||
<ui:NavigationItem Content="Mods" PageType="{x:Type pages:ModsPage}" Icon="DocumentToolbox24" Tag="mods" />
|
||||
<ui:NavigationItem Content="Bootstrapper" PageType="{x:Type pages:BootstrapperPage}" Icon="Window48" Tag="bootstrapper" />
|
||||
<ui:NavigationItem Content="Integrations" PageType="{x:Type pages:IntegrationsPage}" Icon="Add28" Tag="integrations" />
|
||||
<ui:NavigationItem Content="Mods" PageType="{x:Type pages:ModsPage}" Icon="WrenchScrewdriver20" Tag="mods" />
|
||||
<ui:NavigationItem Content="Bootstrapper" PageType="{x:Type pages:BootstrapperPage}" Icon="WindowWrench48" Tag="bootstrapper" />
|
||||
<ui:NavigationItem Content="Installation" PageType="{x:Type pages:InstallationPage}" Icon="HardDrive20" Tag="installation" />
|
||||
<!--<ui:NavigationSeparator />-->
|
||||
<ui:NavigationItem Content="ReShade Help" PageType="{x:Type pages:ReShadeHelpPage}" Icon="BookQuestionMark24" Tag="reshadehelp" Visibility="Collapsed" />
|
||||
|
@ -12,7 +12,7 @@
|
||||
<StackPanel Margin="0,0,14,14">
|
||||
<TextBlock Text="Configure how Bloxstrap and Roblox are installed." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
<ui:CardExpander Margin="0,16,0,0">
|
||||
<ui:CardExpander Margin="0,16,0,0" IsExpanded="True">
|
||||
<ui:CardExpander.Header>
|
||||
<StackPanel>
|
||||
<TextBlock FontSize="13" FontWeight="Medium" Text="Install Location" />
|
||||
@ -29,7 +29,7 @@
|
||||
</Grid>
|
||||
</ui:CardExpander>
|
||||
|
||||
<ui:CardExpander Margin="0,8,0,0">
|
||||
<ui:CardExpander Margin="0,8,0,0" IsExpanded="True">
|
||||
<ui:CardExpander.Header>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
|
@ -114,5 +114,26 @@
|
||||
<ui:ToggleSwitch IsChecked="{Binding RbxFpsUnlockerAutocloseEnabled, Mode=TwoWay}" />
|
||||
</ui:CardControl>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="Custom Integrations" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
|
||||
<TextBlock Margin="0,4,0,0" TextWrapping="Wrap">
|
||||
Using custom integrations, you can have other programs launch with Roblox automatically like how rbxfpsunlocker does.<LineBreak />
|
||||
To manage custom integrations, you'll have to manually edit your Settings.json configuration file in your Bloxstrap folder. If you have any configured, you'll be able to preview them here.
|
||||
</TextBlock>
|
||||
<Grid Margin="0,8,0,0" Visibility="{Binding CustomIntegrationsVisibility}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="250" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ListBox ItemsSource="{Binding CustomIntegrations}" SelectionChanged="CustomIntegrationSelection" SelectedIndex="0"/>
|
||||
<StackPanel Grid.Column="1" Margin="8,0,0,0">
|
||||
<TextBlock FontSize="13" FontWeight="Medium" Text="Application Location" />
|
||||
<TextBlock Text="{Binding SelectedCustomIntegration.Location}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Margin="0,8,0,0" FontSize="13" FontWeight="Medium" Text="Launch Arguments" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Text="{Binding SelectedCustomIntegration.LaunchArgs}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Margin="0,8,0,0" FontSize="13" FontWeight="Medium" Text="Auto close when Roblox closes" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Text="{Binding SelectedCustomIntegration.AutoClose}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:UiPage>
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Bloxstrap.Models;
|
||||
using Bloxstrap.ViewModels;
|
||||
|
||||
namespace Bloxstrap.Views.Pages
|
||||
@ -18,5 +20,12 @@ namespace Bloxstrap.Views.Pages
|
||||
if (!Environment.Is64BitOperatingSystem)
|
||||
this.RbxFpsUnlockerOptions.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public void CustomIntegrationSelection(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
IntegrationsViewModel viewModel = (IntegrationsViewModel)DataContext;
|
||||
viewModel.SelectedCustomIntegration = (CustomIntegration)((ListBox)sender).SelectedItem;
|
||||
viewModel.OnPropertyChanged(nameof(viewModel.SelectedCustomIntegration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user