Compare commits

...

67 Commits

Author SHA1 Message Date
AmazingDM
268bdb7730 Update UpdateChecker.cs 2021-03-30 14:14:19 +08:00
Connection Refused
ed459ec8d6 Update submodules 2021-03-29 23:39:23 +08:00
Connection Refused
ddd1ca5fac Update NFController 2021-03-29 23:34:20 +08:00
Connection Refused
7c54c1f570 Update Redirector 2021-03-29 23:32:12 +08:00
AmazingDM
ed56d51c4d Update binaries(ICMP hijack) 2021-03-28 22:11:54 +08:00
ChsBuffer
c669097aa5 Update csproj 2021-03-28 16:26:11 +08:00
ChsBuffer
5d74321771 Update MarkFilesOld 2021-03-28 03:52:25 +08:00
ChsBuffer
093fe6404b Updater Skip mark logging directory 2021-03-28 03:49:51 +08:00
ChsBuffer
2760b3c7bd Update TUNController 2021-03-28 03:40:24 +08:00
ChsBuffer
ba17366094 trim 2021-03-28 03:32:21 +08:00
ChsBuffer
6c668684e9 Remove AdapterUtil 2021-03-28 03:29:24 +08:00
ChsBuffer
8d6e4bdd96 Fix Publish Build Missing NTT.exe 2021-03-28 03:15:31 +08:00
ChsBuffer
5522245ce0 bump version to 1.8.3-Beta5 2021-03-28 02:47:19 +08:00
ChsBuffer
f518fd6867 Update binaries(Fix DNS) 2021-03-28 02:23:01 +08:00
ChsBuffer
e0120e7de0 Update SettingForm 2021-03-28 02:21:44 +08:00
ChsBuffer
3565251b4d Update Redirector
extract RedirectorConfig
move BypassIPs to Setting.TUNTAP
2021-03-28 02:13:03 +08:00
ChsBuffer
4a50ebd421 Update zh-cn 2021-03-28 02:13:03 +08:00
Connection Refused
4e03793ceb Update submodules 2021-03-28 02:05:24 +08:00
ChsBuffer
23399b872d Remove TUN HijackDNS value check 2021-03-28 00:56:59 +08:00
ChsBuffer
b553ddbb71 Refactor: Create Netch.Interops namespace 2021-03-28 00:54:04 +08:00
ChsBuffer
090e487733 Move MessageException Namespace and Optimize import 2021-03-28 00:51:42 +08:00
ChsBuffer
cada4c997e Update Release workflow 2021-03-28 00:13:49 +08:00
ChsBuffer
8746125dda Create Publish.ps1 2021-03-28 00:01:59 +08:00
ChsBuffer
d09b5adc33 Drop proxy client routing 2021-03-27 23:44:25 +08:00
ChsBuffer
54c1fb5578 remove unused aiodns protocol setting 2021-03-27 23:20:56 +08:00
ChsBuffer
f07413c882 Fix LogForm RouteForm Scale 2021-03-27 23:15:25 +08:00
ChsBuffer
5b2b6c9f96 Update DNSController and TUNController 2021-03-27 23:09:33 +08:00
ChsBuffer
4c4ad72d1d Update Setting 2021-03-27 22:55:18 +08:00
Connection Refused
830f3b3b60 Update modes 2021-03-27 22:33:20 +08:00
Connection Refused
777657e810 Update modes 2021-03-27 22:27:58 +08:00
Connection Refused
2413aabb15 Update aiodns to v1.0.3 2021-03-27 22:16:26 +08:00
Connection Refused
6ccb99d1d8 Update tun2socks 2021-03-27 22:10:23 +08:00
Connection Refused
ac0266a478 Update tun2socks 2021-03-27 21:51:30 +08:00
ChsBuffer
d701a8c950 Fix Create Process Mode validation typo
Update NFController
2021-03-27 19:41:16 +08:00
ChsBuffer
934443556c extract RedirectorInterop
Update TUNController
2021-03-27 19:29:42 +08:00
ChsBuffer
a69252819c Update Readme 2021-03-27 18:36:40 +08:00
ChsBuffer
f90773aa84 Update StringExtension Split 2021-03-27 18:27:09 +08:00
ChsBuffer
246f52e54e cleanup Reference 2021-03-27 18:24:13 +08:00
ChsBuffer
a5f6b4a2c0 Fix BUILD.ps1 2021-03-27 18:09:00 +08:00
ChsBuffer
66d7cededd Fix LogForm RouteForm ScaleDimensions 2021-03-27 17:59:13 +08:00
ChsBuffer
8254482799 Remove SearchComboBox 2021-03-27 17:56:34 +08:00
ChsBuffer
b215b2caa8 Fix TUNNetmaskTextBox Visible 2021-03-27 17:45:50 +08:00
ChsBuffer
5f9dbb0994 Update BUILD.ps1, Remove CLEAN.ps1 2021-03-27 17:44:47 +08:00
ChsBuffer
3cbd5af9a3 Extract TagItem class, Update Nullable 2021-03-27 17:40:18 +08:00
ChsBuffer
2ab693facf Update TFM to net5.0-windows7 2021-03-27 16:26:18 +08:00
ChsBuffer
664b1a7e6c Update TUNController 2021-03-27 16:24:15 +08:00
Connection Refused
ad1575b3c7 Update modes 2021-03-27 16:00:35 +08:00
Connection Refused
62b78d1b1d Update submodules 2021-03-27 15:56:04 +08:00
ChsBuffer
dd3ce126e3 Update TUNController (tun2socks.bin) 2021-03-27 03:06:54 +08:00
ChsBuffer
a295cf6250 Update Append bin to PATH 2021-03-27 03:05:45 +08:00
ChsBuffer
a507df5f30 Debug Level Log 2021-03-27 03:05:32 +08:00
ChsBuffer
0a7b405f1b Revert "Update Netch.csproj"
This reverts commit 5fc7c460aa.
2021-03-26 23:40:33 +08:00
Connection Refused
c61da9b918 Update modes 2021-03-26 19:39:54 +08:00
Connection Refused
9bf3490cf9 Update TUNController 2021-03-26 19:32:57 +08:00
Connection Refused
c505e2abbb Update TUNController 2021-03-26 19:31:42 +08:00
Connection Refused
5fc7c460aa Update Netch.csproj 2021-03-26 19:31:28 +08:00
Connection Refused
c79f62334c Update aiodns.conf 2021-03-26 19:18:31 +08:00
Connection Refused
2dc4308427 Update aiodns.conf 2021-03-26 19:18:09 +08:00
Connection Refused
c3c534eb92 Update binaries 2021-03-26 19:14:14 +08:00
Connection Refused
dbef41d8a4 Update README.md 2021-03-26 18:40:32 +08:00
ChsBuffer
e3d6a62e81 Update RouteHelper usage 2021-03-26 18:35:46 +08:00
ChsBuffer
415c7705ac cleanup drop http support 2021-03-26 18:35:12 +08:00
Connection Refused
4ab844e31c Update NativeMethods 2021-03-26 18:25:08 +08:00
ChsBuffer
f4759d2f94 Drop HTTPController(Drop WebProxy, Update server with proxy etc.) 2021-03-26 18:17:58 +08:00
ChsBuffer
a080de6ca4 replace eycorsican/go-tun2socks with aiocloud/tun2socks(WinTUN) 2021-03-26 17:56:28 +08:00
Connection Refused
f8148cb730 Merge pull request #598 from NetchX/dependabot/submodules/modes-1471298
Bump modes from `72ad96d` to `1471298`
2021-03-26 17:04:27 +08:00
dependabot[bot]
b092b6a4d4 Bump modes from 72ad96d to 1471298
Bumps [modes](https://github.com/NetchX/NetchMode) from `72ad96d` to `1471298`.
- [Release notes](https://github.com/NetchX/NetchMode/releases)
- [Commits](72ad96d018...1471298210)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-26 09:04:07 +00:00
79 changed files with 1422 additions and 2231 deletions

View File

@@ -18,17 +18,17 @@ jobs:
- name: Build Solution
shell: pwsh
run: .\BUILD.ps1
run: .\PUBLISH.ps1
- name: Package
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
run: |
New-Item -ItemType Directory -Path C:\builtfiles -Force > $null
7z a -mx9 C:\builtfiles\Netch.7z .\Netch\bin\x64\Release\
7z rn C:\builtfiles\Netch.7z Release Netch
7z a -mx9 C:\builtfiles\Netch.7z .\Netch\bin\Publish\
7z rn C:\builtfiles\Netch.7z Publish Netch
echo "Netch_SHA256=$(.\GetSHA256.ps1 C:\builtfiles\Netch.7z)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "Netch_EXE_SHA256=$(.\GetSHA256.ps1 Netch\bin\x64\Release\Netch.exe)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "Netch_EXE_SHA256=$(.\GetSHA256.ps1 Netch\bin\Publish\Netch.exe)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
- name: Release
uses: softprops/action-gh-release@v1

View File

@@ -1,10 +1,8 @@
Write-Host 'Building'
msbuild -v:n /p:Configuration="Release" `
/p:Platform="x64" `
/p:TargetFramework=net48 `
/p:SolutionDir="$pwd\" `
/restore `
dotnet build `
-c "Release" `
-p:Platform="x64" `
Netch\Netch.csproj
if ($LASTEXITCODE) { exit $LASTEXITCODE }

View File

@@ -1,21 +0,0 @@
if (Test-Path Netch\bin)
{
Remove-Item -Recurse -Force Netch\bin
}
if (Test-Path Netch\obj)
{
Remove-Item -Recurse -Force Netch\obj
}
if (Test-Path NetchLib\bin)
{
Remove-Item -Recurse -Force NetchLib\bin
}
if (Test-Path NetchLib\obj)
{
Remove-Item -Recurse -Force NetchLib\obj
}
exit 0

View File

@@ -1,9 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<TargetFramework>net5.0-windows7.0</TargetFramework>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release</Configurations>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
</Project>

View File

@@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.29009.5
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Netch", "Netch\Netch.csproj", "{4B041B91-5790-4571-8C58-C63FFE4BC9F8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SearchComboBox", "SearchComboBox\SearchComboBox.csproj", "{A8715AF4-ACC6-43F9-9381-4294C5360623}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{53397641-35CA-4336-8E22-2CE12EF476AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.nfapinet", "Interop.nfapinet\Interop.nfapinet.csproj", "{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}"
@@ -21,17 +19,13 @@ Global
{4B041B91-5790-4571-8C58-C63FFE4BC9F8}.Debug|x64.Build.0 = Debug|x64
{4B041B91-5790-4571-8C58-C63FFE4BC9F8}.Release|x64.ActiveCfg = Release|x64
{4B041B91-5790-4571-8C58-C63FFE4BC9F8}.Release|x64.Build.0 = Release|x64
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Debug|x64.ActiveCfg = Debug|Any CPU
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Debug|x64.Build.0 = Debug|Any CPU
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Release|x64.ActiveCfg = Release|Any CPU
{A8715AF4-ACC6-43F9-9381-4294C5360623}.Release|x64.Build.0 = Release|Any CPU
{53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.ActiveCfg = Debug|x64
{53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.Build.0 = Debug|x64
{53397641-35CA-4336-8E22-2CE12EF476AC}.Release|x64.ActiveCfg = Release|x64
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.ActiveCfg = Debug|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.Build.0 = Debug|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.ActiveCfg = Release|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.Build.0 = Release|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.ActiveCfg = Debug|x64
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.Build.0 = Debug|x64
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.ActiveCfg = Release|x64
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
</configuration>

View File

@@ -3,8 +3,6 @@
public static class Constants
{
public const string EOF = "\r\n";
public const string UserACL = "data\\user.acl";
public const string BuiltinACL = "bin\\default.acl";
public static class Parameter
{

View File

@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using static Netch.Interops.AioDNSInterops;
namespace Netch.Controllers
{
@@ -11,7 +10,7 @@ namespace Netch.Controllers
public void Stop()
{
aiodns_free();
Free();
}
/// <summary>
@@ -20,38 +19,14 @@ namespace Netch.Controllers
/// <returns></returns>
public void Start()
{
aiodns_dial((int) NameList.TYPE_REST, null);
aiodns_dial((int) NameList.TYPE_ADDR, Encoding.UTF8.GetBytes($"{Global.Settings.LocalAddress}:53"));
aiodns_dial((int) NameList.TYPE_LIST, Encoding.UTF8.GetBytes(Path.GetFullPath(Global.Settings.AioDNS.RulePath)));
aiodns_dial((int) NameList.TYPE_CDNS, Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.ChinaDNS}:53"));
aiodns_dial((int) NameList.TYPE_ODNS, Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.OtherDNS}:53"));
aiodns_dial((int) NameList.TYPE_METH, Encoding.UTF8.GetBytes(Global.Settings.AioDNS.Protocol));
Dial(NameList.TYPE_REST, "");
Dial(NameList.TYPE_ADDR, $"{Global.Settings.LocalAddress}:{Global.Settings.AioDNS.ListenPort}");
Dial(NameList.TYPE_LIST, Path.GetFullPath(Global.Settings.AioDNS.RulePath));
Dial(NameList.TYPE_CDNS, $"{Global.Settings.AioDNS.ChinaDNS}");
Dial(NameList.TYPE_ODNS, $"{Global.Settings.AioDNS.OtherDNS}");
if (!aiodns_init())
if (!Init())
throw new Exception("AioDNS start failed");
}
#region NativeMethods
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
public static extern bool aiodns_dial(int name, byte[]? value);
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
public static extern bool aiodns_init();
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
public static extern void aiodns_free();
private enum NameList
{
TYPE_REST,
TYPE_ADDR,
TYPE_LIST,
TYPE_CDNS,
TYPE_ODNS,
TYPE_METH
}
#endregion
}
}

View File

@@ -1,93 +0,0 @@
using System.Threading.Tasks;
using WindowsProxy;
using Netch.Models;
using Netch.Servers.Socks5;
using Netch.Servers.Trojan;
using Netch.Utils;
using Netch.Utils.HttpProxyHandler;
namespace Netch.Controllers
{
public class HTTPController : IModeController
{
public readonly PrivoxyController PrivoxyController = new();
private ProxyStatus? _oldState;
public string Name { get; } = "HTTP";
/// <summary>
/// 启动
/// </summary>
/// <param name="mode">模式</param>
/// <returns>是否启动成功</returns>
public void Start(in Mode mode)
{
PrivoxyController.Start(MainController.Server!);
string? pacUrl = null;
if (MainController.Server is Socks5 or Trojan && mode.BypassChina || (Global.Settings.AlwaysStartPACServer ?? false))
{
try
{
PortHelper.CheckPort(Global.Settings.Pac_Port);
}
catch
{
Global.Settings.Pac_Port = PortHelper.GetAvailablePort();
}
pacUrl = PACServerHandle.InitPACServer();
}
if (mode.Type is 3)
{
using var service = new ProxyService();
_oldState = service.Query();
if (pacUrl != null)
{
service.AutoConfigUrl = pacUrl;
service.Pac();
}
else
{
service.Server = $"127.0.0.1:{Global.Settings.HTTPLocalPort}";
service.Bypass = string.Join(";", ProxyService.LanIp);
service.Global();
}
}
}
/// <summary>
/// 停止
/// </summary>
public void Stop()
{
var tasks = new[]
{
Task.Run(PrivoxyController.Stop),
Task.Run(() =>
{
PACServerHandle.Stop();
if (_oldState != null)
{
using var service = new ProxyService();
if (_oldState.IsProxy && _oldState.ProxyServer == service.Query().ProxyServer ||
_oldState.IsAutoProxyUrl && _oldState.AutoConfigUrl!.StartsWith(PACServerHandle.PacPrefix))
{
service.Direct();
return;
}
service.Set(_oldState);
}
})
};
Task.WaitAll(tasks);
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using Netch.Models;
@@ -59,9 +58,6 @@ namespace Netch.Controllers
Server = server;
Mode = mode;
if (server is Socks5 && mode.Type == 4)
throw new MessageException("Already Socks5 Server");
// 刷新DNS缓存
NativeMethods.FlushDNSResolverCache();
@@ -125,9 +121,6 @@ namespace Netch.Controllers
{
ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName);
if (ModeController == null)
return;
if (port != null)
TryReleaseTcpPort((ushort) port, portName);
@@ -196,7 +189,7 @@ namespace Netch.Controllers
string fileName;
try
{
fileName = p.MainModule!.FileName;
fileName = p.MainModule?.FileName ?? throw new Exception(); // TODO what's this exception?
}
catch (Exception e)
{
@@ -218,15 +211,4 @@ namespace Netch.Controllers
PortCheck(port, portName, PortType.TCP);
}
}
public class MessageException : Exception
{
public MessageException()
{
}
public MessageException(string message) : base(message)
{
}
}
}

View File

@@ -2,14 +2,13 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Threading.Tasks;
using Netch.Models;
using Netch.Servers.Shadowsocks;
using Netch.Servers.Socks5;
using Netch.Utils;
using nfapinet;
using static Netch.Interops.RedirectorInterop;
namespace Netch.Controllers
{
@@ -26,29 +25,30 @@ namespace Netch.Controllers
{
CheckDriver();
aio_dial((int) NameList.TYPE_FILTERLOOPBACK, "false");
aio_dial((int) NameList.TYPE_TCPLISN, Global.Settings.RedirectorTCPPort.ToString());
Dial(NameList.TYPE_FILTERLOOPBACK, "false");
Dial(NameList.TYPE_FILTERICMP, "true");
var p = PortHelper.GetAvailablePort();
Dial(NameList.TYPE_TCPLISN, p.ToString());
Dial(NameList.TYPE_UDPLISN, p.ToString());
// Server
aio_dial((int) NameList.TYPE_FILTERUDP, (Global.Settings.ProcessProxyProtocol != PortType.TCP).ToString().ToLower());
aio_dial((int) NameList.TYPE_FILTERTCP, (Global.Settings.ProcessProxyProtocol != PortType.UDP).ToString().ToLower());
dial_Server(Global.Settings.ProcessProxyProtocol);
Dial(NameList.TYPE_FILTERUDP, (Global.Settings.Redirector.ProxyProtocol != PortType.TCP).ToString().ToLower());
Dial(NameList.TYPE_FILTERTCP, (Global.Settings.Redirector.ProxyProtocol != PortType.UDP).ToString().ToLower());
dial_Server(Global.Settings.Redirector.ProxyProtocol);
// Mode Rule
dial_Name(mode);
// Features
aio_dial((int) NameList.TYPE_REDIRCTOR_DNS, Global.Settings.RedirectDNS ? Global.Settings.RedirectDNSAddr : "");
aio_dial((int) NameList.TYPE_REDIRCTOR_ICMP, Global.Settings.RedirectICMP ? Global.Settings.RedirectICMPAddr : "");
aio_dial((int) NameList.TYPE_FILTERCHILDPROC, Global.Settings.ChildProcessHandle.ToString().ToLower());
Dial(NameList.TYPE_DNSHOST, Global.Settings.Redirector.DNSHijack ? Global.Settings.Redirector.DNSHijackHost : "");
if (!aio_init())
if (!Init())
throw new MessageException("Redirector Start failed, run Netch with \"-console\" argument");
}
public void Stop()
{
aio_free();
Free();
}
#region CheckRule
@@ -63,14 +63,14 @@ namespace Netch.Controllers
try
{
if (r.StartsWith("!"))
return aio_dial((int) NameList.TYPE_ADDNAME, r.Substring(1));
return Dial(NameList.TYPE_ADDNAME, r.Substring(1));
return aio_dial((int) NameList.TYPE_ADDNAME, r);
return Dial(NameList.TYPE_ADDNAME, r);
}
finally
{
if (clear)
aio_dial((int) NameList.TYPE_CLRNAME, "");
Dial(NameList.TYPE_CLRNAME, "");
}
}
@@ -82,7 +82,7 @@ namespace Netch.Controllers
public static bool CheckRules(IEnumerable<string> rules, out IEnumerable<string> results)
{
results = rules.Where(r => !CheckCppRegex(r, false));
aio_dial((int) NameList.TYPE_CLRNAME, "");
Dial(NameList.TYPE_CLRNAME, "");
return !results.Any();
}
@@ -121,52 +121,52 @@ namespace Netch.Controllers
if (server is Socks5 socks5)
{
aio_dial((int) NameList.TYPE_TCPTYPE + offset, "Socks5");
aio_dial((int) NameList.TYPE_TCPHOST + offset, $"{socks5.AutoResolveHostname()}:{socks5.Port}");
aio_dial((int) NameList.TYPE_TCPUSER + offset, socks5.Username ?? string.Empty);
aio_dial((int) NameList.TYPE_TCPPASS + offset, socks5.Password ?? string.Empty);
aio_dial((int) NameList.TYPE_TCPMETH + offset, string.Empty);
Dial(NameList.TYPE_TCPTYPE + offset, "Socks5");
Dial(NameList.TYPE_TCPHOST + offset, $"{socks5.AutoResolveHostname()}:{socks5.Port}");
Dial(NameList.TYPE_TCPUSER + offset, socks5.Username ?? string.Empty);
Dial(NameList.TYPE_TCPPASS + offset, socks5.Password ?? string.Empty);
Dial(NameList.TYPE_TCPMETH + offset, string.Empty);
}
else if (server is Shadowsocks shadowsocks && !shadowsocks.HasPlugin() && Global.Settings.RedirectorSS)
else if (server is Shadowsocks shadowsocks && !shadowsocks.HasPlugin() && Global.Settings.Redirector.RedirectorSS)
{
aio_dial((int) NameList.TYPE_TCPTYPE + offset, "Shadowsocks");
aio_dial((int) NameList.TYPE_TCPHOST + offset, $"{shadowsocks.AutoResolveHostname()}:{shadowsocks.Port}");
aio_dial((int) NameList.TYPE_TCPMETH + offset, shadowsocks.EncryptMethod);
aio_dial((int) NameList.TYPE_TCPPASS + offset, shadowsocks.Password);
Dial(NameList.TYPE_TCPTYPE + offset, "Shadowsocks");
Dial(NameList.TYPE_TCPHOST + offset, $"{shadowsocks.AutoResolveHostname()}:{shadowsocks.Port}");
Dial(NameList.TYPE_TCPMETH + offset, shadowsocks.EncryptMethod);
Dial(NameList.TYPE_TCPPASS + offset, shadowsocks.Password);
}
else
{
aio_dial((int) NameList.TYPE_TCPTYPE + offset, "Socks5");
aio_dial((int) NameList.TYPE_TCPHOST + offset, $"127.0.0.1:{controller.Socks5LocalPort()}");
aio_dial((int) NameList.TYPE_TCPUSER + offset, string.Empty);
aio_dial((int) NameList.TYPE_TCPPASS + offset, string.Empty);
aio_dial((int) NameList.TYPE_TCPMETH + offset, string.Empty);
Dial(NameList.TYPE_TCPTYPE + offset, "Socks5");
Dial(NameList.TYPE_TCPHOST + offset, $"127.0.0.1:{controller.Socks5LocalPort()}");
Dial(NameList.TYPE_TCPUSER + offset, string.Empty);
Dial(NameList.TYPE_TCPPASS + offset, string.Empty);
Dial(NameList.TYPE_TCPMETH + offset, string.Empty);
}
}
private void dial_Name(Mode mode)
{
aio_dial((int) NameList.TYPE_CLRNAME, "");
var list = new List<string>();
Dial(NameList.TYPE_CLRNAME, "");
var invalidList = new List<string>();
foreach (var s in mode.FullRule)
{
if (s.StartsWith("!"))
{
if (!aio_dial((int) NameList.TYPE_BYPNAME, s.Substring(1)))
list.Add(s);
if (!Dial(NameList.TYPE_BYPNAME, s.Substring(1)))
invalidList.Add(s);
continue;
}
if (!aio_dial((int) NameList.TYPE_ADDNAME, s))
list.Add(s);
if (!Dial(NameList.TYPE_ADDNAME, s))
invalidList.Add(s);
}
if (list.Any())
throw new MessageException(GenerateInvalidRulesMessage(list));
if (invalidList.Any())
throw new MessageException(GenerateInvalidRulesMessage(invalidList));
aio_dial((int) NameList.TYPE_ADDNAME, @"NTT\.exe");
aio_dial((int) NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$");
Dial(NameList.TYPE_ADDNAME, @"NTT\.exe");
Dial(NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$");
}
#region DriverUtil
@@ -216,7 +216,7 @@ namespace Netch.Controllers
/// 安装 NF 驱动
/// </summary>
/// <returns>驱动是否安装成功</returns>
public static void InstallDriver()
private static void InstallDriver()
{
Logging.Info("安装 NF 驱动");
@@ -277,61 +277,5 @@ namespace Netch.Controllers
}
#endregion
#region NativeMethods
private const int UdpNameListOffset = (int) NameList.TYPE_UDPTYPE - (int) NameList.TYPE_TCPTYPE;
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
private static extern bool aio_dial(int name, [MarshalAs(UnmanagedType.LPWStr)] string value);
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
private static extern bool aio_init();
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
private static extern bool aio_free();
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
private static extern ulong aio_getUP();
[DllImport("Redirector.bin", CallingConvention = CallingConvention.Cdecl)]
private static extern ulong aio_getDL();
public enum NameList
{
//bool
TYPE_FILTERLOOPBACK,
TYPE_FILTERTCP,
TYPE_FILTERUDP,
TYPE_FILTERIP,
TYPE_FILTERCHILDPROC, //子进程捕获
TYPE_TCPLISN,
TYPE_TCPTYPE,
TYPE_TCPHOST,
TYPE_TCPUSER,
TYPE_TCPPASS,
TYPE_TCPMETH,
TYPE_UDPTYPE,
TYPE_UDPHOST,
TYPE_UDPUSER,
TYPE_UDPPASS,
TYPE_UDPMETH,
TYPE_ADDNAME,
TYPE_ADDFIP,
TYPE_BYPNAME,
TYPE_CLRNAME,
TYPE_CLRFIP,
//str addr x.x.x.x only ipv4
TYPE_REDIRCTOR_DNS,
TYPE_REDIRCTOR_ICMP
}
#endregion
}
}

View File

@@ -1,45 +0,0 @@
using System.IO;
using System.Text;
using Netch.Models;
using Netch.Servers.Socks5;
namespace Netch.Controllers
{
public class PrivoxyController : Guard, IController
{
public PrivoxyController()
{
RedirectStd = false;
}
public override string MainFile { get; protected set; } = "Privoxy.exe";
public override string Name { get; } = "Privoxy";
public override void Stop()
{
StopInstance();
}
public void Start(Server server)
{
var text = new StringBuilder(File.ReadAllText("bin\\default.conf"));
text.Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString());
text.Replace("0.0.0.0", Global.Settings.LocalAddress); /* BIND_HOST */
if (server is Socks5 socks5 && !socks5.Auth())
{
text.Replace("/ 127.0.0.1", $"/ {server.AutoResolveHostname()}"); /* DEST_HOST */
text.Replace("_DEST_PORT_", socks5.Port.ToString());
}
text.Replace("_DEST_PORT_", Global.Settings.Socks5LocalPort.ToString());
File.WriteAllText("data\\privoxy.conf", text.ToString());
StartInstanceAuto("..\\data\\privoxy.conf");
}
}
}

View File

@@ -0,0 +1,310 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Netch.Models;
using Netch.Servers.Socks5;
using Netch.Utils;
using static Netch.Interops.TUNInterop;
namespace Netch.Controllers
{
public class TUNController : IModeController
{
private readonly List<string> _directIPs = new();
private readonly List<string> _proxyIPs = new();
public readonly DNSController DNSController = new();
public string Name { get; } = "tun2socks";
private readonly OutboundAdapter _outboundAdapter = new();
private IAdapter _tunAdapter = null!;
private IPAddress _serverAddresses = null!;
public void Start(in Mode mode)
{
var server = MainController.Server!;
_serverAddresses = DnsUtils.Lookup(server.Hostname)!; // server address have been cached when MainController.Start
CheckDriver();
Dial(NameList.TYPE_ADAPMTU, "1500");
Dial(NameList.TYPE_BYPBIND, _outboundAdapter.Address.ToString());
Dial(NameList.TYPE_BYPLIST, "disabled");
#region Server
Dial(NameList.TYPE_TCPREST, "");
Dial(NameList.TYPE_TCPTYPE, "Socks5");
Dial(NameList.TYPE_UDPREST, "");
Dial(NameList.TYPE_UDPTYPE, "Socks5");
if (server is Socks5 socks5)
{
Dial(NameList.TYPE_TCPHOST, $"{server.AutoResolveHostname()}:{server.Port}");
Dial(NameList.TYPE_UDPHOST, $"{server.AutoResolveHostname()}:{server.Port}");
if (socks5.Auth())
{
Dial(NameList.TYPE_TCPUSER, socks5.Username!);
Dial(NameList.TYPE_TCPPASS, socks5.Password!);
Dial(NameList.TYPE_UDPUSER, socks5.Username!);
Dial(NameList.TYPE_UDPPASS, socks5.Password!);
}
}
else
{
Dial(NameList.TYPE_TCPHOST, $"127.0.0.1:{Global.Settings.Socks5LocalPort}");
Dial(NameList.TYPE_UDPHOST, $"127.0.0.1:{Global.Settings.Socks5LocalPort}");
}
#endregion
#region DNS
if (Global.Settings.TUNTAP.UseCustomDNS)
{
Dial(NameList.TYPE_DNSADDR, Global.Settings.TUNTAP.HijackDNS);
}
else
{
MainController.PortCheck(Global.Settings.AioDNS.ListenPort, "DNS");
DNSController.Start();
Dial(NameList.TYPE_DNSADDR, $"127.0.0.1:{Global.Settings.AioDNS.ListenPort}");
}
#endregion
Logging.Debug("tun2socks init");
Init();
_tunAdapter = new TunAdapter();
NativeMethods.CreateUnicastIP((int) AddressFamily.InterNetwork,
Global.Settings.TUNTAP.Address,
Utils.Utils.SubnetToCidr(Global.Settings.TUNTAP.Netmask),
_tunAdapter.InterfaceIndex);
SetupRouteTable(mode);
}
private readonly string BinDriver = Path.Combine(Global.NetchDir, @"bin\wintun.dll");
private readonly string SysDriver = $@"{Environment.SystemDirectory}\wintun.dll";
private void CheckDriver()
{
var binHash = Utils.Utils.SHA256CheckSum(BinDriver);
var sysHash = Utils.Utils.SHA256CheckSum(SysDriver);
Logging.Info("自带 wintun.dll Hash: " + binHash);
Logging.Info("系统 wintun.dll Hash: " + sysHash);
if (binHash == sysHash)
return;
try
{
File.Copy(BinDriver, SysDriver, true);
}
catch (Exception e)
{
Logging.Error(e.ToString());
throw new MessageException($"Failed to copy wintun.dll to system directory: {e.Message}");
}
}
/// <summary>
/// TUN/TAP停止
/// </summary>
public void Stop()
{
var tasks = new[]
{
Task.Run(Free),
Task.Run(ClearRouteTable),
Task.Run(DNSController.Stop)
};
Task.WaitAll(tasks);
}
/// <summary>
/// 设置绕行规则
/// </summary>
/// <returns>是否设置成功</returns>
private void SetupRouteTable(Mode mode)
{
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
Logging.Info("设置路由规则");
Logging.Info("绕行 → 服务器 IP");
if (!IPAddress.IsLoopback(_serverAddresses))
RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound);
Logging.Info("绕行 → 全局绕过 IP");
RouteAction(Action.Create, Global.Settings.TUNTAP.BypassIPs, RouteType.Outbound);
#region Rule IPs
switch (mode.Type)
{
case 1:
// 代理规则 IP
Logging.Info("代理 → 规则 IP");
RouteAction(Action.Create, mode.FullRule, RouteType.TUNTAP);
if (Global.Settings.TUNTAP.ProxyDNS)
{
Logging.Info("代理 → 自定义 DNS");
if (Global.Settings.TUNTAP.UseCustomDNS)
RouteAction(Action.Create, Global.Settings.TUNTAP.HijackDNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP);
else
RouteAction(Action.Create, $"{Global.Settings.AioDNS.OtherDNS}/32", RouteType.TUNTAP);
}
break;
case 2:
// 绕过规则 IP
Logging.Info("绕行 → 规则 IP");
RouteAction(Action.Create, mode.FullRule, RouteType.Outbound);
break;
}
#endregion
if (mode.Type == 2)
{
Logging.Info("代理 → 全局");
SetInterface(RouteType.TUNTAP, 0);
RouteAction(Action.Create, "0.0.0.0/0", RouteType.TUNTAP, record: false);
}
}
private void SetInterface(RouteType routeType, int? metric = null)
{
var adapter = routeType == RouteType.Outbound ? _outboundAdapter : _tunAdapter;
var arguments = $"interface ip set interface {adapter.InterfaceIndex} ";
if (metric != null)
arguments += $"metric={metric} ";
Utils.Utils.ProcessRunHiddenAsync("netsh", arguments).Wait();
}
/// <summary>
/// 清除绕行规则
/// </summary>
private bool ClearRouteTable()
{
var mode = MainController.Mode!;
RouteAction(Action.Delete, _directIPs, RouteType.Outbound);
RouteAction(Action.Delete, _proxyIPs, RouteType.TUNTAP);
_directIPs.Clear();
_proxyIPs.Clear();
if (mode.Type == 2)
{
SetInterface(RouteType.Outbound);
}
return true;
}
#region Package
private void RouteAction(Action action, in IEnumerable<string> ipNetworks, RouteType routeType, int metric = 0, bool record = true)
{
foreach (var address in ipNetworks)
RouteAction(action, address, routeType, metric);
}
private bool RouteAction(Action action, in string ipNetwork, RouteType routeType, int metric = 0, bool record = true)
{
#region
if (!TryParseIPNetwork(ipNetwork, out var ip, out var cidr))
return false;
IAdapter adapter = routeType switch
{
RouteType.Outbound => _outboundAdapter,
RouteType.TUNTAP => _tunAdapter,
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
};
List<string> ipList = routeType switch
{
RouteType.Outbound => _directIPs,
RouteType.TUNTAP => _proxyIPs,
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
};
string gateway = adapter.Gateway.ToString();
var index = adapter.InterfaceIndex;
#endregion
bool result;
switch (action)
{
case Action.Create:
result = NativeMethods.CreateRoute((int) AddressFamily.InterNetwork, ip, cidr, gateway, index, metric);
if (result && record)
ipList.Add(ipNetwork);
break;
case Action.Delete:
result = NativeMethods.DeleteRoute((int) AddressFamily.InterNetwork, ip, cidr, gateway, index, metric);
break;
default:
throw new ArgumentOutOfRangeException(nameof(action), action, null);
}
Logging.Debug($"{action}Route(\"{ip}\", {cidr}, \"{gateway}\", {index}, {metric})");
if (!result)
{
Logging.Warning($"Failed to invoke {action}Route(\"{ip}\", {cidr}, \"{gateway}\", {index}, {metric})");
}
return result;
}
bool TryParseIPNetwork(string ipNetwork, out string ip, out int cidr)
{
ip = null!;
cidr = 0;
var s = ipNetwork.Split('/');
if (s.Length != 2)
{
Logging.Warning($"Failed to parse rule {ipNetwork}");
return false;
}
ip = s[0];
cidr = int.Parse(s[1]);
return true;
}
private enum RouteType
{
Outbound,
TUNTAP
}
private enum Action
{
Create,
Delete
}
#endregion
}
}

View File

@@ -1,290 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Netch.Models;
using Netch.Servers.Socks5;
using Netch.Utils;
namespace Netch.Controllers
{
public class TUNTAPController : Guard, IModeController
{
private readonly List<string> _directIPs = new();
private readonly List<string> _proxyIPs = new();
/// <summary>
/// 服务器 IP 地址
/// </summary>
private IPAddress _serverAddresses = null!;
/// <summary>
/// 本地 DNS 服务控制器
/// </summary>
public DNSController DNSController = new();
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"Running"};
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"failed", "invalid vconfig file"};
public override string MainFile { get; protected set; } = "tun2socks.exe";
protected override Encoding InstanceOutputEncoding { get; } = Encoding.UTF8;
public override string Name { get; } = "tun2socks";
private readonly OutboundAdapter _outbound = new();
private TapAdapter _tap = null!;
public void Start(in Mode mode)
{
var server = MainController.Server!;
_serverAddresses = DnsUtils.Lookup(server.Hostname)!; // server address have been cached when MainController.Start
if (TUNTAP.GetComponentID() == null)
TUNTAP.AddTap();
_tap = new TapAdapter();
List<string> dns;
if (Global.Settings.TUNTAP.UseCustomDNS)
{
dns = Global.Settings.TUNTAP.DNS.Any() ? Global.Settings.TUNTAP.DNS : Global.Settings.TUNTAP.DNS = new List<string> {"1.1.1.1"};
}
else
{
MainController.PortCheck(53, "DNS");
DNSController.Start();
dns = new List<string> {"127.0.0.1"};
}
var parameter = new Tun2SocksParameter
{
tunAddr = Global.Settings.TUNTAP.Address,
tunMask = Global.Settings.TUNTAP.Netmask,
tunGw = Global.Settings.TUNTAP.Gateway,
tunDns = DnsUtils.Join(dns),
tunName = TUNTAP.GetName(_tap.ComponentID),
fakeDns = Global.Settings.TUNTAP.UseFakeDNS && Flags.SupportFakeDns
};
if (server is Socks5 socks5 && !socks5.Auth())
parameter.proxyServer = $"{server.AutoResolveHostname()}:{server.Port}";
else
parameter.proxyServer = $"127.0.0.1:{Global.Settings.Socks5LocalPort}";
StartInstanceAuto(parameter.ToString(), ProcessPriorityClass.RealTime);
SetupRouteTable(mode);
}
[Verb]
public class Tun2SocksParameter : ParameterBase
{
public string proxyServer { get; set; }
public string tunAddr { get; set; }
public string tunMask { get; set; }
public string tunGw { get; set; }
public string tunDns { get; set; }
public string tunName { get; set; }
public bool fakeDns { get; set; }
}
/// <summary>
/// TUN/TAP停止
/// </summary>
public override void Stop()
{
var tasks = new[]
{
Task.Run(StopInstance),
Task.Run(ClearRouteTable),
Task.Run(DNSController.Stop)
};
Task.WaitAll(tasks);
}
/// <summary>
/// 设置绕行规则
/// </summary>
/// <returns>是否设置成功</returns>
private void SetupRouteTable(Mode mode)
{
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
Logging.Info("设置路由规则");
#region Rule IPs
switch (mode.Type)
{
case 1:
// 代理规则 IP
Logging.Info("代理 → 规则 IP");
RouteAction(Action.Create, mode.FullRule, RouteType.TUNTAP);
if (Global.Settings.TUNTAP.ProxyDNS)
{
Logging.Info("代理 → 自定义 DNS");
if (Global.Settings.TUNTAP.UseCustomDNS)
RouteAction(Action.Create, Global.Settings.TUNTAP.DNS.Select(ip => $"{ip}/32"), RouteType.TUNTAP);
else
RouteAction(Action.Create, $"{Global.Settings.AioDNS.OtherDNS}/32", RouteType.TUNTAP);
}
break;
case 2:
// 绕过规则 IP
// 将 TUN/TAP 网卡权重放到最高
SetInterface(RouteType.TUNTAP, 0);
Logging.Info("绕行 → 规则 IP");
RouteAction(Action.Create, mode.FullRule, RouteType.Outbound);
break;
}
#endregion
Logging.Info("绕行 → 服务器 IP");
if (!IPAddress.IsLoopback(_serverAddresses))
RouteAction(Action.Create, $"{_serverAddresses}/32", RouteType.Outbound);
Logging.Info("绕行 → 全局绕过 IP");
RouteAction(Action.Create, Global.Settings.BypassIPs, RouteType.Outbound);
if (mode.Type == 2)
{
Logging.Info("代理 → 全局");
RouteAction(Action.Create, "0.0.0.0/0", RouteType.TUNTAP);
}
}
private void SetInterface(RouteType routeType, int? metric = null)
{
IAdapter adapter = routeType switch
{
RouteType.Outbound => _outbound,
RouteType.TUNTAP => _tap,
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
};
var arguments = $"interface ip set interface {adapter.Index} ";
if (metric != null)
arguments += $"metric={metric} ";
Process.Start(new ProcessStartInfo
{
FileName = "netsh",
Arguments = arguments,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
CreateNoWindow = true
});
}
/// <summary>
/// 清除绕行规则
/// </summary>
private bool ClearRouteTable()
{
RouteAction(Action.Delete, _directIPs, RouteType.Outbound);
RouteAction(Action.Delete, _proxyIPs, RouteType.TUNTAP);
_directIPs.Clear();
_proxyIPs.Clear();
return true;
}
public bool TestFakeDNS()
{
try
{
InitInstance("-h");
Instance!.Start();
return Instance.StandardError.ReadToEnd().Contains("-fakeDns");
}
catch
{
return false;
}
}
private void RouteAction(Action action, in IEnumerable<string> ipNetworks, RouteType routeType, int metric = 0)
{
foreach (var address in ipNetworks)
RouteAction(action, address, routeType, metric);
}
private bool RouteAction(Action action, in string ipNetwork, RouteType routeType, int metric = 0)
{
var s = ipNetwork.Split('/');
if (s.Length != 2)
{
Logging.Warning($"Failed to parse rule {ipNetwork}");
return false;
}
IAdapter adapter;
List<string> ipList;
switch (routeType)
{
case RouteType.TUNTAP:
adapter = _tap;
ipList = _proxyIPs;
break;
case RouteType.Outbound:
adapter = _outbound;
ipList = _directIPs;
break;
default:
throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null);
}
string network = s[0];
var cidr = ushort.Parse(s[1]);
string gateway = adapter.Gateway.ToString();
var index = adapter.Index;
bool result;
switch (action)
{
case Action.Create:
result = NativeMethods.CreateRoute(network, cidr, gateway, index, metric);
ipList.Add(ipNetwork);
break;
case Action.Delete:
result = NativeMethods.DeleteRoute(network, cidr, gateway, index, metric);
break;
default:
throw new ArgumentOutOfRangeException(nameof(action), action, null);
}
if (!result)
Logging.Warning($"Failed to {action} Route on {routeType} Adapter: {ipNetwork} metric {metric}");
return result;
}
private enum RouteType
{
Outbound,
TUNTAP
}
private enum Action
{
Create,
Delete
}
}
}

View File

@@ -20,7 +20,7 @@ namespace Netch.Controllers
public const string Copyright = @"Copyright © 2019 - 2021";
public const string AssemblyVersion = @"1.8.3";
private const string Suffix = @"Beta4";
private const string Suffix = @"Beta6";
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";

View File

@@ -1,5 +1,4 @@
using System;
using Netch.Controllers;
namespace Netch
{
@@ -7,10 +6,6 @@ namespace Netch
{
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
private static readonly Lazy<bool> LazySupportFakeDns = new(() => new TUNTAPController().TestFakeDNS());
public static bool SupportFakeDns => LazySupportFakeDns.Value;
public static bool AlwaysShowNewVersionFound { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Net;
using System.Windows.Forms;
using Netch.Properties;
@@ -18,7 +19,7 @@ namespace Netch.Forms
{
i18N.TranslateForm(this);
IPListBox.Items.AddRange(Global.Settings.BypassIPs.ToArray());
IPListBox.Items.AddRange(Global.Settings.TUNTAP.BypassIPs.Cast<object>().ToArray());
for (var i = 32; i >= 1; i--)
PrefixComboBox.Items.Add(i);
@@ -31,7 +32,7 @@ namespace Netch.Forms
if (!string.IsNullOrEmpty(IPTextBox.Text))
{
if (IPAddress.TryParse(IPTextBox.Text, out var address))
IPListBox.Items.Add(string.Format("{0}/{1}", address, PrefixComboBox.SelectedItem));
IPListBox.Items.Add($"{address}/{PrefixComboBox.SelectedItem}");
else
MessageBoxX.Show(i18N.Translate("Please enter a correct IP address"));
}
@@ -51,9 +52,9 @@ namespace Netch.Forms
private void ControlButton_Click(object sender, EventArgs e)
{
Global.Settings.BypassIPs.Clear();
Global.Settings.TUNTAP.BypassIPs.Clear();
foreach (var ip in IPListBox.Items)
Global.Settings.BypassIPs.Add((string) ip);
Global.Settings.TUNTAP.BypassIPs.Add((string) ip);
Configuration.Save();
MessageBoxX.Show(i18N.Translate("Saved"));

View File

@@ -40,7 +40,7 @@ namespace Netch.Forms
this.richTextBox1.BackColor = System.Drawing.SystemColors.Control;
this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Top;
this.richTextBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.richTextBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.richTextBox1.Location = new System.Drawing.Point(0, 0);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.ReadOnly = true;
@@ -54,14 +54,14 @@ namespace Netch.Forms
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(12, 297);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(102, 16);
this.checkBox1.Size = new System.Drawing.Size(101, 21);
this.checkBox1.TabIndex = 1;
this.checkBox1.Text = "Scroll to End";
this.checkBox1.UseVisualStyleBackColor = true;
//
// LogForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(454, 318);
this.ControlBox = false;

View File

@@ -16,13 +16,13 @@ namespace Netch.Forms
_parent = parent;
}
protected override void OnLoad(EventArgs e)
protected override void OnLoad(EventArgs? e)
{
base.OnLoad(e);
Parent_Move(null!, null!);
}
private void Parent_Move(object sender, EventArgs e)
private void Parent_Move(object? sender, EventArgs? e)
{
var cl = Location;
var fl = _parent.Location;
@@ -32,7 +32,7 @@ namespace Netch.Forms
Location = cl;
}
private void Parent_Activated(object sender, EventArgs e)
private void Parent_Activated(object? sender, EventArgs? e)
{
SetWindowPos(Handle,
HWND.HWND_TOPMOST,
@@ -51,7 +51,7 @@ namespace Netch.Forms
SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_SHOWWINDOW);
}
private void richTextBox1_TextChanged(object sender, System.EventArgs e)
private void richTextBox1_TextChanged(object? sender, EventArgs? e)
{
if (!checkBox1.Checked)
return;
@@ -60,19 +60,19 @@ namespace Netch.Forms
richTextBox1.ScrollToCaret();
}
private void Notifycation_Load(object sender, EventArgs e)
private void Notifycation_Load(object? sender, EventArgs? e)
{
_parent.LocationChanged += Parent_Move;
_parent.SizeChanged += Parent_Move;
_parent.Activated += Parent_Activated;
}
protected override void OnClosing(CancelEventArgs e)
protected override void OnClosing(CancelEventArgs? e)
{
_parent.Activated -= Parent_Activated;
_parent.LocationChanged -= Parent_Move;
_parent.SizeChanged -= Parent_Move;
base.OnClosing(e);
base.OnClosing(e!);
}
}
}

60
Netch/Forms/LogForm.resx Normal file
View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -38,15 +38,10 @@
this.SubscribeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ManageSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UpdateServersFromSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.OptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.OpenDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.CleanDNSCacheToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UpdateACLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.updateACLWithProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.updatePACToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UninstallTapDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeNetchFirewallRulesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.HelpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.CheckForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -61,7 +56,7 @@
this.ModeLabel = new System.Windows.Forms.Label();
this.ServerLabel = new System.Windows.Forms.Label();
this.ProfileNameText = new System.Windows.Forms.TextBox();
this.ModeComboBox = new System.Windows.Forms.SearchComboBox();
this.ModeComboBox = new System.Windows.Forms.ComboBox();
this.ServerComboBox = new System.Windows.Forms.ComboBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.EditServerPictureBox = new System.Windows.Forms.PictureBox();
@@ -171,8 +166,7 @@
//
this.SubscribeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ManageSubscribeLinksToolStripMenuItem,
this.UpdateServersFromSubscribeLinksToolStripMenuItem,
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem});
this.UpdateServersFromSubscribeLinksToolStripMenuItem});
this.SubscribeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.SubscribeToolStripMenuItem.Name = "SubscribeToolStripMenuItem";
this.SubscribeToolStripMenuItem.Size = new System.Drawing.Size(77, 21);
@@ -181,34 +175,23 @@
// ManageSubscribeLinksToolStripMenuItem
//
this.ManageSubscribeLinksToolStripMenuItem.Name = "ManageSubscribeLinksToolStripMenuItem";
this.ManageSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(360, 22);
this.ManageSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(294, 22);
this.ManageSubscribeLinksToolStripMenuItem.Text = "Manage Subscribe Links";
this.ManageSubscribeLinksToolStripMenuItem.Click += new System.EventHandler(this.ManageSubscribeLinksToolStripMenuItem_Click);
//
// UpdateServersFromSubscribeLinksToolStripMenuItem
//
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Name = "UpdateServersFromSubscribeLinksToolStripMenuItem";
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(360, 22);
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(294, 22);
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Text = "Update Servers From Subscribe Links";
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Click += new System.EventHandler(this.UpdateServersFromSubscribeLinksToolStripMenuItem_Click);
//
// UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem
//
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Name = "UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem";
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Size = new System.Drawing.Size(360, 22);
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Text = "Update Servers From Subscribe Links With Proxy";
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Click += new System.EventHandler(this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem_Click);
//
// OptionsToolStripMenuItem
//
this.OptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.OpenDirectoryToolStripMenuItem,
this.CleanDNSCacheToolStripMenuItem,
this.UpdateACLToolStripMenuItem,
this.updateACLWithProxyToolStripMenuItem,
this.updatePACToolStripMenuItem,
this.UninstallServiceToolStripMenuItem,
this.UninstallTapDriverToolStripMenuItem,
this.removeNetchFirewallRulesToolStripMenuItem});
this.OptionsToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.OptionsToolStripMenuItem.Name = "OptionsToolStripMenuItem";
@@ -229,27 +212,6 @@
this.CleanDNSCacheToolStripMenuItem.Text = "Clean DNS Cache";
this.CleanDNSCacheToolStripMenuItem.Click += new System.EventHandler(this.CleanDNSCacheToolStripMenuItem_Click);
//
// UpdateACLToolStripMenuItem
//
this.UpdateACLToolStripMenuItem.Name = "UpdateACLToolStripMenuItem";
this.UpdateACLToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.UpdateACLToolStripMenuItem.Text = "Update ACL";
this.UpdateACLToolStripMenuItem.Click += new System.EventHandler(this.updateACLToolStripMenuItem_Click);
//
// updateACLWithProxyToolStripMenuItem
//
this.updateACLWithProxyToolStripMenuItem.Name = "updateACLWithProxyToolStripMenuItem";
this.updateACLWithProxyToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.updateACLWithProxyToolStripMenuItem.Text = "Update ACL with proxy";
this.updateACLWithProxyToolStripMenuItem.Click += new System.EventHandler(this.updateACLWithProxyToolStripMenuItem_Click);
//
// updatePACToolStripMenuItem
//
this.updatePACToolStripMenuItem.Name = "updatePACToolStripMenuItem";
this.updatePACToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.updatePACToolStripMenuItem.Text = "Update PAC";
this.updatePACToolStripMenuItem.Click += new System.EventHandler(this.updatePACToolStripMenuItem_Click);
//
// UninstallServiceToolStripMenuItem
//
this.UninstallServiceToolStripMenuItem.Name = "UninstallServiceToolStripMenuItem";
@@ -257,13 +219,6 @@
this.UninstallServiceToolStripMenuItem.Text = "Uninstall NF Service";
this.UninstallServiceToolStripMenuItem.Click += new System.EventHandler(this.UninstallServiceToolStripMenuItem_Click);
//
// UninstallTapDriverToolStripMenuItem
//
this.UninstallTapDriverToolStripMenuItem.Name = "UninstallTapDriverToolStripMenuItem";
this.UninstallTapDriverToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
this.UninstallTapDriverToolStripMenuItem.Text = "Uninstall TUN/TAP driver";
this.UninstallTapDriverToolStripMenuItem.Click += new System.EventHandler(this.UninstallTapDriverToolStripMenuItem_Click);
//
// removeNetchFirewallRulesToolStripMenuItem
//
this.removeNetchFirewallRulesToolStripMenuItem.Name = "removeNetchFirewallRulesToolStripMenuItem";
@@ -414,9 +369,9 @@
//
// ModeComboBox
//
this.ModeComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
this.ModeComboBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.ModeComboBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.ModeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ModeComboBox.FormattingEnabled = true;
this.ModeComboBox.IntegralHeight = false;
this.ModeComboBox.Location = new System.Drawing.Point(54, 33);
@@ -732,7 +687,7 @@
this.Controls.Add(this.MenuStrip);
this.Controls.Add(this.StatusStrip);
this.Controls.Add(this.flowLayoutPanel1);
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.MaximizeBox = false;
@@ -788,7 +743,7 @@
private System.Windows.Forms.ToolStripMenuItem ImportServersFromClipboardToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem ManageSubscribeLinksToolStripMenuItem;
private System.Windows.Forms.MenuStrip MenuStrip;
private System.Windows.Forms.SearchComboBox ModeComboBox;
private System.Windows.Forms.ComboBox ModeComboBox;
private System.Windows.Forms.Label ModeLabel;
private System.Windows.Forms.ToolStripMenuItem ModeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem HelpToolStripMenuItem;
@@ -801,7 +756,6 @@
private System.Windows.Forms.Label ProfileLabel;
private System.Windows.Forms.TextBox ProfileNameText;
private System.Windows.Forms.TableLayoutPanel ProfileTable;
private System.Windows.Forms.ToolStripMenuItem UninstallTapDriverToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem CheckForUpdatesToolStripMenuItem;
private System.Windows.Forms.ComboBox ServerComboBox;
private System.Windows.Forms.Label ServerLabel;
@@ -815,10 +769,7 @@
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.ToolStripMenuItem UninstallServiceToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem UpdateACLToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem updateACLWithProxyToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem;
private System.Windows.Forms.ToolStripStatusLabel UploadSpeedLabel;
private System.Windows.Forms.ToolStripStatusLabel UsedBandwidthLabel;
private System.Windows.Forms.ToolStripLabel NewVersionLabel;
@@ -831,6 +782,5 @@
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.ContainerControl ButtomControlContainerControl;
private System.Windows.Forms.ToolStripMenuItem updatePACToolStripMenuItem;
}
}

View File

@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -42,25 +42,12 @@ namespace Netch.Forms
#region i18N Translations
_mainFormText.Add(UninstallServiceToolStripMenuItem.Name, new[] {"Uninstall {0}", "NF Service"});
_mainFormText.Add(UninstallTapDriverToolStripMenuItem.Name, new[] {"Uninstall {0}", "TUN/TAP driver"});
#endregion
// 监听电源事件
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
ModeComboBox.KeyUp += (_, args) =>
{
switch (args.KeyData)
{
case Keys.Escape:
{
SelectLastMode();
return;
}
}
};
CheckForIllegalCrossThreadCalls = false;
}
@@ -113,7 +100,7 @@ namespace Netch.Forms
{
// 检查订阅更新
if (Global.Settings.UpdateServersWhenOpened)
UpdateServersFromSubscribe(Global.Settings.UseProxyToUpdateSubscription).Wait();
UpdateServersFromSubscribe().Wait();
// 打开软件时启动加速,产生开始按钮点击事件
if (Global.Settings.StartWhenOpened)
@@ -235,8 +222,12 @@ namespace Netch.Forms
}
}
private void AddServerToolStripMenuItem_Click(object sender, EventArgs e)
private void AddServerToolStripMenuItem_Click([NotNull] object? sender, EventArgs? e)
{
if (sender == null)
throw new ArgumentNullException(nameof(sender));
// TODO get Util from Tag
var s = ((ToolStripMenuItem) sender).Text;
var start = s.IndexOf("[", StringComparison.Ordinal) + 1;
@@ -276,33 +267,16 @@ namespace Netch.Forms
private async void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Settings.UseProxyToUpdateSubscription = false;
await UpdateServersFromSubscribe();
}
private async void UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Settings.UseProxyToUpdateSubscription = true;
await UpdateServersFromSubscribe(true);
}
private async Task UpdateServersFromSubscribe(bool useProxy = false)
private async Task UpdateServersFromSubscribe()
{
void DisableItems(bool v)
{
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ProfileGroupBox.Enabled = ControlButton.Enabled = v;
}
var server = ServerComboBox.SelectedItem as Server;
if (useProxy)
{
if (server == null)
{
MessageBoxX.Show(i18N.Translate("Please select a server first"));
return;
}
}
if (Global.Settings.SubscribeLink.Count <= 0)
{
MessageBoxX.Show(i18N.Translate("No subscription link"));
@@ -311,22 +285,10 @@ namespace Netch.Forms
StatusText(i18N.Translate("Starting update subscription"));
DisableItems(false);
try
{
string? proxyServer = null;
if (useProxy)
{
var mode = new Models.Mode
{
Remark = "ProxyUpdate",
Type = 5
};
await MainController.StartAsync(server!, mode);
proxyServer = $"http://127.0.0.1:{Global.Settings.HTTPLocalPort}";
}
await Subscription.UpdateServersAsync(proxyServer);
await Subscription.UpdateServersAsync();
LoadServers();
Configuration.Save();
@@ -339,9 +301,6 @@ namespace Netch.Forms
}
finally
{
if (useProxy)
await MainController.StopAsync();
DisableItems(true);
}
}
@@ -354,12 +313,12 @@ namespace Netch.Forms
{
Task.Run(() =>
{
void OnNewVersionNotFound(object o, EventArgs args)
void OnNewVersionNotFound(object? o, EventArgs? args)
{
NotifyTip(i18N.Translate("Already latest version"));
}
void OnNewVersionFoundFailed(object o, EventArgs args)
void OnNewVersionFoundFailed(object? o, EventArgs? args)
{
NotifyTip(i18N.Translate("New version found failed"), info: false);
}
@@ -405,90 +364,6 @@ namespace Netch.Forms
}
}
private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateACL(true);
}
private void updateACLToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateACL(false);
}
private async void UpdateACL(bool useProxy)
{
Enabled = false;
StatusText(i18N.TranslateFormat("Updating {0}", "ACL"));
try
{
if (useProxy)
{
if (!(ServerComboBox.SelectedItem is Server server))
{
MessageBoxX.Show(i18N.Translate("Please select a server first"));
return;
}
else
{
var mode = new Models.Mode
{
Remark = "ProxyUpdate",
Type = 5
};
await MainController.StartAsync(server, mode);
}
}
var req = WebUtil.CreateRequest(Global.Settings.ACL);
if (useProxy)
req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, Constants.UserACL));
NotifyTip(i18N.Translate("ACL updated successfully"));
}
catch (Exception e)
{
NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false);
Logging.Error("更新 ACL 失败!" + e);
}
finally
{
if (useProxy)
await MainController.StopAsync();
StatusText();
Enabled = true;
}
}
private async void updatePACToolStripMenuItem_Click(object sender, EventArgs eventArgs)
{
Enabled = false;
StatusText(i18N.TranslateFormat("Updating {0}", "PAC"));
try
{
var req = WebUtil.CreateRequest(Global.Settings.PAC);
var pac = Path.Combine(Global.NetchDir, "bin\\pac.txt");
await WebUtil.DownloadFileAsync(req, pac);
NotifyTip(i18N.Translate("PAC updated successfully"));
}
catch (Exception e)
{
NotifyTip(i18N.Translate("PAC update failed") + "\n" + e.Message, info: false);
Logging.Error("更新 PAC 失败!" + e);
}
finally
{
StatusText();
Enabled = true;
}
}
private async void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
{
Enabled = false;
@@ -508,26 +383,6 @@ namespace Netch.Forms
}
}
private async void UninstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
{
Enabled = false;
StatusText(i18N.TranslateFormat("Uninstalling {0}", "TUN/TAP driver"));
try
{
await Task.Run(TUNTAP.deltapall);
NotifyTip(i18N.TranslateFormat("{0} has been uninstalled", "TUN/TAP driver"));
}
catch (Exception exception)
{
Logging.Error($"卸载 TUN/TAP 适配器失败: {exception}");
}
finally
{
StatusText();
Enabled = true;
}
}
private void RemoveNetchFirewallRulesToolStripMenuItem_Click(object sender, EventArgs e)
{
Firewall.RemoveNetchFwRules();
@@ -630,9 +485,6 @@ namespace Netch.Forms
return;
}
// 清除模式搜索框文本选择
ModeComboBox.Select(0, 0);
State = State.Starting;
try
@@ -771,7 +623,7 @@ namespace Netch.Forms
ServerHelper.DelayTestHelper.TestDelayFinished += OnTestDelayFinished;
_ = Task.Run(ServerHelper.DelayTestHelper.TestAllDelay);
void OnTestDelayFinished(object o1, EventArgs e1)
void OnTestDelayFinished(object? o1, EventArgs? e1)
{
Refresh();
@@ -980,7 +832,6 @@ namespace Netch.Forms
private void ActiveProfile(Profile profile)
{
ProfileNameText.Text = profile.ProfileName;
ModeComboBox.ResetCompletionList();
var server = ServerComboBox.Items.Cast<Server>().FirstOrDefault(s => s.Remark.Equals(profile.ServerRemark));
var mode = ModeComboBox.Items.Cast<Models.Mode>().FirstOrDefault(m => m.Remark.Equals(profile.ModeRemark));
@@ -1010,8 +861,11 @@ namespace Netch.Forms
return profile;
}
private async void ProfileButton_Click(object sender, EventArgs e)
private async void ProfileButton_Click([NotNull] object? sender, EventArgs? e)
{
if (sender == null)
throw new ArgumentNullException(nameof(sender));
var profileButton = (Button) sender;
var profile = (Profile?) profileButton.Tag;
var index = ProfileTable.Controls.IndexOf(profileButton);
@@ -1099,9 +953,7 @@ namespace Netch.Forms
EditServerPictureBox.Enabled = DeleteModePictureBox.Enabled = DeleteServerPictureBox.Enabled = enabled;
// 启动需要禁用的控件
UninstallServiceToolStripMenuItem.Enabled = UpdateACLToolStripMenuItem.Enabled = updateACLWithProxyToolStripMenuItem.Enabled =
updatePACToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Enabled = UninstallTapDriverToolStripMenuItem.Enabled = enabled;
UninstallServiceToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = enabled;
}
_state = value;
@@ -1428,7 +1280,7 @@ namespace Netch.Forms
UpdateChecker.NewVersionFound -= OnUpdateCheckerOnNewVersionFound;
}
void OnUpdateCheckerOnNewVersionFound(object o, EventArgs eventArgs)
void OnUpdateCheckerOnNewVersionFound(object? o, EventArgs? eventArgs)
{
NotifyTip($"{i18N.Translate(@"New version available", ": ")}{UpdateChecker.LatestVersionNumber}");
NewVersionLabel.Text = i18N.Translate("New version available");

View File

@@ -1,64 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
@@ -117,16 +57,4 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="StatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>130, 17</value>
</metadata>
<metadata name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>246, 17</value>
</metadata>
<metadata name="NotifyMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>359, 17</value>
</metadata>
</root>

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.WindowsAPICodePack.Dialogs;
using Netch.Controllers;
@@ -135,7 +134,6 @@ namespace Netch.Forms.Mode
var mode = new Models.Mode(fullName)
{
BypassChina = false,
Type = 0,
Remark = RemarkTextBox.Text
};
@@ -149,7 +147,7 @@ namespace Netch.Forms.Mode
Close();
}
private void RemarkTextBox_TextChanged(object sender, EventArgs e)
private void RemarkTextBox_TextChanged(object? sender, EventArgs? e)
{
BeginInvoke(new Action(() =>
{
@@ -195,7 +193,8 @@ namespace Netch.Forms.Mode
foreach (string dir in Directory.GetDirectories(directory))
ScanDirectory(dir, list, maxCount);
list.AddRange(Directory.GetFiles(directory).Select(Path.GetFileName).Where(s => s.EndsWith(".exe")).Select(s => s.ToRegexString()));
list.AddRange(
Directory.GetFiles(directory).Select(s => Path.GetFileName(s)).Where(s => s.EndsWith(".exe")).Select(s => s.ToRegexString()));
if (maxCount != 0 && list.Count > maxCount)
throw new Exception("The number of results is greater than maxCount");
@@ -203,7 +202,7 @@ namespace Netch.Forms.Mode
private void ValidationButton_Click(object sender, EventArgs e)
{
if (NFController.CheckRules(Rules, out var results))
if (!NFController.CheckRules(Rules, out var results))
MessageBoxX.Show(NFController.GenerateInvalidRulesMessage(results), LogLevel.WARNING);
else
MessageBoxX.Show("Fine");

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -72,7 +72,7 @@ namespace Netch.Forms.Mode
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(84, 49);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(138, 20);
this.comboBox1.Size = new System.Drawing.Size(138, 25);
this.comboBox1.TabIndex = 11;
//
// FilenameLabel
@@ -80,7 +80,7 @@ namespace Netch.Forms.Mode
this.FilenameLabel.AutoSize = true;
this.FilenameLabel.Location = new System.Drawing.Point(12, 79);
this.FilenameLabel.Name = "FilenameLabel";
this.FilenameLabel.Size = new System.Drawing.Size(53, 12);
this.FilenameLabel.Size = new System.Drawing.Size(59, 17);
this.FilenameLabel.TabIndex = 6;
this.FilenameLabel.Text = "Filename";
//
@@ -89,7 +89,7 @@ namespace Netch.Forms.Mode
this.FilenameTextBox.Location = new System.Drawing.Point(84, 76);
this.FilenameTextBox.Name = "FilenameTextBox";
this.FilenameTextBox.ReadOnly = true;
this.FilenameTextBox.Size = new System.Drawing.Size(250, 21);
this.FilenameTextBox.Size = new System.Drawing.Size(250, 23);
this.FilenameTextBox.TabIndex = 5;
//
// ActionLabel
@@ -97,7 +97,7 @@ namespace Netch.Forms.Mode
this.ActionLabel.AutoSize = true;
this.ActionLabel.Location = new System.Drawing.Point(12, 52);
this.ActionLabel.Name = "ActionLabel";
this.ActionLabel.Size = new System.Drawing.Size(41, 12);
this.ActionLabel.Size = new System.Drawing.Size(44, 17);
this.ActionLabel.TabIndex = 0;
this.ActionLabel.Text = "Action";
//
@@ -105,7 +105,7 @@ namespace Netch.Forms.Mode
//
this.RemarkTextBox.Location = new System.Drawing.Point(84, 22);
this.RemarkTextBox.Name = "RemarkTextBox";
this.RemarkTextBox.Size = new System.Drawing.Size(250, 21);
this.RemarkTextBox.Size = new System.Drawing.Size(250, 23);
this.RemarkTextBox.TabIndex = 1;
this.RemarkTextBox.TextChanged += new System.EventHandler(this.RemarkTextBox_TextChanged);
//
@@ -114,7 +114,7 @@ namespace Netch.Forms.Mode
this.RemarkLabel.AutoSize = true;
this.RemarkLabel.Location = new System.Drawing.Point(12, 25);
this.RemarkLabel.Name = "RemarkLabel";
this.RemarkLabel.Size = new System.Drawing.Size(41, 12);
this.RemarkLabel.Size = new System.Drawing.Size(53, 17);
this.RemarkLabel.TabIndex = 0;
this.RemarkLabel.Text = "Remark";
//
@@ -161,7 +161,7 @@ namespace Netch.Forms.Mode
//
// Route
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(356, 419);
this.Controls.Add(this.ConfigurationGroupBox);

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Windows.Forms;
using Netch.Models;
using Netch.Properties;
using Netch.Utils;
@@ -8,26 +9,7 @@ namespace Netch.Forms.Mode
{
public partial class Route : Form
{
class Item
{
private string _text;
public Item(int value, string text)
{
_text = text;
Value = value;
}
public string Text
{
get => i18N.Translate(_text);
set => _text = value;
}
public int Value { get; set; }
}
private readonly Item[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")};
private readonly TagItem<int>[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")};
private readonly Models.Mode? _mode;
@@ -41,8 +23,8 @@ namespace Netch.Forms.Mode
InitializeComponent();
Icon = Resources.icon;
comboBox1.DataSource = _items;
comboBox1.ValueMember = "Value";
comboBox1.DisplayMember = "Text";
comboBox1.ValueMember = nameof(TagItem<int>.Value);
comboBox1.DisplayMember = nameof(TagItem<int>.Text);
}
private void Route_Load(object sender, EventArgs e)
@@ -110,12 +92,9 @@ namespace Netch.Forms.Mode
Close();
}
private void RemarkTextBox_TextChanged(object sender, EventArgs e)
private void RemarkTextBox_TextChanged(object? sender, EventArgs? e)
{
BeginInvoke(new Action(() =>
{
FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text);
}));
BeginInvoke(new Action(() => { FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text); }));
}
}
}

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -38,8 +38,6 @@ namespace Netch.Forms
this.Socks5PortTextBox = new System.Windows.Forms.TextBox();
this.HTTPPortLabel = new System.Windows.Forms.Label();
this.HTTPPortTextBox = new System.Windows.Forms.TextBox();
this.RedirectorLabel = new System.Windows.Forms.Label();
this.RedirectorTextBox = new System.Windows.Forms.TextBox();
this.AllowDevicesCheckBox = new System.Windows.Forms.CheckBox();
this.ResolveServerHostnameCheckBox = new System.Windows.Forms.CheckBox();
this.ServerPingTypeLabel = new System.Windows.Forms.Label();
@@ -53,24 +51,20 @@ namespace Netch.Forms
this.StartedPingIntervalTextBox = 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();
this.AclAddrTextBox = new System.Windows.Forms.TextBox();
this.LanguageLabel = new System.Windows.Forms.Label();
this.LanguageComboBox = new System.Windows.Forms.ComboBox();
this.NFTabPage = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.ProcessProxyProtocolLabel = new System.Windows.Forms.Label();
this.ProcessProxyProtocolComboBox = new System.Windows.Forms.ComboBox();
this.DNSRedirectorCheckBox = new System.Windows.Forms.CheckBox();
this.RDRDNSLabel = new System.Windows.Forms.Label();
this.RDRDNSTextBox = new System.Windows.Forms.TextBox();
this.ICMPRedirectorCheckBox = new System.Windows.Forms.CheckBox();
this.RDRICMPLabel = new System.Windows.Forms.Label();
this.ModifiedICMPTextBox = new System.Windows.Forms.TextBox();
this.DNSHijackCheckBox = new System.Windows.Forms.CheckBox();
this.DNSHijackHostTextBox = new System.Windows.Forms.TextBox();
this.ICMPHijackCheckBox = new System.Windows.Forms.CheckBox();
this.ICMPHijackHostTextBox = new System.Windows.Forms.TextBox();
this.RedirectorSSCheckBox = new System.Windows.Forms.CheckBox();
this.ChildProcessHandleCheckBox = new System.Windows.Forms.CheckBox();
this.TAPTabPage = new System.Windows.Forms.TabPage();
this.TUNTAPGroupBox = new System.Windows.Forms.GroupBox();
this.WinTUNTabPage = new System.Windows.Forms.TabPage();
this.WinTUNGroupBox = new System.Windows.Forms.GroupBox();
this.TUNTAPAddressLabel = new System.Windows.Forms.Label();
this.TUNTAPAddressTextBox = new System.Windows.Forms.TextBox();
this.TUNTAPNetmaskLabel = new System.Windows.Forms.Label();
@@ -81,7 +75,6 @@ namespace Netch.Forms
this.TUNTAPDNSTextBox = new System.Windows.Forms.TextBox();
this.UseCustomDNSCheckBox = new System.Windows.Forms.CheckBox();
this.ProxyDNSCheckBox = new System.Windows.Forms.CheckBox();
this.UseFakeDNSCheckBox = new System.Windows.Forms.CheckBox();
this.GlobalBypassIPsButton = new System.Windows.Forms.Button();
this.v2rayTabPage = new System.Windows.Forms.TabPage();
this.XrayConeCheckBox = new System.Windows.Forms.CheckBox();
@@ -124,8 +117,8 @@ namespace Netch.Forms
this.PortGroupBox.SuspendLayout();
this.NFTabPage.SuspendLayout();
this.groupBox1.SuspendLayout();
this.TAPTabPage.SuspendLayout();
this.TUNTAPGroupBox.SuspendLayout();
this.WinTUNTabPage.SuspendLayout();
this.WinTUNGroupBox.SuspendLayout();
this.v2rayTabPage.SuspendLayout();
this.KCPGroupBox.SuspendLayout();
this.OtherTabPage.SuspendLayout();
@@ -138,7 +131,7 @@ namespace Netch.Forms
this.TabControl.Appearance = System.Windows.Forms.TabAppearance.FlatButtons;
this.TabControl.Controls.Add(this.GeneralTabPage);
this.TabControl.Controls.Add(this.NFTabPage);
this.TabControl.Controls.Add(this.TAPTabPage);
this.TabControl.Controls.Add(this.WinTUNTabPage);
this.TabControl.Controls.Add(this.v2rayTabPage);
this.TabControl.Controls.Add(this.OtherTabPage);
this.TabControl.Controls.Add(this.AioDNSTabPage);
@@ -164,14 +157,12 @@ namespace Netch.Forms
this.GeneralTabPage.Controls.Add(this.StartedPingIntervalTextBox);
this.GeneralTabPage.Controls.Add(this.STUNServerLabel);
this.GeneralTabPage.Controls.Add(this.STUN_ServerComboBox);
this.GeneralTabPage.Controls.Add(this.AclLabel);
this.GeneralTabPage.Controls.Add(this.AclAddrTextBox);
this.GeneralTabPage.Controls.Add(this.LanguageLabel);
this.GeneralTabPage.Controls.Add(this.LanguageComboBox);
this.GeneralTabPage.Location = new System.Drawing.Point(4, 25);
this.GeneralTabPage.Location = new System.Drawing.Point(4, 29);
this.GeneralTabPage.Name = "GeneralTabPage";
this.GeneralTabPage.Padding = new System.Windows.Forms.Padding(3);
this.GeneralTabPage.Size = new System.Drawing.Size(461, 325);
this.GeneralTabPage.Size = new System.Drawing.Size(461, 321);
this.GeneralTabPage.TabIndex = 0;
this.GeneralTabPage.Text = "General";
//
@@ -181,8 +172,6 @@ namespace Netch.Forms
this.PortGroupBox.Controls.Add(this.Socks5PortTextBox);
this.PortGroupBox.Controls.Add(this.HTTPPortLabel);
this.PortGroupBox.Controls.Add(this.HTTPPortTextBox);
this.PortGroupBox.Controls.Add(this.RedirectorLabel);
this.PortGroupBox.Controls.Add(this.RedirectorTextBox);
this.PortGroupBox.Controls.Add(this.AllowDevicesCheckBox);
this.PortGroupBox.Location = new System.Drawing.Point(8, 6);
this.PortGroupBox.Name = "PortGroupBox";
@@ -196,7 +185,7 @@ namespace Netch.Forms
this.Socks5PortLabel.AutoSize = true;
this.Socks5PortLabel.Location = new System.Drawing.Point(9, 25);
this.Socks5PortLabel.Name = "Socks5PortLabel";
this.Socks5PortLabel.Size = new System.Drawing.Size(41, 12);
this.Socks5PortLabel.Size = new System.Drawing.Size(49, 17);
this.Socks5PortLabel.TabIndex = 0;
this.Socks5PortLabel.Text = "Socks5";
//
@@ -204,7 +193,7 @@ namespace Netch.Forms
//
this.Socks5PortTextBox.Location = new System.Drawing.Point(120, 22);
this.Socks5PortTextBox.Name = "Socks5PortTextBox";
this.Socks5PortTextBox.Size = new System.Drawing.Size(90, 21);
this.Socks5PortTextBox.Size = new System.Drawing.Size(90, 23);
this.Socks5PortTextBox.TabIndex = 1;
this.Socks5PortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -213,7 +202,7 @@ namespace Netch.Forms
this.HTTPPortLabel.AutoSize = true;
this.HTTPPortLabel.Location = new System.Drawing.Point(9, 54);
this.HTTPPortLabel.Name = "HTTPPortLabel";
this.HTTPPortLabel.Size = new System.Drawing.Size(29, 12);
this.HTTPPortLabel.Size = new System.Drawing.Size(38, 17);
this.HTTPPortLabel.TabIndex = 2;
this.HTTPPortLabel.Text = "HTTP";
//
@@ -221,33 +210,16 @@ namespace Netch.Forms
//
this.HTTPPortTextBox.Location = new System.Drawing.Point(120, 51);
this.HTTPPortTextBox.Name = "HTTPPortTextBox";
this.HTTPPortTextBox.Size = new System.Drawing.Size(90, 21);
this.HTTPPortTextBox.Size = new System.Drawing.Size(90, 23);
this.HTTPPortTextBox.TabIndex = 3;
this.HTTPPortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// RedirectorLabel
//
this.RedirectorLabel.AutoSize = true;
this.RedirectorLabel.Location = new System.Drawing.Point(9, 83);
this.RedirectorLabel.Name = "RedirectorLabel";
this.RedirectorLabel.Size = new System.Drawing.Size(89, 12);
this.RedirectorLabel.TabIndex = 4;
this.RedirectorLabel.Text = "Redirector TCP";
//
// RedirectorTextBox
//
this.RedirectorTextBox.Location = new System.Drawing.Point(120, 80);
this.RedirectorTextBox.Name = "RedirectorTextBox";
this.RedirectorTextBox.Size = new System.Drawing.Size(90, 21);
this.RedirectorTextBox.TabIndex = 5;
this.RedirectorTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// AllowDevicesCheckBox
//
this.AllowDevicesCheckBox.AutoSize = true;
this.AllowDevicesCheckBox.Location = new System.Drawing.Point(6, 107);
this.AllowDevicesCheckBox.Name = "AllowDevicesCheckBox";
this.AllowDevicesCheckBox.Size = new System.Drawing.Size(204, 16);
this.AllowDevicesCheckBox.Size = new System.Drawing.Size(206, 21);
this.AllowDevicesCheckBox.TabIndex = 6;
this.AllowDevicesCheckBox.Text = "Allow other Devices to connect";
this.AllowDevicesCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -258,7 +230,7 @@ namespace Netch.Forms
this.ResolveServerHostnameCheckBox.AutoSize = true;
this.ResolveServerHostnameCheckBox.Location = new System.Drawing.Point(267, 15);
this.ResolveServerHostnameCheckBox.Name = "ResolveServerHostnameCheckBox";
this.ResolveServerHostnameCheckBox.Size = new System.Drawing.Size(162, 16);
this.ResolveServerHostnameCheckBox.Size = new System.Drawing.Size(176, 21);
this.ResolveServerHostnameCheckBox.TabIndex = 1;
this.ResolveServerHostnameCheckBox.Text = "Resolve Server Hostname";
this.ResolveServerHostnameCheckBox.UseVisualStyleBackColor = true;
@@ -268,7 +240,7 @@ namespace Netch.Forms
this.ServerPingTypeLabel.AutoSize = true;
this.ServerPingTypeLabel.Location = new System.Drawing.Point(267, 44);
this.ServerPingTypeLabel.Name = "ServerPingTypeLabel";
this.ServerPingTypeLabel.Size = new System.Drawing.Size(89, 12);
this.ServerPingTypeLabel.Size = new System.Drawing.Size(98, 17);
this.ServerPingTypeLabel.TabIndex = 2;
this.ServerPingTypeLabel.Text = "ServerPingType";
//
@@ -277,7 +249,7 @@ namespace Netch.Forms
this.ICMPingRadioBtn.AutoSize = true;
this.ICMPingRadioBtn.Location = new System.Drawing.Point(268, 63);
this.ICMPingRadioBtn.Name = "ICMPingRadioBtn";
this.ICMPingRadioBtn.Size = new System.Drawing.Size(65, 16);
this.ICMPingRadioBtn.Size = new System.Drawing.Size(75, 21);
this.ICMPingRadioBtn.TabIndex = 3;
this.ICMPingRadioBtn.TabStop = true;
this.ICMPingRadioBtn.Text = "ICMPing";
@@ -286,9 +258,9 @@ namespace Netch.Forms
// TCPingRadioBtn
//
this.TCPingRadioBtn.AutoSize = true;
this.TCPingRadioBtn.Location = new System.Drawing.Point(332, 63);
this.TCPingRadioBtn.Location = new System.Drawing.Point(366, 64);
this.TCPingRadioBtn.Name = "TCPingRadioBtn";
this.TCPingRadioBtn.Size = new System.Drawing.Size(59, 16);
this.TCPingRadioBtn.Size = new System.Drawing.Size(66, 21);
this.TCPingRadioBtn.TabIndex = 4;
this.TCPingRadioBtn.TabStop = true;
this.TCPingRadioBtn.Text = "TCPing";
@@ -299,7 +271,7 @@ namespace Netch.Forms
this.ProfileCountLabel.AutoSize = true;
this.ProfileCountLabel.Location = new System.Drawing.Point(12, 160);
this.ProfileCountLabel.Name = "ProfileCountLabel";
this.ProfileCountLabel.Size = new System.Drawing.Size(77, 12);
this.ProfileCountLabel.Size = new System.Drawing.Size(79, 17);
this.ProfileCountLabel.TabIndex = 5;
this.ProfileCountLabel.Text = "ProfileCount";
//
@@ -307,7 +279,7 @@ namespace Netch.Forms
//
this.ProfileCountTextBox.Location = new System.Drawing.Point(120, 157);
this.ProfileCountTextBox.Name = "ProfileCountTextBox";
this.ProfileCountTextBox.Size = new System.Drawing.Size(90, 21);
this.ProfileCountTextBox.Size = new System.Drawing.Size(90, 23);
this.ProfileCountTextBox.TabIndex = 6;
this.ProfileCountTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -316,7 +288,7 @@ namespace Netch.Forms
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.Size = new System.Drawing.Size(117, 17);
this.DetectionTickLabel.TabIndex = 7;
this.DetectionTickLabel.Text = "Detection Tick(sec)";
//
@@ -324,7 +296,7 @@ namespace Netch.Forms
//
this.DetectionTickTextBox.Location = new System.Drawing.Point(366, 157);
this.DetectionTickTextBox.Name = "DetectionTickTextBox";
this.DetectionTickTextBox.Size = new System.Drawing.Size(68, 21);
this.DetectionTickTextBox.Size = new System.Drawing.Size(68, 23);
this.DetectionTickTextBox.TabIndex = 8;
this.DetectionTickTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -333,7 +305,7 @@ namespace Netch.Forms
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.Size = new System.Drawing.Size(126, 17);
this.StartedPingLabel.TabIndex = 9;
this.StartedPingLabel.Text = "Delay test after start";
//
@@ -341,7 +313,7 @@ namespace Netch.Forms
//
this.StartedPingIntervalTextBox.Location = new System.Drawing.Point(177, 184);
this.StartedPingIntervalTextBox.Name = "StartedPingIntervalTextBox";
this.StartedPingIntervalTextBox.Size = new System.Drawing.Size(68, 21);
this.StartedPingIntervalTextBox.Size = new System.Drawing.Size(68, 23);
this.StartedPingIntervalTextBox.TabIndex = 10;
this.StartedPingIntervalTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -350,7 +322,7 @@ namespace Netch.Forms
this.STUNServerLabel.AutoSize = true;
this.STUNServerLabel.Location = new System.Drawing.Point(12, 216);
this.STUNServerLabel.Name = "STUNServerLabel";
this.STUNServerLabel.Size = new System.Drawing.Size(71, 12);
this.STUNServerLabel.Size = new System.Drawing.Size(82, 17);
this.STUNServerLabel.TabIndex = 11;
this.STUNServerLabel.Text = "STUN Server";
//
@@ -359,32 +331,15 @@ namespace Netch.Forms
this.STUN_ServerComboBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
this.STUN_ServerComboBox.Location = new System.Drawing.Point(120, 213);
this.STUN_ServerComboBox.Name = "STUN_ServerComboBox";
this.STUN_ServerComboBox.Size = new System.Drawing.Size(314, 20);
this.STUN_ServerComboBox.Size = new System.Drawing.Size(314, 25);
this.STUN_ServerComboBox.TabIndex = 12;
//
// AclLabel
//
this.AclLabel.AutoSize = true;
this.AclLabel.Location = new System.Drawing.Point(12, 248);
this.AclLabel.Name = "AclLabel";
this.AclLabel.Size = new System.Drawing.Size(65, 12);
this.AclLabel.TabIndex = 13;
this.AclLabel.Text = "Custom ACL";
//
// AclAddrTextBox
//
this.AclAddrTextBox.Location = new System.Drawing.Point(120, 245);
this.AclAddrTextBox.Name = "AclAddrTextBox";
this.AclAddrTextBox.Size = new System.Drawing.Size(314, 21);
this.AclAddrTextBox.TabIndex = 14;
this.AclAddrTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// LanguageLabel
//
this.LanguageLabel.AutoSize = true;
this.LanguageLabel.Location = new System.Drawing.Point(12, 277);
this.LanguageLabel.Location = new System.Drawing.Point(12, 254);
this.LanguageLabel.Name = "LanguageLabel";
this.LanguageLabel.Size = new System.Drawing.Size(53, 12);
this.LanguageLabel.Size = new System.Drawing.Size(65, 17);
this.LanguageLabel.TabIndex = 15;
this.LanguageLabel.Text = "Language";
//
@@ -392,9 +347,9 @@ namespace Netch.Forms
//
this.LanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.LanguageComboBox.FormattingEnabled = true;
this.LanguageComboBox.Location = new System.Drawing.Point(120, 274);
this.LanguageComboBox.Location = new System.Drawing.Point(120, 251);
this.LanguageComboBox.Name = "LanguageComboBox";
this.LanguageComboBox.Size = new System.Drawing.Size(121, 20);
this.LanguageComboBox.Size = new System.Drawing.Size(121, 25);
this.LanguageComboBox.TabIndex = 16;
//
// NFTabPage
@@ -403,10 +358,10 @@ namespace Netch.Forms
this.NFTabPage.Controls.Add(this.groupBox1);
this.NFTabPage.Controls.Add(this.RedirectorSSCheckBox);
this.NFTabPage.Controls.Add(this.ChildProcessHandleCheckBox);
this.NFTabPage.Location = new System.Drawing.Point(4, 25);
this.NFTabPage.Location = new System.Drawing.Point(4, 29);
this.NFTabPage.Name = "NFTabPage";
this.NFTabPage.Padding = new System.Windows.Forms.Padding(3);
this.NFTabPage.Size = new System.Drawing.Size(461, 325);
this.NFTabPage.Size = new System.Drawing.Size(461, 321);
this.NFTabPage.TabIndex = 1;
this.NFTabPage.Text = "Process Mode";
//
@@ -414,12 +369,10 @@ namespace Netch.Forms
//
this.groupBox1.Controls.Add(this.ProcessProxyProtocolLabel);
this.groupBox1.Controls.Add(this.ProcessProxyProtocolComboBox);
this.groupBox1.Controls.Add(this.DNSRedirectorCheckBox);
this.groupBox1.Controls.Add(this.RDRDNSLabel);
this.groupBox1.Controls.Add(this.RDRDNSTextBox);
this.groupBox1.Controls.Add(this.ICMPRedirectorCheckBox);
this.groupBox1.Controls.Add(this.RDRICMPLabel);
this.groupBox1.Controls.Add(this.ModifiedICMPTextBox);
this.groupBox1.Controls.Add(this.DNSHijackCheckBox);
this.groupBox1.Controls.Add(this.DNSHijackHostTextBox);
this.groupBox1.Controls.Add(this.ICMPHijackCheckBox);
this.groupBox1.Controls.Add(this.ICMPHijackHostTextBox);
this.groupBox1.Location = new System.Drawing.Point(5, 6);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(450, 117);
@@ -431,7 +384,7 @@ namespace Netch.Forms
this.ProcessProxyProtocolLabel.AutoSize = true;
this.ProcessProxyProtocolLabel.Location = new System.Drawing.Point(23, 21);
this.ProcessProxyProtocolLabel.Name = "ProcessProxyProtocolLabel";
this.ProcessProxyProtocolLabel.Size = new System.Drawing.Size(89, 12);
this.ProcessProxyProtocolLabel.Size = new System.Drawing.Size(93, 17);
this.ProcessProxyProtocolLabel.TabIndex = 0;
this.ProcessProxyProtocolLabel.Text = "Proxy Protocol";
//
@@ -441,71 +394,55 @@ namespace Netch.Forms
this.ProcessProxyProtocolComboBox.FormattingEnabled = true;
this.ProcessProxyProtocolComboBox.Location = new System.Drawing.Point(118, 16);
this.ProcessProxyProtocolComboBox.Name = "ProcessProxyProtocolComboBox";
this.ProcessProxyProtocolComboBox.Size = new System.Drawing.Size(191, 20);
this.ProcessProxyProtocolComboBox.Size = new System.Drawing.Size(191, 25);
this.ProcessProxyProtocolComboBox.TabIndex = 1;
//
// DNSRedirectorCheckBox
// DNSHijackCheckBox
//
this.DNSRedirectorCheckBox.AutoSize = true;
this.DNSRedirectorCheckBox.Location = new System.Drawing.Point(6, 51);
this.DNSRedirectorCheckBox.Name = "DNSRedirectorCheckBox";
this.DNSRedirectorCheckBox.Size = new System.Drawing.Size(108, 16);
this.DNSRedirectorCheckBox.TabIndex = 2;
this.DNSRedirectorCheckBox.Text = "DNS Redirector";
this.DNSRedirectorCheckBox.UseVisualStyleBackColor = true;
this.DNSHijackCheckBox.AutoSize = true;
this.DNSHijackCheckBox.Location = new System.Drawing.Point(6, 51);
this.DNSHijackCheckBox.Name = "DNSHijackCheckBox";
this.DNSHijackCheckBox.Size = new System.Drawing.Size(196, 21);
this.DNSHijackCheckBox.TabIndex = 2;
this.DNSHijackCheckBox.Text = "Handle process\'s DNS Hijack";
this.DNSHijackCheckBox.UseVisualStyleBackColor = true;
//
// RDRDNSLabel
// DNSHijackHostTextBox
//
this.RDRDNSLabel.AutoSize = true;
this.RDRDNSLabel.Location = new System.Drawing.Point(224, 52);
this.RDRDNSLabel.Name = "RDRDNSLabel";
this.RDRDNSLabel.Size = new System.Drawing.Size(23, 12);
this.RDRDNSLabel.TabIndex = 3;
this.RDRDNSLabel.Text = "DNS";
this.DNSHijackHostTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.DNSHijackCheckBox, "Checked", true));
this.DNSHijackHostTextBox.Location = new System.Drawing.Point(253, 46);
this.DNSHijackHostTextBox.Name = "DNSHijackHostTextBox";
this.DNSHijackHostTextBox.Size = new System.Drawing.Size(191, 23);
this.DNSHijackHostTextBox.TabIndex = 4;
this.DNSHijackHostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// RDRDNSTextBox
// ICMPHijackCheckBox
//
this.RDRDNSTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.DNSRedirectorCheckBox, "Checked", true));
this.RDRDNSTextBox.Location = new System.Drawing.Point(253, 46);
this.RDRDNSTextBox.Name = "RDRDNSTextBox";
this.RDRDNSTextBox.Size = new System.Drawing.Size(191, 21);
this.RDRDNSTextBox.TabIndex = 4;
this.RDRDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.ICMPHijackCheckBox.AutoSize = true;
this.ICMPHijackCheckBox.Enabled = false;
this.ICMPHijackCheckBox.Location = new System.Drawing.Point(6, 81);
this.ICMPHijackCheckBox.Name = "ICMPHijackCheckBox";
this.ICMPHijackCheckBox.Size = new System.Drawing.Size(139, 21);
this.ICMPHijackCheckBox.TabIndex = 5;
this.ICMPHijackCheckBox.Text = "Global ICMP Hijack";
this.ICMPHijackCheckBox.UseVisualStyleBackColor = true;
//
// ICMPRedirectorCheckBox
// ICMPHijackHostTextBox
//
this.ICMPRedirectorCheckBox.AutoSize = true;
this.ICMPRedirectorCheckBox.Location = new System.Drawing.Point(6, 81);
this.ICMPRedirectorCheckBox.Name = "ICMPRedirectorCheckBox";
this.ICMPRedirectorCheckBox.Size = new System.Drawing.Size(114, 16);
this.ICMPRedirectorCheckBox.TabIndex = 5;
this.ICMPRedirectorCheckBox.Text = "ICMP Redirector";
this.ICMPRedirectorCheckBox.UseVisualStyleBackColor = true;
//
// RDRICMPLabel
//
this.RDRICMPLabel.AutoSize = true;
this.RDRICMPLabel.Location = new System.Drawing.Point(218, 81);
this.RDRICMPLabel.Name = "RDRICMPLabel";
this.RDRICMPLabel.Size = new System.Drawing.Size(29, 12);
this.RDRICMPLabel.TabIndex = 6;
this.RDRICMPLabel.Text = "ICMP";
//
// ModifiedICMPTextBox
//
this.ModifiedICMPTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.ICMPRedirectorCheckBox, "Checked", true));
this.ModifiedICMPTextBox.Location = new System.Drawing.Point(253, 78);
this.ModifiedICMPTextBox.Name = "ModifiedICMPTextBox";
this.ModifiedICMPTextBox.Size = new System.Drawing.Size(191, 21);
this.ModifiedICMPTextBox.TabIndex = 7;
this.ModifiedICMPTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.ICMPHijackHostTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.ICMPHijackCheckBox, "Checked", true));
this.ICMPHijackHostTextBox.Enabled = false;
this.ICMPHijackHostTextBox.Location = new System.Drawing.Point(253, 78);
this.ICMPHijackHostTextBox.Name = "ICMPHijackHostTextBox";
this.ICMPHijackHostTextBox.Size = new System.Drawing.Size(191, 23);
this.ICMPHijackHostTextBox.TabIndex = 7;
this.ICMPHijackHostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// RedirectorSSCheckBox
//
this.RedirectorSSCheckBox.AutoSize = true;
this.RedirectorSSCheckBox.Location = new System.Drawing.Point(11, 129);
this.RedirectorSSCheckBox.Name = "RedirectorSSCheckBox";
this.RedirectorSSCheckBox.Size = new System.Drawing.Size(102, 16);
this.RedirectorSSCheckBox.Size = new System.Drawing.Size(106, 21);
this.RedirectorSSCheckBox.TabIndex = 1;
this.RedirectorSSCheckBox.Text = "Redirector SS";
this.RedirectorSSCheckBox.UseVisualStyleBackColor = true;
@@ -513,51 +450,50 @@ namespace Netch.Forms
// ChildProcessHandleCheckBox
//
this.ChildProcessHandleCheckBox.AutoSize = true;
this.ChildProcessHandleCheckBox.Enabled = false;
this.ChildProcessHandleCheckBox.Location = new System.Drawing.Point(11, 151);
this.ChildProcessHandleCheckBox.Name = "ChildProcessHandleCheckBox";
this.ChildProcessHandleCheckBox.Size = new System.Drawing.Size(144, 16);
this.ChildProcessHandleCheckBox.Size = new System.Drawing.Size(150, 21);
this.ChildProcessHandleCheckBox.TabIndex = 2;
this.ChildProcessHandleCheckBox.Text = "Child Process Handle";
this.ChildProcessHandleCheckBox.UseVisualStyleBackColor = true;
//
// TAPTabPage
// WinTUNTabPage
//
this.TAPTabPage.BackColor = System.Drawing.SystemColors.ButtonFace;
this.TAPTabPage.Controls.Add(this.TUNTAPGroupBox);
this.TAPTabPage.Controls.Add(this.GlobalBypassIPsButton);
this.TAPTabPage.Location = new System.Drawing.Point(4, 25);
this.TAPTabPage.Name = "TAPTabPage";
this.TAPTabPage.Padding = new System.Windows.Forms.Padding(3);
this.TAPTabPage.Size = new System.Drawing.Size(461, 325);
this.TAPTabPage.TabIndex = 2;
this.TAPTabPage.Text = "TUN/TAP";
this.WinTUNTabPage.BackColor = System.Drawing.SystemColors.ButtonFace;
this.WinTUNTabPage.Controls.Add(this.WinTUNGroupBox);
this.WinTUNTabPage.Controls.Add(this.GlobalBypassIPsButton);
this.WinTUNTabPage.Location = new System.Drawing.Point(4, 29);
this.WinTUNTabPage.Name = "WinTUNTabPage";
this.WinTUNTabPage.Padding = new System.Windows.Forms.Padding(3);
this.WinTUNTabPage.Size = new System.Drawing.Size(461, 321);
this.WinTUNTabPage.TabIndex = 2;
this.WinTUNTabPage.Text = "WinTUN";
//
// TUNTAPGroupBox
// WinTUNGroupBox
//
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPAddressLabel);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPAddressTextBox);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPNetmaskLabel);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPNetmaskTextBox);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPGatewayLabel);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPGatewayTextBox);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPDNSLabel);
this.TUNTAPGroupBox.Controls.Add(this.TUNTAPDNSTextBox);
this.TUNTAPGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
this.TUNTAPGroupBox.Controls.Add(this.ProxyDNSCheckBox);
this.TUNTAPGroupBox.Controls.Add(this.UseFakeDNSCheckBox);
this.TUNTAPGroupBox.Location = new System.Drawing.Point(6, 6);
this.TUNTAPGroupBox.Name = "TUNTAPGroupBox";
this.TUNTAPGroupBox.Size = new System.Drawing.Size(420, 187);
this.TUNTAPGroupBox.TabIndex = 0;
this.TUNTAPGroupBox.TabStop = false;
this.TUNTAPGroupBox.Text = "TUN/TAP";
this.WinTUNGroupBox.Controls.Add(this.TUNTAPAddressLabel);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPAddressTextBox);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPNetmaskLabel);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPNetmaskTextBox);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPGatewayLabel);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPGatewayTextBox);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPDNSLabel);
this.WinTUNGroupBox.Controls.Add(this.TUNTAPDNSTextBox);
this.WinTUNGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
this.WinTUNGroupBox.Controls.Add(this.ProxyDNSCheckBox);
this.WinTUNGroupBox.Location = new System.Drawing.Point(6, 6);
this.WinTUNGroupBox.Name = "WinTUNGroupBox";
this.WinTUNGroupBox.Size = new System.Drawing.Size(420, 175);
this.WinTUNGroupBox.TabIndex = 0;
this.WinTUNGroupBox.TabStop = false;
//
// TUNTAPAddressLabel
//
this.TUNTAPAddressLabel.AutoSize = true;
this.TUNTAPAddressLabel.Location = new System.Drawing.Point(9, 25);
this.TUNTAPAddressLabel.Name = "TUNTAPAddressLabel";
this.TUNTAPAddressLabel.Size = new System.Drawing.Size(47, 12);
this.TUNTAPAddressLabel.Size = new System.Drawing.Size(56, 17);
this.TUNTAPAddressLabel.TabIndex = 0;
this.TUNTAPAddressLabel.Text = "Address";
//
@@ -565,7 +501,7 @@ namespace Netch.Forms
//
this.TUNTAPAddressTextBox.Location = new System.Drawing.Point(120, 22);
this.TUNTAPAddressTextBox.Name = "TUNTAPAddressTextBox";
this.TUNTAPAddressTextBox.Size = new System.Drawing.Size(294, 21);
this.TUNTAPAddressTextBox.Size = new System.Drawing.Size(294, 23);
this.TUNTAPAddressTextBox.TabIndex = 1;
this.TUNTAPAddressTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -574,7 +510,7 @@ namespace Netch.Forms
this.TUNTAPNetmaskLabel.AutoSize = true;
this.TUNTAPNetmaskLabel.Location = new System.Drawing.Point(9, 54);
this.TUNTAPNetmaskLabel.Name = "TUNTAPNetmaskLabel";
this.TUNTAPNetmaskLabel.Size = new System.Drawing.Size(47, 12);
this.TUNTAPNetmaskLabel.Size = new System.Drawing.Size(60, 17);
this.TUNTAPNetmaskLabel.TabIndex = 2;
this.TUNTAPNetmaskLabel.Text = "Netmask";
//
@@ -582,7 +518,7 @@ namespace Netch.Forms
//
this.TUNTAPNetmaskTextBox.Location = new System.Drawing.Point(120, 51);
this.TUNTAPNetmaskTextBox.Name = "TUNTAPNetmaskTextBox";
this.TUNTAPNetmaskTextBox.Size = new System.Drawing.Size(294, 21);
this.TUNTAPNetmaskTextBox.Size = new System.Drawing.Size(294, 23);
this.TUNTAPNetmaskTextBox.TabIndex = 3;
this.TUNTAPNetmaskTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -591,7 +527,7 @@ namespace Netch.Forms
this.TUNTAPGatewayLabel.AutoSize = true;
this.TUNTAPGatewayLabel.Location = new System.Drawing.Point(9, 83);
this.TUNTAPGatewayLabel.Name = "TUNTAPGatewayLabel";
this.TUNTAPGatewayLabel.Size = new System.Drawing.Size(47, 12);
this.TUNTAPGatewayLabel.Size = new System.Drawing.Size(57, 17);
this.TUNTAPGatewayLabel.TabIndex = 4;
this.TUNTAPGatewayLabel.Text = "Gateway";
//
@@ -599,7 +535,7 @@ namespace Netch.Forms
//
this.TUNTAPGatewayTextBox.Location = new System.Drawing.Point(120, 80);
this.TUNTAPGatewayTextBox.Name = "TUNTAPGatewayTextBox";
this.TUNTAPGatewayTextBox.Size = new System.Drawing.Size(294, 21);
this.TUNTAPGatewayTextBox.Size = new System.Drawing.Size(294, 23);
this.TUNTAPGatewayTextBox.TabIndex = 5;
this.TUNTAPGatewayTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -608,16 +544,16 @@ namespace Netch.Forms
this.TUNTAPDNSLabel.AutoSize = true;
this.TUNTAPDNSLabel.Location = new System.Drawing.Point(9, 112);
this.TUNTAPDNSLabel.Name = "TUNTAPDNSLabel";
this.TUNTAPDNSLabel.Size = new System.Drawing.Size(23, 12);
this.TUNTAPDNSLabel.Size = new System.Drawing.Size(73, 17);
this.TUNTAPDNSLabel.TabIndex = 6;
this.TUNTAPDNSLabel.Text = "DNS";
this.TUNTAPDNSLabel.Text = "DNS Hijack";
//
// TUNTAPDNSTextBox
//
this.TUNTAPDNSTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.UseCustomDNSCheckBox, "Checked", true));
this.TUNTAPDNSTextBox.Location = new System.Drawing.Point(120, 110);
this.TUNTAPDNSTextBox.Name = "TUNTAPDNSTextBox";
this.TUNTAPDNSTextBox.Size = new System.Drawing.Size(294, 21);
this.TUNTAPDNSTextBox.Size = new System.Drawing.Size(294, 23);
this.TUNTAPDNSTextBox.TabIndex = 7;
this.TUNTAPDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -626,7 +562,7 @@ namespace Netch.Forms
this.UseCustomDNSCheckBox.AutoSize = true;
this.UseCustomDNSCheckBox.Location = new System.Drawing.Point(10, 139);
this.UseCustomDNSCheckBox.Name = "UseCustomDNSCheckBox";
this.UseCustomDNSCheckBox.Size = new System.Drawing.Size(108, 16);
this.UseCustomDNSCheckBox.Size = new System.Drawing.Size(127, 21);
this.UseCustomDNSCheckBox.TabIndex = 8;
this.UseCustomDNSCheckBox.Text = "Use Custom DNS";
this.UseCustomDNSCheckBox.UseVisualStyleBackColor = true;
@@ -637,22 +573,11 @@ namespace Netch.Forms
this.ProxyDNSCheckBox.AutoSize = true;
this.ProxyDNSCheckBox.Location = new System.Drawing.Point(175, 139);
this.ProxyDNSCheckBox.Name = "ProxyDNSCheckBox";
this.ProxyDNSCheckBox.Size = new System.Drawing.Size(216, 16);
this.ProxyDNSCheckBox.Size = new System.Drawing.Size(228, 21);
this.ProxyDNSCheckBox.TabIndex = 9;
this.ProxyDNSCheckBox.Text = "Proxy DNS in Proxy Rule IPs Mode";
this.ProxyDNSCheckBox.UseVisualStyleBackColor = true;
//
// UseFakeDNSCheckBox
//
this.UseFakeDNSCheckBox.AutoSize = true;
this.UseFakeDNSCheckBox.Location = new System.Drawing.Point(10, 160);
this.UseFakeDNSCheckBox.Name = "UseFakeDNSCheckBox";
this.UseFakeDNSCheckBox.Size = new System.Drawing.Size(96, 16);
this.UseFakeDNSCheckBox.TabIndex = 10;
this.UseFakeDNSCheckBox.Text = "Use Fake DNS";
this.UseFakeDNSCheckBox.UseVisualStyleBackColor = true;
this.UseFakeDNSCheckBox.Visible = false;
//
// GlobalBypassIPsButton
//
this.GlobalBypassIPsButton.Location = new System.Drawing.Point(6, 199);
@@ -670,10 +595,10 @@ namespace Netch.Forms
this.v2rayTabPage.Controls.Add(this.TLSAllowInsecureCheckBox);
this.v2rayTabPage.Controls.Add(this.UseMuxCheckBox);
this.v2rayTabPage.Controls.Add(this.KCPGroupBox);
this.v2rayTabPage.Location = new System.Drawing.Point(4, 25);
this.v2rayTabPage.Location = new System.Drawing.Point(4, 29);
this.v2rayTabPage.Name = "v2rayTabPage";
this.v2rayTabPage.Padding = new System.Windows.Forms.Padding(3);
this.v2rayTabPage.Size = new System.Drawing.Size(461, 325);
this.v2rayTabPage.Size = new System.Drawing.Size(461, 321);
this.v2rayTabPage.TabIndex = 3;
this.v2rayTabPage.Text = "V2Ray";
//
@@ -682,7 +607,7 @@ namespace Netch.Forms
this.XrayConeCheckBox.AutoSize = true;
this.XrayConeCheckBox.Location = new System.Drawing.Point(6, 15);
this.XrayConeCheckBox.Name = "XrayConeCheckBox";
this.XrayConeCheckBox.Size = new System.Drawing.Size(336, 16);
this.XrayConeCheckBox.Size = new System.Drawing.Size(340, 21);
this.XrayConeCheckBox.TabIndex = 0;
this.XrayConeCheckBox.Text = "FullCone Support (Required Server Xray-core v1.3.0+)";
this.XrayConeCheckBox.UseVisualStyleBackColor = true;
@@ -692,7 +617,7 @@ namespace Netch.Forms
this.TLSAllowInsecureCheckBox.AutoSize = true;
this.TLSAllowInsecureCheckBox.Location = new System.Drawing.Point(6, 42);
this.TLSAllowInsecureCheckBox.Name = "TLSAllowInsecureCheckBox";
this.TLSAllowInsecureCheckBox.Size = new System.Drawing.Size(126, 16);
this.TLSAllowInsecureCheckBox.Size = new System.Drawing.Size(131, 21);
this.TLSAllowInsecureCheckBox.TabIndex = 1;
this.TLSAllowInsecureCheckBox.Text = "TLS AllowInsecure";
this.TLSAllowInsecureCheckBox.UseVisualStyleBackColor = true;
@@ -702,7 +627,7 @@ namespace Netch.Forms
this.UseMuxCheckBox.AutoSize = true;
this.UseMuxCheckBox.Location = new System.Drawing.Point(148, 42);
this.UseMuxCheckBox.Name = "UseMuxCheckBox";
this.UseMuxCheckBox.Size = new System.Drawing.Size(66, 16);
this.UseMuxCheckBox.Size = new System.Drawing.Size(78, 21);
this.UseMuxCheckBox.TabIndex = 2;
this.UseMuxCheckBox.Text = "Use Mux";
this.UseMuxCheckBox.UseVisualStyleBackColor = true;
@@ -734,7 +659,7 @@ namespace Netch.Forms
this.mtuLabel.AutoSize = true;
this.mtuLabel.Location = new System.Drawing.Point(6, 26);
this.mtuLabel.Name = "mtuLabel";
this.mtuLabel.Size = new System.Drawing.Size(23, 12);
this.mtuLabel.Size = new System.Drawing.Size(30, 17);
this.mtuLabel.TabIndex = 0;
this.mtuLabel.Text = "mtu";
//
@@ -742,16 +667,16 @@ namespace Netch.Forms
//
this.mtuTextBox.Location = new System.Drawing.Point(103, 17);
this.mtuTextBox.Name = "mtuTextBox";
this.mtuTextBox.Size = new System.Drawing.Size(90, 21);
this.mtuTextBox.Size = new System.Drawing.Size(90, 23);
this.mtuTextBox.TabIndex = 1;
this.mtuTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// ttiLabel
//
this.ttiLabel.AutoSize = true;
this.ttiLabel.Location = new System.Drawing.Point(224, 26);
this.ttiLabel.Location = new System.Drawing.Point(216, 26);
this.ttiLabel.Name = "ttiLabel";
this.ttiLabel.Size = new System.Drawing.Size(23, 12);
this.ttiLabel.Size = new System.Drawing.Size(19, 17);
this.ttiLabel.TabIndex = 2;
this.ttiLabel.Text = "tti";
//
@@ -759,7 +684,7 @@ namespace Netch.Forms
//
this.ttiTextBox.Location = new System.Drawing.Point(331, 17);
this.ttiTextBox.Name = "ttiTextBox";
this.ttiTextBox.Size = new System.Drawing.Size(90, 21);
this.ttiTextBox.Size = new System.Drawing.Size(90, 23);
this.ttiTextBox.TabIndex = 3;
this.ttiTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -768,7 +693,7 @@ namespace Netch.Forms
this.uplinkCapacityLabel.AutoSize = true;
this.uplinkCapacityLabel.Location = new System.Drawing.Point(6, 68);
this.uplinkCapacityLabel.Name = "uplinkCapacityLabel";
this.uplinkCapacityLabel.Size = new System.Drawing.Size(89, 12);
this.uplinkCapacityLabel.Size = new System.Drawing.Size(92, 17);
this.uplinkCapacityLabel.TabIndex = 4;
this.uplinkCapacityLabel.Text = "uplinkCapacity";
//
@@ -776,16 +701,16 @@ namespace Netch.Forms
//
this.uplinkCapacityTextBox.Location = new System.Drawing.Point(103, 59);
this.uplinkCapacityTextBox.Name = "uplinkCapacityTextBox";
this.uplinkCapacityTextBox.Size = new System.Drawing.Size(90, 21);
this.uplinkCapacityTextBox.Size = new System.Drawing.Size(90, 23);
this.uplinkCapacityTextBox.TabIndex = 5;
this.uplinkCapacityTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// downlinkCapacityLabel
//
this.downlinkCapacityLabel.AutoSize = true;
this.downlinkCapacityLabel.Location = new System.Drawing.Point(224, 68);
this.downlinkCapacityLabel.Location = new System.Drawing.Point(216, 68);
this.downlinkCapacityLabel.Name = "downlinkCapacityLabel";
this.downlinkCapacityLabel.Size = new System.Drawing.Size(101, 12);
this.downlinkCapacityLabel.Size = new System.Drawing.Size(109, 17);
this.downlinkCapacityLabel.TabIndex = 6;
this.downlinkCapacityLabel.Text = "downlinkCapacity";
//
@@ -793,7 +718,7 @@ namespace Netch.Forms
//
this.downlinkCapacityTextBox.Location = new System.Drawing.Point(331, 65);
this.downlinkCapacityTextBox.Name = "downlinkCapacityTextBox";
this.downlinkCapacityTextBox.Size = new System.Drawing.Size(90, 21);
this.downlinkCapacityTextBox.Size = new System.Drawing.Size(90, 23);
this.downlinkCapacityTextBox.TabIndex = 7;
this.downlinkCapacityTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -802,7 +727,7 @@ namespace Netch.Forms
this.readBufferSizeLabel.AutoSize = true;
this.readBufferSizeLabel.Location = new System.Drawing.Point(6, 109);
this.readBufferSizeLabel.Name = "readBufferSizeLabel";
this.readBufferSizeLabel.Size = new System.Drawing.Size(89, 12);
this.readBufferSizeLabel.Size = new System.Drawing.Size(93, 17);
this.readBufferSizeLabel.TabIndex = 8;
this.readBufferSizeLabel.Text = "readBufferSize";
//
@@ -810,16 +735,16 @@ namespace Netch.Forms
//
this.readBufferSizeTextBox.Location = new System.Drawing.Point(103, 100);
this.readBufferSizeTextBox.Name = "readBufferSizeTextBox";
this.readBufferSizeTextBox.Size = new System.Drawing.Size(90, 21);
this.readBufferSizeTextBox.Size = new System.Drawing.Size(90, 23);
this.readBufferSizeTextBox.TabIndex = 9;
this.readBufferSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// writeBufferSizeLabel
//
this.writeBufferSizeLabel.AutoSize = true;
this.writeBufferSizeLabel.Location = new System.Drawing.Point(224, 109);
this.writeBufferSizeLabel.Location = new System.Drawing.Point(216, 109);
this.writeBufferSizeLabel.Name = "writeBufferSizeLabel";
this.writeBufferSizeLabel.Size = new System.Drawing.Size(95, 12);
this.writeBufferSizeLabel.Size = new System.Drawing.Size(94, 17);
this.writeBufferSizeLabel.TabIndex = 10;
this.writeBufferSizeLabel.Text = "writeBufferSize";
//
@@ -827,7 +752,7 @@ namespace Netch.Forms
//
this.writeBufferSizeTextBox.Location = new System.Drawing.Point(331, 106);
this.writeBufferSizeTextBox.Name = "writeBufferSizeTextBox";
this.writeBufferSizeTextBox.Size = new System.Drawing.Size(90, 21);
this.writeBufferSizeTextBox.Size = new System.Drawing.Size(90, 23);
this.writeBufferSizeTextBox.TabIndex = 11;
this.writeBufferSizeTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -836,7 +761,7 @@ namespace Netch.Forms
this.congestionCheckBox.AutoSize = true;
this.congestionCheckBox.Location = new System.Drawing.Point(8, 139);
this.congestionCheckBox.Name = "congestionCheckBox";
this.congestionCheckBox.Size = new System.Drawing.Size(84, 16);
this.congestionCheckBox.Size = new System.Drawing.Size(91, 21);
this.congestionCheckBox.TabIndex = 12;
this.congestionCheckBox.Text = "congestion";
this.congestionCheckBox.UseVisualStyleBackColor = true;
@@ -852,10 +777,10 @@ namespace Netch.Forms
this.OtherTabPage.Controls.Add(this.CheckUpdateWhenOpenedCheckBox);
this.OtherTabPage.Controls.Add(this.CheckBetaUpdateCheckBox);
this.OtherTabPage.Controls.Add(this.UpdateServersWhenOpenedCheckBox);
this.OtherTabPage.Location = new System.Drawing.Point(4, 25);
this.OtherTabPage.Location = new System.Drawing.Point(4, 29);
this.OtherTabPage.Name = "OtherTabPage";
this.OtherTabPage.Padding = new System.Windows.Forms.Padding(3);
this.OtherTabPage.Size = new System.Drawing.Size(461, 325);
this.OtherTabPage.Size = new System.Drawing.Size(461, 321);
this.OtherTabPage.TabIndex = 4;
this.OtherTabPage.Text = "Others";
//
@@ -864,7 +789,7 @@ namespace Netch.Forms
this.ExitWhenClosedCheckBox.AutoSize = true;
this.ExitWhenClosedCheckBox.Location = new System.Drawing.Point(6, 6);
this.ExitWhenClosedCheckBox.Name = "ExitWhenClosedCheckBox";
this.ExitWhenClosedCheckBox.Size = new System.Drawing.Size(120, 16);
this.ExitWhenClosedCheckBox.Size = new System.Drawing.Size(123, 21);
this.ExitWhenClosedCheckBox.TabIndex = 0;
this.ExitWhenClosedCheckBox.Text = "Exit when closed";
this.ExitWhenClosedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -875,7 +800,7 @@ namespace Netch.Forms
this.StopWhenExitedCheckBox.AutoSize = true;
this.StopWhenExitedCheckBox.Location = new System.Drawing.Point(200, 6);
this.StopWhenExitedCheckBox.Name = "StopWhenExitedCheckBox";
this.StopWhenExitedCheckBox.Size = new System.Drawing.Size(120, 16);
this.StopWhenExitedCheckBox.Size = new System.Drawing.Size(127, 21);
this.StopWhenExitedCheckBox.TabIndex = 1;
this.StopWhenExitedCheckBox.Text = "Stop when exited";
this.StopWhenExitedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -886,7 +811,7 @@ namespace Netch.Forms
this.StartWhenOpenedCheckBox.AutoSize = true;
this.StartWhenOpenedCheckBox.Location = new System.Drawing.Point(6, 28);
this.StartWhenOpenedCheckBox.Name = "StartWhenOpenedCheckBox";
this.StartWhenOpenedCheckBox.Size = new System.Drawing.Size(126, 16);
this.StartWhenOpenedCheckBox.Size = new System.Drawing.Size(137, 21);
this.StartWhenOpenedCheckBox.TabIndex = 2;
this.StartWhenOpenedCheckBox.Text = "Start when opened";
this.StartWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -897,7 +822,7 @@ namespace Netch.Forms
this.MinimizeWhenStartedCheckBox.AutoSize = true;
this.MinimizeWhenStartedCheckBox.Location = new System.Drawing.Point(200, 28);
this.MinimizeWhenStartedCheckBox.Name = "MinimizeWhenStartedCheckBox";
this.MinimizeWhenStartedCheckBox.Size = new System.Drawing.Size(150, 16);
this.MinimizeWhenStartedCheckBox.Size = new System.Drawing.Size(158, 21);
this.MinimizeWhenStartedCheckBox.TabIndex = 3;
this.MinimizeWhenStartedCheckBox.Text = "Minimize when started";
this.MinimizeWhenStartedCheckBox.UseVisualStyleBackColor = true;
@@ -907,7 +832,7 @@ namespace Netch.Forms
this.RunAtStartupCheckBox.AutoSize = true;
this.RunAtStartupCheckBox.Location = new System.Drawing.Point(6, 50);
this.RunAtStartupCheckBox.Name = "RunAtStartupCheckBox";
this.RunAtStartupCheckBox.Size = new System.Drawing.Size(108, 16);
this.RunAtStartupCheckBox.Size = new System.Drawing.Size(109, 21);
this.RunAtStartupCheckBox.TabIndex = 4;
this.RunAtStartupCheckBox.Text = "Run at startup";
this.RunAtStartupCheckBox.UseVisualStyleBackColor = true;
@@ -917,7 +842,7 @@ namespace Netch.Forms
this.CheckUpdateWhenOpenedCheckBox.AutoSize = true;
this.CheckUpdateWhenOpenedCheckBox.Location = new System.Drawing.Point(200, 50);
this.CheckUpdateWhenOpenedCheckBox.Name = "CheckUpdateWhenOpenedCheckBox";
this.CheckUpdateWhenOpenedCheckBox.Size = new System.Drawing.Size(168, 16);
this.CheckUpdateWhenOpenedCheckBox.Size = new System.Drawing.Size(190, 21);
this.CheckUpdateWhenOpenedCheckBox.TabIndex = 5;
this.CheckUpdateWhenOpenedCheckBox.Text = "Check update when opened";
this.CheckUpdateWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -928,7 +853,7 @@ namespace Netch.Forms
this.CheckBetaUpdateCheckBox.AutoSize = true;
this.CheckBetaUpdateCheckBox.Location = new System.Drawing.Point(200, 72);
this.CheckBetaUpdateCheckBox.Name = "CheckBetaUpdateCheckBox";
this.CheckBetaUpdateCheckBox.Size = new System.Drawing.Size(126, 16);
this.CheckBetaUpdateCheckBox.Size = new System.Drawing.Size(137, 21);
this.CheckBetaUpdateCheckBox.TabIndex = 6;
this.CheckBetaUpdateCheckBox.Text = "Check Beta update";
this.CheckBetaUpdateCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -939,7 +864,7 @@ namespace Netch.Forms
this.UpdateServersWhenOpenedCheckBox.AutoSize = true;
this.UpdateServersWhenOpenedCheckBox.Location = new System.Drawing.Point(200, 94);
this.UpdateServersWhenOpenedCheckBox.Name = "UpdateServersWhenOpenedCheckBox";
this.UpdateServersWhenOpenedCheckBox.Size = new System.Drawing.Size(180, 16);
this.UpdateServersWhenOpenedCheckBox.Size = new System.Drawing.Size(200, 21);
this.UpdateServersWhenOpenedCheckBox.TabIndex = 7;
this.UpdateServersWhenOpenedCheckBox.Text = "Update Servers when opened";
this.UpdateServersWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
@@ -953,10 +878,10 @@ namespace Netch.Forms
this.AioDNSTabPage.Controls.Add(this.ChinaDNSTextBox);
this.AioDNSTabPage.Controls.Add(this.OtherDNSLabel);
this.AioDNSTabPage.Controls.Add(this.OtherDNSTextBox);
this.AioDNSTabPage.Location = new System.Drawing.Point(4, 25);
this.AioDNSTabPage.Location = new System.Drawing.Point(4, 29);
this.AioDNSTabPage.Name = "AioDNSTabPage";
this.AioDNSTabPage.Padding = new System.Windows.Forms.Padding(3);
this.AioDNSTabPage.Size = new System.Drawing.Size(461, 325);
this.AioDNSTabPage.Size = new System.Drawing.Size(461, 321);
this.AioDNSTabPage.TabIndex = 5;
this.AioDNSTabPage.Text = "AioDNS";
this.AioDNSTabPage.UseVisualStyleBackColor = true;
@@ -964,51 +889,51 @@ namespace Netch.Forms
// AioDNSRuleRuleLabel
//
this.AioDNSRuleRuleLabel.AutoSize = true;
this.AioDNSRuleRuleLabel.Location = new System.Drawing.Point(16, 27);
this.AioDNSRuleRuleLabel.Location = new System.Drawing.Point(16, 30);
this.AioDNSRuleRuleLabel.Name = "AioDNSRuleRuleLabel";
this.AioDNSRuleRuleLabel.Size = new System.Drawing.Size(59, 12);
this.AioDNSRuleRuleLabel.Size = new System.Drawing.Size(56, 17);
this.AioDNSRuleRuleLabel.TabIndex = 0;
this.AioDNSRuleRuleLabel.Text = "Rule File";
//
// AioDNSRulePathTextBox
//
this.AioDNSRulePathTextBox.Enabled = false;
this.AioDNSRulePathTextBox.Location = new System.Drawing.Point(147, 24);
this.AioDNSRulePathTextBox.Location = new System.Drawing.Point(150, 30);
this.AioDNSRulePathTextBox.Name = "AioDNSRulePathTextBox";
this.AioDNSRulePathTextBox.Size = new System.Drawing.Size(201, 21);
this.AioDNSRulePathTextBox.Size = new System.Drawing.Size(201, 23);
this.AioDNSRulePathTextBox.TabIndex = 1;
//
// ChinaDNSLabel
//
this.ChinaDNSLabel.AutoSize = true;
this.ChinaDNSLabel.Location = new System.Drawing.Point(16, 64);
this.ChinaDNSLabel.Location = new System.Drawing.Point(16, 70);
this.ChinaDNSLabel.Name = "ChinaDNSLabel";
this.ChinaDNSLabel.Size = new System.Drawing.Size(59, 12);
this.ChinaDNSLabel.Size = new System.Drawing.Size(70, 17);
this.ChinaDNSLabel.TabIndex = 2;
this.ChinaDNSLabel.Text = "China DNS";
//
// ChinaDNSTextBox
//
this.ChinaDNSTextBox.Location = new System.Drawing.Point(147, 61);
this.ChinaDNSTextBox.Location = new System.Drawing.Point(150, 70);
this.ChinaDNSTextBox.Name = "ChinaDNSTextBox";
this.ChinaDNSTextBox.Size = new System.Drawing.Size(201, 21);
this.ChinaDNSTextBox.Size = new System.Drawing.Size(201, 23);
this.ChinaDNSTextBox.TabIndex = 3;
this.ChinaDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// OtherDNSLabel
//
this.OtherDNSLabel.AutoSize = true;
this.OtherDNSLabel.Location = new System.Drawing.Point(16, 103);
this.OtherDNSLabel.Location = new System.Drawing.Point(16, 110);
this.OtherDNSLabel.Name = "OtherDNSLabel";
this.OtherDNSLabel.Size = new System.Drawing.Size(59, 12);
this.OtherDNSLabel.Size = new System.Drawing.Size(71, 17);
this.OtherDNSLabel.TabIndex = 4;
this.OtherDNSLabel.Text = "Other DNS";
//
// OtherDNSTextBox
//
this.OtherDNSTextBox.Location = new System.Drawing.Point(147, 100);
this.OtherDNSTextBox.Location = new System.Drawing.Point(150, 110);
this.OtherDNSTextBox.Name = "OtherDNSTextBox";
this.OtherDNSTextBox.Size = new System.Drawing.Size(201, 21);
this.OtherDNSTextBox.Size = new System.Drawing.Size(201, 23);
this.OtherDNSTextBox.TabIndex = 5;
this.OtherDNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
@@ -1059,9 +984,9 @@ namespace Netch.Forms
this.NFTabPage.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.TAPTabPage.ResumeLayout(false);
this.TUNTAPGroupBox.ResumeLayout(false);
this.TUNTAPGroupBox.PerformLayout();
this.WinTUNTabPage.ResumeLayout(false);
this.WinTUNGroupBox.ResumeLayout(false);
this.WinTUNGroupBox.PerformLayout();
this.v2rayTabPage.ResumeLayout(false);
this.v2rayTabPage.PerformLayout();
this.KCPGroupBox.ResumeLayout(false);
@@ -1083,19 +1008,16 @@ namespace Netch.Forms
private System.Windows.Forms.TabControl TabControl;
private System.Windows.Forms.TabPage GeneralTabPage;
private System.Windows.Forms.TabPage NFTabPage;
private System.Windows.Forms.TabPage TAPTabPage;
private System.Windows.Forms.TabPage WinTUNTabPage;
private System.Windows.Forms.TabPage v2rayTabPage;
private System.Windows.Forms.GroupBox PortGroupBox;
private System.Windows.Forms.Label RedirectorLabel;
private System.Windows.Forms.TextBox RedirectorTextBox;
private System.Windows.Forms.CheckBox AllowDevicesCheckBox;
private System.Windows.Forms.Label HTTPPortLabel;
private System.Windows.Forms.TextBox HTTPPortTextBox;
private System.Windows.Forms.Label Socks5PortLabel;
private System.Windows.Forms.TextBox Socks5PortTextBox;
private System.Windows.Forms.CheckBox ResolveServerHostnameCheckBox;
private System.Windows.Forms.GroupBox TUNTAPGroupBox;
private System.Windows.Forms.CheckBox UseFakeDNSCheckBox;
private System.Windows.Forms.GroupBox WinTUNGroupBox;
private System.Windows.Forms.CheckBox ProxyDNSCheckBox;
private System.Windows.Forms.CheckBox UseCustomDNSCheckBox;
private System.Windows.Forms.Label TUNTAPDNSLabel;
@@ -1107,7 +1029,7 @@ namespace Netch.Forms
private System.Windows.Forms.Label TUNTAPAddressLabel;
private System.Windows.Forms.TextBox TUNTAPAddressTextBox;
private System.Windows.Forms.Button GlobalBypassIPsButton;
private System.Windows.Forms.CheckBox DNSRedirectorCheckBox;
private System.Windows.Forms.CheckBox DNSHijackCheckBox;
private System.Windows.Forms.Button ControlButton;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.TabPage OtherTabPage;
@@ -1121,8 +1043,6 @@ namespace Netch.Forms
private System.Windows.Forms.CheckBox ExitWhenClosedCheckBox;
private System.Windows.Forms.Label LanguageLabel;
private System.Windows.Forms.ComboBox LanguageComboBox;
private System.Windows.Forms.TextBox AclAddrTextBox;
private System.Windows.Forms.Label AclLabel;
private System.Windows.Forms.Label DetectionTickLabel;
private System.Windows.Forms.TextBox DetectionTickTextBox;
private System.Windows.Forms.Label StartedPingLabel;
@@ -1153,18 +1073,16 @@ namespace Netch.Forms
private System.Windows.Forms.Label ChinaDNSLabel;
private System.Windows.Forms.TextBox OtherDNSTextBox;
private System.Windows.Forms.TextBox ChinaDNSTextBox;
private System.Windows.Forms.TextBox RDRDNSTextBox;
private System.Windows.Forms.Label RDRDNSLabel;
private System.Windows.Forms.TextBox DNSHijackHostTextBox;
private System.Windows.Forms.CheckBox RedirectorSSCheckBox;
private System.Windows.Forms.Label ServerPingTypeLabel;
private System.Windows.Forms.RadioButton TCPingRadioBtn;
private System.Windows.Forms.RadioButton ICMPingRadioBtn;
private System.Windows.Forms.ComboBox ProcessProxyProtocolComboBox;
private System.Windows.Forms.Label ProcessProxyProtocolLabel;
private System.Windows.Forms.CheckBox ICMPRedirectorCheckBox;
private System.Windows.Forms.TextBox ModifiedICMPTextBox;
private System.Windows.Forms.Label RDRICMPLabel;
private System.Windows.Forms.CheckBox ICMPHijackCheckBox;
private System.Windows.Forms.CheckBox ChildProcessHandleCheckBox;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox ICMPHijackHostTextBox;
}
}

View File

@@ -4,8 +4,8 @@ using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
using Netch.Models;
using Netch.Properties;
using Netch.Utils;
@@ -26,20 +26,15 @@ namespace Netch.Forms
#region General
BindTextBox<ushort>(Socks5PortTextBox,
p => p.ToString() != HTTPPortTextBox.Text && p.ToString() != RedirectorTextBox.Text,
p => p.ToString() != HTTPPortTextBox.Text,
p => Global.Settings.Socks5LocalPort = p,
Global.Settings.Socks5LocalPort);
BindTextBox<ushort>(HTTPPortTextBox,
p => p.ToString() != Socks5PortTextBox.Text && p.ToString() != RedirectorTextBox.Text,
p => p.ToString() != Socks5PortTextBox.Text,
p => Global.Settings.HTTPLocalPort = p,
Global.Settings.HTTPLocalPort);
BindTextBox<ushort>(RedirectorTextBox,
p => p.ToString() != Socks5PortTextBox.Text && p.ToString() != HTTPPortTextBox.Text,
p => Global.Settings.RedirectorTCPPort = p,
Global.Settings.RedirectorTCPPort);
BindCheckBox(AllowDevicesCheckBox,
c => Global.Settings.LocalAddress = AllowDevicesCheckBox.Checked ? "0.0.0.0" : "127.0.0.1",
Global.Settings.LocalAddress switch {"127.0.0.1" => false, "0.0.0.0" => true, _ => false});
@@ -97,33 +92,33 @@ namespace Netch.Forms
Global.Settings.STUN_Server + ":" + Global.Settings.STUN_Server_Port,
stuns);
BindTextBox<string>(AclAddrTextBox, s => true, s => Global.Settings.ACL = s, Global.Settings.ACL);
BindListComboBox(LanguageComboBox,
o => Global.Settings.Language = o.ToString(),
i18N.GetTranslateList().Cast<object>().ToArray(),
Global.Settings.Language);
BindListComboBox(LanguageComboBox, o => Global.Settings.Language = o.ToString(), i18N.GetTranslateList(), Global.Settings.Language);
#endregion
#region Process Mode
BindCheckBox(DNSRedirectorCheckBox, b => Global.Settings.RedirectDNS = b, Global.Settings.RedirectDNS);
BindCheckBox(DNSHijackCheckBox, b => Global.Settings.Redirector.DNSHijack = b, Global.Settings.Redirector.DNSHijack);
BindTextBox(RDRDNSTextBox, s => DnsUtils.TrySplit(s, out _, 2), s => Global.Settings.RedirectDNSAddr = s, Global.Settings.RedirectDNSAddr);
BindTextBox(DNSHijackHostTextBox, s => true, s => Global.Settings.Redirector.DNSHijackHost = s, Global.Settings.Redirector.DNSHijackHost);
BindCheckBox(ICMPRedirectorCheckBox, b => Global.Settings.RedirectICMP = b, Global.Settings.RedirectICMP);
BindCheckBox(ICMPHijackCheckBox, b => Global.Settings.Redirector.ICMPHijack = b, Global.Settings.Redirector.ICMPHijack);
BindTextBox(ModifiedICMPTextBox, s => DnsUtils.TrySplit(s, out _, 2), s => Global.Settings.RedirectICMPAddr = s, Global.Settings.RedirectICMPAddr);
BindTextBox(ICMPHijackHostTextBox,
s => IPAddress.TryParse(s, out _),
s => Global.Settings.Redirector.ICMPHost = s,
Global.Settings.Redirector.ICMPHost);
BindCheckBox(RedirectorSSCheckBox, s => Global.Settings.RedirectorSS = s, Global.Settings.RedirectorSS);
BindCheckBox(RedirectorSSCheckBox, s => Global.Settings.Redirector.RedirectorSS = s, Global.Settings.Redirector.RedirectorSS);
BindCheckBox(ChildProcessHandleCheckBox, s => Global.Settings.ChildProcessHandle = s, Global.Settings.ChildProcessHandle);
BindCheckBox(ChildProcessHandleCheckBox,
s => Global.Settings.Redirector.ChildProcessHandle = s,
Global.Settings.Redirector.ChildProcessHandle);
BindListComboBox(ProcessProxyProtocolComboBox,
s => Global.Settings.ProcessProxyProtocol = (PortType) Enum.Parse(typeof(PortType), s.ToString(), false),
Enum.GetNames(typeof(PortType)).Cast<object>().ToArray(),
Global.Settings.ProcessProxyProtocol.ToString());
s => Global.Settings.Redirector.ProxyProtocol = (PortType) Enum.Parse(typeof(PortType), s.ToString(), false),
Enum.GetNames(typeof(PortType)),
Global.Settings.Redirector.ProxyProtocol.ToString());
#endregion
@@ -147,16 +142,15 @@ namespace Netch.Forms
BindCheckBox(UseCustomDNSCheckBox, b => { Global.Settings.TUNTAP.UseCustomDNS = b; }, Global.Settings.TUNTAP.UseCustomDNS);
BindTextBox(TUNTAPDNSTextBox,
s => !UseCustomDNSCheckBox.Checked || DnsUtils.TrySplit(s, out _, 2),
_ => true,
s =>
{
if (UseCustomDNSCheckBox.Checked)
Global.Settings.TUNTAP.DNS = DnsUtils.Split(s).ToList();
Global.Settings.TUNTAP.HijackDNS = s;
},
DnsUtils.Join(Global.Settings.TUNTAP.DNS));
Global.Settings.TUNTAP.HijackDNS);
BindCheckBox(ProxyDNSCheckBox, b => Global.Settings.TUNTAP.ProxyDNS = b, Global.Settings.TUNTAP.ProxyDNS);
BindCheckBox(UseFakeDNSCheckBox, b => Global.Settings.TUNTAP.UseFakeDNS = b, Global.Settings.TUNTAP.UseFakeDNS);
#endregion
@@ -217,17 +211,11 @@ namespace Netch.Forms
#region AioDNS
BindTextBox(AioDNSRulePathTextBox, s => true, s => Global.Settings.AioDNS.RulePath = s, Global.Settings.AioDNS.RulePath);
BindTextBox(AioDNSRulePathTextBox, _ => true, s => Global.Settings.AioDNS.RulePath = s, Global.Settings.AioDNS.RulePath);
BindTextBox(ChinaDNSTextBox,
s => IPAddress.TryParse(s, out _),
s => Global.Settings.AioDNS.ChinaDNS = s,
Global.Settings.AioDNS.ChinaDNS);
BindTextBox(ChinaDNSTextBox, _ => true, s => Global.Settings.AioDNS.ChinaDNS = s, Global.Settings.AioDNS.ChinaDNS);
BindTextBox(OtherDNSTextBox,
s => IPAddress.TryParse(s, out _),
s => Global.Settings.AioDNS.OtherDNS = s,
Global.Settings.AioDNS.OtherDNS);
BindTextBox(OtherDNSTextBox, _ => true, s => Global.Settings.AioDNS.OtherDNS = s, Global.Settings.AioDNS.OtherDNS);
#endregion
}
@@ -235,13 +223,12 @@ namespace Netch.Forms
private void SettingForm_Load(object sender, EventArgs e)
{
TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null);
Task.Run(() => BeginInvoke(new Action(() => UseFakeDNSCheckBox.Visible = Flags.SupportFakeDns)));
}
private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object? sender, EventArgs? e)
{
if (UseCustomDNSCheckBox.Checked)
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.DNS.Any() ? DnsUtils.Join(Global.Settings.TUNTAP.DNS) : "1.1.1.1";
TUNTAPDNSTextBox.Text = Global.Settings.TUNTAP.HijackDNS;
else
TUNTAPDNSTextBox.Text = "AioDNS";
}
@@ -320,14 +307,19 @@ namespace Netch.Forms
_saveActions.Add(control, c => save.Invoke(((RadioButton) c).Checked));
}
private void BindListComboBox(ComboBox control, Action<object> save, object[] values, object value, string propertyName = "SelectedItem")
private void BindListComboBox<T>(ComboBox comboBox, Action<T> save, IEnumerable<T> values, T value) where T : notnull
{
if (control.DropDownStyle != ComboBoxStyle.DropDownList)
if (comboBox.DropDownStyle != ComboBoxStyle.DropDownList)
throw new ArgumentOutOfRangeException();
control.Items.AddRange(values);
_saveActions.Add(control, c => save.Invoke(((ComboBox) c).SelectedItem));
Load += (_, _) => { control.SelectedItem = value; };
var tagItems = values.Select(o => new TagItem<T>(o, o.ToString()!)).ToArray();
comboBox.Items.AddRange(tagItems.Cast<object>().ToArray());
comboBox.ValueMember = nameof(TagItem<T>.Value);
comboBox.DisplayMember = nameof(TagItem<T>.Text);
_saveActions.Add(comboBox, c => save.Invoke(((TagItem<T>) ((ComboBox) c).SelectedItem).Value));
Load += (_, _) => { comboBox.SelectedItem = tagItems.SingleOrDefault(t => t.Value.Equals(value)); };
}
private void BindComboBox(ComboBox control, Func<string, bool> check, Action<string> save, string value, object[]? values = null)

View File

@@ -1,64 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">

View File

@@ -0,0 +1,33 @@
using System.Runtime.InteropServices;
using System.Text;
namespace Netch.Interops
{
public static class AioDNSInterops
{
private const string aiodns_bin = "aiodns.bin";
public static bool Dial(NameList name, string value)
{
return aiodns_dial(name, Encoding.UTF8.GetBytes(value));
}
[DllImport(aiodns_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool aiodns_dial(NameList name, byte[] value);
[DllImport(aiodns_bin, EntryPoint = "aiodns_init", CallingConvention = CallingConvention.Cdecl)]
public static extern bool Init();
[DllImport(aiodns_bin, EntryPoint = "aiodns_free", CallingConvention = CallingConvention.Cdecl)]
public static extern void Free();
public enum NameList
{
TYPE_REST,
TYPE_ADDR,
TYPE_LIST,
TYPE_CDNS,
TYPE_ODNS
}
}
}

View File

@@ -0,0 +1,79 @@
using System.Runtime.InteropServices;
using Netch.Utils;
namespace Netch.Interops
{
public static class RedirectorInterop
{
public enum NameList
{
TYPE_FILTERLOOPBACK,
TYPE_FILTERICMP,
TYPE_FILTERTCP,
TYPE_FILTERUDP,
TYPE_CLRNAME,
TYPE_ADDNAME,
TYPE_BYPNAME,
TYPE_DNSHOST,
TYPE_TCPLISN,
TYPE_TCPTYPE,
TYPE_TCPHOST,
TYPE_TCPUSER,
TYPE_TCPPASS,
TYPE_TCPMETH,
TYPE_TCPPROT,
TYPE_TCPPRPA,
TYPE_TCPOBFS,
TYPE_TCPOBPA,
TYPE_UDPLISN,
TYPE_UDPTYPE,
TYPE_UDPHOST,
TYPE_UDPUSER,
TYPE_UDPPASS,
TYPE_UDPMETH,
TYPE_UDPPROT,
TYPE_UDPPRPA,
TYPE_UDPOBFS,
TYPE_UDPOBPA
}
public static bool Dial(NameList name, string value)
{
Logging.Debug($"Dial {name} {value}");
return aio_dial(name, value);
}
public static bool Init()
{
return aio_init();
}
public static bool Free()
{
return aio_free();
}
public const int UdpNameListOffset = (int) NameList.TYPE_UDPLISN - (int) NameList.TYPE_TCPLISN;
private const string Redirector_bin = "Redirector.bin";
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool aio_dial(NameList name, [MarshalAs(UnmanagedType.LPWStr)] string value);
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool aio_init();
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool aio_free();
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern ulong aio_getUP();
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern ulong aio_getDL();
}
}

View File

@@ -0,0 +1,73 @@
using System.Runtime.InteropServices;
using System.Text;
using Netch.Utils;
namespace Netch.Interops
{
public static class TUNInterop
{
public enum NameList
{
TYPE_BYPBIND,
TYPE_BYPLIST,
TYPE_DNSADDR,
TYPE_ADAPMTU,
TYPE_TCPREST,
TYPE_TCPTYPE,
TYPE_TCPHOST,
TYPE_TCPUSER,
TYPE_TCPPASS,
TYPE_TCPMETH,
TYPE_TCPPROT,
TYPE_TCPPRPA,
TYPE_TCPOBFS,
TYPE_TCPOBPA,
TYPE_UDPREST,
TYPE_UDPTYPE,
TYPE_UDPHOST,
TYPE_UDPUSER,
TYPE_UDPPASS,
TYPE_UDPMETH,
TYPE_UDPPROT,
TYPE_UDPPRPA,
TYPE_UDPOBFS,
TYPE_UDPOBPA
}
public static bool Dial(NameList name, string value)
{
Logging.Debug($"Dial {name} {value}");
return tun_dial(name, Encoding.UTF8.GetBytes(value));
}
public static bool Init()
{
return tun_init();
}
public static bool Free()
{
return tun_free();
}
private const string tun2socks_bin = "tun2socks.bin";
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool tun_dial(NameList name, byte[] value);
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool tun_init();
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern bool tun_free();
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
public static extern ulong tun_luid();
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern ulong tun_getUP();
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
private static extern ulong tun_getDL();
}
}

View File

@@ -16,8 +16,11 @@ namespace Netch.Models.GitHubRelease
Suffix = suffix;
}
public static SuffixVersion Parse(string input)
public static SuffixVersion Parse(string? input)
{
if (input == null)
throw new ArgumentNullException(nameof(input));
var split = input.Split('-');
var dotNetVersion = Version.Parse(split[0]);
var preRelease = split.ElementAtOrDefault(1) ?? string.Empty;
@@ -39,7 +42,7 @@ namespace Netch.Models.GitHubRelease
}
}
public int CompareTo(object obj)
public int CompareTo(object? obj)
{
if (obj is not SuffixVersion version)
throw new ArgumentOutOfRangeException();

View File

@@ -1,11 +1,18 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace Netch.Models.GitHubRelease
{
public class VersionComparer : IComparer<object>
{
public int Compare(object x, object y)
public int Compare(object? x, object? y)
{
if (x == null)
throw new ArgumentNullException(nameof(x));
if (y == null)
throw new ArgumentNullException(nameof(y));
return VersionUtil.CompareVersion(x.ToString(), y.ToString());
}
}

View File

@@ -23,7 +23,7 @@ namespace Netch.Models.GitHubRelease
/// <returns> =0:versions are equal</returns>
/// <returns> &gt;0:version1 is greater</returns>
/// <returns> &lt;0:version2 is greater</returns>
public static int CompareVersion(string v1, string v2)
public static int CompareVersion(string? v1, string? v2)
{
var version1 = SuffixVersion.Parse(v1);
var version2 = SuffixVersion.Parse(v2);

View File

@@ -3,13 +3,12 @@ using System.Net.NetworkInformation;
namespace Netch.Models
{
public interface IAdapter
public interface IAdapter
{
public abstract int Index { get; }
int InterfaceIndex { get; }
public abstract IPAddress Gateway { get; }
public abstract NetworkInterface NetworkInterface { get; }
IPAddress Gateway { get; }
NetworkInterface NetworkInterface { get; }
}
}

View File

@@ -4,6 +4,7 @@ namespace Netch.Models
{
INFO,
WARNING,
ERROR
ERROR,
DEBUG
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace Netch.Models
{
public class MessageException : Exception
{
public MessageException()
{
}
public MessageException(string message) : base(message)
{
}
}
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Netch.Controllers;
using Netch.Utils;
namespace Netch.Models
@@ -14,7 +13,7 @@ namespace Netch.Models
public string? FullName { get; private set; }
public Mode(string? fullName = default)
public Mode(string? fullName)
{
_lazyRule = new Lazy<List<string>>(ReadRules);
if (fullName == null)
@@ -35,10 +34,8 @@ namespace Netch.Models
var typeResult = int.TryParse(split.ElementAtOrDefault(1), out var type);
Type = typeResult ? type : 0;
// TODO throw NotSupportedModeTypeException
var bypassChinaResult = int.TryParse(split.ElementAtOrDefault(2), out var bypassChina);
BypassChina = this.ClientRouting() && bypassChinaResult && bypassChina == 1;
if (!ModeHelper.ModeTypes.Contains(Type))
throw new NotSupportedException($"not support mode \"[{Type}]{Remark}\".");
}
/// <summary>
@@ -46,11 +43,6 @@ namespace Netch.Models
/// </summary>
public List<string> Rule => _lazyRule.Value;
/// <summary>
/// 绕过中国0. 不绕过 1. 绕过)
/// </summary>
public bool BypassChina { get; set; }
/// <summary>
/// 备注
/// </summary>
@@ -161,7 +153,7 @@ namespace Netch.Models
/// <returns>模式文件字符串</returns>
public string ToFileString()
{
return $"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}{Constants.EOF}{string.Join(Constants.EOF, Rule)}";
return $"# {Remark}, {Type}{Constants.EOF}{string.Join(Constants.EOF, Rule)}";
}
}
@@ -172,11 +164,5 @@ namespace Netch.Models
{
return mode.Type is 0 or 2;
}
/// Socks5 分流是否能被有效实施
public static bool ClientRouting(this Mode mode)
{
return mode.Type is not (1 or 2);
}
}
}

View File

@@ -2,8 +2,6 @@
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using Microsoft.Win32;
using Netch.Controllers;
using Netch.Utils;
using Vanara.PInvoke;
@@ -11,7 +9,7 @@ namespace Netch.Models
{
public class OutboundAdapter : IAdapter
{
public OutboundAdapter(bool logging = true)
public OutboundAdapter()
{
// 寻找出口适配器
if (IpHlpApi.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) != 0)
@@ -23,22 +21,20 @@ namespace Netch.Models
.First(ni => ni.Supports(NetworkInterfaceComponent.IPv4) &&
ni.GetIPProperties().GetIPv4Properties().Index == pRoute.dwForwardIfIndex);
Index = (int) pRoute.dwForwardIfIndex;
Address = new IPAddress(pRoute.dwForwardNextHop.S_addr);
InterfaceIndex = (int) pRoute.dwForwardIfIndex;
Gateway = new IPAddress(pRoute.dwForwardNextHop.S_un_b);
_parametersRegistry =
Registry.LocalMachine.OpenSubKey($@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{NetworkInterface.Id}", true)!;
if (logging)
{
Logging.Info($"出口 网关 地址:{Gateway}");
Logging.Info($"出口适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {Index}");
}
Logging.Info($"出口 网关 地址:{Gateway}");
Logging.Info($"出口适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
}
public IPAddress Address { get; }
/// <summary>
/// 索引
/// </summary>
public int Index { get; }
public int InterfaceIndex { get; }
/// <summary>
/// 网关
@@ -46,24 +42,5 @@ namespace Netch.Models
public IPAddress Gateway { get; }
public NetworkInterface NetworkInterface { get; }
public string DNS
{
get
{
try
{
return (string) _parametersRegistry.GetValue("NameServer");
}
catch
{
return string.Empty;
}
}
set => _parametersRegistry.SetValue("NameServer", value, RegistryValueKind.String);
}
private readonly RegistryKey _parametersRegistry;
}
}

View File

@@ -6,7 +6,7 @@ namespace Netch.Models
/// <summary>
/// TUN/TAP 适配器配置类
/// </summary>
public class TUNTAPConfig
public class TUNConfig
{
/// <summary>
/// 地址
@@ -16,7 +16,7 @@ namespace Netch.Models
/// <summary>
/// DNS
/// </summary>
public List<string> DNS { get; set; } = new();
public string HijackDNS { get; set; } = "tcp://1.1.1.1:53";
/// <summary>
/// 网关
@@ -36,12 +36,12 @@ namespace Netch.Models
/// <summary>
/// 使用自定义 DNS 设置
/// </summary>
public bool UseCustomDNS { get; set; } = false;
public bool UseCustomDNS { get; set; } = true;
/// <summary>
/// 使用Fake DNS
/// 全局绕过 IP 列表
/// </summary>
public bool UseFakeDNS { get; set; } = false;
public List<string> BypassIPs { get; set; } = new();
}
public class KcpConfig
@@ -76,13 +76,45 @@ namespace Netch.Models
public class AioDNSConfig
{
public string ChinaDNS { get; set; } = "223.5.5.5";
public string ChinaDNS { get; set; } = "tcp://223.5.5.5:53";
public string OtherDNS { get; set; } = "1.1.1.1";
public string OtherDNS { get; set; } = "tcp://1.1.1.1:53";
public string Protocol { get; set; } = "tcp";
public ushort ListenPort { get; set; } = 53;
public string RulePath { get; set; } = "bin\\china_site_list";
public string RulePath { get; set; } = "bin\\aiodns.conf";
}
public class RedirectorConfig
{
/// <summary>
/// 不代理TCP
/// </summary>
public PortType ProxyProtocol { get; set; } = PortType.Both;
/// <summary>
/// 是否开启DNS转发
/// </summary>
public bool DNSHijack { get; set; } = true;
/// <summary>
/// 转发DNS地址
/// </summary>
public string DNSHijackHost { get; set; } = "1.1.1.1:53";
public string ICMPHost { get; set; } = "1.2.4.8";
public bool ICMPHijack { get; set; } = false;
/// <summary>
/// 是否使用RDR内置SS
/// </summary>
public bool RedirectorSS { get; set; } = false;
/// <summary>
/// 是否代理子进程
/// </summary>
public bool ChildProcessHandle { get; set; } = false;
}
/// <summary>
@@ -90,23 +122,15 @@ namespace Netch.Models
/// </summary>
public class Setting
{
public RedirectorConfig Redirector { get; set; } = new();
/// <summary>
/// 服务器列表
/// </summary>
public List<Server> Server { get; set; } = new();
/// <summary>
/// ACL规则
/// </summary>
public string ACL { get; set; } = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/banAD.acl";
public AioDNSConfig AioDNS { get; set; } = new();
/// <summary>
/// 全局绕过 IP 列表
/// </summary>
public List<string> BypassIPs { get; set; } = new();
/// <summary>
/// 是否检查 Beta 更新
/// </summary>
@@ -150,42 +174,7 @@ namespace Netch.Models
/// <summary>
/// 模式选择位置
/// </summary>
public int ModeComboBoxSelectedIndex { get; set; } = 0;
/// <summary>
/// 转发DNS地址
/// </summary>
public string RedirectDNSAddr { get; set; } = "8.8.8.8";
/// <summary>
/// 是否开启DNS转发
/// </summary>
public bool RedirectDNS { get; set; } = false;
/// <summary>
/// 转发ICMP地址
/// </summary>
public string RedirectICMPAddr { get; set; } = "1.2.4.8";
/// <summary>
/// 是否开启ICMP转发
/// </summary>
public bool RedirectICMP { get; set; } = false;
/// <summary>
/// GFWList
/// </summary>
public string PAC { get; set; } = "https://raw.githubusercontent.com/HMBSbige/Text_Translation/master/ShadowsocksR/ss_white.pac";
/// <summary>
/// PAC端口
/// </summary>
public ushort Pac_Port { get; set; } = 2803;
/// <summary>
/// 不代理TCP
/// </summary>
public PortType ProcessProxyProtocol { get; set; } = PortType.Both;
public int ModeComboBoxSelectedIndex { get; set; } = -1;
/// <summary>
/// 快捷配置数量
@@ -202,21 +191,6 @@ namespace Netch.Models
/// </summary>
public byte ProfileTableColumnCount { get; set; } = 5;
/// <summary>
/// 是否使用RDR内置SS
/// </summary>
public bool RedirectorSS { get; set; } = false;
/// <summary>
/// 是否代理子进程
/// </summary>
public bool ChildProcessHandle { get; set; } = false;
/// <summary>
/// Redirector TCP 占用端口
/// </summary>
public ushort RedirectorTCPPort { get; set; } = 3901;
/// <summary>
/// 网页请求超时 毫秒
/// </summary>
@@ -225,7 +199,7 @@ namespace Netch.Models
/// <summary>
/// 解析服务器主机名
/// </summary>
public bool ResolveServerHostname { get; set; } = false;
public bool ResolveServerHostname { get; set; } = true;
/// <summary>
/// 是否开机启动软件
@@ -235,7 +209,7 @@ namespace Netch.Models
/// <summary>
/// 服务器选择位置
/// </summary>
public int ServerComboBoxSelectedIndex { get; set; } = 0;
public int ServerComboBoxSelectedIndex { get; set; } = -1;
/// <summary>
/// 服务器测试方式 false.ICMPing true.TCPing
@@ -280,25 +254,24 @@ namespace Netch.Models
/// <summary>
/// TUNTAP 适配器配置
/// </summary>
public TUNTAPConfig TUNTAP { get; set; } = new();
public TUNConfig TUNTAP { get; set; } = new();
/// <summary>
/// 是否打开软件时更新订阅
/// </summary>
public bool UpdateServersWhenOpened { get; set; } = false;
/// <summary>
/// 使用代理更新订阅
/// </summary>
public bool UseProxyToUpdateSubscription { get; set; } = false;
public V2rayConfig V2RayConfig { get; set; } = new();
public bool? AlwaysStartPACServer { get; set; }
public Setting Clone()
{
return (Setting) MemberwiseClone();
}
public void Set(Setting value)
{
foreach (var p in typeof(Setting).GetProperties())
p.SetValue(this, p.GetValue(value));
}
}
}

19
Netch/Models/TagItem.cs Normal file
View File

@@ -0,0 +1,19 @@
using Netch.Utils;
namespace Netch.Models
{
internal class TagItem<T>
{
private readonly string _text;
public TagItem(T value, string text)
{
_text = text;
Value = value;
}
public string Text => i18N.Translate(_text);
public T Value { get; }
}
}

View File

@@ -1,30 +0,0 @@
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using Netch.Controllers;
using Netch.Utils;
namespace Netch.Models
{
public class TapAdapter : IAdapter
{
public TapAdapter()
{
Index = -1;
ComponentID = TUNTAP.GetComponentID() ?? throw new MessageException("TAP 适配器未安装");
// 根据 ComponentID 寻找 Tap适配器
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.Id == ComponentID);
Index = NetworkInterface.GetIPProperties().GetIPv4Properties().Index;
Logging.Info($"TAP 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {Index}");
}
public string ComponentID { get; }
public int Index { get; }
public IPAddress Gateway => IPAddress.Parse(Global.Settings.TUNTAP.Gateway);
public NetworkInterface NetworkInterface { get; }
}
}

View File

@@ -0,0 +1,27 @@
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using Netch.Interops;
using Netch.Utils;
namespace Netch.Models
{
public class TunAdapter : IAdapter
{
public TunAdapter()
{
InterfaceIndex = (int) NativeMethods.ConvertLuidToIndex(TUNInterop.tun_luid());
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.GetIPProperties().GetIPv4Properties().Index == InterfaceIndex);
Gateway = IPAddress.Parse(Global.Settings.TUNTAP.Gateway);
Logging.Info($"WinTUN 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
}
public int InterfaceIndex { get; }
public IPAddress Gateway { get; }
public NetworkInterface NetworkInterface { get; }
}
}

View File

@@ -4,9 +4,21 @@ namespace Netch
{
public static class NativeMethods
{
/// <summary>
/// 分配 IP 地址
/// </summary>
/// <param name="inet">AF_INET / AF_INET6</param>
/// <param name="address">目标地址</param>
/// <param name="cidr">CIDR</param>
/// <param name="index">适配器索引</param>
/// <returns>是否成功</returns>
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl, EntryPoint = "CreateUnicastIP")]
public static extern bool CreateUnicastIP(int inet, string address, int cidr, int index);
/// <summary>
/// 创建路由规则
/// </summary>
/// <param name="inet">AF_INET / AF_INET6</param>
/// <param name="address">目标地址</param>
/// <param name="cidr">CIDR</param>
/// <param name="gateway">网关地址</param>
@@ -14,11 +26,12 @@ namespace Netch
/// <param name="metric">跃点数</param>
/// <returns>是否成功</returns>
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl, EntryPoint = "CreateRoute")]
public static extern bool CreateRoute(string address, int cidr, string gateway, int index, int metric = 0);
public static extern bool CreateRoute(int inet, string address, int cidr, string gateway, int index, int metric = 0);
/// <summary>
/// 删除路由规则
/// </summary>
/// <param name="inet">AF_INET / AF_INET6</param>
/// <param name="address">目标地址</param>
/// <param name="cidr">掩码地址</param>
/// <param name="gateway">网关地址</param>
@@ -26,15 +39,12 @@ namespace Netch
/// <param name="metric">跃点数</param>
/// <returns>是否成功</returns>
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl, EntryPoint = "DeleteRoute")]
public static extern bool DeleteRoute(string address, int cidr, string gateway, int index, int metric = 0);
public static extern bool DeleteRoute(int inet, string address, int cidr, string gateway, int index, int metric = 0);
[DllImport("RouteHelper.bin", CallingConvention = CallingConvention.Cdecl)]
public static extern ulong ConvertLuidToIndex(ulong luid);
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
public static extern uint FlushDNSResolverCache();
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
[DllImport("kernel32.dll")]
public static extern bool AttachConsole(int dwProcessId);
}
}

View File

@@ -8,6 +8,7 @@ using System.Windows.Forms;
using Netch.Controllers;
using Netch.Forms;
using Netch.Utils;
using static Vanara.PInvoke.Kernel32;
namespace Netch
{
@@ -22,10 +23,10 @@ namespace Netch
public static void Main(string[] args)
{
#if DEBUG
AttachConsole();
AttachAllocConsole();
#else
if (args.Contains(Constants.Parameter.Console))
AttachConsole();
AttachAllocConsole();
#endif
if (args.Contains(Constants.Parameter.ForceUpdate))
@@ -33,9 +34,9 @@ namespace Netch
// 设置当前目录
Directory.SetCurrentDirectory(Global.NetchDir);
Environment.SetEnvironmentVariable("PATH",
Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Process) + ";" + Path.Combine(Global.NetchDir, "bin"),
EnvironmentVariableTarget.Process);
var binPath = Path.Combine(Global.NetchDir, "bin");
Environment.SetEnvironmentVariable("PATH", $"{Environment.GetEnvironmentVariable("PATH")};{binPath}");
AddDllDirectory(binPath);
Updater.Updater.CleanOld(Global.NetchDir);
@@ -86,15 +87,16 @@ namespace Netch
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += Application_OnException;
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(Global.MainForm);
}
private static void AttachConsole()
private static void AttachAllocConsole()
{
if (!NativeMethods.AttachConsole(-1))
NativeMethods.AllocConsole();
if (!AttachConsole(ATTACH_PARENT_PROCESS))
AllocConsole();
}
public static void Application_OnException(object sender, ThreadExceptionEventArgs e)

View File

@@ -2,88 +2,68 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net48</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<StartupObject>Netch.Netch</StartupObject>
<ApplicationManifest>App.manifest</ApplicationManifest>
<ApplicationIcon>Resources\Netch.ico</ApplicationIcon>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
<AnalysisMode>Default</AnalysisMode>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net5.0-windows</TargetFramework>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<Configurations>Debug;Release</Configurations>
<Platforms>x64</Platforms>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<!-- <EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>-->
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningsAsErrors />
<NoWarn />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn />
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningsAsErrors />
<OutputPath>bin\x64\Release\</OutputPath>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<None Remove=".gitignore" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="HMBSbige.SingleInstance" Version="5.0.0" />
<PackageReference Include="MaxMind.GeoIP2" Version="4.0.1" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.66" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Nullable.Extended.Analyzer" Version="1.2.4089">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Collections.Immutable" Version="5.0.0" />
<PackageReference Include="System.Reflection.Metadata" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.1" />
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
<PackageReference Include="TaskScheduler" Version="2.9.1" />
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.3.7" />
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
<PackageReference Include="Vanara.PInvoke.User32" Version="3.3.7" />
<PackageReference Include="WindowsFirewallHelper" Version="2.0.4.70-beta2" />
<PackageReference Include="WindowsProxy" Version="5.0.3" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<!-- .NET Framework -->
<PackageReference Include="ILMerge" Version="3.0.41" />
<Reference Include="System.Management" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' != 'net'">
<!-- .NET Core -->
<PackageReference Include="System.Management" Version="5.0.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="5.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Interop.nfapinet\Interop.nfapinet.csproj" />
<ProjectReference Include="..\SearchComboBox\SearchComboBox.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove=".gitignore" />
<None Visible="false" Include="..\binaries\**" LinkBase="bin" CopyToPublishDirectory="PreserveNewest" CopyToOutputDirectory="PreserveNewest" />
<None Update="..\binaries\NTT.exe">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</None>
<None Remove="..\binaries\.git" />
<None Visible="false" Include="..\translations\i18n\**" LinkBase="i18n" CopyToPublishDirectory="PreserveNewest" CopyToOutputDirectory="PreserveNewest" />
<None Visible="false" Include="..\modes\mode\**" LinkBase="mode" CopyToPublishDirectory="PreserveNewest" CopyToOutputDirectory="PreserveNewest" />
@@ -100,9 +80,7 @@
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Update="Forms\Mode\Route.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Forms\Mode\Route.cs" />
</ItemGroup>
<ItemGroup>
@@ -110,7 +88,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Remove="Forms\LogForm.resx" />
</ItemGroup>
<ItemGroup>
@@ -119,14 +96,6 @@
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties />
</VisualStudio>
</ProjectExtensions>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="set TargetFramework=$(TargetFramework)&#xD;&#xA;set Configuration=$(Configuration)&#xD;&#xA;set ILMergeConsolePath=$(ILMergeConsolePath)&#xD;&#xA;set TargetDir=$(TargetDir)&#xD;&#xA;set SolutionDir=$(SolutionDir)&#xD;&#xA;call $(ProjectDir)PostBuild.bat" />
</Target>
<Target Condition="'$(PublishSingleFile)' == 'true'" AfterTargets="_ComputeFilesToBundle" Name="RemoveDupeAssemblies">
<ItemGroup>

View File

@@ -1,20 +0,0 @@
if %Configuration%==Release if %TargetFramework%==net48 (
:: Merge dlls
%ILMergeConsolePath% /wildcards /out:%TargetDir%Netch.exe ^
/lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319" ^
/targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8" ^
%TargetDir%Netch.exe ^
%TargetDir%*.dll
DEL /f %TargetDir%*.dll >NUL 2>&1
)
if %Configuration%==Release (
DEL /f %TargetDir%*.config >NUL 2>&1
DEL /f %TargetDir%*.pdb >NUL 2>&1
)
RD /s /Q %TargetDir%x86 >NUL 2>&1
RD /s /Q %TargetDir%de %TargetDir%es %TargetDir%fr %TargetDir%it %TargetDir%pl %TargetDir%ru %TargetDir%zh-CN >NUL 2>&1
exit 0

View File

@@ -3,7 +3,6 @@
"Information": "信息",
"Error": "错误",
"If this is your first time using this software,\n please check https://netch.org to install supports first,\n or the program may report errors.": "如果你是第一次使用本软件,\n请务必前往 https://netch.org 安装程序所需依赖,\n否则程序将无法正常运行",
"Missing File or runtime components": "缺少文件或运行库",
"Please extract all files then run the program!": "请先解压所有文件再执行程序!",
@@ -20,7 +19,6 @@
"SetupBypass": "设置绕行规则",
"Test failed": "测试失败",
"Starting update subscription": "正在更新订阅",
"Starting update ACL": "正在更新 ACL",
"Subscription updated": "订阅更新完毕",
"Register driver": "正在注册驱动",
@@ -67,7 +65,6 @@
"Subscribe": "订阅",
"Manage Subscribe Links": "管理订阅链接",
"Update Servers From Subscribe Links": "从订阅链接更新服务器",
"Update Servers From Subscribe Links With Proxy": "使用代理从订阅链接更新服务器",
"No subscription link": "没有任何一条订阅链接",
"Updating {0}": "正在更新 {0}",
"Update {1} server(s) from {0}": "从 {0} 更新 {1} 个服务器",
@@ -85,21 +82,10 @@
"Uninstall {0}": "卸载 {0}",
"Uninstalling {0}": "正在卸载 {0} 中",
"{0} has been uninstalled": "{0} 已卸载",
"Reload Modes": "重载模式",
"Modes have been reload": "模式已重载",
"Clean DNS Cache": "清理 DNS 缓存",
"DNS cache cleanup succeeded": "DNS 缓存清理成功",
"Remove Netch Firewall Rules": "移除 Netch 防火墙规则",
"Update PAC": "更新 PAC",
"PAC updated successfully": "PAC 更新成功",
"PAC update failed": "PAC 更新失败",
"Update ACL": "更新 ACL 规则",
"Update ACL with proxy": "使用代理更新 ACL 规则",
"ACL updated successfully": "ACL 更新成功",
"ACL update failed": "ACL 更新失败",
"Open Directory": "打开目录",
"About": "关于",
@@ -155,25 +141,21 @@
"Gateway": "网关",
"Use Custom DNS": "使用自定义 DNS",
"Proxy DNS in Proxy Rule IPs Mode": "在 代理规则IP 模式下代理 DNS",
"Use Fake DNS": "使用 Fake DNS",
"Exit when closed": "关闭时退出",
"Stop when exited": "退出时停止",
"Global Bypass IPs": "全局直连 IP",
"Check update when opened": "打开软件时检查更新",
"Check Beta update": "检查 Beta 更新",
"Update Servers when opened": "打开软件时更新服务器",
"SS DLL": "SS DLL",
"Modify System DNS": "修改系统 DNS",
"Proxy Protocol": "代理协议",
"DNS Redirector": "DNS转发",
"ICMP Redirector": "ICMP转发",
"Handle process's DNS Hijack": "被代理进程 DNS 劫持",
"Global ICMP Hijack": "全局 ICMP 劫持",
"Child Process Handle": "子进程代理",
"ProfileCount": "快捷配置数量",
"Delay test after start": "启动后延迟测试",
"ServerPingType": "测速方式",
"Detection Tick(sec)": "检测心跳(秒)",
"STUN Server": "STUN 服务器",
"Custom ACL": "自定义 ACL 规则",
"Language": "语言",
"Resolve Server Hostname": "解析服务器主机名",
"FullCone Support (Required Server Xray-core v1.3.0+)": "FullCone 支持(需服务端 Xray-core v1.3.0+",
@@ -186,12 +168,5 @@
"Exit": "退出",
"The {0} port is in use.": "{0} 端口已被占用",
"The {0} port is reserved by system.": "{0} 端口是系统保留端口",
"[Web Proxy] Bypass LAN": "[网页代理] 绕过局域网",
"[Non Web Proxy] Bypass LAN": "[不设置代理] 绕过局域网",
"[TUN/TAP] Bypass LAN": "[TUN/TAP] 绕过局域网",
"[Web Proxy] Bypass LAN and China": "[网页代理] 绕过局域网和中国大陆",
"[Non Web Proxy] Bypass LAN and China": "[不设置代理] 绕过局域网和中国大陆",
"[TUN/TAP] Bypass LAN and China": "[TUN/TAP] 绕过局域网和中国大陆"
"The {0} port is reserved by system.": "{0} 端口是系统保留端口"
}

View File

@@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using Netch.Controllers;
using Netch.Models;
@@ -37,9 +35,6 @@ namespace Netch.Servers.Shadowsocks
plugin_opts = server.PluginOption
};
if (mode.BypassChina)
command.acl = $"{Path.GetFullPath(File.Exists(Constants.UserACL) ? Constants.UserACL : Constants.BuiltinACL)}";
StartInstanceAuto(command.ToString());
}

View File

@@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using Netch.Controllers;
using Netch.Models;
@@ -40,9 +38,6 @@ namespace Netch.Servers.ShadowsocksR
u = true
};
if (mode.BypassChina)
command.acl = $"{Path.GetFullPath(File.Exists(Constants.UserACL) ? Constants.UserACL : Constants.BuiltinACL)}";
StartInstanceAuto(command.ToString());
}

View File

@@ -65,25 +65,6 @@ namespace Netch.Servers.V2ray.Utils
outboundTag = "block"
};
if (mode.BypassChina)
switch (mode.Type)
{
case 0:
directRuleObject.ip.Add("geoip:cn");
break;
case 1:
case 2:
if (Flags.SupportFakeDns && Global.Settings.TUNTAP.UseFakeDNS)
directRuleObject.domain.Add("geosite:cn");
else
directRuleObject.ip.Add("geoip:cn");
break;
default:
directRuleObject.domain.Add("geosite:cn");
break;
}
if (mode.Type is 0 or 1 or 2)
blockRuleObject.ip.Add("geoip:private");

View File

@@ -6,8 +6,8 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Threading;
using Netch.Controllers;
using Netch.Models;
using Netch.Properties;
using Netch.Utils;
@@ -92,11 +92,10 @@ namespace Netch.Updater
#region Apply Update
private static readonly ImmutableArray<string> KeepDirectories = new List<string> {"data", "mode\\Custom"}.ToImmutableArray();
private static readonly ImmutableArray<string> KeepDirectories = new List<string> {"data", "mode\\Custom", "logging"}.ToImmutableArray();
private void ApplyUpdate()
{
var dispatcher = Dispatcher.CurrentDispatcher;
var mainForm = Global.MainForm;
#region PreUpdate
@@ -131,7 +130,7 @@ namespace Netch.Updater
MoveAllFilesOver(Path.Combine(extractPath, "Netch"), _installDirectory);
// release mutex, exit
dispatcher.Invoke(Netch.SingleInstance.Dispose);
mainForm.Invoke(new Action(Netch.SingleInstance.Dispose));
Process.Start(Global.NetchExecutable);
Environment.Exit(0);
}
@@ -156,7 +155,15 @@ namespace Netch.Updater
// rename files
foreach (var file in filesToDelete)
File.Move(file, file + ".old");
try
{
File.Move(file, file + ".old");
}
catch
{
Logging.Error($"failed to rename file \"{file}\"");
throw;
}
}
private int Extract(string destDirName, bool overwrite)

View File

@@ -6,7 +6,6 @@ using Microsoft.Diagnostics.Tracing.Parsers;
using Microsoft.Diagnostics.Tracing.Session;
using Netch.Controllers;
using Netch.Models;
using Netch.Servers.Shadowsocks;
namespace Netch.Utils
{
@@ -69,9 +68,6 @@ namespace Netch.Utils
{
case null:
break;
case HTTPController httpController:
instances.Add(httpController.PrivoxyController.Instance!);
break;
case NFController _:
instances.Add(Process.GetCurrentProcess());
break;

View File

@@ -62,6 +62,9 @@ namespace Netch.Utils
if (settings.Profiles.Any(p => settings.Profiles.Any(p1 => p1 != p && p1.Index == p.Index)))
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);
}
/// <summary>

View File

@@ -1,77 +0,0 @@
using System;
using System.Net;
using System.Text;
namespace Netch.Utils.HttpProxyHandler
{
public class HttpWebServer
{
private readonly Func<HttpListenerRequest, string>? _responderMethod;
private HttpListener? _listener;
public HttpWebServer(string[] prefixes, Func<HttpListenerRequest, string> method)
{
_listener = new HttpListener();
// URI prefixes are required, for example
// "http://localhost:8080/index/".
if (prefixes == null || prefixes.Length == 0)
throw new ArgumentException("prefixes");
// A responder method is required
if (method == null)
throw new ArgumentException("method");
foreach (var s in prefixes)
_listener.Prefixes.Add(s);
_responderMethod = method;
_listener.Start();
}
public HttpWebServer(Func<HttpListenerRequest, string> method, params string[] prefixes) : this(prefixes, method)
{
}
public void StartWaitingRequest()
{
Logging.Info("Webserver running...");
while (_listener?.IsListening ?? false)
{
HttpListenerContext ctx;
try
{
ctx = _listener.GetContext();
}
catch
{
break;
}
try
{
var rstr = _responderMethod!(ctx.Request);
var buf = Encoding.UTF8.GetBytes(rstr);
ctx.Response.StatusCode = 200;
ctx.Response.ContentType = "application/x-ns-proxy-autoconfig";
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
}
finally
{
ctx.Response.OutputStream.Close();
}
}
}
public void Stop()
{
if (_listener != null)
{
_listener.Stop();
_listener.Close();
_listener = null;
}
}
}
}

View File

@@ -1,83 +0,0 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Netch.Controllers;
namespace Netch.Utils.HttpProxyHandler
{
/// <summary>
/// 提供PAC功能支持
/// </summary>
internal static class PACServerHandle
{
private static HttpWebServer? _httpWebServer;
private static string? _pacContent;
public static readonly string PacPrefix= $"http://127.0.0.1:{Global.Settings.Pac_Port}/pac/";
public static string InitPACServer()
{
try
{
_pacContent = GetPacList("127.0.0.1");
_httpWebServer = new HttpWebServer(SendResponse, PacPrefix);
Task.Run(() => _httpWebServer.StartWaitingRequest());
var pacUrl = GetPacUrl();
Logging.Info($"Webserver InitServer OK: {pacUrl}");
return pacUrl;
}
catch
{
Logging.Error("Webserver InitServer Failed");
throw;
}
}
public static string SendResponse(HttpListenerRequest request)
{
return _pacContent!;
}
public static void Stop()
{
try
{
_httpWebServer?.Stop();
}
catch
{
// ignored
}
_httpWebServer = null;
}
private static string GetPacList(string address)
{
try
{
var proxy = $"PROXY {address}:{Global.Settings.HTTPLocalPort};";
var pacfile = Path.Combine(Global.NetchDir, "bin\\pac.txt");
var pac = File.ReadAllText(pacfile, Encoding.UTF8).Replace("__PROXY__", proxy);
return pac;
}
catch
{
throw new MessageException("Pac file not found!");
}
}
/// <summary>
/// 获取PAC地址
/// </summary>
/// <returns></returns>
public static string GetPacUrl()
{
return PacPrefix + $"?t={DateTime.Now:yyyyMMddHHmmssfff}";
}
}
}

View File

@@ -43,6 +43,7 @@ namespace Netch.Utils
#if DEBUG
switch (logLevel)
{
case LogLevel.DEBUG:
case LogLevel.INFO:
case LogLevel.WARNING:
Console.Write(contents);
@@ -56,6 +57,13 @@ namespace Netch.Utils
#else
lock (FileLock)
File.AppendAllText(LogFile, contents);
#endif
}
public static void Debug(string s)
{
#if DEBUG
Write(s, LogLevel.DEBUG);
#endif
}
}

View File

@@ -83,9 +83,9 @@ namespace Netch.Utils
{
Global.Modes.Add(new Mode(file));
}
catch (Exception)
catch (Exception e)
{
// ignored
Logging.Warning($"Load mode \"{file}\" failed: {e.Message}");
}
}
catch
@@ -109,39 +109,36 @@ namespace Netch.Utils
public static bool SkipServerController(Server server, Mode mode)
{
return mode.Type switch
{
0 => server switch
{
Socks5 => true,
Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.RedirectorSS => true,
_ => false
},
_ => false
};
switch (mode.Type)
{
case 0:
return server switch
{
Socks5 => true,
Shadowsocks shadowsocks when !shadowsocks.HasPlugin() && Global.Settings.Redirector.RedirectorSS => true,
_ => false
};
case 1:
case 2:
return server is Socks5;
default:
return false;
}
}
public static IModeController? GetModeControllerByType(int type, out ushort? port, out string portName)
public static readonly int[] ModeTypes = {0, 1, 2, 6};
public static IModeController GetModeControllerByType(int type, out ushort? port, out string portName)
{
port = null;
portName = string.Empty;
switch (type)
{
case 0:
port = Global.Settings.RedirectorTCPPort;
portName = "Redirector TCP";
return new NFController();
case 1:
case 2:
return new TUNTAPController();
case 3:
case 5:
port = Global.Settings.HTTPLocalPort;
portName = "HTTP";
StatusPortInfoText.HttpPort = (ushort) port;
return new HTTPController();
case 4:
return null;
return new TUNController();
case 6:
return new PcapController();
default:

View File

@@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using Netch.Models;
using static Vanara.PInvoke.IpHlpApi;
using static Vanara.PInvoke.Ws2_32;
using Range = Netch.Models.Range;
namespace Netch.Utils
{

View File

@@ -5,6 +5,7 @@ using System.Reflection;
using System.Threading.Tasks;
using System.Timers;
using Netch.Models;
using Range = Netch.Models.Range;
namespace Netch.Utils
{
@@ -16,7 +17,7 @@ namespace Netch.Utils
.GetExportedTypes()
.Where(type => type.GetInterfaces().Contains(typeof(IServerUtil)));
ServerUtils = serversUtilsTypes.Select(t => (IServerUtil) Activator.CreateInstance(t)).OrderBy(util => util.Priority);
ServerUtils = serversUtilsTypes.Select(t => (IServerUtil) Activator.CreateInstance(t)!).OrderBy(util => util.Priority);
}
public static Type GetTypeByTypeName(string typeName)

View File

@@ -32,7 +32,7 @@ namespace Netch.Utils
try
{
list.AddRange(JsonSerializer.Deserialize<List<ShadowsocksConfig>>(text)
list.AddRange(JsonSerializer.Deserialize<List<ShadowsocksConfig>>(text)!
.Select(server => new Shadowsocks
{
Hostname = server.server,

View File

@@ -60,12 +60,12 @@ namespace Netch.Utils
public static string[] SplitRemoveEmptyEntriesAndTrimEntries(this string value, params char[] separator)
{
return value.Split(separator).Select(s => s.Trim()).Where(s => s != string.Empty).ToArray();
return value.Split(separator, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
}
public static string[] SplitTrimEntries(this string value, params char[] separator)
{
return value.Split(separator).Select(s => s.Trim()).ToArray();
return value.Split(separator, StringSplitOptions.TrimEntries);
}
public static string[] SplitRemoveEmptyEntries(this string value, params char[] separator)

View File

@@ -1,103 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Win32;
using Netch.Controllers;
namespace Netch.Utils
{
public static class TUNTAP
{
public static string TUNTAP_COMPONENT_ID_0901 = "tap0901";
public static string TUNTAP_COMPONENT_ID_0801 = "tap0801";
public static string NETWORK_KEY = @"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}";
public static string ADAPTER_KEY = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}";
/// <summary>
/// 获取 TUN/TAP 适配器 ID
/// </summary>
/// <returns>适配器 ID</returns>
public static string? GetComponentID()
{
try
{
var adaptersRegistry = Registry.LocalMachine.OpenSubKey(ADAPTER_KEY)!;
foreach (var keyName in adaptersRegistry.GetSubKeyNames().Where(s => s is not ("Configuration" or "Properties")))
{
var adapterRegistry = adaptersRegistry.OpenSubKey(keyName)!;
var componentId = adapterRegistry.GetValue("ComponentId")?.ToString();
if (componentId == null)
continue;
if (componentId == TUNTAP_COMPONENT_ID_0901 || componentId == TUNTAP_COMPONENT_ID_0801)
return (string) (adapterRegistry.GetValue("NetCfgInstanceId") ??
throw new Exception("Tap adapter have no NetCfgInstanceId key"));
}
}
catch (Exception e)
{
Logging.Warning(e.ToString());
}
return null;
}
/// <summary>
/// 获取 TUN/TAP 适配器名称
/// </summary>
/// <param name="componentId">适配器 ID</param>
/// <returns>适配器名称</returns>
public static string GetName(string componentId)
{
var registry = Registry.LocalMachine.OpenSubKey($"{NETWORK_KEY}\\{componentId}\\Connection");
return registry.GetValue("Name", "").ToString();
}
/// <summary>
/// 创建 TUN/TAP 适配器
/// </summary>
/// <returns></returns>
public static bool Create()
{
return false;
}
/// <summary>
/// 卸载tap网卡
/// </summary>
public static void deltapall()
{
Logging.Info("卸载 TUN/TAP 适配器");
var installProcess = new Process
{StartInfo = {WindowStyle = ProcessWindowStyle.Hidden, FileName = Path.Combine("bin/tap-driver", "deltapall.bat")}};
installProcess.Start();
installProcess.WaitForExit();
installProcess.Close();
}
/// <summary>
/// 安装tap网卡
/// </summary>
public static void AddTap()
{
Logging.Info("安装 TUN/TAP 适配器");
//安装Tap Driver
using var process = Process.Start(new ProcessStartInfo
{
FileName = Path.Combine("bin/tap-driver", "addtap.bat"),
WindowStyle = ProcessWindowStyle.Hidden
})!;
process.WaitForExit();
Thread.Sleep(1000);
if (GetComponentID() == null)
throw new MessageException("TAP 驱动安装失败,找不到 ComponentID 注册表项");
}
}
}

View File

@@ -116,7 +116,10 @@ namespace Netch.Utils
public static string GetFileVersion(string file)
{
return File.Exists(file) ? FileVersionInfo.GetVersionInfo(file).FileVersion : string.Empty;
if (File.Exists(file))
return FileVersionInfo.GetVersionInfo(file).FileVersion ?? "";
return "";
}
public static void DrawCenterComboBox(object sender, DrawItemEventArgs e)
@@ -222,5 +225,55 @@ namespace Netch.Utils
break;
}
}
public static async Task ProcessRunHiddenAsync(string fileName, string arguments = "", bool print = true)
{
var p = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
Arguments = arguments,
WindowStyle = ProcessWindowStyle.Hidden,
Verb = "runas",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
Logging.Debug($"{fileName} {arguments}");
p.Start();
var output = await p.StandardOutput.ReadToEndAsync();
var error = await p.StandardError.ReadToEndAsync();
if (print)
{
Console.Write(output);
Console.Write(error);
}
p.WaitForExit();
}
public static int SubnetToCidr(string value)
{
var subnet = IPAddress.Parse(value);
return SubnetToCidr(subnet);
}
public static int SubnetToCidr(IPAddress subnet)
{
return subnet.GetAddressBytes().Sum(b => Convert.ToString(b, 2).Count(c => c == '1'));
}
public static string HostAppendPort(string host, ushort port = 53)
{
if (!host.Contains(':'))
host += $":{port}";
return host;
}
}
}

View File

@@ -1,6 +1,5 @@
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
@@ -30,13 +29,6 @@ namespace Netch.Utils
return req;
}
public static IPEndPoint BestLocalEndPoint(IPEndPoint remoteIPEndPoint)
{
var testSocket = new Socket(remoteIPEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
testSocket.Connect(remoteIPEndPoint);
return (IPEndPoint) testSocket.LocalEndPoint;
}
/// <summary>
/// 异步下载
/// </summary>
@@ -44,9 +36,9 @@ namespace Netch.Utils
/// <returns></returns>
public static async Task<byte[]> DownloadBytesAsync(HttpWebRequest req)
{
using var webResponse = (HttpWebResponse) await req.GetResponseAsync();
using var memoryStream = new MemoryStream();
using var input = webResponse.GetResponseStream();
using var webResponse = req.GetResponseAsync();
await using var memoryStream = new MemoryStream();
await using var input = webResponse.Result.GetResponseStream();
await input.CopyToAsync(memoryStream);
return memoryStream.ToArray();
@@ -77,7 +69,7 @@ namespace Netch.Utils
public static async Task<string> DownloadStringAsync(HttpWebRequest req, string encoding = "UTF-8")
{
using var webResponse = await req.GetResponseAsync();
using var responseStream = webResponse.GetResponseStream();
await using var responseStream = webResponse.GetResponseStream();
using var streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encoding));
return await streamReader.ReadToEndAsync();
@@ -92,8 +84,8 @@ namespace Netch.Utils
public static async Task DownloadFileAsync(HttpWebRequest req, string fileFullPath)
{
using var webResponse = (HttpWebResponse) await req.GetResponseAsync();
using var input = webResponse.GetResponseStream();
using var fileStream = File.OpenWrite(fileFullPath);
await using var input = webResponse.GetResponseStream();
await using var fileStream = File.OpenWrite(fileFullPath);
await input.CopyToAsync(fileStream);
fileStream.Flush();

View File

@@ -88,7 +88,7 @@ namespace Netch.Utils
var a = new StringBuilder();
foreach (var t in text)
if (t is string)
a.Append(Data.Contains(t) ? Data[t].ToString() : t);
a.Append(Data[t]?.ToString() ?? t);
else
a.Append(t);

16
PUBLISH.ps1 Normal file
View File

@@ -0,0 +1,16 @@
Write-Host 'Building'
dotnet publish `
-c "Release" `
-r "win-x64" `
-p:Platform="x64" `
-p:PublishSingleFile=true `
-p:SelfContained=false `
-p:PublishTrimmed=false `
-p:PublishReadyToRun=false `
-o Netch\bin\Publish\ `
Netch\Netch.csproj
if ($LASTEXITCODE) { exit $LASTEXITCODE }
Write-Host 'Build done'

View File

@@ -49,24 +49,20 @@ As well, Netch avoid the restricted NAT problem caused by SSTap. You can use an
![](images/screenshots/main.png)
## Requirements
- [.NET Framework 4.8 (Included in Windows 10 1903+)](https://dotnet.microsoft.com/download/dotnet-framework/net48)
- [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0/runtime)
## Quote
- [core](https://github.com/aiocloud/core)
- [aiodns](https://github.com/aiocloud/aiodns)
- [tun2socks](https://github.com/aiocloud/tun2socks)
- [Redirector](https://github.com/aiocloud/Redirector)
- [go-tun2socks](https://github.com/eycorsican/go-tun2socks)
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
- [NetFilter SDK](https://netfiltersdk.com)
- [pcap2socks](https://github.com/zhxie/pcap2socks)
- [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev)
- [shadowsocksr-libev](https://github.com/shadowsocksrr/shadowsocksr-libev)
- [Xray-core](https://github.com/XTLS/Xray-core)
- [trojan](https://github.com/trojan-gfw/trojan)
- [ACL4SSR](https://github.com/ACL4SSR/ACL4SSR)
- [PAC](https://github.com/HMBSbige/Text_Translation/blob/master/ShadowsocksR/ss_white.pac)
- [xray-core](https://github.com/XTLS/Xray-core)
- [dnsmasq-china-list](https://github.com/felixonmars/dnsmasq-china-list)
- [tap-windows6](https://github.com/OpenVPN/tap-windows6)
- [Privoxy](https://www.privoxy.org/)
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
- [NetFilter SDK](https://netfiltersdk.com/)
- [pcap2socks](https://github.com/zhxie/pcap2socks)
[![Stargazers over time](https://starchart.cc/NetchX/Netch.svg)](https://starchart.cc/NetchX/Netch)

View File

@@ -44,7 +44,7 @@ Netch 是一款 Windows 平台的开源游戏加速工具Netch 可以实现
- XMR *48ju3ELNZEa6wwPBMexCJ9G218BGY2XwhH6B6bmkFuJ3QgM4hPw2Pra35jPtuBZSc7SLNWeBpiWJZWjQeMAiLnTx2tH2Efx*
## 依赖
- [.NET Framework 4.8 (Windows 10 1903+ 已包含)](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net48-offline-installer)
- [.NET 5](https://dotnet.microsoft.com/download/dotnet/5.0/runtime)
## 语言支持
Netch 内置 en-US 和 zh-CN外置 zh-TW 等,默认根据系统语言选择语言。
@@ -54,17 +54,15 @@ Netch 内置 en-US 和 zh-CN外置 zh-TW 等,默认根据系统语言选择
## 引用
- [core](https://github.com/aiocloud/core)
- [aiodns](https://github.com/aiocloud/aiodns)
- [tun2socks](https://github.com/aiocloud/tun2socks)
- [Redirector](https://github.com/aiocloud/Redirector)
- [go-tun2socks](https://github.com/eycorsican/go-tun2socks)
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
- [NetFilter SDK](https://netfiltersdk.com)
- [pcap2socks](https://github.com/zhxie/pcap2socks)
- [shadowsocks-libev](https://github.com/shadowsocks/shadowsocks-libev)
- [shadowsocksr-libev](https://github.com/shadowsocksrr/shadowsocksr-libev)
- [Xray-core](https://github.com/XTLS/Xray-core)
- [trojan](https://github.com/trojan-gfw/trojan)
- [ACL4SSR](https://github.com/ACL4SSR/ACL4SSR)
- [PAC](https://github.com/HMBSbige/Text_Translation/blob/master/ShadowsocksR/ss_white.pac)
- [xray-core](https://github.com/XTLS/Xray-core)
- [dnsmasq-china-list](https://github.com/felixonmars/dnsmasq-china-list)
- [tap-windows6](https://github.com/OpenVPN/tap-windows6)
- [Privoxy](https://www.privoxy.org/)
- [NatTypeTester](https://github.com/HMBSbige/NatTypeTester)
- [NetFilter SDK](https://netfiltersdk.com/)
- [pcap2socks](https://github.com/zhxie/pcap2socks)
[![Stargazers over time](https://starchart.cc/NetchX/Netch.svg)](https://starchart.cc/NetchX/Netch)

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SearchComboBox")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SearchComboBox")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a8715af4-acc6-43f9-9381-4294c5360623")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,179 +0,0 @@
using System.Linq;
namespace System.Windows.Forms
{
[System.ComponentModel.DesignerCategory(@"Code")]
public class SearchComboBox : ComboBox
{
public SearchComboBox()
{
AutoCompleteMode = AutoCompleteMode.Suggest;
}
private string prevKeyword;
private string Keyword
{
get => _keyword;
set
{
prevKeyword = _keyword;
if (value == null)
{
_keyword = null;
return;
}
if (_keyword == value)
{
return;
}
_keyword = value;
ReevaluateCompletionList();
}
}
protected override void OnTextChanged(EventArgs e)
{
try
{
if (string.IsNullOrEmpty(Text))
{
if (!IsOriginalItems)
ResetCompletionList();
Keyword = null;
}
else
{
if (AutoFillTag.All(o => o.ToString() != Text))
{
Keyword = Text;
}
}
}
finally
{
base.OnTextChanged(e);
}
}
private object[] AutoFillTag
{
get
{
if (Tag == null)
{
Tag = Items.Cast<object>().ToArray();
}
return (object[]) Tag;
}
}
private bool IsOriginalItems => Items.Count == AutoFillTag.Length;
public void ResetCompletionList()
{
Keyword = null;
try
{
SuspendLayout();
if (IsOriginalItems)
return;
Items.Clear();
Items.AddRange(AutoFillTag);
}
finally
{
ResumeLayout(true);
}
}
private static int findFirstDifIndex(string s1, string s2)
{
for (var i = 0; i < Math.Min(s1.Length, s2.Length); i++)
if (s1[i] != s2[i])
return i;
return -1;
}
private object[] _newList;
private string _keyword;
private void ReevaluateCompletionList()
{
SuspendLayout();
var keyword = Keyword.ToLowerInvariant().Trim();
var selectionStart = SelectionStart;
if (selectionStart == Text.Length)
{
selectionStart = -1;
}
else
{
selectionStart = findFirstDifIndex(prevKeyword, Keyword);
}
try
{
var originalList = AutoFillTag;
if (originalList == null)
{
Tag = originalList = Items.Cast<object>().ToArray();
}
if (string.IsNullOrEmpty(Keyword))
{
ResetCompletionList();
return;
}
else
{
_newList = originalList.Where(x => x.ToString().ToLowerInvariant().Contains(keyword)).ToArray();
}
if (_newList.Any())
{
Items.Clear();
Items.AddRange(_newList.ToArray());
if (!DroppedDown)
{
DroppedDown = true;
}
else
{
// TODO 预期下拉框高度变长则重新打开下拉框
}
Cursor.Current = Cursors.Default;
}
else
{
DroppedDown = false;
Items.Clear();
}
if (selectionStart == -1)
{
Select(Text.Length, 0);
}
else
{
Select(selectionStart + 1, 0);
}
}
finally
{
ResumeLayout(true);
}
}
}
}

View File

@@ -1,21 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<Platforms>AnyCPU</Platforms>
<UseWindowsForms>true</UseWindowsForms>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<!-- NET Framework -->
<Reference Include="System.Windows.Forms" />
</ItemGroup>
</Project>

View File

@@ -28,5 +28,17 @@ namespace UnitTest
TestLoad("");
TestLoad("-");
}
[TestMethod]
public void TestMaskToCidr()
{
Assert.AreEqual(Utils.SubnetToCidr("0.0.0.0"), 0);
Assert.AreEqual(Utils.SubnetToCidr("248.0.0.0"), 5);
Assert.AreEqual(Utils.SubnetToCidr("255.0.0.0"), 8);
Assert.AreEqual(Utils.SubnetToCidr("255.255.0.0"), 16);
Assert.AreEqual(Utils.SubnetToCidr("255.255.248.0"), 21);
Assert.AreEqual(Utils.SubnetToCidr("255.255.255.0"), 24);
Assert.AreEqual(Utils.SubnetToCidr("255.255.255.255"), 32);
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<TargetFramework>net5.0-windows</TargetFramework>
<Platforms>x64</Platforms>
<UseWindowsForms>true</UseWindowsForms>
<LangVersion>latest</LangVersion>
@@ -17,11 +17,6 @@
<ProjectReference Include="..\Netch\Netch.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<!-- NET Framework -->
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />

2
modes

Submodule modes updated: 72ad96d018...27d099ea8e