Files
rssotto-csharp-client/ModVersionChecker/VersionChecker.cs
2025-09-04 10:14:30 +02:00

146 lines
5.6 KiB
C#

using ModVersionChecker.data.model;
using ModVersionChecker.forms;
using ModVersionChecker.managers.interfaces;
using ModVersionChecker.utils;
using NuGet.Versioning;
using OpenQA.Selenium.BiDi.Script;
using System.Windows.Forms;
namespace ModVersionChecker
{
public class VersionChecker
{
private readonly IConfigManager _configManager;
private readonly IAppsManager _appsManager;
private readonly ISourcesDefManager _sourcesDefManager;
private readonly INotifyIconService _notifyIconService;
private readonly IFlightSimsManager _fsManager;
private List<string> errorMessages = new List<string>();
private List<string> updateMessages = new List<string>();
private NotifyIcon? _notifyIcon;
public event EventHandler<string>? OnFinished;
public VersionChecker(
IConfigManager configManager,
IAppsManager appsManager,
ISourcesDefManager sourcesDefManager,
INotifyIconService notifyIconService,
IFlightSimsManager fsManager)
{
_configManager = configManager ?? throw new ArgumentNullException(nameof(configManager));
_appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager));
_sourcesDefManager = sourcesDefManager ?? throw new ArgumentNullException(nameof(sourcesDefManager));
_notifyIconService = notifyIconService ?? throw new ArgumentNullException(nameof(notifyIconService));
_fsManager = fsManager ?? throw new ArgumentNullException(nameof(fsManager));
}
private void HandleAppError(string message, AppConfig app)
{
errorMessages.Add(message);
_appsManager.UpdateStatus(app, AppStatus.Error);
}
public void StartVersionChecking(NotifyIcon notifyIcon)
{
var config = _configManager.Load() ?? new GlobalConfig();
_notifyIcon = notifyIcon ?? throw new ArgumentNullException(nameof(notifyIcon));
// Run version checks in a background thread
new Thread(async () =>
{
while (true)
{
await CheckAsync();
Thread.Sleep(config.IntervalMinutes * 60 * 1000);
}
})
{ IsBackground = true }.Start();
}
public async Task CheckAsync()
{
var config = _configManager.Load() ?? new GlobalConfig();
var apps = _appsManager.Load() ?? new List<AppConfig>();
var sources = _sourcesDefManager.List() ?? new List<SourceDef>();
var fsMods = _fsManager.Load() ?? new List<FsModPathConfig>();
updateMessages = new List<string>();
errorMessages = new List<string>();
foreach (AppConfig app in apps)
{
if (app.Status != AppStatus.Error && app.LastCheckedAt != 0 && app.LastCheckedAt < TimeUtils.GetUnixTimeMillis(DateTime.Now.AddMinutes(-60)))
continue;
var status = AppStatus.None;
var sourceId = app.Source;
if (string.IsNullOrWhiteSpace(sourceId))
{
HandleAppError($"{app.Name} has no source configured.", app);
continue;
}
var source = sources.FirstOrDefault(s => s.Id == sourceId);
if (source == null)
{
HandleAppError($"{app.Name} has an invalid source: {sourceId}", app);
continue;
}
try
{
foreach (var fsVersion in app.MsfsVersions)
{
var fsConfig = _fsManager.GetByShortName(fsVersion);
if (fsConfig == null)
{
HandleAppError($"{app.Name} has no FS mod path configured for version {fsVersion}.", app);
continue;
}
var checker = CheckerFactory.CreateChecker(source.Type);
var current = NuGetVersion.Parse(VersionUtils.GetCurrentVersion(app, fsConfig));
var latest = NuGetVersion.Parse(await checker.GetLatestVersion(app.Params, source));
app.CurrentVersion = current.ToString();
app.LatestVersion = latest.ToString();
if (latest.CompareTo(current) == 1)
{
updateMessages.Add($"{app.Name}: New version {latest} (current: {current})");
status = AppStatus.UpdateAvailable;
}
}
_appsManager.UpdateStatus(app, status);
}
catch (Exception ex)
{
HandleAppError($"Failed for {app.Name}: {ex.Message}", app);
}
}
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
);
}
OnFinished?.Invoke(this, "Version check completed.");
}
}
}