From 1d8da1833429acd4a9cbea7597c0699c2e3c80bf Mon Sep 17 00:00:00 2001 From: Thog Date: Fri, 24 Jan 2020 17:01:21 +0100 Subject: [PATCH] Make VirtualFileSystem only instanciable once (#901) This fix a regression caused by #888 on temporary saves for SNES Online. (and probably other games) --- Ryujinx.HLE/FileSystem/VirtualFileSystem.cs | 16 ++++++++++++++- Ryujinx/Ui/ApplicationLibrary.cs | 18 ++++++++--------- Ryujinx/Ui/GameTableContextMenu.cs | 22 ++++++++++----------- Ryujinx/Ui/MainWindow.cs | 8 ++++---- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs index 070ec3bc..884f4197 100644 --- a/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs +++ b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs @@ -20,12 +20,14 @@ namespace Ryujinx.HLE.FileSystem public static string SystemNandPath = Path.Combine(NandPath, "system"); public static string UserNandPath = Path.Combine(NandPath, "user"); + private static bool _isInitialized = false; + public Keyset KeySet { get; private set; } public FileSystemServer FsServer { get; private set; } public FileSystemClient FsClient { get; private set; } public EmulatedGameCard GameCard { get; private set; } - public VirtualFileSystem() + private VirtualFileSystem() { Reload(); } @@ -272,5 +274,17 @@ namespace Ryujinx.HLE.FileSystem Unload(); } } + + public static VirtualFileSystem CreateInstance() + { + if (_isInitialized) + { + throw new InvalidOperationException($"VirtualFileSystem can only be instanciated once!"); + } + + _isInitialized = true; + + return new VirtualFileSystem(); + } } } \ No newline at end of file diff --git a/Ryujinx/Ui/ApplicationLibrary.cs b/Ryujinx/Ui/ApplicationLibrary.cs index 3984b78d..9d0f2617 100644 --- a/Ryujinx/Ui/ApplicationLibrary.cs +++ b/Ryujinx/Ui/ApplicationLibrary.cs @@ -34,15 +34,15 @@ namespace Ryujinx.Ui private static readonly byte[] _nroIcon = GetResourceBytes("Ryujinx.Ui.assets.NROIcon.png"); private static readonly byte[] _nsoIcon = GetResourceBytes("Ryujinx.Ui.assets.NSOIcon.png"); - private static Keyset _keySet; - private static Language _desiredTitleLanguage; + private static VirtualFileSystem _virtualFileSystem; + private static Language _desiredTitleLanguage; public static void LoadApplications(List appDirs, VirtualFileSystem virtualFileSystem, Language desiredTitleLanguage) { int numApplicationsFound = 0; int numApplicationsLoaded = 0; - _keySet = virtualFileSystem.KeySet; + _virtualFileSystem = virtualFileSystem; _desiredTitleLanguage = desiredTitleLanguage; // Builds the applications list with paths to found applications @@ -77,7 +77,7 @@ namespace Ryujinx.Ui { nsp.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure(); - Nca nca = new Nca(_keySet, ncaFile.AsStorage()); + Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()); int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program); if (nca.Header.ContentType == NcaContentType.Program && !nca.Header.GetFsHeader(dataIndex).IsPatchSection()) @@ -103,7 +103,7 @@ namespace Ryujinx.Ui { try { - Nca nca = new Nca(_keySet, new FileStream(app, FileMode.Open, FileAccess.Read).AsStorage()); + Nca nca = new Nca(_virtualFileSystem.KeySet, new FileStream(app, FileMode.Open, FileAccess.Read).AsStorage()); int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program); if (nca.Header.ContentType != NcaContentType.Program || nca.Header.GetFsHeader(dataIndex).IsPatchSection()) @@ -145,7 +145,7 @@ namespace Ryujinx.Ui if (Path.GetExtension(applicationPath) == ".xci") { - Xci xci = new Xci(_keySet, file.AsStorage()); + Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); pfs = xci.OpenPartition(XciPartitionType.Secure); } @@ -409,7 +409,7 @@ namespace Ryujinx.Ui { Ticket ticket = new Ticket(ticketFile.AsStream()); - _keySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(_keySet))); + _virtualFileSystem.KeySet.ExternalKeySet.Add(new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(_virtualFileSystem.KeySet))); } } @@ -418,7 +418,7 @@ namespace Ryujinx.Ui { pfs.OpenFile(out IFile ncaFile, fileEntry.FullPath, OpenMode.Read).ThrowIfFailure(); - Nca nca = new Nca(_keySet, ncaFile.AsStorage()); + Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()); if (nca.Header.ContentType == NcaContentType.Control) { @@ -432,7 +432,7 @@ namespace Ryujinx.Ui internal static ApplicationMetadata LoadAndSaveMetaData(string titleId, Action modifyFunction = null) { - string metadataFolder = Path.Combine(new VirtualFileSystem().GetBasePath(), "games", titleId, "gui"); + string metadataFolder = Path.Combine(_virtualFileSystem.GetBasePath(), "games", titleId, "gui"); string metadataFile = Path.Combine(metadataFolder, "metadata.json"); IJsonFormatterResolver resolver = CompositeResolver.Create(new[] { StandardResolver.AllowPrivateSnakeCase }); diff --git a/Ryujinx/Ui/GameTableContextMenu.cs b/Ryujinx/Ui/GameTableContextMenu.cs index e74d1828..196799ea 100644 --- a/Ryujinx/Ui/GameTableContextMenu.cs +++ b/Ryujinx/Ui/GameTableContextMenu.cs @@ -18,7 +18,7 @@ namespace Ryujinx.Ui { private static ListStore _gameTableStore; private static TreeIter _rowIter; - private FileSystemClient _fsClient; + private VirtualFileSystem _virtualFileSystem; #pragma warning disable CS0649 #pragma warning disable IDE0044 @@ -26,18 +26,18 @@ namespace Ryujinx.Ui #pragma warning restore CS0649 #pragma warning restore IDE0044 - public GameTableContextMenu(ListStore gameTableStore, TreeIter rowIter, FileSystemClient fsClient) - : this(new Builder("Ryujinx.Ui.GameTableContextMenu.glade"), gameTableStore, rowIter, fsClient) { } + public GameTableContextMenu(ListStore gameTableStore, TreeIter rowIter, VirtualFileSystem virtualFileSystem) + : this(new Builder("Ryujinx.Ui.GameTableContextMenu.glade"), gameTableStore, rowIter, virtualFileSystem) { } - private GameTableContextMenu(Builder builder, ListStore gameTableStore, TreeIter rowIter, FileSystemClient fsClient) : base(builder.GetObject("_contextMenu").Handle) + private GameTableContextMenu(Builder builder, ListStore gameTableStore, TreeIter rowIter, VirtualFileSystem virtualFileSystem) : base(builder.GetObject("_contextMenu").Handle) { builder.Autoconnect(this); _openSaveDir.Activated += OpenSaveDir_Clicked; - _gameTableStore = gameTableStore; - _rowIter = rowIter; - _fsClient = fsClient; + _gameTableStore = gameTableStore; + _rowIter = rowIter; + _virtualFileSystem = virtualFileSystem; } //Events @@ -76,7 +76,7 @@ namespace Ryujinx.Ui filter.SetUserId(new UserId(1, 0)); filter.SetTitleId(new TitleId(titleId)); - Result result = _fsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); + Result result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); if (result == ResultFs.TargetNotFound) { @@ -95,7 +95,7 @@ namespace Ryujinx.Ui return false; } - result = _fsClient.CreateSaveData(new TitleId(titleId), new UserId(1, 0), new TitleId(titleId), 0, 0, 0); + result = _virtualFileSystem.FsClient.CreateSaveData(new TitleId(titleId), new UserId(1, 0), new TitleId(titleId), 0, 0, 0); if (result.IsFailure()) { @@ -105,7 +105,7 @@ namespace Ryujinx.Ui } // Try to find the savedata again after creating it - result = _fsClient.FindSaveDataWithFilter(out saveDataInfo, SaveDataSpaceId.User, ref filter); + result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out saveDataInfo, SaveDataSpaceId.User, ref filter); } if (result.IsSuccess()) @@ -122,7 +122,7 @@ namespace Ryujinx.Ui private string GetSaveDataDirectory(ulong saveDataId) { - string saveRootPath = System.IO.Path.Combine(new VirtualFileSystem().GetNandPath(), $"user/save/{saveDataId:x16}"); + string saveRootPath = System.IO.Path.Combine(_virtualFileSystem.GetNandPath(), $"user/save/{saveDataId:x16}"); if (!Directory.Exists(saveRootPath)) { diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index f9f36576..02fd801b 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -83,7 +83,7 @@ namespace Ryujinx.Ui End(null); } - _virtualFileSystem = new VirtualFileSystem(); + _virtualFileSystem = VirtualFileSystem.CreateInstance(); _contentManager = new ContentManager(_virtualFileSystem); if (migrationNeeded) @@ -461,7 +461,7 @@ namespace Ryujinx.Ui if (treeIter.UserData == IntPtr.Zero) return; - GameTableContextMenu contextMenu = new GameTableContextMenu(_tableStore, treeIter, _virtualFileSystem.FsClient); + GameTableContextMenu contextMenu = new GameTableContextMenu(_tableStore, treeIter, _virtualFileSystem); contextMenu.ShowAll(); contextMenu.PopupAtPointer(null); } @@ -502,7 +502,7 @@ namespace Ryujinx.Ui { Process.Start(new ProcessStartInfo() { - FileName = new VirtualFileSystem().GetBasePath(), + FileName = _virtualFileSystem.GetBasePath(), UseShellExecute = true, Verb = "open" }); @@ -738,7 +738,7 @@ namespace Ryujinx.Ui private void Update_Pressed(object sender, EventArgs args) { - string ryuUpdater = System.IO.Path.Combine(new VirtualFileSystem().GetBasePath(), "RyuUpdater.exe"); + string ryuUpdater = System.IO.Path.Combine(_virtualFileSystem.GetBasePath(), "RyuUpdater.exe"); try {