misc: fix duplicated code (oops), reorder the commands in-code to match the UI

This commit is contained in:
GreemDev 2025-05-29 02:09:21 -05:00
parent 960421a7c1
commit 81412c7dd5
3 changed files with 236 additions and 583 deletions

View File

@ -51,14 +51,8 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
return High.ToString("x16") + Low.ToString("x16"); return High.ToString("x16") + Low.ToString("x16");
} }
public Uid ToLibHacUid() public Uid ToLibHacUid() => new((ulong)High, (ulong)Low);
{ public LibHac.Fs.UserId ToLibHac() => new((ulong)High, (ulong)Low);
return new Uid((ulong)High, (ulong)Low); public UInt128 ToUInt128() => new((ulong)High, (ulong)Low);
}
public UInt128 ToUInt128()
{
return new UInt128((ulong)High, (ulong)Low);
}
} }
} }

View File

@ -35,369 +35,5 @@ namespace Ryujinx.Ava.UI.Controls
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
public static RelayCommand<MainWindowViewModel> ToggleFavorite { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
{
viewModel.SelectedApplication.Favorite = !viewModel.SelectedApplication.Favorite;
ApplicationLibrary.LoadAndSaveMetaData(viewModel.SelectedApplication.IdString, appMetadata =>
{
appMetadata.Favorite = viewModel.SelectedApplication.Favorite;
});
viewModel.RefreshView();
}
);
public static RelayCommand<MainWindowViewModel> OpenUserSaveDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
OpenSaveDirectory(viewModel, SaveDataType.Account, new UserId((ulong)viewModel.AccountManager.LastOpenedUser.UserId.High, (ulong)viewModel.AccountManager.LastOpenedUser.UserId.Low))
);
public static RelayCommand<MainWindowViewModel> OpenDeviceSaveDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => OpenSaveDirectory(viewModel, SaveDataType.Device, default));
public static RelayCommand<MainWindowViewModel> OpenBcatSaveDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => OpenSaveDirectory(viewModel, SaveDataType.Bcat, default));
private static void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, UserId userId)
{
SaveDataFilter saveDataFilter = SaveDataFilter.Make(viewModel.SelectedApplication.Id, saveDataType, userId, saveDataId: default, index: default);
ApplicationHelper.OpenSaveDir(in saveDataFilter, viewModel.SelectedApplication.Id, viewModel.SelectedApplication.ControlHolder, viewModel.SelectedApplication.Name);
}
public static AsyncRelayCommand<MainWindowViewModel> OpenTitleUpdateManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => TitleUpdateManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication)
);
public static AsyncRelayCommand<MainWindowViewModel> OpenDownloadableContentManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => DownloadableContentManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication)
);
public static AsyncRelayCommand<MainWindowViewModel> OpenCheatManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => StyleableAppWindow.ShowAsync(
new CheatWindow(
viewModel.VirtualFileSystem,
viewModel.SelectedApplication.IdString,
viewModel.SelectedApplication.Name,
viewModel.SelectedApplication.Path
)
));
public static RelayCommand<MainWindowViewModel> OpenModsDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
{
string modsBasePath = ModLoader.GetModsBasePath();
string titleModsPath = ModLoader.GetApplicationDir(modsBasePath, viewModel.SelectedApplication.IdString);
OpenHelper.OpenFolder(titleModsPath);
});
public static RelayCommand<MainWindowViewModel> OpenSdModsDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
{
string sdModsBasePath = ModLoader.GetSdModsBasePath();
string titleModsPath = ModLoader.GetApplicationDir(sdModsBasePath, viewModel.SelectedApplication.IdString);
OpenHelper.OpenFolder(titleModsPath);
});
public static AsyncRelayCommand<MainWindowViewModel> OpenModManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
await ModManagerView.Show(
viewModel.SelectedApplication.Id,
viewModel.SelectedApplication.IdBase,
viewModel.ApplicationLibrary,
viewModel.SelectedApplication.Name);
});
public static AsyncRelayCommand<MainWindowViewModel> PurgePtcCache { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, viewModel.SelectedApplication.Name)
);
if (result == UserResult.Yes)
{
DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "0"));
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "1"));
List<FileInfo> cacheFiles = [];
if (mainDir.Exists)
{
cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
}
if (backupDir.Exists)
{
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
}
if (cacheFiles.Count > 0)
{
foreach (FileInfo file in cacheFiles)
{
try
{
file.Delete();
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
}
}
}
}
});
public static AsyncRelayCommand<MainWindowViewModel> NukePtcCache { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCNukeMessage, viewModel.SelectedApplication.Name)
);
if (result == UserResult.Yes)
{
DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "0"));
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "1"));
List<FileInfo> cacheFiles = [];
if (mainDir.Exists)
{
cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
}
if (backupDir.Exists)
{
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
cacheFiles.AddRange(backupDir.EnumerateFiles("*.info"));
}
if (cacheFiles.Count > 0)
{
foreach (FileInfo file in cacheFiles)
{
try
{
file.Delete();
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
}
}
}
}
});
public static AsyncRelayCommand<MainWindowViewModel> PurgeShaderCache { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, viewModel.SelectedApplication.Name)
);
if (result == UserResult.Yes)
{
DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "shader"));
List<DirectoryInfo> oldCacheDirectories = [];
List<FileInfo> newCacheFiles = [];
if (shaderCacheDir.Exists)
{
oldCacheDirectories.AddRange(shaderCacheDir.EnumerateDirectories("*"));
newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.toc"));
newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.data"));
}
if ((oldCacheDirectories.Count > 0 || newCacheFiles.Count > 0))
{
foreach (DirectoryInfo directory in oldCacheDirectories)
{
try
{
directory.Delete(true);
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, directory.Name, ex));
}
}
foreach (FileInfo file in newCacheFiles)
{
try
{
file.Delete();
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.ShaderCachePurgeError, file.Name, ex));
}
}
}
}
});
public static RelayCommand<MainWindowViewModel> OpenPtcDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
{
string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu");
string mainDir = Path.Combine(ptcDir, "0");
string backupDir = Path.Combine(ptcDir, "1");
if (!Directory.Exists(ptcDir))
{
Directory.CreateDirectory(ptcDir);
Directory.CreateDirectory(mainDir);
Directory.CreateDirectory(backupDir);
}
OpenHelper.OpenFolder(ptcDir);
});
public static RelayCommand<MainWindowViewModel> OpenShaderCacheDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
{
string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString.ToLower(), "cache", "shader");
if (!Directory.Exists(shaderCacheDir))
{
Directory.CreateDirectory(shaderCacheDir);
}
OpenHelper.OpenFolder(shaderCacheDir);
});
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationExeFs { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
await ApplicationHelper.ExtractSection(
viewModel.StorageProvider,
NcaSectionType.Code,
viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name);
});
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationRomFs { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
await ApplicationHelper.ExtractSection(
viewModel.StorageProvider,
NcaSectionType.Data,
viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name);
});
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationAocRomFs { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.Id, viewModel.ApplicationLibrary);
if (selectedDlc is not null)
{
await ApplicationHelper.ExtractAoc(
viewModel.StorageProvider,
selectedDlc.ContainerPath,
selectedDlc.FileName);
}
});
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationLogo { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
IReadOnlyList<IStorageFolder> result = await viewModel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
AllowMultiple = false,
});
if (result.Count == 0)
return;
ApplicationHelper.ExtractSection(
result[0].Path.LocalPath,
NcaSectionType.Logo,
viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name);
IStorageFile iconFile = await result[0].CreateFileAsync($"{viewModel.SelectedApplication.IdString}.png");
await using Stream fileStream = await iconFile.OpenWriteAsync();
using SKBitmap bitmap = SKBitmap.Decode(viewModel.SelectedApplication.Icon)
.Resize(new SKSizeI(512, 512), SKFilterQuality.High);
using SKData png = bitmap.Encode(SKEncodedImageFormat.Png, 100);
png.SaveTo(fileStream);
});
public static RelayCommand<MainWindowViewModel> CreateApplicationShortcut { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => ShortcutHelper.CreateAppShortcut(
viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name,
viewModel.SelectedApplication.IdString,
viewModel.SelectedApplication.Icon
));
public static AsyncRelayCommand<MainWindowViewModel> EditGameConfiguration { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
// just checking for file presence
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false));
viewModel.RefreshView();
});
public static AsyncRelayCommand<MainWindowViewModel> OpenApplicationCompatibility { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => CompatibilityListWindow.Show(viewModel.SelectedApplication.IdString));
public static AsyncRelayCommand<MainWindowViewModel> OpenApplicationData { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => ApplicationDataView.Show(viewModel.SelectedApplication));
public static AsyncRelayCommand<MainWindowViewModel> RunApplication { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel.LoadApplication(viewModel.SelectedApplication));
public static AsyncRelayCommand<MainWindowViewModel> TrimXci { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel.TrimXCIFile(viewModel.SelectedApplication.Path));
} }
} }

View File

@ -1963,8 +1963,12 @@ namespace Ryujinx.Ava.UI.ViewModels
#endregion #endregion
#region Context Menu commands #region Context Menu commands
public static AsyncRelayCommand<MainWindowViewModel> RunApplication { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel.LoadApplication(viewModel.SelectedApplication));
public static RelayCommand<MainWindowViewModel> ToggleFavorite { get; } = public static RelayCommand<MainWindowViewModel> ToggleFavorite { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel =>
{ {
@ -1979,39 +1983,73 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
); );
public static RelayCommand<MainWindowViewModel> OpenUserSaveDirectory { get; } = public static RelayCommand<MainWindowViewModel> CreateApplicationShortcut { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel => ShortcutHelper.CreateAppShortcut(
OpenSaveDirectory(viewModel, SaveDataType.Account, new LibHac.Fs.UserId((ulong)viewModel.AccountManager.LastOpenedUser.UserId.High, (ulong)viewModel.AccountManager.LastOpenedUser.UserId.Low)) viewModel.SelectedApplication.Path,
); viewModel.SelectedApplication.Name,
viewModel.SelectedApplication.IdString,
viewModel.SelectedApplication.Icon
));
public static AsyncRelayCommand<MainWindowViewModel> EditGameConfiguration { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
// just checking for file presence
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(
Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString, false, false));
viewModel.RefreshView();
});
public static AsyncRelayCommand<MainWindowViewModel> OpenApplicationCompatibility { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => CompatibilityListWindow.Show(viewModel.SelectedApplication.IdString));
public static AsyncRelayCommand<MainWindowViewModel> OpenApplicationData { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => ApplicationDataView.Show(viewModel.SelectedApplication));
public static RelayCommand<MainWindowViewModel> OpenUserSaveDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel =>
OpenSaveDirectory(viewModel, SaveDataType.Account, viewModel.AccountManager.LastOpenedUser.UserId.ToLibHac())
);
public static RelayCommand<MainWindowViewModel> OpenDeviceSaveDirectory { get; } = public static RelayCommand<MainWindowViewModel> OpenDeviceSaveDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => OpenSaveDirectory(viewModel, SaveDataType.Device, default)); viewModel => OpenSaveDirectory(viewModel, SaveDataType.Device, default));
public static RelayCommand<MainWindowViewModel> OpenBcatSaveDirectory { get; } = public static RelayCommand<MainWindowViewModel> OpenBcatSaveDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => OpenSaveDirectory(viewModel, SaveDataType.Bcat, default)); viewModel => OpenSaveDirectory(viewModel, SaveDataType.Bcat, default));
private static void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType, LibHac.Fs.UserId userId) private static void OpenSaveDirectory(MainWindowViewModel viewModel, SaveDataType saveDataType,
LibHac.Fs.UserId userId)
{ {
SaveDataFilter saveDataFilter = SaveDataFilter.Make(viewModel.SelectedApplication.Id, saveDataType, userId, saveDataId: default, index: default); SaveDataFilter saveDataFilter = SaveDataFilter.Make(viewModel.SelectedApplication.Id, saveDataType, userId,
saveDataId: default, index: default);
ApplicationHelper.OpenSaveDir(in saveDataFilter, viewModel.SelectedApplication.Id, viewModel.SelectedApplication.ControlHolder, viewModel.SelectedApplication.Name); ApplicationHelper.OpenSaveDir(in saveDataFilter, viewModel.SelectedApplication.Id,
viewModel.SelectedApplication.ControlHolder, viewModel.SelectedApplication.Name);
} }
public static AsyncRelayCommand<MainWindowViewModel> OpenTitleUpdateManager { get; } = public static AsyncRelayCommand<MainWindowViewModel> OpenTitleUpdateManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => TitleUpdateManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication) viewModel => TitleUpdateManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication)
); );
public static AsyncRelayCommand<MainWindowViewModel> OpenDownloadableContentManager { get; } = public static AsyncRelayCommand<MainWindowViewModel> OpenDownloadableContentManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => DownloadableContentManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication) viewModel =>
DownloadableContentManagerView.Show(viewModel.ApplicationLibrary, viewModel.SelectedApplication)
); );
public static AsyncRelayCommand<MainWindowViewModel> OpenCheatManager { get; } = public static AsyncRelayCommand<MainWindowViewModel> OpenCheatManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => StyleableAppWindow.ShowAsync( viewModel => StyleableAppWindow.ShowAsync(
new CheatWindow( new CheatWindow(
viewModel.VirtualFileSystem, viewModel.VirtualFileSystem,
@ -2021,8 +2059,16 @@ namespace Ryujinx.Ava.UI.ViewModels
) )
)); ));
public static AsyncRelayCommand<MainWindowViewModel> OpenModManager { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => ModManagerView.Show(
viewModel.SelectedApplication.Id,
viewModel.SelectedApplication.IdBase,
viewModel.ApplicationLibrary,
viewModel.SelectedApplication.Name));
public static RelayCommand<MainWindowViewModel> OpenModsDirectory { get; } = public static RelayCommand<MainWindowViewModel> OpenModsDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel =>
{ {
string modsBasePath = ModLoader.GetModsBasePath(); string modsBasePath = ModLoader.GetModsBasePath();
@ -2030,191 +2076,202 @@ namespace Ryujinx.Ava.UI.ViewModels
OpenHelper.OpenFolder(titleModsPath); OpenHelper.OpenFolder(titleModsPath);
}); });
public static RelayCommand<MainWindowViewModel> OpenSdModsDirectory { get; } = public static RelayCommand<MainWindowViewModel> OpenSdModsDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel =>
{ {
string sdModsBasePath = ModLoader.GetSdModsBasePath(); string sdModsBasePath = ModLoader.GetSdModsBasePath();
string titleModsPath = ModLoader.GetApplicationDir(sdModsBasePath, viewModel.SelectedApplication.IdString); string titleModsPath = ModLoader.GetApplicationDir(sdModsBasePath, viewModel.SelectedApplication.IdString);
OpenHelper.OpenFolder(titleModsPath); OpenHelper.OpenFolder(titleModsPath);
}); });
public static AsyncRelayCommand<MainWindowViewModel> OpenModManager { get; } = public static AsyncRelayCommand<MainWindowViewModel> TrimXci { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => viewModel => viewModel.TrimXCIFile(viewModel.SelectedApplication.Path));
{
await ModManagerView.Show(
viewModel.SelectedApplication.Id,
viewModel.SelectedApplication.IdBase,
viewModel.ApplicationLibrary,
viewModel.SelectedApplication.Name);
});
public static AsyncRelayCommand<MainWindowViewModel> PurgePtcCache { get; } = public static AsyncRelayCommand<MainWindowViewModel> PurgePtcCache { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage, viewModel.SelectedApplication.Name)
);
if (result == UserResult.Yes)
{ {
DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "0")); UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "1")); LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionMessage,
viewModel.SelectedApplication.Name)
);
List<FileInfo> cacheFiles = []; if (result == UserResult.Yes)
if (mainDir.Exists)
{ {
cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache")); DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath,
} viewModel.SelectedApplication.IdString, "cache", "cpu", "0"));
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath,
viewModel.SelectedApplication.IdString, "cache", "cpu", "1"));
if (backupDir.Exists) List<FileInfo> cacheFiles = [];
{
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
}
if (cacheFiles.Count > 0) if (mainDir.Exists)
{
foreach (FileInfo file in cacheFiles)
{ {
try cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
}
if (backupDir.Exists)
{
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
}
if (cacheFiles.Count > 0)
{
foreach (FileInfo file in cacheFiles)
{ {
file.Delete(); try
} {
catch (Exception ex) file.Delete();
{ }
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex)); catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
}
} }
} }
} }
} });
});
public static AsyncRelayCommand<MainWindowViewModel> NukePtcCache { get; } = public static AsyncRelayCommand<MainWindowViewModel> NukePtcCache { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCNukeMessage, viewModel.SelectedApplication.Name)
);
if (result == UserResult.Yes)
{ {
DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "0")); UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu", "1")); LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCNukeMessage,
viewModel.SelectedApplication.Name)
);
List<FileInfo> cacheFiles = []; if (result == UserResult.Yes)
if (mainDir.Exists)
{ {
cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache")); DirectoryInfo mainDir = new(Path.Combine(AppDataManager.GamesDirPath,
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info")); viewModel.SelectedApplication.IdString, "cache", "cpu", "0"));
} DirectoryInfo backupDir = new(Path.Combine(AppDataManager.GamesDirPath,
viewModel.SelectedApplication.IdString, "cache", "cpu", "1"));
if (backupDir.Exists) List<FileInfo> cacheFiles = [];
{
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
cacheFiles.AddRange(backupDir.EnumerateFiles("*.info"));
}
if (cacheFiles.Count > 0) if (mainDir.Exists)
{
foreach (FileInfo file in cacheFiles)
{ {
try cacheFiles.AddRange(mainDir.EnumerateFiles("*.cache"));
cacheFiles.AddRange(mainDir.EnumerateFiles("*.info"));
}
if (backupDir.Exists)
{
cacheFiles.AddRange(backupDir.EnumerateFiles("*.cache"));
cacheFiles.AddRange(backupDir.EnumerateFiles("*.info"));
}
if (cacheFiles.Count > 0)
{
foreach (FileInfo file in cacheFiles)
{ {
file.Delete(); try
} {
catch (Exception ex) file.Delete();
{ }
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex)); catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogPPTCDeletionErrorMessage, file.Name, ex));
}
} }
} }
} }
} });
});
public static AsyncRelayCommand<MainWindowViewModel> PurgeShaderCache { get; } = public static AsyncRelayCommand<MainWindowViewModel> PurgeShaderCache { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{
UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
LocaleManager.Instance[LocaleKeys.DialogWarning],
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage, viewModel.SelectedApplication.Name)
);
if (result == UserResult.Yes)
{
DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "shader"));
List<DirectoryInfo> oldCacheDirectories = [];
List<FileInfo> newCacheFiles = [];
if (shaderCacheDir.Exists)
{ {
oldCacheDirectories.AddRange(shaderCacheDir.EnumerateDirectories("*")); UserResult result = await ContentDialogHelper.CreateLocalizedConfirmationDialog(
newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.toc")); LocaleManager.Instance[LocaleKeys.DialogWarning],
newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.data")); LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogShaderDeletionMessage,
} viewModel.SelectedApplication.Name)
);
if ((oldCacheDirectories.Count > 0 || newCacheFiles.Count > 0)) if (result == UserResult.Yes)
{
foreach (DirectoryInfo directory in oldCacheDirectories)
{ {
try DirectoryInfo shaderCacheDir = new(Path.Combine(AppDataManager.GamesDirPath,
viewModel.SelectedApplication.IdString, "cache", "shader"));
List<DirectoryInfo> oldCacheDirectories = [];
List<FileInfo> newCacheFiles = [];
if (shaderCacheDir.Exists)
{ {
directory.Delete(true); oldCacheDirectories.AddRange(shaderCacheDir.EnumerateDirectories("*"));
newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.toc"));
newCacheFiles.AddRange(shaderCacheDir.GetFiles("*.data"));
} }
catch (Exception ex)
if ((oldCacheDirectories.Count > 0 || newCacheFiles.Count > 0))
{ {
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogPPTCDeletionErrorMessage, directory.Name, ex)); foreach (DirectoryInfo directory in oldCacheDirectories)
{
try
{
directory.Delete(true);
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.DialogPPTCDeletionErrorMessage, directory.Name, ex));
}
}
foreach (FileInfo file in newCacheFiles)
{
try
{
file.Delete();
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(
LocaleManager.Instance.UpdateAndGetDynamicValue(
LocaleKeys.ShaderCachePurgeError, file.Name, ex));
}
}
} }
} }
});
foreach (FileInfo file in newCacheFiles)
{
try
{
file.Delete();
}
catch (Exception ex)
{
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.ShaderCachePurgeError, file.Name, ex));
}
}
}
}
});
public static RelayCommand<MainWindowViewModel> OpenPtcDirectory { get; } = public static RelayCommand<MainWindowViewModel> OpenPtcDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel =>
{
string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu");
string mainDir = Path.Combine(ptcDir, "0");
string backupDir = Path.Combine(ptcDir, "1");
if (!Directory.Exists(ptcDir))
{ {
Directory.CreateDirectory(ptcDir); string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString,
Directory.CreateDirectory(mainDir); "cache", "cpu");
Directory.CreateDirectory(backupDir); string mainDir = Path.Combine(ptcDir, "0");
} string backupDir = Path.Combine(ptcDir, "1");
if (!Directory.Exists(ptcDir))
{
Directory.CreateDirectory(ptcDir);
Directory.CreateDirectory(mainDir);
Directory.CreateDirectory(backupDir);
}
OpenHelper.OpenFolder(ptcDir);
});
OpenHelper.OpenFolder(ptcDir);
});
public static RelayCommand<MainWindowViewModel> OpenShaderCacheDirectory { get; } = public static RelayCommand<MainWindowViewModel> OpenShaderCacheDirectory { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel =>
{ {
string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString.ToLower(), "cache", "shader"); string shaderCacheDir = Path.Combine(AppDataManager.GamesDirPath,
viewModel.SelectedApplication.IdString.ToLower(), "cache", "shader");
if (!Directory.Exists(shaderCacheDir)) if (!Directory.Exists(shaderCacheDir))
{ {
@ -2225,7 +2282,7 @@ namespace Ryujinx.Ava.UI.ViewModels
}); });
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationExeFs { get; } = public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationExeFs { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{ {
await ApplicationHelper.ExtractSection( await ApplicationHelper.ExtractSection(
@ -2234,9 +2291,9 @@ namespace Ryujinx.Ava.UI.ViewModels
viewModel.SelectedApplication.Path, viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name); viewModel.SelectedApplication.Name);
}); });
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationRomFs { get; } = public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationRomFs { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{ {
await ApplicationHelper.ExtractSection( await ApplicationHelper.ExtractSection(
@ -2245,13 +2302,14 @@ namespace Ryujinx.Ava.UI.ViewModels
viewModel.SelectedApplication.Path, viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name); viewModel.SelectedApplication.Name);
}); });
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationAocRomFs { get; } = public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationAocRomFs { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{ {
DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.Id, viewModel.ApplicationLibrary); DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.Id,
viewModel.ApplicationLibrary);
if (selectedDlc is not null) if (selectedDlc is not null)
{ {
await ApplicationHelper.ExtractAoc( await ApplicationHelper.ExtractAoc(
@ -2260,16 +2318,17 @@ namespace Ryujinx.Ava.UI.ViewModels
selectedDlc.FileName); selectedDlc.FileName);
} }
}); });
public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationLogo { get; } = public static AsyncRelayCommand<MainWindowViewModel> ExtractApplicationLogo { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null, Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel => async viewModel =>
{ {
IReadOnlyList<IStorageFolder> result = await viewModel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions IReadOnlyList<IStorageFolder> result = await viewModel.StorageProvider.OpenFolderPickerAsync(
{ new FolderPickerOpenOptions
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle], {
AllowMultiple = false, Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
}); AllowMultiple = false,
});
if (result.Count == 0) if (result.Count == 0)
return; return;
@ -2280,7 +2339,8 @@ namespace Ryujinx.Ava.UI.ViewModels
viewModel.SelectedApplication.Path, viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name); viewModel.SelectedApplication.Name);
IStorageFile iconFile = await result[0].CreateFileAsync($"{viewModel.SelectedApplication.IdString}.png"); IStorageFile iconFile =
await result[0].CreateFileAsync($"{viewModel.SelectedApplication.IdString}.png");
await using Stream fileStream = await iconFile.OpenWriteAsync(); await using Stream fileStream = await iconFile.OpenWriteAsync();
using SKBitmap bitmap = SKBitmap.Decode(viewModel.SelectedApplication.Icon) using SKBitmap bitmap = SKBitmap.Decode(viewModel.SelectedApplication.Icon)
@ -2291,43 +2351,6 @@ namespace Ryujinx.Ava.UI.ViewModels
png.SaveTo(fileStream); png.SaveTo(fileStream);
}); });
public static RelayCommand<MainWindowViewModel> CreateApplicationShortcut { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => ShortcutHelper.CreateAppShortcut(
viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name,
viewModel.SelectedApplication.IdString,
viewModel.SelectedApplication.Icon
));
public static AsyncRelayCommand<MainWindowViewModel> EditGameConfiguration { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
async viewModel =>
{
await StyleableAppWindow.ShowAsync(new GameSpecificSettingsWindow(viewModel));
// just checking for file presence
viewModel.SelectedApplication.HasIndependentConfiguration = File.Exists(Program.GetDirGameUserConfig(viewModel.SelectedApplication.IdString,false,false));
viewModel.RefreshView();
});
public static AsyncRelayCommand<MainWindowViewModel> OpenApplicationCompatibility { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => CompatibilityListWindow.Show(viewModel.SelectedApplication.IdString));
public static AsyncRelayCommand<MainWindowViewModel> OpenApplicationData { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => ApplicationDataView.Show(viewModel.SelectedApplication));
public static AsyncRelayCommand<MainWindowViewModel> RunApplication { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel.LoadApplication(viewModel.SelectedApplication));
public static AsyncRelayCommand<MainWindowViewModel> TrimXci { get; } =
Commands.CreateConditional<MainWindowViewModel>(vm => vm?.SelectedApplication != null,
viewModel => viewModel.TrimXCIFile(viewModel.SelectedApplication.Path));
#endregion #endregion
} }
} }