diff --git a/.gitignore b/.gitignore index 3ca5d96..71941eb 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ bin/ .vs/ obj/ *.DotSettings -*.user \ No newline at end of file +*.user +packages/ \ No newline at end of file diff --git a/ACSE.csproj b/ACSE.csproj index 7a5a713..7a3e98f 100644 --- a/ACSE.csproj +++ b/ACSE.csproj @@ -54,6 +54,9 @@ + + packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + @@ -82,6 +85,7 @@ SettingsSingleFileGenerator ItemColorSettings.Designer.cs + @@ -4894,6 +4898,7 @@ + diff --git a/Classes/Updater.cs b/Classes/Updater.cs new file mode 100644 index 0000000..df1c5f0 --- /dev/null +++ b/Classes/Updater.cs @@ -0,0 +1,104 @@ +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Reflection; +using Newtonsoft.Json.Linq; + +namespace ACSE +{ + internal sealed class Updater + { + private int _versionMajor; + private int _versionMinor; + private int _versionRevision; + + public string UpdateUrl { get; private set; } + + private void SetCurrentVersionInfo() + { + var versionInfo = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); + _versionMajor = versionInfo.FileMajorPart; + _versionMinor = versionInfo.FileMinorPart; + _versionRevision = versionInfo.ProductBuildPart; + } + + public Updater() + { + SetCurrentVersionInfo(); + } + + public string GetVersion() => $"{_versionMajor}.{_versionMinor}.{_versionRevision}"; + + private (bool, string) CheckForUpdate(string url) + { + // Check the "latest" release first. + var request = (HttpWebRequest) WebRequest.Create(url); + request.Credentials = CredentialCache.DefaultCredentials; + request.ContentType = "application/json"; + request.Method = "GET"; + request.Accept = "application/json"; + request.UserAgent = "ACSE"; + + // Read response. + string content; + try + { + var response = (HttpWebResponse) request.GetResponse(); + using (var contentStream = response.GetResponseStream()) + { + if (contentStream == null) return (false, null); + using (var reader = new StreamReader(contentStream)) + { + content = reader.ReadToEnd(); + } + } + } + catch + { + return (false, null); + } + + // Parse JSON. + JObject jObj; + switch (JToken.Parse(content)) + { + case JArray jArray: + jObj = (JObject) jArray[0]; + break; + case JObject jObject: + jObj = jObject; + break; + default: + return (false, null); + } + + var version = (string) jObj["tag_name"]; + var updateUrl = (string) jObj["html_url"]; + + try + { + var versionInfo = version.Split('.'); + var updateMajor = int.Parse(versionInfo[0]); + var updateMinor = int.Parse(versionInfo[1]); + var updateRevision = int.Parse(versionInfo[2]); + + return (updateMajor > _versionMajor || updateMinor > _versionMinor || updateRevision > _versionRevision, updateUrl); + } + catch + { + return (false, null); + } + } + + public bool HasUpdate() + { + var (latestResult, latestUrl) = CheckForUpdate(@"https://api.github.com/repos/cuyler36/ACSE/releases/latest"); + UpdateUrl = latestUrl; + if (latestResult) return true; + + var (releasesResult, releaseUrl) = CheckForUpdate(@"https://api.github.com/repos/cuyler36/ACSE/releases"); + UpdateUrl = releaseUrl; + return releasesResult; + } + } +} diff --git a/Forms/MainForm.cs b/Forms/MainForm.cs index 8a871cf..297db37 100644 --- a/Forms/MainForm.cs +++ b/Forms/MainForm.cs @@ -260,6 +260,16 @@ public MainForm() // Palette Change Buttons paletteNextButton.MouseClick += (sender, e) => ChangePatternPalette(1); palettePreviousButton.MouseClick += (sender, e) => ChangePatternPalette(-1); + + // Check for updates + var updater = new Updater(); + if (updater.HasUpdate() && + MessageBox.Show( + "An updated version of ACSE is available! Would you like to be taken to the download page?", + "ACSE Update", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + System.Diagnostics.Process.Start(updater.UpdateUrl); + } } #region Settings Changing Functions diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..f01737d --- /dev/null +++ b/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file