diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index a36d7a1cf3..63ce3a8fb6 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -63,6 +63,8 @@ private void MainForm_Load(object sender, EventArgs e) _comboBoxNumberBoxWidth = ServerComboBox.Width / 10; InitServer(); + ServerHelper.DelayTestHelper.UpdateInterval(); + ModeHelper.Load(); InitMode(); _comboBoxInitialized = true; @@ -597,19 +599,28 @@ private async void ControlButton_Click(object sender, EventArgs e) if (Global.Settings.MinimizeWhenStarted) Minimize(); - if (Global.Settings.StartedTcping) - // 自动检测延迟 - _ = Task.Run(() => + // 自动检测延迟 + _ = Task.Run(() => + { + while (State == State.Started) { - while (State == State.Started) + bool StartedPingEnabled() + { + return Global.Settings.StartedPingInterval >= 0; + } + + if (StartedPingEnabled()) { server.Test(); - // 重绘 ServerComboBox ServerComboBox.Refresh(); - - Thread.Sleep(Global.Settings.StartedTcping_Interval * 1000); } - }); + + if (StartedPingEnabled()) + Thread.Sleep(Global.Settings.StartedPingInterval * 1000); + else + Thread.Sleep(5000); + } + }); } #endregion @@ -629,6 +640,9 @@ private void SettingsButton_Click(object sender, EventArgs e) InitProfile(); } + if (ServerHelper.DelayTestHelper.Interval != Global.Settings.DetectionTick) + ServerHelper.DelayTestHelper.UpdateInterval(); + if (ProfileButtons.Count != Global.Settings.ProfileCount) InitProfile(); @@ -691,15 +705,25 @@ private void SpeedPictureBox_Click(object sender, EventArgs e) Enabled = false; StatusText(i18N.Translate("Testing")); - ServerHelper.TestDelayFinished += OnTestDelayFinished; - _ = Task.Run(ServerHelper.TestAllDelay); - - void OnTestDelayFinished(object o1, EventArgs e1) + if (IsWaiting()) { - Refresh(); - NotifyTip(i18N.Translate("Test done")); + ServerHelper.DelayTestHelper.TestDelayFinished += OnTestDelayFinished; + _ = Task.Run(ServerHelper.DelayTestHelper.TestAllDelay); + + void OnTestDelayFinished(object o1, EventArgs e1) + { + Refresh(); + NotifyTip(i18N.Translate("Test done")); - ServerHelper.TestDelayFinished -= OnTestDelayFinished; + ServerHelper.DelayTestHelper.TestDelayFinished -= OnTestDelayFinished; + Enabled = true; + StatusText(); + } + } + else + { + (ServerComboBox.SelectedItem as Server)?.Test(); + ServerComboBox.Refresh(); Enabled = true; StatusText(); } @@ -1024,7 +1048,7 @@ void StartDisableItems(bool enabled) _state = value; - ServerHelper.Timer.Enabled = IsWaiting(_state); + ServerHelper.DelayTestHelper.Enabled = IsWaiting(_state); StatusText(); switch (value) diff --git a/Netch/Forms/SettingForm.Designer.cs b/Netch/Forms/SettingForm.Designer.cs index d84fad8987..310d520b15 100644 --- a/Netch/Forms/SettingForm.Designer.cs +++ b/Netch/Forms/SettingForm.Designer.cs @@ -49,9 +49,10 @@ private void InitializeComponent() this.ResolveServerHostnameCheckBox = new System.Windows.Forms.CheckBox(); this.ProfileCountLabel = new System.Windows.Forms.Label(); this.ProfileCountTextBox = new System.Windows.Forms.TextBox(); - this.TcpingAtStartedCheckBox = new System.Windows.Forms.CheckBox(); - this.DetectionIntervalLabel = new System.Windows.Forms.Label(); - this.DetectionIntervalTextBox = new System.Windows.Forms.TextBox(); + this.StartedPingLabel = new System.Windows.Forms.Label(); + this.DetectionTickLabel = new System.Windows.Forms.Label(); + this.StartedPingIntervalTextBox = new System.Windows.Forms.TextBox(); + this.DetectionTickTextBox = new System.Windows.Forms.TextBox(); this.STUNServerLabel = new System.Windows.Forms.Label(); this.STUN_ServerComboBox = new System.Windows.Forms.ComboBox(); this.AclLabel = new System.Windows.Forms.Label(); @@ -154,9 +155,10 @@ private void InitializeComponent() this.GeneralTabPage.Controls.Add(this.ResolveServerHostnameCheckBox); this.GeneralTabPage.Controls.Add(this.ProfileCountLabel); this.GeneralTabPage.Controls.Add(this.ProfileCountTextBox); - this.GeneralTabPage.Controls.Add(this.TcpingAtStartedCheckBox); - this.GeneralTabPage.Controls.Add(this.DetectionIntervalLabel); - this.GeneralTabPage.Controls.Add(this.DetectionIntervalTextBox); + this.GeneralTabPage.Controls.Add(this.StartedPingLabel); + this.GeneralTabPage.Controls.Add(this.DetectionTickLabel); + this.GeneralTabPage.Controls.Add(this.StartedPingIntervalTextBox); + this.GeneralTabPage.Controls.Add(this.DetectionTickTextBox); this.GeneralTabPage.Controls.Add(this.STUNServerLabel); this.GeneralTabPage.Controls.Add(this.STUN_ServerComboBox); this.GeneralTabPage.Controls.Add(this.AclLabel); @@ -173,7 +175,7 @@ private void InitializeComponent() // ServerPingTypeLabel // this.ServerPingTypeLabel.AutoSize = true; - this.ServerPingTypeLabel.Location = new System.Drawing.Point(217, 160); + this.ServerPingTypeLabel.Location = new System.Drawing.Point(267, 66); this.ServerPingTypeLabel.Name = "ServerPingTypeLabel"; this.ServerPingTypeLabel.Size = new System.Drawing.Size(89, 12); this.ServerPingTypeLabel.TabIndex = 16; @@ -182,7 +184,7 @@ private void InitializeComponent() // TCPingRadioBtn // this.TCPingRadioBtn.AutoSize = true; - this.TCPingRadioBtn.Location = new System.Drawing.Point(376, 158); + this.TCPingRadioBtn.Location = new System.Drawing.Point(332, 85); this.TCPingRadioBtn.Name = "TCPingRadioBtn"; this.TCPingRadioBtn.Size = new System.Drawing.Size(59, 16); this.TCPingRadioBtn.TabIndex = 15; @@ -193,7 +195,7 @@ private void InitializeComponent() // ICMPingRadioBtn // this.ICMPingRadioBtn.AutoSize = true; - this.ICMPingRadioBtn.Location = new System.Drawing.Point(312, 158); + this.ICMPingRadioBtn.Location = new System.Drawing.Point(268, 85); this.ICMPingRadioBtn.Name = "ICMPingRadioBtn"; this.ICMPingRadioBtn.Size = new System.Drawing.Size(65, 16); this.ICMPingRadioBtn.TabIndex = 14; @@ -316,32 +318,39 @@ private void InitializeComponent() this.ProfileCountTextBox.TabIndex = 4; this.ProfileCountTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // - // TcpingAtStartedCheckBox + // StartedPingLabel // - this.TcpingAtStartedCheckBox.AutoSize = true; - this.TcpingAtStartedCheckBox.Location = new System.Drawing.Point(15, 186); - this.TcpingAtStartedCheckBox.Name = "TcpingAtStartedCheckBox"; - this.TcpingAtStartedCheckBox.Size = new System.Drawing.Size(156, 16); - this.TcpingAtStartedCheckBox.TabIndex = 5; - this.TcpingAtStartedCheckBox.Text = "Delay test after start"; - this.TcpingAtStartedCheckBox.UseVisualStyleBackColor = true; + this.StartedPingLabel.AutoSize = true; + this.StartedPingLabel.Location = new System.Drawing.Point(12, 187); + this.StartedPingLabel.Name = "StartedPingLabel"; + this.StartedPingLabel.Size = new System.Drawing.Size(137, 12); + this.StartedPingLabel.TabIndex = 5; + this.StartedPingLabel.Text = "Delay test after start"; // - // DetectionIntervalLabel + // DetectionTickLabel // - this.DetectionIntervalLabel.AutoSize = true; - this.DetectionIntervalLabel.Location = new System.Drawing.Point(217, 187); - this.DetectionIntervalLabel.Name = "DetectionIntervalLabel"; - this.DetectionIntervalLabel.Size = new System.Drawing.Size(143, 12); - this.DetectionIntervalLabel.TabIndex = 6; - this.DetectionIntervalLabel.Text = "Detection interval(sec)"; + this.DetectionTickLabel.AutoSize = true; + this.DetectionTickLabel.Location = new System.Drawing.Point(225, 160); + this.DetectionTickLabel.Name = "DetectionTickLabel"; + this.DetectionTickLabel.Size = new System.Drawing.Size(119, 12); + this.DetectionTickLabel.TabIndex = 6; + this.DetectionTickLabel.Text = "Detection Tick(sec)"; // - // DetectionIntervalTextBox + // StartedPingIntervalTextBox // - this.DetectionIntervalTextBox.Location = new System.Drawing.Point(366, 184); - this.DetectionIntervalTextBox.Name = "DetectionIntervalTextBox"; - this.DetectionIntervalTextBox.Size = new System.Drawing.Size(68, 21); - this.DetectionIntervalTextBox.TabIndex = 7; - this.DetectionIntervalTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.StartedPingIntervalTextBox.Location = new System.Drawing.Point(177, 184); + this.StartedPingIntervalTextBox.Name = "StartedPingIntervalTextBox"; + this.StartedPingIntervalTextBox.Size = new System.Drawing.Size(68, 21); + this.StartedPingIntervalTextBox.TabIndex = 7; + this.StartedPingIntervalTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // DetectionTickTextBox + // + this.DetectionTickTextBox.Location = new System.Drawing.Point(366, 157); + this.DetectionTickTextBox.Name = "DetectionTickTextBox"; + this.DetectionTickTextBox.Size = new System.Drawing.Size(68, 21); + this.DetectionTickTextBox.TabIndex = 7; + this.DetectionTickTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // STUNServerLabel // @@ -373,7 +382,7 @@ private void InitializeComponent() // this.AclAddrTextBox.Location = new System.Drawing.Point(120, 245); this.AclAddrTextBox.Name = "AclAddrTextBox"; - this.AclAddrTextBox.Size = new System.Drawing.Size(315, 21); + this.AclAddrTextBox.Size = new System.Drawing.Size(314, 21); this.AclAddrTextBox.TabIndex = 11; this.AclAddrTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // @@ -1027,6 +1036,7 @@ private void InitializeComponent() this.ResumeLayout(false); this.PerformLayout(); } + private System.Windows.Forms.TextBox StartedPingIntervalTextBox; private System.Windows.Forms.CheckBox NoProxyForTcpCheckBox; #endregion @@ -1076,9 +1086,9 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox LanguageComboBox; private System.Windows.Forms.TextBox AclAddrTextBox; private System.Windows.Forms.Label AclLabel; - private System.Windows.Forms.Label DetectionIntervalLabel; - private System.Windows.Forms.TextBox DetectionIntervalTextBox; - private System.Windows.Forms.CheckBox TcpingAtStartedCheckBox; + private System.Windows.Forms.Label DetectionTickLabel; + private System.Windows.Forms.TextBox DetectionTickTextBox; + private System.Windows.Forms.Label StartedPingLabel; private System.Windows.Forms.Label STUNServerLabel; private System.Windows.Forms.ComboBox STUN_ServerComboBox; private System.Windows.Forms.Label ProfileCountLabel; diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index 5bed59916e..929210bbf0 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -72,13 +72,14 @@ private void InitValue() i => i > -1, i => Global.Settings.ProfileCount = i, Global.Settings.ProfileCount); - BindCheckBox(TcpingAtStartedCheckBox, - b => Global.Settings.StartedTcping = b, - Global.Settings.StartedTcping); - BindTextBox(DetectionIntervalTextBox, + BindTextBox(DetectionTickTextBox, i => i >= 0, - i => Global.Settings.StartedTcping_Interval = i, - Global.Settings.StartedTcping_Interval); + i => Global.Settings.DetectionTick = i, + Global.Settings.DetectionTick); + BindTextBox(StartedPingIntervalTextBox, + _ => true, + i => Global.Settings.StartedPingInterval = i, + Global.Settings.StartedPingInterval); InitSTUN(); diff --git a/Netch/Models/Setting.cs b/Netch/Models/Setting.cs index 43f6e4caf6..cb252ef01e 100644 --- a/Netch/Models/Setting.cs +++ b/Netch/Models/Setting.cs @@ -115,6 +115,11 @@ public class Setting /// public bool CheckUpdateWhenOpened = true; + /// + /// 测试所有服务器心跳/秒 + /// + public int DetectionTick = 10; + /// /// 是否关闭窗口时退出 /// @@ -230,15 +235,10 @@ public class Setting /// public ushort Socks5LocalPort = 2801; - /// - /// 是否启用启动后延迟测试 - /// - public bool StartedTcping = false; - /// /// 启动后延迟测试间隔/秒 /// - public int StartedTcping_Interval = 3; + public int StartedPingInterval = -1; /// /// 是否打开软件时启动加速 diff --git a/Netch/Utils/ServerHelper.cs b/Netch/Utils/ServerHelper.cs index 554559510b..57e3f3bcf6 100644 --- a/Netch/Utils/ServerHelper.cs +++ b/Netch/Utils/ServerHelper.cs @@ -15,23 +15,75 @@ static ServerHelper() { var serversUtilsTypes = Assembly.GetExecutingAssembly().GetExportedTypes().Where(type => type.GetInterfaces().Contains(typeof(IServerUtil))); ServerUtils = serversUtilsTypes.Select(t => (IServerUtil) Activator.CreateInstance(t)).OrderBy(util => util.Priority); + } + + #region Delay + + public static class DelayTestHelper + { + private static readonly Timer Timer; + private static bool _mux; + static DelayTestHelper() + { + Timer = new Timer + { + Interval = 10000, + AutoReset = true, + Enabled = false + }; + + Timer.Elapsed += (_, _) => TestAllDelay(); + } - Timer = new Timer + public static bool Enabled { - Interval = 10000, - AutoReset = true, - Enabled = false - }; + get => Timer.Enabled; + set => Timer.Enabled = value; + } - Timer.Elapsed += (_, _) => TestAllDelay(); - Timer.Start(); + public static int Interval => (int) (Timer.Interval / 1000); + public static event EventHandler TestDelayFinished; + + public static void TestAllDelay() + { + if (_mux) + return; + try + { + _mux = true; + Parallel.ForEach(Global.Settings.Server, new ParallelOptions {MaxDegreeOfParallelism = 16}, + server => { server.Test(); }); + _mux = false; + TestDelayFinished?.Invoke(null, new EventArgs()); + } + catch (Exception) + { + // ignored + } + } + + public static void UpdateInterval() + { + var enabled = Enabled; + Timer.Stop(); + if (Global.Settings.DetectionTick <= 0) + return; + + Timer.Interval = Global.Settings.DetectionTick * 1000; + if (enabled) + { + Task.Run(TestAllDelay); + Timer.Start(); + } + } } + #endregion + #region Handler public static readonly IEnumerable ServerUtils; - public static Server ParseJObject(JObject o) { var handle = GetUtilByTypeName((string) o["Type"]); @@ -64,32 +116,5 @@ public static IServerUtil GetUtilByUriScheme(string typeName) } #endregion - - #region Delay - - public static readonly Timer Timer; - - private static bool _mux; - public static event EventHandler TestDelayFinished; - - public static void TestAllDelay() - { - if (_mux) - return; - try - { - _mux = true; - Parallel.ForEach(Global.Settings.Server, new ParallelOptions {MaxDegreeOfParallelism = 16}, - server => { server.Test(); }); - _mux = false; - TestDelayFinished?.Invoke(null, new EventArgs()); - } - catch (Exception) - { - // ignored - } - } - - #endregion } } \ No newline at end of file