diff options
Diffstat (limited to 'Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs')
-rw-r--r-- | Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs | 151 |
1 files changed, 100 insertions, 51 deletions
diff --git a/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs index 972ffbc3..b1c86afc 100644 --- a/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs +++ b/Ryujinx.Ava/Ui/Windows/DownloadableContentManagerWindow.axaml.cs @@ -8,6 +8,7 @@ using LibHac.FsSystem; using LibHac.Tools.Fs; using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.NcaUtils; +using LibHac.Tools.FsSystem.Save; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Ui.Controls; using Ryujinx.Ava.Ui.Models; @@ -16,8 +17,11 @@ using Ryujinx.Common.Utilities; using Ryujinx.HLE.FileSystem; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; using System.IO; using System.Linq; +using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; using Path = System.IO.Path; @@ -27,14 +31,13 @@ namespace Ryujinx.Ava.Ui.Windows public partial class DownloadableContentManagerWindow : StyleableWindow { private readonly List<DownloadableContentContainer> _downloadableContentContainerList; - private readonly string _downloadableContentJsonPath; + private readonly string _downloadableContentJsonPath; - public VirtualFileSystem VirtualFileSystem { get; } - public AvaloniaList<DownloadableContentModel> DownloadableContents { get; set; } = new AvaloniaList<DownloadableContentModel>(); - public ulong TitleId { get; } - public string TitleName { get; } + private VirtualFileSystem _virtualFileSystem { get; } + private AvaloniaList<DownloadableContentModel> _downloadableContents { get; set; } - public string Heading => string.Format(LocaleManager.Instance["DlcWindowHeading"], TitleName, TitleId.ToString("X16")); + private ulong TitleId { get; } + private string TitleName { get; } public DownloadableContentManagerWindow() { @@ -42,14 +45,15 @@ namespace Ryujinx.Ava.Ui.Windows InitializeComponent(); - Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"]; + Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["DlcWindowTitle"]} - {TitleName} ({TitleId:X16})"; } public DownloadableContentManagerWindow(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName) { - VirtualFileSystem = virtualFileSystem; - TitleId = titleId; - TitleName = titleName; + _virtualFileSystem = virtualFileSystem; + _downloadableContents = new AvaloniaList<DownloadableContentModel>(); + TitleId = titleId; + TitleName = titleName; _downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json"); @@ -66,9 +70,24 @@ namespace Ryujinx.Ava.Ui.Windows InitializeComponent(); - Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"]; + RemoveButton.IsEnabled = false; + + DlcDataGrid.SelectionChanged += DlcDataGrid_SelectionChanged; + + Title = $"Ryujinx {Program.Version} - {LocaleManager.Instance["DlcWindowTitle"]} - {TitleName} ({TitleId:X16})"; LoadDownloadableContents(); + PrintHeading(); + } + + private void DlcDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + RemoveButton.IsEnabled = (DlcDataGrid.SelectedItems.Count > 0); + } + + private void PrintHeading() + { + Heading.Text = string.Format(LocaleManager.Instance["DlcWindowHeading"], _downloadableContents.Count, TitleName, TitleId.ToString("X16")); } private void LoadDownloadableContents() @@ -79,23 +98,23 @@ namespace Ryujinx.Ava.Ui.Windows { using FileStream containerFile = File.OpenRead(downloadableContentContainer.ContainerPath); - PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage()); + PartitionFileSystem pfs = new(containerFile.AsStorage()); - VirtualFileSystem.ImportTickets(pfs); + _virtualFileSystem.ImportTickets(pfs); foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList) { - using var ncaFile = new UniqueRef<IFile>(); + using UniqueRef<IFile> ncaFile = new(); pfs.OpenFile(ref ncaFile.Ref(), downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); - Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath); + Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath); if (nca != null) { - DownloadableContents.Add(new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), - downloadableContentContainer.ContainerPath, - downloadableContentNca.FullPath, - downloadableContentNca.Enabled)); + _downloadableContents.Add(new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), + downloadableContentContainer.ContainerPath, + downloadableContentNca.FullPath, + downloadableContentNca.Enabled)); } } } @@ -105,11 +124,11 @@ namespace Ryujinx.Ava.Ui.Windows Save(); } - private Nca TryCreateNca(IStorage ncaStorage, string containerPath) + private Nca TryOpenNca(IStorage ncaStorage, string containerPath) { try { - return new Nca(VirtualFileSystem.KeySet, ncaStorage); + return new Nca(_virtualFileSystem.KeySet, ncaStorage); } catch (Exception ex) { @@ -124,48 +143,46 @@ namespace Ryujinx.Ava.Ui.Windows private async Task AddDownloadableContent(string path) { - if (!File.Exists(path) || DownloadableContents.FirstOrDefault(x => x.ContainerPath == path) != null) + if (!File.Exists(path) || _downloadableContents.FirstOrDefault(x => x.ContainerPath == path) != null) { return; } - using (FileStream containerFile = File.OpenRead(path)) - { - PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage()); - bool containsDownloadableContent = false; + using FileStream containerFile = File.OpenRead(path); - VirtualFileSystem.ImportTickets(pfs); + PartitionFileSystem partitionFileSystem = new(containerFile.AsStorage()); + bool containsDownloadableContent = false; - foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca")) - { - using var ncaFile = new UniqueRef<IFile>(); + _virtualFileSystem.ImportTickets(partitionFileSystem); + + foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca")) + { + using var ncaFile = new UniqueRef<IFile>(); - pfs.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); + partitionFileSystem.OpenFile(ref ncaFile.Ref(), fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); - Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), path); + Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), path); + if (nca == null) + { + continue; + } - if (nca == null) + if (nca.Header.ContentType == NcaContentType.PublicData) + { + if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != TitleId) { - continue; + break; } - if (nca.Header.ContentType == NcaContentType.PublicData) - { - if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != TitleId) - { - break; - } - - DownloadableContents.Add(new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), path, fileEntry.FullPath, true)); + _downloadableContents.Add(new DownloadableContentModel(nca.Header.TitleId.ToString("X16"), path, fileEntry.FullPath, true)); - containsDownloadableContent = true; - } + containsDownloadableContent = true; } + } - if (!containsDownloadableContent) - { - await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]); - } + if (!containsDownloadableContent) + { + await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]); } } @@ -173,12 +190,26 @@ namespace Ryujinx.Ava.Ui.Windows { if (removeSelectedOnly) { - DownloadableContents.RemoveAll(DownloadableContents.Where(x => x.Enabled).ToList()); + AvaloniaList<DownloadableContentModel> removedItems = new(); + + foreach (var item in DlcDataGrid.SelectedItems) + { + removedItems.Add(item as DownloadableContentModel); + } + + DlcDataGrid.SelectedItems.Clear(); + + foreach (var item in removedItems) + { + _downloadableContents.RemoveAll(_downloadableContents.Where(x => x.TitleId == item.TitleId).ToList()); + } } else { - DownloadableContents.Clear(); + _downloadableContents.Clear(); } + + PrintHeading(); } public void RemoveSelected() @@ -191,6 +222,22 @@ namespace Ryujinx.Ava.Ui.Windows RemoveDownloadableContents(); } + public void EnableAll() + { + foreach(var item in _downloadableContents) + { + item.Enabled = true; + } + } + + public void DisableAll() + { + foreach (var item in _downloadableContents) + { + item.Enabled = false; + } + } + public async void Add() { OpenFileDialog dialog = new OpenFileDialog() @@ -214,6 +261,8 @@ namespace Ryujinx.Ava.Ui.Windows await AddDownloadableContent(file); } } + + PrintHeading(); } public void Save() @@ -222,7 +271,7 @@ namespace Ryujinx.Ava.Ui.Windows DownloadableContentContainer container = default; - foreach (DownloadableContentModel downloadableContent in DownloadableContents) + foreach (DownloadableContentModel downloadableContent in _downloadableContents) { if (container.ContainerPath != downloadableContent.ContainerPath) { |