using System; using System.IO; using System.Net.Http; using System.Windows; using AutoUpdaterDotNET; using NebulaAuth.Model; using NebulaAuth.Model.Update; using Newtonsoft.Json; namespace NebulaAuth.Core; public static class UpdateManager { private const string BASE_URL = "https://raw.githubusercontent.com/achiez/NebulaAuth-Steam-Desktop-Authenticator-by-Achies/master/"; private const string UPDATE_URL = BASE_URL + "NebulaAuth/update.xml"; private const string CHANGELOG_BASE_URL = BASE_URL + "changelog/"; private static readonly HttpClient HttpClient = new(); private static bool _isManualCheck; public static bool HasPendingUpdate { get; private set; } static UpdateManager() { AutoUpdater.CheckForUpdateEvent += HandleCheckForUpdateEvent; } public static event Action? PendingUpdateDetected; public static void CheckForUpdates(bool manual = false) { _isManualCheck = manual; var jsonPath = Path.Combine(Environment.CurrentDirectory, "update-settings.json"); AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath); AutoUpdater.ShowSkipButton = false; AutoUpdater.RunUpdateAsAdmin = RequiresAdminAccess(); AutoUpdater.Start(UPDATE_URL); } public static void SkipVersion(string version) { var settings = UpdateSettings.Load(); settings.SkipVersion(version); } public static void SetRemindAfter(TimeSpan delay) { var settings = UpdateSettings.Load(); settings.SetRemindAfter(DateTime.Now + delay); } private static async void HandleCheckForUpdateEvent(UpdateInfoEventArgs args) { try { var isManual = _isManualCheck; _isManualCheck = false; if (args.Error != null) { if (isManual) { Application.Current.Dispatcher.Invoke(() => SnackbarController.SendSnackbar(LocManager.GetCommonOrDefault("Request error", "RequestError"))); } return; } if (!args.IsUpdateAvailable) { if (isManual) { Application.Current.Dispatcher.Invoke(() => SnackbarController.SendSnackbar( LocManager.GetCodeBehindOrDefault("You are using the latest version", "UpdateService", "LatestVersion"))); } return; } var version = args.CurrentVersion; var settings = UpdateSettings.Load(); if (!isManual && !settings.ShouldShow(version)) { HasPendingUpdate = true; Application.Current.Dispatcher.Invoke(() => PendingUpdateDetected?.Invoke()); return; } ChangelogEntry? changelog = null; try { var jsonUrl = $"{CHANGELOG_BASE_URL}{version}.json"; var response = await HttpClient.GetAsync(jsonUrl).ConfigureAwait(false); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false); changelog = JsonConvert.DeserializeObject(json); } } catch { // fallback to HTML changelog URL } var htmlFallbackUrl = changelog == null ? args.ChangelogURL : null; await Application.Current.Dispatcher.BeginInvoke(async () => { await DialogsController.ShowUpdateDialog(args, changelog, htmlFallbackUrl); }); } catch (Exception e) { Shell.Logger.Error(e, "Error while checking updates"); } } private static bool RequiresAdminAccess() { try { var testFile = Path.Combine(Environment.CurrentDirectory, "test.tmp"); using (File.Create(testFile)) { } File.Delete(testFile); return false; } catch (UnauthorizedAccessException) { return true; } } }