mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-07-23 15:07:11 +02:00
android - move title updates support to SAF
This commit is contained in:
parent
7955b4f287
commit
f403484276
10 changed files with 165 additions and 128 deletions
|
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||
private static readonly DownloadableContentJsonSerializerContext _contentSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||
private static readonly TitleUpdateMetadataJsonSerializerContext _titleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||
|
||||
internal static (bool, ProcessResult) TryLoad<TMetaData, TFormat, THeader, TEntry>(this PartitionFileSystemCore<TMetaData, TFormat, THeader, TEntry> partitionFileSystem, Switch device, Stream stream, out string errorMessage, string extension)
|
||||
internal static (bool, ProcessResult) TryLoad<TMetaData, TFormat, THeader, TEntry>(this PartitionFileSystemCore<TMetaData, TFormat, THeader, TEntry> partitionFileSystem, Switch device, Stream stream, out string errorMessage, string extension, Stream updateStream = null)
|
||||
where TMetaData : PartitionFileSystemMetaCore<TFormat, THeader, TEntry>, new()
|
||||
where TFormat : IPartitionFileSystemFormat
|
||||
where THeader : unmanaged, IPartitionFileSystemHeader
|
||||
|
@ -87,42 +87,21 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||
{
|
||||
// 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))
|
||||
PartitionFileSystem updatePartitionFileSystem = new();
|
||||
if (updateStream != null)
|
||||
{
|
||||
string updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, _titleSerializerContext.TitleUpdateMetadata).Selected;
|
||||
if (File.Exists(updatePath))
|
||||
LoadUpdate(device, updateStream, ref updatePatchNca, ref updateControlNca, titleIdBase, updatePartitionFileSystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load update information if exists.
|
||||
string titleUpdateMetadataPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, titleIdBase.ToString("x16"), "updates.json");
|
||||
if (File.Exists(titleUpdateMetadataPath))
|
||||
{
|
||||
PartitionFileSystem updatePartitionFileSystem = new();
|
||||
updatePartitionFileSystem.Initialize(new FileStream(updatePath, FileMode.Open, FileAccess.Read).AsStorage()).ThrowIfFailure();
|
||||
|
||||
device.Configuration.VirtualFileSystem.ImportTickets(updatePartitionFileSystem);
|
||||
|
||||
// TODO: This should use CNMT NCA instead.
|
||||
foreach (DirectoryEntryEx fileEntry in updatePartitionFileSystem.EnumerateEntries("/", "*.nca"))
|
||||
string updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, _titleSerializerContext.TitleUpdateMetadata).Selected;
|
||||
if (File.Exists(updatePath))
|
||||
{
|
||||
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;
|
||||
}
|
||||
LoadUpdate(device, new FileStream(updatePath, FileMode.Open, FileAccess.Read), ref updatePatchNca, ref updateControlNca, titleIdBase, updatePartitionFileSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +150,38 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||
errorMessage = "Unable to load: Could not find Main NCA";
|
||||
|
||||
return (false, ProcessResult.Failed);
|
||||
|
||||
static void LoadUpdate(Switch device, Stream updateStream, ref Nca updatePatchNca, ref Nca updateControlNca, ulong titleIdBase, PartitionFileSystem updatePartitionFileSystem)
|
||||
{
|
||||
updatePartitionFileSystem.Initialize(updateStream.AsStorage()).ThrowIfFailure();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Nca GetNca(this IFileSystem fileSystem, Switch device, string path)
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||
return LoadXci(stream);
|
||||
}
|
||||
|
||||
public bool LoadXci(Stream stream)
|
||||
public bool LoadXci(Stream stream, Stream updateStream = null)
|
||||
{
|
||||
Xci xci = new(_device.Configuration.VirtualFileSystem.KeySet, stream.AsStorage());
|
||||
|
||||
|
@ -50,7 +50,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||
return false;
|
||||
}
|
||||
|
||||
(bool success, ProcessResult processResult) = xci.OpenPartition(XciPartitionType.Secure).TryLoad(_device, stream, out string errorMessage, "xci");
|
||||
(bool success, ProcessResult processResult) = xci.OpenPartition(XciPartitionType.Secure).TryLoad(_device, stream, out string errorMessage, "xci", updateStream);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
|
@ -79,12 +79,12 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||
return LoadNsp(file);
|
||||
}
|
||||
|
||||
public bool LoadNsp(Stream stream)
|
||||
public bool LoadNsp(Stream stream, Stream updateStream = null)
|
||||
{
|
||||
PartitionFileSystem partitionFileSystem = new();
|
||||
partitionFileSystem.Initialize(stream.AsStorage()).ThrowIfFailure();
|
||||
|
||||
(bool success, ProcessResult processResult) = partitionFileSystem.TryLoad(_device, stream, out string errorMessage, "nsp");
|
||||
(bool success, ProcessResult processResult) = partitionFileSystem.TryLoad(_device, stream, out string errorMessage, "nsp", updateStream);
|
||||
|
||||
if (processResult.ProcessId == 0)
|
||||
{
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace Ryujinx.HLE
|
|||
return Processes.LoadNxo(fileName);
|
||||
}
|
||||
|
||||
public bool LoadXci(Stream xciStream)
|
||||
public bool LoadXci(Stream xciStream, Stream updateStream = null)
|
||||
{
|
||||
return Processes.LoadXci(xciStream);
|
||||
}
|
||||
|
@ -103,9 +103,9 @@ namespace Ryujinx.HLE
|
|||
return Processes.LoadNca(ncaStream);
|
||||
}
|
||||
|
||||
public bool LoadNsp(Stream nspStream)
|
||||
public bool LoadNsp(Stream nspStream, Stream updateStream = null)
|
||||
{
|
||||
return Processes.LoadNsp(nspStream);
|
||||
return Processes.LoadNsp(nspStream, updateStream);
|
||||
}
|
||||
|
||||
public bool LoadProgram(Stream stream, bool isNro, string name)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue