diff options
Diffstat (limited to 'src/Ryujinx.HLE/FileSystem/ContentManager.cs')
-rw-r--r-- | src/Ryujinx.HLE/FileSystem/ContentManager.cs | 391 |
1 files changed, 178 insertions, 213 deletions
diff --git a/src/Ryujinx.HLE/FileSystem/ContentManager.cs b/src/Ryujinx.HLE/FileSystem/ContentManager.cs index e00310a0..13f98763 100644 --- a/src/Ryujinx.HLE/FileSystem/ContentManager.cs +++ b/src/Ryujinx.HLE/FileSystem/ContentManager.cs @@ -26,17 +26,17 @@ namespace Ryujinx.HLE.FileSystem public class ContentManager { private const ulong SystemVersionTitleId = 0x0100000000000809; - private const ulong SystemUpdateTitleId = 0x0100000000000816; + private const ulong SystemUpdateTitleId = 0x0100000000000816; private Dictionary<StorageId, LinkedList<LocationEntry>> _locationEntries; - private Dictionary<string, ulong> _sharedFontTitleDictionary; - private Dictionary<ulong, string> _systemTitlesNameDictionary; - private Dictionary<string, string> _sharedFontFilenameDictionary; + private readonly Dictionary<string, ulong> _sharedFontTitleDictionary; + private readonly Dictionary<ulong, string> _systemTitlesNameDictionary; + private readonly Dictionary<string, string> _sharedFontFilenameDictionary; private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary; - private struct AocItem + private readonly struct AocItem { public readonly string ContainerPath; public readonly string NcaPath; @@ -48,16 +48,16 @@ namespace Ryujinx.HLE.FileSystem } } - private SortedList<ulong, AocItem> _aocData { get; } + private SortedList<ulong, AocItem> AocData { get; } - private VirtualFileSystem _virtualFileSystem; + private readonly VirtualFileSystem _virtualFileSystem; private readonly object _lock = new(); public ContentManager(VirtualFileSystem virtualFileSystem) { _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>(); - _locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>(); + _locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>(); _sharedFontTitleDictionary = new Dictionary<string, ulong> { @@ -66,7 +66,7 @@ namespace Ryujinx.HLE.FileSystem { "FontExtendedChineseSimplified", 0x0100000000000814 }, { "FontKorean", 0x0100000000000812 }, { "FontChineseTraditional", 0x0100000000000813 }, - { "FontNintendoExtended", 0x0100000000000810 } + { "FontNintendoExtended", 0x0100000000000810 }, }; _systemTitlesNameDictionary = new Dictionary<ulong, string>() @@ -86,12 +86,12 @@ namespace Ryujinx.HLE.FileSystem { "FontExtendedChineseSimplified", "nintendo_udsg-r_ext_zh-cn_003.bfttf" }, { "FontKorean", "nintendo_udsg-r_ko_003.bfttf" }, { "FontChineseTraditional", "nintendo_udjxh-db_zh-tw_003.bfttf" }, - { "FontNintendoExtended", "nintendo_ext_003.bfttf" } + { "FontNintendoExtended", "nintendo_ext_003.bfttf" }, }; _virtualFileSystem = virtualFileSystem; - _aocData = new SortedList<ulong, AocItem>(); + AocData = new SortedList<ulong, AocItem>(); } public void LoadEntries(Switch device = null) @@ -99,18 +99,18 @@ namespace Ryujinx.HLE.FileSystem lock (_lock) { _contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>(); - _locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>(); + _locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>(); foreach (StorageId storageId in Enum.GetValues<StorageId>()) { - string contentDirectory = null; - string contentPathString = null; + string contentDirectory = null; + string contentPathString = null; string registeredDirectory = null; try { - contentPathString = ContentPath.GetContentPath(storageId); - contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString); + contentPathString = ContentPath.GetContentPath(storageId); + contentDirectory = ContentPath.GetRealPath(contentPathString); registeredDirectory = Path.Combine(contentDirectory, "registered"); } catch (NotSupportedException) @@ -120,7 +120,7 @@ namespace Ryujinx.HLE.FileSystem Directory.CreateDirectory(registeredDirectory); - LinkedList<LocationEntry> locationList = new LinkedList<LocationEntry>(); + LinkedList<LocationEntry> locationList = new(); void AddEntry(LocationEntry entry) { @@ -133,24 +133,19 @@ namespace Ryujinx.HLE.FileSystem { string ncaName = new DirectoryInfo(directoryPath).Name.Replace(".nca", string.Empty); - using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0])) - { - Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()); + using FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]); + Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage()); - string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); + string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); - // Change path format to switch's - switchPath = switchPath.Replace('\\', '/'); + // Change path format to switch's + switchPath = switchPath.Replace('\\', '/'); - LocationEntry entry = new LocationEntry(switchPath, - 0, - nca.Header.TitleId, - nca.Header.ContentType); + LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType); - AddEntry(entry); + AddEntry(entry); - _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); - } + _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); } } @@ -160,24 +155,19 @@ namespace Ryujinx.HLE.FileSystem { string ncaName = Path.GetFileNameWithoutExtension(filePath); - using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()); + using FileStream ncaFile = new(filePath, FileMode.Open, FileAccess.Read); + Nca nca = new(_virtualFileSystem.KeySet, ncaFile.AsStorage()); - string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); + string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar); - // Change path format to switch's - switchPath = switchPath.Replace('\\', '/'); + // Change path format to switch's + switchPath = switchPath.Replace('\\', '/'); - LocationEntry entry = new LocationEntry(switchPath, - 0, - nca.Header.TitleId, - nca.Header.ContentType); + LocationEntry entry = new(switchPath, 0, nca.Header.TitleId, nca.Header.ContentType); - AddEntry(entry); + AddEntry(entry); - _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); - } + _contentDictionary.Add((nca.Header.TitleId, nca.Header.ContentType), ncaName); } } @@ -186,10 +176,7 @@ namespace Ryujinx.HLE.FileSystem _locationEntries.Remove(storageId); } - if (!_locationEntries.ContainsKey(storageId)) - { - _locationEntries.Add(storageId, locationList); - } + _locationEntries.TryAdd(storageId, locationList); } if (device != null) @@ -239,7 +226,7 @@ namespace Ryujinx.HLE.FileSystem public void AddAocItem(ulong titleId, string containerPath, string ncaPath, bool mergedToContainer = false) { // TODO: Check Aoc version. - if (!_aocData.TryAdd(titleId, new AocItem(containerPath, ncaPath))) + if (!AocData.TryAdd(titleId, new AocItem(containerPath, ncaPath))) { Logger.Warning?.Print(LogClass.Application, $"Duplicate AddOnContent detected. TitleId {titleId:X16}"); } @@ -249,7 +236,7 @@ namespace Ryujinx.HLE.FileSystem if (!mergedToContainer) { - using FileStream fileStream = File.OpenRead(containerPath); + using FileStream fileStream = File.OpenRead(containerPath); using PartitionFileSystem partitionFileSystem = new(fileStream.AsStorage()); _virtualFileSystem.ImportTickets(partitionFileSystem); @@ -257,17 +244,17 @@ namespace Ryujinx.HLE.FileSystem } } - public void ClearAocData() => _aocData.Clear(); + public void ClearAocData() => AocData.Clear(); - public int GetAocCount() => _aocData.Count; + public int GetAocCount() => AocData.Count; - public IList<ulong> GetAocTitleIds() => _aocData.Select(e => e.Key).ToList(); + public IList<ulong> GetAocTitleIds() => AocData.Select(e => e.Key).ToList(); public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage, IntegrityCheckLevel integrityCheckLevel) { aocStorage = null; - if (_aocData.TryGetValue(aocTitleId, out AocItem aoc)) + if (AocData.TryGetValue(aocTitleId, out AocItem aoc)) { var file = new FileStream(aoc.ContainerPath, FileMode.Open, FileAccess.Read); using var ncaFile = new UniqueRef<IFile>(); @@ -307,7 +294,7 @@ namespace Ryujinx.HLE.FileSystem { lock (_lock) { - LinkedList<LocationEntry> locationList = _locationEntries[storageId]; + LinkedList<LocationEntry> locationList = _locationEntries[storageId]; LinkedListNode<LocationEntry> locationEntry = locationList.First; while (locationEntry != null) @@ -331,7 +318,7 @@ namespace Ryujinx.HLE.FileSystem if (_contentDictionary.ContainsValue(ncaId)) { var content = _contentDictionary.FirstOrDefault(x => x.Value == ncaId); - ulong titleId = content.Key.Item1; + ulong titleId = content.Key.titleId; NcaContentType contentType = content.Key.type; StorageId storage = GetInstalledStorage(titleId, contentType, storageId); @@ -403,19 +390,17 @@ namespace Ryujinx.HLE.FileSystem return false; } - string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath); + string installedPath = VirtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath); if (!string.IsNullOrWhiteSpace(installedPath)) { if (File.Exists(installedPath)) { - using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read)) - { - Nca nca = new Nca(_virtualFileSystem.KeySet, file.AsStorage()); - bool contentCheck = nca.Header.ContentType == contentType; + using FileStream file = new(installedPath, FileMode.Open, FileAccess.Read); + Nca nca = new(_virtualFileSystem.KeySet, file.AsStorage()); + bool contentCheck = nca.Header.ContentType == contentType; - return contentCheck; - } + return contentCheck; } } @@ -426,9 +411,9 @@ namespace Ryujinx.HLE.FileSystem { LinkedList<LocationEntry> locationList = null; - if (_locationEntries.ContainsKey(storageId)) + if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry)) { - locationList = _locationEntries[storageId]; + locationList = locationEntry; } if (locationList != null) @@ -446,9 +431,9 @@ namespace Ryujinx.HLE.FileSystem { LinkedList<LocationEntry> locationList = null; - if (_locationEntries.ContainsKey(storageId)) + if (_locationEntries.TryGetValue(storageId, out LinkedList<LocationEntry> locationEntry)) { - locationList = _locationEntries[storageId]; + locationList = locationEntry; } if (locationList != null) @@ -487,10 +472,10 @@ namespace Ryujinx.HLE.FileSystem public void InstallFirmware(string firmwareSource) { - string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem); - string contentDirectory = ContentPath.GetRealPath(_virtualFileSystem, contentPathString); + string contentPathString = ContentPath.GetContentPath(StorageId.BuiltInSystem); + string contentDirectory = ContentPath.GetRealPath(contentPathString); string registeredDirectory = Path.Combine(contentDirectory, "registered"); - string temporaryDirectory = Path.Combine(contentDirectory, "temp"); + string temporaryDirectory = Path.Combine(contentDirectory, "temp"); if (Directory.Exists(temporaryDirectory)) { @@ -510,28 +495,27 @@ namespace Ryujinx.HLE.FileSystem throw new FileNotFoundException("Firmware file does not exist."); } - FileInfo info = new FileInfo(firmwareSource); + FileInfo info = new(firmwareSource); - using (FileStream file = File.OpenRead(firmwareSource)) - { - switch (info.Extension) - { - case ".zip": - using (ZipArchive archive = ZipFile.OpenRead(firmwareSource)) - { - InstallFromZip(archive, temporaryDirectory); - } - break; - case ".xci": - Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); - InstallFromCart(xci, temporaryDirectory); - break; - default: - throw new InvalidFirmwarePackageException("Input file is not a valid firmware package"); - } + using FileStream file = File.OpenRead(firmwareSource); - FinishInstallation(temporaryDirectory, registeredDirectory); + switch (info.Extension) + { + case ".zip": + using (ZipArchive archive = ZipFile.OpenRead(firmwareSource)) + { + InstallFromZip(archive, temporaryDirectory); + } + break; + case ".xci": + Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage()); + InstallFromCart(xci, temporaryDirectory); + break; + default: + throw new InvalidFirmwarePackageException("Input file is not a valid firmware package"); } + + FinishInstallation(temporaryDirectory, registeredDirectory); } private void FinishInstallation(string temporaryDirectory, string registeredDirectory) @@ -555,7 +539,7 @@ namespace Ryujinx.HLE.FileSystem { foreach (var entry in filesystem.EnumerateEntries("/", "*.nca")) { - Nca nca = new Nca(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage()); + Nca nca = new(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage()); SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory); } @@ -575,52 +559,47 @@ namespace Ryujinx.HLE.FileSystem } } - private void InstallFromZip(ZipArchive archive, string temporaryDirectory) + private static void InstallFromZip(ZipArchive archive, string temporaryDirectory) { - using (archive) + foreach (var entry in archive.Entries) { - foreach (var entry in archive.Entries) + if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00")) { - if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00")) - { - // Clean up the name and get the NcaId + // Clean up the name and get the NcaId - string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/'); + string[] pathComponents = entry.FullName.Replace(".cnmt", "").Split('/'); - string ncaId = pathComponents[pathComponents.Length - 1]; + string ncaId = pathComponents[^1]; - // If this is a fragmented nca, we need to get the previous element.GetZip - if (ncaId.Equals("00")) - { - ncaId = pathComponents[pathComponents.Length - 2]; - } + // If this is a fragmented nca, we need to get the previous element.GetZip + if (ncaId.Equals("00")) + { + ncaId = pathComponents[^2]; + } - if (ncaId.Contains(".nca")) - { - string newPath = Path.Combine(temporaryDirectory, ncaId); + if (ncaId.Contains(".nca")) + { + string newPath = Path.Combine(temporaryDirectory, ncaId); - Directory.CreateDirectory(newPath); + Directory.CreateDirectory(newPath); - entry.ExtractToFile(Path.Combine(newPath, "00")); - } + entry.ExtractToFile(Path.Combine(newPath, "00")); } } } } - public void SaveNca(Nca nca, string ncaId, string temporaryDirectory) + public static void SaveNca(Nca nca, string ncaId, string temporaryDirectory) { string newPath = Path.Combine(temporaryDirectory, ncaId + ".nca"); Directory.CreateDirectory(newPath); - using (FileStream file = File.Create(Path.Combine(newPath, "00"))) - { - nca.BaseStorage.AsStream().CopyTo(file); - } + using FileStream file = File.Create(Path.Combine(newPath, "00")); + nca.BaseStorage.AsStream().CopyTo(file); } - private IFile OpenPossibleFragmentedFile(IFileSystem filesystem, string path, OpenMode mode) + private static IFile OpenPossibleFragmentedFile(IFileSystem filesystem, string path, OpenMode mode) { using var file = new UniqueRef<IFile>(); @@ -636,14 +615,12 @@ namespace Ryujinx.HLE.FileSystem return file.Release(); } - private Stream GetZipStream(ZipArchiveEntry entry) + private static Stream GetZipStream(ZipArchiveEntry entry) { MemoryStream dest = MemoryStreamManager.Shared.GetStream(); - using (Stream src = entry.Open()) - { - src.CopyTo(dest); - } + using Stream src = entry.Open(); + src.CopyTo(dest); return dest; } @@ -659,7 +636,7 @@ namespace Ryujinx.HLE.FileSystem throw new MissingKeyException("HeaderKey is empty. Cannot decrypt NCA headers."); } - Dictionary<ulong, List<(NcaContentType type, string path)>> updateNcas = new Dictionary<ulong, List<(NcaContentType, string)>>(); + Dictionary<ulong, List<(NcaContentType type, string path)>> updateNcas = new(); if (Directory.Exists(firmwarePackage)) { @@ -671,33 +648,32 @@ namespace Ryujinx.HLE.FileSystem throw new FileNotFoundException("Firmware file does not exist."); } - FileInfo info = new FileInfo(firmwarePackage); + FileInfo info = new(firmwarePackage); + + using FileStream file = File.OpenRead(firmwarePackage); - using (FileStream file = File.OpenRead(firmwarePackage)) + switch (info.Extension) { - switch (info.Extension) - { - case ".zip": - using (ZipArchive archive = ZipFile.OpenRead(firmwarePackage)) - { - return VerifyAndGetVersionZip(archive); - } - case ".xci": - Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); + case ".zip": + using (ZipArchive archive = ZipFile.OpenRead(firmwarePackage)) + { + return VerifyAndGetVersionZip(archive); + } + case ".xci": + Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage()); - if (xci.HasPartition(XciPartitionType.Update)) - { - XciPartition partition = xci.OpenPartition(XciPartitionType.Update); + if (xci.HasPartition(XciPartitionType.Update)) + { + XciPartition partition = xci.OpenPartition(XciPartitionType.Update); - return VerifyAndGetVersion(partition); - } - else - { - throw new InvalidFirmwarePackageException("Update not found in xci file."); - } - default: - break; - } + return VerifyAndGetVersion(partition); + } + else + { + throw new InvalidFirmwarePackageException("Update not found in xci file."); + } + default: + break; } SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory) @@ -713,21 +689,19 @@ namespace Ryujinx.HLE.FileSystem { if (entry.FullName.EndsWith(".nca") || entry.FullName.EndsWith(".nca/00")) { - using (Stream ncaStream = GetZipStream(entry)) - { - IStorage storage = ncaStream.AsStorage(); + using Stream ncaStream = GetZipStream(entry); + IStorage storage = ncaStream.AsStorage(); - Nca nca = new Nca(_virtualFileSystem.KeySet, storage); + Nca nca = new(_virtualFileSystem.KeySet, storage); - if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem)) - { - updateNcasItem.Add((nca.Header.ContentType, entry.FullName)); - } - else - { - updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>()); - updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName)); - } + if (updateNcas.TryGetValue(nca.Header.TitleId, out var updateNcasItem)) + { + updateNcasItem.Add((nca.Header.ContentType, entry.FullName)); + } + else + { + updateNcas.Add(nca.Header.TitleId, new List<(NcaContentType, string)>()); + updateNcas[nca.Header.TitleId].Add((nca.Header.ContentType, entry.FullName)); } } } @@ -742,7 +716,7 @@ namespace Ryujinx.HLE.FileSystem using (Stream ncaStream = GetZipStream(fileEntry)) { - Nca metaNca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage()); + Nca metaNca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage()); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); @@ -772,18 +746,16 @@ namespace Ryujinx.HLE.FileSystem { string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path; - using (Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry))) - { - Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage()); + using Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry)); + Nca nca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage()); - var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); + var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); - using var systemVersionFile = new UniqueRef<IFile>(); + using var systemVersionFile = new UniqueRef<IFile>(); - if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) - { - systemVersion = new SystemVersion(systemVersionFile.Get.AsStream()); - } + if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) + { + systemVersion = new SystemVersion(systemVersionFile.Get.AsStream()); } } @@ -804,43 +776,39 @@ namespace Ryujinx.HLE.FileSystem continue; } - ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath); + ZipArchiveEntry metaZipEntry = archive.GetEntry(metaPath); ZipArchiveEntry contentZipEntry = archive.GetEntry(contentPath); - using (Stream metaNcaStream = GetZipStream(metaZipEntry)) - { - using (Stream contentNcaStream = GetZipStream(contentZipEntry)) - { - Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage()); + using Stream metaNcaStream = GetZipStream(metaZipEntry); + using Stream contentNcaStream = GetZipStream(contentZipEntry); + Nca metaNca = new(_virtualFileSystem.KeySet, metaNcaStream.AsStorage()); - IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); + IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); - string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath; + string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath; - using var metaFile = new UniqueRef<IFile>(); + using var metaFile = new UniqueRef<IFile>(); - if (fs.OpenFile(ref metaFile.Ref, cnmtPath.ToU8Span(), OpenMode.Read).IsSuccess()) - { - var meta = new Cnmt(metaFile.Get.AsStream()); + if (fs.OpenFile(ref metaFile.Ref, cnmtPath.ToU8Span(), OpenMode.Read).IsSuccess()) + { + var meta = new Cnmt(metaFile.Get.AsStream()); - IStorage contentStorage = contentNcaStream.AsStorage(); - if (contentStorage.GetSize(out long size).IsSuccess()) - { - byte[] contentData = new byte[size]; + IStorage contentStorage = contentNcaStream.AsStorage(); + if (contentStorage.GetSize(out long size).IsSuccess()) + { + byte[] contentData = new byte[size]; - Span<byte> content = new Span<byte>(contentData); + Span<byte> content = new(contentData); - contentStorage.Read(0, content); + contentStorage.Read(0, content); - Span<byte> hash = new Span<byte>(new byte[32]); + Span<byte> hash = new(new byte[32]); - LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash); + LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash); - if (LibHac.Common.Utilities.ArraysEqual(hash.ToArray(), meta.ContentEntries[0].Hash)) - { - updateNcas.Remove(metaEntry.TitleId); - } - } + if (LibHac.Common.Utilities.ArraysEqual(hash.ToArray(), meta.ContentEntries[0].Hash)) + { + updateNcas.Remove(metaEntry.TitleId); } } } @@ -853,9 +821,9 @@ namespace Ryujinx.HLE.FileSystem foreach (var entry in updateNcas) { - foreach (var nca in entry.Value) + foreach (var (type, path) in entry.Value) { - extraNcas += nca.path + Environment.NewLine; + extraNcas += path + Environment.NewLine; } } @@ -880,7 +848,7 @@ namespace Ryujinx.HLE.FileSystem { IStorage ncaStorage = OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage(); - Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStorage); + Nca nca = new(_virtualFileSystem.KeySet, ncaStorage); if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta) { @@ -936,8 +904,8 @@ namespace Ryujinx.HLE.FileSystem { if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry)) { - var metaNcaEntry = ncaEntry.Find(x => x.type == NcaContentType.Meta); - string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path; + string metaNcaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path; + string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path; // Nintendo in 9.0.0, removed PPC and only kept the meta nca of it. // This is a perfect valid case, so we should just ignore the missing content nca and continue. @@ -948,10 +916,10 @@ namespace Ryujinx.HLE.FileSystem continue; } - IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaEntry.path, OpenMode.Read).AsStorage(); + IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaPath, OpenMode.Read).AsStorage(); IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage(); - Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaStorage); + Nca metaNca = new(_virtualFileSystem.KeySet, metaStorage); IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); @@ -967,11 +935,11 @@ namespace Ryujinx.HLE.FileSystem { byte[] contentData = new byte[size]; - Span<byte> content = new Span<byte>(contentData); + Span<byte> content = new(contentData); contentStorage.Read(0, content); - Span<byte> hash = new Span<byte>(new byte[32]); + Span<byte> hash = new(new byte[32]); LibHac.Crypto.Sha256.GenerateSha256Hash(content, hash); @@ -1017,24 +985,21 @@ namespace Ryujinx.HLE.FileSystem { if (entry.ContentType == NcaContentType.Data) { - var path = _virtualFileSystem.SwitchPathToSystemPath(entry.ContentPath); + var path = VirtualFileSystem.SwitchPathToSystemPath(entry.ContentPath); - using (FileStream fileStream = File.OpenRead(path)) - { - Nca nca = new Nca(_virtualFileSystem.KeySet, fileStream.AsStorage()); + using FileStream fileStream = File.OpenRead(path); + Nca nca = new(_virtualFileSystem.KeySet, fileStream.AsStorage()); - if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) - { - var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); + if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) + { + var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); - using var systemVersionFile = new UniqueRef<IFile>(); + using var systemVersionFile = new UniqueRef<IFile>(); - if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) - { - return new SystemVersion(systemVersionFile.Get.AsStream()); - } + if (romfs.OpenFile(ref systemVersionFile.Ref, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) + { + return new SystemVersion(systemVersionFile.Get.AsStream()); } - } } } |