mirror of
https://github.com/netchx/netch.git
synced 2026-03-14 17:43:18 +08:00
@@ -1,3 +1,5 @@
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -7,8 +9,6 @@ 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,6 +178,69 @@ 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;
|
||||
@@ -216,69 +279,5 @@ 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
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ using System.Threading.Tasks;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ namespace Netch.Controllers
|
||||
{
|
||||
public class NFController : IModeController
|
||||
{
|
||||
private const string BinDriver = "bin\\nfdriver.sys";
|
||||
private static readonly ServiceController NFService = new("netfilter2");
|
||||
|
||||
private const string BinDriver = "bin\\nfdriver.sys";
|
||||
private static readonly string SystemDriver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys";
|
||||
|
||||
public string Name { get; } = "Redirector";
|
||||
@@ -52,6 +53,48 @@ namespace Netch.Controllers
|
||||
Free();
|
||||
}
|
||||
|
||||
#region CheckRule
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="r"></param>
|
||||
/// <param name="clear"></param>
|
||||
/// <returns>No Problem true</returns>
|
||||
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, "");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="rules"></param>
|
||||
/// <param name="results"></param>
|
||||
/// <returns>No Problem true</returns>
|
||||
public static bool CheckRules(IEnumerable<string> rules, out IEnumerable<string> results)
|
||||
{
|
||||
results = rules.Where(r => !CheckCppRegex(r, false));
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
return !results.Any();
|
||||
}
|
||||
|
||||
public static string GenerateInvalidRulesMessage(IEnumerable<string> 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)
|
||||
@@ -128,54 +171,12 @@ namespace Netch.Controllers
|
||||
Dial(NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$");
|
||||
}
|
||||
|
||||
#region CheckRule
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="r"></param>
|
||||
/// <param name="clear"></param>
|
||||
/// <returns>No Problem true</returns>
|
||||
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, "");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="rules"></param>
|
||||
/// <param name="results"></param>
|
||||
/// <returns>No Problem true</returns>
|
||||
public static bool CheckRules(IEnumerable<string> rules, out IEnumerable<string> results)
|
||||
{
|
||||
results = rules.Where(r => !CheckCppRegex(r, false));
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
return !results.Any();
|
||||
}
|
||||
|
||||
public static string GenerateInvalidRulesMessage(IEnumerable<string> 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 = Misc.GetFileVersion(BinDriver);
|
||||
var systemFileVersion = Misc.GetFileVersion(SystemDriver);
|
||||
var binFileVersion = Utils.Utils.GetFileVersion(BinDriver);
|
||||
var systemFileVersion = Utils.Utils.GetFileVersion(SystemDriver);
|
||||
|
||||
Log.Information("内置驱动版本: " + binFileVersion);
|
||||
Log.Information("系统驱动版本: " + systemFileVersion);
|
||||
@@ -230,7 +231,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}");
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("注册驱动失败: {Result}", result);
|
||||
Log.Error("注册驱动失败: {Result}",result);
|
||||
throw new MessageException($"Register NF driver failed\n{result}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
public class PcapController : Guard, IModeController
|
||||
{
|
||||
private LogForm? _form;
|
||||
public override string Name { get; } = "pcap2socks";
|
||||
|
||||
public override string MainFile { get; protected set; } = "pcap2socks.exe";
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Netch.Controllers
|
||||
|
||||
protected override Encoding? InstanceOutputEncoding { get; } = Encoding.UTF8;
|
||||
|
||||
public override string Name { get; } = "pcap2socks";
|
||||
private LogForm? _form;
|
||||
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
@@ -44,12 +44,6 @@ namespace Netch.Controllers
|
||||
StartInstanceAuto(argument.ToString());
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
_form!.Close();
|
||||
StopInstance();
|
||||
}
|
||||
|
||||
protected override void OnReadNewLine(string line)
|
||||
{
|
||||
Global.MainForm.BeginInvoke(new Action(() =>
|
||||
@@ -71,13 +65,19 @@ namespace Netch.Controllers
|
||||
Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
Misc.Open("https://github.com/zhxie/pcap2socks#dependencies");
|
||||
Utils.Utils.Open("https://github.com/zhxie/pcap2socks#dependencies");
|
||||
});
|
||||
|
||||
throw new MessageException("Pleases install pcap2socks's dependency");
|
||||
}
|
||||
|
||||
Misc.Open(LogPath);
|
||||
Utils.Utils.Open(LogPath);
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
_form!.Close();
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 Mode _mode = null!;
|
||||
|
||||
private NetRoute _outbound;
|
||||
|
||||
private IPAddress? _serverRemoteAddress;
|
||||
|
||||
private NetRoute _tun;
|
||||
|
||||
public string Name => "tun2socks";
|
||||
private IPAddress? _serverRemoteAddress;
|
||||
|
||||
private Mode _mode = null!;
|
||||
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
@@ -97,52 +97,16 @@ namespace Netch.Controllers
|
||||
throw new MessageException("tun2socks start failed.");
|
||||
|
||||
var tunIndex = (int)RouteHelper.ConvertLuidToIndex(tun_luid());
|
||||
_tun = NetRoute.TemplateBuilder(IPAddress.Parse(Global.Settings.TUNTAP.Gateway), tunIndex);
|
||||
_tun = NetRoute.TemplateBuilder(Global.Settings.TUNTAP.Gateway, tunIndex);
|
||||
|
||||
RouteHelper.CreateUnicastIP(AddressFamily.InterNetwork,
|
||||
Global.Settings.TUNTAP.Address,
|
||||
(byte)Misc.SubnetToCidr(Global.Settings.TUNTAP.Netmask),
|
||||
(byte)Utils.Utils.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)
|
||||
@@ -172,7 +136,7 @@ namespace Netch.Controllers
|
||||
|
||||
if (!Global.Settings.TUNTAP.UseCustomDNS)
|
||||
// proxy AioDNS other dns
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate(Misc.GetHostFromUri(Global.Settings.AioDNS.OtherDNS), 32));
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.OtherDNS), 32));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -183,7 +147,7 @@ namespace Netch.Controllers
|
||||
|
||||
if (!Global.Settings.TUNTAP.UseCustomDNS)
|
||||
// bypass AioDNS other dns
|
||||
RouteUtils.CreateRoute(_outbound.FillTemplate(Misc.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32));
|
||||
RouteUtils.CreateRoute(_outbound.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32));
|
||||
|
||||
NetworkInterfaceUtils.SetInterfaceMetric(_tun.InterfaceIndex, 0);
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate("0.0.0.0", 0));
|
||||
@@ -208,5 +172,41 @@ 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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Properties;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
@@ -20,17 +21,17 @@ namespace Netch.Forms
|
||||
|
||||
private void NetchPictureBox_Click(object sender, EventArgs e)
|
||||
{
|
||||
Misc.Open("https://github.com/NetchX/Netch");
|
||||
Utils.Utils.Open("https://github.com/NetchX/Netch");
|
||||
}
|
||||
|
||||
private void ChannelLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
Misc.Open("https://t.me/Netch");
|
||||
Utils.Utils.Open("https://t.me/Netch");
|
||||
}
|
||||
|
||||
private void SponsorPictureBox_Click(object sender, EventArgs e)
|
||||
{
|
||||
Misc.Open("https://www.mansora.co");
|
||||
Utils.Utils.Open("https://www.mansora.co");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Properties;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
|
||||
@@ -151,8 +151,8 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
Misc.ComponentIterator(this, RecordText);
|
||||
Misc.ComponentIterator(NotifyMenu, RecordText);
|
||||
Utils.Utils.ComponentIterator(this, RecordText);
|
||||
Utils.Utils.ComponentIterator(NotifyMenu, RecordText);
|
||||
_textRecorded = true;
|
||||
}
|
||||
|
||||
@@ -192,8 +192,8 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
Misc.ComponentIterator(this, TranslateText);
|
||||
Misc.ComponentIterator(NotifyMenu, TranslateText);
|
||||
Utils.Utils.ComponentIterator(this, TranslateText);
|
||||
Utils.Utils.ComponentIterator(NotifyMenu, TranslateText);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -340,7 +340,7 @@ namespace Netch.Forms
|
||||
|
||||
private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Misc.Open(".\\");
|
||||
Utils.Utils.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)
|
||||
{
|
||||
Misc.Open($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases");
|
||||
Utils.Utils.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())
|
||||
{
|
||||
Misc.Open(UpdateChecker.LatestVersionUrl!);
|
||||
Utils.Utils.Open(UpdateChecker.LatestVersionUrl!);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ namespace Netch.Forms
|
||||
|
||||
private void fAQToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Misc.Open("https://netch.org/#/docs/zh-CN/faq");
|
||||
Utils.Utils.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)
|
||||
{
|
||||
Misc.Open(ModeHelper.GetFullPath(mode.RelativePath!));
|
||||
Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -744,7 +744,7 @@ namespace Netch.Forms
|
||||
Show();
|
||||
break;
|
||||
default:
|
||||
Misc.Open(ModeHelper.GetFullPath(mode.RelativePath!));
|
||||
Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1149,7 +1149,7 @@ namespace Netch.Forms
|
||||
|
||||
if (!string.IsNullOrEmpty(publicEnd))
|
||||
{
|
||||
var country = Misc.GetCityCode(publicEnd!);
|
||||
var country = Utils.Utils.GetCityCode(publicEnd!);
|
||||
NatTypeStatusText(result, country);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
using System;
|
||||
using Microsoft.WindowsAPICodePack.Dialogs;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
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
|
||||
{
|
||||
@@ -36,6 +35,25 @@ namespace Netch.Forms.Mode
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
#region Model
|
||||
|
||||
public IEnumerable<string> Rules => RuleRichTextBox.Lines;
|
||||
|
||||
private void RuleAdd(string value)
|
||||
{
|
||||
RuleRichTextBox.AppendText($"{value}\n");
|
||||
}
|
||||
|
||||
private void RuleAddRange(IEnumerable<string> value)
|
||||
{
|
||||
foreach (string s in value)
|
||||
{
|
||||
RuleAdd(s);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ModeForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (_mode != null)
|
||||
@@ -64,6 +82,7 @@ namespace Netch.Forms.Mode
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog(Handle) == CommonFileDialogResult.Ok)
|
||||
{
|
||||
foreach (string p in dialog.FileNames)
|
||||
{
|
||||
string path = p;
|
||||
@@ -72,6 +91,7 @@ namespace Netch.Forms.Mode
|
||||
|
||||
RuleAdd($"^{path.ToRegexString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ControlButton_Click(object sender, EventArgs e)
|
||||
@@ -188,22 +208,5 @@ namespace Netch.Forms.Mode
|
||||
else
|
||||
MessageBoxX.Show("Fine");
|
||||
}
|
||||
|
||||
#region Model
|
||||
|
||||
public IEnumerable<string> Rules => RuleRichTextBox.Lines;
|
||||
|
||||
private void RuleAdd(string value)
|
||||
{
|
||||
RuleRichTextBox.AppendText($"{value}\n");
|
||||
}
|
||||
|
||||
private void RuleAddRange(IEnumerable<string> value)
|
||||
{
|
||||
foreach (string s in value)
|
||||
RuleAdd(s);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
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
|
||||
{
|
||||
|
||||
@@ -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<Control, Action<object>> _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 += Misc.DrawCenterComboBox;
|
||||
comboBox.DrawItem += Utils.Utils.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)
|
||||
{
|
||||
Misc.ComponentIterator(this, component => Misc.ChangeControlForeColor(component, Color.Black));
|
||||
Utils.Utils.ComponentIterator(this, component => Utils.Utils.ChangeControlForeColor(component, Color.Black));
|
||||
|
||||
var flag = true;
|
||||
foreach (var pair in _checkActions.Where(pair => !pair.Value.Invoke(pair.Key.Text)))
|
||||
{
|
||||
Misc.ChangeControlForeColor(pair.Key, Color.Red);
|
||||
Utils.Utils.ChangeControlForeColor(pair.Key, Color.Red);
|
||||
flag = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
@@ -5,10 +8,6 @@ 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
|
||||
@@ -244,13 +243,13 @@ namespace Netch.Forms
|
||||
|
||||
private async void ControlButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Misc.ComponentIterator(this, component => Misc.ChangeControlForeColor(component, Color.Black));
|
||||
Utils.Utils.ComponentIterator(this, component => Utils.Utils.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)
|
||||
Misc.ChangeControlForeColor(control, Color.Red);
|
||||
Utils.Utils.ChangeControlForeColor(control, Color.Red);
|
||||
|
||||
if (checkNotPassControl.Any())
|
||||
return;
|
||||
@@ -264,7 +263,7 @@ namespace Netch.Forms
|
||||
|
||||
#endregion
|
||||
|
||||
Misc.RegisterNetchStartupItem();
|
||||
Utils.Utils.RegisterNetchStartupItem();
|
||||
|
||||
await Configuration.SaveAsync();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Netch.Enums;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Netch.Models
|
||||
{
|
||||
public struct NetRoute
|
||||
{
|
||||
public static NetRoute TemplateBuilder(IPAddress gateway, int interfaceIndex, int metric = 0)
|
||||
public static NetRoute TemplateBuilder(string gateway, int interfaceIndex, int metric = 0)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
@@ -23,25 +23,20 @@ namespace Netch.Models
|
||||
|
||||
address = new IPAddress(route.dwForwardNextHop.S_addr);
|
||||
var gateway = new IPAddress(route.dwForwardNextHop.S_un_b);
|
||||
return TemplateBuilder(gateway, (int)route.dwForwardIfIndex);
|
||||
return TemplateBuilder(gateway.ToString(), (int)route.dwForwardIfIndex);
|
||||
}
|
||||
|
||||
public int InterfaceIndex;
|
||||
|
||||
public IPAddress Gateway;
|
||||
public string Gateway;
|
||||
|
||||
public IPAddress Network;
|
||||
public string 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;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
@@ -67,9 +66,13 @@ namespace Netch.Models
|
||||
|
||||
string shortName;
|
||||
if (Type == string.Empty)
|
||||
{
|
||||
shortName = "WTF";
|
||||
}
|
||||
else
|
||||
{
|
||||
shortName = ServerHelper.GetUtilByTypeName(Type).ShortName;
|
||||
}
|
||||
|
||||
return $"[{shortName}][{Group}] {remark}";
|
||||
}
|
||||
@@ -93,8 +96,8 @@ namespace Netch.Models
|
||||
try
|
||||
{
|
||||
return Global.Settings.ServerTCPing
|
||||
? await Misc.TCPingAsync(destination, Port)
|
||||
: await Misc.ICMPingAsync(destination, Port);
|
||||
? await Utils.Utils.TCPingAsync(destination, Port)
|
||||
: Utils.Utils.ICMPing(destination, Port);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
using System;
|
||||
using Netch.Controllers;
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
using Netch.Services;
|
||||
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}", $"{Misc.Sha256CheckSum(Global.NetchExecutable)}"); });
|
||||
Task.Run(() => { Log.Information("主程序 SHA256: {Hash}", $"{Utils.Utils.SHA256CheckSum(Global.NetchExecutable)}"); });
|
||||
|
||||
// 绑定错误捕获
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||
@@ -116,7 +116,9 @@ namespace Netch
|
||||
private static void SingleInstance_ArgumentsReceived(IEnumerable<string> args)
|
||||
{
|
||||
if (args.Contains(Constants.Parameter.Show))
|
||||
{
|
||||
Global.MainForm.ShowMainFormToolStripButton_Click(null!, null!);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
@@ -16,37 +17,6 @@ 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
|
||||
|
||||
/// <summary>
|
||||
@@ -70,7 +40,7 @@ namespace Netch.Services
|
||||
|
||||
if (File.Exists(updateFile))
|
||||
{
|
||||
if (Misc.Sha256CheckSum(updateFile) == sha256)
|
||||
if (Utils.Utils.SHA256CheckSum(updateFile) == sha256)
|
||||
{
|
||||
await updater.ApplyUpdate();
|
||||
return;
|
||||
@@ -103,12 +73,25 @@ namespace Netch.Services
|
||||
client.DownloadProgressChanged -= onDownloadProgressChanged;
|
||||
}
|
||||
|
||||
if (Misc.Sha256CheckSum(fileFullPath) != sha256)
|
||||
if (Utils.Utils.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()
|
||||
@@ -136,7 +119,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
|
||||
@@ -223,5 +206,22 @@ 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
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,25 @@
|
||||
using System;
|
||||
using Netch.Models;
|
||||
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.Services
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据目录
|
||||
/// </summary>
|
||||
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";
|
||||
@@ -24,15 +32,6 @@ namespace Netch.Services
|
||||
JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据目录
|
||||
/// </summary>
|
||||
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
|
||||
@@ -82,8 +81,8 @@ namespace Netch.Services
|
||||
for (var i = 0; i < settings.Profiles.Count; i++)
|
||||
settings.Profiles[i].Index = i;
|
||||
|
||||
settings.AioDNS.ChinaDNS = Misc.HostAppendPort(settings.AioDNS.ChinaDNS);
|
||||
settings.AioDNS.OtherDNS = Misc.HostAppendPort(settings.AioDNS.OtherDNS);
|
||||
settings.AioDNS.ChinaDNS = Utils.HostAppendPort(settings.AioDNS.ChinaDNS);
|
||||
settings.AioDNS.OtherDNS = Utils.HostAppendPort(settings.AioDNS.OtherDNS);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -4,13 +4,14 @@ 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.Services
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class ModeHelper
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Netch.Interops;
|
||||
using Netch.Models;
|
||||
using Serilog;
|
||||
@@ -28,18 +28,7 @@ namespace Netch.Utils
|
||||
|
||||
public static bool CreateRoute(NetRoute o)
|
||||
{
|
||||
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);
|
||||
return RouteHelper.CreateRoute(AddressFamily.InterNetwork, o.Network, o.Cidr, o.Gateway, (ulong)o.InterfaceIndex, o.Metric);
|
||||
}
|
||||
|
||||
public static void DeleteRouteFill(NetRoute template, IEnumerable<string> rules, int? metric = null)
|
||||
@@ -52,7 +41,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;
|
||||
}
|
||||
|
||||
@@ -61,15 +50,10 @@ namespace Netch.Utils
|
||||
|
||||
public static bool DeleteRoute(NetRoute o)
|
||||
{
|
||||
return RouteHelper.DeleteRoute(o.Network.AddressFamily,
|
||||
o.Network.ToString(),
|
||||
o.Cidr,
|
||||
o.Gateway.ToString(),
|
||||
(ulong)o.InterfaceIndex,
|
||||
o.Metric);
|
||||
return RouteHelper.DeleteRoute(AddressFamily.InterNetwork, o.Network, o.Cidr, o.Gateway, (ulong)o.InterfaceIndex, o.Metric);
|
||||
}
|
||||
|
||||
public static bool TryParseIPNetwork(string ipNetwork, [NotNullWhen(true)] out IPAddress? ip, out int cidr)
|
||||
public static bool TryParseIPNetwork(string ipNetwork, [NotNullWhen(true)] out string? ip, out int cidr)
|
||||
{
|
||||
ip = null;
|
||||
cidr = 0;
|
||||
@@ -78,7 +62,7 @@ namespace Netch.Utils
|
||||
if (s.Length != 2)
|
||||
return false;
|
||||
|
||||
ip = IPAddress.Parse(s[0]);
|
||||
ip = s[0];
|
||||
cidr = int.Parse(s[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
using System;
|
||||
using Netch.Models;
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Netch.Models;
|
||||
using Netch.Services;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public class ServerConverterWithTypeDiscriminator : JsonConverter<Server>
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert)
|
||||
{
|
||||
return typeToConvert == typeof(Server);
|
||||
}
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Server);
|
||||
|
||||
public override Server Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace Netch.Services
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class ServerHelper
|
||||
{
|
||||
@@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Shadowsocks;
|
||||
using Netch.Servers.Shadowsocks.Models;
|
||||
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
|
||||
@@ -48,6 +47,7 @@ namespace Netch.Utils
|
||||
catch (JsonException)
|
||||
{
|
||||
foreach (var line in text.GetLines())
|
||||
{
|
||||
try
|
||||
{
|
||||
list.AddRange(ParseUri(line));
|
||||
@@ -56,6 +56,7 @@ namespace Netch.Utils
|
||||
{
|
||||
Log.Error(e, "从分享链接导入服务器异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class Misc
|
||||
public static class Utils
|
||||
{
|
||||
public static void Open(string path)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ namespace Netch.Utils
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
var task = client.ConnectAsync(ip, port, ct).AsTask();
|
||||
var task = client.ConnectAsync(ip, port);
|
||||
|
||||
var resTask = await Task.WhenAny(task, Task.Delay(timeout, ct));
|
||||
|
||||
@@ -57,33 +57,33 @@ namespace Netch.Utils
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public static async Task<int> ICMPingAsync(IPAddress ip, int timeout = 1000)
|
||||
public static int ICMPing(IPAddress ip, int timeout = 1000)
|
||||
{
|
||||
var reply = await new Ping().SendPingAsync(ip, timeout);
|
||||
var reply = new Ping().Send(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
|
||||
{
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using Netch.Properties;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
@@ -6,17 +7,12 @@ 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
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public static Hashtable Data = new();
|
||||
#if NET
|
||||
static i18N()
|
||||
{
|
||||
@@ -24,6 +20,11 @@ namespace Netch.Utils
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public static Hashtable Data = new();
|
||||
|
||||
public static string LangCode { get; private set; } = "en-US";
|
||||
|
||||
/// <summary>
|
||||
@@ -41,7 +42,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)
|
||||
@@ -117,7 +118,7 @@ namespace Netch.Utils
|
||||
|
||||
public static void TranslateForm(in Control c)
|
||||
{
|
||||
Misc.ComponentIterator(c,
|
||||
Utils.ComponentIterator(c,
|
||||
component =>
|
||||
{
|
||||
switch (component)
|
||||
|
||||
Reference in New Issue
Block a user