diff --git a/StarterNG.Tests/UpdateCheckTests.cs b/StarterNG.Tests/UpdateCheckTests.cs
deleted file mode 100644
index 434bb6d..0000000
--- a/StarterNG.Tests/UpdateCheckTests.cs
+++ /dev/null
@@ -1,291 +0,0 @@
-using System.Net;
-using System.Net.Http;
-using StarterNG.Application;
-using StarterNG.Application.Abstractions;
-using StarterNG.Domain.Settings;
-using StarterNG.Infrastructure.Adapters;
-using StarterNG.Tests.Fakes;
-
-namespace StarterNG.Tests;
-
-public class UpdateCheckTests
-{
- private const string Page = "https://github.com/MaSzyna-EU07/StarterNG/releases/tag/v1.4.107";
- private const string StagingPage = "https://github.com/MaSzyna-EU07/StarterNG/releases/tag/staging";
- private const string RecordPath = "/home/user/.config/starter/updatecheck.txt";
- private const string RunningCommit = "9d981cb0932c372074eaba25d5c917acbacc25d8";
- private const string OtherCommit = "f7219cf7055670ad0f39fc18e0640358b8fff8f7";
-
- private static readonly Version Current = new(1, 4, 100, 0);
-
- [Theory]
- [InlineData("v1.4.107")]
- [InlineData("v1.5.0")]
- [InlineData("1.4.101")]
- public async Task A_higher_release_is_an_update(string tag)
- {
- var check = new Rig(new StubFeed(Stable(tag))).Check;
-
- Assert.Equal(UpdateCheckOutcome.UpdateAvailable, await check.CheckNowAsync(UpdateChannel.Stable));
- Assert.Equal(UpdateCheck.ParseTag(tag)!.ToString(), check.Available!.Label);
- Assert.Equal(Page, check.Available.PageUrl);
- }
-
- [Theory]
- [InlineData("v1.4.100")]
- [InlineData("v1.4.99")]
- [InlineData("v1.3.500")]
- [InlineData("staging")]
- [InlineData("v1.5.0-rc1")]
- public async Task The_same_an_older_or_an_unversioned_release_is_not(string tag)
- {
- var check = new Rig(new StubFeed(Stable(tag))).Check;
-
- Assert.Equal(UpdateCheckOutcome.UpToDate, await check.CheckNowAsync(UpdateChannel.Stable));
- Assert.Null(check.Available);
- }
-
- [Fact]
- public async Task No_answer_is_reported_as_such_and_not_remembered()
- {
- var rig = new Rig(new StubFeed(lookup: ReleaseLookup.NoAnswer));
-
- Assert.Equal(UpdateCheckOutcome.NoAnswer, await rig.Check.CheckNowAsync(UpdateChannel.Stable));
- Assert.False(rig.Files.FileExists(RecordPath));
- }
-
- [Fact]
- public async Task The_daily_check_asks_once_a_day_and_keeps_showing_the_answer()
- {
- var feed = new StubFeed(Stable("v1.4.107"));
- var rig = new Rig(feed);
- await rig.Check.CheckDailyAsync();
-
- // A second start the same day: no request, the update still shown.
- var again = rig.Restart();
- await again.CheckDailyAsync();
-
- Assert.Equal(1, feed.Calls);
- Assert.Equal("1.4.107", again.Available!.Label);
- }
-
- [Fact]
- public async Task The_next_day_it_asks_again()
- {
- var feed = new StubFeed(Stable("v1.4.107"));
- var rig = new Rig(feed);
- await rig.Check.CheckDailyAsync();
-
- rig.Clock.Now = rig.Clock.Now.AddDays(1);
- await rig.Restart().CheckDailyAsync();
-
- Assert.Equal(2, feed.Calls);
- }
-
- [Fact]
- public async Task A_remembered_release_already_installed_is_not_offered()
- {
- var rig = new Rig(new StubFeed(Stable("v1.4.107")));
- await rig.Check.CheckDailyAsync();
-
- var upgraded = rig.Restart(current: new Version(1, 4, 107, 0));
- await upgraded.CheckDailyAsync();
-
- Assert.Null(upgraded.Available);
- }
-
- [Fact]
- public async Task Switching_the_channel_asks_again_the_same_day()
- {
- var feed = new StubFeed(Stable("v1.4.107"));
- var rig = new Rig(feed);
- await rig.Check.CheckDailyAsync();
-
- rig.Settings.UpdateChannel = UpdateChannel.Staging;
- await rig.Restart().CheckDailyAsync();
-
- Assert.Equal(2, feed.Calls);
- Assert.Equal(UpdateChannel.Staging, feed.LastChannel);
- }
-
- [Fact]
- public async Task Switched_off_the_daily_check_does_not_ask_but_the_button_does()
- {
- var feed = new StubFeed(Stable("v9.0.0"));
- var rig = new Rig(feed);
- rig.Settings.CheckForUpdates = false;
-
- await rig.Check.CheckDailyAsync();
- Assert.Equal(0, feed.Calls);
-
- Assert.Equal(UpdateCheckOutcome.UpdateAvailable, await rig.Check.CheckNowAsync(UpdateChannel.Stable));
- }
-
- [Fact]
- public async Task A_staging_build_from_another_commit_is_offered()
- {
- var check = new Rig(new StubFeed(Staging(OtherCommit))).Check;
-
- Assert.Equal(UpdateCheckOutcome.UpdateAvailable, await check.CheckNowAsync(UpdateChannel.Staging));
- Assert.Equal("staging f7219cf", check.Available!.Label);
- Assert.Equal(StagingPage, check.Available.PageUrl);
- }
-
- [Fact]
- public async Task The_staging_build_already_running_is_not()
- {
- var check = new Rig(new StubFeed(Staging(RunningCommit))).Check;
-
- Assert.Equal(UpdateCheckOutcome.UpToDate, await check.CheckNowAsync(UpdateChannel.Staging));
- }
-
- [Fact]
- public async Task Finding_an_update_tells_the_top_bar()
- {
- var check = new Rig(new StubFeed(Stable("v1.4.107"))).Check;
- int changes = 0;
- check.Changed += () => changes++;
-
- await check.CheckNowAsync(UpdateChannel.Stable);
- await check.CheckNowAsync(UpdateChannel.Stable);
-
- Assert.Equal(1, changes);
- }
-
- [Fact]
- public void The_commit_is_read_from_the_informational_version()
- {
- Assert.Equal(RunningCommit, UpdateCheck.CommitOf("1.4.113+" + RunningCommit));
- Assert.Null(UpdateCheck.CommitOf("1.4.113"));
- Assert.Null(UpdateCheck.CommitOf(null));
- }
-
- [Fact]
- public void The_four_part_assembly_version_matches_a_three_part_tag()
- {
- Assert.Equal(new Version(1, 4, 0), UpdateCheck.ParseTag("v1.4"));
- Assert.Equal(new Version(1, 4, 107), UpdateCheck.ParseTag("V1.4.107"));
- }
-
- [Fact]
- public async Task The_feed_reads_a_stable_release()
- {
- var feed = Feed(HttpStatusCode.OK,
- $$"""{"tag_name":"v1.4.107","html_url":"{{Page}}","target_commitish":"{{OtherCommit}}","prerelease":false}""");
-
- var lookup = await feed.LatestAsync(UpdateChannel.Stable);
-
- Assert.True(lookup.Answered);
- Assert.Equal(new ReleaseInfo("v1.4.107", Page, OtherCommit), lookup.Release);
- }
-
- [Fact]
- public async Task The_stable_feed_skips_a_pre_release_and_the_staging_feed_takes_it()
- {
- string json = $$"""{"tag_name":"staging","html_url":"{{StagingPage}}","target_commitish":"{{OtherCommit}}","prerelease":true}""";
-
- Assert.Null((await Feed(HttpStatusCode.OK, json).LatestAsync(UpdateChannel.Stable)).Release);
- Assert.Equal(OtherCommit, (await Feed(HttpStatusCode.OK, json).LatestAsync(UpdateChannel.Staging)).Release!.Commit);
- }
-
- [Fact]
- public async Task The_staging_feed_asks_for_the_staging_tag()
- {
- string? asked = null;
- var feed = new GitHubReleaseFeed(new TestInstallation().Log, Current, new StubHandler(request =>
- {
- asked = request.RequestUri!.AbsolutePath;
- return Respond(HttpStatusCode.NotFound, "{}");
- }));
-
- await feed.LatestAsync(UpdateChannel.Staging);
-
- Assert.EndsWith("/releases/tags/staging", asked);
- }
-
- [Fact]
- public async Task Nothing_released_yet_is_an_answer()
- {
- var lookup = await Feed(HttpStatusCode.NotFound, """{"message":"Not Found"}""").LatestAsync(UpdateChannel.Stable);
-
- Assert.True(lookup.Answered);
- Assert.Null(lookup.Release);
- }
-
- [Fact]
- public async Task No_network_is_no_answer_and_nothing_in_the_log()
- {
- var log = new TestInstallation().Log;
- var feed = new GitHubReleaseFeed(log, Current, new StubHandler(_ => throw new HttpRequestException("offline")));
-
- Assert.False((await feed.LatestAsync(UpdateChannel.Stable)).Answered);
- Assert.Equal("", log.Text);
- }
-
- [Fact]
- public async Task A_broken_answer_is_logged()
- {
- var log = new TestInstallation().Log;
- var feed = new GitHubReleaseFeed(log, Current, new StubHandler(_ => Respond(HttpStatusCode.OK, "")));
-
- Assert.False((await feed.LatestAsync(UpdateChannel.Stable)).Answered);
- Assert.Contains("update check", log.Text);
- }
-
- private static ReleaseLookup Stable(string tag) => ReleaseLookup.Found(new ReleaseInfo(tag, Page));
-
- private static ReleaseLookup Staging(string commit) =>
- ReleaseLookup.Found(new ReleaseInfo("staging", StagingPage, commit));
-
- private static GitHubReleaseFeed Feed(HttpStatusCode status, string body) =>
- new(new TestInstallation().Log, Current, new StubHandler(_ => Respond(status, body)));
-
- private static HttpResponseMessage Respond(HttpStatusCode status, string body) =>
- new(status) { Content = new StringContent(body) };
-
- /// One installation's worth of update checking, restartable on the same disk.
- private sealed class Rig
- {
- private readonly IReleaseFeed _feed;
- private readonly TestInstallation _installation;
-
- public Rig(IReleaseFeed feed)
- {
- _feed = feed;
- _installation = new TestInstallation(Files, new DateTime(2026, 10, 4, 9, 0, 0));
- Check = Restart();
- }
-
- public InMemoryFileSystem Files { get; } = new();
-
- public SimulatorSettings Settings { get; } = new();
-
- public FixedClock Clock => _installation.Clock;
-
- public UpdateCheck Check { get; }
-
- public UpdateCheck Restart(Version? current = null) =>
- new(Settings, _feed, current ?? Current, RunningCommit, Files, Clock, _installation.Log, RecordPath);
- }
-
- private sealed class StubFeed(ReleaseLookup lookup) : IReleaseFeed
- {
- public int Calls { get; private set; }
-
- public UpdateChannel? LastChannel { get; private set; }
-
- public Task LatestAsync(UpdateChannel channel, CancellationToken cancellationToken = default)
- {
- Calls++;
- LastChannel = channel;
- return Task.FromResult(lookup);
- }
- }
-
- private sealed class StubHandler(Func respond) : HttpMessageHandler
- {
- protected override Task SendAsync(HttpRequestMessage request,
- CancellationToken cancellationToken) =>
- Task.FromResult(respond(request));
- }
-}
diff --git a/StarterNG/Application/Abstractions/IReleaseFeed.cs b/StarterNG/Application/Abstractions/IReleaseFeed.cs
deleted file mode 100644
index 76c01d5..0000000
--- a/StarterNG/Application/Abstractions/IReleaseFeed.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Threading;
-using System.Threading.Tasks;
-using StarterNG.Domain.Settings;
-
-namespace StarterNG.Application.Abstractions;
-
-///
-/// A published build of the starter: its tag, the page it is downloaded from and
-/// the commit it was built from - the only way to tell rolling builds apart.
-///
-public sealed record ReleaseInfo(string Tag, string PageUrl, string? Commit = null);
-
-///
-/// What asking for the newest release came back with. No answer - offline, rate
-/// limited, timed out - is kept apart from an answer of "nothing released", so a
-/// failed check is not remembered as a done one.
-///
-public sealed record ReleaseLookup(bool Answered, ReleaseInfo? Release)
-{
- public static ReleaseLookup NoAnswer { get; } = new(false, null);
-
- public static ReleaseLookup Found(ReleaseInfo? release) => new(true, release);
-}
-
-public interface IReleaseFeed
-{
- Task LatestAsync(UpdateChannel channel, CancellationToken cancellationToken = default);
-}
diff --git a/StarterNG/Application/AppServices.cs b/StarterNG/Application/AppServices.cs
index a2cb1cc..744912b 100644
--- a/StarterNG/Application/AppServices.cs
+++ b/StarterNG/Application/AppServices.cs
@@ -1,5 +1,4 @@
using System;
-using System.Reflection;
using StarterNG.Application.Abstractions;
using StarterNG.Domain.Settings;
using StarterNG.Infrastructure.Adapters;
@@ -54,12 +53,6 @@ public sealed class AppServices
SettingsStore = new SettingsStore(files, clock, log, settingsPaths, new SettingsSerializer(), Executables);
MissingVehicleLog = new MissingVehicleLog(SettingsStore.Settings, MissingAssets, Library, log);
Favorites = new FavoriteSceneries(files, log, settingsPaths.FavoritesPath());
- var assembly = typeof(AppServices).Assembly;
- var version = assembly.GetName().Version ?? new Version(0, 0);
- string? commit = UpdateCheck.CommitOf(
- assembly.GetCustomAttribute()?.InformationalVersion);
- Updates = new UpdateCheck(SettingsStore.Settings, new GitHubReleaseFeed(log, version), version, commit,
- files, clock, log, settingsPaths.UpdateCheckPath());
StartSimulation = new StartSimulation(State, SettingsStore, Library.Vehicles, Executables, files, paths,
Processes, Random, log);
Aftermath = new SimulatorAftermath(files, paths, log);
@@ -134,8 +127,6 @@ public sealed class AppServices
public MissingVehicleLog MissingVehicleLog { get; }
- public UpdateCheck Updates { get; }
-
public FavoriteSceneries Favorites { get; }
public StartSimulation StartSimulation { get; }
diff --git a/StarterNG/Application/UpdateCheck.cs b/StarterNG/Application/UpdateCheck.cs
deleted file mode 100644
index 3f475c7..0000000
--- a/StarterNG/Application/UpdateCheck.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-using System;
-using System.Globalization;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-using StarterNG.Application.Abstractions;
-using StarterNG.Domain.Settings;
-
-namespace StarterNG.Application;
-
-/// A build to offer: what to call it on the top bar and where to get it.
-public sealed record AvailableUpdate(string Label, string PageUrl);
-
-public enum UpdateCheckOutcome
-{
- UpToDate,
- UpdateAvailable,
- NoAnswer
-}
-
-public sealed class UpdateCheck
-{
- private const string DayFormat = "yyyy-MM-dd";
- private const int ShortCommit = 7;
-
- private readonly SimulatorSettings _settings;
- private readonly IReleaseFeed _feed;
- private readonly string? _commit;
- private readonly IFileSystem _files;
- private readonly IClock _clock;
- private readonly IDiagnosticsLog _log;
- private readonly string _recordPath;
-
- public UpdateCheck(SimulatorSettings settings, IReleaseFeed feed, Version current, string? commit,
- IFileSystem files, IClock clock, IDiagnosticsLog log, string recordPath)
- {
- _settings = settings;
- _feed = feed;
- _commit = commit;
- _files = files;
- _clock = clock;
- _log = log;
- _recordPath = recordPath;
- Current = Normalize(current);
- }
-
- public Version Current { get; }
-
- /// The build to offer, as last heard of; null when up to date or not asked yet.
- public AvailableUpdate? Available { get; private set; }
-
- public event Action? Changed;
-
- ///
- /// The check made on start. GitHub is asked at most once a day, and its answer
- /// is remembered, so a second start the same day still shows the update.
- ///
- public async Task CheckDailyAsync(CancellationToken cancellationToken = default)
- {
- if (!_settings.CheckForUpdates)
- return;
-
- var channel = _settings.UpdateChannel;
- if (ReadRecord() is { } record && record.Day == Today() && record.Channel == channel)
- {
- Publish(channel, record.Release);
- return;
- }
-
- await CheckNowAsync(channel, cancellationToken);
- }
-
- /// Asks straight away, whatever the switch in the settings says.
- public async Task CheckNowAsync(UpdateChannel channel,
- CancellationToken cancellationToken = default)
- {
- var lookup = await _feed.LatestAsync(channel, cancellationToken);
-
- // Not recorded, so the next start asks again instead of waiting a day.
- if (!lookup.Answered)
- return UpdateCheckOutcome.NoAnswer;
-
- WriteRecord(channel, lookup.Release);
- Publish(channel, lookup.Release);
- return Available is null ? UpdateCheckOutcome.UpToDate : UpdateCheckOutcome.UpdateAvailable;
- }
-
- ///
- /// "v1.4.107" as 1.4.107. Anything that is not a plain version - a suffix, a
- /// rolling tag like "staging" - is not an update.
- ///
- public static Version? ParseTag(string tag)
- {
- string text = tag.StartsWith('v') || tag.StartsWith('V') ? tag[1..] : tag;
- return Version.TryParse(text, out var version) ? Normalize(version) : null;
- }
-
- /// The commit a build carries after the "+" of its informational version.
- public static string? CommitOf(string? informationalVersion)
- {
- int plus = informationalVersion?.IndexOf('+') ?? -1;
- return plus >= 0 && plus < informationalVersion!.Length - 1 ? informationalVersion[(plus + 1)..] : null;
- }
-
- private void Publish(UpdateChannel channel, ReleaseInfo? release)
- {
- // Compared again on every start: the build remembered this morning may be
- // the very one installed since.
- var available = channel == UpdateChannel.Staging ? StagingUpdate(release) : StableUpdate(release);
- if (available == Available)
- return;
-
- Available = available;
- Changed?.Invoke();
- }
-
- private AvailableUpdate? StableUpdate(ReleaseInfo? release) =>
- release is not null && ParseTag(release.Tag) is { } version && version > Current
- ? new AvailableUpdate(version.ToString(), release.PageUrl)
- : null;
-
- // The staging build has no version of its own, only its commit, and the newest
- // one is the only one there is: any build but the running one is worth offering.
- private AvailableUpdate? StagingUpdate(ReleaseInfo? release) =>
- release is { Commit: { Length: > 0 } commit } && !SameCommit(commit, _commit)
- ? new AvailableUpdate($"{release.Tag} {commit[..Math.Min(ShortCommit, commit.Length)]}", release.PageUrl)
- : null;
-
- private static bool SameCommit(string a, string? b) =>
- !string.IsNullOrEmpty(b) &&
- (a.StartsWith(b, StringComparison.OrdinalIgnoreCase) || b.StartsWith(a, StringComparison.OrdinalIgnoreCase));
-
- private string Today() => _clock.Now.ToString(DayFormat, CultureInfo.InvariantCulture);
-
- private (string Day, UpdateChannel Channel, ReleaseInfo? Release)? ReadRecord()
- {
- try
- {
- if (!_files.FileExists(_recordPath))
- return null;
-
- string[] lines = _files.ReadAllText(_recordPath).Split('\n', StringSplitOptions.TrimEntries);
- if (lines.Length < 5 || !Enum.TryParse(lines[1], out UpdateChannel channel))
- return null;
-
- var release = lines[2].Length > 0 && lines[3].Length > 0
- ? new ReleaseInfo(lines[2], lines[3], lines[4].Length > 0 ? lines[4] : null)
- : null;
- return (lines[0], channel, release);
- }
- catch (Exception ex)
- {
- _log.Log($"reading {_recordPath}", ex);
- return null;
- }
- }
-
- private void WriteRecord(UpdateChannel channel, ReleaseInfo? release)
- {
- try
- {
- if (Path.GetDirectoryName(_recordPath) is { Length: > 0 } directory)
- _files.CreateDirectory(directory);
-
- _files.WriteAllText(_recordPath, string.Join('\n', Today(), channel, release?.Tag ?? "",
- release?.PageUrl ?? "", release?.Commit ?? ""));
- }
- catch (Exception ex)
- {
- _log.Log($"writing {_recordPath}", ex);
- }
- }
-
- // The assembly carries four parts and the tags three; an unset part reads as -1.
- private static Version Normalize(Version version) =>
- new(version.Major, version.Minor, Math.Max(version.Build, 0));
-}
diff --git a/StarterNG/Domain/Settings/SimulatorSettings.cs b/StarterNG/Domain/Settings/SimulatorSettings.cs
index 5dc28f8..e1dea3c 100644
--- a/StarterNG/Domain/Settings/SimulatorSettings.cs
+++ b/StarterNG/Domain/Settings/SimulatorSettings.cs
@@ -36,8 +36,6 @@ public sealed class SimulatorSettings
public bool VirtualShunting = true;
public bool LogMissingVehicleFiles;
public bool DeveloperTools;
- public bool CheckForUpdates = true;
- public UpdateChannel UpdateChannel = UpdateChannel.Stable;
public int RenderEngine;
public int Width = 1280;
diff --git a/StarterNG/Domain/Settings/UpdateChannel.cs b/StarterNG/Domain/Settings/UpdateChannel.cs
deleted file mode 100644
index 8f6b032..0000000
--- a/StarterNG/Domain/Settings/UpdateChannel.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace StarterNG.Domain.Settings;
-
-/// Which builds the starter offers as updates.
-public enum UpdateChannel
-{
- /// The versioned releases of main.
- Stable,
-
- /// The rolling pre-release of the staging branch, for testers.
- Staging
-}
diff --git a/StarterNG/Infrastructure/Adapters/GitHubReleaseFeed.cs b/StarterNG/Infrastructure/Adapters/GitHubReleaseFeed.cs
deleted file mode 100644
index 002f678..0000000
--- a/StarterNG/Infrastructure/Adapters/GitHubReleaseFeed.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Threading;
-using System.Threading.Tasks;
-using StarterNG.Application.Abstractions;
-using StarterNG.Domain.Settings;
-
-namespace StarterNG.Infrastructure.Adapters;
-
-public sealed class GitHubReleaseFeed : IReleaseFeed
-{
- private const string ReleasesUrl = "https://api.github.com/repos/MaSzyna-EU07/StarterNG/releases/";
-
- /// The tag CI keeps recreating for every build of the staging branch.
- public const string StagingTag = "staging";
-
- private readonly HttpClient _http;
- private readonly IDiagnosticsLog _log;
-
- public GitHubReleaseFeed(IDiagnosticsLog log, Version current, HttpMessageHandler? handler = null)
- {
- _log = log;
- _http = handler is null ? new HttpClient() : new HttpClient(handler);
- _http.Timeout = TimeSpan.FromSeconds(10);
-
- // The API turns away requests without a User-Agent.
- _http.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("StarterNG", current.ToString()));
- _http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json"));
- }
-
- public async Task LatestAsync(UpdateChannel channel, CancellationToken cancellationToken = default)
- {
- // "latest" is GitHub's own pick: the newest release that is not a pre-release.
- string url = ReleasesUrl + (channel == UpdateChannel.Staging ? "tags/" + StagingTag : "latest");
-
- try
- {
- using var response = await _http.GetAsync(url, cancellationToken);
-
- // Nothing released yet.
- if (response.StatusCode == HttpStatusCode.NotFound)
- return ReleaseLookup.Found(null);
-
- response.EnsureSuccessStatusCode();
- return ReleaseLookup.Found(Parse(await response.Content.ReadAsStringAsync(cancellationToken), channel));
- }
- // Offline, rate limited or timed out: there is simply no answer this time,
- // and a log entry on every start without a network would only be noise.
- catch (HttpRequestException)
- {
- return ReleaseLookup.NoAnswer;
- }
- catch (TaskCanceledException)
- {
- return ReleaseLookup.NoAnswer;
- }
- catch (Exception ex)
- {
- _log.Log("update check", ex);
- return ReleaseLookup.NoAnswer;
- }
- }
-
- public static ReleaseInfo? Parse(string json, UpdateChannel channel)
- {
- var release = JsonSerializer.Deserialize(json, GitHubReleaseContext.Default.GitHubReleaseDocument);
- if (release is null || release.Draft ||
- string.IsNullOrEmpty(release.TagName) || string.IsNullOrEmpty(release.HtmlUrl))
- return null;
-
- bool belongs = channel == UpdateChannel.Staging
- ? release.TagName == StagingTag
- : !release.Prerelease;
-
- return belongs ? new ReleaseInfo(release.TagName, release.HtmlUrl, release.TargetCommitish) : null;
- }
-}
-
-internal sealed class GitHubReleaseDocument
-{
- [JsonPropertyName("tag_name")] public string? TagName { get; set; }
-
- [JsonPropertyName("html_url")] public string? HtmlUrl { get; set; }
-
- [JsonPropertyName("target_commitish")] public string? TargetCommitish { get; set; }
-
- [JsonPropertyName("draft")] public bool Draft { get; set; }
-
- [JsonPropertyName("prerelease")] public bool Prerelease { get; set; }
-}
-
-[JsonSerializable(typeof(GitHubReleaseDocument))]
-internal partial class GitHubReleaseContext : JsonSerializerContext
-{
-}
diff --git a/StarterNG/Infrastructure/Settings/SettingsPaths.cs b/StarterNG/Infrastructure/Settings/SettingsPaths.cs
index 0864b19..a80a297 100644
--- a/StarterNG/Infrastructure/Settings/SettingsPaths.cs
+++ b/StarterNG/Infrastructure/Settings/SettingsPaths.cs
@@ -53,9 +53,6 @@ public sealed class SettingsPaths
/// The sceneries starred in the list.
public string FavoritesPath() => Path.Combine(UserConfigDirectory(), "favorites.txt");
- /// The day of the last update check and the release it found.
- public string UpdateCheckPath() => Path.Combine(UserConfigDirectory(), "updatecheck.txt");
-
public string UserConfigDirectory() =>
Path.GetDirectoryName(UserConfigPath()) ?? _environment.BaseDirectory;
}
diff --git a/StarterNG/Infrastructure/Settings/SettingsSerializer.cs b/StarterNG/Infrastructure/Settings/SettingsSerializer.cs
index f7e2e0e..79260d8 100644
--- a/StarterNG/Infrastructure/Settings/SettingsSerializer.cs
+++ b/StarterNG/Infrastructure/Settings/SettingsSerializer.cs
@@ -57,11 +57,6 @@ public sealed class SettingsSerializer
s.VirtualShunting = c.GetBool("ai.trainman", true);
s.LogMissingVehicleFiles = c.GetBool("starter.logmissingvehicles", false);
s.DeveloperTools = c.GetBool("starter.developertools", false);
- s.CheckForUpdates = c.GetBool("starter.checkupdates", true);
- s.UpdateChannel = string.Equals(c.GetString("starter.updatechannel", "stable"), "staging",
- StringComparison.OrdinalIgnoreCase)
- ? UpdateChannel.Staging
- : UpdateChannel.Stable;
s.RenderEngine = IndexOf(SimulatorSettings.RenderEngines, c.GetString("gfxrenderer", "full"), 0);
s.Width = c.GetInt("width", 1280);
@@ -202,8 +197,6 @@ public sealed class SettingsSerializer
c.SetBool("ai.trainman", s.VirtualShunting);
c.SetBool("starter.logmissingvehicles", s.LogMissingVehicleFiles);
c.SetBool("starter.developertools", s.DeveloperTools);
- c.SetBool("starter.checkupdates", s.CheckForUpdates);
- c.Set("starter.updatechannel", s.UpdateChannel == UpdateChannel.Staging ? "staging" : "stable");
c.Set("gfxrenderer", SimulatorSettings.RenderEngines[Clamp(s.RenderEngine, 0, SimulatorSettings.RenderEngines.Length - 1)]);
c.SetInt("width", s.Width);
diff --git a/StarterNG/MainWindow.axaml b/StarterNG/MainWindow.axaml
index 7f3ce12..c631bd1 100644
--- a/StarterNG/MainWindow.axaml
+++ b/StarterNG/MainWindow.axaml
@@ -55,16 +55,6 @@
-
-
diff --git a/StarterNG/MainWindow.axaml.cs b/StarterNG/MainWindow.axaml.cs
index 2cc5225..286f9ba 100644
--- a/StarterNG/MainWindow.axaml.cs
+++ b/StarterNG/MainWindow.axaml.cs
@@ -57,7 +57,6 @@ public partial class MainWindow : Window
RoutingStrategies.Tunnel);
SettingsView.DeveloperToolsChanged += ApplyDeveloperTab;
- AppServices.Current.Updates.Changed += ShowUpdate;
SettingsView.ThumbnailSizeChanged += () =>
{
@@ -86,11 +85,6 @@ public partial class MainWindow : Window
_openedUtc = DateTime.UtcNow;
UpdateStartButton();
-#if !DEBUG
- // A local build carries the bare major.minor, older than any release;
- // the button in the settings still checks on demand.
- _ = AppServices.Current.Updates.CheckDailyAsync();
-#endif
};
Activated += (_, _) => CheckExternalSettings();
}
@@ -258,26 +252,8 @@ public partial class MainWindow : Window
App.ApplyLanguage(code);
}
- private void ShowUpdate()
- {
- var update = AppServices.Current.Updates.Available;
- UpdateButton.IsVisible = update is not null;
- if (update is null)
- return;
-
- UpdateText.Text = string.Format(App.Loc["UpdateAvailable"], update.Label);
- ToolTip.SetTip(UpdateButton, string.Format(App.Loc["UpdateAvailableTip"], update.Label));
- }
-
- private void UpdateButton_OnClick(object? sender, RoutedEventArgs e)
- {
- if (AppServices.Current.Updates.Available is { } update)
- AppServices.Current.Processes.OpenInShell(update.PageUrl);
- }
-
private void OnLanguageChanged()
{
- ShowUpdate();
SelectActiveLanguage();
ScenariosView?.RebuildAfterLanguageChange();
DepotView?.RebuildAfterLanguageChange();
diff --git a/StarterNG/Views/Settings.axaml b/StarterNG/Views/Settings.axaml
index 4378719..95873eb 100644
--- a/StarterNG/Views/Settings.axaml
+++ b/StarterNG/Views/Settings.axaml
@@ -109,26 +109,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/StarterNG/Views/Settings.axaml.cs b/StarterNG/Views/Settings.axaml.cs
index 9b0b740..dbc46ac 100644
--- a/StarterNG/Views/Settings.axaml.cs
+++ b/StarterNG/Views/Settings.axaml.cs
@@ -260,8 +260,6 @@ public partial class Settings : UserControl, ISettingsCapture
VirtualShuntingCb.IsChecked = s.VirtualShunting;
LogMissingVehicleFilesCb.IsChecked = s.LogMissingVehicleFiles;
DeveloperToolsCb.IsChecked = s.DeveloperTools;
- CheckUpdatesCb.IsChecked = s.CheckForUpdates;
- UpdateChannelCb.SelectedIndex = s.UpdateChannel == UpdateChannel.Staging ? 1 : 0;
RenderEngineCb.SelectedIndex = s.RenderEngine;
SelectResolution(s.Width, s.Height);
@@ -361,8 +359,6 @@ public partial class Settings : UserControl, ISettingsCapture
s.VirtualShunting = IsChecked(VirtualShuntingCb);
s.LogMissingVehicleFiles = IsChecked(LogMissingVehicleFilesCb);
s.DeveloperTools = IsChecked(DeveloperToolsCb);
- s.CheckForUpdates = IsChecked(CheckUpdatesCb);
- s.UpdateChannel = SelectedChannel();
s.RenderEngine = Math.Max(0, RenderEngineCb.SelectedIndex);
ReadResolution(s);
@@ -455,36 +451,6 @@ public partial class Settings : UserControl, ISettingsCapture
SimulatorSettings.RenderEngines.ElementAtOrDefault(RenderEngineCb.SelectedIndex) == "experimental";
}
- private UpdateChannel SelectedChannel() =>
- UpdateChannelCb.SelectedIndex == 1 ? UpdateChannel.Staging : UpdateChannel.Stable;
-
- private void UpdateChannelCb_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
- {
- if (UpdateChannelWarning is not null)
- UpdateChannelWarning.IsVisible = SelectedChannel() == UpdateChannel.Staging;
- }
-
- /// Checks the channel picked in the list, saved or not, so it can be tried first.
- private async void CheckUpdatesNowButton_OnClick(object? sender, RoutedEventArgs e)
- {
- var updates = AppServices.Current.Updates;
- CheckUpdatesNowButton.IsEnabled = false;
- CheckUpdatesStatus.Text = App.Loc["UpdateChecking"];
- try
- {
- CheckUpdatesStatus.Text = await updates.CheckNowAsync(SelectedChannel()) switch
- {
- UpdateCheckOutcome.UpdateAvailable => string.Format(App.Loc["UpdateFound"], updates.Available!.Label),
- UpdateCheckOutcome.UpToDate => string.Format(App.Loc["UpdateUpToDate"], updates.Current),
- _ => App.Loc["UpdateCheckFailed"]
- };
- }
- finally
- {
- CheckUpdatesNowButton.IsEnabled = true;
- }
- }
-
private void RedrawNavIfNeeded()
{
bool developer = AppServices.Current.Settings.DeveloperTools;
diff --git a/StarterNG/startercfg/lang/cz.xml b/StarterNG/startercfg/lang/cz.xml
index 0064dc5..f9eafdc 100644
--- a/StarterNG/startercfg/lang/cz.xml
+++ b/StarterNG/startercfg/lang/cz.xml
@@ -356,18 +356,6 @@
Virtuální posun
Zaznamenat chybějící soubory vozidel při exportu
Show the package author's tab
- Kontrolovat aktualizace starteru
- Jednou denně zjistí na GitHubu, zda vyšla novější verze starteru, a zobrazí ji v horní liště. Testovací kanál nabízí buildy z větve staging.
- Aktualizace {0}
- Je k dispozici verze {0}. Kliknutím otevřete stránku ke stažení.
- Stabilní
- Testovací (staging)
- Upozornění: kanál se týká pouze starteru. Simulátor MaSzyna a jeho soubory se aktualizují zvlášť - tato volba je nemění.
- Zkontrolovat nyní
- Kontroluji…
- K dispozici je verze {0} - tlačítko je v horní liště.
- Máte nejnovější verzi ({0}).
- Nepodařilo se připojit ke GitHubu. Zkuste to později.
Grafika
Vykreslovací engine
diff --git a/StarterNG/startercfg/lang/en.xml b/StarterNG/startercfg/lang/en.xml
index 0c60b01..dfb6ffd 100644
--- a/StarterNG/startercfg/lang/en.xml
+++ b/StarterNG/startercfg/lang/en.xml
@@ -363,18 +363,6 @@
Writes vehicles the starter could not find into the log.
Show the package author's tab
Adds a tab with the state of the vehicle database, for preparing rolling stock packages.
- Check for starter updates
- Once a day, asks GitHub whether a newer starter has been released and shows it on the top bar. The testing channel offers builds of the staging branch.
- Update {0}
- Version {0} is available. Click to open its download page.
- Stable
- Testing (staging)
- Note: the channel applies to the starter only. The MaSzyna simulator and its files are updated separately - this choice does not change them.
- Check now
- Checking…
- Version {0} is available - see the button on the top bar.
- You have the newest version ({0}).
- Could not reach GitHub. Try again later.
Graphics
Render engine
diff --git a/StarterNG/startercfg/lang/hu.xml b/StarterNG/startercfg/lang/hu.xml
index 721329b..99071cf 100644
--- a/StarterNG/startercfg/lang/hu.xml
+++ b/StarterNG/startercfg/lang/hu.xml
@@ -356,18 +356,6 @@
Virtuális tolatás
Hiányzó járműfájlok naplózása exportáláskor
Show the package author's tab
- Starter frissítéseinek keresése
- Naponta egyszer ellenőrzi a GitHubon, hogy megjelent-e újabb starter-verzió, és megjeleníti a felső sávon. A teszt csatorna a staging ág buildjeit kínálja.
- Frissítés: {0}
- Elérhető a(z) {0} verzió. Kattints a letöltési oldal megnyitásához.
- Stabil
- Teszt (staging)
- Figyelem: a csatorna csak a startert érinti. A MaSzyna szimulátort és fájljait külön kell frissíteni - ez a választás nem módosítja őket.
- Ellenőrzés most
- Ellenőrzés…
- Elérhető a(z) {0} verzió - a gomb a felső sávon található.
- A legújabb verzió van telepítve ({0}).
- Nem sikerült elérni a GitHubot. Próbáld újra később.
Grafika
Megjelenítő motor
diff --git a/StarterNG/startercfg/lang/pl.xml b/StarterNG/startercfg/lang/pl.xml
index 90c13a3..e23f455 100644
--- a/StarterNG/startercfg/lang/pl.xml
+++ b/StarterNG/startercfg/lang/pl.xml
@@ -363,18 +363,6 @@
Zapisuje w logu pojazdy, których starter nie znalazł.
Pokaż zakładkę dla twórców paczek
Dodaje zakładkę ze stanem bazy pojazdów, przydatną przy przygotowywaniu paczek z taborem.
- Sprawdzaj aktualizacje startera
- Raz dziennie sprawdza na GitHubie, czy wyszła nowsza wersja startera, i pokazuje ją na górnym pasku. Kanał testowy to buildy z gałęzi staging.
- Aktualizacja {0}
- Dostępna jest wersja {0}. Kliknij, aby otworzyć stronę pobierania.
- Stabilne
- Testowe (staging)
- Uwaga: kanał dotyczy tylko startera. Symulator MaSzyna i jego pliki aktualizujesz osobno - ten wybór ich nie zmienia.
- Sprawdź teraz
- Sprawdzanie…
- Dostępna jest wersja {0} - przycisk pojawił się na górnym pasku.
- Masz najnowszą wersję ({0}).
- Nie udało się połączyć z GitHubem. Spróbuj później.
Grafika
Silnik renderowania
diff --git a/StarterNG/startercfg/lang/ru.xml b/StarterNG/startercfg/lang/ru.xml
index d557dcb..5afab3e 100644
--- a/StarterNG/startercfg/lang/ru.xml
+++ b/StarterNG/startercfg/lang/ru.xml
@@ -356,18 +356,6 @@
Виртуальный манёвр
Записывать в журнал отсутствующие файлы состава при экспорте
Show the package author's tab
- Проверять обновления стартера
- Раз в день проверяет на GitHub, вышла ли новая версия стартера, и показывает её на верхней панели. Тестовый канал предлагает сборки ветки staging.
- Обновление {0}
- Доступна версия {0}. Нажмите, чтобы открыть страницу загрузки.
- Стабильные
- Тестовые (staging)
- Внимание: канал относится только к стартеру. Симулятор MaSzyna и его файлы обновляются отдельно - этот выбор их не меняет.
- Проверить сейчас
- Проверка…
- Доступна версия {0} - кнопка появилась на верхней панели.
- У вас последняя версия ({0}).
- Не удалось связаться с GitHub. Попробуйте позже.
Графика
Движок отрисовки