aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs')
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs60
1 files changed, 42 insertions, 18 deletions
diff --git a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
index cdecae77..9f3a0045 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
@@ -17,11 +17,12 @@ using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem;
+using Ryujinx.HLE.Loaders.Processes.Extensions;
+using Ryujinx.Ui.App.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Threading.Tasks;
using Application = Avalonia.Application;
using Path = System.IO.Path;
@@ -38,7 +39,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private AvaloniaList<DownloadableContentModel> _selectedDownloadableContents = new();
private string _search;
- private readonly ulong _titleId;
+ private readonly ApplicationData _applicationData;
private static readonly DownloadableContentJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
@@ -92,18 +93,25 @@ namespace Ryujinx.Ava.UI.ViewModels
public IStorageProvider StorageProvider;
- public DownloadableContentManagerViewModel(VirtualFileSystem virtualFileSystem, ulong titleId)
+ public DownloadableContentManagerViewModel(VirtualFileSystem virtualFileSystem, ApplicationData applicationData)
{
_virtualFileSystem = virtualFileSystem;
- _titleId = titleId;
+ _applicationData = applicationData;
if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
StorageProvider = desktop.MainWindow.StorageProvider;
}
- _downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "dlc.json");
+ _downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationData.IdString, "dlc.json");
+
+ if (!File.Exists(_downloadableContentJsonPath))
+ {
+ _downloadableContentContainerList = new List<DownloadableContentContainer>();
+
+ Save();
+ }
try
{
@@ -120,6 +128,9 @@ namespace Ryujinx.Ava.UI.ViewModels
private void LoadDownloadableContents()
{
+ // NOTE: Try to load downloadable contents from PFS first.
+ AddDownloadableContent(_applicationData.Path);
+
foreach (DownloadableContentContainer downloadableContentContainer in _downloadableContentContainerList)
{
if (File.Exists(downloadableContentContainer.ContainerPath))
@@ -127,7 +138,11 @@ namespace Ryujinx.Ava.UI.ViewModels
using FileStream containerFile = File.OpenRead(downloadableContentContainer.ContainerPath);
PartitionFileSystem partitionFileSystem = new();
- partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
+
+ if (partitionFileSystem.Initialize(containerFile.AsStorage()).IsFailure())
+ {
+ continue;
+ }
_virtualFileSystem.ImportTickets(partitionFileSystem);
@@ -220,22 +235,34 @@ namespace Ryujinx.Ava.UI.ViewModels
foreach (var file in result)
{
- await AddDownloadableContent(file.Path.LocalPath);
+ if (!AddDownloadableContent(file.Path.LocalPath))
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogDlcNoDlcErrorMessage]);
+ }
}
}
- private async Task AddDownloadableContent(string path)
+ private bool AddDownloadableContent(string path)
{
if (!File.Exists(path) || DownloadableContents.FirstOrDefault(x => x.ContainerPath == path) != null)
{
- return;
+ return true;
}
using FileStream containerFile = File.OpenRead(path);
- PartitionFileSystem partitionFileSystem = new();
- partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
- bool containsDownloadableContent = false;
+ IFileSystem partitionFileSystem;
+
+ if (Path.GetExtension(path).ToLower() == ".xci")
+ {
+ partitionFileSystem = new Xci(_virtualFileSystem.KeySet, containerFile.AsStorage()).OpenPartition(XciPartitionType.Secure);
+ }
+ else
+ {
+ var pfsTemp = new PartitionFileSystem();
+ pfsTemp.Initialize(containerFile.AsStorage()).ThrowIfFailure();
+ partitionFileSystem = pfsTemp;
+ }
_virtualFileSystem.ImportTickets(partitionFileSystem);
@@ -253,7 +280,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (nca.Header.ContentType == NcaContentType.PublicData)
{
- if ((nca.Header.TitleId & 0xFFFFFFFFFFFFE000) != _titleId)
+ if (nca.GetProgramIdBase() != _applicationData.IdBase)
{
break;
}
@@ -265,14 +292,11 @@ namespace Ryujinx.Ava.UI.ViewModels
OnPropertyChanged(nameof(UpdateCount));
Sort();
- containsDownloadableContent = true;
+ return true;
}
}
- if (!containsDownloadableContent)
- {
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogDlcNoDlcErrorMessage]);
- }
+ return false;
}
public void Remove(DownloadableContentModel model)