diff options
author | TSRBerry <20988865+TSRBerry@users.noreply.github.com> | 2023-11-11 21:56:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-11 21:56:57 +0100 |
commit | 5c3cfb84c09b0566da677425915afa0b2d76da55 (patch) | |
tree | d53c683c3ed3e685bec5b16ca661755d8815f66e /src/Ryujinx.HLE/FileSystem/ContentCollection.cs | |
parent | 55557525b16f8256d91f769e026874b5c70c3b2d (diff) |
Add support for multi game XCIs (#5638)1.1.1076
* Add default values to ApplicationData directly
* Refactor application loading
It should now be possible to load multi game XCIs.
Included updates won't be detected for now.
Opening a game from the command line currently only opens the first one.
* Only include program NCAs where at least one tuple item is not null
* Get application data by title id and add programIndex check back
* Refactor application loading again and remove duplicate code
* Actually use patch ncas for updates
* Fix number of applications found with multi game xcis
* Don't load bundled updates from multi game xcis
* Change ApplicationData.TitleId type to ulong & Add TitleIdString property
* Use cnmt files and ContentCollection to load programs
* Ava: Add updates and DLCs from gamecarts
* Get the cnmt file from its NCA
* Ava: Identify bundled updates in updater window
* Fix the (hopefully) last few bugs
* Add idOffset parameter to GetNcaByType
* Handle missing file for dlc.json
* Ava: Shorten error message for invalid files
* Gtk: Add additional string for bundled updates in TitleUpdateWindow
* Hopefully fix DLC issues
* Apply formatting
* Finally fix DLC issues
* Adjust property names and fileSize field
* Read the correct update file
* Fix wrong casing for application id strings
* Rename TitleId to ApplicationId
* Address review comments
* Fix formatting issues
* Apply suggestions from code review
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
* Gracefully fail when loading pfs for update and dlc window
* Fix applications with multiple programs
* Fix DLCWindow crash on GTK
* Fix some GUI issues
* Remove IsXci again
---------
Co-authored-by: gdkchan <gab.dark.100@gmail.com>
Diffstat (limited to 'src/Ryujinx.HLE/FileSystem/ContentCollection.cs')
-rw-r--r-- | src/Ryujinx.HLE/FileSystem/ContentCollection.cs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/FileSystem/ContentCollection.cs b/src/Ryujinx.HLE/FileSystem/ContentCollection.cs new file mode 100644 index 00000000..1c19887b --- /dev/null +++ b/src/Ryujinx.HLE/FileSystem/ContentCollection.cs @@ -0,0 +1,61 @@ +using LibHac.Common.Keys; +using LibHac.Fs.Fsa; +using LibHac.Ncm; +using LibHac.Tools.FsSystem.NcaUtils; +using LibHac.Tools.Ncm; +using Ryujinx.HLE.Loaders.Processes.Extensions; +using System; + +namespace Ryujinx.HLE.FileSystem +{ + /// <summary> + /// Thin wrapper around <see cref="Cnmt"/> + /// </summary> + public class ContentCollection + { + private readonly IFileSystem _pfs; + private readonly Cnmt _cnmt; + + public ulong Id => _cnmt.TitleId; + public TitleVersion Version => _cnmt.TitleVersion; + public ContentMetaType Type => _cnmt.Type; + public ulong ApplicationId => _cnmt.ApplicationTitleId; + public ulong PatchId => _cnmt.PatchTitleId; + public TitleVersion RequiredSystemVersion => _cnmt.MinimumSystemVersion; + public TitleVersion RequiredApplicationVersion => _cnmt.MinimumApplicationVersion; + public byte[] Digest => _cnmt.Hash; + + public ulong ProgramBaseId => Id & ~0x1FFFUL; + public bool IsSystemTitle => _cnmt.Type < ContentMetaType.Application; + + public ContentCollection(IFileSystem pfs, Cnmt cnmt) + { + _pfs = pfs; + _cnmt = cnmt; + } + + public Nca GetNcaByType(KeySet keySet, ContentType type, int programIndex = 0) + { + // TODO: Replace this with a check for IdOffset as soon as LibHac supports it: + // && entry.IdOffset == programIndex + + foreach (var entry in _cnmt.ContentEntries) + { + if (entry.Type != type) + { + continue; + } + + string ncaId = BitConverter.ToString(entry.NcaId).Replace("-", null).ToLower(); + Nca nca = _pfs.GetNca(keySet, $"/{ncaId}.nca"); + + if (nca.GetProgramIndex() == programIndex) + { + return nca; + } + } + + return null; + } + } +} |