diff --git a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs index 397eabe21..248e154af 100644 --- a/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs @@ -120,7 +120,7 @@ namespace Ryujinx.Ava.UI.Controls { await CheatWindow.Show( viewModel.VirtualFileSystem, - viewModel.SelectedApplication.TitleId, + ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber), viewModel.SelectedApplication.TitleName, viewModel.SelectedApplication.Path); } diff --git a/src/Ryujinx.Ava/UI/ViewModels/CheatWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/CheatWindowViewModel.cs new file mode 100644 index 000000000..89b243104 --- /dev/null +++ b/src/Ryujinx.Ava/UI/ViewModels/CheatWindowViewModel.cs @@ -0,0 +1,82 @@ +using Avalonia.Collections; +using Ryujinx.Ava.UI.Models; +using Ryujinx.HLE.FileSystem; +using Ryujinx.HLE.HOS; +using Ryujinx.Ui.App.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace Ryujinx.Ava.UI.ViewModels +{ + public class CheatWindowViewModel : BaseModel + { + private readonly string _enabledCheatsPath; + public AvaloniaList LoadedCheats { get; } = new(); + public string BuildId { get; } + + public CheatWindowViewModel(VirtualFileSystem virtualFileSystem, ulong titleId, string titlePath) + { + BuildId = ApplicationData.GetApplicationBuildId(virtualFileSystem, titlePath); + + string modsBasePath = ModLoader.GetModsBasePath(); + string titleModsPath = ModLoader.GetTitleDir(modsBasePath, titleId.ToString("x16")); + + _enabledCheatsPath = Path.Combine(titleModsPath, "cheats", "enabled.txt"); + + string[] enabled = Array.Empty(); + + if (File.Exists(_enabledCheatsPath)) + { + enabled = File.ReadAllLines(_enabledCheatsPath); + } + + var mods = new ModLoader.ModCache(); + + ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleId); + + string currentCheatFile = string.Empty; + string buildId = string.Empty; + + CheatNode currentGroup = null; + + foreach (var cheat in mods.Cheats) + { + if (cheat.Path.FullName != currentCheatFile) + { + currentCheatFile = cheat.Path.FullName; + string parentPath = currentCheatFile.Replace(titleModsPath, ""); + + buildId = Path.GetFileNameWithoutExtension(currentCheatFile).ToUpper(); + currentGroup = new CheatNode("", buildId, parentPath, true); + + LoadedCheats.Add(currentGroup); + } + + var model = new CheatNode(cheat.Name, buildId, "", false, enabled.Contains($"{buildId}-{cheat.Name}")); + currentGroup?.SubNodes.Add(model); + } + } + + public void Save() + { + List enabledCheats = new(); + + foreach (var cheats in LoadedCheats) + { + foreach (var cheat in cheats.SubNodes) + { + if (cheat.IsEnabled) + { + enabledCheats.Add(cheat.BuildIdKey); + } + } + } + + Directory.CreateDirectory(Path.GetDirectoryName(_enabledCheatsPath)); + + File.WriteAllLines(_enabledCheatsPath, enabledCheats); + } + } +} diff --git a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs index f56249933..439c6fcc6 100644 --- a/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs +++ b/src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs @@ -15,6 +15,7 @@ using Ryujinx.Ui.Common.Configuration; using Ryujinx.Ui.Common.Helper; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; @@ -172,7 +173,7 @@ namespace Ryujinx.Ava.UI.Views.Main await CheatWindow.Show( Window.VirtualFileSystem, - ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText, + ulong.Parse(ViewModel.AppHost.Device.Processes.ActiveApplication.ProgramIdText, NumberStyles.HexNumber), name, Window.ViewModel.SelectedApplication.Path); diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml index b0fbea2e5..a0290ebe9 100644 --- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml +++ b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml @@ -5,10 +5,10 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows" + xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" Width="500" - Height="500" - x:DataType="window:CheatWindow" + Height="380" + x:DataType="viewModels:CheatWindowViewModel" mc:Ignorable="d" Focusable="True"> @@ -88,15 +88,14 @@ Name="SaveButton" MinWidth="90" Margin="5" - Command="{Binding Save}" - IsVisible="{Binding !NoCheatsFound}"> + Click="SaveAndClose"> diff --git a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs index c282aebf0..ac59f0d92 100644 --- a/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs +++ b/src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml.cs @@ -1,29 +1,18 @@ -using Avalonia.Collections; -using Avalonia.Controls; +using Avalonia.Controls; +using Avalonia.Interactivity; using Avalonia.Styling; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.Models; +using Ryujinx.Ava.UI.ViewModels; using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.HOS; -using Ryujinx.Ui.App.Common; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; using System.Threading.Tasks; namespace Ryujinx.Ava.UI.Windows { public partial class CheatWindow : UserControl { - private readonly string _enabledCheatsPath; - public bool NoCheatsFound { get; } - - public AvaloniaList LoadedCheats { get; } - public string BuildId { get; } + public CheatWindowViewModel ViewModel; public CheatWindow() { @@ -32,66 +21,14 @@ namespace Ryujinx.Ava.UI.Windows InitializeComponent(); } - public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath) + public CheatWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) { - LoadedCheats = new AvaloniaList(); - - BuildId = ApplicationData.GetApplicationBuildId(virtualFileSystem, titlePath); + DataContext = ViewModel = new CheatWindowViewModel(virtualFileSystem, titleId, titlePath); InitializeComponent(); - - string modsBasePath = ModLoader.GetModsBasePath(); - string titleModsPath = ModLoader.GetTitleDir(modsBasePath, titleId); - ulong titleIdValue = ulong.Parse(titleId, NumberStyles.HexNumber); - - _enabledCheatsPath = Path.Combine(titleModsPath, "cheats", "enabled.txt"); - - string[] enabled = Array.Empty(); - - if (File.Exists(_enabledCheatsPath)) - { - enabled = File.ReadAllLines(_enabledCheatsPath); - } - - int cheatAdded = 0; - - var mods = new ModLoader.ModCache(); - - ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue); - - string currentCheatFile = string.Empty; - string buildId = string.Empty; - - CheatNode currentGroup = null; - - foreach (var cheat in mods.Cheats) - { - if (cheat.Path.FullName != currentCheatFile) - { - currentCheatFile = cheat.Path.FullName; - string parentPath = currentCheatFile.Replace(titleModsPath, ""); - - buildId = Path.GetFileNameWithoutExtension(currentCheatFile).ToUpper(); - currentGroup = new CheatNode("", buildId, parentPath, true); - - LoadedCheats.Add(currentGroup); - } - - var model = new CheatNode(cheat.Name, buildId, "", false, enabled.Contains($"{buildId}-{cheat.Name}")); - currentGroup?.SubNodes.Add(model); - - cheatAdded++; - } - - if (cheatAdded == 0) - { - NoCheatsFound = true; - } - - DataContext = this; } - public static async Task Show(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath) + public static async Task Show(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName, string titlePath) { ContentDialog contentDialog = new() { @@ -99,7 +36,7 @@ namespace Ryujinx.Ava.UI.Windows SecondaryButtonText = "", CloseButtonText = "", Content = new CheatWindow(virtualFileSystem, titleId, titleName, titlePath), - Title = string.Format(LocaleManager.Instance[LocaleKeys.CheatWindowHeading], titleName, titleId.ToUpper()), + Title = string.Format(LocaleManager.Instance[LocaleKeys.CheatWindowHeading], titleName, titleId.ToString("X16")), }; Style bottomBorder = new(x => x.OfType().Name("DialogSpace").Child().OfType()); @@ -110,34 +47,13 @@ namespace Ryujinx.Ava.UI.Windows await ContentDialogHelper.ShowAsync(contentDialog); } - public void Save() + private void SaveAndClose(object sender, RoutedEventArgs e) { - if (NoCheatsFound) - { - return; - } - - List enabledCheats = new(); - - foreach (var cheats in LoadedCheats) - { - foreach (var cheat in cheats.SubNodes) - { - if (cheat.IsEnabled) - { - enabledCheats.Add(cheat.BuildIdKey); - } - } - } - - Directory.CreateDirectory(Path.GetDirectoryName(_enabledCheatsPath)); - - File.WriteAllLines(_enabledCheatsPath, enabledCheats); - + ViewModel.Save(); ((ContentDialog)Parent).Hide(); } - public void Close() + private void Close(object sender, RoutedEventArgs e) { ((ContentDialog)Parent).Hide(); }