Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cheat refactor #7

Merged
merged 6 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/Ryujinx.Ava/Assets/Locales/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -591,11 +591,10 @@
"SelectDlcDialogTitle": "Select DLC files",
"SelectUpdateDialogTitle": "Select update files",
"UserProfileWindowTitle": "User Profiles Manager",
"CheatWindowTitle": "Cheats Manager",
"DlcWindowTitle": "Manage Downloadable Content for {0} ({1})",
"UpdateWindowTitle": "Title Update Manager",
"CheatWindowHeading": "Cheats Available for {0} [{1}]",
"BuildId": "BuildId:",
"CheatWindowHeading": "Manage Cheats for {0} ({1})",
"BuildId": "Build ID:",
"DlcWindowHeading": "{0} Downloadable Content(s)",
"UserProfilesEditProfile": "Edit Selected",
"Cancel": "Cancel",
Expand Down
6 changes: 3 additions & 3 deletions src/Ryujinx.Ava/UI/Controls/ApplicationContextMenu.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ public async void OpenCheatManager_Click(object sender, RoutedEventArgs args)

if (viewModel?.SelectedApplication != null)
{
await new CheatWindow(
await CheatWindow.Show(
viewModel.VirtualFileSystem,
viewModel.SelectedApplication.TitleId,
ulong.Parse(viewModel.SelectedApplication.TitleId, NumberStyles.HexNumber),
viewModel.SelectedApplication.TitleName,
viewModel.SelectedApplication.Path).ShowDialog(viewModel.TopLevel as Window);
viewModel.SelectedApplication.Path);
}
}

Expand Down
92 changes: 92 additions & 0 deletions src/Ryujinx.Ava/UI/ViewModels/CheatWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls.ApplicationLifetimes;
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<CheatNode> 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<string>();

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 async void CopyToClipboard()
{
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
await desktop.MainWindow.Clipboard.SetTextAsync(BuildId);
}
}

public void Save()
{
List<string> 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);
}
}
}
7 changes: 4 additions & 3 deletions src/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Ryujinx.Ui.Common.Helper;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;

Expand Down Expand Up @@ -170,11 +171,11 @@ public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e

string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString();

await new CheatWindow(
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).ShowDialog(Window);
Window.ViewModel.SelectedApplication.Path);

ViewModel.AppHost.Device.EnableCheats();
}
Expand Down
145 changes: 74 additions & 71 deletions src/Ryujinx.Ava/UI/Windows/CheatWindow.axaml
Original file line number Diff line number Diff line change
@@ -1,81 +1,66 @@
<window:StyleableWindow
<UserControl
x:Class="Ryujinx.Ava.UI.Windows.CheatWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
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:model="clr-namespace:Ryujinx.Ava.UI.Models"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
Width="500"
Height="500"
MinWidth="500"
MinHeight="500"
x:DataType="window:CheatWindow"
WindowStartupLocation="CenterOwner"
Height="380"
x:DataType="viewModels:CheatWindowViewModel"
mc:Ignorable="d"
Focusable="True">
<Window.Styles>
<Style Selector="TreeViewItem">
<Setter Property="IsExpanded" Value="True" />
</Style>
</Window.Styles>
<Grid Name="CheatGrid" Margin="15">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
MaxWidth="500"
Margin="20,15,20,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
LineHeight="18"
Text="{Binding Heading}"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="2"
Grid.Column="0"
MaxWidth="500"
Margin="140,15,20,5"
HorizontalAlignment="Center"
VerticalAlignment="Center"
LineHeight="30"
Text="{locale:Locale BuildId}"
TextAlignment="Center"
TextWrapping="Wrap" />
<TextBox
Grid.Row="2"
Grid.Column="1"
Margin="0,5,110,5"
MinWidth="160"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding BuildId}"
IsReadOnly="True" />
<Panel
Margin="0 0 0 10"
Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Orientation="Horizontal"
Grid.Column="0">
<TextBlock
Padding="0 0 10 0"
Text="{locale:Locale BuildId}" />
<Button
Name="CopyButton"
Command="{Binding CopyToClipboard}">
<TextBlock Text="{Binding BuildId}" />
</Button>
</StackPanel>
<TextBox
Grid.Column="2"
MinHeight="29"
MaxHeight="29"
MinWidth="180"
MaxWidth="180"
HorizontalAlignment="Stretch"
Watermark="{locale:Locale Search}"
Text="" />
</Grid>
</Panel>
<Border
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="5"
Grid.Row="1"
Margin="0 0 0 24"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="Gray"
BorderThickness="1">
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
BorderThickness="1"
CornerRadius="5"
Padding="2.5">
<TreeView
Name="CheatsView"
MinHeight="300"
SelectionMode="Multiple, Toggle"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding LoadedCheats}">
Expand All @@ -98,29 +83,47 @@
</TreeView.ItemTemplate>
</TreeView>
</Border>
<DockPanel
Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0"
<Panel
Grid.Row="2"
HorizontalAlignment="Stretch">
<DockPanel Margin="0" HorizontalAlignment="Right">
<StackPanel
Orientation="Horizontal"
Spacing="10"
HorizontalAlignment="Left">
<Button
Name="AddButton"
MinWidth="90"
Margin="5"
Command="{Binding}">
<TextBlock Text="{locale:Locale SettingsTabGeneralAdd}" />
</Button>
<Button
Name="RemoveAllButton"
MinWidth="90"
Margin="5"
Command="{Binding}">
<TextBlock Text="{locale:Locale DlcManagerRemoveAllButton}" />
</Button>
</StackPanel>
<StackPanel
Orientation="Horizontal"
Spacing="10"
HorizontalAlignment="Right">
<Button
Name="SaveButton"
MinWidth="90"
Margin="5"
Command="{Binding Save}"
IsVisible="{Binding !NoCheatsFound}">
Click="SaveAndClose">
<TextBlock Text="{locale:Locale SettingsButtonSave}" />
</Button>
<Button
Name="CancelButton"
MinWidth="90"
Margin="5"
Command="{Binding Close}">
Click="Close">
<TextBlock Text="{locale:Locale InputDialogCancel}" />
</Button>
</DockPanel>
</DockPanel>
</StackPanel>
</Panel>
</Grid>
</window:StyleableWindow>
</UserControl>
Loading
Loading