Followup on custom integration support

stopped being lazy and actually added editing inside the menu window
This commit is contained in:
pizzaboxer 2023-02-15 15:33:06 +00:00
parent 475a9ef3bf
commit 1d48657152
9 changed files with 115 additions and 64 deletions

View File

@ -230,9 +230,9 @@ namespace Bloxstrap
process.Close(); process.Close();
} }
} }
catch (Exception e) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Failed to close process! {e}"); App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] Failed to close process! {ex}");
} }
App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] All Roblox processes closed"); App.Logger.WriteLine($"[Bootstrapper::CheckIfRunning] All Roblox processes closed");
@ -316,12 +316,20 @@ namespace Bloxstrap
foreach (CustomIntegration integration in App.Settings.Prop.CustomIntegrations) 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})"); 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) try
{ {
shouldWait = true; Process process = Process.Start(integration.Location, integration.LaunchArgs);
autocloseProcesses.Add(process);
if (integration.AutoClose)
{
shouldWait = true;
autocloseProcesses.Add(process);
}
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Failed to launch integration '{integration.Name}'! ({ex.Message})");
} }
} }
@ -372,10 +380,10 @@ namespace Bloxstrap
else if (Directory.Exists(_versionFolder)) else if (Directory.Exists(_versionFolder))
Directory.Delete(_versionFolder, true); Directory.Delete(_versionFolder, true);
} }
catch (Exception e) catch (Exception ex)
{ {
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Could not fully clean up installation!"); App.Logger.WriteLine("[Bootstrapper::CancelInstall] Could not fully clean up installation!");
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {e}"); App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}");
} }
App.Terminate(ERROR_INSTALL_USEREXIT); App.Terminate(ERROR_INSTALL_USEREXIT);
@ -532,9 +540,9 @@ namespace Bloxstrap
// (should delete everything except bloxstrap itself) // (should delete everything except bloxstrap itself)
Directory.Delete(Directories.Base, true); Directory.Delete(Directories.Base, true);
} }
catch (Exception e) catch (Exception ex)
{ {
App.Logger.WriteLine($"Could not fully uninstall! ({e})"); App.Logger.WriteLine($"Could not fully uninstall! ({ex})");
} }
Dialog?.ShowSuccess($"{App.ProjectName} has succesfully uninstalled"); Dialog?.ShowSuccess($"{App.ProjectName} has succesfully uninstalled");

View File

@ -48,9 +48,9 @@ namespace Bloxstrap.Helpers.Integrations
process.Close(); process.Close();
} }
} }
catch (Exception e) catch (Exception ex)
{ {
App.Logger.WriteLine($"[RbxFpsUnlocker::CheckIfRunning] Could not close rbxfpsunlocker process! {e}"); App.Logger.WriteLine($"[RbxFpsUnlocker::CheckIfRunning] Could not close rbxfpsunlocker process! {ex}");
} }
} }

View File

@ -107,9 +107,9 @@ namespace Bloxstrap.Helpers
{ {
Registry.CurrentUser.DeleteSubKeyTree($@"Software\Classes\{key}"); Registry.CurrentUser.DeleteSubKeyTree($@"Software\Classes\{key}");
} }
catch (Exception e) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Protocol::Unregister] Failed to unregister {key}: {e}"); App.Logger.WriteLine($"[Protocol::Unregister] Failed to unregister {key}: {ex}");
} }
} }
} }

View File

@ -9,14 +9,9 @@ namespace Bloxstrap.Models
{ {
public class CustomIntegration public class CustomIntegration
{ {
public string Name { get; set; } = null!; public string Name { get; set; } = "";
public string Location { get; set; } = null!; public string Location { get; set; } = "";
public string LaunchArgs { get; set; } = null!; public string LaunchArgs { get; set; } = "";
public bool AutoClose { get; set; } = false; public bool AutoClose { get; set; } = true;
public override string ToString()
{
return Name;
}
} }
} }

View File

@ -1,4 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Bloxstrap.Enums; using Bloxstrap.Enums;
using Bloxstrap.Helpers; using Bloxstrap.Helpers;
@ -25,7 +27,8 @@ namespace Bloxstrap.Models
public bool RFUAutoclose { get; set; } = false; public bool RFUAutoclose { get; set; } = false;
public bool UseReShade { get; set; } = false; public bool UseReShade { get; set; } = false;
public bool UseReShadeExtraviPresets { get; set; } = false; public bool UseReShadeExtraviPresets { get; set; } = false;
public List<CustomIntegration> CustomIntegrations { get; set; } = new(); // ideally should be List<CustomIntegration> but wpf moment so blehhhhh :P
public ObservableCollection<CustomIntegration> CustomIntegrations { get; set; } = new();
// mod preset configuration // mod preset configuration
public bool UseOldDeathSound { get; set; } = true; public bool UseOldDeathSound { get; set; } = true;

View File

@ -1,16 +1,13 @@
using System.Collections.Generic; using System.ComponentModel;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Wpf.Ui.Mvvm.Contracts;
using Bloxstrap.Helpers; using Bloxstrap.Helpers;
using Bloxstrap.Models; using Bloxstrap.Models;
using Bloxstrap.Views.Pages; using Bloxstrap.Views.Pages;
using System.Collections.ObjectModel;
namespace Bloxstrap.ViewModels namespace Bloxstrap.ViewModels
{ {
@ -19,28 +16,46 @@ namespace Bloxstrap.ViewModels
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private readonly Page _page;
public ICommand OpenReShadeFolderCommand => new RelayCommand(OpenReShadeFolder); public ICommand OpenReShadeFolderCommand => new RelayCommand(OpenReShadeFolder);
public ICommand AddIntegrationCommand => new RelayCommand(AddIntegration);
public ICommand DeleteIntegrationCommand => new RelayCommand(DeleteIntegration);
public bool CanOpenReShadeFolder => App.Settings.Prop.UseReShade; public bool CanOpenReShadeFolder => App.Settings.Prop.UseReShade;
public IntegrationsViewModel(Page page)
{
_page = page;
if (CustomIntegrations.Count > 0)
{
CustomIntegrationsVisibility = Visibility.Visible;
OnPropertyChanged(nameof(CustomIntegrationsVisibility));
}
}
private void OpenReShadeFolder() private void OpenReShadeFolder()
{ {
Process.Start("explorer.exe", Path.Combine(Directories.Integrations, "ReShade")); Process.Start("explorer.exe", Path.Combine(Directories.Integrations, "ReShade"));
} }
private void AddIntegration()
{
CustomIntegrations.Add(new CustomIntegration()
{
Name = "New Integration"
});
SelectedCustomIntegrationIndex = CustomIntegrations.Count - 1;
OnPropertyChanged(nameof(SelectedCustomIntegrationIndex));
OnPropertyChanged(nameof(IsCustomIntegrationSelected));
}
private void DeleteIntegration()
{
if (SelectedCustomIntegration is null)
return;
CustomIntegrations.Remove(SelectedCustomIntegration);
if (CustomIntegrations.Count > 0)
{
SelectedCustomIntegrationIndex = CustomIntegrations.Count - 1;
OnPropertyChanged(nameof(SelectedCustomIntegrationIndex));
}
OnPropertyChanged(nameof(IsCustomIntegrationSelected));
}
public bool DiscordActivityEnabled public bool DiscordActivityEnabled
{ {
get => App.Settings.Prop.UseDiscordRichPresence; get => App.Settings.Prop.UseDiscordRichPresence;
@ -96,14 +111,14 @@ namespace Bloxstrap.ViewModels
set => App.Settings.Prop.RFUAutoclose = value; set => App.Settings.Prop.RFUAutoclose = value;
} }
public Visibility CustomIntegrationsVisibility { get; set; } = Visibility.Collapsed; public ObservableCollection<CustomIntegration> CustomIntegrations
public List<CustomIntegration> CustomIntegrations
{ {
get => App.Settings.Prop.CustomIntegrations; get => App.Settings.Prop.CustomIntegrations;
set => App.Settings.Prop.CustomIntegrations = value; set => App.Settings.Prop.CustomIntegrations = value;
} }
public CustomIntegration SelectedCustomIntegration { get; set; } = new(); public CustomIntegration? SelectedCustomIntegration { get; set; }
public int SelectedCustomIntegrationIndex { get; set; }
public bool IsCustomIntegrationSelected => SelectedCustomIntegration is not null;
} }
} }

View File

@ -18,7 +18,7 @@
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock FontSize="13" FontWeight="Medium" Text="Create desktop icon" /> <TextBlock FontSize="13" FontWeight="Medium" Text="Create desktop icon" />
<TextBlock FontSize="12" Text="Bloxstrap will place an icon on the desktop that launches Roblox." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock FontSize="12" Text="Bloxstrap will place an icon on the desktop that launches Roblox the next time it launches." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding CreateDesktopIcon, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding CreateDesktopIcon, Mode=TwoWay}" />
@ -45,7 +45,7 @@
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock FontSize="13" FontWeight="Medium" Text="Prompt on Roblox-forced channel change" /> <TextBlock FontSize="13" FontWeight="Medium" Text="Prompt on Roblox-forced channel change" />
<TextBlock FontSize="12" Text="Confirm if Roblox mandates a channel change on launch. Otherwise, it'll change automatically." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock FontSize="12" Text="Confirm change if Roblox mandates it when launching. Otherwise, it'll change automatically." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ChannelChangePromptingEnabled, Mode=TwoWay}" /> <ui:ToggleSwitch IsChecked="{Binding ChannelChangePromptingEnabled, Mode=TwoWay}" />

View File

@ -7,7 +7,7 @@
xmlns:models="clr-namespace:Bloxstrap.ViewModels" xmlns:models="clr-namespace:Bloxstrap.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="680" d:DesignWidth="800" d:DesignHeight="1080" d:DesignWidth="800"
Title="IntegrationsPage" Title="IntegrationsPage"
Scrollable="True"> Scrollable="True">
<StackPanel Margin="0,0,14,14"> <StackPanel Margin="0,0,14,14">
@ -107,7 +107,7 @@
<ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=RbxFpsUnlockerEnabledToggle, Mode=OneWay}"> <ui:CardControl Margin="0,8,0,0" IsEnabled="{Binding IsChecked, ElementName=RbxFpsUnlockerEnabledToggle, Mode=OneWay}">
<ui:CardControl.Header> <ui:CardControl.Header>
<StackPanel Grid.Column="0"> <StackPanel Grid.Column="0">
<TextBlock FontSize="13" FontWeight="Medium" Text="Stop when Roblox closes" /> <TextBlock FontSize="13" FontWeight="Medium" Text="Auto close when Roblox closes" />
<TextBlock FontSize="12" Text="rbxfpsunlocker will automatically close when Roblox closes." Foreground="{DynamicResource TextFillColorTertiaryBrush}" /> <TextBlock FontSize="12" Text="rbxfpsunlocker will automatically close when Roblox closes." Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
</StackPanel> </StackPanel>
</ui:CardControl.Header> </ui:CardControl.Header>
@ -116,24 +116,54 @@
</StackPanel> </StackPanel>
<TextBlock Text="Custom Integrations" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" /> <TextBlock Text="Custom Integrations" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
<TextBlock Margin="0,4,0,0" TextWrapping="Wrap"> <TextBlock Margin="0,4,0,0" Text="Here, you can have other programs launch with Roblox automatically like how rbxfpsunlocker does." TextWrapping="Wrap" />
Using custom integrations, you can have other programs launch with Roblox automatically like how rbxfpsunlocker does.<LineBreak /> <Grid Margin="0,8,0,0">
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. <Grid.RowDefinitions>
</TextBlock> <RowDefinition Height="*" />
<Grid Margin="0,8,0,0" Visibility="{Binding CustomIntegrationsVisibility}"> <RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="250" /> <ColumnDefinition Width="250" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding CustomIntegrations}" SelectionChanged="CustomIntegrationSelection" SelectedIndex="0"/> <ListBox x:Name="CustomIntegrationsListBox" Grid.Row="0" Grid.Column="0" Margin="0,0,4,0" ItemsSource="{Binding CustomIntegrations, Mode=OneWay}" DisplayMemberPath="Name" SelectionChanged="CustomIntegrationSelection" SelectedIndex="{Binding SelectedCustomIntegrationIndex, Mode=TwoWay}" />
<StackPanel Grid.Column="1" Margin="8,0,0,0"> <Grid Grid.Row="1" Grid.Column="0" Margin="0,8,4,0">
<TextBlock FontSize="13" FontWeight="Medium" Text="Application Location" /> <Grid.ColumnDefinitions>
<TextBlock Text="{Binding SelectedCustomIntegration.Location}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <ColumnDefinition Width="*" />
<TextBlock Margin="0,8,0,0" FontSize="13" FontWeight="Medium" Text="Launch Arguments" /> <ColumnDefinition Width="*" />
<TextBlock Text="{Binding SelectedCustomIntegration.LaunchArgs}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> </Grid.ColumnDefinitions>
<TextBlock Margin="0,8,0,0" FontSize="13" FontWeight="Medium" Text="Auto close when Roblox closes" /> <ui:Button Grid.Column="0" Margin="0,0,4,0" Icon="Add28" Content="New" HorizontalAlignment="Stretch" Command="{Binding AddIntegrationCommand, Mode=OneTime}" />
<TextBlock Text="{Binding SelectedCustomIntegration.AutoClose}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" /> <ui:Button Grid.Column="1" Margin="4,0,0,0" Icon="Delete28" Content="Delete" HorizontalAlignment="Stretch" Appearance="Danger" IsEnabled="{Binding IsCustomIntegrationSelected, Mode=OneWay}" Command="{Binding DeleteIntegrationCommand, Mode=OneTime}" />
</Grid>
<StackPanel Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Margin="4,0,0,0">
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsCustomIntegrationSelected}" Value="False">
<Setter Property="StackPanel.Visibility" Value="Hidden"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<TextBlock Text="Name" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" Text="{Binding SelectedCustomIntegration.Name}" />
<TextBlock Margin="0,8,0,0" Text="Application Location" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" PlaceholderText="e.g. C:\Windows\System32\cmd.exe" Text="{Binding SelectedCustomIntegration.Location}" />
<TextBlock Margin="0,8,0,0" Text="Launch Args" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<ui:TextBox Margin="0,4,0,0" PlaceholderText="e.g. /k echo Roblox is running!" Text="{Binding SelectedCustomIntegration.LaunchArgs}" />
<CheckBox Margin="0,8,0,0" Content="Auto close when Roblox closes" IsChecked="{Binding SelectedCustomIntegration.AutoClose}" />
</StackPanel> </StackPanel>
<TextBlock Grid.Row="0" Grid.RowSpan="2" Grid.Column="1" Text="No integration selected, please select or add a new one" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsCustomIntegrationSelected}" Value="True">
<Setter Property="TextBlock.Visibility" Value="Hidden"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid> </Grid>
</StackPanel> </StackPanel>
</ui:UiPage> </ui:UiPage>

View File

@ -13,7 +13,7 @@ namespace Bloxstrap.Views.Pages
{ {
public IntegrationsPage() public IntegrationsPage()
{ {
DataContext = new IntegrationsViewModel(this); DataContext = new IntegrationsViewModel();
InitializeComponent(); InitializeComponent();
// rbxfpsunlocker does not have 64 bit support // rbxfpsunlocker does not have 64 bit support