mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-27 19:56:23 +02:00
infra: Use Ryujinx.UpdateClient NuGet package for checking for updates.
Main benefit to this is sharing the C# model definitions from what the server returns and Ryujinx uses in-app without differences. Additionally removed the GitHub API JSON models.
This commit is contained in:
parent
6226eadf55
commit
6773406bb6
8 changed files with 38 additions and 101 deletions
|
@ -42,6 +42,8 @@
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0" />
|
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||||
|
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.28" />
|
||||||
|
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.28" />
|
||||||
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||||
|
|
|
@ -10,11 +10,13 @@
|
||||||
</packageSources>
|
</packageSources>
|
||||||
<packageSourceMapping>
|
<packageSourceMapping>
|
||||||
<!-- key value for <packageSource> should match key values from <packageSources> element -->
|
<!-- key value for <packageSource> should match key values from <packageSources> element -->
|
||||||
|
<!-- These are defined and .NET still yells about multiple package sources with no mappings. Not sure what to do, this is in the docs lol -->
|
||||||
<packageSource key="nuget.org">
|
<packageSource key="nuget.org">
|
||||||
<package pattern="*" />
|
<package pattern="*" />
|
||||||
</packageSource>
|
</packageSource>
|
||||||
<packageSource key="Ryujinx.UpdateClient">
|
<packageSource key="Ryujinx.UpdateClient">
|
||||||
<package pattern="Ryujinx.UpdateClient" />
|
<package pattern="Ryujinx.UpdateClient" />
|
||||||
|
<package pattern="Ryujinx.Systems.Update.Common" />
|
||||||
</packageSource>
|
</packageSource>
|
||||||
<!--<packageSource key="LibHacAlpha">
|
<!--<packageSource key="LibHacAlpha">
|
||||||
<package pattern="Ryujinx.LibHac" />
|
<package pattern="Ryujinx.LibHac" />
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
namespace Ryujinx.Ava.Common.Models.Github
|
|
||||||
{
|
|
||||||
public class GithubReleaseAssetJsonResponse
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string State { get; set; }
|
|
||||||
public string BrowserDownloadUrl { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Models.Github
|
|
||||||
{
|
|
||||||
public class GithubReleasesJsonResponse
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public string TagName { get; set; }
|
|
||||||
public List<GithubReleaseAssetJsonResponse> Assets { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Common.Models.Github
|
|
||||||
{
|
|
||||||
[JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)]
|
|
||||||
public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext;
|
|
||||||
}
|
|
|
@ -65,6 +65,8 @@
|
||||||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" />
|
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" />
|
||||||
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'" />
|
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64' AND '$(RuntimeIdentifier)' != 'win-arm64'" />
|
||||||
|
<PackageReference Include="Ryujinx.UpdateClient" />
|
||||||
|
<PackageReference Include="Ryujinx.Systems.Update.Common" />
|
||||||
<PackageReference Include="securifybv.ShellLink" />
|
<PackageReference Include="securifybv.ShellLink" />
|
||||||
<PackageReference Include="Sep" />
|
<PackageReference Include="Sep" />
|
||||||
<PackageReference Include="Silk.NET.Vulkan" />
|
<PackageReference Include="Silk.NET.Vulkan" />
|
||||||
|
|
|
@ -4,42 +4,27 @@ using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Systems.Update.Client;
|
||||||
|
using Ryujinx.Systems.Update.Common;
|
||||||
|
using Ryujinx.Systems.Updater.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.Systems
|
namespace Ryujinx.Ava.Systems
|
||||||
{
|
{
|
||||||
internal static partial class Updater
|
internal static partial class Updater
|
||||||
{
|
{
|
||||||
private static string CreateUpdateQueryUrl()
|
private static VersionResponse _versionResponse;
|
||||||
{
|
|
||||||
#pragma warning disable CS8524
|
|
||||||
var os = RunningPlatform.CurrentOS switch
|
|
||||||
#pragma warning restore CS8524
|
|
||||||
{
|
|
||||||
OperatingSystemType.MacOS => "mac",
|
|
||||||
OperatingSystemType.Linux => "linux",
|
|
||||||
OperatingSystemType.Windows => "win"
|
|
||||||
};
|
|
||||||
|
|
||||||
var arch = RunningPlatform.Architecture switch
|
private static UpdateClient CreateUpdateClient()
|
||||||
{
|
=> UpdateClient.Builder()
|
||||||
Architecture.Arm64 => "arm",
|
.WithServerEndpoint("https://update.ryujinx.app") // This is the default, and doesn't need to be provided; it's here for transparency.
|
||||||
Architecture.X64 => "amd64",
|
.WithLogger((format, args, caller) =>
|
||||||
_ => null
|
Logger.Info?.Print(
|
||||||
};
|
LogClass.Application,
|
||||||
|
args.Length is 0 ? format : format.Format(args),
|
||||||
if (arch is null)
|
caller: caller)
|
||||||
return null;
|
);
|
||||||
|
|
||||||
var rc = ReleaseInformation.IsCanaryBuild ? "canary" : "stable";
|
|
||||||
|
|
||||||
return $"https://update.ryujinx.app/latest/query?os={os}&arch={arch}&rc={rc}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false)
|
public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false)
|
||||||
{
|
{
|
||||||
|
@ -57,39 +42,31 @@ namespace Ryujinx.Ava.Systems
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CreateUpdateQueryUrl() is not {} updateUrl)
|
using UpdateClient updateClient = CreateUpdateClient();
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, "Could not determine URL for updates.");
|
|
||||||
|
|
||||||
_running = false;
|
|
||||||
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Info?.Print(LogClass.Application, $"Checking for updates from {updateUrl}.");
|
|
||||||
|
|
||||||
// Get latest version number from update.ryujinx.app API
|
|
||||||
using HttpClient jsonClient = ConstructHttpClient();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
UpdaterResponse response =
|
_versionResponse = await updateClient.QueryLatestAsync(ReleaseInformation.IsCanaryBuild
|
||||||
await jsonClient.GetFromJsonAsync(updateUrl, UpdaterResponseJsonContext.Default.UpdaterResponse);
|
? ReleaseChannel.Canary
|
||||||
|
: ReleaseChannel.Stable);
|
||||||
_buildVer = response.Tag;
|
|
||||||
_buildUrl = response.DownloadUrl;
|
|
||||||
_changelogUrlFormat = response.ReleaseUrlFormat;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, $"An error occurred when parsing JSON response from API ({e.GetType().AsFullNamePrettyString()}): {e.Message}");
|
Logger.Error?.Print(LogClass.Application, $"An error occurred when requesting for updates ({e.GetType().AsFullNamePrettyString()}): {e.Message}");
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_versionResponse == null)
|
||||||
|
{
|
||||||
|
// logging is done via the UpdateClient library
|
||||||
|
_running = false;
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
// If build URL not found, assume no new update is available.
|
// If build URL not found, assume no new update is available.
|
||||||
if (_buildUrl is null or "")
|
if (_versionResponse.ArtifactUrl is null or "")
|
||||||
{
|
{
|
||||||
if (showVersionUpToDate)
|
if (showVersionUpToDate)
|
||||||
{
|
{
|
||||||
|
@ -99,7 +76,7 @@ namespace Ryujinx.Ava.Systems
|
||||||
|
|
||||||
if (userResult is UserResult.Ok)
|
if (userResult is UserResult.Ok)
|
||||||
{
|
{
|
||||||
OpenHelper.OpenUrl(_changelogUrlFormat.Format(currentVersion));
|
OpenHelper.OpenUrl(_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +88,7 @@ namespace Ryujinx.Ava.Systems
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!Version.TryParse(_buildVer, out Version newVersion))
|
if (!Version.TryParse(_versionResponse.Version, out Version newVersion))
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application,
|
Logger.Error?.Print(LogClass.Application,
|
||||||
$"Failed to convert the received {RyujinxApp.FullAppName} version from the update server!");
|
$"Failed to convert the received {RyujinxApp.FullAppName} version from the update server!");
|
||||||
|
@ -127,17 +104,5 @@ namespace Ryujinx.Ava.Systems
|
||||||
|
|
||||||
return (currentVersion, newVersion);
|
return (currentVersion, newVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonSerializable(typeof(UpdaterResponse))]
|
|
||||||
partial class UpdaterResponseJsonContext : JsonSerializerContext;
|
|
||||||
|
|
||||||
public class UpdaterResponse
|
|
||||||
{
|
|
||||||
[JsonPropertyName("tag")] public string Tag { get; set; }
|
|
||||||
[JsonPropertyName("download_url")] public string DownloadUrl { get; set; }
|
|
||||||
[JsonPropertyName("web_url")] public string ReleaseUrl { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore] public string ReleaseUrlFormat => ReleaseUrl.Replace(Tag, "{0}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,11 @@ using ICSharpCode.SharpZipLib.GZip;
|
||||||
using ICSharpCode.SharpZipLib.Tar;
|
using ICSharpCode.SharpZipLib.Tar;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Common.Models.Github;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.Utilities;
|
using Ryujinx.Ava.Utilities;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Helper;
|
using Ryujinx.Common.Helper;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Utilities;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
@ -35,17 +33,13 @@ namespace Ryujinx.Ava.Systems
|
||||||
private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
|
private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
|
||||||
private static readonly string _updatePublishDir = Path.Combine(_updateDir, "publish");
|
private static readonly string _updatePublishDir = Path.Combine(_updateDir, "publish");
|
||||||
private const int ConnectionCount = 4;
|
private const int ConnectionCount = 4;
|
||||||
|
|
||||||
private static string _buildVer;
|
|
||||||
private static string _buildUrl;
|
|
||||||
private static long _buildSize;
|
private static long _buildSize;
|
||||||
private static bool _updateSuccessful;
|
private static bool _updateSuccessful;
|
||||||
private static bool _running;
|
private static bool _running;
|
||||||
|
|
||||||
private static readonly string[] _windowsDependencyDirs = [];
|
private static readonly string[] _windowsDependencyDirs = [];
|
||||||
|
|
||||||
private static string _changelogUrlFormat = null;
|
|
||||||
|
|
||||||
public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
|
public static async Task BeginUpdateAsync(bool showVersionUpToDate = false)
|
||||||
{
|
{
|
||||||
if (_running)
|
if (_running)
|
||||||
|
@ -72,7 +66,7 @@ namespace Ryujinx.Ava.Systems
|
||||||
|
|
||||||
if (userResult is UserResult.Ok)
|
if (userResult is UserResult.Ok)
|
||||||
{
|
{
|
||||||
OpenHelper.OpenUrl(_changelogUrlFormat.Format(currentVersion));
|
OpenHelper.OpenUrl(_versionResponse.ReleaseUrlFormat.Format(currentVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +86,7 @@ namespace Ryujinx.Ava.Systems
|
||||||
// GitLab instance is located in Ukraine. Connection times will vary across the world.
|
// GitLab instance is located in Ukraine. Connection times will vary across the world.
|
||||||
buildSizeClient.Timeout = TimeSpan.FromSeconds(10);
|
buildSizeClient.Timeout = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_buildUrl), HttpCompletionOption.ResponseHeadersRead);
|
HttpResponseMessage message = await buildSizeClient.GetAsync(new Uri(_versionResponse.ArtifactUrl), HttpCompletionOption.ResponseHeadersRead);
|
||||||
|
|
||||||
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +116,7 @@ namespace Ryujinx.Ava.Systems
|
||||||
switch (shouldUpdate)
|
switch (shouldUpdate)
|
||||||
{
|
{
|
||||||
case UserResult.Yes:
|
case UserResult.Yes:
|
||||||
await UpdateRyujinx(_buildUrl);
|
await UpdateRyujinx(_versionResponse.ArtifactUrl);
|
||||||
break;
|
break;
|
||||||
// Secondary button maps to no, which in this case is the show changelog button.
|
// Secondary button maps to no, which in this case is the show changelog button.
|
||||||
case UserResult.No:
|
case UserResult.No:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue