Extract DLC json load logic

This commit is contained in:
Jimmy Reichley 2024-08-16 22:14:33 -04:00
parent 472feb9680
commit a90a6b2786
No known key found for this signature in database
GPG key ID: 67715DC5A329803C
2 changed files with 116 additions and 27 deletions

View file

@ -0,0 +1,107 @@
using LibHac.Common;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Utilities;
using Ryujinx.UI.Common.Models;
using System;
using System.Collections.Generic;
using System.IO;
using Path = System.IO.Path;
namespace Ryujinx.UI.Common.Helper
{
public static class DownloadableContentsHelper
{
private static readonly DownloadableContentJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public static List<(DownloadableContentModel, bool IsEnabled)> LoadSavedDownloadableContents(VirtualFileSystem vfs, ulong applicationIdBase)
{
var downloadableContentJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationIdBase.ToString("X16"), "dlc.json");
if (!File.Exists(downloadableContentJsonPath))
{
return [];
}
try
{
var downloadableContentContainerList = JsonHelper.DeserializeFromFile(downloadableContentJsonPath,
_serializerContext.ListDownloadableContentContainer);
return LoadDownloadableContents(vfs, downloadableContentContainerList);
}
catch
{
Logger.Error?.Print(LogClass.Configuration, "Downloadable Content JSON failed to deserialize.");
return [];
}
}
private static List<(DownloadableContentModel, bool IsEnabled)> LoadDownloadableContents(VirtualFileSystem vfs, List<DownloadableContentContainer> downloadableContentContainers)
{
var result = new List<(DownloadableContentModel, bool IsEnabled)>();
foreach (DownloadableContentContainer downloadableContentContainer in downloadableContentContainers)
{
if (!File.Exists(downloadableContentContainer.ContainerPath))
{
continue;
}
using IFileSystem partitionFileSystem = PartitionFileSystemUtils.OpenApplicationFileSystem(downloadableContentContainer.ContainerPath, vfs);
foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
{
using UniqueRef<IFile> ncaFile = new();
partitionFileSystem.OpenFile(ref ncaFile.Ref, downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
// Nca nca = TryOpenNca(vfs, ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath);
Nca nca = TryOpenNca(vfs, ncaFile.Get.AsStorage());
if (nca == null)
{
// result.Add((content, downloadableContentNca.Enabled));
continue;
}
var content = new DownloadableContentModel(nca.Header.TitleId,
downloadableContentContainer.ContainerPath,
downloadableContentNca.FullPath);
result.Add((content, downloadableContentNca.Enabled));
// if (downloadableContentNca.Enabled)
// {
// SelectedDownloadableContents.Add(content);
// }
// OnPropertyChanged(nameof(UpdateCount));
}
}
return result;
}
private static Nca TryOpenNca(VirtualFileSystem vfs, IStorage ncaStorage)
{
try
{
return new Nca(vfs.KeySet, ncaStorage);
}
catch (Exception ex)
{
// Dispatcher.UIThread.InvokeAsync(async () =>
// {
// await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[LocaleKeys.DialogLoadFileErrorMessage], ex.Message, containerPath));
// });
}
return null;
}
}
}

View file

@ -19,6 +19,7 @@ using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.HLE.Utilities; using Ryujinx.HLE.Utilities;
using Ryujinx.UI.App.Common; using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.Models; using Ryujinx.UI.Common.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -130,36 +131,17 @@ namespace Ryujinx.Ava.UI.ViewModels
private void LoadDownloadableContents() private void LoadDownloadableContents()
{ {
foreach (DownloadableContentContainer downloadableContentContainer in _downloadableContentContainerList) var savedDlc = DownloadableContentsHelper.LoadSavedDownloadableContents(_virtualFileSystem, _applicationData.IdBase);
foreach ((DownloadableContentModel dlc, bool isEnabled) in savedDlc)
{ {
if (File.Exists(downloadableContentContainer.ContainerPath)) DownloadableContents.Add(dlc);
if (isEnabled)
{ {
using IFileSystem partitionFileSystem = PartitionFileSystemUtils.OpenApplicationFileSystem(downloadableContentContainer.ContainerPath, _virtualFileSystem); SelectedDownloadableContents.Add(dlc);
foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
{
using UniqueRef<IFile> ncaFile = new();
partitionFileSystem.OpenFile(ref ncaFile.Ref, downloadableContentNca.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = TryOpenNca(ncaFile.Get.AsStorage(), downloadableContentContainer.ContainerPath);
if (nca != null)
{
var content = new DownloadableContentModel(nca.Header.TitleId,
downloadableContentContainer.ContainerPath,
downloadableContentNca.FullPath);
DownloadableContents.Add(content);
if (downloadableContentNca.Enabled)
{
SelectedDownloadableContents.Add(content);
}
OnPropertyChanged(nameof(UpdateCount));
}
}
} }
OnPropertyChanged(nameof(UpdateCount));
} }
// NOTE: Try to load downloadable contents from PFS last to preserve enabled state. // NOTE: Try to load downloadable contents from PFS last to preserve enabled state.