diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs index c378b588..38985483 100644 --- a/Netch/Controllers/MainController.cs +++ b/Netch/Controllers/MainController.cs @@ -14,63 +14,22 @@ namespace Netch.Controllers { public static class MainController { - /// - /// 记录当前使用的端口 - /// - /// - public static readonly List UsingPorts = new List(); - public static EncryptedProxy EncryptedProxyController { get; private set; } - public static ModeController ModeController { get; private set; } - private static Server _savedServer; - private static Mode _savedMode; - public static string PortInfo - { - get - { - if (_savedMode == null || _savedServer == null) - return string.Empty; + public static Server SavedServer; + public static Mode SavedMode; - if (_savedServer.Type == "Socks5" && _savedMode.Type != 3 && _savedMode.Type != 5) - // 不可控Socks5, 不可控HTTP - return string.Empty; + public static bool IsSocks5Server => SavedServer.Type == "Socks5"; + public static string LocalAddress; + public static int RedirectorTcpPort; + public static int HttpPort; + public static int Socks5Port; - var text = new StringBuilder(); - if (_localAddress == "0.0.0.0") - text.Append(i18N.Translate("Allow other Devices to connect") + " "); + public static bool NttTested; - if (_savedServer.Type != "Socks5") - // 可控Socks5 - text.Append($"Socks5 {i18N.Translate("Local Port", ": ")}{_socks5Port}"); - - if (_savedMode.Type == 3 || _savedMode.Type == 5) - // 有HTTP - { - if (_savedServer.Type != "Socks5") - text.Append(" | "); - text.Append($"HTTP {i18N.Translate("Local Port", ": ")}{_httpPort}"); - } - - return $" ({text})"; - } - } - - /// - /// NTT 控制器 - /// - public static readonly NTTController NTTController = new NTTController(); - - private static string _localAddress; - private static int _redirectorTCPPort; - private static int _httpPort; - private static int _socks5Port; - - - [DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")] - public static extern uint FlushDNSResolverCache(); + private static readonly NTTController NTTController = new NTTController(); /// /// 启动 @@ -84,20 +43,20 @@ namespace Netch.Controllers #region Record Settings - _httpPort = Global.Settings.HTTPLocalPort; - _socks5Port = server.Type != "Socks5" ? Global.Settings.Socks5LocalPort : server.Port; - _redirectorTCPPort = Global.Settings.RedirectorTCPPort; - _localAddress = server.Type != "Socks5" ? Global.Settings.LocalAddress : "127.0.0.1"; - _savedServer = server; - _savedMode = mode; + HttpPort = Global.Settings.HTTPLocalPort; + Socks5Port = server.Type != "Socks5" ? Global.Settings.Socks5LocalPort : server.Port; + RedirectorTcpPort = Global.Settings.RedirectorTCPPort; + LocalAddress = server.Type != "Socks5" ? Global.Settings.LocalAddress : "127.0.0.1"; + SavedServer = server; + SavedMode = mode; #endregion - FlushDNSResolverCache(); + NativeMethods.FlushDNSResolverCache(); _ = Task.Run(Firewall.AddNetchFwRules); bool result; - if (server.Type == "Socks5") + if (IsSocks5Server) { result = mode.Type != 4; } @@ -112,24 +71,31 @@ namespace Netch.Controllers _ => EncryptedProxyController }; - KillProcessByName(EncryptedProxyController.MainFile); + Utils.Utils.KillProcessByName(EncryptedProxyController.MainFile); #region 检查端口是否被占用 - var portNotAvailable = false; - if (_savedServer.Type != "Socks5") + static bool PortCheckAndShowMessageBox(int port, string portName, PortType portType = PortType.Both) { - portNotAvailable |= PortCheckAndShowMessageBox(_socks5Port, "Socks5"); + if (!PortHelper.PortInUse(port, portType)) return false; + MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", portName)); + return true; } - switch (_savedMode.Type) + var portNotAvailable = false; + if (!IsSocks5Server) + { + portNotAvailable |= PortCheckAndShowMessageBox(Socks5Port, "Socks5"); + } + + switch (SavedMode.Type) { case 0: - portNotAvailable |= PortCheckAndShowMessageBox(_redirectorTCPPort, "Redirector TCP"); + portNotAvailable |= PortCheckAndShowMessageBox(RedirectorTcpPort, "Redirector TCP"); break; case 3: case 5: - portNotAvailable |= PortCheckAndShowMessageBox(_httpPort, "HTTP"); + portNotAvailable |= PortCheckAndShowMessageBox(HttpPort, "HTTP"); break; } @@ -156,7 +122,6 @@ namespace Netch.Controllers if (result) { // 加密代理成功启动 - UsingPorts.Add(_socks5Port); switch (mode.Type) { @@ -197,14 +162,17 @@ namespace Netch.Controllers { // 成功启动 + if (!IsSocks5Server) + PortHelper.UsingPorts.Add(Socks5Port); + switch (mode.Type) // 记录使用端口 { case 0: - UsingPorts.Add(_redirectorTCPPort); + PortHelper.UsingPorts.Add(RedirectorTcpPort); break; case 3: case 5: - UsingPorts.Add(_httpPort); + PortHelper.UsingPorts.Add(HttpPort); break; } @@ -235,7 +203,25 @@ namespace Netch.Controllers return result; } - public static bool NttTested; + /// + /// 停止 + /// + public static async Task Stop() + { + HttpPort = Socks5Port = RedirectorTcpPort = 0; + LocalAddress = null; + SavedMode = null; + SavedServer = null; + PortHelper.UsingPorts.Clear(); + + var tasks = new Task[] + { + Task.Run(() => EncryptedProxyController?.Stop()), + Task.Run(() => ModeController?.Stop()), + Task.Run(() => NTTController.Stop()) + }; + await Task.WhenAll(tasks); + } /// /// 测试 NAT @@ -260,57 +246,5 @@ namespace Netch.Controllers NttTested = true; }); } - - /// - /// 停止 - /// - public static async Task Stop() - { - _httpPort = _socks5Port = _redirectorTCPPort = 0; - _localAddress = null; - _savedMode = null; - _savedServer = null; - UsingPorts.Clear(); - - var tasks = new Task[] - { - Task.Run(() => EncryptedProxyController?.Stop()), - Task.Run(() => ModeController?.Stop()), - Task.Run(() => NTTController.Stop()) - }; - await Task.WhenAll(tasks); - } - - public static void KillProcessByName(string name) - { - try - { - foreach (var p in Process.GetProcessesByName(name)) - if (p.MainModule != null && p.MainModule.FileName.StartsWith(Global.NetchDir)) - p.Kill(); - } - catch (Win32Exception e) - { - Logging.Error($"结束进程 {name} 错误:" + e.Message); - } - catch (Exception) - { - // ignored - } - } - - /// - /// - /// - /// - /// - /// - /// 端口是否被占用 - private static bool PortCheckAndShowMessageBox(int port, string portName, PortType portType = PortType.Both) - { - if (!PortHelper.PortInUse(port, portType)) return false; - MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", portName)); - return true; - } } } \ No newline at end of file diff --git a/Netch/Forms/MainForm.Status.cs b/Netch/Forms/MainForm.Status.cs index 9c7d4f1f..e1ab770e 100644 --- a/Netch/Forms/MainForm.Status.cs +++ b/Netch/Forms/MainForm.Status.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Text; using System.Threading; using System.Windows; using Netch.Controllers; @@ -69,7 +70,7 @@ namespace Netch.Forms ControlButton.Enabled = true; ControlButton.Text = i18N.Translate("Stop"); - StatusTextAppend(MainController.PortInfo); + StatusTextAppend(StatusPortInfoText); ProfileGroupBox.Enabled = true; @@ -227,5 +228,36 @@ namespace Netch.Forms { StatusLabel.Text += text; } + + private static string StatusPortInfoText + { + get + { + if (MainController.SavedMode == null || MainController.SavedServer == null) + return string.Empty; + + if (MainController.SavedServer.Type == "Socks5" && MainController.SavedMode.Type != 3 && MainController.SavedMode.Type != 5) + // 不可控Socks5, 不可控HTTP + return string.Empty; + + var text = new StringBuilder(); + if (MainController.LocalAddress == "0.0.0.0") + text.Append(i18N.Translate("Allow other Devices to connect") + " "); + + if (MainController.SavedServer.Type != "Socks5") + // 可控Socks5 + text.Append($"Socks5 {i18N.Translate("Local Port", ": ")}{MainController.Socks5Port}"); + + if (MainController.SavedMode.Type == 3 || MainController.SavedMode.Type == 5) + // 有HTTP + { + if (MainController.SavedServer.Type != "Socks5") + text.Append(" | "); + text.Append($"HTTP {i18N.Translate("Local Port", ": ")}{MainController.HttpPort}"); + } + + return $" ({text})"; + } + } } } \ No newline at end of file diff --git a/Netch/NativeMethods.cs b/Netch/NativeMethods.cs index 6edd21f7..e23d5cb6 100644 --- a/Netch/NativeMethods.cs +++ b/Netch/NativeMethods.cs @@ -61,5 +61,8 @@ namespace Netch [DllImport("bin\\shadowsocks-windows-dynamic", CallingConvention = CallingConvention.Cdecl)] public static extern void Stop(); } + + [DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")] + public static extern uint FlushDNSResolverCache(); } } diff --git a/Netch/Utils/MessageBoxX.cs b/Netch/Utils/MessageBoxX.cs index 1f096313..f66967d0 100644 --- a/Netch/Utils/MessageBoxX.cs +++ b/Netch/Utils/MessageBoxX.cs @@ -4,7 +4,7 @@ using Netch.Models; namespace Netch.Utils { - class MessageBoxX + static class MessageBoxX { /// /// diff --git a/Netch/Utils/PortHelper.cs b/Netch/Utils/PortHelper.cs index bfd7e6bc..6bed11ef 100644 --- a/Netch/Utils/PortHelper.cs +++ b/Netch/Utils/PortHelper.cs @@ -107,7 +107,7 @@ namespace Netch.Utils var isUdpUsed = type != PortType.TCP && (IsPortExcluded(port, PortType.UDP) || netInfo.GetActiveUdpListeners().Any(ipEndPoint => ipEndPoint.Port == port)); - var isPortExcluded = !MainController.UsingPorts.Contains(port); + var isPortExcluded = !UsingPorts.Contains(port); return isPortExcluded && (isTcpUsed || isUdpUsed); } @@ -125,6 +125,11 @@ namespace Netch.Utils throw new Exception("Cant Generate Available Port"); } + + /// + /// 记录Netch使用的端口 + /// + public static readonly List UsingPorts = new List(); } /// diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index 52a59ad6..6a3ae5e5 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -1,5 +1,6 @@ using MaxMind.GeoIP2; using System; +using System.ComponentModel; using System.Diagnostics; using System.IO; using System.IO.Compression; @@ -105,17 +106,21 @@ namespace Netch.Utils } } - public static bool IsZipValid(string path) + public static void KillProcessByName(string name) { try { - using var zipFile = ZipFile.OpenRead(path); - _ = zipFile.Entries; - return true; + foreach (var p in Process.GetProcessesByName(name)) + if (p.MainModule != null && p.MainModule.FileName.StartsWith(Global.NetchDir)) + p.Kill(); } - catch (InvalidDataException) + catch (Win32Exception e) { - return false; + Logging.Error($"结束进程 {name} 错误:" + e.Message); + } + catch (Exception) + { + // ignored } } }