diff --git a/Netch/Controllers/Guard.cs b/Netch/Controllers/Guard.cs index 472dd27a..493a7e75 100644 --- a/Netch/Controllers/Guard.cs +++ b/Netch/Controllers/Guard.cs @@ -1,5 +1,3 @@ -using Netch.Models; -using Netch.Utils; using System; using System.Collections.Generic; using System.ComponentModel; @@ -9,6 +7,8 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Netch.Models; +using Netch.Utils; using Serilog; using Timer = System.Timers.Timer; @@ -178,69 +178,6 @@ namespace Netch.Controllers throw new MessageException($"{Name} 控制器启动超时"); } - #region FileStream - - private void OpenLogFile() - { - if (!RedirectToFile) - return; - - _logFileStream = File.Open(LogPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); - _logStreamWriter = new StreamWriter(_logFileStream); - - _flushFileStreamTimer.Elapsed += FlushFileStreamTimerEvent; - _flushFileStreamTimer.Enabled = true; - } - - private void WriteLog(string line) - { - if (!RedirectToFile) - return; - - _logStreamWriter!.WriteLine(line); - } - - private readonly object _logStreamLock = new(); - private void CloseLogFile() - { - if (!RedirectToFile) - return; - - lock (_logStreamLock) - { - if (_logFileStream == null) - return; - - _flushFileStreamTimer.Enabled = false; - _logStreamWriter?.Close(); - _logFileStream?.Close(); - _logStreamWriter = _logStreamWriter = null; - } - } - - #endregion - - #region virtual - - protected virtual void OnReadNewLine(string line) - { - } - - protected virtual void OnKeywordStarted() - { - } - - protected virtual void OnKeywordStopped() - { - Utils.Utils.Open(LogPath); - } - - protected virtual void OnKeywordTimeout() - { - } - - #endregion - protected void ReadOutput(TextReader reader) { string? line; @@ -279,5 +216,69 @@ namespace Netch.Controllers Log.Warning(ex, "写入 {Name} 日志异常", Name); } } + + #region FileStream + + private void OpenLogFile() + { + if (!RedirectToFile) + return; + + _logFileStream = File.Open(LogPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); + _logStreamWriter = new StreamWriter(_logFileStream); + + _flushFileStreamTimer.Elapsed += FlushFileStreamTimerEvent; + _flushFileStreamTimer.Enabled = true; + } + + private void WriteLog(string line) + { + if (!RedirectToFile) + return; + + _logStreamWriter!.WriteLine(line); + } + + private readonly object _logStreamLock = new(); + + private void CloseLogFile() + { + if (!RedirectToFile) + return; + + lock (_logStreamLock) + { + if (_logFileStream == null) + return; + + _flushFileStreamTimer.Enabled = false; + _logStreamWriter?.Close(); + _logFileStream?.Close(); + _logStreamWriter = _logStreamWriter = null; + } + } + + #endregion + + #region virtual + + protected virtual void OnReadNewLine(string line) + { + } + + protected virtual void OnKeywordStarted() + { + } + + protected virtual void OnKeywordStopped() + { + Misc.Open(LogPath); + } + + protected virtual void OnKeywordTimeout() + { + } + + #endregion } } \ No newline at end of file diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs index 26f6de35..6df14764 100644 --- a/Netch/Controllers/MainController.cs +++ b/Netch/Controllers/MainController.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Netch.Interfaces; using Netch.Models; using Netch.Servers.Socks5; +using Netch.Services; using Netch.Utils; using Serilog; diff --git a/Netch/Controllers/NFController.cs b/Netch/Controllers/NFController.cs index da628f9e..8aceac10 100644 --- a/Netch/Controllers/NFController.cs +++ b/Netch/Controllers/NFController.cs @@ -16,9 +16,8 @@ namespace Netch.Controllers { public class NFController : IModeController { - private static readonly ServiceController NFService = new("netfilter2"); - private const string BinDriver = "bin\\nfdriver.sys"; + private static readonly ServiceController NFService = new("netfilter2"); private static readonly string SystemDriver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys"; public string Name { get; } = "Redirector"; @@ -53,48 +52,6 @@ namespace Netch.Controllers Free(); } - #region CheckRule - - /// - /// - /// - /// - /// No Problem true - private static bool CheckCppRegex(string r, bool clear = true) - { - try - { - if (r.StartsWith("!")) - return Dial(NameList.TYPE_ADDNAME, r.Substring(1)); - - return Dial(NameList.TYPE_ADDNAME, r); - } - finally - { - if (clear) - Dial(NameList.TYPE_CLRNAME, ""); - } - } - - /// - /// - /// - /// - /// No Problem true - public static bool CheckRules(IEnumerable rules, out IEnumerable results) - { - results = rules.Where(r => !CheckCppRegex(r, false)); - Dial(NameList.TYPE_CLRNAME, ""); - return !results.Any(); - } - - public static string GenerateInvalidRulesMessage(IEnumerable rules) - { - return $"{string.Join("\n", rules)}\nAbove rules does not conform to C++ regular expression syntax"; - } - - #endregion - private void dial_Server(in PortType portType) { if (portType == PortType.Both) @@ -171,12 +128,54 @@ namespace Netch.Controllers Dial(NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$"); } + #region CheckRule + + /// + /// + /// + /// + /// No Problem true + private static bool CheckCppRegex(string r, bool clear = true) + { + try + { + if (r.StartsWith("!")) + return Dial(NameList.TYPE_ADDNAME, r.Substring(1)); + + return Dial(NameList.TYPE_ADDNAME, r); + } + finally + { + if (clear) + Dial(NameList.TYPE_CLRNAME, ""); + } + } + + /// + /// + /// + /// + /// No Problem true + public static bool CheckRules(IEnumerable rules, out IEnumerable results) + { + results = rules.Where(r => !CheckCppRegex(r, false)); + Dial(NameList.TYPE_CLRNAME, ""); + return !results.Any(); + } + + public static string GenerateInvalidRulesMessage(IEnumerable rules) + { + return $"{string.Join("\n", rules)}\nAbove rules does not conform to C++ regular expression syntax"; + } + + #endregion + #region DriverUtil private static void CheckDriver() { - var binFileVersion = Utils.Utils.GetFileVersion(BinDriver); - var systemFileVersion = Utils.Utils.GetFileVersion(SystemDriver); + var binFileVersion = Misc.GetFileVersion(BinDriver); + var systemFileVersion = Misc.GetFileVersion(SystemDriver); Log.Information("内置驱动版本: " + binFileVersion); Log.Information("系统驱动版本: " + systemFileVersion); @@ -231,7 +230,7 @@ namespace Netch.Controllers } catch (Exception e) { - Log.Error(e,"驱动复制失败\n"); + Log.Error(e, "驱动复制失败\n"); throw new MessageException($"Copy NF driver file failed\n{e.Message}"); } @@ -244,7 +243,7 @@ namespace Netch.Controllers } else { - Log.Error("注册驱动失败: {Result}",result); + Log.Error("注册驱动失败: {Result}", result); throw new MessageException($"Register NF driver failed\n{result}"); } } diff --git a/Netch/Controllers/PcapController.cs b/Netch/Controllers/PcapController.cs index 765cf3e0..e1306924 100644 --- a/Netch/Controllers/PcapController.cs +++ b/Netch/Controllers/PcapController.cs @@ -15,7 +15,7 @@ namespace Netch.Controllers { public class PcapController : Guard, IModeController { - public override string Name { get; } = "pcap2socks"; + private LogForm? _form; public override string MainFile { get; protected set; } = "pcap2socks.exe"; @@ -23,7 +23,7 @@ namespace Netch.Controllers protected override Encoding? InstanceOutputEncoding { get; } = Encoding.UTF8; - private LogForm? _form; + public override string Name { get; } = "pcap2socks"; public void Start(in Mode mode) { @@ -44,6 +44,12 @@ namespace Netch.Controllers StartInstanceAuto(argument.ToString()); } + public override void Stop() + { + _form!.Close(); + StopInstance(); + } + protected override void OnReadNewLine(string line) { Global.MainForm.BeginInvoke(new Action(() => @@ -65,19 +71,13 @@ namespace Netch.Controllers Task.Run(() => { Thread.Sleep(1000); - Utils.Utils.Open("https://github.com/zhxie/pcap2socks#dependencies"); + Misc.Open("https://github.com/zhxie/pcap2socks#dependencies"); }); throw new MessageException("Pleases install pcap2socks's dependency"); } - Utils.Utils.Open(LogPath); - } - - public override void Stop() - { - _form!.Close(); - StopInstance(); + Misc.Open(LogPath); } } } \ No newline at end of file diff --git a/Netch/Controllers/TUNController.cs b/Netch/Controllers/TUNController.cs index eede3230..0628e5bd 100644 --- a/Netch/Controllers/TUNController.cs +++ b/Netch/Controllers/TUNController.cs @@ -5,10 +5,10 @@ using System.Net.Sockets; using System.Threading.Tasks; using Netch.Enums; using Netch.Interfaces; +using Netch.Interops; using Netch.Models; using Netch.Servers.Socks5; using Netch.Utils; -using Netch.Interops; using Serilog; using static Netch.Interops.tun2socks; @@ -16,19 +16,19 @@ namespace Netch.Controllers { public class TUNController : IModeController { - public string Name => "tun2socks"; - private const string DummyDns = "6.6.6.6"; private readonly DNSController _aioDnsController = new(); - private NetRoute _outbound; + private Mode _mode = null!; - private NetRoute _tun; + private NetRoute _outbound; private IPAddress? _serverRemoteAddress; - private Mode _mode = null!; + private NetRoute _tun; + + public string Name => "tun2socks"; public void Start(in Mode mode) { @@ -97,16 +97,52 @@ namespace Netch.Controllers throw new MessageException("tun2socks start failed."); var tunIndex = (int)RouteHelper.ConvertLuidToIndex(tun_luid()); - _tun = NetRoute.TemplateBuilder(Global.Settings.TUNTAP.Gateway, tunIndex); + _tun = NetRoute.TemplateBuilder(IPAddress.Parse(Global.Settings.TUNTAP.Gateway), tunIndex); RouteHelper.CreateUnicastIP(AddressFamily.InterNetwork, Global.Settings.TUNTAP.Address, - (byte)Utils.Utils.SubnetToCidr(Global.Settings.TUNTAP.Netmask), + (byte)Misc.SubnetToCidr(Global.Settings.TUNTAP.Netmask), (ulong)tunIndex); SetupRouteTable(mode); } + public void Stop() + { + var tasks = new[] + { + Task.Run(Free), + Task.Run(ClearRouteTable), + Task.Run(_aioDnsController.Stop) + }; + + Task.WaitAll(tasks); + } + + private void CheckDriver() + { + string binDriver = Path.Combine(Global.NetchDir, @"bin\wintun.dll"); + string sysDriver = $@"{Environment.SystemDirectory}\wintun.dll"; + + var binHash = Misc.Sha256CheckSum(binDriver); + var sysHash = Misc.Sha256CheckSum(sysDriver); + Log.Information("自带 wintun.dll Hash: {Hash}", binHash); + Log.Information("系统 wintun.dll Hash: {Hash}", sysHash); + if (binHash == sysHash) + return; + + try + { + Log.Information("Copy wintun.dll to System Directory"); + File.Copy(binDriver, sysDriver, true); + } + catch (Exception e) + { + Log.Error(e, "复制 wintun.dll 异常"); + throw new MessageException($"Failed to copy wintun.dll to system directory: {e.Message}"); + } + } + #region Route private void SetupRouteTable(Mode mode) @@ -136,7 +172,7 @@ namespace Netch.Controllers if (!Global.Settings.TUNTAP.UseCustomDNS) // proxy AioDNS other dns - RouteUtils.CreateRoute(_tun.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.OtherDNS), 32)); + RouteUtils.CreateRoute(_tun.FillTemplate(Misc.GetHostFromUri(Global.Settings.AioDNS.OtherDNS), 32)); } break; @@ -147,7 +183,7 @@ namespace Netch.Controllers if (!Global.Settings.TUNTAP.UseCustomDNS) // bypass AioDNS other dns - RouteUtils.CreateRoute(_outbound.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32)); + RouteUtils.CreateRoute(_outbound.FillTemplate(Misc.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32)); NetworkInterfaceUtils.SetInterfaceMetric(_tun.InterfaceIndex, 0); RouteUtils.CreateRoute(_tun.FillTemplate("0.0.0.0", 0)); @@ -172,41 +208,5 @@ namespace Netch.Controllers } #endregion - - public void Stop() - { - var tasks = new[] - { - Task.Run(Free), - Task.Run(ClearRouteTable), - Task.Run(_aioDnsController.Stop) - }; - - Task.WaitAll(tasks); - } - - private void CheckDriver() - { - string binDriver = Path.Combine(Global.NetchDir, @"bin\wintun.dll"); - string sysDriver = $@"{Environment.SystemDirectory}\wintun.dll"; - - var binHash = Utils.Utils.SHA256CheckSum(binDriver); - var sysHash = Utils.Utils.SHA256CheckSum(sysDriver); - Log.Information("自带 wintun.dll Hash: {Hash}", binHash); - Log.Information("系统 wintun.dll Hash: {Hash}", sysHash); - if (binHash == sysHash) - return; - - try - { - Log.Information("Copy wintun.dll to System Directory"); - File.Copy(binDriver, sysDriver, true); - } - catch (Exception e) - { - Log.Error(e, "复制 wintun.dll 异常"); - throw new MessageException($"Failed to copy wintun.dll to system directory: {e.Message}"); - } - } } } \ No newline at end of file diff --git a/Netch/Forms/AboutForm.cs b/Netch/Forms/AboutForm.cs index 96431cae..ffbb83eb 100644 --- a/Netch/Forms/AboutForm.cs +++ b/Netch/Forms/AboutForm.cs @@ -1,8 +1,7 @@ -using Netch.Properties; -using Netch.Utils; -using System; -using System.Diagnostics; +using System; using System.Windows.Forms; +using Netch.Properties; +using Netch.Utils; namespace Netch.Forms { @@ -21,17 +20,17 @@ namespace Netch.Forms private void NetchPictureBox_Click(object sender, EventArgs e) { - Utils.Utils.Open("https://github.com/NetchX/Netch"); + Misc.Open("https://github.com/NetchX/Netch"); } private void ChannelLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { - Utils.Utils.Open("https://t.me/Netch"); + Misc.Open("https://t.me/Netch"); } private void SponsorPictureBox_Click(object sender, EventArgs e) { - Utils.Utils.Open("https://www.mansora.co"); + Misc.Open("https://www.mansora.co"); } } } \ No newline at end of file diff --git a/Netch/Forms/GlobalBypassIPForm.cs b/Netch/Forms/GlobalBypassIPForm.cs index 94c3bb23..3276dbf6 100644 --- a/Netch/Forms/GlobalBypassIPForm.cs +++ b/Netch/Forms/GlobalBypassIPForm.cs @@ -1,9 +1,10 @@ -using Netch.Properties; -using Netch.Utils; -using System; +using System; using System.Linq; using System.Net; using System.Windows.Forms; +using Netch.Properties; +using Netch.Services; +using Netch.Utils; namespace Netch.Forms { diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index 0d64b3b4..44ee9ade 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -151,8 +151,8 @@ namespace Netch.Forms } } - Utils.Utils.ComponentIterator(this, RecordText); - Utils.Utils.ComponentIterator(NotifyMenu, RecordText); + Misc.ComponentIterator(this, RecordText); + Misc.ComponentIterator(NotifyMenu, RecordText); _textRecorded = true; } @@ -192,8 +192,8 @@ namespace Netch.Forms } } - Utils.Utils.ComponentIterator(this, TranslateText); - Utils.Utils.ComponentIterator(NotifyMenu, TranslateText); + Misc.ComponentIterator(this, TranslateText); + Misc.ComponentIterator(NotifyMenu, TranslateText); #endregion @@ -340,7 +340,7 @@ namespace Netch.Forms private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e) { - Utils.Utils.Open(".\\"); + Misc.Open(".\\"); } private async void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e) @@ -407,14 +407,14 @@ namespace Netch.Forms private void VersionLabel_Click(object sender, EventArgs e) { - Utils.Utils.Open($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases"); + Misc.Open($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases"); } private async void NewVersionLabel_Click(object sender, EventArgs e) { if (ModifierKeys == Keys.Control || !UpdateChecker.LatestRelease!.assets.Any()) { - Utils.Utils.Open(UpdateChecker.LatestVersionUrl!); + Misc.Open(UpdateChecker.LatestVersionUrl!); return; } @@ -455,7 +455,7 @@ namespace Netch.Forms private void fAQToolStripMenuItem_Click(object sender, EventArgs e) { - Utils.Utils.Open("https://netch.org/#/docs/zh-CN/faq"); + Misc.Open("https://netch.org/#/docs/zh-CN/faq"); } #endregion @@ -726,7 +726,7 @@ namespace Netch.Forms var mode = (Models.Mode)ModeComboBox.SelectedItem; if (ModifierKeys == Keys.Control) { - Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!)); + Misc.Open(ModeHelper.GetFullPath(mode.RelativePath!)); return; } @@ -744,7 +744,7 @@ namespace Netch.Forms Show(); break; default: - Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!)); + Misc.Open(ModeHelper.GetFullPath(mode.RelativePath!)); break; } } @@ -1149,7 +1149,7 @@ namespace Netch.Forms if (!string.IsNullOrEmpty(publicEnd)) { - var country = Utils.Utils.GetCityCode(publicEnd!); + var country = Misc.GetCityCode(publicEnd!); NatTypeStatusText(result, country); } else diff --git a/Netch/Forms/Mode/Process.cs b/Netch/Forms/Mode/Process.cs index 9e4b5302..ef8b4a4f 100644 --- a/Netch/Forms/Mode/Process.cs +++ b/Netch/Forms/Mode/Process.cs @@ -1,14 +1,15 @@ -using Microsoft.WindowsAPICodePack.Dialogs; -using Netch.Controllers; -using Netch.Models; -using Netch.Properties; -using Netch.Utils; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; +using Microsoft.WindowsAPICodePack.Dialogs; +using Netch.Controllers; using Netch.Enums; +using Netch.Models; +using Netch.Properties; +using Netch.Services; +using Netch.Utils; namespace Netch.Forms.Mode { @@ -35,25 +36,6 @@ namespace Netch.Forms.Mode _mode = mode; } - #region Model - - public IEnumerable Rules => RuleRichTextBox.Lines; - - private void RuleAdd(string value) - { - RuleRichTextBox.AppendText($"{value}\n"); - } - - private void RuleAddRange(IEnumerable value) - { - foreach (string s in value) - { - RuleAdd(s); - } - } - - #endregion - public void ModeForm_Load(object sender, EventArgs e) { if (_mode != null) @@ -82,7 +64,6 @@ namespace Netch.Forms.Mode }; if (dialog.ShowDialog(Handle) == CommonFileDialogResult.Ok) - { foreach (string p in dialog.FileNames) { string path = p; @@ -91,7 +72,6 @@ namespace Netch.Forms.Mode RuleAdd($"^{path.ToRegexString()}"); } - } } public void ControlButton_Click(object sender, EventArgs e) @@ -208,5 +188,22 @@ namespace Netch.Forms.Mode else MessageBoxX.Show("Fine"); } + + #region Model + + public IEnumerable Rules => RuleRichTextBox.Lines; + + private void RuleAdd(string value) + { + RuleRichTextBox.AppendText($"{value}\n"); + } + + private void RuleAddRange(IEnumerable value) + { + foreach (string s in value) + RuleAdd(s); + } + + #endregion } } \ No newline at end of file diff --git a/Netch/Forms/Mode/Route.cs b/Netch/Forms/Mode/Route.cs index 8eecd5da..71337b83 100644 --- a/Netch/Forms/Mode/Route.cs +++ b/Netch/Forms/Mode/Route.cs @@ -1,10 +1,11 @@ -using Netch.Models; -using Netch.Properties; -using Netch.Utils; -using System; +using System; using System.IO; using System.Windows.Forms; using Netch.Enums; +using Netch.Models; +using Netch.Properties; +using Netch.Services; +using Netch.Utils; namespace Netch.Forms.Mode { diff --git a/Netch/Forms/ServerForm.cs b/Netch/Forms/ServerForm.cs index 0a0daa7e..cc1210f5 100644 --- a/Netch/Forms/ServerForm.cs +++ b/Netch/Forms/ServerForm.cs @@ -1,13 +1,13 @@ #nullable disable -using Netch.Models; -using Netch.Properties; -using Netch.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Windows.Forms; +using Netch.Models; +using Netch.Properties; +using Netch.Utils; namespace Netch.Forms { @@ -21,12 +21,12 @@ namespace Netch.Forms private readonly Dictionary> _saveActions = new(); + private readonly IContainer components = null; + private int _controlLines = 2; private Label AddressLabel; protected TextBox AddressTextBox; - private readonly IContainer components = null; - private GroupBox ConfigurationGroupBox; private Label PortLabel; private TextBox PortTextBox; @@ -130,7 +130,7 @@ namespace Netch.Forms comboBox.Items.AddRange(values.ToArray()); comboBox.SelectedIndex = values.IndexOf(value); - comboBox.DrawItem += Utils.Utils.DrawCenterComboBox; + comboBox.DrawItem += Misc.DrawCenterComboBox; _saveActions.Add(comboBox, o => save.Invoke((string)o)); ConfigurationGroupBox.Controls.AddRange(new Control[] { @@ -184,12 +184,12 @@ namespace Netch.Forms private void ControlButton_Click(object sender, EventArgs e) { - Utils.Utils.ComponentIterator(this, component => Utils.Utils.ChangeControlForeColor(component, Color.Black)); + Misc.ComponentIterator(this, component => Misc.ChangeControlForeColor(component, Color.Black)); var flag = true; foreach (var pair in _checkActions.Where(pair => !pair.Value.Invoke(pair.Key.Text))) { - Utils.Utils.ChangeControlForeColor(pair.Key, Color.Red); + Misc.ChangeControlForeColor(pair.Key, Color.Red); flag = false; } diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index 59cbda36..b2a73412 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -1,6 +1,3 @@ -using Netch.Models; -using Netch.Properties; -using Netch.Utils; using System; using System.Collections.Generic; using System.Drawing; @@ -8,6 +5,10 @@ using System.IO; using System.Linq; using System.Net; using System.Windows.Forms; +using Netch.Models; +using Netch.Properties; +using Netch.Services; +using Netch.Utils; using Serilog; namespace Netch.Forms @@ -243,13 +244,13 @@ namespace Netch.Forms private async void ControlButton_Click(object sender, EventArgs e) { - Utils.Utils.ComponentIterator(this, component => Utils.Utils.ChangeControlForeColor(component, Color.Black)); + Misc.ComponentIterator(this, component => Misc.ChangeControlForeColor(component, Color.Black)); #region Check var checkNotPassControl = _checkActions.Where(pair => !pair.Value.Invoke(pair.Key.Text)).Select(pair => pair.Key).ToList(); foreach (Control control in checkNotPassControl) - Utils.Utils.ChangeControlForeColor(control, Color.Red); + Misc.ChangeControlForeColor(control, Color.Red); if (checkNotPassControl.Any()) return; @@ -263,7 +264,7 @@ namespace Netch.Forms #endregion - Utils.Utils.RegisterNetchStartupItem(); + Misc.RegisterNetchStartupItem(); await Configuration.SaveAsync(); MessageBoxX.Show(i18N.Translate("Saved")); diff --git a/Netch/Forms/SubscribeForm.cs b/Netch/Forms/SubscribeForm.cs index 2109dedb..497bfad1 100644 --- a/Netch/Forms/SubscribeForm.cs +++ b/Netch/Forms/SubscribeForm.cs @@ -1,9 +1,10 @@ -using Netch.Models; -using Netch.Properties; -using Netch.Utils; -using System; +using System; using System.Linq; using System.Windows.Forms; +using Netch.Models; +using Netch.Properties; +using Netch.Services; +using Netch.Utils; namespace Netch.Forms { diff --git a/Netch/Models/Mode.cs b/Netch/Models/Mode.cs index d8979970..3f6f5421 100644 --- a/Netch/Models/Mode.cs +++ b/Netch/Models/Mode.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Text; using Netch.Enums; +using Netch.Services; using Netch.Utils; namespace Netch.Models diff --git a/Netch/Models/NetRoute.cs b/Netch/Models/NetRoute.cs index 01b5073d..838476a8 100644 --- a/Netch/Models/NetRoute.cs +++ b/Netch/Models/NetRoute.cs @@ -6,7 +6,7 @@ namespace Netch.Models { public struct NetRoute { - public static NetRoute TemplateBuilder(string gateway, int interfaceIndex, int metric = 0) + public static NetRoute TemplateBuilder(IPAddress gateway, int interfaceIndex, int metric = 0) { return new() { @@ -23,20 +23,25 @@ namespace Netch.Models address = new IPAddress(route.dwForwardNextHop.S_addr); var gateway = new IPAddress(route.dwForwardNextHop.S_un_b); - return TemplateBuilder(gateway.ToString(), (int)route.dwForwardIfIndex); + return TemplateBuilder(gateway, (int)route.dwForwardIfIndex); } public int InterfaceIndex; - public string Gateway; + public IPAddress Gateway; - public string Network; + public IPAddress Network; public byte Cidr; public int Metric; public NetRoute FillTemplate(string network, byte cidr, int? metric = null) + { + return FillTemplate(IPAddress.Parse(network), cidr, metric); + } + + public NetRoute FillTemplate(IPAddress network, byte cidr, int? metric = null) { var o = (NetRoute)MemberwiseClone(); o.Network = network; diff --git a/Netch/Models/Server.cs b/Netch/Models/Server.cs index b7043a27..397d7d14 100644 --- a/Netch/Models/Server.cs +++ b/Netch/Models/Server.cs @@ -1,8 +1,9 @@ -using Netch.Utils; -using System; +using System; using System.Collections.Generic; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Netch.Services; +using Netch.Utils; namespace Netch.Models { @@ -66,13 +67,9 @@ namespace Netch.Models string shortName; if (Type == string.Empty) - { shortName = "WTF"; - } else - { shortName = ServerHelper.GetUtilByTypeName(Type).ShortName; - } return $"[{shortName}][{Group}] {remark}"; } @@ -96,8 +93,8 @@ namespace Netch.Models try { return Global.Settings.ServerTCPing - ? await Utils.Utils.TCPingAsync(destination, Port) - : Utils.Utils.ICMPing(destination, Port); + ? await Misc.TCPingAsync(destination, Port) + : await Misc.ICMPingAsync(destination, Port); } catch (Exception) { diff --git a/Netch/Netch.cs b/Netch/Netch.cs index 0c0165db..e6ca70d6 100644 --- a/Netch/Netch.cs +++ b/Netch/Netch.cs @@ -1,14 +1,14 @@ -using Netch.Controllers; -using Netch.Forms; -using Netch.Utils; -using Netch.Services; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; +using Netch.Controllers; +using Netch.Forms; +using Netch.Services; +using Netch.Utils; using Serilog; using Vanara.PInvoke; @@ -80,7 +80,7 @@ namespace Netch } Log.Information("版本: {Version}", $"{UpdateChecker.Owner}/{UpdateChecker.Repo}@{UpdateChecker.Version}"); - Task.Run(() => { Log.Information("主程序 SHA256: {Hash}", $"{Utils.Utils.SHA256CheckSum(Global.NetchExecutable)}"); }); + Task.Run(() => { Log.Information("主程序 SHA256: {Hash}", $"{Misc.Sha256CheckSum(Global.NetchExecutable)}"); }); // 绑定错误捕获 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); @@ -116,9 +116,7 @@ namespace Netch private static void SingleInstance_ArgumentsReceived(IEnumerable args) { if (args.Contains(Constants.Parameter.Show)) - { Global.MainForm.ShowMainFormToolStripButton_Click(null!, null!); - } } } } \ No newline at end of file diff --git a/Netch/Utils/Configuration.cs b/Netch/Services/Configuration.cs similarity index 93% rename from Netch/Utils/Configuration.cs rename to Netch/Services/Configuration.cs index e3daaef5..b783c3f1 100644 --- a/Netch/Utils/Configuration.cs +++ b/Netch/Services/Configuration.cs @@ -1,25 +1,17 @@ -using Netch.Models; -using System; +using System; using System.IO; using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Netch.Models; +using Netch.Utils; using Serilog; -namespace Netch.Utils +namespace Netch.Services { public static class Configuration { - /// - /// 数据目录 - /// - public static string DataDirectoryFullName => Path.Combine(Global.NetchDir, "data"); - - public static string FileFullName => Path.Combine(DataDirectoryFullName, FileName); - - private static string BackupFileFullName => Path.Combine(DataDirectoryFullName, BackupFileName); - private const string FileName = "settings.json"; private const string BackupFileName = "settings.json.bak"; @@ -32,6 +24,15 @@ namespace Netch.Utils JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); } + /// + /// 数据目录 + /// + public static string DataDirectoryFullName => Path.Combine(Global.NetchDir, "data"); + + public static string FileFullName => Path.Combine(DataDirectoryFullName, FileName); + + private static string BackupFileFullName => Path.Combine(DataDirectoryFullName, BackupFileName); + public static async Task LoadAsync() { try @@ -81,8 +82,8 @@ namespace Netch.Utils for (var i = 0; i < settings.Profiles.Count; i++) settings.Profiles[i].Index = i; - settings.AioDNS.ChinaDNS = Utils.HostAppendPort(settings.AioDNS.ChinaDNS); - settings.AioDNS.OtherDNS = Utils.HostAppendPort(settings.AioDNS.OtherDNS); + settings.AioDNS.ChinaDNS = Misc.HostAppendPort(settings.AioDNS.ChinaDNS); + settings.AioDNS.OtherDNS = Misc.HostAppendPort(settings.AioDNS.OtherDNS); } /// diff --git a/Netch/Utils/ModeHelper.cs b/Netch/Services/ModeHelper.cs similarity index 99% rename from Netch/Utils/ModeHelper.cs rename to Netch/Services/ModeHelper.cs index 36b250f1..7608cd56 100644 --- a/Netch/Utils/ModeHelper.cs +++ b/Netch/Services/ModeHelper.cs @@ -4,14 +4,13 @@ using System.Linq; using System.Reactive.Linq; using Netch.Controllers; using Netch.Enums; -using Netch.Forms; using Netch.Interfaces; using Netch.Models; using Netch.Servers.Shadowsocks; using Netch.Servers.Socks5; using Serilog; -namespace Netch.Utils +namespace Netch.Services { public static class ModeHelper { diff --git a/Netch/Utils/ServerHelper.cs b/Netch/Services/ServerHelper.cs similarity index 99% rename from Netch/Utils/ServerHelper.cs rename to Netch/Services/ServerHelper.cs index afe23711..a3e48e30 100644 --- a/Netch/Utils/ServerHelper.cs +++ b/Netch/Services/ServerHelper.cs @@ -8,7 +8,7 @@ using Netch.Interfaces; using Netch.Models; using Timer = System.Timers.Timer; -namespace Netch.Utils +namespace Netch.Services { public static class ServerHelper { diff --git a/Netch/Services/Updater.cs b/Netch/Services/Updater.cs index 224a93b3..e4937895 100644 --- a/Netch/Services/Updater.cs +++ b/Netch/Services/Updater.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.IO; @@ -17,6 +16,37 @@ namespace Netch.Services { public class Updater { + private readonly string _installDirectory; + private readonly string _tempDirectory; + + private readonly string _updateFile; + + private Updater(string updateFile, string installDirectory) + { + _updateFile = updateFile; + _installDirectory = installDirectory; + _tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + + Directory.CreateDirectory(_tempDirectory); + } + + #region Clean files marked as old when start + + public static void CleanOld(string targetPath) + { + foreach (var f in Directory.GetFiles(targetPath, "*.old", SearchOption.AllDirectories)) + try + { + File.Delete(f); + } + catch (Exception) + { + // ignored + } + } + + #endregion + #region Download Update and apply update /// @@ -40,7 +70,7 @@ namespace Netch.Services if (File.Exists(updateFile)) { - if (Utils.Utils.SHA256CheckSum(updateFile) == sha256) + if (Misc.Sha256CheckSum(updateFile) == sha256) { await updater.ApplyUpdate(); return; @@ -73,25 +103,12 @@ namespace Netch.Services client.DownloadProgressChanged -= onDownloadProgressChanged; } - if (Utils.Utils.SHA256CheckSum(fileFullPath) != sha256) + if (Misc.Sha256CheckSum(fileFullPath) != sha256) throw new MessageException(i18N.Translate("The downloaded file has the wrong hash")); } #endregion - private readonly string _updateFile; - private readonly string _installDirectory; - private readonly string _tempDirectory; - - private Updater(string updateFile, string installDirectory) - { - _updateFile = updateFile; - _installDirectory = installDirectory; - _tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - - Directory.CreateDirectory(_tempDirectory); - } - #region Apply Update private async Task ApplyUpdate() @@ -119,7 +136,7 @@ namespace Netch.Services var updateMainProgramFilePath = Path.Combine(updateDirectory, "Netch.exe"); if (!File.Exists(updateMainProgramFilePath)) - throw new MessageException(i18N.Translate($"Update file main program not exist")); + throw new MessageException(i18N.Translate("Update file main program not exist")); // rename install directory files with .old suffix unless in keep folders @@ -206,22 +223,5 @@ namespace Netch.Services } #endregion - - #region Clean files marked as old when start - - public static void CleanOld(string targetPath) - { - foreach (var f in Directory.GetFiles(targetPath, "*.old", SearchOption.AllDirectories)) - try - { - File.Delete(f); - } - catch (Exception) - { - // ignored - } - } - - #endregion } } \ No newline at end of file diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Misc.cs similarity index 91% rename from Netch/Utils/Utils.cs rename to Netch/Utils/Misc.cs index 2f438cc7..37cdfdeb 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Misc.cs @@ -18,7 +18,7 @@ using Task = System.Threading.Tasks.Task; namespace Netch.Utils { - public static class Utils + public static class Misc { public static void Open(string path) { @@ -43,7 +43,7 @@ namespace Netch.Utils var stopwatch = Stopwatch.StartNew(); - var task = client.ConnectAsync(ip, port); + var task = client.ConnectAsync(ip, port, ct).AsTask(); var resTask = await Task.WhenAny(task, Task.Delay(timeout, ct)); @@ -57,33 +57,33 @@ namespace Netch.Utils return timeout; } - public static int ICMPing(IPAddress ip, int timeout = 1000) + public static async Task ICMPingAsync(IPAddress ip, int timeout = 1000) { - var reply = new Ping().Send(ip, timeout); + var reply = await new Ping().SendPingAsync(ip, timeout); - if (reply?.Status == IPStatus.Success) + if (reply.Status == IPStatus.Success) return Convert.ToInt32(reply.RoundtripTime); return timeout; } - public static string GetCityCode(string Hostname) + public static string GetCityCode(string hostname) { - if (Hostname.Contains(":")) - Hostname = Hostname.Split(':')[0]; + if (hostname.Contains(":")) + hostname = hostname.Split(':')[0]; string? country = null; try { var databaseReader = new DatabaseReader("bin\\GeoLite2-Country.mmdb"); - if (IPAddress.TryParse(Hostname, out _)) + if (IPAddress.TryParse(hostname, out _)) { - country = databaseReader.Country(Hostname).Country.IsoCode; + country = databaseReader.Country(hostname).Country.IsoCode; } else { - var dnsResult = DnsUtils.Lookup(Hostname); + var dnsResult = DnsUtils.Lookup(hostname); if (dnsResult != null) country = databaseReader.Country(dnsResult).Country.IsoCode; @@ -99,7 +99,7 @@ namespace Netch.Utils return country; } - public static string SHA256CheckSum(string filePath) + public static string Sha256CheckSum(string filePath) { try { diff --git a/Netch/Utils/RouteUtils.cs b/Netch/Utils/RouteUtils.cs index 8bfb9485..6b83a79b 100644 --- a/Netch/Utils/RouteUtils.cs +++ b/Netch/Utils/RouteUtils.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Net.Sockets; +using System.Net; using Netch.Interops; using Netch.Models; using Serilog; @@ -28,7 +28,18 @@ namespace Netch.Utils public static bool CreateRoute(NetRoute o) { - return RouteHelper.CreateRoute(AddressFamily.InterNetwork, o.Network, o.Cidr, o.Gateway, (ulong)o.InterfaceIndex, o.Metric); + if (o.Network.AddressFamily != o.Gateway.AddressFamily) + { + Log.Warning("Address({Address}) and Gateway({Gateway}) Address Family Different", o.Network, o.Gateway); + return false; + } + + return RouteHelper.CreateRoute(o.Network.AddressFamily, + o.Network.ToString(), + o.Cidr, + o.Gateway.ToString(), + (ulong)o.InterfaceIndex, + o.Metric); } public static void DeleteRouteFill(NetRoute template, IEnumerable rules, int? metric = null) @@ -41,7 +52,7 @@ namespace Netch.Utils { if (!TryParseIPNetwork(rule, out var network, out var cidr)) { - Log.Warning("invalid rule {Rule}",rule); + Log.Warning("invalid rule {Rule}", rule); return false; } @@ -50,10 +61,15 @@ namespace Netch.Utils public static bool DeleteRoute(NetRoute o) { - return RouteHelper.DeleteRoute(AddressFamily.InterNetwork, o.Network, o.Cidr, o.Gateway, (ulong)o.InterfaceIndex, o.Metric); + return RouteHelper.DeleteRoute(o.Network.AddressFamily, + o.Network.ToString(), + o.Cidr, + o.Gateway.ToString(), + (ulong)o.InterfaceIndex, + o.Metric); } - public static bool TryParseIPNetwork(string ipNetwork, [NotNullWhen(true)] out string? ip, out int cidr) + public static bool TryParseIPNetwork(string ipNetwork, [NotNullWhen(true)] out IPAddress? ip, out int cidr) { ip = null; cidr = 0; @@ -62,7 +78,7 @@ namespace Netch.Utils if (s.Length != 2) return false; - ip = s[0]; + ip = IPAddress.Parse(s[0]); cidr = int.Parse(s[1]); return true; } diff --git a/Netch/Utils/ServerConverterWithTypeDiscriminator.cs b/Netch/Utils/ServerConverterWithTypeDiscriminator.cs index ef48024a..3ba89528 100644 --- a/Netch/Utils/ServerConverterWithTypeDiscriminator.cs +++ b/Netch/Utils/ServerConverterWithTypeDiscriminator.cs @@ -1,13 +1,17 @@ -using Netch.Models; -using System; +using System; using System.Text.Json; using System.Text.Json.Serialization; +using Netch.Models; +using Netch.Services; namespace Netch.Utils { public class ServerConverterWithTypeDiscriminator : JsonConverter { - public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Server); + public override bool CanConvert(Type typeToConvert) + { + return typeToConvert == typeof(Server); + } public override Server Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/Netch/Utils/ShareLink.cs b/Netch/Utils/ShareLink.cs index 9ebac219..9a8c3c55 100644 --- a/Netch/Utils/ShareLink.cs +++ b/Netch/Utils/ShareLink.cs @@ -1,12 +1,13 @@ -using Netch.Models; -using Netch.Servers.Shadowsocks; -using Netch.Servers.Shadowsocks.Models; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.Json; +using Netch.Models; +using Netch.Servers.Shadowsocks; +using Netch.Servers.Shadowsocks.Models; +using Netch.Services; using Serilog; namespace Netch.Utils @@ -47,7 +48,6 @@ namespace Netch.Utils catch (JsonException) { foreach (var line in text.GetLines()) - { try { list.AddRange(ParseUri(line)); @@ -56,7 +56,6 @@ namespace Netch.Utils { Log.Error(e, "从分享链接导入服务器异常"); } - } } catch (Exception e) { diff --git a/Netch/Utils/i18N.cs b/Netch/Utils/i18N.cs index 6435f72f..c21f3f3d 100644 --- a/Netch/Utils/i18N.cs +++ b/Netch/Utils/i18N.cs @@ -1,5 +1,4 @@ -using Netch.Properties; -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -7,12 +6,17 @@ using System.Linq; using System.Text; using System.Text.Json; using System.Windows.Forms; +using Netch.Properties; using Serilog; namespace Netch.Utils { public static class i18N { + /// + /// 数据 + /// + public static Hashtable Data = new(); #if NET static i18N() { @@ -20,11 +24,6 @@ namespace Netch.Utils } #endif - /// - /// 数据 - /// - public static Hashtable Data = new(); - public static string LangCode { get; private set; } = "en-US"; /// @@ -42,7 +41,7 @@ namespace Netch.Utils { var oldLangCode = LangCode; LangCode = languages.FirstOrDefault(s => GetLanguage(s).Equals(GetLanguage(LangCode))) ?? "en-US"; - Log.Information("找不到语言 {OldLangCode}, 使用 {LangCode}",oldLangCode,LangCode); + Log.Information("找不到语言 {OldLangCode}, 使用 {LangCode}", oldLangCode, LangCode); } switch (LangCode) @@ -118,7 +117,7 @@ namespace Netch.Utils public static void TranslateForm(in Control c) { - Utils.ComponentIterator(c, + Misc.ComponentIterator(c, component => { switch (component)