AutoLoad DLC/updates #12

Merged
J-Swift merged 38 commits from feature/auto-load-extra-files into master 2024-10-08 01:08:41 +00:00
2 changed files with 116 additions and 27 deletions
Showing only changes of commit a90a6b2786 - Show all commits

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.Utilities;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common.Helper;
using Ryujinx.UI.Common.Models;
using System;
using System.Collections.Generic;
@ -130,36 +131,17 @@ namespace Ryujinx.Ava.UI.ViewModels
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);
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));
}
}
SelectedDownloadableContents.Add(dlc);
}
OnPropertyChanged(nameof(UpdateCount));
}
// NOTE: Try to load downloadable contents from PFS last to preserve enabled state.