diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index 296bb8fd..83c59493 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -18,12 +18,14 @@ namespace Shadowsocks.Controller private Configuration config; public bool NewVersionFound; public string LatestVersionNumber; + public string LatestVersionSuffix; public string LatestVersionName; public string LatestVersionURL; public string LatestVersionLocalName; public event EventHandler CheckUpdateCompleted; public const string Version = "3.3.5"; + public const bool PreRelease = false; private class CheckUpdateTimer : System.Timers.Timer { @@ -83,17 +85,21 @@ namespace Shadowsocks.Controller { foreach (JObject release in result) { - if ((bool)release["prerelease"]) + var isPreRelease = (bool) release["prerelease"]; + if (isPreRelease && !config.checkPreRelease) { continue; } foreach (JObject asset in (JArray)release["assets"]) { - Asset ass = new Asset(); - ass.Parse(asset); - if (ass.IsNewVersion(Version)) + Asset ass = Asset.ParseAsset(asset); + if (ass != null) { - asserts.Add(ass); + ass.prerelease = isPreRelease; + if (ass.IsNewVersion(Version, PreRelease, config.checkPreRelease)) + { + asserts.Add(ass); + } } } } @@ -106,6 +112,7 @@ namespace Shadowsocks.Controller LatestVersionURL = asset.browser_download_url; LatestVersionNumber = asset.version; LatestVersionName = asset.name; + LatestVersionSuffix = asset.suffix == null ? "" : $"-{asset.suffix}"; startDownload(); } @@ -148,7 +155,7 @@ namespace Shadowsocks.Controller Logging.LogUsefulException(e.Error); return; } - Logging.Debug($"New version {LatestVersionNumber} found: {LatestVersionLocalName}"); + Logging.Debug($"New version {LatestVersionNumber}{LatestVersionSuffix} found: {LatestVersionLocalName}"); if (CheckUpdateCompleted != null) { CheckUpdateCompleted(this, new EventArgs()); @@ -179,10 +186,38 @@ namespace Shadowsocks.Controller public string name; public string version; public string browser_download_url; + public string suffix; - public bool IsNewVersion(string currentVersion) + public static Asset ParseAsset(JObject aJObject) { - if (prerelease) + var name = (string) aJObject["name"]; + Match match = Regex.Match(name, @"^Shadowsocks-(?\d+(?:\.\d+)*)(?:|-(?.+))\.\w+$", + RegexOptions.IgnoreCase); + if (match.Success) + { + string version = match.Groups["version"].Value; + + var asset = new Asset + { + browser_download_url = (string) aJObject["browser_download_url"], + name = name, + version = version + }; + + if (match.Groups["suffix"].Success) + { + asset.suffix = match.Groups["suffix"].Value; + } + + return asset; + } + + return null; + } + + public bool IsNewVersion(string currentVersion, bool isPreRelease, bool checkPreRelease) + { + if (prerelease && !checkPreRelease) { return false; } @@ -190,28 +225,13 @@ namespace Shadowsocks.Controller { return false; } - return CompareVersion(version, currentVersion) > 0; - } - - public void Parse(JObject asset) - { - name = (string)asset["name"]; - browser_download_url = (string)asset["browser_download_url"]; - version = ParseVersionFromURL(browser_download_url); - prerelease = browser_download_url.IndexOf("prerelease", StringComparison.Ordinal) >= 0; - } - - private static string ParseVersionFromURL(string url) - { - Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase); - if (match.Success) + var cmp = CompareVersion(version, currentVersion); + if (cmp == 0) { - if (match.Groups.Count == 2) - { - return match.Groups[1].Value; - } + // If current version is pre-release and we find non-prerelease version online, then the non-prelease version is newer. + return !prerelease && isPreRelease; } - return null; + return cmp > 0; } public static int CompareVersion(string l, string r) diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 06bce1c4..a9da8197 100644 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -357,6 +357,16 @@ namespace Shadowsocks.Controller } } + public void ToggleCheckingPreRelease(bool enabled) + { + _config.checkPreRelease = enabled; + Configuration.Save(_config); + if (ConfigChanged != null) + { + ConfigChanged(this, new EventArgs()); + } + } + public void SaveLogViewerConfig(LogViewerConfig newConfig) { _config.logViewer = newConfig; diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 4a736e8a..0d9de1cf 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -27,6 +27,7 @@ Verbose Logging=详细记录日志 Updates...=更新... Check for Updates...=检查更新 Check for Updates at Startup=启动时检查更新 +Check Pre-release Version=检查测试版更新 Edit Hotkeys...=编辑快捷键... About...=关于... Quit=退出 diff --git a/shadowsocks-csharp/Data/zh_tw.txt b/shadowsocks-csharp/Data/zh_tw.txt index 97b58ccb..f0f960ef 100644 --- a/shadowsocks-csharp/Data/zh_tw.txt +++ b/shadowsocks-csharp/Data/zh_tw.txt @@ -27,6 +27,7 @@ Verbose Logging=詳細記錄日誌 Updates...=更新... Check for Updates...=檢查更新 Check for Updates at Startup=啟動時檢查更新 +Check Pre-release Version=檢查測試版更新 Edit Hotkeys...=編輯捷徑鍵... About...=關於... Quit=退出 diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs old mode 100755 new mode 100644 index 64ece808..546974a0 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -24,6 +24,7 @@ namespace Shadowsocks.Model public bool useOnlinePac; public bool availabilityStatistics; public bool autoCheckUpdate; + public bool checkPreRelease; public bool isVerboseLogging; public LogViewerConfig logViewer; public ProxyConfig proxy; diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 41cd73db..4daeddc8 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -48,6 +48,7 @@ namespace Shadowsocks.View private MenuItem editGFWUserRuleItem; private MenuItem editOnlinePACItem; private MenuItem autoCheckUpdatesToggleItem; + private MenuItem checkPreReleaseToggleItem; private MenuItem proxyItem; private MenuItem hotKeyItem; private MenuItem VerboseLoggingToggleItem; @@ -283,6 +284,7 @@ namespace Shadowsocks.View CreateMenuItem("Check for Updates...", new EventHandler(this.checkUpdatesItem_Click)), new MenuItem("-"), this.autoCheckUpdatesToggleItem = CreateMenuItem("Check for Updates at Startup", new EventHandler(this.autoCheckUpdatesToggleItem_Click)), + this.checkPreReleaseToggleItem = CreateMenuItem("Check Pre-release Version", new EventHandler(this.checkPreReleaseToggleItem_Click)), }), CreateMenuItem("About...", new EventHandler(this.AboutItem_Click)), new MenuItem("-"), @@ -352,7 +354,7 @@ namespace Shadowsocks.View { if (updateChecker.NewVersionFound) { - ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); + ShowBalloonTip(String.Format(I18N.GetString("Shadowsocks {0} Update Found"), updateChecker.LatestVersionNumber + updateChecker.LatestVersionSuffix), I18N.GetString("Click here to update"), ToolTipIcon.Info, 5000); } else if (!_isStartupChecking) { @@ -816,6 +818,7 @@ namespace Shadowsocks.View { Configuration configuration = controller.GetConfigurationCopy(); autoCheckUpdatesToggleItem.Checked = configuration.autoCheckUpdate; + checkPreReleaseToggleItem.Checked = configuration.checkPreRelease; } private void autoCheckUpdatesToggleItem_Click(object sender, EventArgs e) @@ -825,6 +828,13 @@ namespace Shadowsocks.View UpdateUpdateMenu(); } + private void checkPreReleaseToggleItem_Click(object sender, EventArgs e) + { + Configuration configuration = controller.GetConfigurationCopy(); + controller.ToggleCheckingPreRelease(!configuration.checkPreRelease); + UpdateUpdateMenu(); + } + private void checkUpdatesItem_Click(object sender, EventArgs e) { updateChecker.CheckUpdate(controller.GetConfigurationCopy());