using ModVersionChecker.enums; using ModVersionChecker.managers.interfaces; using ModVersionChecker.model; using ModVersionChecker.service.interfaces; using ModVersionChecker.utils; using NuGet.Versioning; namespace ModVersionChecker.service { public class VersionService: IVersionService { private readonly IApiService _apiService; private readonly IAppsManager _appsManager; private readonly INotifyIconService _notifyIconService; private readonly Config _globalConfig; public VersionService( IApiService apiVersionService, IAppsManager appsManager, IConfigManager configManager, INotifyIconService notifyIconService) { _apiService = apiVersionService; _appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager)); _notifyIconService = notifyIconService ?? throw new ArgumentNullException(nameof(notifyIconService)); _globalConfig = configManager.Load() ?? new Config(); } public App CheckApp(App app) { var status = AppStatus.NONE; if (app.LatestVersion== null) { app.Status = AppStatus.ERROR; _appsManager.Update(app); return app; } var currentVersion = app.CurrentVersion; var updateMessage = ""; if (isUpdateAvailable(currentVersion, app.LatestVersion)) { updateMessage = $"{app.Name}: New version {app.LatestVersion} (current: {currentVersion})"; status = AppStatus.UPDATE_AVAILABLE; } app.Status = status; app.LastCheckedAt = TimeUtils.GetUnixTimeMillis(null); _appsManager.Update(app); return app; } public async Task CheckAllApps() { var apps = _appsManager.Load(); var sources = await _apiService.GetSources(); var appVersionsMap = await _apiService.GetAppVersionsAsync(apps); List errorMessages = new List(); List updateMessages = new List(); if (apps == null || apps.Count == 0) { return; } foreach (App app in apps) { var sourceId = app.Source; if ( app.Status != AppStatus.ERROR && app.LastCheckedAt != 0 && app.LastCheckedAt < TimeUtils.GetUnixTimeMillis(DateTime.UtcNow.AddMinutes(-60)) || !app.Active || string.IsNullOrWhiteSpace(sourceId) ) { continue; } try { var latesstVersion = appVersionsMap.FirstOrDefault(a => a.Id == app.Id)?.LatestVersion; var source = sources.FirstOrDefault(s => s.Id == sourceId); if (source == null) { errorMessages.Add($"{app.Name} has an invalid source: {sourceId}"); continue; } var typeConfig = _globalConfig.Types.FirstOrDefault(t => t.ShortName == app.Type); if (typeConfig == null) { errorMessages.Add($"{app.Name} has no valid type config."); continue; } app.CurrentVersion = VersionUtils.GetCurrentVersion(app, typeConfig); var updatedApp = CheckApp(app); if (updatedApp.Status == AppStatus.UPDATE_AVAILABLE) { updateMessages.Add($"{app.Name}: New version {app.LatestVersion} (current: {app.CurrentVersion})"); } } catch (Exception ex) { errorMessages.Add($"Failed to check {app.Name}: {ex.Message}"); } } if (updateMessages.Count > 0) { _notifyIconService.ShowBalloonTip( 10000, "Updates Available", string.Join("\n", updateMessages), ToolTipIcon.Info ); } if (errorMessages.Count > 0) { _notifyIconService.ShowBalloonTip( 10000, "Errors", string.Join("\n", errorMessages), ToolTipIcon.Error ); } } private bool isUpdateAvailable(string currentVersion, string latestVersion) { try { var current = NuGetVersion.Parse(currentVersion); var latest = NuGetVersion.Parse(latestVersion); return latest.CompareTo(current) == 1; } catch (Exception ex) { Console.WriteLine($"Failed to compare versions: {ex.Message}"); return false; } } } }