Implement update loader and log loaded application info (#1023)

* Implement update loader

* Add title version to titlebar and log loaded application info

* nits

* requested changes
This commit is contained in:
Xpl0itR 2020-04-12 22:02:37 +01:00 committed by GitHub
parent 6052aa17f2
commit ad3d2fb5a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 605 additions and 39 deletions

View file

@ -7,6 +7,7 @@ using LibHac.FsSystem.NcaUtils;
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Spl;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem.Content;
using Ryujinx.HLE.HOS.Font;
@ -30,6 +31,8 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using Utf8Json;
using Utf8Json.Resolvers;
using TimeServiceManager = Ryujinx.HLE.HOS.Services.Time.TimeManager;
using NsoExecutable = Ryujinx.HLE.Loaders.Executables.NsoExecutable;
@ -117,6 +120,10 @@ namespace Ryujinx.HLE.HOS
public ulong TitleId { get; private set; }
public string TitleIdText => TitleId.ToString("x16");
public string TitleVersionString { get; private set; }
public bool TitleIs64Bit { get; private set; }
public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
public int GlobalAccessLogMode { get; set; }
@ -368,6 +375,8 @@ namespace Ryujinx.HLE.HOS
TitleName = ControlData.Value.Titles.ToArray()
.FirstOrDefault(x => x.Name[0] != 0).Name.ToString();
}
TitleVersionString = ControlData.Value.DisplayVersion.ToString();
}
}
else
@ -455,6 +464,54 @@ namespace Ryujinx.HLE.HOS
IStorage dataStorage = null;
IFileSystem codeFs = null;
if (File.Exists(Path.Combine(Device.FileSystem.GetBasePath(), "games", mainNca.Header.TitleId.ToString("x16"), "updates.json")))
{
using (Stream stream = File.OpenRead(Path.Combine(Device.FileSystem.GetBasePath(), "games", mainNca.Header.TitleId.ToString("x16"), "updates.json")))
{
IJsonFormatterResolver resolver = CompositeResolver.Create(StandardResolver.AllowPrivateSnakeCase);
string updatePath = JsonSerializer.Deserialize<TitleUpdateMetadata>(stream, resolver).Selected;
if (File.Exists(updatePath))
{
FileStream file = new FileStream(updatePath, FileMode.Open, FileAccess.Read);
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage());
foreach (DirectoryEntryEx ticketEntry in nsp.EnumerateEntries("/", "*.tik"))
{
Result result = nsp.OpenFile(out IFile ticketFile, ticketEntry.FullPath.ToU8Span(), OpenMode.Read);
if (result.IsSuccess())
{
Ticket ticket = new Ticket(ticketFile.AsStream());
KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(KeySet)));
}
}
foreach (DirectoryEntryEx fileEntry in nsp.EnumerateEntries("/", "*.nca"))
{
nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new Nca(KeySet, ncaFile.AsStorage());
if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != mainNca.Header.TitleId.ToString("x16"))
{
break;
}
if (nca.Header.ContentType == NcaContentType.Program)
{
patchNca = nca;
}
else if (nca.Header.ContentType == NcaContentType.Control)
{
controlNca = nca;
}
}
}
}
}
if (patchNca == null)
{
if (mainNca.CanOpenSection(NcaSectionType.Data))
@ -498,7 +555,8 @@ namespace Ryujinx.HLE.HOS
LoadExeFs(codeFs, out Npdm metaData);
TitleId = metaData.Aci0.TitleId;
TitleId = metaData.Aci0.TitleId;
TitleIs64Bit = metaData.Is64Bit;
if (controlNca != null)
{
@ -513,6 +571,8 @@ namespace Ryujinx.HLE.HOS
{
EnsureSaveData(new TitleId(TitleId));
}
Logger.PrintInfo(LogClass.Loader, $"Application Loaded: {TitleName} v{TitleVersionString} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]");
}
private void LoadExeFs(IFileSystem codeFs, out Npdm metaData)
@ -551,7 +611,8 @@ namespace Ryujinx.HLE.HOS
}
}
TitleId = metaData.Aci0.TitleId;
TitleId = metaData.Aci0.TitleId;
TitleIs64Bit = metaData.Is64Bit;
LoadNso("rtld");
LoadNso("main");
@ -653,8 +714,9 @@ namespace Ryujinx.HLE.HOS
ContentManager.LoadEntries(Device);
TitleName = metaData.TitleName;
TitleId = metaData.Aci0.TitleId;
TitleName = metaData.TitleName;
TitleId = metaData.Aci0.TitleId;
TitleIs64Bit = metaData.Is64Bit;
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject });
}