326749498b
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address or silence dotnet format IDE1006 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA2208 warnings * Address or silence dotnet format CA1806 and a few CA1854 warnings * Address dotnet format CA2211 warnings * Address dotnet format CA1822 warnings * Address or silence dotnet format CA1069 warnings * Make dotnet format succeed in style mode * Address or silence dotnet format CA2211 warnings * Address review comments * Address dotnet format CA2208 warnings properly * Make ProcessResult readonly * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Add previously silenced warnings back I have no clue how these disappeared * Revert formatting changes for while and for-loops * Format if-blocks correctly * Run dotnet format style after rebase * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Fix a few disabled warnings * Fix naming rule violation, Convert shader properties to auto-property and convert values to const * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Fix and silence a few dotnet-format warnings again * Run dotnet format after rebase * Use using declaration instead of block syntax * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Fix naming rule violations * Fix typo * Add trailing commas, use targeted new and use array initializer * Fix build issues * Fix remaining build issues * Remove SuppressMessage for CA1069 where possible * Address dotnet format issues * Address formatting issues Co-authored-by: Ac_K <acoustik666@gmail.com> * Add GetHashCode implementation for RenderingSurfaceInfo * Explicitly silence CA1822 for every affected method in Syscall * Address formatting issues in Demangler.cs * Address review feedback Co-authored-by: Ac_K <acoustik666@gmail.com> * Revert marking service methods as static * Next dotnet format pass * Address review feedback --------- Co-authored-by: Ac_K <acoustik666@gmail.com>
180 lines
7.7 KiB
C#
180 lines
7.7 KiB
C#
using LibHac.Common;
|
|
using LibHac.Fs;
|
|
using LibHac.Fs.Fsa;
|
|
using LibHac.FsSystem;
|
|
using LibHac.Tools.Fs;
|
|
using LibHac.Tools.FsSystem;
|
|
using LibHac.Tools.FsSystem.NcaUtils;
|
|
using Ryujinx.Common.Configuration;
|
|
using Ryujinx.Common.Logging;
|
|
using Ryujinx.Common.Utilities;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
|
|
namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|
{
|
|
public static class PartitionFileSystemExtensions
|
|
{
|
|
private static readonly DownloadableContentJsonSerializerContext _contentSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
|
private static readonly TitleUpdateMetadataJsonSerializerContext _titleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
|
|
|
internal static (bool, ProcessResult) TryLoad(this PartitionFileSystem partitionFileSystem, Switch device, string path, out string errorMessage)
|
|
{
|
|
errorMessage = null;
|
|
|
|
// Load required NCAs.
|
|
Nca mainNca = null;
|
|
Nca patchNca = null;
|
|
Nca controlNca = null;
|
|
|
|
try
|
|
{
|
|
device.Configuration.VirtualFileSystem.ImportTickets(partitionFileSystem);
|
|
|
|
// TODO: To support multi-games container, this should use CNMT NCA instead.
|
|
foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
|
|
{
|
|
Nca nca = partitionFileSystem.GetNca(device, fileEntry.FullPath);
|
|
|
|
if (nca.GetProgramIndex() != device.Configuration.UserChannelPersistence.Index)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (nca.IsPatch())
|
|
{
|
|
patchNca = nca;
|
|
}
|
|
else if (nca.IsProgram())
|
|
{
|
|
mainNca = nca;
|
|
}
|
|
else if (nca.IsControl())
|
|
{
|
|
controlNca = nca;
|
|
}
|
|
}
|
|
|
|
ProcessLoaderHelper.RegisterProgramMapInfo(device, partitionFileSystem).ThrowIfFailure();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errorMessage = $"Unable to load: {ex.Message}";
|
|
|
|
return (false, ProcessResult.Failed);
|
|
}
|
|
|
|
if (mainNca != null)
|
|
{
|
|
if (mainNca.Header.ContentType != NcaContentType.Program)
|
|
{
|
|
errorMessage = "Selected NCA file is not a \"Program\" NCA";
|
|
|
|
return (false, ProcessResult.Failed);
|
|
}
|
|
|
|
// Load Update NCAs.
|
|
Nca updatePatchNca = null;
|
|
Nca updateControlNca = null;
|
|
|
|
if (ulong.TryParse(mainNca.Header.TitleId.ToString("x16"), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdBase))
|
|
{
|
|
// Clear the program index part.
|
|
titleIdBase &= ~0xFUL;
|
|
|
|
// Load update information if exists.
|
|
string titleUpdateMetadataPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, titleIdBase.ToString("x16"), "updates.json");
|
|
if (File.Exists(titleUpdateMetadataPath))
|
|
{
|
|
string updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, _titleSerializerContext.TitleUpdateMetadata).Selected;
|
|
if (File.Exists(updatePath))
|
|
{
|
|
PartitionFileSystem updatePartitionFileSystem = new(new FileStream(updatePath, FileMode.Open, FileAccess.Read).AsStorage());
|
|
|
|
device.Configuration.VirtualFileSystem.ImportTickets(updatePartitionFileSystem);
|
|
|
|
// TODO: This should use CNMT NCA instead.
|
|
foreach (DirectoryEntryEx fileEntry in updatePartitionFileSystem.EnumerateEntries("/", "*.nca"))
|
|
{
|
|
Nca nca = updatePartitionFileSystem.GetNca(device, fileEntry.FullPath);
|
|
|
|
if (nca.GetProgramIndex() != device.Configuration.UserChannelPersistence.Index)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != titleIdBase.ToString("x16"))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (nca.IsProgram())
|
|
{
|
|
updatePatchNca = nca;
|
|
}
|
|
else if (nca.IsControl())
|
|
{
|
|
updateControlNca = nca;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (updatePatchNca != null)
|
|
{
|
|
patchNca = updatePatchNca;
|
|
}
|
|
|
|
if (updateControlNca != null)
|
|
{
|
|
controlNca = updateControlNca;
|
|
}
|
|
|
|
// Load contained DownloadableContents.
|
|
// TODO: If we want to support multi-processes in future, we shouldn't clear AddOnContent data here.
|
|
device.Configuration.ContentManager.ClearAocData();
|
|
device.Configuration.ContentManager.AddAocData(partitionFileSystem, path, mainNca.Header.TitleId, device.Configuration.FsIntegrityCheckLevel);
|
|
|
|
// Load DownloadableContents.
|
|
string addOnContentMetadataPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, mainNca.Header.TitleId.ToString("x16"), "dlc.json");
|
|
if (File.Exists(addOnContentMetadataPath))
|
|
{
|
|
List<DownloadableContentContainer> dlcContainerList = JsonHelper.DeserializeFromFile(addOnContentMetadataPath, _contentSerializerContext.ListDownloadableContentContainer);
|
|
|
|
foreach (DownloadableContentContainer downloadableContentContainer in dlcContainerList)
|
|
{
|
|
foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
|
|
{
|
|
if (File.Exists(downloadableContentContainer.ContainerPath) && downloadableContentNca.Enabled)
|
|
{
|
|
device.Configuration.ContentManager.AddAocItem(downloadableContentNca.TitleId, downloadableContentContainer.ContainerPath, downloadableContentNca.FullPath);
|
|
}
|
|
else
|
|
{
|
|
Logger.Warning?.Print(LogClass.Application, $"Cannot find AddOnContent file {downloadableContentContainer.ContainerPath}. It may have been moved or renamed.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (true, mainNca.Load(device, patchNca, controlNca));
|
|
}
|
|
|
|
errorMessage = "Unable to load: Could not find Main NCA";
|
|
|
|
return (false, ProcessResult.Failed);
|
|
}
|
|
|
|
public static Nca GetNca(this IFileSystem fileSystem, Switch device, string path)
|
|
{
|
|
using var ncaFile = new UniqueRef<IFile>();
|
|
|
|
fileSystem.OpenFile(ref ncaFile.Ref, path.ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
|
|
|
return new Nca(device.Configuration.VirtualFileSystem.KeySet, ncaFile.Release().AsStorage());
|
|
}
|
|
}
|
|
}
|