Add the ability to add individual files exefs with mod loader (#1766)

Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
Somebody Whoisbored 2020-12-29 12:54:32 -07:00 committed by GitHub
parent 9a808fe484
commit fb0db32338
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 43 deletions

View file

@ -21,6 +21,7 @@ using System.Linq;
using System.Reflection;
using static LibHac.Fs.ApplicationSaveDataManagement;
using static Ryujinx.HLE.HOS.ModLoader;
using ApplicationId = LibHac.Ncm.ApplicationId;
namespace Ryujinx.HLE.HOS
@ -30,7 +31,22 @@ namespace Ryujinx.HLE.HOS
public class ApplicationLoader
{
// Binaries from exefs are loaded into mem in this order. Do not change.
private static readonly string[] ExeFsPrefixes = { "rtld", "main", "subsdk*", "sdk" };
internal static readonly string[] ExeFsPrefixes =
{
"rtld",
"main",
"subsdk0",
"subsdk1",
"subsdk2",
"subsdk3",
"subsdk4",
"subsdk5",
"subsdk6",
"subsdk7",
"subsdk8",
"subsdk9",
"sdk"
};
private readonly Switch _device;
private readonly ContentManager _contentManager;
@ -463,37 +479,48 @@ namespace Ryujinx.HLE.HOS
metaData ??= ReadNpdm(codeFs);
List<NsoExecutable> nsos = new List<NsoExecutable>();
NsoExecutable[] nsos = new NsoExecutable[ExeFsPrefixes.Length];
foreach (string exePrefix in ExeFsPrefixes) // Load binaries with standard prefixes
for(int i = 0; i < nsos.Length; i++)
{
foreach (DirectoryEntryEx file in codeFs.EnumerateEntries("/", exePrefix))
string name = ExeFsPrefixes[i];
if (!codeFs.FileExists(name))
{
if (Path.GetExtension(file.Name) != string.Empty)
{
continue;
}
Logger.Info?.Print(LogClass.Loader, $"Loading {file.Name}...");
codeFs.OpenFile(out IFile nsoFile, file.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
NsoExecutable nso = new NsoExecutable(nsoFile.AsStorage(), file.Name);
nsos.Add(nso);
continue; // file doesn't exist, skip
}
Logger.Info?.Print(LogClass.Loader, $"Loading {name}...");
codeFs.OpenFile(out IFile nsoFile, $"/{name}".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nsos[i] = new NsoExecutable(nsoFile.AsStorage(), name);
}
// ExeFs file replacements
bool modified = _fileSystem.ModLoader.ApplyExefsMods(TitleId, nsos);
ModLoadResult modLoadResult = _fileSystem.ModLoader.ApplyExefsMods(TitleId, nsos);
NsoExecutable[] programs = nsos.ToArray();
// collect the nsos, ignoring ones that aren't used
NsoExecutable[] programs = nsos.Where(x => x != null).ToArray();
modified |= _fileSystem.ModLoader.ApplyNsoPatches(TitleId, programs);
// take the npdm from mods if present
if (modLoadResult.Npdm != null)
{
metaData = modLoadResult.Npdm;
}
bool hasPatches = _fileSystem.ModLoader.ApplyNsoPatches(TitleId, programs);
_contentManager.LoadEntries(_device);
if (_device.System.EnablePtc && modified)
bool usePtc = _device.System.EnablePtc;
// don't use PTC if exefs files have been replaced
usePtc &= !modLoadResult.Modified;
// don't use PTC if exefs files have been patched
usePtc &= !hasPatches;
if (_device.System.EnablePtc && !usePtc)
{
Logger.Warning?.Print(LogClass.Ptc, $"Detected exefs modifications. PPTC disabled.");
}
@ -501,7 +528,7 @@ namespace Ryujinx.HLE.HOS
Graphics.Gpu.GraphicsConfig.TitleId = TitleIdText;
_device.Gpu.HostInitalized.Set();
Ptc.Initialize(TitleIdText, DisplayVersion, _device.System.EnablePtc && !modified);
Ptc.Initialize(TitleIdText, DisplayVersion, usePtc);
ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, executables: programs);
}
@ -657,4 +684,4 @@ namespace Ryujinx.HLE.HOS
return resultCode;
}
}
}
}