forked from Mirror/Ryujinx
Local Amiibo.json should be used if connection failed (#3681)
* Local Amiibo.json should be used if connection failed Currently Ryujinx is not loading any Amiibo if connection fails, even if the Amiibo.json exists. This fix will use the local file and show a Dialog if connection fails. * using local Amiibo.json & fixed Amiibo.json date comparison Using local Amiibo.json when connection fails and comparison without milliseconds for LastModified that comes from https://amiibo.ryujinx.org/ and the local one (The JSON file has milliseconds on it, those will cause an error when comparing the date from the header because the header one doesn't has milliseconds on it). Both changes made for Avalonia UI. * Fixed date comparison Same date comparison fix, but made for normal UI (Not for AvaloniaUI). This error can be prevented if the file in https://amiibo.ryujinx.org/ did not have the date with milliseconds. * Securely trying to get a list of Amiibo (For normal UI) * Securely trying to get a list of Amiibo (Change for AvaloniaUI) * Date comparison reverted * Apply suggestions from code review * Use fallback amiibo.json if remote file is not valid (Normal UI) * Use fallback amiibo.json if remote file is not valid (Avalonia UI) * Code styles corrected. * Code styles corrected in AmiiboWindowViewModel. * Readded Ryujinx.Common.Logging using. * Fixed using order. --------- Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
parent
19a949d0bf
commit
f11d663df7
2 changed files with 93 additions and 66 deletions
|
@ -188,35 +188,61 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
_httpClient.Dispose();
|
_httpClient.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadContentAsync()
|
private bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
|
||||||
{
|
{
|
||||||
string amiiboJsonString = DefaultJson;
|
try
|
||||||
|
|
||||||
if (File.Exists(_amiiboJsonPath))
|
|
||||||
{
|
{
|
||||||
amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath);
|
amiiboJson = JsonHelper.Deserialize<AmiiboJson>(json, _serializerContext.AmiiboJson);
|
||||||
|
|
||||||
if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).LastUpdated))
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<AmiiboJson> GetMostRecentAmiiboListOrDefaultJson()
|
||||||
|
{
|
||||||
|
bool localIsValid = false;
|
||||||
|
bool remoteIsValid = false;
|
||||||
|
AmiiboJson amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
localIsValid = TryGetAmiiboJson(File.ReadAllText(_amiiboJsonPath), out amiiboJson);
|
||||||
|
|
||||||
|
if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated))
|
||||||
{
|
{
|
||||||
amiiboJsonString = await DownloadAmiiboJson();
|
remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
catch
|
||||||
{
|
{
|
||||||
try
|
if (!(localIsValid || remoteIsValid))
|
||||||
{
|
{
|
||||||
amiiboJsonString = await DownloadAmiiboJson();
|
// Neither local or remote files are valid JSON, close window.
|
||||||
|
ShowInfoDialog();
|
||||||
|
Close();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else if (!remoteIsValid)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data: {ex}");
|
// Only the local file is valid, the local one should be used
|
||||||
|
// but the user should be warned.
|
||||||
ShowInfoDialog();
|
ShowInfoDialog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_amiiboList = JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).Amiibo;
|
return amiiboJson;
|
||||||
_amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
|
}
|
||||||
|
|
||||||
|
private async Task LoadContentAsync()
|
||||||
|
{
|
||||||
|
AmiiboJson amiiboJson = await GetMostRecentAmiiboListOrDefaultJson();
|
||||||
|
|
||||||
|
_amiiboList = amiiboJson.Amiibo.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
|
||||||
|
|
||||||
ParseAmiiboData();
|
ParseAmiiboData();
|
||||||
}
|
}
|
||||||
|
@ -362,26 +388,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
|
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
|
||||||
{
|
{
|
||||||
try
|
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
HttpResponseMessage response =
|
return response.Content.Headers.LastModified != oldLastModified;
|
||||||
await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
return response.Content.Headers.LastModified != new DateTimeOffset(oldLastModified.Ticks - (oldLastModified.Ticks % TimeSpan.TicksPerSecond), TimeSpan.Zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, $"Failed to check for amiibo updates: {ex}");
|
|
||||||
|
|
||||||
ShowInfoDialog();
|
return false;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> DownloadAmiiboJson()
|
private async Task<string> DownloadAmiiboJson()
|
||||||
|
|
|
@ -72,37 +72,61 @@ namespace Ryujinx.Ui.Windows
|
||||||
_ = LoadContentAsync();
|
_ = LoadContentAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadContentAsync()
|
private bool TryGetAmiiboJson(string json, out AmiiboJson amiiboJson)
|
||||||
{
|
{
|
||||||
string amiiboJsonString = DefaultJson;
|
try
|
||||||
|
|
||||||
if (File.Exists(_amiiboJsonPath))
|
|
||||||
{
|
{
|
||||||
amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath);
|
amiiboJson = JsonHelper.Deserialize<AmiiboJson>(json, _serializerContext.AmiiboJson);
|
||||||
|
|
||||||
if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).LastUpdated))
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<AmiiboJson> GetMostRecentAmiiboListOrDefaultJson()
|
||||||
|
{
|
||||||
|
bool localIsValid = false;
|
||||||
|
bool remoteIsValid = false;
|
||||||
|
AmiiboJson amiiboJson = JsonHelper.Deserialize<AmiiboJson>(DefaultJson, _serializerContext.AmiiboJson);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
localIsValid = TryGetAmiiboJson(File.ReadAllText(_amiiboJsonPath), out amiiboJson);
|
||||||
|
|
||||||
|
if (!localIsValid || await NeedsUpdate(amiiboJson.LastUpdated))
|
||||||
{
|
{
|
||||||
amiiboJsonString = await DownloadAmiiboJson();
|
remoteIsValid = TryGetAmiiboJson(await DownloadAmiiboJson(), out amiiboJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
catch
|
||||||
{
|
{
|
||||||
try
|
if (!(localIsValid || remoteIsValid))
|
||||||
{
|
{
|
||||||
amiiboJsonString = await DownloadAmiiboJson();
|
// Neither local or remote files are valid JSON, close window.
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, $"Failed to download amiibo data: {ex}");
|
|
||||||
|
|
||||||
ShowInfoDialog();
|
ShowInfoDialog();
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
else if (!remoteIsValid)
|
||||||
|
{
|
||||||
|
// Only the local file is valid, the local one should be used
|
||||||
|
// but the user should be warned.
|
||||||
|
ShowInfoDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_amiiboList = JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).Amiibo;
|
return amiiboJson;
|
||||||
_amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
|
}
|
||||||
|
|
||||||
|
private async Task LoadContentAsync()
|
||||||
|
{
|
||||||
|
AmiiboJson amiiboJson = await GetMostRecentAmiiboListOrDefaultJson();
|
||||||
|
|
||||||
|
_amiiboList = amiiboJson.Amiibo.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
|
||||||
|
|
||||||
if (LastScannedAmiiboShowAll)
|
if (LastScannedAmiiboShowAll)
|
||||||
{
|
{
|
||||||
|
@ -172,25 +196,14 @@ namespace Ryujinx.Ui.Windows
|
||||||
|
|
||||||
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
|
private async Task<bool> NeedsUpdate(DateTime oldLastModified)
|
||||||
{
|
{
|
||||||
try
|
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
HttpResponseMessage response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, "https://amiibo.ryujinx.org/"));
|
return response.Content.Headers.LastModified != oldLastModified;
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
return response.Content.Headers.LastModified != new DateTimeOffset(oldLastModified.Ticks - (oldLastModified.Ticks % TimeSpan.TicksPerSecond), TimeSpan.Zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, $"Failed to check for amiibo updates: {ex}");
|
|
||||||
|
|
||||||
ShowInfoDialog();
|
return false;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> DownloadAmiiboJson()
|
private async Task<string> DownloadAmiiboJson()
|
||||||
|
|
Loading…
Reference in a new issue