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();
}
}
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");
@ -316,6 +316,9 @@ namespace Bloxstrap
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})");
try
{
Process process = Process.Start(integration.Location, integration.LaunchArgs);
if (integration.AutoClose)
@ -324,6 +327,11 @@ namespace Bloxstrap
autocloseProcesses.Add(process);
}
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Failed to launch integration '{integration.Name}'! ({ex.Message})");
}
}
// event fired, wait for 3 seconds then close
await Task.Delay(3000);
@ -372,10 +380,10 @@ namespace Bloxstrap
else if (Directory.Exists(_versionFolder))
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] {e}");
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}");
}
App.Terminate(ERROR_INSTALL_USEREXIT);
@ -532,9 +540,9 @@ namespace Bloxstrap
// (should delete everything except bloxstrap itself)
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");

View File

@ -48,9 +48,9 @@ namespace Bloxstrap.Helpers.Integrations
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}");
}
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 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;
}
public string Name { get; set; } = "";
public string Location { get; set; } = "";
public string LaunchArgs { get; set; } = "";
public bool AutoClose { get; set; } = true;
}
}

View File

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Bloxstrap.Enums;
using Bloxstrap.Helpers;
@ -25,7 +27,8 @@ 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();
// ideally should be List<CustomIntegration> but wpf moment so blehhhhh :P
public ObservableCollection<CustomIntegration> CustomIntegrations { get; set; } = new();
// mod preset configuration
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.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using Wpf.Ui.Mvvm.Contracts;
using Bloxstrap.Helpers;
using Bloxstrap.Models;
using Bloxstrap.Views.Pages;
using System.Collections.ObjectModel;
namespace Bloxstrap.ViewModels
{
@ -19,28 +16,46 @@ namespace Bloxstrap.ViewModels
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private readonly Page _page;
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 IntegrationsViewModel(Page page)
{
_page = page;
if (CustomIntegrations.Count > 0)
{
CustomIntegrationsVisibility = Visibility.Visible;
OnPropertyChanged(nameof(CustomIntegrationsVisibility));
}
}
private void OpenReShadeFolder()
{
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
{
get => App.Settings.Prop.UseDiscordRichPresence;
@ -96,14 +111,14 @@ namespace Bloxstrap.ViewModels
set => App.Settings.Prop.RFUAutoclose = value;
}
public Visibility CustomIntegrationsVisibility { get; set; } = Visibility.Collapsed;
public List<CustomIntegration> CustomIntegrations
public ObservableCollection<CustomIntegration> CustomIntegrations
{
get => App.Settings.Prop.CustomIntegrations;
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>
<StackPanel Grid.Column="0">
<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>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding CreateDesktopIcon, Mode=TwoWay}" />
@ -45,7 +45,7 @@
<ui:CardControl.Header>
<StackPanel Grid.Column="0">
<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>
</ui:CardControl.Header>
<ui:ToggleSwitch IsChecked="{Binding ChannelChangePromptingEnabled, Mode=TwoWay}" />

View File

@ -7,7 +7,7 @@
xmlns:models="clr-namespace:Bloxstrap.ViewModels"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
mc:Ignorable="d"
d:DesignHeight="680" d:DesignWidth="800"
d:DesignHeight="1080" d:DesignWidth="800"
Title="IntegrationsPage"
Scrollable="True">
<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.Header>
<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}" />
</StackPanel>
</ui:CardControl.Header>
@ -116,24 +116,54 @@
</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}">
<TextBlock Margin="0,4,0,0" Text="Here, you can have other programs launch with Roblox automatically like how rbxfpsunlocker does." TextWrapping="Wrap" />
<Grid Margin="0,8,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<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" />
<TextBlock Text="{Binding SelectedCustomIntegration.LaunchArgs}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<TextBlock Margin="0,8,0,0" FontSize="13" FontWeight="Medium" Text="Auto close when Roblox closes" />
<TextBlock Text="{Binding SelectedCustomIntegration.AutoClose}" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<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}" />
<Grid Grid.Row="1" Grid.Column="0" Margin="0,8,4,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ui:Button Grid.Column="0" Margin="0,0,4,0" Icon="Add28" Content="New" HorizontalAlignment="Stretch" Command="{Binding AddIntegrationCommand, Mode=OneTime}" />
<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>
<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>
</StackPanel>
</ui:UiPage>

View File

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