From f61827a575d2b882a1651cf93349451af55ba96c Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Thu, 30 Jul 2020 02:36:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0WebUtil=20Beta=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=A3=80=E6=9F=A5=20=E8=AE=A2=E9=98=85=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=BC=82=E5=B8=B8=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Netch/Controllers/UpdateChecker.cs | 36 +-- Netch/Forms/MainForm.Control.cs | 7 +- Netch/Forms/MainForm.MenuStrip.cs | 336 +++++++++------------- Netch/Forms/MainForm.Misc.cs | 20 +- Netch/Forms/MainForm.cs | 36 ++- Netch/Forms/SettingForm.Designer.cs | 54 ++-- Netch/Forms/SettingForm.cs | 3 + Netch/Models/GitHubRelease/VersionUtil.cs | 27 +- Netch/Models/Setting.cs | 10 + Netch/Override/WebClient.cs | 17 -- Netch/Resources/zh-CN | 4 +- Netch/Utils/WebUtil.cs | 76 +++++ 12 files changed, 321 insertions(+), 305 deletions(-) delete mode 100644 Netch/Override/WebClient.cs create mode 100644 Netch/Utils/WebUtil.cs diff --git a/Netch/Controllers/UpdateChecker.cs b/Netch/Controllers/UpdateChecker.cs index 30d7f5c4..6f5299f2 100644 --- a/Netch/Controllers/UpdateChecker.cs +++ b/Netch/Controllers/UpdateChecker.cs @@ -1,19 +1,15 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Net.Http; using System.Threading.Tasks; using Netch.Models.GitHubRelease; +using Netch.Utils; using Newtonsoft.Json; + namespace Netch.Controllers { public class UpdateChecker { - private const string DefaultUserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"; - - private const int DefaultGetTimeout = 30000; - public const string Owner = @"NetchX"; public const string Repo = @"Netch"; @@ -28,14 +24,14 @@ namespace Netch.Controllers public event EventHandler NewVersionFoundFailed; public event EventHandler NewVersionNotFound; - public async void Check(bool notifyNoFound, bool isPreRelease) + public void Check(bool notifyNoFound, bool isPreRelease) { try { var updater = new GitHubRelease(Owner, Repo); var url = updater.AllReleaseUrl; - var json = await GetAsync(url, true); + var json = WebUtil.DownloadString(WebUtil.CreateRequest(url)); var releases = JsonConvert.DeserializeObject>(json); var latestRelease = VersionUtil.GetLatestRelease(releases, isPreRelease); @@ -53,29 +49,9 @@ namespace Netch.Controllers } catch (Exception e) { - Debug.WriteLine(e.ToString()); + Logging.Error(e.ToString()); if (notifyNoFound) NewVersionFoundFailed?.Invoke(this, new EventArgs()); } } - - private static async Task GetAsync(string url, bool useProxy, string userAgent = @"", double timeout = DefaultGetTimeout) - { - var httpClientHandler = new HttpClientHandler - { - UseProxy = useProxy - }; - var httpClient = new HttpClient(httpClientHandler) - { - Timeout = TimeSpan.FromMilliseconds(timeout) - }; - var request = new HttpRequestMessage(HttpMethod.Get, url); - request.Headers.Add(@"User-Agent", string.IsNullOrWhiteSpace(userAgent) ? DefaultUserAgent : userAgent); - - var response = await httpClient.SendAsync(request); - - response.EnsureSuccessStatusCode(); - var resultStr = await response.Content.ReadAsStringAsync(); - return resultStr; - } } -} +} \ No newline at end of file diff --git a/Netch/Forms/MainForm.Control.cs b/Netch/Forms/MainForm.Control.cs index 95fbff3d..21545582 100644 --- a/Netch/Forms/MainForm.Control.cs +++ b/Netch/Forms/MainForm.Control.cs @@ -77,12 +77,7 @@ namespace Netch.Forms if (_isFirstCloseWindow) { // 显示提示语 - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, - i18N.Translate( - "Netch is now minimized to the notification bar, double click this icon to restore."), - ToolTipIcon.Info); - + NotifyTip(i18N.Translate("Netch is now minimized to the notification bar, double click this icon to restore.")); _isFirstCloseWindow = false; } diff --git a/Netch/Forms/MainForm.MenuStrip.cs b/Netch/Forms/MainForm.MenuStrip.cs index 840694d5..b09b9443 100644 --- a/Netch/Forms/MainForm.MenuStrip.cs +++ b/Netch/Forms/MainForm.MenuStrip.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; @@ -10,7 +12,6 @@ using Netch.Models; using Netch.Utils; using Trojan = Netch.Forms.Server.Trojan; using VMess = Netch.Forms.Server.VMess; -using WebClient = Netch.Override.WebClient; namespace Netch.Forms { @@ -97,31 +98,20 @@ namespace Netch.Forms private void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e) { - var bak_State = State; - var bak_StateText = StatusLabel.Text; - if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1) Global.Settings.UseProxyToUpdateSubscription = false; - if (Global.Settings.UseProxyToUpdateSubscription) + if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1) { - // 当前 ServerComboBox 中至少有一项 - if (ServerComboBox.SelectedIndex == -1) - { - MessageBoxX.Show(i18N.Translate("Please select a server first")); - return; - } - - MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false; - ControlButton.Text = "..."; + MessageBoxX.Show(i18N.Translate("Please select a server first")); + return; } if (Global.Settings.SubscribeLink.Count > 0) { - StatusText(i18N.Translate("Starting update subscription")); DeleteServerPictureBox.Enabled = false; - UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = false; + Task.Run(() => { if (Global.Settings.UseProxyToUpdateSubscription) @@ -131,96 +121,72 @@ namespace Netch.Forms Remark = "ProxyUpdate", Type = 5 }; - _mainController = new MainController(); - _mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode); + State = State.Starting; + if (_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode)) + StatusText(i18N.Translate("Starting update subscription")); } + else + StatusText(i18N.Translate("Starting update subscription")); - foreach (var item in Global.Settings.SubscribeLink) + Task.WaitAll(Global.Settings.SubscribeLink.Select(item => Task.Factory.StartNew(() => { - using var client = new WebClient(); try { - if (!string.IsNullOrEmpty(item.UserAgent)) - { - client.Headers.Add("User-Agent", item.UserAgent); - } - else - { - client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36"); - } + var request = WebUtil.CreateRequest(item.Link); - if (Global.Settings.UseProxyToUpdateSubscription) - { - client.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); - } + if (!string.IsNullOrEmpty(item.UserAgent)) request.UserAgent = item.UserAgent; + if (Global.Settings.UseProxyToUpdateSubscription) request.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); - var response = client.DownloadString(item.Link); + var str = WebUtil.DownloadString(request); try { - response = ShareLink.URLSafeBase64Decode(response); + str = ShareLink.URLSafeBase64Decode(str); } - catch (Exception) + catch { // ignored } Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList(); - var result = ShareLink.Parse(response); + var result = ShareLink.Parse(str); if (result != null) { - foreach (var x in result) - { - x.Group = item.Remark; - } + foreach (var x in result) x.Group = item.Remark; Global.Settings.Server.AddRange(result); - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, - string.Format(i18N.Translate("Update {1} server(s) from {0}"), item.Remark, result.Count), - ToolTipIcon.Info); - } - else - { - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, - string.Format(i18N.Translate("Update servers error from {0}"), item.Remark), - ToolTipIcon.Error); + NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, result.Count)); } } - catch (Exception) + catch (WebException e) { + NotifyTip($"{i18N.TranslateFormat("Update servers error from {0}", item.Remark)}\n{e.Message}", info: false); } - } + })).ToArray()); InitServer(); - DeleteServerPictureBox.Enabled = true; - if (Global.Settings.UseProxyToUpdateSubscription) - { - MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true; - ControlButton.Text = i18N.Translate("Start"); - _mainController.Stop(); - NatTypeStatusLabel.Text = ""; - } Configuration.Save(); - StatusText(i18N.Translate("Subscription updated")); + NotifyTip(i18N.Translate("Subscription updated")); + if (Global.Settings.UseProxyToUpdateSubscription) + { + _mainController.Stop(); + State = State.Stopped; + } + + State = State.Waiting; + DeleteModePictureBox.Enabled = true; MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true; - State = bak_State; - StatusLabel.Text = bak_StateText; - }).ContinueWith(task => { BeginInvoke(new Action(() => { UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true; })); }); + UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true; + }); - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, - i18N.Translate("Updating in the background"), - ToolTipIcon.Info); + NotifyTip(i18N.Translate("Updating in the background")); } else { MessageBoxX.Show(i18N.Translate("No subscription link")); - } } @@ -228,6 +194,98 @@ namespace Netch.Forms #region 选项 + private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e) + { + Utils.Utils.Open(".\\"); + } + + private void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e) + { + Task.Run(() => + { + DNS.Cache.Clear(); + NotifyTip(i18N.Translate("DNS cache cleanup succeeded")); + }); + } + + private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e) + { + Enabled = false; + SaveConfigs(); + Task.Run(() => + { + InitMode(); + + NotifyTip(i18N.Translate("Modes have been reload")); + Enabled = true; + }); + } + + private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e) + { + UpdateACL(true, sender); + } + + private void updateACLToolStripMenuItem_Click(object sender, EventArgs e) + { + UpdateACL(false, sender); + } + + private void UpdateACL(bool useProxy, object sender) + { + if (useProxy && ServerComboBox.SelectedIndex == -1) + { + MessageBoxX.Show(i18N.Translate("Please select a server first")); + return; + } + + ((ToolStripMenuItem) sender).Enabled = false; + + Task.Run(async () => + { + if (useProxy) + { + var mode = new Models.Mode + { + Remark = "ProxyUpdate", + Type = 5 + }; + State = State.Starting; + if (_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode)) + StatusText(i18N.Translate("Updating in the background")); + } + + try + { + var req = WebUtil.CreateRequest(Global.Settings.ACL); + if (useProxy) + req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); + + await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, "bin\\default.acl")); + NotifyTip(i18N.Translate("ACL updated successfully")); + } + catch (Exception e) + { + NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false); + Logging.Error("更新 ACL 失败!" + e); + if (!(e is WebException)) + throw; + } + finally + { + ((ToolStripMenuItem) sender).Enabled = true; + if (useProxy) + { + _mainController.Stop(); + State = State.Stopped; + } + + State = State.Waiting; + } + }); + } + + private void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e) { Enabled = false; @@ -244,52 +302,15 @@ namespace Netch.Forms } catch (Exception e) { - MessageBoxX.Show(e.ToString(),LogLevel.ERROR); + MessageBoxX.Show(e.ToString(), LogLevel.ERROR); + Console.WriteLine(e); throw; } + Enabled = true; }); } - private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e) - { - Enabled = false; - SaveConfigs(); - Task.Run(() => - { - InitMode(); - - MessageBoxX.Show(i18N.Translate("Modes have been reload"), owner: this); - Enabled = true; - }); - } - - private void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e) - { - var bak_State = State; - var bak_StateText = StatusLabel.Text; - - try - { - Enabled = false; - DNS.Cache.Clear(); - - MessageBoxX.Show(i18N.Translate("DNS cache cleanup succeeded"), owner: this); - StatusText(i18N.Translate("DNS cache cleanup succeeded")); - Enabled = true; - } - finally - { - State = bak_State; - StatusLabel.Text = bak_StateText; - } - } - - private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e) - { - Utils.Utils.Open(@".\"); - } - private void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e) { Task.Run(() => @@ -300,15 +321,11 @@ namespace Netch.Forms { Configuration.deltapall(); Configuration.addtap(); - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, i18N.Translate("Reinstall TUN/TAP driver successfully"), - ToolTipIcon.Info); + NotifyTip(i18N.Translate("Reinstall TUN/TAP driver successfully")); } catch { - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, i18N.Translate("Reinstall TUN/TAP driver failed"), - ToolTipIcon.Error); + NotifyTip(i18N.Translate("Reinstall TUN/TAP driver failed"), info: false); } finally { @@ -318,56 +335,6 @@ namespace Netch.Forms }); } - private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e) - { - updateACLWithProxyToolStripMenuItem.Enabled = false; - - // 当前 ServerComboBox 中至少有一项 - if (ServerComboBox.SelectedIndex == -1) - { - MessageBoxX.Show(i18N.Translate("Please select a server first")); - return; - } - - MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false; - ControlButton.Text = "..."; - - - Task.Run(() => - { - var mode = new Models.Mode - { - Remark = "ProxyUpdate", - Type = 5 - }; - _mainController = new MainController(); - _mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode); - - using var client = new WebClient(); - - client.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); - - StatusText(i18N.Translate("Updating in the background")); - try - { - client.DownloadFile(Global.Settings.ACL, "bin\\default.acl"); - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, i18N.Translate("ACL updated successfully"), - ToolTipIcon.Info); - } - catch (Exception e) - { - Logging.Error("使用代理更新 ACL 失败!" + e); - MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + e); - } - finally - { - State = State.Waiting; - _mainController.Stop(); - } - }); - } - #endregion @@ -378,12 +345,12 @@ namespace Netch.Forms private void RelyToolStripMenuItem_Click(object sender, EventArgs e) { - System.Diagnostics.Process.Start("https://mega.nz/file/9OQ1EazJ#0pjJ3xt57AVLr29vYEEv15GSACtXVQOGlEOPpi_2Ico"); + Utils.Utils.Open("https://mega.nz/file/9OQ1EazJ#0pjJ3xt57AVLr29vYEEv15GSACtXVQOGlEOPpi_2Ico"); } private void VersionLabel_Click(object sender, EventArgs e) { - System.Diagnostics.Process.Start($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases"); + Utils.Utils.Open($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases"); } private void AboutToolStripButton_Click(object sender, EventArgs e) @@ -392,39 +359,6 @@ namespace Netch.Forms Hide(); } - private void updateACLToolStripMenuItem_Click(object sender, EventArgs e) - { - var bak_State = State; - var bak_StateText = StatusLabel.Text; - - StatusText(i18N.Translate("Starting update ACL")); - using var client = new WebClient(); - - client.DownloadFileTaskAsync(Global.Settings.ACL, "bin\\default.acl"); - client.DownloadFileCompleted += ((sender, args) => - { - try - { - if (args.Error == null) - { - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, i18N.Translate("ACL updated successfully"), - ToolTipIcon.Info); - } - else - { - Logging.Error("ACL 更新失败!" + args.Error); - MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + args.Error); - } - } - finally - { - State = bak_State; - StatusLabel.Text = bak_StateText; - } - }); - } - #endregion } } \ No newline at end of file diff --git a/Netch/Forms/MainForm.Misc.cs b/Netch/Forms/MainForm.Misc.cs index 7bc514e7..fc8e2fef 100644 --- a/Netch/Forms/MainForm.Misc.cs +++ b/Netch/Forms/MainForm.Misc.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using System.Windows.Forms; +using System.Threading.Tasks; using Netch.Controllers; using Netch.Utils; @@ -11,22 +11,18 @@ namespace Netch.Forms /// /// 此类用于禁用设计器 /// - [DesignerCategory("")] public partial class Dummy { } + [DesignerCategory("")] + public partial class Dummy + { + } + partial class MainForm { private void CheckUpdate() { var updater = new UpdateChecker(); - updater.NewVersionFound += (o, args) => - { - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, - $"{i18N.Translate(@"New version available",": ")}{updater.LatestVersionNumber}", - ToolTipIcon.Info); - }; - updater.Check(false, false); + updater.NewVersionFound += (o, args) => { NotifyTip($"{i18N.Translate(@"New version available", ": ")}{updater.LatestVersionNumber}"); }; + updater.Check(false, Global.Settings.CheckBetaUpdate); } - - } } \ No newline at end of file diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index 3bc63abb..169f9990 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -73,6 +73,11 @@ namespace Netch.Forms // 加载快速配置 InitProfile(); + // 打开软件时启动加速,产生开始按钮点击事件 + if (Global.Settings.StartWhenOpened) + { + ControlButton.PerformClick(); + } // 自动检测延迟 Task.Run(() => @@ -92,17 +97,14 @@ namespace Netch.Forms } }); - // 打开软件时启动加速,产生开始按钮点击事件 - if (Global.Settings.StartWhenOpened) + Task.Run(() => { - ControlButton.PerformClick(); - } - - // 检查更新 - if (Global.Settings.CheckUpdateWhenOpened) - { - CheckUpdate(); - } + // 检查更新 + if (Global.Settings.CheckUpdateWhenOpened) + { + CheckUpdate(); + } + }); } @@ -122,11 +124,7 @@ namespace Netch.Forms if (_isFirstCloseWindow) { // 显示提示语 - NotifyIcon.ShowBalloonTip(5, - UpdateChecker.Name, - i18N.Translate("Netch is now minimized to the notification bar, double click this icon to restore."), - ToolTipIcon.Info); - + NotifyTip(i18N.Translate("Netch is now minimized to the notification bar, double click this icon to restore.")); _isFirstCloseWindow = false; } @@ -451,6 +449,14 @@ namespace Netch.Forms Activate(); } + private void NotifyTip(string text, int timeout = 5, bool info = true) + { + NotifyIcon.ShowBalloonTip(timeout, + UpdateChecker.Name, + text, + info ? ToolTipIcon.Info : ToolTipIcon.Error); + } + #endregion #endregion diff --git a/Netch/Forms/SettingForm.Designer.cs b/Netch/Forms/SettingForm.Designer.cs index aea38724..0da51569 100644 --- a/Netch/Forms/SettingForm.Designer.cs +++ b/Netch/Forms/SettingForm.Designer.cs @@ -54,6 +54,7 @@ this.BehaviorGroupBox = new System.Windows.Forms.GroupBox(); this.LanguageLabel = new System.Windows.Forms.Label(); this.LanguageComboBox = new System.Windows.Forms.ComboBox(); + this.ModifySystemDNSCheckBox = new System.Windows.Forms.CheckBox(); this.BootShadowsocksFromDLLCheckBox = new System.Windows.Forms.CheckBox(); this.AclAddrTextBox = new System.Windows.Forms.TextBox(); this.AclLabel = new System.Windows.Forms.Label(); @@ -68,11 +69,11 @@ this.MinimizeWhenStartedCheckBox = new System.Windows.Forms.CheckBox(); this.ProfileCountLabel = new System.Windows.Forms.Label(); this.ProfileCountTextBox = new System.Windows.Forms.TextBox(); + this.CheckBetaUpdateCheckBox = new System.Windows.Forms.CheckBox(); this.CheckUpdateWhenOpenedCheckBox = new System.Windows.Forms.CheckBox(); this.StartWhenOpenedCheckBox = new System.Windows.Forms.CheckBox(); this.StopWhenExitedCheckBox = new System.Windows.Forms.CheckBox(); this.ExitWhenClosedCheckBox = new System.Windows.Forms.CheckBox(); - this.ModifySystemDNSCheckBox = new System.Windows.Forms.CheckBox(); this.PortGroupBox.SuspendLayout(); this.TUNTAPGroupBox.SuspendLayout(); this.BehaviorGroupBox.SuspendLayout(); @@ -316,6 +317,7 @@ this.BehaviorGroupBox.Controls.Add(this.MinimizeWhenStartedCheckBox); this.BehaviorGroupBox.Controls.Add(this.ProfileCountLabel); this.BehaviorGroupBox.Controls.Add(this.ProfileCountTextBox); + this.BehaviorGroupBox.Controls.Add(this.CheckBetaUpdateCheckBox); this.BehaviorGroupBox.Controls.Add(this.CheckUpdateWhenOpenedCheckBox); this.BehaviorGroupBox.Controls.Add(this.StartWhenOpenedCheckBox); this.BehaviorGroupBox.Controls.Add(this.StopWhenExitedCheckBox); @@ -345,17 +347,27 @@ this.LanguageComboBox.Size = new System.Drawing.Size(121, 25); this.LanguageComboBox.TabIndex = 22; // + // ModifySystemDNSCheckBox + // + this.ModifySystemDNSCheckBox.AutoSize = true; + this.ModifySystemDNSCheckBox.Location = new System.Drawing.Point(12, 129); + this.ModifySystemDNSCheckBox.Name = "ModifySystemDNSCheckBox"; + this.ModifySystemDNSCheckBox.Size = new System.Drawing.Size(143, 21); + this.ModifySystemDNSCheckBox.TabIndex = 21; + this.ModifySystemDNSCheckBox.Text = "Modify System DNS"; + this.ModifySystemDNSCheckBox.UseVisualStyleBackColor = true; + // // BootShadowsocksFromDLLCheckBox // this.BootShadowsocksFromDLLCheckBox.AutoSize = true; this.BootShadowsocksFromDLLCheckBox.Location = new System.Drawing.Point(12, 102); this.BootShadowsocksFromDLLCheckBox.Name = "BootShadowsocksFromDLLCheckBox"; - this.BootShadowsocksFromDLLCheckBox.Size = new System.Drawing.Size(321, 21); + this.BootShadowsocksFromDLLCheckBox.Size = new System.Drawing.Size(168, 21); this.BootShadowsocksFromDLLCheckBox.TabIndex = 21; - this.BootShadowsocksFromDLLCheckBox.Text = "Start Shadowsocks from DLL (No support for ACL)"; + this.BootShadowsocksFromDLLCheckBox.Text = "SS DLL(No ACL support)"; this.BootShadowsocksFromDLLCheckBox.UseVisualStyleBackColor = true; // - // AclAddr + // AclAddrTextBox // this.AclAddrTextBox.Location = new System.Drawing.Point(120, 273); this.AclAddrTextBox.Name = "AclAddrTextBox"; @@ -372,7 +384,7 @@ this.AclLabel.TabIndex = 20; this.AclLabel.Text = "Custom ACL"; // - // DetectionInterval_Label + // DetectionIntervalLabel // this.DetectionIntervalLabel.AutoSize = true; this.DetectionIntervalLabel.Location = new System.Drawing.Point(228, 215); @@ -381,7 +393,7 @@ this.DetectionIntervalLabel.TabIndex = 18; this.DetectionIntervalLabel.Text = "Detection interval(sec)"; // - // DetectionInterval_TextBox + // DetectionIntervalTextBox // this.DetectionIntervalTextBox.Location = new System.Drawing.Point(366, 212); this.DetectionIntervalTextBox.Name = "DetectionIntervalTextBox"; @@ -389,7 +401,7 @@ this.DetectionIntervalTextBox.TabIndex = 17; this.DetectionIntervalTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // - // EnableStartedTcping_CheckBox + // TcpingAtStartedCheckBox // this.TcpingAtStartedCheckBox.AutoSize = true; this.TcpingAtStartedCheckBox.Location = new System.Drawing.Point(15, 214); @@ -426,7 +438,7 @@ this.STUNServerLabel.TabIndex = 10; this.STUNServerLabel.Text = "STUN Server"; // - // RunAtStartup + // RunAtStartupCheckBox // this.RunAtStartupCheckBox.AutoSize = true; this.RunAtStartupCheckBox.Location = new System.Drawing.Point(12, 75); @@ -454,7 +466,7 @@ this.MinimizeWhenStartedCheckBox.Text = "Minimize when started"; this.MinimizeWhenStartedCheckBox.UseVisualStyleBackColor = true; // - // ProfileCount_Label + // ProfileCountLabel // this.ProfileCountLabel.AutoSize = true; this.ProfileCountLabel.Location = new System.Drawing.Point(12, 188); @@ -463,7 +475,7 @@ this.ProfileCountLabel.TabIndex = 8; this.ProfileCountLabel.Text = "ProfileCount"; // - // ProfileCount_TextBox + // ProfileCountTextBox // this.ProfileCountTextBox.Location = new System.Drawing.Point(120, 185); this.ProfileCountTextBox.Name = "ProfileCountTextBox"; @@ -471,6 +483,17 @@ this.ProfileCountTextBox.TabIndex = 9; this.ProfileCountTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // + // CheckBetaUpdateCheckBox + // + this.CheckBetaUpdateCheckBox.AutoSize = true; + this.CheckBetaUpdateCheckBox.Location = new System.Drawing.Point(206, 102); + this.CheckBetaUpdateCheckBox.Name = "CheckBetaUpdateCheckBox"; + this.CheckBetaUpdateCheckBox.Size = new System.Drawing.Size(137, 21); + this.CheckBetaUpdateCheckBox.TabIndex = 8; + this.CheckBetaUpdateCheckBox.Text = "Check Beta update"; + this.CheckBetaUpdateCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.CheckBetaUpdateCheckBox.UseVisualStyleBackColor = true; + // // CheckUpdateWhenOpenedCheckBox // this.CheckUpdateWhenOpenedCheckBox.AutoSize = true; @@ -515,16 +538,6 @@ this.ExitWhenClosedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight; this.ExitWhenClosedCheckBox.UseVisualStyleBackColor = true; // - // ModifySystemDNSCheckBox - // - this.ModifySystemDNSCheckBox.AutoSize = true; - this.ModifySystemDNSCheckBox.Location = new System.Drawing.Point(12, 129); - this.ModifySystemDNSCheckBox.Name = "ModifySystemDNSCheckBox"; - this.ModifySystemDNSCheckBox.Size = new System.Drawing.Size(143, 21); - this.ModifySystemDNSCheckBox.TabIndex = 21; - this.ModifySystemDNSCheckBox.Text = "Modify System DNS"; - this.ModifySystemDNSCheckBox.UseVisualStyleBackColor = true; - // // SettingForm // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); @@ -601,5 +614,6 @@ private System.Windows.Forms.Label LanguageLabel; private System.Windows.Forms.ComboBox LanguageComboBox; private System.Windows.Forms.CheckBox ModifySystemDNSCheckBox; + private System.Windows.Forms.CheckBox CheckBetaUpdateCheckBox; } } \ No newline at end of file diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index 9fe5ea7f..35b1d1b1 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -106,6 +106,7 @@ namespace Netch.Forms CheckUpdateWhenOpenedCheckBox.Checked = Global.Settings.CheckUpdateWhenOpened; BootShadowsocksFromDLLCheckBox.Checked = Global.Settings.BootShadowsocksFromDLL; ModifySystemDNSCheckBox.Checked = Global.Settings.ModifySystemDNS; + CheckBetaUpdateCheckBox.Checked = Global.Settings.CheckBetaUpdate; ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString(); TcpingAtStartedCheckBox.Checked = Global.Settings.StartedTcping; @@ -133,6 +134,7 @@ namespace Netch.Forms ControlButton.Text = i18N.Translate(ControlButton.Text); BootShadowsocksFromDLLCheckBox.Text = i18N.Translate(BootShadowsocksFromDLLCheckBox.Text); ModifySystemDNSCheckBox.Text = i18N.Translate(ModifySystemDNSCheckBox.Text); + CheckBetaUpdateCheckBox.Text = i18N.Translate(CheckBetaUpdateCheckBox.Text); BehaviorGroupBox.Text = i18N.Translate(BehaviorGroupBox.Text); ExitWhenClosedCheckBox.Text = i18N.Translate(ExitWhenClosedCheckBox.Text); StopWhenExitedCheckBox.Text = i18N.Translate(StopWhenExitedCheckBox.Text); @@ -173,6 +175,7 @@ namespace Netch.Forms Global.Settings.StopWhenExited = StopWhenExitedCheckBox.Checked; Global.Settings.StartWhenOpened = StartWhenOpenedCheckBox.Checked; Global.Settings.CheckUpdateWhenOpened = CheckUpdateWhenOpenedCheckBox.Checked; + Global.Settings.CheckBetaUpdate = CheckBetaUpdateCheckBox.Checked; Global.Settings.MinimizeWhenStarted = MinimizeWhenStartedCheckBox.Checked; Global.Settings.RunAtStartup = RunAtStartupCheckBox.Checked; Global.Settings.BootShadowsocksFromDLL = BootShadowsocksFromDLLCheckBox.Checked; diff --git a/Netch/Models/GitHubRelease/VersionUtil.cs b/Netch/Models/GitHubRelease/VersionUtil.cs index e49cf60f..fc0015d5 100644 --- a/Netch/Models/GitHubRelease/VersionUtil.cs +++ b/Netch/Models/GitHubRelease/VersionUtil.cs @@ -12,6 +12,7 @@ namespace Netch.Models.GitHubRelease { releases = releases.Where(release => !release.prerelease); } + releases = releases.Where(release => IsVersionString(release.tag_name)); var ordered = releases.OrderByDescending(release => release.tag_name, new VersionComparer()); return ordered.ElementAt(0); @@ -19,6 +20,8 @@ namespace Netch.Models.GitHubRelease private static bool IsVersionString(string str) { + if (Global.Settings.CheckBetaUpdate) + str = str.Split('-')[0]; return Version.TryParse(str, out _); } @@ -27,10 +30,28 @@ namespace Netch.Models.GitHubRelease /// <0:version2 is greater public static int CompareVersion(string v1, string v2) { - var version1 = new Version(v1); - var version2 = new Version(v2); + var version1 = ToVersion(v1); + var version2 = ToVersion(v2); var res = version1.CompareTo(version2); return res; } + + private static Version ToVersion(string versionStr) + { + var v = versionStr.Split('-'); + var version = Version.Parse(v[0]); + if (v.Length == 1) + return version; + var beta = v[1]; + + var result = string.Empty; + foreach (var c in beta) + { + if (int.TryParse(c.ToString(), out var n)) + result += n; + } + + return new Version(version.Major, version.Minor, version.Build, int.Parse(result)); + } } -} +} \ No newline at end of file diff --git a/Netch/Models/Setting.cs b/Netch/Models/Setting.cs index 167d4863..f312ce40 100644 --- a/Netch/Models/Setting.cs +++ b/Netch/Models/Setting.cs @@ -87,12 +87,22 @@ namespace Netch.Models /// 是否打开软件时检查更新 /// public bool CheckUpdateWhenOpened = true; + + /// + /// 是否检查 Beta 更新 + /// + public bool CheckBetaUpdate = false; /// /// 修改系统 DNS /// public bool ModifySystemDNS = false; + /// + /// 网页请求超时 毫秒 + /// + public int RequestTimeout = 10000; + /// /// 使用何种模式文件名 /// 0 为自定义文件名,1 为使用和备注一致的文件名,2 为使用时间数据作为文件名 diff --git a/Netch/Override/WebClient.cs b/Netch/Override/WebClient.cs deleted file mode 100644 index 7f93c9b5..00000000 --- a/Netch/Override/WebClient.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Net; - -namespace Netch.Override -{ - public class WebClient : System.Net.WebClient - { - protected override WebRequest GetWebRequest(Uri address) - { - var request = base.GetWebRequest(address); - request.Timeout = 10000; - ((HttpWebRequest)request).ReadWriteTimeout = 10000; - - return request; - } - } -} diff --git a/Netch/Resources/zh-CN b/Netch/Resources/zh-CN index b7e83815..4d505969 100644 --- a/Netch/Resources/zh-CN +++ b/Netch/Resources/zh-CN @@ -5,6 +5,7 @@ "If this is your first time using this software,\n please check https://netch.org to install supports first,\n or the program may report errors.": "如果你是第一次使用本软件,\n请务必前往https://netch.org安装程序所需依赖,\n否则程序将无法正常运行!", "Netch is already running": "Netch 已经在运行中", + "Missing File or runtime components": "缺少文件或运行库", "Start": "启动", "Stop": "停止", @@ -156,7 +157,8 @@ "Global Bypass IPs": "全局直连 IP", "Port value illegal. Try again.": "端口值非法。请重试。", "Check update when opened": "打开软件时检查更新", - "Start Shadowsocks from DLL (No support for ACL)": "SS DLL(推荐使用,不支持 ACL)", + "Check Beta update": "检查 Beta 更新", + "SS DLL(No ACL support)": "SS DLL(不支持 ACL)", "Modify System DNS": "修改系统 DNS", "ProfileCount": "快捷配置数量", "ProfileCount value illegal. Try again.": "快捷配置数值非法。请重试。", diff --git a/Netch/Utils/WebUtil.cs b/Netch/Utils/WebUtil.cs new file mode 100644 index 00000000..77fb2269 --- /dev/null +++ b/Netch/Utils/WebUtil.cs @@ -0,0 +1,76 @@ +using System; +using System.IO; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Netch.Utils +{ + public class WebUtil + { + private const string DefaultUserAgent = @"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"; + + private static int DefaultGetTimeout => Global.Settings.RequestTimeout; + + public static HttpWebRequest CreateRequest(string url, int? timeout = null, string userAgent = null) + { + var req = (HttpWebRequest) WebRequest.Create(url); + req.UserAgent = string.IsNullOrEmpty(userAgent) ? DefaultUserAgent : userAgent; + req.Accept = "*/*"; + req.KeepAlive = true; + req.Timeout = timeout ?? DefaultGetTimeout; + req.ReadWriteTimeout = timeout ?? DefaultGetTimeout; + req.Headers.Add("Accept-Charset", "utf-8"); + return req; + } + + /// + /// + /// + public static async Task DownloadStringAsync(HttpWebRequest req) + { + string content; + var response = (HttpWebResponse) await req.GetResponseAsync(); + using (var responseStream = response.GetResponseStream()) + { + using (var sr = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"))) + { + content = await sr.ReadToEndAsync(); + } + } + + response.Close(); + return content; + } + + /// + /// + /// + public static string DownloadString(HttpWebRequest req) + { + string content; + var response = (HttpWebResponse) req.GetResponse(); + using (var responseStream = response.GetResponseStream()) + { + using (var sr = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"))) + { + content = sr.ReadToEnd(); + } + } + + response.Close(); + return content; + } + + /// + /// + /// + public static async Task DownloadFileAsync(HttpWebRequest req, string fileFullPath) + { + var dir = Path.GetDirectoryName(fileFullPath) ?? throw new ArgumentException(); + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); + File.WriteAllText(fileFullPath, await DownloadStringAsync(req)); + } + } +} \ No newline at end of file