aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs')
-rw-r--r--src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs63
1 files changed, 51 insertions, 12 deletions
diff --git a/src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs b/src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
index 51918eea..2f7f14f1 100644
--- a/src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
+++ b/src/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
@@ -4,12 +4,15 @@ using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Ns;
+using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem;
+using Ryujinx.HLE.Loaders.Processes.Extensions;
using Ryujinx.Ui.App.Common;
+using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Widgets;
using System;
using System.Collections.Generic;
@@ -24,7 +27,7 @@ namespace Ryujinx.Ui.Windows
{
private readonly MainWindow _parent;
private readonly VirtualFileSystem _virtualFileSystem;
- private readonly string _titleId;
+ private readonly ApplicationData _title;
private readonly string _updateJsonPath;
private TitleUpdateMetadata _titleUpdateWindowData;
@@ -38,17 +41,17 @@ namespace Ryujinx.Ui.Windows
[GUI] RadioButton _noUpdateRadioButton;
#pragma warning restore CS0649, IDE0044
- public TitleUpdateWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, string titleId, string titleName) : this(new Builder("Ryujinx.Ui.Windows.TitleUpdateWindow.glade"), parent, virtualFileSystem, titleId, titleName) { }
+ public TitleUpdateWindow(MainWindow parent, VirtualFileSystem virtualFileSystem, ApplicationData applicationData) : this(new Builder("Ryujinx.Ui.Windows.TitleUpdateWindow.glade"), parent, virtualFileSystem, applicationData) { }
- private TitleUpdateWindow(Builder builder, MainWindow parent, VirtualFileSystem virtualFileSystem, string titleId, string titleName) : base(builder.GetRawOwnedObject("_titleUpdateWindow"))
+ private TitleUpdateWindow(Builder builder, MainWindow parent, VirtualFileSystem virtualFileSystem, ApplicationData applicationData) : base(builder.GetRawOwnedObject("_titleUpdateWindow"))
{
_parent = parent;
builder.Autoconnect(this);
- _titleId = titleId;
+ _title = applicationData;
_virtualFileSystem = virtualFileSystem;
- _updateJsonPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleId, "updates.json");
+ _updateJsonPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, applicationData.IdString, "updates.json");
_radioButtonToPathDictionary = new Dictionary<RadioButton, string>();
try
@@ -64,7 +67,10 @@ namespace Ryujinx.Ui.Windows
};
}
- _baseTitleInfoLabel.Text = $"Updates Available for {titleName} [{titleId.ToUpper()}]";
+ _baseTitleInfoLabel.Text = $"Updates Available for {applicationData.Name} [{applicationData.IdString}]";
+
+ // Try to get updates from PFS first
+ AddUpdate(_title.Path, true);
foreach (string path in _titleUpdateWindowData.Paths)
{
@@ -84,18 +90,41 @@ namespace Ryujinx.Ui.Windows
}
}
- private void AddUpdate(string path)
+ private void AddUpdate(string path, bool ignoreNotFound = false)
{
if (File.Exists(path))
{
+ IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
+ ? IntegrityCheckLevel.ErrorOnInvalid
+ : IntegrityCheckLevel.None;
+
using FileStream file = new(path, FileMode.Open, FileAccess.Read);
- PartitionFileSystem nsp = new();
- nsp.Initialize(file.AsStorage()).ThrowIfFailure();
+ IFileSystem pfs;
try
{
- (Nca patchNca, Nca controlNca) = ApplicationLibrary.GetGameUpdateDataFromPartition(_virtualFileSystem, nsp, _titleId, 0);
+ if (System.IO.Path.GetExtension(path).ToLower() == ".xci")
+ {
+ pfs = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure);
+ }
+ else
+ {
+ var pfsTemp = new PartitionFileSystem();
+ pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
+ pfs = pfsTemp;
+ }
+
+ Dictionary<ulong, ContentCollection> updates = pfs.GetUpdateData(_virtualFileSystem, checkLevel);
+
+ Nca patchNca = null;
+ Nca controlNca = null;
+
+ if (updates.TryGetValue(_title.Id, out ContentCollection update))
+ {
+ patchNca = update.GetNcaByType(_virtualFileSystem.KeySet, LibHac.Ncm.ContentType.Program);
+ controlNca = update.GetNcaByType(_virtualFileSystem.KeySet, LibHac.Ncm.ContentType.Control);
+ }
if (controlNca != null && patchNca != null)
{
@@ -106,7 +135,14 @@ namespace Ryujinx.Ui.Windows
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
- RadioButton radioButton = new($"Version {controlData.DisplayVersionString.ToString()} - {path}");
+ string radioLabel = $"Version {controlData.DisplayVersionString.ToString()} - {path}";
+
+ if (System.IO.Path.GetExtension(path).ToLower() == ".xci")
+ {
+ radioLabel = "Bundled: " + radioLabel;
+ }
+
+ RadioButton radioButton = new(radioLabel);
radioButton.JoinGroup(_noUpdateRadioButton);
_availableUpdatesBox.Add(radioButton);
@@ -117,7 +153,10 @@ namespace Ryujinx.Ui.Windows
}
else
{
- GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!");
+ if (!ignoreNotFound)
+ {
+ GtkDialog.CreateErrorDialog("The specified file does not contain an update for the selected title!");
+ }
}
}
catch (Exception exception)