simple mod manager

This commit is contained in:
Dexrn ZacAttack
2025-02-24 00:41:33 -08:00
parent f1ce3e1e0d
commit 1883d0edea
32 changed files with 486 additions and 222 deletions

View File

@@ -4,7 +4,6 @@ using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Markup.Localizer;
using Windows.Storage;
using WinDurango.UI.Settings;
using WinDurango.UI.Utils;

View File

@@ -33,7 +33,7 @@
</SplitButton.Flyout>
</SplitButton>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button x:Name="manageModsButton" Margin="10 0 0 0" HorizontalAlignment="Left" Click="ShowNotImplemented" ToolTipService.ToolTip="Manage mods">
<Button x:Name="manageModsButton" Margin="10 0 0 0" HorizontalAlignment="Left" Click="ShowModManager" ToolTipService.ToolTip="Manage mods">
<SymbolIcon Symbol="Manage"></SymbolIcon>
</Button>
<Button x:Name="viewFolderButton" Margin="10 0 0 0" HorizontalAlignment="Left" Click="OpenFolder" ToolTipService.ToolTip="View install folder">

View File

@@ -1,5 +1,4 @@
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
@@ -7,12 +6,12 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Windows.Storage.Streams;
using WinDurango.UI.Dialogs;
using WinDurango.UI.Pages.Dialog;
using WinDurango.UI.Settings;
using WinDurango.UI.Utils;
@@ -66,7 +65,7 @@ namespace WinDurango.UI.Controls
Logger.WriteDebug($"Opening app installation folder {_package.InstalledPath}");
_ = Process.Start(new ProcessStartInfo(_package.InstalledPath) { UseShellExecute = true });
}
private async void ShowNotImplemented(object sender, RoutedEventArgs e)
{
Logger.WriteWarning($"Not implemented");
@@ -74,6 +73,13 @@ namespace WinDurango.UI.Controls
await impl.Show();
}
private async void ShowModManager(object sender, RoutedEventArgs e)
{
PageDialog pgd = new PageDialog(typeof(ModMan), _package.InstalledPath, $"Installed mods for {_package.DisplayName}");
pgd.XamlRoot = App.MainWindow.Content.XamlRoot;
await pgd.ShowAsync();
}
private async void RepatchPackage(object sender, RoutedEventArgs args)
{
var progress = new ProgressDialog($"Repatching {_Name}...", $"Repatching {_Name}", isIndeterminate: true).GetController();
@@ -84,7 +90,7 @@ namespace WinDurango.UI.Controls
});
NoticeDialog good = new NoticeDialog($"WinDurango was reinstalled in package {_Name}", "Reinstalled");
await good.Show();
App.MainWindow.ReloadAppList();
}
@@ -142,7 +148,8 @@ namespace WinDurango.UI.Controls
try
{
appListEntries = _package.GetAppListEntries();
} catch
}
catch
{
Logger.WriteWarning($"Could not get the applist entries of \"{_Name}\"");
}
@@ -184,7 +191,7 @@ namespace WinDurango.UI.Controls
MenuFlyout rcFlyout = new();
bool isPatched = false;
installedPackage instPackage = App.InstalledPackages.GetPackage(_package.Id.FamilyName);
if (instPackage != null)
isPatched = instPackage.IsPatched;
@@ -205,7 +212,8 @@ namespace WinDurango.UI.Controls
};
unpatchButton.Click += UnpatchPackage;
rcFlyout.Items.Add(unpatchButton);
} else
}
else
{
patchButton.Click += PatchPackage;
}

View File

@@ -1,22 +1,5 @@
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media.Animation;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
using Windows.Storage.Streams;
using WinDurango.UI.Dialogs;
using System;
using WinDurango.UI.Settings;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Controls
{

35
Controls/ModInfo.xaml Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<UserControl
x:Class="WinDurango.UI.Controls.ModInfo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinDurango.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ScrollViewer>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Name="modInfo">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="name" FontSize="20">Name</TextBlock>
<TextBlock x:Name="version" FontSize="14" Foreground="Gray" Margin="5,2,0,0">Version</TextBlock>
</StackPanel>
<TextBlock x:Name="description" FontSize="14" TextWrapping="Wrap">Description</TextBlock>
<TextBlock x:Name="publisher" FontSize="14" Foreground="Gray">Publisher</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="1">
<Button x:Name="deleteButton" ToolTipService.ToolTip="Delete" Click="DeleteMod" Margin="10, 0, 0, 10" HorizontalAlignment="Right">
<SymbolIcon Symbol="Delete"></SymbolIcon>
</Button>
<ToggleSwitch x:Name="enableSwitch" OffContent="" OnContent="" ToolTipService.ToolTip="Enabled" Margin="10, 0, -110, 10" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</ScrollViewer>
</UserControl>

92
Controls/ModInfo.xaml.cs Normal file
View File

@@ -0,0 +1,92 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System.Diagnostics;
using System.IO;
using WinDurango.UI.Pages.Dialog;
namespace WinDurango.UI.Controls
{
public sealed partial class ModInfo : UserControl
{
private string _dllPath;
private readonly FileVersionInfo _info;
public ModInfo(string dll)
{
_dllPath = dll;
this.InitializeComponent();
enableSwitch.IsOn = Path.GetExtension(_dllPath) == ".dll";
enableSwitch.Toggled += ChangeModStatus;
_info = FileVersionInfo.GetVersionInfo(_dllPath);
string name = _info.ProductName;
string description = _info.FileDescription;
string publisher = _info.CompanyName;
if (name == "" || name == null)
name = Path.GetFileNameWithoutExtension(_dllPath);
if (publisher == "" || publisher == null)
publisher = "Unknown Author";
this.name.Text = name;
// check if desc is invalid OR the name bc C# projs seem to have a bunch of fields set "incorrectly"
if (description == null || description == "" || description == name)
this.description.Visibility = Visibility.Collapsed;
this.version.Text = $"v{_info.ProductVersion}";
this.description.Text = description;
this.publisher.Text = publisher;
}
private void ChangeModStatus(object sender, RoutedEventArgs e)
{
ToggleSwitch s = (ToggleSwitch)sender;
string newExt = s.IsOn ? ".dll" : ".disabled";
string newPath = Path.ChangeExtension(_dllPath, newExt);
File.Move(_dllPath, newPath);
_dllPath = newPath;
}
private void DeleteMod(object sender, RoutedEventArgs e)
{
Flyout flyout = new Flyout();
TextBlock title = new TextBlock { Text = $"Are you sure you want to delete {_info.ProductName}?" };
TextBlock info = new TextBlock { Text = $"This file will be deleted from the disk." };
title.Style = (Style)Application.Current.Resources["BaseTextBlockStyle"];
Button button = new Button();
button.Content = "Delete";
button.Margin = new Thickness(0, 10, 0, 0);
button.Click += (s, e) =>
{
flyout.Hide();
File.Delete(_dllPath);
var parent = VisualTreeHelper.GetParent(this);
while (parent != null && !(parent is ModMan))
{
parent = VisualTreeHelper.GetParent(parent);
}
if (parent != null)
((ModMan)parent).RemoveElement(this);
};
flyout.Content = new StackPanel
{
Children =
{
title,
info,
button
}
};
flyout.ShowAt((Button)sender);
}
}
}

View File

@@ -4,10 +4,7 @@ using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.ApplicationModel;
using WinDurango.UI.Settings;
using WinDurango.UI.Utils;
using Image = Microsoft.UI.Xaml.Controls.Image;
namespace WinDurango.UI.Dialogs
@@ -52,9 +49,9 @@ namespace WinDurango.UI.Dialogs
Width = 64,
Height = 64,
Margin = new Thickness(5),
Source = new BitmapImage(pkg.Logo ?? new Uri("ms-appx:///Assets/testimg.png"))
Source = new BitmapImage(pkg.Logo)
};
packageLogo.ImageFailed += LogoFailed;
//packageLogo.ImageFailed += LogoFailed;
var packageInfo = new StackPanel
{

View File

@@ -10,7 +10,7 @@ namespace WinDurango.UI.Dialogs
private string _title;
private ContentDialog _confirmationDialog;
public Confirmation(string content, string title = "Information")
public Confirmation(string content, string title = "Confirmation")
{
_content = content;
_title = title;

View File

@@ -1,18 +1,7 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Dialogs

13
Dialogs/PageDialog.xaml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<ContentDialog
x:Class="WinDurango.UI.Dialogs.PageDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PageDialog"
Style="{ThemeResource DefaultContentDialogStyle}"
PrimaryButtonText="Close">
<ContentDialog.Resources>
<x:Double x:Key="ContentDialogMaxWidth">1200</x:Double>
</ContentDialog.Resources>
<Frame Name="frame"/>
</ContentDialog>

View File

@@ -0,0 +1,17 @@
using Microsoft.UI.Xaml.Controls;
using System;
namespace WinDurango.UI.Dialogs
{
public sealed partial class PageDialog : ContentDialog
{
public PageDialog(Type pg, object p, string title = "PageDialog")
{
this.DataContext = this;
this.InitializeComponent();
this.Title = title;
//this.MaxWidth = 1200;
this.frame.Navigate(pg, p);
}
}
}

View File

@@ -1,7 +1,5 @@
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
namespace WinDurango.UI.Dialogs
{
@@ -28,7 +26,7 @@ namespace WinDurango.UI.Dialogs
Width = 300,
Value = _progress
};
_textBlock = new TextBlock
{
Text = _text,
@@ -49,7 +47,7 @@ namespace WinDurango.UI.Dialogs
_progressBar
}
};
Grid.SetRow(_progressBar, 2);
Title = _title;
XamlRoot = App.MainWindow.Content.XamlRoot;

View File

@@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
using Windows.UI.Text.Core;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Dialogs
@@ -50,7 +49,7 @@ namespace WinDurango.UI.Dialogs
NoticeDialog oops = new NoticeDialog(title, reason);
await oops.Show();
});
}
}
public async Task Fail(string title, Exception ex)
{
@@ -64,56 +63,57 @@ namespace WinDurango.UI.Dialogs
});
}
public bool failed {
public bool failed
{
get => hasFailed;
}
public void Close()
{
_dialog.DispatcherQueue.TryEnqueue(() =>
{
_dialog.DispatcherQueue.TryEnqueue(() =>
{
_dialog.Hide();
});
}
public void Show()
{
_dialog.DispatcherQueue.TryEnqueue(() =>
{
_dialog.ShowAsync();
});
}
_dialog.Hide();
});
}
public async Task Create(Action action)
public void Show()
{
_dialog.DispatcherQueue.TryEnqueue(() =>
{
_dialog.ShowAsync();
try
{
action();
_dialog.Hide();
}
catch (Exception ex)
{
_dialog.Hide();
NoticeDialog oops = new NoticeDialog(ex.Message, "Error");
await oops.Show();
}
}
});
}
public async Task CreateAsync(Func<Task> action)
public async Task Create(Action action)
{
_dialog.ShowAsync();
try
{
_dialog.ShowAsync();
try
{
await action();
_dialog.Hide();
}
catch (Exception ex)
{
_dialog.Hide();
NoticeDialog oops = new NoticeDialog(ex.Message, "Error");
await oops.Show();
}
action();
_dialog.Hide();
}
catch (Exception ex)
{
_dialog.Hide();
NoticeDialog oops = new NoticeDialog(ex.Message, "Error");
await oops.Show();
}
}
public async Task CreateAsync(Func<Task> action)
{
_dialog.ShowAsync();
try
{
await action();
_dialog.Hide();
}
catch (Exception ex)
{
_dialog.Hide();
NoticeDialog oops = new NoticeDialog(ex.Message, "Error");
await oops.Show();
}
}
}
}

View File

@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using WinDurango.UI.Utils;
using WinUI3Localizer;

View File

@@ -1,4 +1,3 @@
using CommunityToolkit.WinUI;
using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
@@ -6,7 +5,6 @@ using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Threading.Tasks;
using WinDurango.UI.Dialogs;
using WinDurango.UI.Pages;
using WinDurango.UI.Settings;
@@ -21,7 +19,7 @@ namespace WinDurango.UI
public AppsListPage AppsListPage;
public SettingsPage SettingsPage;
public AboutPage AboutPage;
private void NavigationInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
if (args.IsSettingsInvoked)

View File

@@ -1,7 +1,6 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Pages

View File

@@ -1,14 +1,11 @@
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Security.Principal;
using System.Threading.Tasks;
using Windows.Management.Deployment;
using Windows.Storage;
using Windows.Storage.Pickers;

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="WinDurango.UI.Pages.Dialog.ModMan"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinDurango.UI.Pages.Dialog"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<ScrollViewer>
<StackPanel>
<StackPanel Name="cModList">
<TextBlock Name="noModsFolder" Visibility="Collapsed">
Mods directory hasn't been created yet.
<LineBreak/>Click "View mods folder" to create one.
</TextBlock>
<TextBlock Name="noMods" Visibility="Collapsed">No mods found.</TextBlock>
<StackPanel Name="modList"></StackPanel>
</StackPanel>
<Button HorizontalAlignment="Right" Margin="0, 10, 0, 0" Content="Open mods folder" Name="openModsFolder" Click="OpenModsFolder"></Button>
<Button HorizontalAlignment="Right" Margin="0, 10, 0, 0" Content="Create mods folder" Name="createModsFolder" Click="CreateModsFolder" Visibility="Collapsed"></Button>
</StackPanel>
</ScrollViewer>
</Grid>
</Page>

View File

@@ -0,0 +1,144 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using WinDurango.UI.Controls;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Pages.Dialog
{
public sealed partial class ModMan : Page
{
private string _modsPath;
private string _packagePath;
public ModMan()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if ((e.Parameter).GetType() != typeof(string))
return;
string path = (string)e.Parameter;
Init(path);
}
private void Init(string path)
{
// Layer makes it uppercase. This may cause issues once multiplatform support happens
_modsPath = Path.Combine(path, "mods");
_packagePath = path;
if (!Directory.Exists(_modsPath))
{
noModsFolder.Visibility = Visibility.Visible;
openModsFolder.Visibility = Visibility.Collapsed;
createModsFolder.Visibility = Visibility.Visible;
return;
};
ReadOnlySpan<string> mods = Directory.GetFiles(_modsPath);
if (mods.IsEmpty)
{
noMods.Visibility = Visibility.Visible;
return;
}
modList.Children.Clear();
foreach (var mod in mods)
{
if (Path.GetExtension(mod) != ".dll" && Path.GetExtension(mod) != ".disabled")
continue;
ModInfo info = new ModInfo(mod);
modList.Children.Add(info);
}
}
public void RemoveElement(ModInfo element)
{
modList.Children.Remove(element);
if (cModList.Children.ToList().Capacity == 0)
{
noMods.Visibility = Visibility.Visible;
}
}
private void ShowInfo(string error)
{
Visibility nmLastState = noMods.Visibility;
Visibility nmfLastState = noModsFolder.Visibility;
noMods.Visibility = Visibility.Collapsed;
noModsFolder.Visibility = Visibility.Collapsed;
InfoBar info = new InfoBar();
TextBlock text = new TextBlock();
text.Text = error;
info.IsOpen = true;
info.Content = text;
info.MaxWidth = this.ActualWidth;
text.TextWrapping = TextWrapping.WrapWholeWords;
info.Closed += (InfoBar sender, InfoBarClosedEventArgs args) =>
{
noMods.Visibility = nmLastState;
noModsFolder.Visibility = nmfLastState;
};
cModList.Children.Insert(0, info);
}
private void CreateModsFolder(object sender, RoutedEventArgs e)
{
try
{
if (!Directory.Exists(_modsPath))
Directory.CreateDirectory(_modsPath);
this.modList.Children.Clear();
openModsFolder.Visibility = Visibility.Visible;
createModsFolder.Visibility = Visibility.Collapsed;
noMods.Visibility = Visibility.Collapsed;
noModsFolder.Visibility = Visibility.Collapsed;
Init(_packagePath);
}
catch (Exception ex)
{
ShowInfo($"Couldn't create mod folder\n{ex.Message}");
Logger.WriteError($"Couldn't create mod folder {_modsPath}");
Logger.WriteException(ex);
}
}
private void OpenModsFolder(object sender, RoutedEventArgs e)
{
try
{
if (!Directory.Exists(_modsPath))
Directory.CreateDirectory(_modsPath);
_ = Process.Start(new ProcessStartInfo(_modsPath) { UseShellExecute = true });
}
catch (Exception ex)
{
ShowInfo($"Couldn't open mod folder\n{ex.Message}");
Logger.WriteError($"Couldn't open mod folder path {_modsPath}");
Logger.WriteException(ex);
}
}
}
}

View File

@@ -1,17 +1,4 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
namespace WinDurango.UI.Pages
{

View File

@@ -1,20 +1,9 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using WinDurango.UI.Settings;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Pages.Settings
@@ -24,7 +13,7 @@ namespace WinDurango.UI.Pages.Settings
public UiSettings()
{
this.InitializeComponent();
ComboBoxItem psbSelected = PatchSourceButton.Items
.OfType<ComboBoxItem>()
.FirstOrDefault(item => item.Tag.ToString() == App.Settings.Settings.DownloadSource.ToString());
@@ -32,7 +21,7 @@ namespace WinDurango.UI.Pages.Settings
{
PatchSourceButton.SelectedItem = psbSelected;
}
ComboBoxItem themeSelected = themeButton.Items
.OfType<ComboBoxItem>()
.FirstOrDefault(item => item.Tag.ToString() == App.Settings.Settings.Theme.ToString());
@@ -41,7 +30,7 @@ namespace WinDurango.UI.Pages.Settings
themeButton.SelectedItem = themeSelected;
}
}
private void OnThemeSelected(object sender, RoutedEventArgs e)
{
if (themeButton.SelectedItem is not ComboBoxItem sel)
@@ -53,7 +42,7 @@ namespace WinDurango.UI.Pages.Settings
{
return;
}
if (App.Settings.Settings.Theme == theme)
{
return;
@@ -61,24 +50,24 @@ namespace WinDurango.UI.Pages.Settings
App.Settings.Set("Theme", theme);
}
private async void OnSourceSelected(object sender, RoutedEventArgs e)
{
if (PatchSourceButton.SelectedItem is not ComboBoxItem sel)
{
return;
}
if (!Enum.TryParse(sel.Tag.ToString(), out UiConfigData.PatchSource source))
{
return;
}
if (App.Settings.Settings.DownloadSource == source)
{
return;
}
PatchSourceButton.SelectedItem = sel.Content;
App.Settings.Set("DownloadSource", source);
}
@@ -100,7 +89,7 @@ namespace WinDurango.UI.Pages.Settings
App.Settings.Set(settingName, toggleSwitch.IsOn);
}
}
private void OnDebugLogToggleLoaded(object sender, RoutedEventArgs e)
{
if (!Debugger.IsAttached || ((ToggleSwitch)sender).IsEnabled)

View File

@@ -1,21 +1,9 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using WinDurango.UI.Controls;
using WinDurango.UI.Settings;
using static WinUI3Localizer.LanguageDictionary;
namespace WinDurango.UI.Pages.Settings
@@ -50,7 +38,7 @@ namespace WinDurango.UI.Pages.Settings
{
return App.CoreSettings.Settings.Users.Find(u => u.Id == id);
}
public void OnToggleSetting(object sender, RoutedEventArgs e)
{
if (sender is ToggleSwitch toggleSwitch && toggleSwitch.Tag is string settingName)
@@ -58,7 +46,7 @@ namespace WinDurango.UI.Pages.Settings
App.CoreSettings.Set(settingName, toggleSwitch.IsOn);
}
}
private void SaveUsers(object sender, RoutedEventArgs e)
{
foreach (var userElement in users)
@@ -69,7 +57,7 @@ namespace WinDurango.UI.Pages.Settings
userElement.Save();
}
}
private void OpenAppData(object sender, RoutedEventArgs e)
{
Process.Start(new ProcessStartInfo(App.CoreDataDir) { UseShellExecute = true });
@@ -87,7 +75,7 @@ namespace WinDurango.UI.Pages.Settings
LayerUser.Children.Clear();
var user = users.Find(user => user.user.Id.ToString() == item.Tag.ToString());
LayerUser.Children.Add(user);
}
}
}

View File

@@ -1,11 +1,5 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Diagnostics;
using System.Linq;
using System.Windows.Controls.Primitives;
using WinDurango.UI.Settings;
using WinDurango.UI.Utils;
using WinDurango.UI.Pages.Settings;
namespace WinDurango.UI.Pages
@@ -13,7 +7,7 @@ namespace WinDurango.UI.Pages
public sealed partial class SettingsPage : Page
{
// should probably merge these into one?
private void NavigationInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
{
if (args.InvokedItemContainer is not NavigationViewItem item)

View File

@@ -39,7 +39,7 @@ namespace WinDurango.UI.Settings
writer.WriteEndObject();
}
}
public class CoreConfigData
{
public class User
@@ -53,7 +53,7 @@ namespace WinDurango.UI.Settings
public GamepadButtons? ControllerBind { get; set; }
public Key? KeyBind { get; set; }
}
public string Version { get; set; } = "unset"; // to be set by core if for some reason the config already exists
public bool EnableConsole { get; set; } = false;
public bool DebugLogging { get; set; } = false;
@@ -62,7 +62,7 @@ namespace WinDurango.UI.Settings
Enum.GetValues(typeof(GamepadButtons))
.Cast<GamepadButtons>()
.ToDictionary(button => button, button => Key.None);
public List<User> Users { get; set; } = [
new User() {
Name = "durangler",
@@ -80,11 +80,11 @@ namespace WinDurango.UI.Settings
Name = "durangled2",
Id = 3
},
];
}
public class CoreConfig : IConfig
{
private readonly string _settingsFile = Path.Combine(App.CoreDataDir, "settings.json");
@@ -93,7 +93,7 @@ namespace WinDurango.UI.Settings
public CoreConfig()
{
Settings = new CoreConfigData();
if (!Directory.Exists(App.DataDir))
Directory.CreateDirectory(App.DataDir);
@@ -104,7 +104,8 @@ namespace WinDurango.UI.Settings
return;
}
try {
try
{
string json = File.ReadAllText(_settingsFile);
Settings = JsonSerializer.Deserialize<CoreConfigData>(json);
@@ -144,7 +145,7 @@ namespace WinDurango.UI.Settings
try
{
Logger.WriteInformation($"Saving core settings...");
JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true, Converters = { new BindingsConverter() }};
JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true, Converters = { new BindingsConverter() } };
File.WriteAllText(_settingsFile, JsonSerializer.Serialize(Settings, options));
}
catch (Exception ex)

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks;
namespace WinDurango.UI.Settings
namespace WinDurango.UI.Settings
{
public interface IConfig
{

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using Windows.ApplicationModel;
@@ -25,7 +24,7 @@ namespace WinDurango.UI.Settings
{
WriteIndented = true
};
private readonly List<installedPackage> _installedPackages;
public InstalledPackages()
@@ -51,7 +50,7 @@ namespace WinDurango.UI.Settings
?? [];
}
}
public void RemovePackage(Package pkg)
{
installedPackage package = _installedPackages.Find(p => p.FamilyName == pkg.Id.FamilyName);
@@ -78,7 +77,7 @@ namespace WinDurango.UI.Settings
{
return _installedPackages.Find(p => p.FamilyName == pkg.Id.FamilyName);
}
public installedPackage? GetPackage(string familyName)
{
return _installedPackages.Find(p => p.FamilyName == familyName);
@@ -104,7 +103,7 @@ namespace WinDurango.UI.Settings
File.WriteAllText(Path.Combine(App.DataDir, "InstalledPackages.json"), json);
Logger.WriteDebug("Saved InstalledPackages.json");
}
public void AddPackage(Package package)
{
if (_installedPackages.Exists(p => p.FamilyName == package.Id.FamilyName))

View File

@@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using WinDurango.UI.Dialogs;
using WinDurango.UI.Utils;
namespace WinDurango.UI.Settings;
@@ -37,6 +33,7 @@ public class UiConfigData
public PatchSource DownloadSource { get; set; } = PatchSource.Release;
}
// TODO: fix type init exception
public class UiConfig : IConfig
{
private readonly string _settingsFile = Path.Combine(App.DataDir, "settings.json");
@@ -52,26 +49,27 @@ public class UiConfig : IConfig
{
Logger.WriteWarning($"Settings file doesn't exist");
Generate();
}
}
try {
string json = File.ReadAllText(_settingsFile);
UiConfigData loadedSettings = JsonSerializer.Deserialize<UiConfigData>(json);
try
{
string json = File.ReadAllText(_settingsFile);
UiConfigData loadedSettings = JsonSerializer.Deserialize<UiConfigData>(json);
if (loadedSettings == null)
{
Logger.WriteWarning("loadedSettings is null... wtf?");
return;
}
if (loadedSettings == null)
{
Logger.WriteWarning("loadedSettings is null... wtf?");
return;
}
if (loadedSettings.SaveVersion > App.VerPacked)
{
Reset();
Logger.WriteInformation($"Settings were reset due to the settings file version being too new. ({loadedSettings.SaveVersion})");
}
loadedSettings = JsonSerializer.Deserialize<UiConfigData>(json);
Settings = loadedSettings;
if (loadedSettings.SaveVersion > App.VerPacked)
{
Reset();
Logger.WriteInformation($"Settings were reset due to the settings file version being too new. ({loadedSettings.SaveVersion})");
}
loadedSettings = JsonSerializer.Deserialize<UiConfigData>(json);
Settings = loadedSettings;
}
catch (Exception ex)
{

View File

@@ -8,7 +8,6 @@ using System.Xml.Linq;
using Windows.ApplicationModel;
using Windows.Management.Deployment;
using WinDurango.UI.Dialogs;
using WinDurango.UI.Settings;
using WinUI3Localizer;
using static WinDurango.UI.Localization.Locale;
@@ -16,7 +15,8 @@ namespace WinDurango.UI.Utils
{
// do not touch or you will combust from all the glue holding this together
// this class sucks so much that we literally had to stop bc we didn't know how to rewrite a function and make it still work with the UI stuff
#nullable enable
// update: this was fixed same commit.
#nullable enable
public class ManifestInfo
{
public string? DisplayName { get; set; }
@@ -38,7 +38,7 @@ namespace WinDurango.UI.Utils
public static ManifestInfo GetPropertiesFromManifest(string manifestPath)
{
ManifestInfo manifestInfo = new();
if (!File.Exists(manifestPath))
return manifestInfo;
@@ -76,7 +76,8 @@ namespace WinDurango.UI.Utils
public static string GetSplashScreenPath(Package pkg)
{
try {
try
{
string installPath = pkg.InstalledPath;
string manifestPath = Path.Combine(installPath, "AppxManifest.xml");

View File

@@ -1,18 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.IO.Packaging;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using WinDurango.UI.Dialogs;
using WinDurango.UI.Settings;
using Package = Windows.ApplicationModel.Package;
@@ -25,6 +18,7 @@ namespace WinDurango.UI.Utils
public string DownloadLink { get; set; }
}
// yes it's the wrong term but it sounds good to my head
public static class WinDurangoPatcher
{
private static readonly HttpClient httpClient = new(new HttpClientHandler { AllowAutoRedirect = true });
@@ -40,20 +34,20 @@ namespace WinDurango.UI.Utils
installedPackage pkg = App.InstalledPackages.GetPackage(package);
if (pkg == null)
return false;
return await UnpatchPackage(pkg, controller);
}
public static async Task<bool> PatchPackage(Package package, bool forceRedownload,
ProgressController controller)
{
installedPackage pkg = App.InstalledPackages.GetPackage(package);
if (pkg == null)
return false;
return await PatchPackage(pkg, forceRedownload, controller);
}
// todo: clean this up
public static async Task<bool> PatchPackage(installedPackage package, bool forceRedownload,
ProgressController controller)
@@ -92,6 +86,7 @@ namespace WinDurango.UI.Utils
await using Stream httpStream = await httpClient.GetStreamAsync(dlLink);
await using FileStream stream = new(archivePath, FileMode.Create, FileAccess.Write, FileShare.None);
controller?.Update("Writing release zip", 30);
// why so slow?
await httpStream.CopyToAsync(stream);
}
catch (Exception ex)
@@ -138,7 +133,8 @@ namespace WinDurango.UI.Utils
try
{
File.Move(oldFile.FullName, Path.Combine(dllBackup, oldFile.Name));
} catch (Exception e)
}
catch (Exception e)
{
await controller.Fail(e.Message, "Failed to move backed-up file " + oldFile.Name);
return false;
@@ -163,7 +159,7 @@ namespace WinDurango.UI.Utils
}
Logger.WriteInformation($"Added {file.Name}");
if (!package.PatchedDlls.Contains(patchPath))
package.PatchedDlls.Add(patchPath);
}
@@ -179,9 +175,9 @@ namespace WinDurango.UI.Utils
builder.AppendLine($"# This package was patched by WinDurango.UI with WinDurango release \"{relName}\".");
builder.AppendLine("# If you want to unpatch manually, delete this file and edit %appdata%\\WinDurango\\UI\\InstalledPackages.json and set IsPatched to false.");
builder.AppendLine("# Format is ReleaseName;VerPacked");
builder.AppendLine($"{relName.Replace(";","-")};{App.VerPacked}");
builder.AppendLine($"{relName.Replace(";", "-")};{App.VerPacked}");
await File.WriteAllTextAsync(Path.Combine(installPath, "installed.txt"), builder.ToString());
controller?.Update($"Updating package list", 95);
package.IsPatched = true;
App.InstalledPackages.UpdatePackage(package);
@@ -236,7 +232,7 @@ namespace WinDurango.UI.Utils
controller?.Update($"Removing patched.txt", 99);
if (Path.Exists(Path.Combine(installPath, "installed.txt")))
File.Delete(Path.Combine(installPath, "installed.txt"));
controller?.Update($"Updating package list", 99);
App.InstalledPackages.UpdatePackage(package);
controller?.Update($"Done!", 100);

View File

@@ -1,5 +1,4 @@
using Microsoft.Windows.ApplicationModel.DynamicDependency;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;

View File

@@ -38,13 +38,20 @@
<ItemGroup>
<None Remove="Controls\AppTile.xaml" />
<None Remove="Controls\ContributorInfo.xaml" />
<None Remove="Controls\ModInfo.xaml" />
<None Remove="Dialogs\AppListDialog.xaml" />
<None Remove="Dialogs\InstallConfirmationDialog.xaml" />
<None Remove="Dialogs\PageDialog.xaml" />
<None Remove="Pages\AboutPage.xaml" />
<None Remove="Pages\AppsListPage.xaml" />
<None Remove="Pages\Dialog\ModManPage.xaml" />
<None Remove="Pages\NotImplementedPage.xaml" />
<None Remove="Pages\SettingsPage.xaml" />
</ItemGroup>
<PropertyGroup Label="Globals">
<WebView2UseWinRT>False</WebView2UseWinRT>
<WebView2EnableCsWinRTProjection>False</WebView2EnableCsWinRTProjection>
</PropertyGroup>
<PropertyGroup>
<WindowsSdkPackageVersion>10.0.26100.38</WindowsSdkPackageVersion>
@@ -53,6 +60,7 @@
<Authors>WinDurango</Authors>
<Company>WinDurango</Company>
<PackageProjectUrl>https://github.com/WinDurango/WinDurango.UI</PackageProjectUrl>
<Nullable>disable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
@@ -103,6 +111,10 @@
<Page Update="Controls\ContributorInfo.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Update="Dialogs\PageDialog.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
@@ -153,7 +165,15 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Pages\Settings\" />
<Page Update="Controls\ModInfo.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Pages\Dialog\ModManPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>