aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTSRBerry <20988865+TSRBerry@users.noreply.github.com>2024-01-13 11:45:38 +0100
committerGitHub <noreply@github.com>2024-01-13 11:45:38 +0100
commit7e58b21f3d1b0ef69121b66e91488e1529ee5719 (patch)
tree97c7e98b5f94dc737983da405161c3c324fb2b8c
parent4fbc978e7341de5aea9004753433ce8ecba309f9 (diff)
Fix Amiibo regression and some minor code improvements (#6107)1.1.1108
* Remove redundant code and fix small issues * Log amiibo exceptions * Add more checks when getting Amiibo data * Fall back to online data if local file is inaccessible * Make dotnet format happy
-rw-r--r--src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs84
-rw-r--r--src/Ryujinx/Ui/Windows/AmiiboWindow.cs106
2 files changed, 135 insertions, 55 deletions
diff --git a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
index c41e8bcc..0e0d858a 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
@@ -17,6 +17,7 @@ using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
+using System.Text.Json;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.ViewModels
@@ -188,17 +189,25 @@ namespace Ryujinx.Ava.UI.ViewModels
_httpClient.Dispose();
}
- private bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
+ private static bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
{
+ if (string.IsNullOrEmpty(json))
+ {
+ amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
+
+ return false;
+ }
+
try
{
- amiiboJson = JsonHelper.Deserialize<AmiiboJson>(json, _serializerContext.AmiiboJson);
+ amiiboJson = JsonHelper.Deserialize(json, _serializerContext.AmiiboJson);
return true;
}
- catch
+ catch (JsonException exception)
{
- amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
+ Logger.Error?.Print(LogClass.Application, $"Unable to deserialize amiibo data: {exception}");
+ amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
return false;
}
@@ -208,27 +217,41 @@ namespace Ryujinx.Ava.UI.ViewModels
{
bool localIsValid = false;
bool remoteIsValid = false;
- AmiiboJson amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
+ AmiiboJson amiiboJson = new();
try
{
- localIsValid = TryGetAmiiboJson(File.ReadAllText(_amiiboJsonPath), out amiiboJson);
+ try
+ {
+ if (File.Exists(_amiiboJsonPath))
+ {
+ localIsValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson);
+ }
+ }
+ catch (Exception exception)
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}");
+ }
if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated))
{
remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson);
}
}
- catch
+ catch (Exception exception)
{
if (!(localIsValid || remoteIsValid))
{
+ Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
+
// Neither local or remote files are valid JSON, close window.
ShowInfoDialog();
Close();
}
else if (!remoteIsValid)
{
+ Logger.Warning?.Print(LogClass.Application, $"Couldn't update amiibo data: {exception}");
+
// Only the local file is valid, the local one should be used
// but the user should be warned.
ShowInfoDialog();
@@ -388,11 +411,18 @@ namespace Ryujinx.Ava.UI.ViewModels
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
{
- HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
+ try
+ {
+ HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
- if (response.IsSuccessStatusCode)
+ if (response.IsSuccessStatusCode)
+ {
+ return response.Content.Headers.LastModified != oldLastModified;
+ }
+ }
+ catch (HttpRequestException exception)
{
- return response.Content.Headers.LastModified != oldLastModified;
+ Logger.Error?.Print(LogClass.Application, $"Unable to check for amiibo data updates: {exception}");
}
return false;
@@ -400,21 +430,33 @@ namespace Ryujinx.Ava.UI.ViewModels
private async Task<string> DownloadAmiiboJson()
{
- HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
-
- if (response.IsSuccessStatusCode)
+ try
{
- string amiiboJsonString = await response.Content.ReadAsStringAsync();
+ HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
- using (FileStream amiiboJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough))
+ if (response.IsSuccessStatusCode)
{
- amiiboJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
+ string amiiboJsonString = await response.Content.ReadAsStringAsync();
+
+ try
+ {
+ using FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough);
+ dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
+ }
+ catch (Exception exception)
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Couldn't write amiibo data to file '{_amiiboJsonPath}: {exception}'");
+ }
+
+ return amiiboJsonString;
}
- return amiiboJsonString;
+ Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
+ }
+ catch (HttpRequestException exception)
+ {
+ Logger.Error?.Print(LogClass.Application, $"Failed to request amiibo data: {exception}");
}
-
- Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
await ContentDialogHelper.CreateInfoDialog(LocaleManager.Instance[LocaleKeys.DialogAmiiboApiTitle],
LocaleManager.Instance[LocaleKeys.DialogAmiiboApiFailFetchMessage],
@@ -422,9 +464,7 @@ namespace Ryujinx.Ava.UI.ViewModels
"",
LocaleManager.Instance[LocaleKeys.RyujinxInfo]);
- Close();
-
- return DefaultJson;
+ return null;
}
private void Close()
diff --git a/src/Ryujinx/Ui/Windows/AmiiboWindow.cs b/src/Ryujinx/Ui/Windows/AmiiboWindow.cs
index 2673f912..a2a5bce6 100644
--- a/src/Ryujinx/Ui/Windows/AmiiboWindow.cs
+++ b/src/Ryujinx/Ui/Windows/AmiiboWindow.cs
@@ -1,3 +1,4 @@
+using Gdk;
using Gtk;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
@@ -13,7 +14,9 @@ using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
+using System.Text.Json;
using System.Threading.Tasks;
+using Window = Gtk.Window;
namespace Ryujinx.Ui.Windows
{
@@ -49,11 +52,11 @@ namespace Ryujinx.Ui.Windows
public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo")
{
- Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
+ Icon = new Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
InitializeComponent();
- _httpClient = new HttpClient()
+ _httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30),
};
@@ -64,7 +67,7 @@ namespace Ryujinx.Ui.Windows
_amiiboList = new List<AmiiboApi>();
_amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png");
- _amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes);
+ _amiiboImage.Pixbuf = new Pixbuf(_amiiboLogoBytes);
_scanButton.Sensitive = false;
_randomUuidCheckBox.Sensitive = false;
@@ -72,17 +75,25 @@ namespace Ryujinx.Ui.Windows
_ = LoadContentAsync();
}
- private bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
+ private static bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
{
+ if (string.IsNullOrEmpty(json))
+ {
+ amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
+
+ return false;
+ }
+
try
{
- amiiboJson = JsonHelper.Deserialize<AmiiboJson>(json, _serializerContext.AmiiboJson);
+ amiiboJson = JsonHelper.Deserialize(json, _serializerContext.AmiiboJson);
return true;
}
- catch
+ catch (JsonException exception)
{
- amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
+ Logger.Error?.Print(LogClass.Application, $"Unable to deserialize amiibo data: {exception}");
+ amiiboJson = JsonHelper.Deserialize(DefaultJson, _serializerContext.AmiiboJson);
return false;
}
@@ -92,27 +103,41 @@ namespace Ryujinx.Ui.Windows
{
bool localIsValid = false;
bool remoteIsValid = false;
- AmiiboJson amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
+ AmiiboJson amiiboJson = new();
try
{
- localIsValid = TryGetAmiiboJson(File.ReadAllText(_amiiboJsonPath), out amiiboJson);
+ try
+ {
+ if (File.Exists(_amiiboJsonPath))
+ {
+ localIsValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson);
+ }
+ }
+ catch (Exception exception)
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}");
+ }
if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated))
{
remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson);
}
}
- catch
+ catch (Exception exception)
{
if (!(localIsValid || remoteIsValid))
{
+ Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
+
// Neither local or remote files are valid JSON, close window.
ShowInfoDialog();
Close();
}
else if (!remoteIsValid)
{
+ Logger.Warning?.Print(LogClass.Application, $"Couldn't update amiibo data: {exception}");
+
// Only the local file is valid, the local one should be used
// but the user should be warned.
ShowInfoDialog();
@@ -196,11 +221,18 @@ namespace Ryujinx.Ui.Windows
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
{
- HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
+ try
+ {
+ HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
- if (response.IsSuccessStatusCode)
+ if (response.IsSuccessStatusCode)
+ {
+ return response.Content.Headers.LastModified != oldLastModified;
+ }
+ }
+ catch (HttpRequestException exception)
{
- return response.Content.Headers.LastModified != oldLastModified;
+ Logger.Error?.Print(LogClass.Application, $"Unable to check for amiibo data updates: {exception}");
}
return false;
@@ -208,29 +240,37 @@ namespace Ryujinx.Ui.Windows
private async Task<string> DownloadAmiiboJson()
{
- HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
-
- if (response.IsSuccessStatusCode)
+ try
{
- string amiiboJsonString = await response.Content.ReadAsStringAsync();
+ HttpResponseMessage response = await _httpClient.GetAsync("https://amiibo.ryujinx.org/");
- using (FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough))
+ if (response.IsSuccessStatusCode)
{
- dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
+ string amiiboJsonString = await response.Content.ReadAsStringAsync();
+
+ try
+ {
+ using FileStream dlcJsonStream = File.Create(_amiiboJsonPath, 4096, FileOptions.WriteThrough);
+ dlcJsonStream.Write(Encoding.UTF8.GetBytes(amiiboJsonString));
+ }
+ catch (Exception exception)
+ {
+ Logger.Warning?.Print(LogClass.Application, $"Couldn't write amiibo data to file '{_amiiboJsonPath}: {exception}'");
+ }
+
+ return amiiboJsonString;
}
- return amiiboJsonString;
+ Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
}
- else
+ catch (HttpRequestException exception)
{
- Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data. Response status code: {response.StatusCode}");
-
- GtkDialog.CreateInfoDialog($"Amiibo API", "An error occured while fetching information from the API.");
-
- Close();
+ Logger.Error?.Print(LogClass.Application, $"Failed to request amiibo data: {exception}");
}
- return DefaultJson;
+ GtkDialog.CreateInfoDialog("Amiibo API", "An error occured while fetching information from the API.");
+
+ return null;
}
private async Task UpdateAmiiboPreview(string imageUrl)
@@ -240,7 +280,7 @@ namespace Ryujinx.Ui.Windows
if (response.IsSuccessStatusCode)
{
byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync();
- Gdk.Pixbuf amiiboPreview = new(amiiboPreviewBytes);
+ Pixbuf amiiboPreview = new(amiiboPreviewBytes);
float ratio = Math.Min((float)_amiiboImage.AllocatedWidth / amiiboPreview.Width,
(float)_amiiboImage.AllocatedHeight / amiiboPreview.Height);
@@ -248,7 +288,7 @@ namespace Ryujinx.Ui.Windows
int resizeHeight = (int)(amiiboPreview.Height * ratio);
int resizeWidth = (int)(amiiboPreview.Width * ratio);
- _amiiboImage.Pixbuf = amiiboPreview.ScaleSimple(resizeWidth, resizeHeight, Gdk.InterpType.Bilinear);
+ _amiiboImage.Pixbuf = amiiboPreview.ScaleSimple(resizeWidth, resizeHeight, InterpType.Bilinear);
}
else
{
@@ -258,7 +298,7 @@ namespace Ryujinx.Ui.Windows
private static void ShowInfoDialog()
{
- GtkDialog.CreateInfoDialog($"Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online.");
+ GtkDialog.CreateInfoDialog("Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online.");
}
//
@@ -314,7 +354,7 @@ namespace Ryujinx.Ui.Windows
{
AmiiboId = _amiiboCharsComboBox.ActiveId;
- _amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes);
+ _amiiboImage.Pixbuf = new Pixbuf(_amiiboLogoBytes);
string imageUrl = _amiiboList.Find(amiibo => amiibo.Head + amiibo.Tail == _amiiboCharsComboBox.ActiveId).Image;
@@ -354,7 +394,7 @@ namespace Ryujinx.Ui.Windows
private void ShowAllCheckBox_Clicked(object sender, EventArgs e)
{
- _amiiboImage.Pixbuf = new Gdk.Pixbuf(_amiiboLogoBytes);
+ _amiiboImage.Pixbuf = new Pixbuf(_amiiboLogoBytes);
_amiiboSeriesComboBox.Changed -= SeriesComboBox_Changed;
_amiiboCharsComboBox.Changed -= CharacterComboBox_Changed;
@@ -365,7 +405,7 @@ namespace Ryujinx.Ui.Windows
_scanButton.Sensitive = false;
_randomUuidCheckBox.Sensitive = false;
- new Task(() => ParseAmiiboData()).Start();
+ new Task(ParseAmiiboData).Start();
}
private void ScanButton_Pressed(object sender, EventArgs args)