From 89230bd6997fe56532be67113e1a61f21e603ff0 Mon Sep 17 00:00:00 2001 From: Vesly <74131882+Veslydev@users.noreply.github.com> Date: Wed, 29 Jul 2026 16:29:56 +0300 Subject: [PATCH] fix(updater): fallback to GitHub API for releases and bump version to 2.1.3 --- SiteLink.API/Packages/PackageManager.cs | 123 ++++++++++++++++++++++-- SiteLink.API/SiteLinkAPI.cs | 4 +- SiteLink/Services/BuildInformation.cs | 4 +- SiteLink/SiteLink.csproj | 4 +- 4 files changed, 123 insertions(+), 12 deletions(-) diff --git a/SiteLink.API/Packages/PackageManager.cs b/SiteLink.API/Packages/PackageManager.cs index 476a7e8..424b750 100644 --- a/SiteLink.API/Packages/PackageManager.cs +++ b/SiteLink.API/Packages/PackageManager.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System.Diagnostics; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -20,12 +21,25 @@ public static async Task GetIndexAsync( CancellationToken cancellationToken = default) { (string owner, string name) = ParseRepository(repository); - string url = $"https://{owner.ToLowerInvariant()}.github.io/{name}/releases.json"; - using HttpResponseMessage response = await Http.GetAsync(url, cancellationToken); - response.EnsureSuccessStatusCode(); - string json = await response.Content.ReadAsStringAsync(); - return JsonConvert.DeserializeObject(json) - ?? throw new InvalidDataException($"Release index '{url}' was empty."); + + try + { + string url = $"https://{owner.ToLowerInvariant()}.github.io/{name}/releases.json"; + using HttpResponseMessage response = await Http.GetAsync(url, cancellationToken); + if (response.IsSuccessStatusCode) + { + string json = await response.Content.ReadAsStringAsync(); + PackageReleaseIndex index = JsonConvert.DeserializeObject(json); + if (index != null && index.Versions != null && index.Versions.Count > 0) + return index; + } + } + catch + { + // Fall back to GitHub REST API if releases.json is missing or invalid + } + + return await GetIndexFromGitHubApiAsync(owner, name, cancellationToken); } public static PackageManifest GetLatest( @@ -174,6 +188,103 @@ public static (string Owner, string Repository) ParseRepository(string repositor private static Version ParseVersion(string value) => Version.TryParse(value?.TrimStart('v', 'V'), out Version version) ? version : null; + private static async Task GetIndexFromGitHubApiAsync( + string owner, + string name, + CancellationToken cancellationToken) + { + string url = $"https://api.github.com/repos/{owner}/{name}/releases"; + using HttpResponseMessage response = await Http.GetAsync(url, cancellationToken); + response.EnsureSuccessStatusCode(); + + string json = await response.Content.ReadAsStringAsync(); + JArray releases = JArray.Parse(json); + + PackageReleaseIndex index = new() + { + DisplayName = name, + OwnerName = owner, + RepositoryName = name + }; + + foreach (JObject release in releases.Children()) + { + if (release["draft"]?.Value() == true) + continue; + + string tagName = release["tag_name"]?.ToString(); + if (string.IsNullOrWhiteSpace(tagName)) + continue; + + string versionStr = tagName.TrimStart('v', 'V'); + PackageManifest manifest = new() + { + DisplayName = name, + OwnerName = owner, + RepositoryName = name, + Version = versionStr, + PackageType = "core" + }; + + if (release["assets"] is JArray assets) + { + foreach (JObject asset in assets.Children()) + { + string fileName = asset["name"]?.ToString(); + string downloadUrl = asset["browser_download_url"]?.ToString(); + long size = asset["size"]?.Value() ?? 0; + + if (string.IsNullOrWhiteSpace(fileName) || string.IsNullOrWhiteSpace(downloadUrl)) + continue; + + string platform; + if (fileName.Equals("SiteLink.exe", StringComparison.OrdinalIgnoreCase) || + fileName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || + fileName.Contains("win", StringComparison.OrdinalIgnoreCase)) + { + platform = "windows"; + } + else if (fileName.Equals("SiteLink", StringComparison.OrdinalIgnoreCase) || + fileName.Contains("linux", StringComparison.OrdinalIgnoreCase)) + { + platform = "linux"; + } + else if (fileName.Contains("mac", StringComparison.OrdinalIgnoreCase) || + fileName.Contains("osx", StringComparison.OrdinalIgnoreCase)) + { + platform = "macos"; + } + else + { + platform = "any"; + } + + manifest.Platforms[platform] = new PackageAsset + { + Platform = platform, + FileName = fileName, + FileUrl = downloadUrl, + Size = size + }; + } + } + + if (index.DisplayName == name && release["name"] != null) + { + string relName = release["name"].ToString(); + if (!string.IsNullOrWhiteSpace(relName)) + index.DisplayName = relName; + } + + index.Versions[versionStr] = manifest; + } + + if (index.Versions.Count == 0) + throw new InvalidOperationException($"No valid releases found in GitHub repository '{owner}/{name}'."); + + return index; + } + private static HttpClient CreateHttpClient() { HttpClient client = new(); diff --git a/SiteLink.API/SiteLinkAPI.cs b/SiteLink.API/SiteLinkAPI.cs index 27daa25..c09e1d5 100644 --- a/SiteLink.API/SiteLinkAPI.cs +++ b/SiteLink.API/SiteLinkAPI.cs @@ -1,4 +1,4 @@ -using SiteLink.API; +using SiteLink.API; [assembly: AssemblyProduct("SiteLinkAPI")] [assembly: AssemblyCopyright("Killers0992 @ 2026")] @@ -12,7 +12,7 @@ public class SiteLinkAPI static Version _apiVersion; public const string GameVersionText = "14.2.7"; - public const string ApiVersionText = "2.1.2"; + public const string ApiVersionText = "2.1.3"; public static int ThresholdBytes => 65535 * (NetConstants.MaxPacketSize - 6); diff --git a/SiteLink/Services/BuildInformation.cs b/SiteLink/Services/BuildInformation.cs index eb3853a..b6a5a0e 100644 --- a/SiteLink/Services/BuildInformation.cs +++ b/SiteLink/Services/BuildInformation.cs @@ -1,6 +1,6 @@ -namespace SiteLink.Services; +namespace SiteLink.Services; public class BuildInformation { - public const string VersionText = "1.0.1"; + public static string VersionText => SiteLink.API.SiteLinkAPI.ApiVersionText; } \ No newline at end of file diff --git a/SiteLink/SiteLink.csproj b/SiteLink/SiteLink.csproj index edd085b..89e4a4f 100644 --- a/SiteLink/SiteLink.csproj +++ b/SiteLink/SiteLink.csproj @@ -1,4 +1,4 @@ - + Exe @@ -8,7 +8,7 @@ SiteLink Multi-server proxy for SCP: Secret Laboratory. Killers0992 - 2.1.2 + 2.1.3 win-x64;linux-x64