diff --git a/TarkovMonitor/App.config b/TarkovMonitor/App.config index 9eb8272..fb2dd49 100644 --- a/TarkovMonitor/App.config +++ b/TarkovMonitor/App.config @@ -94,6 +94,12 @@ True + + + + + + diff --git a/TarkovMonitor/Properties/Settings.Designer.cs b/TarkovMonitor/Properties/Settings.Designer.cs index 4b15938..9290eba 100644 --- a/TarkovMonitor/Properties/Settings.Designer.cs +++ b/TarkovMonitor/Properties/Settings.Designer.cs @@ -382,5 +382,29 @@ public bool floatingTimerPanelShowRunThrough { this["floatingTimerPanelShowRunThrough"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string lastSeenReleaseTag { + get { + return ((string)(this["lastSeenReleaseTag"])); + } + set { + this["lastSeenReleaseTag"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string lastSeenReleaseAssetUpdatedAt { + get { + return ((string)(this["lastSeenReleaseAssetUpdatedAt"])); + } + set { + this["lastSeenReleaseAssetUpdatedAt"] = value; + } + } } } diff --git a/TarkovMonitor/Properties/Settings.settings b/TarkovMonitor/Properties/Settings.settings index 6a08071..8eef34f 100644 --- a/TarkovMonitor/Properties/Settings.settings +++ b/TarkovMonitor/Properties/Settings.settings @@ -92,5 +92,11 @@ True + + + + + + diff --git a/TarkovMonitor/UpdateCheck.cs b/TarkovMonitor/UpdateCheck.cs index cf74a4e..e794616 100644 --- a/TarkovMonitor/UpdateCheck.cs +++ b/TarkovMonitor/UpdateCheck.cs @@ -12,6 +12,7 @@ internal interface IGitHubAPI } private static readonly string repo = "the-hideout/TarkovMonitor"; + private static readonly string releaseAssetName = "TarkovMonitor.zip"; private static readonly System.Timers.Timer updateCheckTimer; private static readonly IGitHubAPI api = RestService.For($"https://api.github.com/repos/{repo}"); @@ -41,9 +42,28 @@ public static async void CheckForNewVersion() var release = await api.GetLatestRelease(); Version remoteVersion = new Version(release.tag_name); Version localVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version ?? throw new Exception("Could not retrieve version from assembly"); - //System.Diagnostics.Debug.WriteLine(localVersion.ToString()); + string assetUpdatedAt = release.assets?.FirstOrDefault(asset => asset.name == releaseAssetName)?.updated_at ?? ""; - if (localVersion.CompareTo(remoteVersion) == -1) + var settings = Properties.Settings.Default; + // An absent asset timestamp carries no information, so it must never read as a change. + bool assetUpdatedAtKnown = assetUpdatedAt != ""; + bool sameReleaseAsLastCheck = settings.lastSeenReleaseTag == release.tag_name; + bool assetUpdatedAtChanged = assetUpdatedAtKnown && settings.lastSeenReleaseAssetUpdatedAt != assetUpdatedAt; + + // Remember what the latest release looked like, so replacing its asset later is detectable. + if (assetUpdatedAtKnown && (!sameReleaseAsLastCheck || assetUpdatedAtChanged)) + { + settings.lastSeenReleaseTag = release.tag_name; + settings.lastSeenReleaseAssetUpdatedAt = assetUpdatedAt; + settings.Save(); + } + + // The download can be re-uploaded in place (a hotfix published under the same tag), + // which leaves the version unchanged; a changed asset timestamp means the build we + // are running was replaced. Only notified once, since there is nothing left to compare. + bool runningBuildWasReplaced = sameReleaseAsLastCheck && assetUpdatedAtChanged && localVersion == remoteVersion; + + if (localVersion < remoteVersion || runningBuildWasReplaced) { NewVersion?.Invoke(null, new() { Version = remoteVersion, Uri = new(release.html_url) }); } @@ -62,6 +82,13 @@ public class ReleaseData { public string tag_name { get; set; } public string html_url { get; set; } + public List? assets { get; set; } + } + + public class ReleaseAsset + { + public string? name { get; set; } + public string? updated_at { get; set; } } }