diff --git a/Directory.Packages.props b/Directory.Packages.props index fd61602a8..bcce686ac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -44,7 +44,7 @@ - + @@ -59,4 +59,4 @@ - \ No newline at end of file + diff --git a/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.Builder.cs b/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.Builder.cs index e12df291b..27f516697 100644 --- a/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.Builder.cs +++ b/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.Builder.cs @@ -2,6 +2,7 @@ using Avalonia; using Avalonia.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Controls; +using Ryujinx.Ava.UI.SetupWizard; using Ryujinx.Ava.UI.ViewModels; namespace Ryujinx.Ava.Systems.SetupWizard diff --git a/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.cs b/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.cs index c96664fed..f01794d06 100644 --- a/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.cs +++ b/src/Ryujinx/Systems/SetupWizard/SetupWizardPage.cs @@ -2,6 +2,8 @@ using Avalonia.Controls.Presenters; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Controls; +using Ryujinx.Ava.UI.SetupWizard; using Ryujinx.Ava.UI.ViewModels; using System.Threading; using System.Threading.Tasks; diff --git a/src/Ryujinx/Systems/SetupWizard/SetupWizardPageContext.cs b/src/Ryujinx/Systems/SetupWizard/SetupWizardPageContext.cs new file mode 100644 index 000000000..9107a8f0b --- /dev/null +++ b/src/Ryujinx/Systems/SetupWizard/SetupWizardPageContext.cs @@ -0,0 +1,10 @@ +using Gommon; +using Ryujinx.Ava.UI.ViewModels; + +namespace Ryujinx.Ava.Systems.SetupWizard +{ + public abstract class SetupWizardPageContext: BaseModel + { + public abstract Result CompleteStep(); + } +} diff --git a/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml b/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml index 870f9720a..1549cf17a 100644 --- a/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml +++ b/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml @@ -5,7 +5,7 @@ xmlns:markup="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:pages="clr-namespace:Ryujinx.Ava.UI.SetupWizard.Pages" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:DataType="pages:SetupFirmwarePageViewModel" + x:DataType="pages:SetupFirmwarePageContext" x:Class="Ryujinx.Ava.UI.SetupWizard.Pages.SetupFirmwarePage"> diff --git a/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml.cs b/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml.cs index d5e02cfc9..5f2950bee 100644 --- a/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml.cs +++ b/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePage.axaml.cs @@ -2,7 +2,7 @@ using Ryujinx.Ava.UI.Controls; namespace Ryujinx.Ava.UI.SetupWizard.Pages { - public partial class SetupFirmwarePage : RyujinxControl + public partial class SetupFirmwarePage : RyujinxControl { public SetupFirmwarePage() { diff --git a/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePageViewModel.cs b/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePageContext.cs similarity index 54% rename from src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePageViewModel.cs rename to src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePageContext.cs index 50f0d4627..0359fab88 100644 --- a/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePageViewModel.cs +++ b/src/Ryujinx/UI/SetupWizard/Pages/SetupFirmwarePageContext.cs @@ -3,16 +3,20 @@ using Avalonia.Platform.Storage; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Gommon; -using Ryujinx.Ava; using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.Systems.SetupWizard; +using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.Utilities; +using Ryujinx.Common.Configuration; +using Ryujinx.HLE.FileSystem; +using System; using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; namespace Ryujinx.Ava.UI.SetupWizard.Pages { - public partial class SetupFirmwarePageViewModel : BaseModel + public partial class SetupFirmwarePageContext : SetupWizardPageContext { [ObservableProperty] public partial string FirmwareSourcePath { get; set; } @@ -65,5 +69,54 @@ namespace Ryujinx.Ava.UI.SetupWizard.Pages tb.Text = firmwareFolder.TryGetLocalPath(); } } + + public override Result CompleteStep() + { + if (!Directory.Exists(FirmwareSourcePath)) + return Result.Fail; + + try + { + RyujinxApp.MainWindow.ContentManager.InstallFirmware(FirmwareSourcePath); + SystemVersion installedFwVer = RyujinxApp.MainWindow.ContentManager.GetCurrentFirmwareVersion(); + if (installedFwVer != null) + { + NotificationHelper.ShowInformation( + "Firmware installed", + $"Installed firmware version {installedFwVer.VersionString}." + ); + } + else + { + NotificationHelper.ShowError( + "Firmware not installed", + $"It seems some error occurred when trying to install the firmware at path '{FirmwareSourcePath}'." + + "\nDid that folder contain a firmware dump?" + ); + } + RyujinxApp.MainWindow.ViewModel.RefreshFirmwareStatus(installedFwVer, allowNullVersion: true); + + if (installedFwVer is null) + return Result.Fail; + + // Purge Applet Cache. + + DirectoryInfo miiEditorCacheFolder = new( + Path.Combine(AppDataManager.GamesDirPath, "0100000000001009", "cache") + ); + + if (miiEditorCacheFolder.Exists) + { + miiEditorCacheFolder.Delete(true); + } + } + catch (Exception e) + { + NotificationHelper.ShowError(e.Message, waitingExit: true); + return Result.Fail; + } + + return Result.Success; + } } } diff --git a/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml index 702eb29d0..d24e86687 100644 --- a/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml +++ b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml @@ -6,7 +6,7 @@ xmlns:markup="clr-namespace:Ryujinx.Ava.Common.Markup" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Ryujinx.Ava.UI.SetupWizard.Pages.SetupKeysPage" - x:DataType="pages:SetupKeysPageViewModel"> + x:DataType="pages:SetupKeysPageContext"> diff --git a/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml.cs b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml.cs index 78febdb7d..fdde29fd6 100644 --- a/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml.cs +++ b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPage.axaml.cs @@ -2,7 +2,7 @@ using Ryujinx.Ava.UI.Controls; namespace Ryujinx.Ava.UI.SetupWizard.Pages { - public partial class SetupKeysPage : RyujinxControl + public partial class SetupKeysPage : RyujinxControl { public SetupKeysPage() { diff --git a/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.Helpers.cs b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPageContext.cs similarity index 61% rename from src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.Helpers.cs rename to src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPageContext.cs index cdec13a4d..8b0543957 100644 --- a/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.Helpers.cs +++ b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPageContext.cs @@ -1,19 +1,48 @@ +using Avalonia.Controls; +using Avalonia.Platform.Storage; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; using DynamicData; using Gommon; using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.Systems.SetupWizard; using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.Utilities; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.FileSystem; using System; using System.IO; +using System.Threading.Tasks; -namespace Ryujinx.Ava.UI.SetupWizard +namespace Ryujinx.Ava.UI.SetupWizard.Pages { - public partial class RyujinxSetupWizard + public partial class SetupKeysPageContext : SetupWizardPageContext { - private Result InstallKeys(string directory) + public override Result CompleteStep() => + !Directory.Exists(KeysFolderPath) + ? Result.Fail + : InstallKeys(KeysFolderPath); + + [ObservableProperty] + public partial string KeysFolderPath { get; set; } + + [RelayCommand] + private static async Task Browse(TextBox tb) + { + Optional result = await RyujinxApp.MainWindow.ViewModel.StorageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions + { + Title = LocaleManager.Instance[LocaleKeys.SetupWizardKeysPageFolderPopupTitle] + }); + + if (result.TryGet(out IStorageFolder keyFolder)) + { + tb.Text = keyFolder.TryGetLocalPath(); + } + } + + private static Result InstallKeys(string directory) { try { @@ -53,11 +82,11 @@ namespace Ryujinx.Ava.UI.SetupWizard NotificationHelper.ShowError(message, waitingExit: true); - return Result.Failure(new MessageError(ex.Message)); + return Result.Failure(new MessageError(message)); } finally { - _mainWindow.VirtualFileSystem.ReloadKeySet(); + RyujinxApp.MainWindow.VirtualFileSystem.ReloadKeySet(); } return Result.Success; diff --git a/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPageViewModel.cs b/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPageViewModel.cs deleted file mode 100644 index 234b50d6e..000000000 --- a/src/Ryujinx/UI/SetupWizard/Pages/SetupKeysPageViewModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Platform.Storage; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using Gommon; -using Ryujinx.Ava.Common.Locale; -using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ava.Utilities; -using System.Threading.Tasks; - -namespace Ryujinx.Ava.UI.SetupWizard.Pages -{ - public partial class SetupKeysPageViewModel : BaseModel - { - [ObservableProperty] - public partial string KeysFolderPath { get; set; } - - [RelayCommand] - private static async Task Browse(TextBox tb) - { - Optional result = await RyujinxApp.MainWindow.ViewModel.StorageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions - { - Title = LocaleManager.Instance[LocaleKeys.SetupWizardKeysPageFolderPopupTitle] - }); - - if (result.TryGet(out IStorageFolder keyFolder)) - { - tb.Text = keyFolder.TryGetLocalPath(); - } - } - } -} diff --git a/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.cs b/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.cs index 30ebcb743..ef0ed6b55 100644 --- a/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.cs +++ b/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizard.cs @@ -1,25 +1,19 @@ -using Avalonia.Controls.Presenters; -using Gommon; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.SetupWizard; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.SetupWizard.Pages; using Ryujinx.Ava.UI.Windows; -using Ryujinx.Common.Configuration; -using Ryujinx.HLE.FileSystem; -using System; -using System.IO; using System.Threading.Tasks; namespace Ryujinx.Ava.UI.SetupWizard { - public partial class RyujinxSetupWizard(RyujinxSetupWizardWindow wizardWindow) + public class RyujinxSetupWizard(RyujinxSetupWizardWindow wizardWindow) : BaseSetupWizard(wizardWindow.WizardPresenter) { private readonly MainWindow _mainWindow = RyujinxApp.MainWindow; - private bool _configWasModified = false; + private bool _configWasModified; public bool HasFirmware => _mainWindow.ContentManager.GetCurrentFirmwareVersion() != null; @@ -60,20 +54,14 @@ namespace Ryujinx.Ava.UI.SetupWizard Retry: bool result = await NextPage() .WithTitle(LocaleKeys.SetupWizardKeysPageTitle) - .WithContent(out SetupKeysPageViewModel kpvm) + .WithContent(out SetupKeysPageContext keyContext) .Show(); if (!result) return false; - if (!Directory.Exists(kpvm.KeysFolderPath)) + if (!keyContext.CompleteStep()) goto Retry; - - Result installResult = InstallKeys(kpvm.KeysFolderPath); - if (!installResult.IsSuccess) - { - goto Retry; - } } return true; @@ -92,55 +80,22 @@ namespace Ryujinx.Ava.UI.SetupWizard Retry: bool result = await NextPage() .WithTitle(LocaleKeys.SetupWizardFirmwarePageTitle) - .WithContent(out SetupFirmwarePageViewModel fwvm) + .WithContent(out SetupFirmwarePageContext fwContext) .Show(); if (!result) return false; - if (!Directory.Exists(fwvm.FirmwareSourcePath)) + if (!fwContext.CompleteStep()) goto Retry; - - try - { - _mainWindow.ContentManager.InstallFirmware(fwvm.FirmwareSourcePath); - SystemVersion installedFwVer = _mainWindow.ContentManager.GetCurrentFirmwareVersion(); - if (installedFwVer != null) - { - NotificationHelper.ShowInformation( - "Firmware installed", - $"Installed firmware version {installedFwVer.VersionString}." - ); - } - else - { - NotificationHelper.ShowError( - "Firmware not installed", - $"It seems some error occurred when trying to install the firmware at path '{fwvm.FirmwareSourcePath}'. " + - "\nPlease check the log or try again." - ); - } - _mainWindow.ViewModel.RefreshFirmwareStatus(installedFwVer, allowNullVersion: true); - - // Purge Applet Cache. - - DirectoryInfo miiEditorCacheFolder = new( - Path.Combine(AppDataManager.GamesDirPath, "0100000000001009", "cache") - ); - - if (miiEditorCacheFolder.Exists) - { - miiEditorCacheFolder.Delete(true); - } - } - catch (Exception e) - { - NotificationHelper.ShowError(e.Message, waitingExit: true); - goto Retry; - } } return true; } + + public void SignalConfigModified() + { + _configWasModified = true; + } } } diff --git a/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizardWindow.axaml.cs b/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizardWindow.axaml.cs index 71d0aa054..61a5295e1 100644 --- a/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizardWindow.axaml.cs +++ b/src/Ryujinx/UI/SetupWizard/RyujinxSetupWizardWindow.axaml.cs @@ -1,4 +1,5 @@ using Avalonia.Controls; +using Gommon; using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Systems.SetupWizard; using Ryujinx.Ava.UI.Windows; @@ -28,10 +29,10 @@ namespace Ryujinx.Ava.UI.SetupWizard { if (!CanShowSetupWizard) return Task.CompletedTask; - + Task windowTask = ShowAsync( CreateWindow(out BaseSetupWizard wiz), - owner ?? RyujinxApp.MainWindow + owner ); _ = wiz.Start(); return windowTask;