UpdateChecker.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Text.Json;
  7. using System.Threading.Tasks;
  8. namespace PixiEditor.UpdateModule
  9. {
  10. public class UpdateChecker
  11. {
  12. private const string ReleaseApiUrl = "https://api.github.com/repos/PixiEditor/PixiEditor/releases/latest";
  13. private const string IncompatibleFileApiUrl = "https://raw.githubusercontent.com/PixiEditor/PixiEditor/{0}/incompatible.json";
  14. public UpdateChecker(string currentVersionTag)
  15. {
  16. CurrentVersionTag = currentVersionTag;
  17. }
  18. public ReleaseInfo LatestReleaseInfo { get; private set; }
  19. public string CurrentVersionTag { get; }
  20. /// <summary>
  21. /// Compares version strings and returns true if newVer > originalVer.
  22. /// </summary>
  23. /// <param name="originalVer">Version to compare.</param>
  24. /// <param name="newVer">Version to compare with.</param>
  25. /// <returns>True if semantic version is higher.</returns>
  26. public static bool VersionBigger(string originalVer, string newVer)
  27. {
  28. if (!ParseVersionString(originalVer, out float ver1))
  29. {
  30. return false;
  31. }
  32. if (ParseVersionString(newVer, out float ver2))
  33. {
  34. return ver2 > ver1;
  35. }
  36. return false;
  37. }
  38. public async Task<bool> CheckUpdateAvailable()
  39. {
  40. LatestReleaseInfo = await GetLatestReleaseInfoAsync();
  41. return CheckUpdateAvailable(LatestReleaseInfo);
  42. }
  43. public bool CheckUpdateAvailable(ReleaseInfo latestRelease)
  44. {
  45. return latestRelease.WasDataFetchSuccessful && VersionBigger(CurrentVersionTag, latestRelease.TagName);
  46. }
  47. public bool IsUpdateCompatible(string[] incompatibleVersions)
  48. {
  49. return !incompatibleVersions.Select(x => x.Trim()).Contains(CurrentVersionTag.Trim());
  50. }
  51. public async Task<bool> IsUpdateCompatible()
  52. {
  53. string[] incompatibleVersions = await GetUpdateIncompatibleVersionsAsync(LatestReleaseInfo.TagName);
  54. return IsUpdateCompatible(incompatibleVersions);
  55. }
  56. public async Task<string[]> GetUpdateIncompatibleVersionsAsync(string tag)
  57. {
  58. using (HttpClient client = new HttpClient())
  59. {
  60. client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
  61. HttpResponseMessage response = await client.GetAsync(string.Format(IncompatibleFileApiUrl, tag));
  62. if (response.StatusCode == HttpStatusCode.OK)
  63. {
  64. string content = await response.Content.ReadAsStringAsync();
  65. return JsonSerializer.Deserialize<string[]>(content);
  66. }
  67. }
  68. return Array.Empty<string>();
  69. }
  70. private static async Task<ReleaseInfo> GetLatestReleaseInfoAsync()
  71. {
  72. using (HttpClient client = new HttpClient())
  73. {
  74. client.DefaultRequestHeaders.Add("User-Agent", "PixiEditor");
  75. HttpResponseMessage response = await client.GetAsync(ReleaseApiUrl);
  76. if (response.StatusCode == HttpStatusCode.OK)
  77. {
  78. string content = await response.Content.ReadAsStringAsync();
  79. return JsonSerializer.Deserialize<ReleaseInfo>(content);
  80. }
  81. }
  82. return new ReleaseInfo(false);
  83. }
  84. private static bool ParseVersionString(string versionString, out float version)
  85. {
  86. return float.TryParse(versionString.Replace(".", string.Empty).Insert(1, "."), NumberStyles.Any, CultureInfo.InvariantCulture, out version);
  87. }
  88. }
  89. }