mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f82cac1d6 | ||
|
|
2d295a1449 | ||
|
|
5826d1a1a6 | ||
|
|
072f2d16e6 | ||
|
|
ecaab55934 | ||
|
|
3c93aff15d | ||
|
|
de856dd2ec | ||
|
|
a4a221ef2f | ||
|
|
1dbda9cbf9 | ||
|
|
cecae73c03 | ||
|
|
0d535aa27e | ||
|
|
03c3c151bf | ||
|
|
7a3b5ff487 | ||
|
|
598ff19535 | ||
|
|
d02135f31b | ||
|
|
a7756dabc1 | ||
|
|
7ce1127006 | ||
|
|
fec84a4952 | ||
|
|
d335c69fab | ||
|
|
1228a565c1 | ||
|
|
dc904c9c0b | ||
|
|
d829e347d3 | ||
|
|
a01761d2e2 | ||
|
|
68d87e2ff2 | ||
|
|
04d6933319 | ||
|
|
e46eef17d0 | ||
|
|
d3c3958dab | ||
|
|
5ec8d38fd1 | ||
|
|
2a8754ecfb | ||
|
|
cbc6822bff | ||
|
|
96bd7473ca | ||
|
|
54b2b87dec | ||
|
|
42baed8b8f | ||
|
|
f68aae6795 | ||
|
|
8e2008077d | ||
|
|
5b4f0026ff | ||
|
|
89f9dccb87 | ||
|
|
3e377f2e9d | ||
|
|
635212f24d | ||
|
|
46d60babbc | ||
|
|
8f80f9abef | ||
|
|
e268f1838f | ||
|
|
d99229ad50 | ||
|
|
df85d5797d | ||
|
|
74856ccd61 | ||
|
|
0165d080c6 | ||
|
|
97fb20e326 | ||
|
|
4d71e2d12f | ||
|
|
0fa83eac3c | ||
|
|
aa6623b063 | ||
|
|
94335ad900 | ||
|
|
baf3b39dd3 | ||
|
|
c12122f7d0 | ||
|
|
3e5a4fc102 | ||
|
|
57dbd0193a | ||
|
|
5647a6c7ea | ||
|
|
773bad4845 | ||
|
|
3e943ec6b8 | ||
|
|
920b068a1e | ||
|
|
7eac7b0837 |
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@@ -1,13 +1,18 @@
|
||||
name: Netch Build CI
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
uses: microsoft/setup-msbuild@v1.0.3
|
||||
with:
|
||||
vs-prerelease: true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
9
.github/workflows/release.yml
vendored
9
.github/workflows/release.yml
vendored
@@ -7,10 +7,12 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
uses: microsoft/setup-msbuild@v1.0.3
|
||||
with:
|
||||
vs-prerelease: true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
@@ -41,6 +43,9 @@ jobs:
|
||||
Netch.7z
|
||||
body: |
|
||||
[](https://t.me/netch_channel) [](https://t.me/netch_group)
|
||||
|
||||
[**第一次使用请务必先安装 .NET 5.0 运行库**](https://aka.ms/dotnet/5.0/windowsdesktop-runtime-win-x64.exe)
|
||||
|
||||
## Changelogs
|
||||
* This is an automated deployment of GitHub Actions, the change log should be updated manually soon
|
||||
|
||||
|
||||
11
Netch.sln
11
Netch.sln
@@ -11,9 +11,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AdditionalFiles", "Addition
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.gitignore = .gitignore
|
||||
common.props = common.props
|
||||
global.json = global.json
|
||||
LICENSE = LICENSE
|
||||
README.md = README.md
|
||||
global.json = global.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
@@ -26,10 +27,10 @@ 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
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Debug|x64.Build.0 = Debug|x64
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Release|x64.ActiveCfg = Release|x64
|
||||
{38240783-9AD2-4A01-84C1-1A3E5F05720F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -23,5 +23,9 @@
|
||||
}
|
||||
|
||||
public const string WintunDllFile = "bin\\wintun.dll";
|
||||
public const string DisableModeDirectoryFileName = "disabled";
|
||||
|
||||
public const string DefaultPrimaryDNS = "1.1.1.1:53";
|
||||
public const string DefaultCNPrimaryDNS = "223.5.5.5:53";
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,8 @@ namespace Netch.Controllers
|
||||
var listenAddress = Global.Settings.LocalAddress;
|
||||
|
||||
Dial(NameList.TYPE_REST, "");
|
||||
Dial(NameList.TYPE_ADDR, $"{listenAddress}:{aioDnsConfig.ListenPort}");
|
||||
Dial(NameList.TYPE_LIST, Path.GetFullPath(Constants.AioDnsRuleFile));
|
||||
Dial(NameList.TYPE_LISN, $"{listenAddress}:{aioDnsConfig.ListenPort}");
|
||||
Dial(NameList.TYPE_CDNS, $"{aioDnsConfig.ChinaDNS}");
|
||||
Dial(NameList.TYPE_ODNS, $"{aioDnsConfig.OtherDNS}");
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
using Netch.Enums;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
@@ -156,7 +157,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
Log.Error(e, "停止 {Name} 异常", Instance.ProcessName);
|
||||
Log.Error(e, "Stop {Name} failed", Instance.ProcessName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -1,56 +1,85 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Servers;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public static class MainController
|
||||
{
|
||||
public static Mode? Mode { get; private set; }
|
||||
public static Socks5Server? Socks5Server { get; private set; }
|
||||
|
||||
public static readonly NTTController NTTController = new();
|
||||
public static Server? Server { get; private set; }
|
||||
|
||||
public static Mode? Mode { get; private set; }
|
||||
|
||||
public static IServerController? ServerController { get; private set; }
|
||||
|
||||
public static IModeController? ModeController { get; private set; }
|
||||
|
||||
private static readonly AsyncSemaphore Lock = new(1);
|
||||
|
||||
public static async Task StartAsync(Server server, Mode mode)
|
||||
{
|
||||
using var releaser = await Lock.EnterAsync();
|
||||
|
||||
Log.Information("Start MainController: {Server} {Mode}", $"{server.Type}", $"[{(int)mode.Type}]{mode.Remark}");
|
||||
|
||||
if (await DnsUtils.LookupAsync(server.Hostname) == null)
|
||||
throw new MessageException(i18N.Translate("Lookup Server hostname failed"));
|
||||
|
||||
// TODO Disable NAT Type Test setting
|
||||
// cache STUN Server ip to prevent "Wrong STUN Server"
|
||||
DnsUtils.LookupAsync(Global.Settings.STUN_Server).Forget();
|
||||
|
||||
Server = server;
|
||||
Mode = mode;
|
||||
|
||||
await Task.WhenAll(
|
||||
Task.Run(NativeMethods.RefreshDNSCache),
|
||||
Task.Run(Firewall.AddNetchFwRules)
|
||||
);
|
||||
|
||||
if (Log.IsEnabled(LogEventLevel.Debug))
|
||||
Task.Run(() =>
|
||||
{
|
||||
// TODO log level setting
|
||||
Log.Debug("Running Processes: \n{Processes}", string.Join("\n", SystemInfo.Processes(false)));
|
||||
})
|
||||
.Forget();
|
||||
await Task.WhenAll(Task.Run(NativeMethods.RefreshDNSCache), Task.Run(Firewall.AddNetchFwRules));
|
||||
|
||||
try
|
||||
{
|
||||
if (!ModeHelper.SkipServerController(server, mode))
|
||||
server = await StartServerAsync(server);
|
||||
ModeController = ModeService.GetModeControllerByType(mode.Type, out var modePort, out var portName);
|
||||
|
||||
await StartModeAsync(server, mode);
|
||||
if (modePort != null)
|
||||
TryReleaseTcpPort((ushort)modePort, portName);
|
||||
|
||||
if (Server is Socks5Server socks5 && (!socks5.Auth() || ModeController.Features.HasFlag(ModeFeature.SupportSocks5Auth)))
|
||||
{
|
||||
Socks5Server = socks5;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start Server Controller to get a local socks5 server
|
||||
Log.Debug("Server Information: {Data}", $"{server.Type} {server.MaskedData()}");
|
||||
|
||||
ServerController = ServerHelper.GetUtilByTypeName(server.Type).GetController();
|
||||
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ServerController.Name));
|
||||
|
||||
TryReleaseTcpPort(ServerController.Socks5LocalPort(), "Socks5");
|
||||
Socks5Server = await ServerController.StartAsync(server);
|
||||
|
||||
StatusPortInfoText.Socks5Port = Socks5Server.Port;
|
||||
StatusPortInfoText.UpdateShareLan();
|
||||
}
|
||||
|
||||
// Start Mode Controller
|
||||
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ModeController.Name));
|
||||
|
||||
await ModeController.StartAsync(Socks5Server, mode);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
releaser.Dispose();
|
||||
await StopAsync();
|
||||
|
||||
switch (e)
|
||||
@@ -68,49 +97,26 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<Server> StartServerAsync(Server server)
|
||||
{
|
||||
ServerController = ServerHelper.GetUtilByTypeName(server.Type).GetController();
|
||||
|
||||
TryReleaseTcpPort(ServerController.Socks5LocalPort(), "Socks5");
|
||||
|
||||
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ServerController.Name));
|
||||
|
||||
Log.Debug("Server Information: {Data}", $"{server.Type} {server.MaskedData()}");
|
||||
var socks5 = await ServerController.StartAsync(server);
|
||||
|
||||
StatusPortInfoText.Socks5Port = socks5.Port;
|
||||
StatusPortInfoText.UpdateShareLan();
|
||||
|
||||
return socks5;
|
||||
}
|
||||
|
||||
private static async Task StartModeAsync(Server server, Mode mode)
|
||||
{
|
||||
ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName);
|
||||
|
||||
if (port != null)
|
||||
TryReleaseTcpPort((ushort)port, portName);
|
||||
|
||||
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ModeController.Name));
|
||||
|
||||
await ModeController.StartAsync(server, mode);
|
||||
}
|
||||
|
||||
public static async Task StopAsync()
|
||||
{
|
||||
if (Lock.CurrentCount == 0)
|
||||
{
|
||||
(await Lock.EnterAsync()).Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
using var _ = await Lock.EnterAsync();
|
||||
|
||||
if (ServerController == null && ModeController == null)
|
||||
return;
|
||||
|
||||
Log.Information("Stop Main Controller");
|
||||
StatusPortInfoText.Reset();
|
||||
|
||||
Task.Run(() => NTTController.StopAsync()).Forget();
|
||||
|
||||
var tasks = new[]
|
||||
{
|
||||
Task.Run(() => ServerController?.StopAsync()),
|
||||
Task.Run(() => ModeController?.StopAsync())
|
||||
ServerController?.StopAsync() ?? Task.CompletedTask,
|
||||
ModeController?.StopAsync() ?? Task.CompletedTask
|
||||
};
|
||||
|
||||
try
|
||||
@@ -122,8 +128,8 @@ namespace Netch.Controllers
|
||||
Log.Error(e, "MainController Stop Error");
|
||||
}
|
||||
|
||||
ModeController = null;
|
||||
ServerController = null;
|
||||
ModeController = null;
|
||||
}
|
||||
|
||||
public static void PortCheck(ushort port, string portName, PortType portType = PortType.Both)
|
||||
@@ -163,5 +169,30 @@ namespace Netch.Controllers
|
||||
|
||||
PortCheck(port, portName, PortType.TCP);
|
||||
}
|
||||
|
||||
public static async Task<NatTypeTestResult> DiscoveryNatTypeAsync(CancellationToken ctx = default)
|
||||
{
|
||||
Debug.Assert(Socks5Server != null, nameof(Socks5Server) + " != null");
|
||||
return await Socks5ServerTestUtils.DiscoveryNatTypeAsync(Socks5Server, ctx);
|
||||
}
|
||||
|
||||
public static async Task<int?> HttpConnectAsync(CancellationToken ctx = default)
|
||||
{
|
||||
Debug.Assert(Socks5Server != null, nameof(Socks5Server) + " != null");
|
||||
try
|
||||
{
|
||||
return await Socks5ServerTestUtils.HttpConnectAsync(Socks5Server, ctx);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Warning(e, "Unhandled Socks5ServerTestUtils.HttpConnectAsync Exception");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Interops;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Models.Modes.ProcessMode;
|
||||
using Netch.Servers;
|
||||
using Netch.Servers.Shadowsocks;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
using static Netch.Interops.Redirector;
|
||||
@@ -19,7 +19,7 @@ namespace Netch.Controllers
|
||||
public class NFController : IModeController
|
||||
{
|
||||
private Server? _server;
|
||||
private Mode? _mode;
|
||||
private Redirector _mode = null!;
|
||||
private RedirectorConfig _rdrConfig = null!;
|
||||
|
||||
private static readonly ServiceController NFService = new("netfilter2");
|
||||
@@ -28,29 +28,55 @@ namespace Netch.Controllers
|
||||
|
||||
public string Name => "Redirector";
|
||||
|
||||
public async Task StartAsync(Server server, Mode mode)
|
||||
public ModeFeature Features => ModeFeature.SupportIPv6 | ModeFeature.SupportSocks5Auth;
|
||||
|
||||
public async Task StartAsync(Socks5Server server, Mode mode)
|
||||
{
|
||||
if (mode is not Redirector processMode)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
_server = server;
|
||||
_mode = mode;
|
||||
_mode = processMode;
|
||||
_rdrConfig = Global.Settings.Redirector;
|
||||
|
||||
CheckDriver();
|
||||
|
||||
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());
|
||||
Dial(NameList.AIO_FILTERLOOPBACK, _mode.FilterLoopback);
|
||||
Dial(NameList.AIO_FILTERINTRANET, _mode.FilterIntranet);
|
||||
Dial(NameList.AIO_FILTERPARENT, _mode.FilterParent ?? _rdrConfig.HandleOnlyDNS);
|
||||
Dial(NameList.AIO_FILTERICMP, _mode.FilterICMP ?? _rdrConfig.FilterICMP);
|
||||
if (_mode.FilterICMP ?? _rdrConfig.FilterICMP)
|
||||
Dial(NameList.AIO_ICMPING, (_mode.FilterICMP != null ? _mode.ICMPDelay ?? 10 : _rdrConfig.ICMPDelay).ToString());
|
||||
|
||||
Dial(NameList.AIO_FILTERTCP, _mode.FilterTCP ?? _rdrConfig.FilterTCP);
|
||||
Dial(NameList.AIO_FILTERUDP, _mode.FilterUDP ?? _rdrConfig.FilterUDP);
|
||||
|
||||
// DNS
|
||||
Dial(NameList.AIO_FILTERDNS, _mode.FilterDNS ?? _rdrConfig.FilterDNS);
|
||||
Dial(NameList.AIO_DNSONLY, _mode.HandleOnlyDNS ?? _rdrConfig.HandleOnlyDNS);
|
||||
Dial(NameList.AIO_DNSPROX, _mode.DNSProxy ?? _rdrConfig.DNSProxy);
|
||||
if (_mode.FilterDNS ?? _rdrConfig.FilterDNS)
|
||||
{
|
||||
var dnsStr = _mode.FilterDNS != null ? _mode.DNSHost : _rdrConfig.DNSHost;
|
||||
|
||||
dnsStr = dnsStr.ValueOrDefault() ?? Constants.DefaultPrimaryDNS;
|
||||
|
||||
var dns = IPEndPoint.Parse(dnsStr);
|
||||
if (dns.Port == 0)
|
||||
dns.Port = 53;
|
||||
|
||||
Dial(NameList.AIO_DNSHOST, dns.Address.ToString());
|
||||
Dial(NameList.AIO_DNSPORT, dns.Port.ToString());
|
||||
}
|
||||
|
||||
// Server
|
||||
Dial(NameList.TYPE_FILTERUDP, _rdrConfig.FilterProtocol.HasFlag(PortType.UDP).ToString().ToLower());
|
||||
Dial(NameList.TYPE_FILTERTCP, _rdrConfig.FilterProtocol.HasFlag(PortType.TCP).ToString().ToLower());
|
||||
await DialServerAsync(_rdrConfig.FilterProtocol, _server);
|
||||
Dial(NameList.AIO_TGTHOST, await server.AutoResolveHostnameAsync());
|
||||
Dial(NameList.AIO_TGTPORT, server.Port.ToString());
|
||||
Dial(NameList.AIO_TGTUSER, server.Username ?? string.Empty);
|
||||
Dial(NameList.AIO_TGTPASS, server.Password ?? string.Empty);
|
||||
|
||||
// Mode Rule
|
||||
dial_Name(_mode);
|
||||
|
||||
// Features
|
||||
Dial(NameList.TYPE_DNSHOST, _rdrConfig.DNSHijack ? _rdrConfig.DNSHijackHost : "");
|
||||
DialRule();
|
||||
|
||||
if (!await InitAsync())
|
||||
throw new MessageException("Redirector start failed.");
|
||||
@@ -73,14 +99,14 @@ namespace Netch.Controllers
|
||||
try
|
||||
{
|
||||
if (r.StartsWith("!"))
|
||||
return Dial(NameList.TYPE_ADDNAME, r.Substring(1));
|
||||
return Dial(NameList.AIO_ADDNAME, r.Substring(1));
|
||||
|
||||
return Dial(NameList.TYPE_ADDNAME, r);
|
||||
return Dial(NameList.AIO_ADDNAME, r);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (clear)
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
Dial(NameList.AIO_CLRNAME, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,72 +118,38 @@ namespace Netch.Controllers
|
||||
public static bool CheckRules(IEnumerable<string> rules, out IEnumerable<string> results)
|
||||
{
|
||||
results = rules.Where(r => !CheckCppRegex(r, false));
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
Dial(NameList.AIO_CLRNAME, "");
|
||||
return !results.Any();
|
||||
}
|
||||
|
||||
public static string GenerateInvalidRulesMessage(IEnumerable<string> rules)
|
||||
{
|
||||
return $"{string.Join("\n", rules)}\nAbove rules does not conform to C++ regular expression syntax";
|
||||
return $"{string.Join("\n", rules)}\n" + i18N.Translate("Above rules does not conform to C++ regular expression syntax");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private async Task DialServerAsync(PortType portType, Server server)
|
||||
private void DialRule()
|
||||
{
|
||||
if (portType == PortType.Both)
|
||||
{
|
||||
await DialServerAsync(PortType.TCP, server);
|
||||
await DialServerAsync(PortType.UDP, server);
|
||||
return;
|
||||
}
|
||||
|
||||
var offset = portType == PortType.UDP ? UdpNameListOffset : 0;
|
||||
|
||||
if (server is Socks5 socks5)
|
||||
{
|
||||
Dial(NameList.TYPE_TCPTYPE + offset, "Socks5");
|
||||
Dial(NameList.TYPE_TCPHOST + offset, $"{await socks5.AutoResolveHostnameAsync()}:{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() && _rdrConfig.RedirectorSS)
|
||||
{
|
||||
Dial(NameList.TYPE_TCPTYPE + offset, "Shadowsocks");
|
||||
Dial(NameList.TYPE_TCPHOST + offset, $"{await shadowsocks.AutoResolveHostnameAsync()}:{shadowsocks.Port}");
|
||||
Dial(NameList.TYPE_TCPMETH + offset, shadowsocks.EncryptMethod);
|
||||
Dial(NameList.TYPE_TCPPASS + offset, shadowsocks.Password);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace.Assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void dial_Name(Mode mode)
|
||||
{
|
||||
Dial(NameList.TYPE_CLRNAME, "");
|
||||
Dial(NameList.AIO_CLRNAME, "");
|
||||
var invalidList = new List<string>();
|
||||
foreach (var s in mode.GetRules())
|
||||
foreach (var s in _mode.Bypass)
|
||||
{
|
||||
if (s.StartsWith("!"))
|
||||
{
|
||||
if (!Dial(NameList.TYPE_BYPNAME, s.Substring(1)))
|
||||
invalidList.Add(s);
|
||||
if (!Dial(NameList.AIO_BYPNAME, s))
|
||||
invalidList.Add(s);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Dial(NameList.TYPE_ADDNAME, s))
|
||||
foreach (var s in _mode.Handle)
|
||||
{
|
||||
if (!Dial(NameList.AIO_ADDNAME, s))
|
||||
invalidList.Add(s);
|
||||
}
|
||||
|
||||
if (invalidList.Any())
|
||||
throw new MessageException(GenerateInvalidRulesMessage(invalidList));
|
||||
|
||||
Dial(NameList.TYPE_ADDNAME, @"NTT\.exe");
|
||||
Dial(NameList.TYPE_BYPNAME, "^" + Global.NetchDir.ToRegexString() + @"((?!NTT\.exe).)*$");
|
||||
// Bypass Self
|
||||
Dial(NameList.AIO_BYPNAME, "^" + Global.NetchDir.ToRegexString());
|
||||
}
|
||||
|
||||
#region DriverUtil
|
||||
@@ -167,8 +159,8 @@ namespace Netch.Controllers
|
||||
var binFileVersion = Utils.Utils.GetFileVersion(Constants.NFDriver);
|
||||
var systemFileVersion = Utils.Utils.GetFileVersion(SystemDriver);
|
||||
|
||||
Log.Information("内置驱动版本: {Name}", binFileVersion);
|
||||
Log.Information("系统驱动版本: {Name}", systemFileVersion);
|
||||
Log.Information("Built-in netfilter2 driver version: {Name}", binFileVersion);
|
||||
Log.Information("Installed netfilter2 driver version: {Name}", systemFileVersion);
|
||||
|
||||
if (!File.Exists(SystemDriver))
|
||||
{
|
||||
@@ -198,7 +190,7 @@ namespace Netch.Controllers
|
||||
if (!reinstall)
|
||||
return;
|
||||
|
||||
Log.Information("更新驱动");
|
||||
Log.Information("Update netfilter2 driver");
|
||||
UninstallDriver();
|
||||
InstallDriver();
|
||||
}
|
||||
@@ -209,7 +201,8 @@ namespace Netch.Controllers
|
||||
/// <returns>驱动是否安装成功</returns>
|
||||
private static void InstallDriver()
|
||||
{
|
||||
Log.Information("安装 NF 驱动");
|
||||
Log.Information("Install netfilter2 driver");
|
||||
Global.MainForm.StatusText(i18N.Translate("Installing netfilter2 driver"));
|
||||
|
||||
if (!File.Exists(Constants.NFDriver))
|
||||
throw new MessageException(i18N.Translate("builtin driver files missing, can't install NF driver"));
|
||||
@@ -220,21 +213,18 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "驱动复制失败\n");
|
||||
throw new MessageException($"Copy NF driver file failed\n{e.Message}");
|
||||
Log.Error(e, "Copy netfilter2.sys failed\n");
|
||||
throw new MessageException($"Copy netfilter2.sys failed\n{e.Message}");
|
||||
}
|
||||
|
||||
Global.MainForm.StatusText(i18N.Translate("Register driver"));
|
||||
// 注册驱动文件
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result == NF_STATUS.NF_STATUS_SUCCESS)
|
||||
if (Interops.Redirector.aio_register("netfilter2"))
|
||||
{
|
||||
Log.Information("驱动安装成功");
|
||||
Log.Information("Install netfilter2 driver finished");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("注册驱动失败: {Result}", result);
|
||||
throw new MessageException($"Register NF driver failed\n{result}");
|
||||
Log.Error("Register netfilter2 failed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +234,7 @@ namespace Netch.Controllers
|
||||
/// <returns>是否成功卸载</returns>
|
||||
public static bool UninstallDriver()
|
||||
{
|
||||
Log.Information("卸载 NF 驱动");
|
||||
Log.Information("Uninstall netfilter2");
|
||||
try
|
||||
{
|
||||
if (NFService.Status == ServiceControllerStatus.Running)
|
||||
@@ -261,7 +251,7 @@ namespace Netch.Controllers
|
||||
if (!File.Exists(SystemDriver))
|
||||
return true;
|
||||
|
||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
Interops.Redirector.aio_unregister("netfilter2");
|
||||
File.Delete(SystemDriver);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NTTController : Guard, IController
|
||||
{
|
||||
public NTTController() : base("NTT.exe")
|
||||
{
|
||||
}
|
||||
|
||||
public override string Name => "NTT";
|
||||
|
||||
/// <summary>
|
||||
/// 启动 NatTypeTester
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<(string? result, string? localEnd, string? publicEnd)> StartAsync()
|
||||
{
|
||||
string? localEnd = null, publicEnd = null, result = null, bindingTest = null;
|
||||
|
||||
try
|
||||
{
|
||||
Instance.StartInfo.Arguments = $" {Global.Settings.STUN_Server} {Global.Settings.STUN_Server_Port}";
|
||||
Instance.Start();
|
||||
|
||||
var output = await Instance.StandardOutput.ReadToEndAsync();
|
||||
var error = await Instance.StandardError.ReadToEndAsync();
|
||||
|
||||
try
|
||||
{
|
||||
await File.WriteAllTextAsync(Path.Combine(Global.NetchDir, $"logging\\{Name}.log"), $"{output}\r\n{error}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Warning(e, "写入 {Name} 日志错误", Name);
|
||||
}
|
||||
|
||||
if (output.IsNullOrWhiteSpace())
|
||||
{
|
||||
if (error.IsNullOrWhiteSpace())
|
||||
{
|
||||
Log.Warning("NTT no output");
|
||||
return (null, null, null);
|
||||
}
|
||||
|
||||
var errorFirst = error.GetLines().First();
|
||||
return (errorFirst.SplitTrimEntries(':').Last(), null, null);
|
||||
}
|
||||
|
||||
foreach (var line in output.Split('\n'))
|
||||
{
|
||||
var str = line.SplitTrimEntries(':');
|
||||
if (str.Length < 2)
|
||||
continue;
|
||||
|
||||
var key = str[0];
|
||||
var value = str[1];
|
||||
switch (key)
|
||||
{
|
||||
case "Other address is":
|
||||
case "Nat mapping behavior":
|
||||
case "Nat filtering behavior":
|
||||
break;
|
||||
case "Binding test":
|
||||
bindingTest = value;
|
||||
break;
|
||||
case "Local address":
|
||||
localEnd = value;
|
||||
break;
|
||||
case "Mapped address":
|
||||
publicEnd = value;
|
||||
break;
|
||||
case "result":
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bindingTest == "Fail")
|
||||
result = "Fail";
|
||||
|
||||
return (result, localEnd, publicEnd);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "{Name} 控制器启动异常", Name);
|
||||
try
|
||||
{
|
||||
await StopAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return (null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -10,6 +8,8 @@ using Microsoft.VisualStudio.Threading;
|
||||
using Netch.Forms;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Models.Modes.ShareMode;
|
||||
using Netch.Servers;
|
||||
using Netch.Utils;
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace Netch.Controllers
|
||||
public class PcapController : Guard, IModeController
|
||||
{
|
||||
private readonly LogForm _form;
|
||||
private Mode? _mode;
|
||||
private Server? _server;
|
||||
private ShareMode _mode = null!;
|
||||
private Socks5Server _server = null!;
|
||||
|
||||
public PcapController() : base("pcap2socks.exe", encoding: Encoding.UTF8)
|
||||
{
|
||||
@@ -31,20 +31,25 @@ namespace Netch.Controllers
|
||||
|
||||
public override string Name => "pcap2socks";
|
||||
|
||||
public async Task StartAsync(Server server, Mode mode)
|
||||
public ModeFeature Features => 0;
|
||||
|
||||
public async Task StartAsync(Socks5Server server, Mode mode)
|
||||
{
|
||||
if (mode is not ShareMode shareMode)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
_server = server;
|
||||
_mode = mode;
|
||||
_mode = shareMode;
|
||||
|
||||
var outboundNetworkInterface = NetworkInterfaceUtils.GetBest();
|
||||
|
||||
var argument = new StringBuilder($@"-i \Device\NPF_{outboundNetworkInterface.Id}");
|
||||
if (_server is Socks5Bridge socks5)
|
||||
argument.Append($" --destination {await socks5.AutoResolveHostnameAsync()}:{socks5.Port}");
|
||||
if (!_server.Auth())
|
||||
argument.Append($" --destination {await _server.AutoResolveHostnameAsync()}:{_server.Port}");
|
||||
else
|
||||
Trace.Assert(false);
|
||||
throw new InvalidOperationException();
|
||||
|
||||
argument.Append($" {_mode.GetRules().FirstOrDefault() ?? "-P n"}");
|
||||
argument.Append($" {_mode.Argument}");
|
||||
await StartGuardAsync(argument.ToString());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Enums;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Interops;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Models.Modes.TunMode;
|
||||
using Netch.Servers;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
@@ -21,7 +21,7 @@ namespace Netch.Controllers
|
||||
|
||||
private readonly DNSController _aioDnsController = new();
|
||||
|
||||
private Mode _mode = null!;
|
||||
private TunMode _mode = null!;
|
||||
private IPAddress? _serverRemoteAddress;
|
||||
private TUNConfig _tunConfig = null!;
|
||||
|
||||
@@ -30,13 +30,20 @@ namespace Netch.Controllers
|
||||
|
||||
public string Name => "tun2socks";
|
||||
|
||||
public async Task StartAsync(Server server, Mode mode)
|
||||
public ModeFeature Features => ModeFeature.SupportSocks5Auth;
|
||||
|
||||
public async Task StartAsync(Socks5Server server, Mode mode)
|
||||
{
|
||||
_mode = mode;
|
||||
if (mode is not TunMode tunMode)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
_mode = tunMode;
|
||||
_tunConfig = Global.Settings.TUNTAP;
|
||||
|
||||
if (server is Socks5Bridge socks5Bridge)
|
||||
if (server is Socks5LocalServer socks5Bridge)
|
||||
_serverRemoteAddress = await DnsUtils.LookupAsync(socks5Bridge.RemoteHostname);
|
||||
else
|
||||
_serverRemoteAddress = await DnsUtils.LookupAsync(server.Hostname);
|
||||
|
||||
if (_serverRemoteAddress != null && IPAddress.IsLoopback(_serverRemoteAddress))
|
||||
_serverRemoteAddress = null;
|
||||
@@ -56,24 +63,17 @@ namespace Netch.Controllers
|
||||
Dial(NameList.TYPE_UDPREST, "");
|
||||
Dial(NameList.TYPE_UDPTYPE, "Socks5");
|
||||
|
||||
if (server is Socks5 socks5)
|
||||
Dial(NameList.TYPE_TCPHOST, $"{await server.AutoResolveHostnameAsync()}:{server.Port}");
|
||||
|
||||
Dial(NameList.TYPE_UDPHOST, $"{await server.AutoResolveHostnameAsync()}:{server.Port}");
|
||||
|
||||
if (server.Auth())
|
||||
{
|
||||
Dial(NameList.TYPE_TCPHOST, $"{await socks5.AutoResolveHostnameAsync()}:{socks5.Port}");
|
||||
Dial(NameList.TYPE_TCPUSER, server.Username!);
|
||||
Dial(NameList.TYPE_TCPPASS, server.Password!);
|
||||
|
||||
Dial(NameList.TYPE_UDPHOST, $"{await socks5.AutoResolveHostnameAsync()}:{socks5.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
|
||||
{
|
||||
Trace.Assert(false);
|
||||
Dial(NameList.TYPE_UDPUSER, server.Username!);
|
||||
Dial(NameList.TYPE_UDPPASS, server.Password!);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -125,8 +125,8 @@ namespace Netch.Controllers
|
||||
|
||||
var binHash = Utils.Utils.SHA256CheckSum(binDriver);
|
||||
var sysHash = Utils.Utils.SHA256CheckSum(sysDriver);
|
||||
Log.Information("自带 wintun.dll Hash: {Hash}", binHash);
|
||||
Log.Information("系统 wintun.dll Hash: {Hash}", sysHash);
|
||||
Log.Information("Built-in wintun.dll Hash: {Hash}", binHash);
|
||||
Log.Information("Installed wintun.dll Hash: {Hash}", sysHash);
|
||||
if (binHash == sysHash)
|
||||
return;
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "复制 wintun.dll 异常");
|
||||
Log.Error(e, "Copy wintun.dll failed");
|
||||
throw new MessageException($"Failed to copy wintun.dll to system directory: {e.Message}");
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
Global.MainForm.StatusText(i18N.Translate("Setup Route Table Rule"));
|
||||
|
||||
var tunNetworkInterface = NetworkInterfaceUtils.Get(_tun.InterfaceIndex);
|
||||
// Server Address
|
||||
if (_serverRemoteAddress != null)
|
||||
RouteUtils.CreateRoute(_outbound.FillTemplate(_serverRemoteAddress.ToString(), 32));
|
||||
@@ -155,38 +156,22 @@ namespace Netch.Controllers
|
||||
// Global Bypass IPs
|
||||
RouteUtils.CreateRouteFill(_outbound, _tunConfig.BypassIPs);
|
||||
|
||||
var tunNetworkInterface = NetworkInterfaceUtils.Get(_tun.InterfaceIndex);
|
||||
switch (_mode.Type)
|
||||
// rule
|
||||
RouteUtils.CreateRouteFill(_tun, _mode.Handle);
|
||||
RouteUtils.CreateRouteFill(_outbound, _mode.Bypass);
|
||||
|
||||
// dns
|
||||
// NOTICE: DNS metric is network interface metric
|
||||
tunNetworkInterface.SetDns(DummyDns);
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate(DummyDns, 32));
|
||||
|
||||
if (!_tunConfig.UseCustomDNS)
|
||||
{
|
||||
case ModeType.ProxyRuleIPs:
|
||||
// rules
|
||||
RouteUtils.CreateRouteFill(_tun, _mode.GetRules());
|
||||
|
||||
if (_tunConfig.ProxyDNS)
|
||||
{
|
||||
tunNetworkInterface.SetDns(DummyDns);
|
||||
// proxy dummy dns
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate(DummyDns, 32));
|
||||
|
||||
if (!_tunConfig.UseCustomDNS)
|
||||
// proxy AioDNS other dns
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.OtherDNS), 32));
|
||||
}
|
||||
|
||||
break;
|
||||
case ModeType.BypassRuleIPs:
|
||||
RouteUtils.CreateRouteFill(_outbound, _mode.GetRules());
|
||||
|
||||
tunNetworkInterface.SetDns(DummyDns);
|
||||
|
||||
if (!_tunConfig.UseCustomDNS)
|
||||
// bypass AioDNS other dns
|
||||
RouteUtils.CreateRoute(_outbound.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32));
|
||||
|
||||
NetworkInterfaceUtils.SetInterfaceMetric(_tun.InterfaceIndex, 0);
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate("0.0.0.0", 0));
|
||||
break;
|
||||
RouteUtils.CreateRoute(_outbound.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32));
|
||||
RouteUtils.CreateRoute(_tun.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.OtherDNS), 32));
|
||||
}
|
||||
|
||||
NetworkInterfaceUtils.SetInterfaceMetric(_tun.InterfaceIndex, 0);
|
||||
}
|
||||
|
||||
private void ClearRouteTable()
|
||||
@@ -196,13 +181,11 @@ namespace Netch.Controllers
|
||||
|
||||
RouteUtils.DeleteRouteFill(_outbound, Global.Settings.TUNTAP.BypassIPs);
|
||||
|
||||
switch (_mode.Type)
|
||||
{
|
||||
case ModeType.BypassRuleIPs:
|
||||
RouteUtils.DeleteRouteFill(_outbound, _mode.GetRules());
|
||||
NetworkInterfaceUtils.SetInterfaceMetric(_outbound.InterfaceIndex);
|
||||
break;
|
||||
}
|
||||
RouteUtils.DeleteRouteFill(_outbound, _mode.Bypass);
|
||||
|
||||
RouteUtils.DeleteRoute(_outbound.FillTemplate(Utils.Utils.GetHostFromUri(Global.Settings.AioDNS.ChinaDNS), 32));
|
||||
|
||||
NetworkInterfaceUtils.SetInterfaceMetric(_outbound.InterfaceIndex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Netch.Controllers
|
||||
public const string Name = @"Netch";
|
||||
public const string Copyright = @"Copyright © 2019 - 2021";
|
||||
|
||||
public const string AssemblyVersion = @"1.8.7";
|
||||
public const string AssemblyVersion = @"1.9.3";
|
||||
private const string Suffix = @"";
|
||||
|
||||
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";
|
||||
@@ -48,24 +48,24 @@ namespace Netch.Controllers
|
||||
|
||||
var releases = JsonSerializer.Deserialize<List<Release>>(json)!;
|
||||
LatestRelease = GetLatestRelease(releases, isPreRelease);
|
||||
Log.Information("Github 最新发布版本: {Version}", LatestRelease.tag_name);
|
||||
Log.Information("Github latest release: {Version}", LatestRelease.tag_name);
|
||||
if (VersionUtil.CompareVersion(LatestRelease.tag_name, Version) > 0)
|
||||
{
|
||||
Log.Information("发现新版本");
|
||||
Log.Information("Found newer version");
|
||||
NewVersionFound?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Information("目前是最新版本");
|
||||
Log.Information("Already the latest version");
|
||||
NewVersionNotFound?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is WebException)
|
||||
Log.Warning(e, "获取新版本失败");
|
||||
Log.Warning(e, "Get releases failed");
|
||||
else
|
||||
Log.Error(e, "获取新版本异常");
|
||||
Log.Error(e, "Get releases error");
|
||||
|
||||
NewVersionFoundFailed?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Netch.Models
|
||||
namespace Netch.Enums
|
||||
{
|
||||
public enum LogLevel
|
||||
{
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Netch.Enums
|
||||
{
|
||||
public enum ModeType
|
||||
{
|
||||
Process = 0,
|
||||
ProxyRuleIPs = 1,
|
||||
BypassRuleIPs = 2,
|
||||
Pcap2Socks = 6
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Netch.Models
|
||||
namespace Netch.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// 状态
|
||||
@@ -7,5 +7,7 @@ namespace Netch
|
||||
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
|
||||
|
||||
public static bool AlwaysShowNewVersionFound { get; set; }
|
||||
|
||||
public static bool NoSupport { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Netch.Forms
|
||||
|
||||
94
Netch/Forms/BindingForm.cs
Normal file
94
Netch/Forms/BindingForm.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public class BindingForm : Form
|
||||
{
|
||||
private readonly Dictionary<Control, Func<string, bool>> _checkActions = new();
|
||||
private readonly Dictionary<Control, Action<Control>> _saveActions = new();
|
||||
|
||||
protected void BindTextBox(TextBoxBase control, Func<string, bool> check, Action<string> save, object value)
|
||||
{
|
||||
BindTextBox<string>(control, check, save, value);
|
||||
}
|
||||
|
||||
protected void BindTextBox<T>(TextBoxBase control, Func<T, bool> check, Action<T> save, object value)
|
||||
{
|
||||
control.Text = value.ToString();
|
||||
_checkActions.Add(control,
|
||||
s =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return check.Invoke((T)Convert.ChangeType(s, typeof(T)));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
_saveActions.Add(control, c => save.Invoke((T)Convert.ChangeType(((TextBoxBase)c).Text, typeof(T))));
|
||||
}
|
||||
|
||||
protected void BindCheckBox(CheckBox control, Action<bool> save, bool value)
|
||||
{
|
||||
control.Checked = value;
|
||||
_saveActions.Add(control, c => save(((CheckBox)c).Checked));
|
||||
}
|
||||
|
||||
protected void BindSyncGlobalCheckBox(SyncGlobalCheckBox control, Action<bool?> save, bool? value, bool globalValue)
|
||||
{
|
||||
control.Value = value;
|
||||
control.GlobalValue = globalValue;
|
||||
_saveActions.Add(control, c => save(((SyncGlobalCheckBox)c).Value));
|
||||
}
|
||||
|
||||
protected void BindRadioBox(RadioButton control, Action<bool> save, bool value)
|
||||
{
|
||||
control.Checked = value;
|
||||
_saveActions.Add(control, c => save.Invoke(((RadioButton)c).Checked));
|
||||
}
|
||||
|
||||
protected void BindListComboBox<T>(ComboBox comboBox, Action<T> save, IEnumerable<T> values, T value) where T : notnull
|
||||
{
|
||||
if (comboBox.DropDownStyle != ComboBoxStyle.DropDownList)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
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)); };
|
||||
}
|
||||
|
||||
protected void BindComboBox(ComboBox control, Func<string, bool> check, Action<string> save, string value, object[]? values = null)
|
||||
{
|
||||
if (values != null)
|
||||
control.Items.AddRange(values);
|
||||
|
||||
_saveActions.Add(control, c => save.Invoke(((ComboBox)c).Text));
|
||||
_checkActions.Add(control, check.Invoke);
|
||||
|
||||
Load += (_, _) => { control.Text = value; };
|
||||
}
|
||||
|
||||
protected List<Control> GetCheckFailedControls()
|
||||
{
|
||||
return _checkActions.Where(pair => !pair.Value.Invoke(pair.Key.Text)).Select(pair => pair.Key).ToList();
|
||||
}
|
||||
|
||||
protected void SaveBinds()
|
||||
{
|
||||
foreach (var pair in _saveActions)
|
||||
pair.Value.Invoke(pair.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
144
Netch/Forms/MainForm.Designer.cs
generated
144
Netch/Forms/MainForm.Designer.cs
generated
@@ -35,19 +35,19 @@
|
||||
this.ModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CreateProcessModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CreateRouteTableRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SubscribeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ManageSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SubscriptionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ManageSubscriptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UpdateServersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.OptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.OpenDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ShowHideConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CleanDNSCacheToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.removeNetchFirewallRulesToolStripMenuItem = 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();
|
||||
this.fAQToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CheckForUpdateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.FAQToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ForceExitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.AboutToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.NewVersionLabel = new System.Windows.Forms.ToolStripLabel();
|
||||
this.VersionLabel = new System.Windows.Forms.ToolStripLabel();
|
||||
@@ -73,6 +73,7 @@
|
||||
this.DownloadSpeedLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.UploadSpeedLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.blankToolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.HttpStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.NatTypeStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.NatTypeStatusLightLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.ControlButton = new System.Windows.Forms.Button();
|
||||
@@ -85,6 +86,7 @@
|
||||
this.ProfileTable = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.ButtomControlContainerControl = new System.Windows.Forms.ContainerControl();
|
||||
this.ReloadModesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MenuStrip.SuspendLayout();
|
||||
this.ConfigurationGroupBox.SuspendLayout();
|
||||
this.configLayoutPanel.SuspendLayout();
|
||||
@@ -110,10 +112,10 @@
|
||||
this.MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ServerToolStripMenuItem,
|
||||
this.ModeToolStripMenuItem,
|
||||
this.SubscribeToolStripMenuItem,
|
||||
this.SubscriptionToolStripMenuItem,
|
||||
this.OptionsToolStripMenuItem,
|
||||
this.HelpToolStripMenuItem,
|
||||
this.exitToolStripMenuItem,
|
||||
this.ForceExitToolStripMenuItem,
|
||||
this.AboutToolStripButton,
|
||||
this.NewVersionLabel,
|
||||
this.VersionLabel});
|
||||
@@ -143,7 +145,8 @@
|
||||
//
|
||||
this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.CreateProcessModeToolStripMenuItem,
|
||||
this.CreateRouteTableRuleToolStripMenuItem});
|
||||
this.CreateRouteTableRuleToolStripMenuItem,
|
||||
this.ReloadModesToolStripMenuItem});
|
||||
this.ModeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.ModeToolStripMenuItem.Name = "ModeToolStripMenuItem";
|
||||
this.ModeToolStripMenuItem.Size = new System.Drawing.Size(55, 21);
|
||||
@@ -163,29 +166,29 @@
|
||||
this.CreateRouteTableRuleToolStripMenuItem.Text = "Create Route Table Rule";
|
||||
this.CreateRouteTableRuleToolStripMenuItem.Click += new System.EventHandler(this.createRouteTableModeToolStripMenuItem_Click);
|
||||
//
|
||||
// SubscribeToolStripMenuItem
|
||||
// SubscriptionToolStripMenuItem
|
||||
//
|
||||
this.SubscribeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ManageSubscribeLinksToolStripMenuItem,
|
||||
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);
|
||||
this.SubscribeToolStripMenuItem.Text = "Subscribe";
|
||||
this.SubscriptionToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ManageSubscriptionsToolStripMenuItem,
|
||||
this.UpdateServersToolStripMenuItem});
|
||||
this.SubscriptionToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.SubscriptionToolStripMenuItem.Name = "SubscriptionToolStripMenuItem";
|
||||
this.SubscriptionToolStripMenuItem.Size = new System.Drawing.Size(92, 21);
|
||||
this.SubscriptionToolStripMenuItem.Text = "Subscription";
|
||||
//
|
||||
// ManageSubscribeLinksToolStripMenuItem
|
||||
// ManageSubscriptionsToolStripMenuItem
|
||||
//
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Name = "ManageSubscribeLinksToolStripMenuItem";
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Size = new System.Drawing.Size(294, 22);
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Text = "Manage Subscribe Links";
|
||||
this.ManageSubscribeLinksToolStripMenuItem.Click += new System.EventHandler(this.ManageSubscribeLinksToolStripMenuItem_Click);
|
||||
this.ManageSubscriptionsToolStripMenuItem.Name = "ManageSubscriptionsToolStripMenuItem";
|
||||
this.ManageSubscriptionsToolStripMenuItem.Size = new System.Drawing.Size(206, 22);
|
||||
this.ManageSubscriptionsToolStripMenuItem.Text = "Manage Subscriptions";
|
||||
this.ManageSubscriptionsToolStripMenuItem.Click += new System.EventHandler(this.ManageSubscriptionLinksToolStripMenuItem_Click);
|
||||
//
|
||||
// UpdateServersFromSubscribeLinksToolStripMenuItem
|
||||
// UpdateServersToolStripMenuItem
|
||||
//
|
||||
this.UpdateServersFromSubscribeLinksToolStripMenuItem.Name = "UpdateServersFromSubscribeLinksToolStripMenuItem";
|
||||
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);
|
||||
this.UpdateServersToolStripMenuItem.Name = "UpdateServersToolStripMenuItem";
|
||||
this.UpdateServersToolStripMenuItem.Size = new System.Drawing.Size(206, 22);
|
||||
this.UpdateServersToolStripMenuItem.Text = "Update Servers";
|
||||
this.UpdateServersToolStripMenuItem.Click += new System.EventHandler(this.UpdateServersFromSubscriptionLinksToolStripMenuItem_Click);
|
||||
//
|
||||
// OptionsToolStripMenuItem
|
||||
//
|
||||
@@ -194,7 +197,7 @@
|
||||
this.ShowHideConsoleToolStripMenuItem,
|
||||
this.CleanDNSCacheToolStripMenuItem,
|
||||
this.UninstallServiceToolStripMenuItem,
|
||||
this.removeNetchFirewallRulesToolStripMenuItem});
|
||||
this.RemoveNetchFirewallRulesToolStripMenuItem});
|
||||
this.OptionsToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.OptionsToolStripMenuItem.Name = "OptionsToolStripMenuItem";
|
||||
this.OptionsToolStripMenuItem.Size = new System.Drawing.Size(66, 21);
|
||||
@@ -228,43 +231,43 @@
|
||||
this.UninstallServiceToolStripMenuItem.Text = "Uninstall NF Service";
|
||||
this.UninstallServiceToolStripMenuItem.Click += new System.EventHandler(this.UninstallServiceToolStripMenuItem_Click);
|
||||
//
|
||||
// removeNetchFirewallRulesToolStripMenuItem
|
||||
// RemoveNetchFirewallRulesToolStripMenuItem
|
||||
//
|
||||
this.removeNetchFirewallRulesToolStripMenuItem.Name = "removeNetchFirewallRulesToolStripMenuItem";
|
||||
this.removeNetchFirewallRulesToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.removeNetchFirewallRulesToolStripMenuItem.Text = "Remove Netch Firewall Rules";
|
||||
this.removeNetchFirewallRulesToolStripMenuItem.Click += new System.EventHandler(this.RemoveNetchFirewallRulesToolStripMenuItem_Click);
|
||||
this.RemoveNetchFirewallRulesToolStripMenuItem.Name = "RemoveNetchFirewallRulesToolStripMenuItem";
|
||||
this.RemoveNetchFirewallRulesToolStripMenuItem.Size = new System.Drawing.Size(243, 22);
|
||||
this.RemoveNetchFirewallRulesToolStripMenuItem.Text = "Remove Netch Firewall Rules";
|
||||
this.RemoveNetchFirewallRulesToolStripMenuItem.Click += new System.EventHandler(this.RemoveNetchFirewallRulesToolStripMenuItem_Click);
|
||||
//
|
||||
// HelpToolStripMenuItem
|
||||
//
|
||||
this.HelpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.CheckForUpdatesToolStripMenuItem,
|
||||
this.fAQToolStripMenuItem});
|
||||
this.CheckForUpdateToolStripMenuItem,
|
||||
this.FAQToolStripMenuItem});
|
||||
this.HelpToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.HelpToolStripMenuItem.Name = "HelpToolStripMenuItem";
|
||||
this.HelpToolStripMenuItem.Size = new System.Drawing.Size(47, 21);
|
||||
this.HelpToolStripMenuItem.Text = "Help";
|
||||
//
|
||||
// CheckForUpdatesToolStripMenuItem
|
||||
// CheckForUpdateToolStripMenuItem
|
||||
//
|
||||
this.CheckForUpdatesToolStripMenuItem.Name = "CheckForUpdatesToolStripMenuItem";
|
||||
this.CheckForUpdatesToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.CheckForUpdatesToolStripMenuItem.Text = "Check for updates";
|
||||
this.CheckForUpdatesToolStripMenuItem.Click += new System.EventHandler(this.CheckForUpdatesToolStripMenuItem_Click);
|
||||
this.CheckForUpdateToolStripMenuItem.Name = "CheckForUpdateToolStripMenuItem";
|
||||
this.CheckForUpdateToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
|
||||
this.CheckForUpdateToolStripMenuItem.Text = "Check for update";
|
||||
this.CheckForUpdateToolStripMenuItem.Click += new System.EventHandler(this.CheckForUpdatesToolStripMenuItem_Click);
|
||||
//
|
||||
// fAQToolStripMenuItem
|
||||
// FAQToolStripMenuItem
|
||||
//
|
||||
this.fAQToolStripMenuItem.Name = "fAQToolStripMenuItem";
|
||||
this.fAQToolStripMenuItem.Size = new System.Drawing.Size(183, 22);
|
||||
this.fAQToolStripMenuItem.Text = "FAQ";
|
||||
this.fAQToolStripMenuItem.Click += new System.EventHandler(this.fAQToolStripMenuItem_Click);
|
||||
this.FAQToolStripMenuItem.Name = "FAQToolStripMenuItem";
|
||||
this.FAQToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
|
||||
this.FAQToolStripMenuItem.Text = "FAQ";
|
||||
this.FAQToolStripMenuItem.Click += new System.EventHandler(this.fAQToolStripMenuItem_Click);
|
||||
//
|
||||
// exitToolStripMenuItem
|
||||
// ForceExitToolStripMenuItem
|
||||
//
|
||||
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
|
||||
this.exitToolStripMenuItem.Size = new System.Drawing.Size(40, 22);
|
||||
this.exitToolStripMenuItem.Text = "Exit";
|
||||
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
|
||||
this.ForceExitToolStripMenuItem.Name = "ForceExitToolStripMenuItem";
|
||||
this.ForceExitToolStripMenuItem.Size = new System.Drawing.Size(40, 22);
|
||||
this.ForceExitToolStripMenuItem.Text = "Exit";
|
||||
this.ForceExitToolStripMenuItem.Click += new System.EventHandler(this.ForceExitToolStripMenuItem_Click);
|
||||
//
|
||||
// AboutToolStripButton
|
||||
//
|
||||
@@ -521,6 +524,7 @@
|
||||
this.DownloadSpeedLabel,
|
||||
this.UploadSpeedLabel,
|
||||
this.blankToolStripStatusLabel,
|
||||
this.HttpStatusLabel,
|
||||
this.NatTypeStatusLabel,
|
||||
this.NatTypeStatusLightLabel});
|
||||
this.StatusStrip.Location = new System.Drawing.Point(0, 272);
|
||||
@@ -563,6 +567,15 @@
|
||||
this.blankToolStripStatusLabel.Size = new System.Drawing.Size(494, 17);
|
||||
this.blankToolStripStatusLabel.Spring = true;
|
||||
//
|
||||
// HttpStatusLabel
|
||||
//
|
||||
this.HttpStatusLabel.Name = "HttpStatusLabel";
|
||||
this.HttpStatusLabel.Size = new System.Drawing.Size(41, 17);
|
||||
this.HttpStatusLabel.Text = "HTTP:";
|
||||
this.HttpStatusLabel.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
|
||||
this.HttpStatusLabel.Visible = false;
|
||||
this.HttpStatusLabel.Click += new System.EventHandler(this.TcpStatusLabel_Click);
|
||||
//
|
||||
// NatTypeStatusLabel
|
||||
//
|
||||
this.NatTypeStatusLabel.Name = "NatTypeStatusLabel";
|
||||
@@ -609,19 +622,19 @@
|
||||
this.ExitToolStripButton});
|
||||
this.NotifyMenu.Name = "NotifyMenu";
|
||||
this.NotifyMenu.ShowItemToolTips = false;
|
||||
this.NotifyMenu.Size = new System.Drawing.Size(181, 70);
|
||||
this.NotifyMenu.Size = new System.Drawing.Size(108, 48);
|
||||
//
|
||||
// ShowMainFormToolStripButton
|
||||
//
|
||||
this.ShowMainFormToolStripButton.Name = "ShowMainFormToolStripButton";
|
||||
this.ShowMainFormToolStripButton.Size = new System.Drawing.Size(180, 22);
|
||||
this.ShowMainFormToolStripButton.Size = new System.Drawing.Size(107, 22);
|
||||
this.ShowMainFormToolStripButton.Text = "Show";
|
||||
this.ShowMainFormToolStripButton.Click += new System.EventHandler(this.ShowMainFormToolStripButton_Click);
|
||||
//
|
||||
// ExitToolStripButton
|
||||
//
|
||||
this.ExitToolStripButton.Name = "ExitToolStripButton";
|
||||
this.ExitToolStripButton.Size = new System.Drawing.Size(180, 22);
|
||||
this.ExitToolStripButton.Size = new System.Drawing.Size(107, 22);
|
||||
this.ExitToolStripButton.Text = "Exit";
|
||||
this.ExitToolStripButton.Click += new System.EventHandler(this.ExitToolStripButton_Click);
|
||||
//
|
||||
@@ -686,6 +699,13 @@
|
||||
this.ButtomControlContainerControl.TabStop = false;
|
||||
this.ButtomControlContainerControl.Text = "groupBox1";
|
||||
//
|
||||
// ReloadModesToolStripMenuItem
|
||||
//
|
||||
this.ReloadModesToolStripMenuItem.Name = "ReloadModesToolStripMenuItem";
|
||||
this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
|
||||
this.ReloadModesToolStripMenuItem.Text = "Reload Modes";
|
||||
this.ReloadModesToolStripMenuItem.Click += new System.EventHandler(this.ReloadModesToolStripMenuItem_Click);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||
@@ -733,7 +753,7 @@
|
||||
|
||||
private System.Windows.Forms.ToolStripMenuItem CreateRouteTableRuleToolStripMenuItem;
|
||||
|
||||
private System.Windows.Forms.ToolStripMenuItem removeNetchFirewallRulesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem RemoveNetchFirewallRulesToolStripMenuItem;
|
||||
|
||||
private System.Windows.Forms.ToolStripButton AboutToolStripButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem CleanDNSCacheToolStripMenuItem;
|
||||
@@ -748,9 +768,9 @@
|
||||
private System.Windows.Forms.PictureBox EditModePictureBox;
|
||||
private System.Windows.Forms.PictureBox EditServerPictureBox;
|
||||
private System.Windows.Forms.ToolStripMenuItem ExitToolStripButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ForceExitToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ImportServersFromClipboardToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ManageSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ManageSubscriptionsToolStripMenuItem;
|
||||
private System.Windows.Forms.MenuStrip MenuStrip;
|
||||
public System.Windows.Forms.ComboBox ModeComboBox;
|
||||
private System.Windows.Forms.Label ModeLabel;
|
||||
@@ -765,7 +785,7 @@
|
||||
private System.Windows.Forms.Label ProfileLabel;
|
||||
private System.Windows.Forms.TextBox ProfileNameText;
|
||||
private System.Windows.Forms.TableLayoutPanel ProfileTable;
|
||||
private System.Windows.Forms.ToolStripMenuItem CheckForUpdatesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem CheckForUpdateToolStripMenuItem;
|
||||
private System.Windows.Forms.ComboBox ServerComboBox;
|
||||
private System.Windows.Forms.Label ServerLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem ServerToolStripMenuItem;
|
||||
@@ -774,23 +794,25 @@
|
||||
private System.Windows.Forms.PictureBox SpeedPictureBox;
|
||||
private System.Windows.Forms.ToolStripStatusLabel StatusLabel;
|
||||
private System.Windows.Forms.StatusStrip StatusStrip;
|
||||
private System.Windows.Forms.ToolStripMenuItem SubscribeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SubscriptionToolStripMenuItem;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
|
||||
private System.Windows.Forms.ToolStripMenuItem UninstallServiceToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateServersToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UploadSpeedLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UsedBandwidthLabel;
|
||||
private System.Windows.Forms.ToolStripLabel NewVersionLabel;
|
||||
private System.Windows.Forms.ToolStripLabel VersionLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel NatTypeStatusLightLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel blankToolStripStatusLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem fAQToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem FAQToolStripMenuItem;
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
||||
private System.Windows.Forms.ContainerControl ButtomControlContainerControl;
|
||||
private System.Windows.Forms.ToolStripMenuItem ShowHideConsoleToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripStatusLabel HttpStatusLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem ReloadModesToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ using Netch.Enums;
|
||||
using Netch.Forms.ModeForms;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Properties;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
@@ -43,6 +44,9 @@ namespace Netch.Forms
|
||||
|
||||
#region i18N Translations
|
||||
|
||||
if (Flags.NoSupport)
|
||||
_mainFormText.Add(Name, new[] { "{0} ({1})", "Netch", "No Support" });
|
||||
|
||||
_mainFormText.Add(UninstallServiceToolStripMenuItem.Name, new[] { "Uninstall {0}", "NF Service" });
|
||||
|
||||
#endregion
|
||||
@@ -54,7 +58,7 @@ namespace Netch.Forms
|
||||
private void AddAddServerToolStripMenuItems()
|
||||
{
|
||||
foreach (var serversUtil in ServerHelper.ServerUtilDictionary.Values.OrderBy(i => i.Priority)
|
||||
.Where(i => !string.IsNullOrEmpty(i.FullName)))
|
||||
.Where(i => !string.IsNullOrEmpty(i.FullName)))
|
||||
{
|
||||
var fullName = serversUtil.FullName;
|
||||
var control = new ToolStripMenuItem
|
||||
@@ -78,18 +82,15 @@ namespace Netch.Forms
|
||||
|
||||
LoadServers();
|
||||
SelectLastServer();
|
||||
ServerHelper.DelayTestHelper.UpdateInterval();
|
||||
DelayTestHelper.UpdateTick(true);
|
||||
|
||||
ModeHelper.InitWatcher();
|
||||
ModeHelper.Load();
|
||||
LoadModes();
|
||||
SelectLastMode();
|
||||
ModeService.Instance.Load();
|
||||
|
||||
// 加载翻译
|
||||
TranslateControls();
|
||||
|
||||
// 隐藏 NatTypeStatusLabel
|
||||
NatTypeStatusText();
|
||||
// 隐藏 ConnectivityStatusLabel
|
||||
ConnectivityStatusVisible(false);
|
||||
|
||||
// 加载快速配置
|
||||
LoadProfiles();
|
||||
@@ -100,13 +101,13 @@ namespace Netch.Forms
|
||||
|
||||
// 检查订阅更新
|
||||
if (Global.Settings.UpdateServersWhenOpened)
|
||||
UpdateServersFromSubscribeAsync().Forget();
|
||||
UpdateServersFromSubscriptionAsync().Forget();
|
||||
|
||||
// 打开软件时启动加速,产生开始按钮点击事件
|
||||
if (Global.Settings.StartWhenOpened)
|
||||
ControlButton.PerformClick();
|
||||
|
||||
Netch.SingleInstance.ListenForArgumentsFromSuccessiveInstances();
|
||||
Program.SingleInstance.ListenForArgumentsFromSuccessiveInstances();
|
||||
}
|
||||
|
||||
private void RecordSize()
|
||||
@@ -212,15 +213,18 @@ namespace Netch.Forms
|
||||
private async void ImportServersFromClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var texts = Clipboard.GetText();
|
||||
if (!string.IsNullOrWhiteSpace(texts))
|
||||
{
|
||||
var servers = ShareLink.ParseText(texts);
|
||||
Global.Settings.Server.AddRange(servers);
|
||||
NotifyTip(i18N.TranslateFormat("Import {0} server(s) form Clipboard", servers.Count));
|
||||
if (string.IsNullOrWhiteSpace(texts))
|
||||
return;
|
||||
|
||||
LoadServers();
|
||||
await Configuration.SaveAsync();
|
||||
}
|
||||
var servers = ShareLink.ParseText(texts);
|
||||
foreach (var server in servers)
|
||||
server.Group = Constants.DefaultGroup;
|
||||
|
||||
Global.Settings.Server.AddRange(servers);
|
||||
NotifyTip(i18N.TranslateFormat("Import {0} server(s) form Clipboard", servers.Count));
|
||||
|
||||
LoadServers();
|
||||
await Configuration.SaveAsync();
|
||||
}
|
||||
|
||||
private async void AddServerToolStripMenuItem_Click([NotNull] object? sender, EventArgs? e)
|
||||
@@ -256,51 +260,64 @@ namespace Netch.Forms
|
||||
Show();
|
||||
}
|
||||
|
||||
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
try
|
||||
{
|
||||
ModeService.Instance.Load();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Subscription
|
||||
|
||||
private void ManageSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private void ManageSubscriptionLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
new SubscribeForm().ShowDialog();
|
||||
new SubscriptionForm().ShowDialog();
|
||||
LoadServers();
|
||||
Show();
|
||||
}
|
||||
|
||||
private async void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private async void UpdateServersFromSubscriptionLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
await UpdateServersFromSubscribeAsync();
|
||||
await UpdateServersFromSubscriptionAsync();
|
||||
}
|
||||
|
||||
private async Task UpdateServersFromSubscribeAsync()
|
||||
private async Task UpdateServersFromSubscriptionAsync()
|
||||
{
|
||||
void DisableItems(bool v)
|
||||
{
|
||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ProfileGroupBox.Enabled = ControlButton.Enabled = v;
|
||||
}
|
||||
|
||||
if (Global.Settings.SubscribeLink.Count <= 0)
|
||||
if (Global.Settings.Subscription.Count <= 0)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("No subscription link"));
|
||||
return;
|
||||
}
|
||||
|
||||
StatusText(i18N.Translate("Starting update subscription"));
|
||||
StatusText(i18N.Translate("Updating servers"));
|
||||
DisableItems(false);
|
||||
|
||||
try
|
||||
{
|
||||
await Subscription.UpdateServersAsync();
|
||||
await SubscriptionUtil.UpdateServersAsync();
|
||||
|
||||
LoadServers();
|
||||
await Configuration.SaveAsync();
|
||||
StatusText(i18N.Translate("Subscription updated"));
|
||||
StatusText(i18N.Translate("Servers updated"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
NotifyTip(i18N.Translate("update servers failed") + "\n" + e.Message, info: false);
|
||||
Log.Error("更新服务器 失败!" + e);
|
||||
NotifyTip(i18N.Translate("Unhandled update servers error") + "\n" + e.Message, info: false);
|
||||
Log.Error(e, "Unhandled Update servers error");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -321,7 +338,7 @@ namespace Netch.Forms
|
||||
|
||||
void OnNewVersionFoundFailed(object? o, EventArgs? args)
|
||||
{
|
||||
NotifyTip(i18N.Translate("New version found failed"), info: false);
|
||||
NotifyTip(i18N.Translate("Check for update failed"), info: false);
|
||||
}
|
||||
|
||||
try
|
||||
@@ -389,9 +406,9 @@ namespace Netch.Forms
|
||||
|
||||
private void ShowHideConsoleToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var windowStyles = (WINDOW_STYLE)PInvoke.GetWindowLong(new HWND(Netch.ConsoleHwnd), WINDOW_LONG_PTR_INDEX.GWL_STYLE);
|
||||
var windowStyles = (WINDOW_STYLE)PInvoke.GetWindowLong(new HWND(Program.ConsoleHwnd), WINDOW_LONG_PTR_INDEX.GWL_STYLE);
|
||||
var visible = windowStyles.HasFlag(WINDOW_STYLE.WS_VISIBLE);
|
||||
PInvoke.ShowWindow(Netch.ConsoleHwnd, visible ? SHOW_WINDOW_CMD.SW_HIDE : SHOW_WINDOW_CMD.SW_SHOWNOACTIVATE);
|
||||
PInvoke.ShowWindow(Program.ConsoleHwnd, visible ? SHOW_WINDOW_CMD.SW_HIDE : SHOW_WINDOW_CMD.SW_SHOWNOACTIVATE);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -399,7 +416,7 @@ namespace Netch.Forms
|
||||
/// <summary>
|
||||
/// 菜单栏强制退出
|
||||
/// </summary>
|
||||
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private void ForceExitToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Exit(true);
|
||||
}
|
||||
@@ -461,7 +478,6 @@ namespace Netch.Forms
|
||||
throw new MessageException(i18N.Translate("The downloaded file has the wrong hash"));
|
||||
}
|
||||
|
||||
ModeHelper.SuspendWatcher = true;
|
||||
await StopAsync();
|
||||
await Configuration.SaveAsync();
|
||||
|
||||
@@ -469,7 +485,7 @@ namespace Netch.Forms
|
||||
await Task.Run(updater.ApplyUpdate);
|
||||
|
||||
// release mutex, exit
|
||||
Netch.SingleInstance.Dispose();
|
||||
Program.SingleInstance.Dispose();
|
||||
Process.Start(Global.NetchExecutable);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
@@ -479,7 +495,7 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "更新未处理异常");
|
||||
Log.Error(exception, "Unhandled Update error");
|
||||
NotifyTip(exception.Message, info: false);
|
||||
}
|
||||
finally
|
||||
@@ -498,7 +514,7 @@ namespace Netch.Forms
|
||||
|
||||
private void fAQToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Utils.Utils.Open("https://netch.org/#/docs/zh-CN/faq");
|
||||
Utils.Utils.Open("https://docs.netch.org");
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -545,7 +561,8 @@ namespace Netch.Forms
|
||||
State = State.Started;
|
||||
|
||||
Task.Run(Bandwidth.NetTraffic).Forget();
|
||||
NatTestAsync().Forget();
|
||||
DiscoveryNatTypeAsync().Forget();
|
||||
HttpConnectAsync().Forget();
|
||||
|
||||
if (Global.Settings.MinimizeWhenStarted)
|
||||
Minimize();
|
||||
@@ -578,7 +595,7 @@ namespace Netch.Forms
|
||||
|
||||
private void SettingsButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var oldSettings = Global.Settings.Clone();
|
||||
var oldSettings = Global.Settings.ShallowCopy();
|
||||
|
||||
Hide();
|
||||
new SettingForm().ShowDialog();
|
||||
@@ -592,7 +609,7 @@ namespace Netch.Forms
|
||||
}
|
||||
|
||||
if (oldSettings.DetectionTick != Global.Settings.DetectionTick)
|
||||
ServerHelper.DelayTestHelper.UpdateInterval();
|
||||
DelayTestHelper.UpdateTick(true);
|
||||
|
||||
if (oldSettings.ProfileCount != Global.Settings.ProfileCount)
|
||||
LoadProfiles();
|
||||
@@ -663,7 +680,7 @@ namespace Netch.Forms
|
||||
}
|
||||
else
|
||||
{
|
||||
await ServerHelper.DelayTestHelper.TestAllDelayAsync();
|
||||
await DelayTestHelper.PerformTestAsync(true);
|
||||
Enable();
|
||||
}
|
||||
}
|
||||
@@ -761,25 +778,26 @@ namespace Netch.Forms
|
||||
var mode = (Mode)ModeComboBox.SelectedItem;
|
||||
if (ModifierKeys == Keys.Control)
|
||||
{
|
||||
Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!));
|
||||
Utils.Utils.Open(mode.FullName);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode.Type)
|
||||
{
|
||||
case ModeType.Process:
|
||||
case ModeType.ProcessMode:
|
||||
Hide();
|
||||
new ProcessForm(mode).ShowDialog();
|
||||
Show();
|
||||
break;
|
||||
case ModeType.ProxyRuleIPs:
|
||||
case ModeType.BypassRuleIPs:
|
||||
case ModeType.TunMode:
|
||||
Hide();
|
||||
new RouteForm(mode).ShowDialog();
|
||||
Show();
|
||||
break;
|
||||
case ModeType.ShareMode:
|
||||
// throw new NotImplementedException();
|
||||
default:
|
||||
Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath!));
|
||||
Utils.Utils.Open(mode.FullName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -793,7 +811,7 @@ namespace Netch.Forms
|
||||
return;
|
||||
}
|
||||
|
||||
ModeHelper.Delete((Mode)ModeComboBox.SelectedItem);
|
||||
ModeService.Delete((Mode)ModeComboBox.SelectedItem);
|
||||
SelectLastMode();
|
||||
}
|
||||
|
||||
@@ -990,12 +1008,13 @@ namespace Netch.Forms
|
||||
EditServerPictureBox.Enabled = DeleteModePictureBox.Enabled = DeleteServerPictureBox.Enabled = enabled;
|
||||
|
||||
// 启动需要禁用的控件
|
||||
UninstallServiceToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = enabled;
|
||||
ServerToolStripMenuItem.Enabled = ModeToolStripMenuItem.Enabled =
|
||||
SubscriptionToolStripMenuItem.Enabled = UninstallServiceToolStripMenuItem.Enabled = enabled;
|
||||
}
|
||||
|
||||
_state = value;
|
||||
|
||||
ServerHelper.DelayTestHelper.Enabled = IsWaiting(_state);
|
||||
DelayTestHelper.Enabled = IsWaiting(_state);
|
||||
|
||||
StatusText();
|
||||
switch (value)
|
||||
@@ -1025,7 +1044,7 @@ namespace Netch.Forms
|
||||
|
||||
ProfileGroupBox.Enabled = false;
|
||||
BandwidthState(false);
|
||||
NatTypeStatusText();
|
||||
ConnectivityStatusVisible(false);
|
||||
break;
|
||||
case State.Stopped:
|
||||
ControlButton.Enabled = true;
|
||||
@@ -1053,18 +1072,17 @@ namespace Netch.Forms
|
||||
private async Task StopCoreAsync()
|
||||
{
|
||||
State = State.Stopping;
|
||||
_discoveryNatCts?.Cancel();
|
||||
_httpConnectCts?.Cancel();
|
||||
await MainController.StopAsync();
|
||||
State = State.Stopped;
|
||||
}
|
||||
|
||||
private bool IsWaiting()
|
||||
{
|
||||
return State == State.Waiting || State == State.Stopped;
|
||||
}
|
||||
private bool IsWaiting() => IsWaiting(_state);
|
||||
|
||||
private static bool IsWaiting(State state)
|
||||
{
|
||||
return state == State.Waiting || state == State.Stopped;
|
||||
return state is State.Waiting or State.Stopped;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1080,9 +1098,10 @@ namespace Netch.Forms
|
||||
}
|
||||
|
||||
text ??= i18N.Translate(StateExtension.GetStatusString(State));
|
||||
StatusLabel.Text = i18N.Translate("Status", ": ") + text;
|
||||
if (_state == State.Started)
|
||||
StatusLabel.Text += StatusPortInfoText.Value;
|
||||
text += StatusPortInfoText.Value;
|
||||
|
||||
StatusLabel.Text = i18N.Translate("Status", ": ") + text;
|
||||
}
|
||||
|
||||
public void BandwidthState(bool state)
|
||||
@@ -1099,18 +1118,14 @@ namespace Netch.Forms
|
||||
UsedBandwidthLabel.Visible /*= UploadSpeedLabel.Visible*/ = DownloadSpeedLabel.Visible = state;
|
||||
}
|
||||
|
||||
private void NatTypeStatusText(string? text = null, string? country = null)
|
||||
private void UpdateNatTypeStatusLabelText(string? text, string? country = null)
|
||||
{
|
||||
if (State != State.Started)
|
||||
{
|
||||
NatTypeStatusLabel.Text = "";
|
||||
NatTypeStatusLabel.Visible = NatTypeStatusLightLabel.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
NatTypeStatusLabel.Text = $"NAT{i18N.Translate(": ")}{text} {(!country.IsNullOrEmpty() ? $"[{country}]" : "")}";
|
||||
if (country == null)
|
||||
NatTypeStatusLabel.Text = $"NAT{i18N.Translate(": ")}{text} ";
|
||||
else
|
||||
NatTypeStatusLabel.Text = $"NAT{i18N.Translate(": ")}{text} [{country}]";
|
||||
|
||||
UpdateNatTypeLight(int.TryParse(text, out var natType) ? natType : -1);
|
||||
}
|
||||
@@ -1122,10 +1137,18 @@ namespace Netch.Forms
|
||||
NatTypeStatusLabel.Visible = true;
|
||||
}
|
||||
|
||||
private void ConnectivityStatusVisible(bool visible)
|
||||
{
|
||||
if (!visible)
|
||||
HttpStatusLabel.Text = NatTypeStatusLabel.Text = "";
|
||||
|
||||
HttpStatusLabel.Visible = NatTypeStatusLabel.Visible = NatTypeStatusLightLabel.Visible = visible;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新 NAT指示灯颜色
|
||||
/// </summary>
|
||||
/// <param name="natType"></param>
|
||||
/// <param name="natType">NAT Type. keep default(-1) to Hide Light</param>
|
||||
private void UpdateNatTypeLight(int natType = -1)
|
||||
{
|
||||
if (natType > 0 && natType < 5)
|
||||
@@ -1148,46 +1171,81 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private async void NatTypeStatusLabel_Click(object sender, EventArgs e)
|
||||
private async void TcpStatusLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_state == State.Started && !Monitor.IsEntered(_natTestLock))
|
||||
await NatTestAsync();
|
||||
await HttpConnectAsync();
|
||||
}
|
||||
|
||||
private bool _natTestLock = true;
|
||||
|
||||
/// <summary>
|
||||
/// 测试 NAT
|
||||
/// </summary>
|
||||
private async Task NatTestAsync()
|
||||
private async void NatTypeStatusLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!MainController.Mode!.TestNatRequired())
|
||||
return;
|
||||
await DiscoveryNatTypeAsync();
|
||||
}
|
||||
|
||||
if (!_natTestLock)
|
||||
return;
|
||||
private CancellationTokenSource? _discoveryNatCts;
|
||||
|
||||
_natTestLock = false;
|
||||
private async Task DiscoveryNatTypeAsync()
|
||||
{
|
||||
NatTypeStatusLabel.Enabled = false;
|
||||
UpdateNatTypeStatusLabelText(i18N.Translate("Testing NAT Type"));
|
||||
|
||||
_discoveryNatCts = new CancellationTokenSource();
|
||||
|
||||
try
|
||||
{
|
||||
NatTypeStatusText(i18N.Translate("Testing NAT"));
|
||||
var res = await MainController.DiscoveryNatTypeAsync(_discoveryNatCts.Token);
|
||||
if (_discoveryNatCts.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var (result, _, publicEnd) = await MainController.NTTController.StartAsync();
|
||||
|
||||
if (!string.IsNullOrEmpty(publicEnd))
|
||||
if (!string.IsNullOrEmpty(res.PublicEnd))
|
||||
{
|
||||
var country = await Utils.Utils.GetCityCodeAsync(publicEnd!);
|
||||
NatTypeStatusText(result, country);
|
||||
var country = await Utils.Utils.GetCityCodeAsync(res.PublicEnd);
|
||||
|
||||
UpdateNatTypeStatusLabelText(res.Result, country);
|
||||
if (int.TryParse(res.Result, out var natType))
|
||||
UpdateNatTypeLight(natType);
|
||||
else
|
||||
UpdateNatTypeLight();
|
||||
}
|
||||
else
|
||||
{
|
||||
NatTypeStatusText(result ?? "Error");
|
||||
UpdateNatTypeStatusLabelText(res.Result ?? "Error");
|
||||
NatTypeStatusLightLabel.Visible = false;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_natTestLock = true;
|
||||
_discoveryNatCts.Dispose();
|
||||
_discoveryNatCts = null;
|
||||
NatTypeStatusLabel.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private CancellationTokenSource? _httpConnectCts;
|
||||
|
||||
private async Task HttpConnectAsync()
|
||||
{
|
||||
HttpStatusLabel.Enabled = false;
|
||||
|
||||
_httpConnectCts = new CancellationTokenSource();
|
||||
|
||||
try
|
||||
{
|
||||
var res = await MainController.HttpConnectAsync(_httpConnectCts.Token);
|
||||
if (_httpConnectCts.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
if (res != null)
|
||||
HttpStatusLabel.Text = $"HTTP{i18N.Translate(": ")}{res}ms";
|
||||
else
|
||||
HttpStatusLabel.Text = $"HTTP{i18N.Translate(": ", "Timeout")}";
|
||||
|
||||
HttpStatusLabel.Visible = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_httpConnectCts.Dispose();
|
||||
_httpConnectCts = null;
|
||||
HttpStatusLabel.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1209,7 +1267,7 @@ namespace Netch.Forms
|
||||
if (!IsWaiting())
|
||||
{
|
||||
_resumeFlag = true;
|
||||
Log.Information("操作系统即将挂起,自动停止");
|
||||
Log.Information("OS Suspend, Stop");
|
||||
ControlButton_Click(null, null);
|
||||
}
|
||||
|
||||
@@ -1218,7 +1276,7 @@ namespace Netch.Forms
|
||||
if (_resumeFlag)
|
||||
{
|
||||
_resumeFlag = false;
|
||||
Log.Information("操作系统即将从挂起状态继续,自动重启");
|
||||
Log.Information("OS Resume, Restart");
|
||||
ControlButton_Click(null, null);
|
||||
}
|
||||
|
||||
@@ -1253,7 +1311,7 @@ namespace Netch.Forms
|
||||
return;
|
||||
}
|
||||
|
||||
State = State.Terminating;
|
||||
// State = State.Terminating;
|
||||
NotifyIcon.Visible = false;
|
||||
Hide();
|
||||
|
||||
@@ -1445,6 +1503,7 @@ namespace Netch.Forms
|
||||
}
|
||||
case Mode item:
|
||||
{
|
||||
/*
|
||||
// 绘制 模式Box 底色
|
||||
e.Graphics.FillRectangle(Brushes.Gray, _numberBoxX, e.Bounds.Y, _numberBoxWidth, e.Bounds.Height);
|
||||
|
||||
@@ -1455,6 +1514,7 @@ namespace Netch.Forms
|
||||
new Point(_numberBoxX + _numberBoxWrap, e.Bounds.Y),
|
||||
Color.Black,
|
||||
TextFormatFlags.Left);
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Enums;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Netch.Forms.ModeForms
|
||||
return string.Empty;
|
||||
|
||||
var safeFileName = ToSafeFileName(name);
|
||||
var relativePath = $"Custom\\{safeFileName}.txt";
|
||||
var relativePath = $"Custom\\{safeFileName}.json";
|
||||
return relativePath;
|
||||
}
|
||||
}
|
||||
|
||||
628
Netch/Forms/ModeForms/ProcessForm.Designer.cs
generated
628
Netch/Forms/ModeForms/ProcessForm.Designer.cs
generated
@@ -32,43 +32,103 @@ namespace Netch.Forms.ModeForms
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.ConfigurationGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.ConfigurationLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.NamePanel = new System.Windows.Forms.Panel();
|
||||
this.RemarkLabel = new System.Windows.Forms.Label();
|
||||
this.RemarkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.FilenameLabel = new System.Windows.Forms.Label();
|
||||
this.FilenameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.containerControl1 = new System.Windows.Forms.ContainerControl();
|
||||
this.RuleRichTextBox = new System.Windows.Forms.RichTextBox();
|
||||
this.ProcessGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.SelectButton = new System.Windows.Forms.Button();
|
||||
this.ScanButton = new System.Windows.Forms.Button();
|
||||
this.ValidationButton = new System.Windows.Forms.Button();
|
||||
this.ControlButton = new System.Windows.Forms.Button();
|
||||
this.OptionsGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.ModeSpecificOptionsLabel = new System.Windows.Forms.Label();
|
||||
this.HandleTCPCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.HandleUDPCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.HandleDNSCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.DNSLabel = new System.Windows.Forms.Label();
|
||||
this.DNSTextBox = new System.Windows.Forms.TextBox();
|
||||
this.HandleProcDNSCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.ProxyDNSCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.HandleICMPCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.ICMPDelayLabel = new System.Windows.Forms.Label();
|
||||
this.ICMPDelayTextBox = new System.Windows.Forms.TextBox();
|
||||
this.HandleLoopbackCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.HandleLANCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.HandleChildProcCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.RuleTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.ValidationButton = new System.Windows.Forms.Button();
|
||||
this.HandleTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.HandleHelperFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.HandleLabel = new System.Windows.Forms.Label();
|
||||
this.HandleSelectButton = new System.Windows.Forms.Button();
|
||||
this.HandleScanButton = new System.Windows.Forms.Button();
|
||||
this.HandleContentTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.HandleRuleRichTextBox = new System.Windows.Forms.RichTextBox();
|
||||
this.BypassTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.BypassFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.BypassLabel = new System.Windows.Forms.Label();
|
||||
this.BypassSelectButton = new System.Windows.Forms.Button();
|
||||
this.BypassScanButton = new System.Windows.Forms.Button();
|
||||
this.BypassContentTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.BypassRuleRichTextBox = new System.Windows.Forms.RichTextBox();
|
||||
this.ConfigurationGroupBox.SuspendLayout();
|
||||
this.containerControl1.SuspendLayout();
|
||||
this.ProcessGroupBox.SuspendLayout();
|
||||
this.ConfigurationLayoutPanel.SuspendLayout();
|
||||
this.NamePanel.SuspendLayout();
|
||||
this.OptionsGroupBox.SuspendLayout();
|
||||
this.RuleTableLayoutPanel.SuspendLayout();
|
||||
this.HandleTableLayoutPanel.SuspendLayout();
|
||||
this.HandleHelperFlowLayoutPanel.SuspendLayout();
|
||||
this.HandleContentTableLayoutPanel.SuspendLayout();
|
||||
this.BypassTableLayoutPanel.SuspendLayout();
|
||||
this.BypassFlowLayoutPanel.SuspendLayout();
|
||||
this.BypassContentTableLayoutPanel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ConfigurationGroupBox
|
||||
//
|
||||
this.ConfigurationGroupBox.Controls.Add(this.RemarkLabel);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.RemarkTextBox);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.FilenameLabel);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.FilenameTextBox);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.containerControl1);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.ProcessGroupBox);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.ControlButton);
|
||||
this.ConfigurationGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.ConfigurationGroupBox.Controls.Add(this.ConfigurationLayoutPanel);
|
||||
this.ConfigurationGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ConfigurationGroupBox.Location = new System.Drawing.Point(12, 5);
|
||||
this.ConfigurationGroupBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.ConfigurationGroupBox.Name = "ConfigurationGroupBox";
|
||||
this.ConfigurationGroupBox.Size = new System.Drawing.Size(431, 378);
|
||||
this.ConfigurationGroupBox.Size = new System.Drawing.Size(934, 591);
|
||||
this.ConfigurationGroupBox.TabIndex = 0;
|
||||
this.ConfigurationGroupBox.TabStop = false;
|
||||
this.ConfigurationGroupBox.Text = "Configuration";
|
||||
//
|
||||
// ConfigurationLayoutPanel
|
||||
//
|
||||
this.ConfigurationLayoutPanel.ColumnCount = 1;
|
||||
this.ConfigurationLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.ConfigurationLayoutPanel.Controls.Add(this.NamePanel, 0, 0);
|
||||
this.ConfigurationLayoutPanel.Controls.Add(this.OptionsGroupBox, 0, 1);
|
||||
this.ConfigurationLayoutPanel.Controls.Add(this.RuleTableLayoutPanel, 0, 2);
|
||||
this.ConfigurationLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ConfigurationLayoutPanel.Location = new System.Drawing.Point(3, 19);
|
||||
this.ConfigurationLayoutPanel.Name = "ConfigurationLayoutPanel";
|
||||
this.ConfigurationLayoutPanel.RowCount = 3;
|
||||
this.ConfigurationLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.ConfigurationLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.ConfigurationLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.ConfigurationLayoutPanel.Size = new System.Drawing.Size(928, 569);
|
||||
this.ConfigurationLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// NamePanel
|
||||
//
|
||||
this.NamePanel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.NamePanel.Controls.Add(this.RemarkLabel);
|
||||
this.NamePanel.Controls.Add(this.RemarkTextBox);
|
||||
this.NamePanel.Controls.Add(this.FilenameLabel);
|
||||
this.NamePanel.Controls.Add(this.FilenameTextBox);
|
||||
this.NamePanel.Controls.Add(this.ControlButton);
|
||||
this.NamePanel.Location = new System.Drawing.Point(208, 3);
|
||||
this.NamePanel.Name = "NamePanel";
|
||||
this.NamePanel.Size = new System.Drawing.Size(512, 72);
|
||||
this.NamePanel.TabIndex = 0;
|
||||
//
|
||||
// RemarkLabel
|
||||
//
|
||||
this.RemarkLabel.AutoSize = true;
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(12, 25);
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(8, 8);
|
||||
this.RemarkLabel.Name = "RemarkLabel";
|
||||
this.RemarkLabel.Size = new System.Drawing.Size(53, 17);
|
||||
this.RemarkLabel.TabIndex = 0;
|
||||
@@ -76,7 +136,7 @@ namespace Netch.Forms.ModeForms
|
||||
//
|
||||
// RemarkTextBox
|
||||
//
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(84, 22);
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(72, 8);
|
||||
this.RemarkTextBox.Name = "RemarkTextBox";
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(341, 23);
|
||||
this.RemarkTextBox.TabIndex = 1;
|
||||
@@ -85,7 +145,7 @@ namespace Netch.Forms.ModeForms
|
||||
// FilenameLabel
|
||||
//
|
||||
this.FilenameLabel.AutoSize = true;
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(12, 55);
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(8, 40);
|
||||
this.FilenameLabel.Name = "FilenameLabel";
|
||||
this.FilenameLabel.Size = new System.Drawing.Size(59, 17);
|
||||
this.FilenameLabel.TabIndex = 2;
|
||||
@@ -93,119 +153,491 @@ namespace Netch.Forms.ModeForms
|
||||
//
|
||||
// FilenameTextBox
|
||||
//
|
||||
this.FilenameTextBox.Location = new System.Drawing.Point(84, 52);
|
||||
this.FilenameTextBox.Location = new System.Drawing.Point(72, 40);
|
||||
this.FilenameTextBox.Name = "FilenameTextBox";
|
||||
this.FilenameTextBox.ReadOnly = true;
|
||||
this.FilenameTextBox.Size = new System.Drawing.Size(341, 23);
|
||||
this.FilenameTextBox.TabIndex = 3;
|
||||
//
|
||||
// containerControl1
|
||||
//
|
||||
this.containerControl1.Controls.Add(this.RuleRichTextBox);
|
||||
this.containerControl1.Location = new System.Drawing.Point(6, 81);
|
||||
this.containerControl1.Name = "containerControl1";
|
||||
this.containerControl1.Size = new System.Drawing.Size(419, 221);
|
||||
this.containerControl1.TabIndex = 4;
|
||||
this.containerControl1.Text = "containerControl1";
|
||||
//
|
||||
// RuleRichTextBox
|
||||
//
|
||||
this.RuleRichTextBox.DetectUrls = false;
|
||||
this.RuleRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.RuleRichTextBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.RuleRichTextBox.Name = "RuleRichTextBox";
|
||||
this.RuleRichTextBox.Size = new System.Drawing.Size(419, 221);
|
||||
this.RuleRichTextBox.TabIndex = 0;
|
||||
this.RuleRichTextBox.Text = "";
|
||||
this.RuleRichTextBox.WordWrap = false;
|
||||
//
|
||||
// ProcessGroupBox
|
||||
//
|
||||
this.ProcessGroupBox.Controls.Add(this.SelectButton);
|
||||
this.ProcessGroupBox.Controls.Add(this.ScanButton);
|
||||
this.ProcessGroupBox.Controls.Add(this.ValidationButton);
|
||||
this.ProcessGroupBox.Location = new System.Drawing.Point(6, 295);
|
||||
this.ProcessGroupBox.Name = "ProcessGroupBox";
|
||||
this.ProcessGroupBox.Size = new System.Drawing.Size(419, 44);
|
||||
this.ProcessGroupBox.TabIndex = 5;
|
||||
this.ProcessGroupBox.TabStop = false;
|
||||
//
|
||||
// SelectButton
|
||||
//
|
||||
this.SelectButton.Location = new System.Drawing.Point(6, 13);
|
||||
this.SelectButton.Name = "SelectButton";
|
||||
this.SelectButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.SelectButton.TabIndex = 0;
|
||||
this.SelectButton.Text = "Select";
|
||||
this.SelectButton.UseVisualStyleBackColor = true;
|
||||
this.SelectButton.Click += new System.EventHandler(this.SelectButton_Click);
|
||||
//
|
||||
// ScanButton
|
||||
//
|
||||
this.ScanButton.Location = new System.Drawing.Point(87, 13);
|
||||
this.ScanButton.Name = "ScanButton";
|
||||
this.ScanButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.ScanButton.TabIndex = 1;
|
||||
this.ScanButton.Text = "Scan";
|
||||
this.ScanButton.UseVisualStyleBackColor = true;
|
||||
this.ScanButton.Click += new System.EventHandler(this.ScanButton_Click);
|
||||
//
|
||||
// ValidationButton
|
||||
//
|
||||
this.ValidationButton.Location = new System.Drawing.Point(338, 13);
|
||||
this.ValidationButton.Name = "ValidationButton";
|
||||
this.ValidationButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.ValidationButton.TabIndex = 2;
|
||||
this.ValidationButton.Text = "Validation";
|
||||
this.ValidationButton.UseVisualStyleBackColor = true;
|
||||
this.ValidationButton.Click += new System.EventHandler(this.ValidationButton_Click);
|
||||
//
|
||||
// ControlButton
|
||||
//
|
||||
this.ControlButton.Location = new System.Drawing.Point(344, 345);
|
||||
this.ControlButton.Location = new System.Drawing.Point(424, 40);
|
||||
this.ControlButton.Name = "ControlButton";
|
||||
this.ControlButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.ControlButton.TabIndex = 6;
|
||||
this.ControlButton.TabIndex = 4;
|
||||
this.ControlButton.Text = "Save";
|
||||
this.ControlButton.UseVisualStyleBackColor = true;
|
||||
this.ControlButton.Click += new System.EventHandler(this.ControlButton_Click);
|
||||
//
|
||||
// Process
|
||||
// OptionsGroupBox
|
||||
//
|
||||
this.OptionsGroupBox.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.OptionsGroupBox.Controls.Add(this.ModeSpecificOptionsLabel);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleTCPCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleUDPCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleDNSCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.DNSLabel);
|
||||
this.OptionsGroupBox.Controls.Add(this.DNSTextBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleProcDNSCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.ProxyDNSCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleICMPCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.ICMPDelayLabel);
|
||||
this.OptionsGroupBox.Controls.Add(this.ICMPDelayTextBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleLoopbackCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleLANCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleChildProcCheckBox);
|
||||
this.OptionsGroupBox.Location = new System.Drawing.Point(15, 81);
|
||||
this.OptionsGroupBox.Name = "OptionsGroupBox";
|
||||
this.OptionsGroupBox.Size = new System.Drawing.Size(898, 183);
|
||||
this.OptionsGroupBox.TabIndex = 1;
|
||||
this.OptionsGroupBox.TabStop = false;
|
||||
//
|
||||
// ModeSpecificOptionsLabel
|
||||
//
|
||||
this.ModeSpecificOptionsLabel.AutoSize = true;
|
||||
this.ModeSpecificOptionsLabel.Location = new System.Drawing.Point(720, 24);
|
||||
this.ModeSpecificOptionsLabel.Name = "ModeSpecificOptionsLabel";
|
||||
this.ModeSpecificOptionsLabel.Size = new System.Drawing.Size(138, 17);
|
||||
this.ModeSpecificOptionsLabel.TabIndex = 13;
|
||||
this.ModeSpecificOptionsLabel.Text = "Mode specific options";
|
||||
//
|
||||
// HandleTCPCheckBox
|
||||
//
|
||||
this.HandleTCPCheckBox.AutoCheck = false;
|
||||
this.HandleTCPCheckBox.AutoSize = true;
|
||||
this.HandleTCPCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleTCPCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleTCPCheckBox.GlobalValue = false;
|
||||
this.HandleTCPCheckBox.Location = new System.Drawing.Point(8, 24);
|
||||
this.HandleTCPCheckBox.Name = "HandleTCPCheckBox";
|
||||
this.HandleTCPCheckBox.Size = new System.Drawing.Size(99, 21);
|
||||
this.HandleTCPCheckBox.SyncGlobal = false;
|
||||
this.HandleTCPCheckBox.TabIndex = 0;
|
||||
this.HandleTCPCheckBox.Text = "Handle TCP";
|
||||
this.HandleTCPCheckBox.ThreeState = true;
|
||||
this.HandleTCPCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleTCPCheckBox.Value = false;
|
||||
//
|
||||
// HandleUDPCheckBox
|
||||
//
|
||||
this.HandleUDPCheckBox.AutoCheck = false;
|
||||
this.HandleUDPCheckBox.AutoSize = true;
|
||||
this.HandleUDPCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleUDPCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleUDPCheckBox.GlobalValue = false;
|
||||
this.HandleUDPCheckBox.Location = new System.Drawing.Point(8, 56);
|
||||
this.HandleUDPCheckBox.Name = "HandleUDPCheckBox";
|
||||
this.HandleUDPCheckBox.Size = new System.Drawing.Size(102, 21);
|
||||
this.HandleUDPCheckBox.SyncGlobal = false;
|
||||
this.HandleUDPCheckBox.TabIndex = 1;
|
||||
this.HandleUDPCheckBox.Text = "Handle UDP";
|
||||
this.HandleUDPCheckBox.ThreeState = true;
|
||||
this.HandleUDPCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleUDPCheckBox.Value = false;
|
||||
//
|
||||
// HandleDNSCheckBox
|
||||
//
|
||||
this.HandleDNSCheckBox.AutoCheck = false;
|
||||
this.HandleDNSCheckBox.AutoSize = true;
|
||||
this.HandleDNSCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleDNSCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleDNSCheckBox.GlobalValue = false;
|
||||
this.HandleDNSCheckBox.Location = new System.Drawing.Point(8, 88);
|
||||
this.HandleDNSCheckBox.Name = "HandleDNSCheckBox";
|
||||
this.HandleDNSCheckBox.Size = new System.Drawing.Size(203, 21);
|
||||
this.HandleDNSCheckBox.SyncGlobal = false;
|
||||
this.HandleDNSCheckBox.TabIndex = 2;
|
||||
this.HandleDNSCheckBox.Text = "Handle DNS (DNS hijacking)";
|
||||
this.HandleDNSCheckBox.ThreeState = true;
|
||||
this.HandleDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleDNSCheckBox.Value = false;
|
||||
//
|
||||
// DNSLabel
|
||||
//
|
||||
this.DNSLabel.AutoSize = true;
|
||||
this.DNSLabel.Location = new System.Drawing.Point(248, 88);
|
||||
this.DNSLabel.Name = "DNSLabel";
|
||||
this.DNSLabel.Size = new System.Drawing.Size(34, 17);
|
||||
this.DNSLabel.TabIndex = 3;
|
||||
this.DNSLabel.Text = "DNS";
|
||||
//
|
||||
// DNSTextBox
|
||||
//
|
||||
this.DNSTextBox.Location = new System.Drawing.Point(296, 88);
|
||||
this.DNSTextBox.Name = "DNSTextBox";
|
||||
this.DNSTextBox.Size = new System.Drawing.Size(184, 23);
|
||||
this.DNSTextBox.TabIndex = 4;
|
||||
this.DNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// HandleProcDNSCheckBox
|
||||
//
|
||||
this.HandleProcDNSCheckBox.AutoCheck = false;
|
||||
this.HandleProcDNSCheckBox.AutoSize = true;
|
||||
this.HandleProcDNSCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleProcDNSCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleProcDNSCheckBox.GlobalValue = false;
|
||||
this.HandleProcDNSCheckBox.Location = new System.Drawing.Point(8, 120);
|
||||
this.HandleProcDNSCheckBox.Name = "HandleProcDNSCheckBox";
|
||||
this.HandleProcDNSCheckBox.Size = new System.Drawing.Size(216, 21);
|
||||
this.HandleProcDNSCheckBox.SyncGlobal = false;
|
||||
this.HandleProcDNSCheckBox.TabIndex = 5;
|
||||
this.HandleProcDNSCheckBox.Text = "Handle handled process\'s DNS";
|
||||
this.HandleProcDNSCheckBox.ThreeState = true;
|
||||
this.HandleProcDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleProcDNSCheckBox.Value = false;
|
||||
//
|
||||
// ProxyDNSCheckBox
|
||||
//
|
||||
this.ProxyDNSCheckBox.AutoCheck = false;
|
||||
this.ProxyDNSCheckBox.AutoSize = true;
|
||||
this.ProxyDNSCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.ProxyDNSCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.ProxyDNSCheckBox.GlobalValue = false;
|
||||
this.ProxyDNSCheckBox.Location = new System.Drawing.Point(240, 120);
|
||||
this.ProxyDNSCheckBox.Name = "ProxyDNSCheckBox";
|
||||
this.ProxyDNSCheckBox.Size = new System.Drawing.Size(195, 21);
|
||||
this.ProxyDNSCheckBox.SyncGlobal = false;
|
||||
this.ProxyDNSCheckBox.TabIndex = 6;
|
||||
this.ProxyDNSCheckBox.Text = "Handle DNS through proxy";
|
||||
this.ProxyDNSCheckBox.ThreeState = true;
|
||||
this.ProxyDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.ProxyDNSCheckBox.Value = false;
|
||||
//
|
||||
// HandleICMPCheckBox
|
||||
//
|
||||
this.HandleICMPCheckBox.AutoCheck = false;
|
||||
this.HandleICMPCheckBox.AutoSize = true;
|
||||
this.HandleICMPCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleICMPCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleICMPCheckBox.GlobalValue = false;
|
||||
this.HandleICMPCheckBox.Location = new System.Drawing.Point(8, 152);
|
||||
this.HandleICMPCheckBox.Name = "HandleICMPCheckBox";
|
||||
this.HandleICMPCheckBox.Size = new System.Drawing.Size(107, 21);
|
||||
this.HandleICMPCheckBox.SyncGlobal = false;
|
||||
this.HandleICMPCheckBox.TabIndex = 7;
|
||||
this.HandleICMPCheckBox.Text = "Handle ICMP";
|
||||
this.HandleICMPCheckBox.ThreeState = true;
|
||||
this.HandleICMPCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleICMPCheckBox.Value = false;
|
||||
//
|
||||
// ICMPDelayLabel
|
||||
//
|
||||
this.ICMPDelayLabel.AutoSize = true;
|
||||
this.ICMPDelayLabel.Location = new System.Drawing.Point(176, 152);
|
||||
this.ICMPDelayLabel.Name = "ICMPDelayLabel";
|
||||
this.ICMPDelayLabel.Size = new System.Drawing.Size(99, 17);
|
||||
this.ICMPDelayLabel.TabIndex = 8;
|
||||
this.ICMPDelayLabel.Text = "ICMP delay(ms)";
|
||||
//
|
||||
// ICMPDelayTextBox
|
||||
//
|
||||
this.ICMPDelayTextBox.Location = new System.Drawing.Point(296, 152);
|
||||
this.ICMPDelayTextBox.Name = "ICMPDelayTextBox";
|
||||
this.ICMPDelayTextBox.Size = new System.Drawing.Size(80, 23);
|
||||
this.ICMPDelayTextBox.TabIndex = 9;
|
||||
this.ICMPDelayTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// HandleLoopbackCheckBox
|
||||
//
|
||||
this.HandleLoopbackCheckBox.AutoSize = true;
|
||||
this.HandleLoopbackCheckBox.Location = new System.Drawing.Point(720, 56);
|
||||
this.HandleLoopbackCheckBox.Name = "HandleLoopbackCheckBox";
|
||||
this.HandleLoopbackCheckBox.Size = new System.Drawing.Size(158, 21);
|
||||
this.HandleLoopbackCheckBox.TabIndex = 10;
|
||||
this.HandleLoopbackCheckBox.Text = "Handle local loopback";
|
||||
this.HandleLoopbackCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// HandleLANCheckBox
|
||||
//
|
||||
this.HandleLANCheckBox.AutoSize = true;
|
||||
this.HandleLANCheckBox.Location = new System.Drawing.Point(720, 88);
|
||||
this.HandleLANCheckBox.Name = "HandleLANCheckBox";
|
||||
this.HandleLANCheckBox.Size = new System.Drawing.Size(96, 21);
|
||||
this.HandleLANCheckBox.TabIndex = 11;
|
||||
this.HandleLANCheckBox.Text = "Handle LAN";
|
||||
this.HandleLANCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// HandleChildProcCheckBox
|
||||
//
|
||||
this.HandleChildProcCheckBox.AutoCheck = false;
|
||||
this.HandleChildProcCheckBox.AutoSize = true;
|
||||
this.HandleChildProcCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleChildProcCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleChildProcCheckBox.GlobalValue = false;
|
||||
this.HandleChildProcCheckBox.Location = new System.Drawing.Point(496, 24);
|
||||
this.HandleChildProcCheckBox.Name = "HandleChildProcCheckBox";
|
||||
this.HandleChildProcCheckBox.Size = new System.Drawing.Size(155, 21);
|
||||
this.HandleChildProcCheckBox.SyncGlobal = false;
|
||||
this.HandleChildProcCheckBox.TabIndex = 12;
|
||||
this.HandleChildProcCheckBox.Text = "Handle child process";
|
||||
this.HandleChildProcCheckBox.ThreeState = true;
|
||||
this.HandleChildProcCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleChildProcCheckBox.Value = false;
|
||||
//
|
||||
// RuleTableLayoutPanel
|
||||
//
|
||||
this.RuleTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.RuleTableLayoutPanel.ColumnCount = 2;
|
||||
this.RuleTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.RuleTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.RuleTableLayoutPanel.Controls.Add(this.ValidationButton, 0, 0);
|
||||
this.RuleTableLayoutPanel.Controls.Add(this.HandleTableLayoutPanel, 0, 1);
|
||||
this.RuleTableLayoutPanel.Controls.Add(this.BypassTableLayoutPanel, 1, 1);
|
||||
this.RuleTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.RuleTableLayoutPanel.Location = new System.Drawing.Point(3, 270);
|
||||
this.RuleTableLayoutPanel.Name = "RuleTableLayoutPanel";
|
||||
this.RuleTableLayoutPanel.RowCount = 2;
|
||||
this.RuleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.RuleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.RuleTableLayoutPanel.Size = new System.Drawing.Size(922, 296);
|
||||
this.RuleTableLayoutPanel.TabIndex = 2;
|
||||
//
|
||||
// ValidationButton
|
||||
//
|
||||
this.ValidationButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.RuleTableLayoutPanel.SetColumnSpan(this.ValidationButton, 2);
|
||||
this.ValidationButton.Location = new System.Drawing.Point(423, 3);
|
||||
this.ValidationButton.Name = "ValidationButton";
|
||||
this.ValidationButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.ValidationButton.TabIndex = 0;
|
||||
this.ValidationButton.Text = "Validation";
|
||||
this.ValidationButton.UseVisualStyleBackColor = true;
|
||||
this.ValidationButton.Click += new System.EventHandler(this.ValidationButton_Click);
|
||||
//
|
||||
// HandleTableLayoutPanel
|
||||
//
|
||||
this.HandleTableLayoutPanel.ColumnCount = 1;
|
||||
this.HandleTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.HandleTableLayoutPanel.Controls.Add(this.HandleHelperFlowLayoutPanel, 0, 0);
|
||||
this.HandleTableLayoutPanel.Controls.Add(this.HandleContentTableLayoutPanel, 0, 1);
|
||||
this.HandleTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.HandleTableLayoutPanel.Location = new System.Drawing.Point(3, 32);
|
||||
this.HandleTableLayoutPanel.Name = "HandleTableLayoutPanel";
|
||||
this.HandleTableLayoutPanel.RowCount = 2;
|
||||
this.HandleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.HandleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.HandleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.HandleTableLayoutPanel.Size = new System.Drawing.Size(455, 261);
|
||||
this.HandleTableLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// HandleHelperFlowLayoutPanel
|
||||
//
|
||||
this.HandleHelperFlowLayoutPanel.Controls.Add(this.HandleLabel);
|
||||
this.HandleHelperFlowLayoutPanel.Controls.Add(this.HandleSelectButton);
|
||||
this.HandleHelperFlowLayoutPanel.Controls.Add(this.HandleScanButton);
|
||||
this.HandleHelperFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
|
||||
this.HandleHelperFlowLayoutPanel.Name = "HandleHelperFlowLayoutPanel";
|
||||
this.HandleHelperFlowLayoutPanel.Size = new System.Drawing.Size(269, 32);
|
||||
this.HandleHelperFlowLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// HandleLabel
|
||||
//
|
||||
this.HandleLabel.AutoSize = true;
|
||||
this.HandleLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.HandleLabel.Name = "HandleLabel";
|
||||
this.HandleLabel.Padding = new System.Windows.Forms.Padding(7);
|
||||
this.HandleLabel.Size = new System.Drawing.Size(95, 31);
|
||||
this.HandleLabel.TabIndex = 0;
|
||||
this.HandleLabel.Text = "Handle rules";
|
||||
//
|
||||
// HandleSelectButton
|
||||
//
|
||||
this.HandleSelectButton.Location = new System.Drawing.Point(104, 3);
|
||||
this.HandleSelectButton.Name = "HandleSelectButton";
|
||||
this.HandleSelectButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.HandleSelectButton.TabIndex = 1;
|
||||
this.HandleSelectButton.Text = "Select";
|
||||
this.HandleSelectButton.UseVisualStyleBackColor = true;
|
||||
this.HandleSelectButton.Click += new System.EventHandler(this.SelectButton_Click);
|
||||
//
|
||||
// HandleScanButton
|
||||
//
|
||||
this.HandleHelperFlowLayoutPanel.SetFlowBreak(this.HandleScanButton, true);
|
||||
this.HandleScanButton.Location = new System.Drawing.Point(185, 3);
|
||||
this.HandleScanButton.Name = "HandleScanButton";
|
||||
this.HandleScanButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.HandleScanButton.TabIndex = 2;
|
||||
this.HandleScanButton.Text = "Scan";
|
||||
this.HandleScanButton.UseVisualStyleBackColor = true;
|
||||
this.HandleScanButton.Click += new System.EventHandler(this.ScanButton_Click);
|
||||
//
|
||||
// HandleContentTableLayoutPanel
|
||||
//
|
||||
this.HandleContentTableLayoutPanel.ColumnCount = 1;
|
||||
this.HandleContentTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.HandleContentTableLayoutPanel.Controls.Add(this.HandleRuleRichTextBox, 0, 0);
|
||||
this.HandleContentTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.HandleContentTableLayoutPanel.Location = new System.Drawing.Point(3, 41);
|
||||
this.HandleContentTableLayoutPanel.Name = "HandleContentTableLayoutPanel";
|
||||
this.HandleContentTableLayoutPanel.RowCount = 1;
|
||||
this.HandleContentTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.HandleContentTableLayoutPanel.Size = new System.Drawing.Size(449, 217);
|
||||
this.HandleContentTableLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// HandleRuleRichTextBox
|
||||
//
|
||||
this.HandleRuleRichTextBox.DetectUrls = false;
|
||||
this.HandleRuleRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.HandleRuleRichTextBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.HandleRuleRichTextBox.Name = "HandleRuleRichTextBox";
|
||||
this.HandleRuleRichTextBox.Size = new System.Drawing.Size(443, 211);
|
||||
this.HandleRuleRichTextBox.TabIndex = 0;
|
||||
this.HandleRuleRichTextBox.Text = "";
|
||||
this.HandleRuleRichTextBox.WordWrap = false;
|
||||
//
|
||||
// BypassTableLayoutPanel
|
||||
//
|
||||
this.BypassTableLayoutPanel.ColumnCount = 1;
|
||||
this.BypassTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.BypassTableLayoutPanel.Controls.Add(this.BypassFlowLayoutPanel, 0, 0);
|
||||
this.BypassTableLayoutPanel.Controls.Add(this.BypassContentTableLayoutPanel, 0, 1);
|
||||
this.BypassTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.BypassTableLayoutPanel.Location = new System.Drawing.Point(464, 32);
|
||||
this.BypassTableLayoutPanel.Name = "BypassTableLayoutPanel";
|
||||
this.BypassTableLayoutPanel.RowCount = 2;
|
||||
this.BypassTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.BypassTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.BypassTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.BypassTableLayoutPanel.Size = new System.Drawing.Size(455, 261);
|
||||
this.BypassTableLayoutPanel.TabIndex = 2;
|
||||
//
|
||||
// BypassFlowLayoutPanel
|
||||
//
|
||||
this.BypassFlowLayoutPanel.Controls.Add(this.BypassLabel);
|
||||
this.BypassFlowLayoutPanel.Controls.Add(this.BypassSelectButton);
|
||||
this.BypassFlowLayoutPanel.Controls.Add(this.BypassScanButton);
|
||||
this.BypassFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
|
||||
this.BypassFlowLayoutPanel.Name = "BypassFlowLayoutPanel";
|
||||
this.BypassFlowLayoutPanel.Size = new System.Drawing.Size(269, 32);
|
||||
this.BypassFlowLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// BypassLabel
|
||||
//
|
||||
this.BypassLabel.AutoSize = true;
|
||||
this.BypassLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.BypassLabel.Name = "BypassLabel";
|
||||
this.BypassLabel.Padding = new System.Windows.Forms.Padding(7);
|
||||
this.BypassLabel.Size = new System.Drawing.Size(95, 31);
|
||||
this.BypassLabel.TabIndex = 0;
|
||||
this.BypassLabel.Text = "Bypass rules";
|
||||
//
|
||||
// BypassSelectButton
|
||||
//
|
||||
this.BypassSelectButton.Location = new System.Drawing.Point(104, 3);
|
||||
this.BypassSelectButton.Name = "BypassSelectButton";
|
||||
this.BypassSelectButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.BypassSelectButton.TabIndex = 1;
|
||||
this.BypassSelectButton.Text = "Select";
|
||||
this.BypassSelectButton.UseVisualStyleBackColor = true;
|
||||
this.BypassSelectButton.Click += new System.EventHandler(this.SelectButton_Click);
|
||||
//
|
||||
// BypassScanButton
|
||||
//
|
||||
this.BypassScanButton.Location = new System.Drawing.Point(185, 3);
|
||||
this.BypassScanButton.Name = "BypassScanButton";
|
||||
this.BypassScanButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.BypassScanButton.TabIndex = 2;
|
||||
this.BypassScanButton.Text = "Scan";
|
||||
this.BypassScanButton.UseVisualStyleBackColor = true;
|
||||
this.BypassScanButton.Click += new System.EventHandler(this.ScanButton_Click);
|
||||
//
|
||||
// BypassContentTableLayoutPanel
|
||||
//
|
||||
this.BypassContentTableLayoutPanel.ColumnCount = 1;
|
||||
this.BypassContentTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.BypassContentTableLayoutPanel.Controls.Add(this.BypassRuleRichTextBox, 0, 0);
|
||||
this.BypassContentTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.BypassContentTableLayoutPanel.Location = new System.Drawing.Point(3, 41);
|
||||
this.BypassContentTableLayoutPanel.Name = "BypassContentTableLayoutPanel";
|
||||
this.BypassContentTableLayoutPanel.RowCount = 1;
|
||||
this.BypassContentTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.BypassContentTableLayoutPanel.Size = new System.Drawing.Size(449, 217);
|
||||
this.BypassContentTableLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// BypassRuleRichTextBox
|
||||
//
|
||||
this.BypassRuleRichTextBox.DetectUrls = false;
|
||||
this.BypassRuleRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.BypassRuleRichTextBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.BypassRuleRichTextBox.Name = "BypassRuleRichTextBox";
|
||||
this.BypassRuleRichTextBox.Size = new System.Drawing.Size(443, 211);
|
||||
this.BypassRuleRichTextBox.TabIndex = 0;
|
||||
this.BypassRuleRichTextBox.Text = "";
|
||||
this.BypassRuleRichTextBox.WordWrap = false;
|
||||
//
|
||||
// ProcessForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||
this.ClientSize = new System.Drawing.Size(455, 388);
|
||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.ClientSize = new System.Drawing.Size(934, 591);
|
||||
this.Controls.Add(this.ConfigurationGroupBox);
|
||||
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimumSize = new System.Drawing.Size(950, 630);
|
||||
this.Name = "ProcessForm";
|
||||
this.Padding = new System.Windows.Forms.Padding(12, 5, 12, 5);
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Create Process Mode";
|
||||
this.Load += new System.EventHandler(this.ModeForm_Load);
|
||||
this.ConfigurationGroupBox.ResumeLayout(false);
|
||||
this.ConfigurationGroupBox.PerformLayout();
|
||||
this.containerControl1.ResumeLayout(false);
|
||||
this.ProcessGroupBox.ResumeLayout(false);
|
||||
this.ConfigurationLayoutPanel.ResumeLayout(false);
|
||||
this.NamePanel.ResumeLayout(false);
|
||||
this.NamePanel.PerformLayout();
|
||||
this.OptionsGroupBox.ResumeLayout(false);
|
||||
this.OptionsGroupBox.PerformLayout();
|
||||
this.RuleTableLayoutPanel.ResumeLayout(false);
|
||||
this.HandleTableLayoutPanel.ResumeLayout(false);
|
||||
this.HandleHelperFlowLayoutPanel.ResumeLayout(false);
|
||||
this.HandleHelperFlowLayoutPanel.PerformLayout();
|
||||
this.HandleContentTableLayoutPanel.ResumeLayout(false);
|
||||
this.BypassTableLayoutPanel.ResumeLayout(false);
|
||||
this.BypassFlowLayoutPanel.ResumeLayout(false);
|
||||
this.BypassFlowLayoutPanel.PerformLayout();
|
||||
this.BypassContentTableLayoutPanel.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button ScanButton;
|
||||
private System.Windows.Forms.ContainerControl containerControl1;
|
||||
private System.Windows.Forms.Button HandleScanButton;
|
||||
public System.Windows.Forms.GroupBox ConfigurationGroupBox;
|
||||
private System.Windows.Forms.Label RemarkLabel;
|
||||
private System.Windows.Forms.GroupBox ProcessGroupBox;
|
||||
private System.Windows.Forms.TextBox RemarkTextBox;
|
||||
private System.Windows.Forms.Button SelectButton;
|
||||
private System.Windows.Forms.Button HandleSelectButton;
|
||||
public System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.Label FilenameLabel;
|
||||
private System.Windows.Forms.TextBox FilenameTextBox;
|
||||
private RichTextBox RuleRichTextBox;
|
||||
private RichTextBox HandleRuleRichTextBox;
|
||||
private Button ValidationButton;
|
||||
private RichTextBox BypassRuleRichTextBox;
|
||||
private Button BypassSelectButton;
|
||||
private Button BypassScanButton;
|
||||
private Label BypassLabel;
|
||||
private Label HandleLabel;
|
||||
private GroupBox OptionsGroupBox;
|
||||
private SyncGlobalCheckBox ProxyDNSCheckBox;
|
||||
private SyncGlobalCheckBox HandleDNSCheckBox;
|
||||
private SyncGlobalCheckBox HandleUDPCheckBox;
|
||||
private SyncGlobalCheckBox HandleTCPCheckBox;
|
||||
private CheckBox HandleLANCheckBox;
|
||||
private CheckBox HandleLoopbackCheckBox;
|
||||
private TextBox ICMPDelayTextBox;
|
||||
private TextBox DNSTextBox;
|
||||
private SyncGlobalCheckBox HandleICMPCheckBox;
|
||||
private SyncGlobalCheckBox HandleProcDNSCheckBox;
|
||||
private Label ICMPDelayLabel;
|
||||
private Label DNSLabel;
|
||||
private FlowLayoutPanel BypassFlowLayoutPanel;
|
||||
private FlowLayoutPanel HandleHelperFlowLayoutPanel;
|
||||
private TableLayoutPanel ConfigurationLayoutPanel;
|
||||
private Panel NamePanel;
|
||||
private TableLayoutPanel HandleTableLayoutPanel;
|
||||
private TableLayoutPanel RuleTableLayoutPanel;
|
||||
private TableLayoutPanel BypassTableLayoutPanel;
|
||||
private TableLayoutPanel HandleContentTableLayoutPanel;
|
||||
private TableLayoutPanel BypassContentTableLayoutPanel;
|
||||
private SyncGlobalCheckBox HandleChildProcCheckBox;
|
||||
private Label ModeSpecificOptionsLabel;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,24 @@
|
||||
using Microsoft.WindowsAPICodePack.Dialogs;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Enums;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Models.Modes.ProcessMode;
|
||||
using Netch.Properties;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.ModeForms
|
||||
{
|
||||
public partial class ProcessForm : Form
|
||||
public partial class ProcessForm : BindingForm
|
||||
{
|
||||
/// <summary>
|
||||
/// 被编辑的模式
|
||||
/// </summary>
|
||||
private readonly Mode? _mode;
|
||||
private readonly bool IsCreateMode;
|
||||
|
||||
private readonly Redirector _mode;
|
||||
|
||||
/// <summary>
|
||||
/// 编辑模式
|
||||
@@ -25,131 +26,141 @@ namespace Netch.Forms.ModeForms
|
||||
/// <param name="mode">模式</param>
|
||||
public ProcessForm(Mode? mode = null)
|
||||
{
|
||||
if (mode != null && mode.Type is not ModeType.Process)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
switch (mode)
|
||||
{
|
||||
case Redirector processMode:
|
||||
IsCreateMode = false;
|
||||
_mode = processMode;
|
||||
break;
|
||||
case null:
|
||||
IsCreateMode = true;
|
||||
_mode = new Redirector();
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
Icon = Resources.icon;
|
||||
CheckForIllegalCrossThreadCalls = false;
|
||||
InitBindings();
|
||||
|
||||
_mode = mode;
|
||||
var g = Global.Settings.Redirector;
|
||||
BindTextBox(RemarkTextBox, _ => true, s => _mode.i18NRemark = s, _mode.i18NRemark);
|
||||
BindSyncGlobalCheckBox(HandleTCPCheckBox, b => _mode.FilterTCP = b, _mode.FilterTCP, g.FilterTCP);
|
||||
BindSyncGlobalCheckBox(HandleUDPCheckBox, b => _mode.FilterUDP = b, _mode.FilterUDP, g.FilterUDP);
|
||||
BindSyncGlobalCheckBox(HandleDNSCheckBox, b => _mode.FilterDNS = b, _mode.FilterDNS, g.FilterDNS);
|
||||
BindTextBox(DNSTextBox, s => IPEndPoint.TryParse(s, out _), s => _mode.DNSHost = s, _mode.DNSHost ?? Constants.DefaultPrimaryDNS);
|
||||
|
||||
BindSyncGlobalCheckBox(HandleProcDNSCheckBox, b => _mode.HandleOnlyDNS = b, _mode.HandleOnlyDNS, g.HandleOnlyDNS);
|
||||
BindSyncGlobalCheckBox(ProxyDNSCheckBox, b => _mode.DNSProxy = b, _mode.DNSProxy, g.DNSProxy);
|
||||
BindSyncGlobalCheckBox(HandleICMPCheckBox, b => _mode.FilterICMP = b, _mode.FilterICMP, g.FilterICMP);
|
||||
BindTextBox<int>(ICMPDelayTextBox, s => s >= 0, s => _mode.ICMPDelay = s, _mode.ICMPDelay ?? 10);
|
||||
BindCheckBox(HandleLoopbackCheckBox, b => _mode.FilterLoopback = b, _mode.FilterLoopback);
|
||||
BindCheckBox(HandleLANCheckBox, b => _mode.FilterIntranet = b, _mode.FilterIntranet);
|
||||
BindSyncGlobalCheckBox(HandleChildProcCheckBox, b => _mode.FilterParent = b, _mode.FilterParent, g.FilterParent);
|
||||
|
||||
BindTextBox(BypassRuleRichTextBox, s => true, s => _mode.Bypass = s.GetLines().ToList(), string.Join(Constants.EOF, _mode.Bypass));
|
||||
BindTextBox(HandleRuleRichTextBox, s => true, s => _mode.Handle = s.GetLines().ToList(), string.Join(Constants.EOF, _mode.Handle));
|
||||
}
|
||||
|
||||
#region Model
|
||||
|
||||
public IEnumerable<string> Rules => RuleRichTextBox.Lines;
|
||||
|
||||
private void RuleAdd(string value)
|
||||
private void InitBindings()
|
||||
{
|
||||
RuleRichTextBox.AppendText($"{value}\n");
|
||||
DNSTextBox.DataBindings.Add(new Binding("Enabled", HandleDNSCheckBox, "Checked", true));
|
||||
HandleProcDNSCheckBox.DataBindings.Add(new Binding("Enabled", HandleDNSCheckBox, "Checked", true));
|
||||
ProxyDNSCheckBox.DataBindings.Add(new Binding("Enabled", HandleDNSCheckBox, "Checked", true));
|
||||
ICMPDelayTextBox.DataBindings.Add(new Binding("Enabled", HandleICMPCheckBox, "Checked", true));
|
||||
}
|
||||
|
||||
private void RuleAddRange(IEnumerable<string> value)
|
||||
{
|
||||
foreach (string s in value)
|
||||
{
|
||||
RuleAdd(s);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ModeForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (_mode != null)
|
||||
if (!IsCreateMode)
|
||||
{
|
||||
Text = "Edit Process Mode";
|
||||
|
||||
RemarkTextBox.TextChanged -= RemarkTextBox_TextChanged;
|
||||
RemarkTextBox.Text = _mode.Remark;
|
||||
FilenameTextBox.Text = _mode.RelativePath;
|
||||
RuleAddRange(_mode.Content);
|
||||
RemarkTextBox.Text = _mode.i18NRemark;
|
||||
FilenameTextBox.Text = ModeService.Instance.GetRelativePath(_mode.FullName);
|
||||
}
|
||||
|
||||
if (!_mode.FullName.EndsWith(".json"))
|
||||
ControlButton.Enabled = false;
|
||||
|
||||
BypassRuleRichTextBox.Text = string.Join(Constants.EOF, _mode.Bypass);
|
||||
HandleRuleRichTextBox.Text = string.Join(Constants.EOF, _mode.Handle);
|
||||
i18N.TranslateForm(this);
|
||||
}
|
||||
|
||||
private void SelectButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var dialog = new CommonOpenFileDialog
|
||||
RichTextBox ruleRichTextBox;
|
||||
if (sender == HandleSelectButton)
|
||||
ruleRichTextBox = HandleRuleRichTextBox;
|
||||
else if (sender == BypassSelectButton)
|
||||
ruleRichTextBox = BypassRuleRichTextBox;
|
||||
else
|
||||
{
|
||||
IsFolderPicker = true,
|
||||
Multiselect = true,
|
||||
Title = i18N.Translate("Select a folder"),
|
||||
AddToMostRecentlyUsedList = false,
|
||||
EnsurePathExists = true,
|
||||
NavigateToShortcut = true
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog(Handle) == CommonFileDialogResult.Ok)
|
||||
{
|
||||
foreach (string p in dialog.FileNames)
|
||||
{
|
||||
string path = p;
|
||||
if (!path.EndsWith(@"\"))
|
||||
path += @"\";
|
||||
|
||||
RuleAdd($"^{path.ToRegexString()}");
|
||||
}
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
var dialog = new FolderBrowserDialog();
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
var path = dialog.SelectedPath;
|
||||
if (!path.EndsWith(@"\"))
|
||||
path += @"\";
|
||||
|
||||
AppendText(ruleRichTextBox, $"^{path.ToRegexString()}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void AppendText(Control ruleTextBox, string value)
|
||||
{
|
||||
if (ruleTextBox.Text.Any())
|
||||
ruleTextBox.Text = ruleTextBox.Text.Trim() + Constants.EOF + value;
|
||||
else
|
||||
ruleTextBox.Text = value;
|
||||
}
|
||||
|
||||
public void ControlButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!RuleRichTextBox.Lines.Any())
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Unable to add empty rule"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(RemarkTextBox.Text))
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a mode remark"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(FilenameTextBox.Text))
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a mode filename"));
|
||||
return;
|
||||
}
|
||||
SaveBinds();
|
||||
|
||||
if (_mode != null)
|
||||
{
|
||||
_mode.Remark = RemarkTextBox.Text;
|
||||
_mode.Content.Clear();
|
||||
_mode.Content.AddRange(RuleRichTextBox.Lines);
|
||||
|
||||
_mode.WriteFile();
|
||||
MessageBoxX.Show(i18N.Translate("Mode updated successfully"));
|
||||
}
|
||||
else
|
||||
if (IsCreateMode)
|
||||
{
|
||||
var relativePath = FilenameTextBox.Text;
|
||||
var fullName = ModeHelper.GetFullPath(relativePath);
|
||||
var fullName = ModeService.Instance.GetFullPath(relativePath);
|
||||
if (File.Exists(fullName))
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("File already exists.\n Please Change the filename"));
|
||||
return;
|
||||
}
|
||||
|
||||
var mode = new Mode(fullName)
|
||||
{
|
||||
Type = ModeType.Process,
|
||||
Remark = RemarkTextBox.Text
|
||||
};
|
||||
_mode.FullName = fullName;
|
||||
|
||||
mode.Content.AddRange(RuleRichTextBox.Lines);
|
||||
|
||||
mode.WriteFile();
|
||||
ModeService.Instance.Add(_mode);
|
||||
MessageBoxX.Show(i18N.Translate("Mode added successfully"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_mode.WriteFile();
|
||||
MessageBoxX.Show(i18N.Translate("Mode updated successfully"));
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void RemarkTextBox_TextChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
if (!IsHandleCreated)
|
||||
return;
|
||||
|
||||
BeginInvoke(new Action(() =>
|
||||
{
|
||||
FilenameTextBox.Text = FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text);
|
||||
@@ -158,24 +169,26 @@ namespace Netch.Forms.ModeForms
|
||||
|
||||
private void ScanButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var dialog = new CommonOpenFileDialog
|
||||
RichTextBox ruleRichTextBox;
|
||||
if (sender == HandleScanButton)
|
||||
ruleRichTextBox = HandleRuleRichTextBox;
|
||||
else if (sender == BypassScanButton)
|
||||
ruleRichTextBox = BypassRuleRichTextBox;
|
||||
else
|
||||
{
|
||||
IsFolderPicker = true,
|
||||
Multiselect = false,
|
||||
Title = i18N.Translate("Select a folder"),
|
||||
AddToMostRecentlyUsedList = false,
|
||||
EnsurePathExists = true,
|
||||
NavigateToShortcut = true
|
||||
};
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (dialog.ShowDialog(Handle) == CommonFileDialogResult.Ok)
|
||||
var dialog = new FolderBrowserDialog();
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
var path = dialog.FileName;
|
||||
var path = dialog.SelectedPath;
|
||||
var list = new List<string>();
|
||||
const uint maxCount = 50;
|
||||
try
|
||||
{
|
||||
ScanDirectory(path, list);
|
||||
ScanDirectory(path, list, maxCount);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -185,13 +198,13 @@ namespace Netch.Forms.ModeForms
|
||||
return;
|
||||
}
|
||||
|
||||
RuleAddRange(list);
|
||||
AppendText(ruleRichTextBox, string.Join(Constants.EOF, list));
|
||||
}
|
||||
}
|
||||
|
||||
private void ScanDirectory(string directory, List<string> list, uint maxCount = 30)
|
||||
{
|
||||
foreach (string dir in Directory.GetDirectories(directory))
|
||||
foreach (var dir in Directory.GetDirectories(directory))
|
||||
ScanDirectory(dir, list, maxCount);
|
||||
|
||||
list.AddRange(
|
||||
@@ -203,7 +216,7 @@ namespace Netch.Forms.ModeForms
|
||||
|
||||
private void ValidationButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!NFController.CheckRules(Rules, out var results))
|
||||
if (!NFController.CheckRules(_mode.Bypass, out var results))
|
||||
MessageBoxX.Show(NFController.GenerateInvalidRulesMessage(results), LogLevel.WARNING);
|
||||
else
|
||||
MessageBoxX.Show("Fine");
|
||||
|
||||
@@ -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">
|
||||
@@ -112,9 +52,9 @@
|
||||
<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>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.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>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
395
Netch/Forms/ModeForms/RouteForm.Designer.cs
generated
395
Netch/Forms/ModeForms/RouteForm.Designer.cs
generated
@@ -32,166 +32,349 @@ namespace Netch.Forms.ModeForms
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.ConfigurationGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.comboBox1 = new System.Windows.Forms.ComboBox();
|
||||
this.HandleTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.HandleLabel = new System.Windows.Forms.Label();
|
||||
this.HandleContentTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.HandleRuleRichTextBox = new System.Windows.Forms.RichTextBox();
|
||||
this.BypassTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.BypassLabel = new System.Windows.Forms.Label();
|
||||
this.BypassContentTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.BypassRuleRichTextBox = new System.Windows.Forms.RichTextBox();
|
||||
this.HandleDNSCheckBox = new Netch.Forms.SyncGlobalCheckBox();
|
||||
this.DNSLabel = new System.Windows.Forms.Label();
|
||||
this.DNSTextBox = new System.Windows.Forms.TextBox();
|
||||
this.UseCustomDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.RuleTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.OptionsGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.RemarkLabel = new System.Windows.Forms.Label();
|
||||
this.RemarkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.FilenameLabel = new System.Windows.Forms.Label();
|
||||
this.FilenameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.ActionLabel = new System.Windows.Forms.Label();
|
||||
this.RemarkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.RemarkLabel = new System.Windows.Forms.Label();
|
||||
this.containerControl1 = new System.Windows.Forms.ContainerControl();
|
||||
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
|
||||
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.DeleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ControlButton = new System.Windows.Forms.Button();
|
||||
this.NamePanel = new System.Windows.Forms.Panel();
|
||||
this.ConfigurationLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.ConfigurationGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.HandleTableLayoutPanel.SuspendLayout();
|
||||
this.HandleContentTableLayoutPanel.SuspendLayout();
|
||||
this.BypassTableLayoutPanel.SuspendLayout();
|
||||
this.BypassContentTableLayoutPanel.SuspendLayout();
|
||||
this.RuleTableLayoutPanel.SuspendLayout();
|
||||
this.OptionsGroupBox.SuspendLayout();
|
||||
this.NamePanel.SuspendLayout();
|
||||
this.ConfigurationLayoutPanel.SuspendLayout();
|
||||
this.ConfigurationGroupBox.SuspendLayout();
|
||||
this.containerControl1.SuspendLayout();
|
||||
this.contextMenuStrip.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ConfigurationGroupBox
|
||||
// HandleTableLayoutPanel
|
||||
//
|
||||
this.ConfigurationGroupBox.Controls.Add(this.comboBox1);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.FilenameLabel);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.FilenameTextBox);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.ActionLabel);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.RemarkTextBox);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.RemarkLabel);
|
||||
this.ConfigurationGroupBox.Controls.Add(this.containerControl1);
|
||||
this.ConfigurationGroupBox.Location = new System.Drawing.Point(8, 12);
|
||||
this.ConfigurationGroupBox.Name = "ConfigurationGroupBox";
|
||||
this.ConfigurationGroupBox.Size = new System.Drawing.Size(340, 355);
|
||||
this.ConfigurationGroupBox.TabIndex = 2;
|
||||
this.ConfigurationGroupBox.TabStop = false;
|
||||
this.ConfigurationGroupBox.Text = "Configuration";
|
||||
this.HandleTableLayoutPanel.ColumnCount = 1;
|
||||
this.HandleTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.HandleTableLayoutPanel.Controls.Add(this.HandleLabel, 0, 0);
|
||||
this.HandleTableLayoutPanel.Controls.Add(this.HandleContentTableLayoutPanel, 0, 1);
|
||||
this.HandleTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.HandleTableLayoutPanel.Location = new System.Drawing.Point(3, 3);
|
||||
this.HandleTableLayoutPanel.Name = "HandleTableLayoutPanel";
|
||||
this.HandleTableLayoutPanel.RowCount = 2;
|
||||
this.HandleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.HandleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.HandleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.HandleTableLayoutPanel.Size = new System.Drawing.Size(455, 424);
|
||||
this.HandleTableLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// comboBox1
|
||||
// HandleLabel
|
||||
//
|
||||
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
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, 25);
|
||||
this.comboBox1.TabIndex = 11;
|
||||
this.HandleLabel.AutoSize = true;
|
||||
this.HandleLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.HandleLabel.Name = "HandleLabel";
|
||||
this.HandleLabel.Size = new System.Drawing.Size(81, 17);
|
||||
this.HandleLabel.TabIndex = 0;
|
||||
this.HandleLabel.Text = "Handle rules";
|
||||
//
|
||||
// FilenameLabel
|
||||
// HandleContentTableLayoutPanel
|
||||
//
|
||||
this.FilenameLabel.AutoSize = true;
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(12, 79);
|
||||
this.FilenameLabel.Name = "FilenameLabel";
|
||||
this.FilenameLabel.Size = new System.Drawing.Size(59, 17);
|
||||
this.FilenameLabel.TabIndex = 6;
|
||||
this.FilenameLabel.Text = "Filename";
|
||||
this.HandleContentTableLayoutPanel.ColumnCount = 1;
|
||||
this.HandleContentTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.HandleContentTableLayoutPanel.Controls.Add(this.HandleRuleRichTextBox, 0, 0);
|
||||
this.HandleContentTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.HandleContentTableLayoutPanel.Location = new System.Drawing.Point(3, 20);
|
||||
this.HandleContentTableLayoutPanel.Name = "HandleContentTableLayoutPanel";
|
||||
this.HandleContentTableLayoutPanel.RowCount = 1;
|
||||
this.HandleContentTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.HandleContentTableLayoutPanel.Size = new System.Drawing.Size(449, 401);
|
||||
this.HandleContentTableLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// FilenameTextBox
|
||||
// HandleRuleRichTextBox
|
||||
//
|
||||
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, 23);
|
||||
this.FilenameTextBox.TabIndex = 5;
|
||||
this.HandleRuleRichTextBox.DetectUrls = false;
|
||||
this.HandleRuleRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.HandleRuleRichTextBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.HandleRuleRichTextBox.Name = "HandleRuleRichTextBox";
|
||||
this.HandleRuleRichTextBox.Size = new System.Drawing.Size(443, 395);
|
||||
this.HandleRuleRichTextBox.TabIndex = 0;
|
||||
this.HandleRuleRichTextBox.Text = "";
|
||||
this.HandleRuleRichTextBox.WordWrap = false;
|
||||
//
|
||||
// ActionLabel
|
||||
// BypassTableLayoutPanel
|
||||
//
|
||||
this.ActionLabel.AutoSize = true;
|
||||
this.ActionLabel.Location = new System.Drawing.Point(12, 52);
|
||||
this.ActionLabel.Name = "ActionLabel";
|
||||
this.ActionLabel.Size = new System.Drawing.Size(44, 17);
|
||||
this.ActionLabel.TabIndex = 0;
|
||||
this.ActionLabel.Text = "Action";
|
||||
this.BypassTableLayoutPanel.ColumnCount = 1;
|
||||
this.BypassTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.BypassTableLayoutPanel.Controls.Add(this.BypassLabel, 0, 0);
|
||||
this.BypassTableLayoutPanel.Controls.Add(this.BypassContentTableLayoutPanel, 0, 1);
|
||||
this.BypassTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.BypassTableLayoutPanel.Location = new System.Drawing.Point(464, 3);
|
||||
this.BypassTableLayoutPanel.Name = "BypassTableLayoutPanel";
|
||||
this.BypassTableLayoutPanel.RowCount = 2;
|
||||
this.BypassTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.BypassTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.BypassTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.BypassTableLayoutPanel.Size = new System.Drawing.Size(455, 424);
|
||||
this.BypassTableLayoutPanel.TabIndex = 2;
|
||||
//
|
||||
// RemarkTextBox
|
||||
// BypassLabel
|
||||
//
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(84, 22);
|
||||
this.RemarkTextBox.Name = "RemarkTextBox";
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(250, 23);
|
||||
this.RemarkTextBox.TabIndex = 1;
|
||||
this.RemarkTextBox.TextChanged += new System.EventHandler(this.RemarkTextBox_TextChanged);
|
||||
this.BypassLabel.AutoSize = true;
|
||||
this.BypassLabel.Location = new System.Drawing.Point(3, 0);
|
||||
this.BypassLabel.Name = "BypassLabel";
|
||||
this.BypassLabel.Size = new System.Drawing.Size(81, 17);
|
||||
this.BypassLabel.TabIndex = 0;
|
||||
this.BypassLabel.Text = "Bypass rules";
|
||||
//
|
||||
// BypassContentTableLayoutPanel
|
||||
//
|
||||
this.BypassContentTableLayoutPanel.ColumnCount = 1;
|
||||
this.BypassContentTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.BypassContentTableLayoutPanel.Controls.Add(this.BypassRuleRichTextBox, 0, 0);
|
||||
this.BypassContentTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.BypassContentTableLayoutPanel.Location = new System.Drawing.Point(3, 20);
|
||||
this.BypassContentTableLayoutPanel.Name = "BypassContentTableLayoutPanel";
|
||||
this.BypassContentTableLayoutPanel.RowCount = 1;
|
||||
this.BypassContentTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.BypassContentTableLayoutPanel.Size = new System.Drawing.Size(449, 401);
|
||||
this.BypassContentTableLayoutPanel.TabIndex = 1;
|
||||
//
|
||||
// BypassRuleRichTextBox
|
||||
//
|
||||
this.BypassRuleRichTextBox.DetectUrls = false;
|
||||
this.BypassRuleRichTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.BypassRuleRichTextBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.BypassRuleRichTextBox.Name = "BypassRuleRichTextBox";
|
||||
this.BypassRuleRichTextBox.Size = new System.Drawing.Size(443, 395);
|
||||
this.BypassRuleRichTextBox.TabIndex = 0;
|
||||
this.BypassRuleRichTextBox.Text = "";
|
||||
this.BypassRuleRichTextBox.WordWrap = false;
|
||||
//
|
||||
// HandleDNSCheckBox
|
||||
//
|
||||
this.HandleDNSCheckBox.AutoCheck = false;
|
||||
this.HandleDNSCheckBox.AutoSize = true;
|
||||
this.HandleDNSCheckBox.BackColor = System.Drawing.Color.Yellow;
|
||||
this.HandleDNSCheckBox.Font = new System.Drawing.Font("Microsoft YaHei UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic))), System.Drawing.GraphicsUnit.Point);
|
||||
this.HandleDNSCheckBox.GlobalValue = false;
|
||||
this.HandleDNSCheckBox.Location = new System.Drawing.Point(8, 24);
|
||||
this.HandleDNSCheckBox.Name = "HandleDNSCheckBox";
|
||||
this.HandleDNSCheckBox.Size = new System.Drawing.Size(203, 21);
|
||||
this.HandleDNSCheckBox.SyncGlobal = false;
|
||||
this.HandleDNSCheckBox.TabIndex = 2;
|
||||
this.HandleDNSCheckBox.Text = "Handle DNS (DNS hijacking)";
|
||||
this.HandleDNSCheckBox.ThreeState = true;
|
||||
this.HandleDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.HandleDNSCheckBox.Value = false;
|
||||
//
|
||||
// DNSLabel
|
||||
//
|
||||
this.DNSLabel.AutoSize = true;
|
||||
this.DNSLabel.Location = new System.Drawing.Point(176, 56);
|
||||
this.DNSLabel.Name = "DNSLabel";
|
||||
this.DNSLabel.Size = new System.Drawing.Size(34, 17);
|
||||
this.DNSLabel.TabIndex = 3;
|
||||
this.DNSLabel.Text = "DNS";
|
||||
//
|
||||
// DNSTextBox
|
||||
//
|
||||
this.DNSTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.UseCustomDNSCheckBox, "Checked", true));
|
||||
this.DNSTextBox.Location = new System.Drawing.Point(224, 56);
|
||||
this.DNSTextBox.Name = "DNSTextBox";
|
||||
this.DNSTextBox.Size = new System.Drawing.Size(184, 23);
|
||||
this.DNSTextBox.TabIndex = 4;
|
||||
this.DNSTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// UseCustomDNSCheckBox
|
||||
//
|
||||
this.UseCustomDNSCheckBox.AutoSize = true;
|
||||
this.UseCustomDNSCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.HandleDNSCheckBox, "Checked", true));
|
||||
this.UseCustomDNSCheckBox.Location = new System.Drawing.Point(8, 56);
|
||||
this.UseCustomDNSCheckBox.Name = "UseCustomDNSCheckBox";
|
||||
this.UseCustomDNSCheckBox.Size = new System.Drawing.Size(125, 21);
|
||||
this.UseCustomDNSCheckBox.TabIndex = 7;
|
||||
this.UseCustomDNSCheckBox.Text = "Use custom DNS";
|
||||
this.UseCustomDNSCheckBox.ThreeState = true;
|
||||
this.UseCustomDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RuleTableLayoutPanel
|
||||
//
|
||||
this.RuleTableLayoutPanel.ColumnCount = 2;
|
||||
this.RuleTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.RuleTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.RuleTableLayoutPanel.Controls.Add(this.HandleTableLayoutPanel, 0, 0);
|
||||
this.RuleTableLayoutPanel.Controls.Add(this.BypassTableLayoutPanel, 1, 0);
|
||||
this.RuleTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.RuleTableLayoutPanel.Location = new System.Drawing.Point(3, 206);
|
||||
this.RuleTableLayoutPanel.Name = "RuleTableLayoutPanel";
|
||||
this.RuleTableLayoutPanel.RowCount = 1;
|
||||
this.RuleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.RuleTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 430F));
|
||||
this.RuleTableLayoutPanel.Size = new System.Drawing.Size(922, 430);
|
||||
this.RuleTableLayoutPanel.TabIndex = 2;
|
||||
//
|
||||
// OptionsGroupBox
|
||||
//
|
||||
this.OptionsGroupBox.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.OptionsGroupBox.Controls.Add(this.HandleDNSCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.UseCustomDNSCheckBox);
|
||||
this.OptionsGroupBox.Controls.Add(this.DNSLabel);
|
||||
this.OptionsGroupBox.Controls.Add(this.DNSTextBox);
|
||||
this.OptionsGroupBox.Location = new System.Drawing.Point(15, 81);
|
||||
this.OptionsGroupBox.Name = "OptionsGroupBox";
|
||||
this.OptionsGroupBox.Size = new System.Drawing.Size(898, 119);
|
||||
this.OptionsGroupBox.TabIndex = 1;
|
||||
this.OptionsGroupBox.TabStop = false;
|
||||
this.OptionsGroupBox.Visible = false;
|
||||
//
|
||||
// RemarkLabel
|
||||
//
|
||||
this.RemarkLabel.AutoSize = true;
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(12, 25);
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(8, 8);
|
||||
this.RemarkLabel.Name = "RemarkLabel";
|
||||
this.RemarkLabel.Size = new System.Drawing.Size(53, 17);
|
||||
this.RemarkLabel.TabIndex = 0;
|
||||
this.RemarkLabel.Text = "Remark";
|
||||
//
|
||||
// containerControl1
|
||||
// RemarkTextBox
|
||||
//
|
||||
this.containerControl1.Controls.Add(this.richTextBox1);
|
||||
this.containerControl1.Location = new System.Drawing.Point(6, 103);
|
||||
this.containerControl1.Name = "containerControl1";
|
||||
this.containerControl1.Size = new System.Drawing.Size(328, 246);
|
||||
this.containerControl1.TabIndex = 10;
|
||||
this.containerControl1.Text = "containerControl1";
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(72, 8);
|
||||
this.RemarkTextBox.Name = "RemarkTextBox";
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(341, 23);
|
||||
this.RemarkTextBox.TabIndex = 1;
|
||||
//
|
||||
// richTextBox1
|
||||
// FilenameLabel
|
||||
//
|
||||
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.richTextBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.richTextBox1.Name = "richTextBox1";
|
||||
this.richTextBox1.Size = new System.Drawing.Size(328, 246);
|
||||
this.richTextBox1.TabIndex = 0;
|
||||
this.richTextBox1.Text = "";
|
||||
this.FilenameLabel.AutoSize = true;
|
||||
this.FilenameLabel.Location = new System.Drawing.Point(8, 40);
|
||||
this.FilenameLabel.Name = "FilenameLabel";
|
||||
this.FilenameLabel.Size = new System.Drawing.Size(59, 17);
|
||||
this.FilenameLabel.TabIndex = 2;
|
||||
this.FilenameLabel.Text = "Filename";
|
||||
//
|
||||
// contextMenuStrip
|
||||
// FilenameTextBox
|
||||
//
|
||||
this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.DeleteToolStripMenuItem});
|
||||
this.contextMenuStrip.Name = "contextMenuStrip";
|
||||
this.contextMenuStrip.Size = new System.Drawing.Size(114, 26);
|
||||
//
|
||||
// DeleteToolStripMenuItem
|
||||
//
|
||||
this.DeleteToolStripMenuItem.Name = "DeleteToolStripMenuItem";
|
||||
this.DeleteToolStripMenuItem.Size = new System.Drawing.Size(113, 22);
|
||||
this.DeleteToolStripMenuItem.Text = "Delete";
|
||||
this.FilenameTextBox.Location = new System.Drawing.Point(72, 40);
|
||||
this.FilenameTextBox.Name = "FilenameTextBox";
|
||||
this.FilenameTextBox.ReadOnly = true;
|
||||
this.FilenameTextBox.Size = new System.Drawing.Size(341, 23);
|
||||
this.FilenameTextBox.TabIndex = 3;
|
||||
//
|
||||
// ControlButton
|
||||
//
|
||||
this.ControlButton.Location = new System.Drawing.Point(273, 373);
|
||||
this.ControlButton.Location = new System.Drawing.Point(424, 40);
|
||||
this.ControlButton.Name = "ControlButton";
|
||||
this.ControlButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.ControlButton.TabIndex = 3;
|
||||
this.ControlButton.TabIndex = 4;
|
||||
this.ControlButton.Text = "Save";
|
||||
this.ControlButton.UseVisualStyleBackColor = true;
|
||||
this.ControlButton.Click += new System.EventHandler(this.ControlButton_Click);
|
||||
//
|
||||
// Route
|
||||
// NamePanel
|
||||
//
|
||||
this.NamePanel.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.NamePanel.Controls.Add(this.RemarkLabel);
|
||||
this.NamePanel.Controls.Add(this.RemarkTextBox);
|
||||
this.NamePanel.Controls.Add(this.FilenameLabel);
|
||||
this.NamePanel.Controls.Add(this.FilenameTextBox);
|
||||
this.NamePanel.Controls.Add(this.ControlButton);
|
||||
this.NamePanel.Location = new System.Drawing.Point(208, 3);
|
||||
this.NamePanel.Name = "NamePanel";
|
||||
this.NamePanel.Size = new System.Drawing.Size(512, 72);
|
||||
this.NamePanel.TabIndex = 0;
|
||||
//
|
||||
// ConfigurationLayoutPanel
|
||||
//
|
||||
this.ConfigurationLayoutPanel.ColumnCount = 1;
|
||||
this.ConfigurationLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.ConfigurationLayoutPanel.Controls.Add(this.NamePanel, 0, 0);
|
||||
this.ConfigurationLayoutPanel.Controls.Add(this.OptionsGroupBox, 0, 1);
|
||||
this.ConfigurationLayoutPanel.Controls.Add(this.RuleTableLayoutPanel, 0, 2);
|
||||
this.ConfigurationLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ConfigurationLayoutPanel.Location = new System.Drawing.Point(3, 19);
|
||||
this.ConfigurationLayoutPanel.Name = "ConfigurationLayoutPanel";
|
||||
this.ConfigurationLayoutPanel.RowCount = 3;
|
||||
this.ConfigurationLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.ConfigurationLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.ConfigurationLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.ConfigurationLayoutPanel.Size = new System.Drawing.Size(928, 639);
|
||||
this.ConfigurationLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// ConfigurationGroupBox
|
||||
//
|
||||
this.ConfigurationGroupBox.Controls.Add(this.ConfigurationLayoutPanel);
|
||||
this.ConfigurationGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ConfigurationGroupBox.Location = new System.Drawing.Point(0, 0);
|
||||
this.ConfigurationGroupBox.Name = "ConfigurationGroupBox";
|
||||
this.ConfigurationGroupBox.Size = new System.Drawing.Size(934, 661);
|
||||
this.ConfigurationGroupBox.TabIndex = 1;
|
||||
this.ConfigurationGroupBox.TabStop = false;
|
||||
this.ConfigurationGroupBox.Text = "Configuration";
|
||||
//
|
||||
// RouteForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(356, 419);
|
||||
this.ClientSize = new System.Drawing.Size(934, 661);
|
||||
this.Controls.Add(this.ConfigurationGroupBox);
|
||||
this.Controls.Add(this.ControlButton);
|
||||
this.MinimumSize = new System.Drawing.Size(950, 700);
|
||||
this.Name = "RouteForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Create Route Table Rule";
|
||||
this.Load += new System.EventHandler(this.Route_Load);
|
||||
this.HandleTableLayoutPanel.ResumeLayout(false);
|
||||
this.HandleTableLayoutPanel.PerformLayout();
|
||||
this.HandleContentTableLayoutPanel.ResumeLayout(false);
|
||||
this.BypassTableLayoutPanel.ResumeLayout(false);
|
||||
this.BypassTableLayoutPanel.PerformLayout();
|
||||
this.BypassContentTableLayoutPanel.ResumeLayout(false);
|
||||
this.RuleTableLayoutPanel.ResumeLayout(false);
|
||||
this.OptionsGroupBox.ResumeLayout(false);
|
||||
this.OptionsGroupBox.PerformLayout();
|
||||
this.NamePanel.ResumeLayout(false);
|
||||
this.NamePanel.PerformLayout();
|
||||
this.ConfigurationLayoutPanel.ResumeLayout(false);
|
||||
this.ConfigurationGroupBox.ResumeLayout(false);
|
||||
this.ConfigurationGroupBox.PerformLayout();
|
||||
this.containerControl1.ResumeLayout(false);
|
||||
this.contextMenuStrip.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
public System.Windows.Forms.GroupBox ConfigurationGroupBox;
|
||||
private System.Windows.Forms.ContainerControl containerControl1;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuStrip;
|
||||
public System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem DeleteToolStripMenuItem;
|
||||
private System.Windows.Forms.Label FilenameLabel;
|
||||
private System.Windows.Forms.TextBox FilenameTextBox;
|
||||
private System.Windows.Forms.Label RemarkLabel;
|
||||
private System.Windows.Forms.TextBox RemarkTextBox;
|
||||
private System.Windows.Forms.RichTextBox richTextBox1;
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ComboBox comboBox1;
|
||||
private System.Windows.Forms.Label ActionLabel;
|
||||
private System.Windows.Forms.TableLayoutPanel HandleTableLayoutPanel;
|
||||
private System.Windows.Forms.Label HandleLabel;
|
||||
private System.Windows.Forms.TableLayoutPanel HandleContentTableLayoutPanel;
|
||||
private System.Windows.Forms.RichTextBox HandleRuleRichTextBox;
|
||||
private System.Windows.Forms.TableLayoutPanel BypassTableLayoutPanel;
|
||||
private System.Windows.Forms.Label BypassLabel;
|
||||
private System.Windows.Forms.TableLayoutPanel BypassContentTableLayoutPanel;
|
||||
private System.Windows.Forms.RichTextBox BypassRuleRichTextBox;
|
||||
private SyncGlobalCheckBox HandleDNSCheckBox;
|
||||
private System.Windows.Forms.Label DNSLabel;
|
||||
private System.Windows.Forms.TextBox DNSTextBox;
|
||||
private System.Windows.Forms.TableLayoutPanel RuleTableLayoutPanel;
|
||||
private System.Windows.Forms.GroupBox OptionsGroupBox;
|
||||
private System.Windows.Forms.Label RemarkLabel;
|
||||
private System.Windows.Forms.TextBox RemarkTextBox;
|
||||
private System.Windows.Forms.Label FilenameLabel;
|
||||
private System.Windows.Forms.TextBox FilenameTextBox;
|
||||
private System.Windows.Forms.Panel NamePanel;
|
||||
private System.Windows.Forms.TableLayoutPanel ConfigurationLayoutPanel;
|
||||
private System.Windows.Forms.CheckBox UseCustomDNSCheckBox;
|
||||
private System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.GroupBox ConfigurationGroupBox;
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,61 @@
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Enums;
|
||||
using System.Linq;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Models.Modes.TunMode;
|
||||
using Netch.Properties;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.ModeForms
|
||||
{
|
||||
public partial class RouteForm : Form
|
||||
public partial class RouteForm : BindingForm
|
||||
{
|
||||
private readonly TagItem<ModeType>[] _items =
|
||||
{ new(ModeType.ProxyRuleIPs, "Proxy Rule IPs"), new(ModeType.BypassRuleIPs, "Bypass Rule IPs") };
|
||||
private readonly bool IsCreateMode;
|
||||
|
||||
private readonly Mode? _mode;
|
||||
private readonly TunMode _mode;
|
||||
|
||||
public RouteForm(Mode? mode = null)
|
||||
{
|
||||
if (mode != null && mode.Type is not (ModeType.ProxyRuleIPs or ModeType.BypassRuleIPs))
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
_mode = mode;
|
||||
switch (mode)
|
||||
{
|
||||
case null:
|
||||
IsCreateMode = true;
|
||||
_mode = new TunMode();
|
||||
break;
|
||||
case TunMode tunMode:
|
||||
IsCreateMode = false;
|
||||
_mode = tunMode;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
InitializeComponent();
|
||||
Icon = Resources.icon;
|
||||
comboBox1.DataSource = _items;
|
||||
comboBox1.ValueMember = nameof(TagItem<int>.Value);
|
||||
comboBox1.DisplayMember = nameof(TagItem<int>.Text);
|
||||
|
||||
|
||||
BindTextBox(RemarkTextBox, _ => true, s => _mode.i18NRemark = s, _mode.i18NRemark);
|
||||
// TODO Options Not implemented
|
||||
|
||||
BindTextBox(BypassRuleRichTextBox, s => true, s => _mode.Bypass = s.GetLines().ToList(), string.Join(Constants.EOF, _mode.Bypass));
|
||||
BindTextBox(HandleRuleRichTextBox, s => true, s => _mode.Handle = s.GetLines().ToList(), string.Join(Constants.EOF, _mode.Handle));
|
||||
}
|
||||
|
||||
private void Route_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (_mode != null)
|
||||
if (!IsCreateMode)
|
||||
{
|
||||
Text = "Edit Route Table Rule";
|
||||
|
||||
RemarkTextBox.TextChanged -= RemarkTextBox_TextChanged;
|
||||
RemarkTextBox.Text = _mode.Remark;
|
||||
comboBox1.SelectedValue = _mode.Type; // ComboBox SelectedValue worked after ctor
|
||||
FilenameTextBox.Text = _mode.RelativePath;
|
||||
richTextBox1.Lines = _mode.Content.ToArray();
|
||||
RemarkTextBox.Text = _mode.i18NRemark;
|
||||
FilenameTextBox.Text = ModeService.Instance.GetRelativePath(_mode.FullName);
|
||||
}
|
||||
|
||||
if (!_mode.FullName.EndsWith(".json"))
|
||||
ControlButton.Enabled = false;
|
||||
|
||||
i18N.TranslateForm(this);
|
||||
}
|
||||
|
||||
@@ -53,50 +67,33 @@ namespace Netch.Forms.ModeForms
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(FilenameTextBox.Text))
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a mode filename"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_mode != null)
|
||||
{
|
||||
_mode.Remark = RemarkTextBox.Text;
|
||||
_mode.Content.Clear();
|
||||
_mode.Content.AddRange(richTextBox1.Lines);
|
||||
_mode.Type = (ModeType)comboBox1.SelectedValue;
|
||||
|
||||
_mode.WriteFile();
|
||||
MessageBoxX.Show(i18N.Translate("Mode updated successfully"));
|
||||
}
|
||||
else
|
||||
if (IsCreateMode)
|
||||
{
|
||||
var relativePath = FilenameTextBox.Text;
|
||||
var fullName = ModeHelper.GetFullPath(relativePath);
|
||||
var fullName = ModeService.Instance.GetFullPath(relativePath);
|
||||
if (File.Exists(fullName))
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("File already exists.\n Please Change the filename"));
|
||||
return;
|
||||
}
|
||||
|
||||
var mode = new Mode(fullName)
|
||||
{
|
||||
Type = (ModeType)comboBox1.SelectedValue,
|
||||
Remark = RemarkTextBox.Text
|
||||
};
|
||||
_mode.FullName = fullName;
|
||||
|
||||
mode.Content.AddRange(richTextBox1.Lines);
|
||||
|
||||
mode.WriteFile();
|
||||
ModeService.Instance.Add(_mode);
|
||||
MessageBoxX.Show(i18N.Translate("Mode added successfully"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_mode.WriteFile();
|
||||
MessageBoxX.Show(i18N.Translate("Mode updated successfully"));
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void RemarkTextBox_TextChanged(object? sender, EventArgs? e)
|
||||
{
|
||||
BeginInvoke(new Action(() => { FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text); }));
|
||||
FilenameTextBox.Text = ModeEditorUtils.GetCustomModeRelativePath(RemarkTextBox.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
241
Netch/Forms/SettingForm.Designer.cs
generated
241
Netch/Forms/SettingForm.Designer.cs
generated
@@ -36,10 +36,7 @@ namespace Netch.Forms
|
||||
this.PortGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.Socks5PortLabel = new System.Windows.Forms.Label();
|
||||
this.Socks5PortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.HTTPPortLabel = new System.Windows.Forms.Label();
|
||||
this.HTTPPortTextBox = 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();
|
||||
this.ICMPingRadioBtn = new System.Windows.Forms.RadioButton();
|
||||
this.TCPingRadioBtn = new System.Windows.Forms.RadioButton();
|
||||
@@ -54,14 +51,16 @@ namespace Netch.Forms
|
||||
this.LanguageLabel = new System.Windows.Forms.Label();
|
||||
this.LanguageComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.NFTabPage = new System.Windows.Forms.TabPage();
|
||||
this.ProcessFilterProtocolLabel = new System.Windows.Forms.Label();
|
||||
this.ProcessFilterProtocolComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.DNSHijackCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.DNSHijackHostTextBox = new System.Windows.Forms.TextBox();
|
||||
this.FilterTCPCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.FilterUDPCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.FilterICMPCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.DNSHijackLabel = new System.Windows.Forms.Label();
|
||||
this.ICMPDelayLabel = new System.Windows.Forms.Label();
|
||||
this.ICMPDelayTextBox = new System.Windows.Forms.TextBox();
|
||||
this.RedirectorSSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.FilterDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.DNSHijackHostTextBox = new System.Windows.Forms.TextBox();
|
||||
this.DNSProxyCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.HandleProcDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ChildProcessHandleCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.WinTUNTabPage = new System.Windows.Forms.TabPage();
|
||||
this.WinTUNGroupBox = new System.Windows.Forms.GroupBox();
|
||||
@@ -101,6 +100,7 @@ namespace Netch.Forms
|
||||
this.MinimizeWhenStartedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.RunAtStartupCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.CheckUpdateWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.NoSupportDialogCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.CheckBetaUpdateCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.UpdateServersWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.AioDNSTabPage = new System.Windows.Forms.TabPage();
|
||||
@@ -144,7 +144,6 @@ namespace Netch.Forms
|
||||
//
|
||||
this.GeneralTabPage.BackColor = System.Drawing.SystemColors.ButtonFace;
|
||||
this.GeneralTabPage.Controls.Add(this.PortGroupBox);
|
||||
this.GeneralTabPage.Controls.Add(this.ResolveServerHostnameCheckBox);
|
||||
this.GeneralTabPage.Controls.Add(this.ServerPingTypeLabel);
|
||||
this.GeneralTabPage.Controls.Add(this.ICMPingRadioBtn);
|
||||
this.GeneralTabPage.Controls.Add(this.TCPingRadioBtn);
|
||||
@@ -169,8 +168,6 @@ namespace Netch.Forms
|
||||
//
|
||||
this.PortGroupBox.Controls.Add(this.Socks5PortLabel);
|
||||
this.PortGroupBox.Controls.Add(this.Socks5PortTextBox);
|
||||
this.PortGroupBox.Controls.Add(this.HTTPPortLabel);
|
||||
this.PortGroupBox.Controls.Add(this.HTTPPortTextBox);
|
||||
this.PortGroupBox.Controls.Add(this.AllowDevicesCheckBox);
|
||||
this.PortGroupBox.Location = new System.Drawing.Point(8, 6);
|
||||
this.PortGroupBox.Name = "PortGroupBox";
|
||||
@@ -196,23 +193,6 @@ namespace Netch.Forms
|
||||
this.Socks5PortTextBox.TabIndex = 1;
|
||||
this.Socks5PortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// HTTPPortLabel
|
||||
//
|
||||
this.HTTPPortLabel.AutoSize = true;
|
||||
this.HTTPPortLabel.Location = new System.Drawing.Point(9, 54);
|
||||
this.HTTPPortLabel.Name = "HTTPPortLabel";
|
||||
this.HTTPPortLabel.Size = new System.Drawing.Size(38, 17);
|
||||
this.HTTPPortLabel.TabIndex = 2;
|
||||
this.HTTPPortLabel.Text = "HTTP";
|
||||
//
|
||||
// HTTPPortTextBox
|
||||
//
|
||||
this.HTTPPortTextBox.Location = new System.Drawing.Point(120, 51);
|
||||
this.HTTPPortTextBox.Name = "HTTPPortTextBox";
|
||||
this.HTTPPortTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.HTTPPortTextBox.TabIndex = 3;
|
||||
this.HTTPPortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// AllowDevicesCheckBox
|
||||
//
|
||||
this.AllowDevicesCheckBox.AutoSize = true;
|
||||
@@ -224,20 +204,10 @@ namespace Netch.Forms
|
||||
this.AllowDevicesCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.AllowDevicesCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ResolveServerHostnameCheckBox
|
||||
//
|
||||
this.ResolveServerHostnameCheckBox.AutoSize = true;
|
||||
this.ResolveServerHostnameCheckBox.Location = new System.Drawing.Point(267, 15);
|
||||
this.ResolveServerHostnameCheckBox.Name = "ResolveServerHostnameCheckBox";
|
||||
this.ResolveServerHostnameCheckBox.Size = new System.Drawing.Size(176, 21);
|
||||
this.ResolveServerHostnameCheckBox.TabIndex = 1;
|
||||
this.ResolveServerHostnameCheckBox.Text = "Resolve Server Hostname";
|
||||
this.ResolveServerHostnameCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ServerPingTypeLabel
|
||||
//
|
||||
this.ServerPingTypeLabel.AutoSize = true;
|
||||
this.ServerPingTypeLabel.Location = new System.Drawing.Point(267, 44);
|
||||
this.ServerPingTypeLabel.Location = new System.Drawing.Point(267, 15);
|
||||
this.ServerPingTypeLabel.Name = "ServerPingTypeLabel";
|
||||
this.ServerPingTypeLabel.Size = new System.Drawing.Size(86, 17);
|
||||
this.ServerPingTypeLabel.TabIndex = 2;
|
||||
@@ -246,7 +216,7 @@ namespace Netch.Forms
|
||||
// ICMPingRadioBtn
|
||||
//
|
||||
this.ICMPingRadioBtn.AutoSize = true;
|
||||
this.ICMPingRadioBtn.Location = new System.Drawing.Point(268, 63);
|
||||
this.ICMPingRadioBtn.Location = new System.Drawing.Point(268, 34);
|
||||
this.ICMPingRadioBtn.Name = "ICMPingRadioBtn";
|
||||
this.ICMPingRadioBtn.Size = new System.Drawing.Size(75, 21);
|
||||
this.ICMPingRadioBtn.TabIndex = 3;
|
||||
@@ -257,7 +227,7 @@ namespace Netch.Forms
|
||||
// TCPingRadioBtn
|
||||
//
|
||||
this.TCPingRadioBtn.AutoSize = true;
|
||||
this.TCPingRadioBtn.Location = new System.Drawing.Point(366, 64);
|
||||
this.TCPingRadioBtn.Location = new System.Drawing.Point(366, 35);
|
||||
this.TCPingRadioBtn.Name = "TCPingRadioBtn";
|
||||
this.TCPingRadioBtn.Size = new System.Drawing.Size(66, 21);
|
||||
this.TCPingRadioBtn.TabIndex = 4;
|
||||
@@ -354,14 +324,16 @@ namespace Netch.Forms
|
||||
// NFTabPage
|
||||
//
|
||||
this.NFTabPage.BackColor = System.Drawing.SystemColors.ButtonFace;
|
||||
this.NFTabPage.Controls.Add(this.ProcessFilterProtocolLabel);
|
||||
this.NFTabPage.Controls.Add(this.ProcessFilterProtocolComboBox);
|
||||
this.NFTabPage.Controls.Add(this.DNSHijackCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.DNSHijackHostTextBox);
|
||||
this.NFTabPage.Controls.Add(this.FilterTCPCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.FilterUDPCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.FilterICMPCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.DNSHijackLabel);
|
||||
this.NFTabPage.Controls.Add(this.ICMPDelayLabel);
|
||||
this.NFTabPage.Controls.Add(this.ICMPDelayTextBox);
|
||||
this.NFTabPage.Controls.Add(this.RedirectorSSCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.FilterDNSCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.DNSHijackHostTextBox);
|
||||
this.NFTabPage.Controls.Add(this.HandleProcDNSCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.DNSProxyCheckBox);
|
||||
this.NFTabPage.Controls.Add(this.ChildProcessHandleCheckBox);
|
||||
this.NFTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
this.NFTabPage.Name = "NFTabPage";
|
||||
@@ -370,90 +342,112 @@ namespace Netch.Forms
|
||||
this.NFTabPage.TabIndex = 1;
|
||||
this.NFTabPage.Text = "Process Mode";
|
||||
//
|
||||
// ProcessFilterProtocolLabel
|
||||
// FilterTCPCheckBox
|
||||
//
|
||||
this.ProcessFilterProtocolLabel.AutoSize = true;
|
||||
this.ProcessFilterProtocolLabel.Location = new System.Drawing.Point(30, 20);
|
||||
this.ProcessFilterProtocolLabel.Name = "ProcessFilterProtocolLabel";
|
||||
this.ProcessFilterProtocolLabel.Size = new System.Drawing.Size(89, 17);
|
||||
this.ProcessFilterProtocolLabel.TabIndex = 0;
|
||||
this.ProcessFilterProtocolLabel.Text = "Filter Protocol";
|
||||
this.FilterTCPCheckBox.AutoSize = true;
|
||||
this.FilterTCPCheckBox.Location = new System.Drawing.Point(16, 16);
|
||||
this.FilterTCPCheckBox.Name = "FilterTCPCheckBox";
|
||||
this.FilterTCPCheckBox.Size = new System.Drawing.Size(81, 21);
|
||||
this.FilterTCPCheckBox.TabIndex = 1;
|
||||
this.FilterTCPCheckBox.Text = "Handle TCP";
|
||||
this.FilterTCPCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ProcessFilterProtocolComboBox
|
||||
// FilterUDPCheckBox
|
||||
//
|
||||
this.ProcessFilterProtocolComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.ProcessFilterProtocolComboBox.FormattingEnabled = true;
|
||||
this.ProcessFilterProtocolComboBox.Location = new System.Drawing.Point(237, 17);
|
||||
this.ProcessFilterProtocolComboBox.Name = "ProcessFilterProtocolComboBox";
|
||||
this.ProcessFilterProtocolComboBox.Size = new System.Drawing.Size(98, 25);
|
||||
this.ProcessFilterProtocolComboBox.TabIndex = 1;
|
||||
//
|
||||
// DNSHijackCheckBox
|
||||
//
|
||||
this.DNSHijackCheckBox.AutoSize = true;
|
||||
this.DNSHijackCheckBox.Location = new System.Drawing.Point(15, 50);
|
||||
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;
|
||||
//
|
||||
// DNSHijackHostTextBox
|
||||
//
|
||||
this.DNSHijackHostTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.DNSHijackCheckBox, "Checked", true));
|
||||
this.DNSHijackHostTextBox.Location = new System.Drawing.Point(237, 48);
|
||||
this.DNSHijackHostTextBox.Name = "DNSHijackHostTextBox";
|
||||
this.DNSHijackHostTextBox.Size = new System.Drawing.Size(191, 23);
|
||||
this.DNSHijackHostTextBox.TabIndex = 3;
|
||||
this.DNSHijackHostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.FilterUDPCheckBox.AutoSize = true;
|
||||
this.FilterUDPCheckBox.Location = new System.Drawing.Point(216, 16);
|
||||
this.FilterUDPCheckBox.Name = "FilterUDPCheckBox";
|
||||
this.FilterUDPCheckBox.Size = new System.Drawing.Size(84, 21);
|
||||
this.FilterUDPCheckBox.TabIndex = 2;
|
||||
this.FilterUDPCheckBox.Text = "Handle UDP";
|
||||
this.FilterUDPCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// FilterICMPCheckBox
|
||||
//
|
||||
this.FilterICMPCheckBox.AutoSize = true;
|
||||
this.FilterICMPCheckBox.Location = new System.Drawing.Point(13, 80);
|
||||
this.FilterICMPCheckBox.Location = new System.Drawing.Point(16, 48);
|
||||
this.FilterICMPCheckBox.Name = "FilterICMPCheckBox";
|
||||
this.FilterICMPCheckBox.Size = new System.Drawing.Size(90, 21);
|
||||
this.FilterICMPCheckBox.TabIndex = 4;
|
||||
this.FilterICMPCheckBox.Text = "Filter ICMP";
|
||||
this.FilterICMPCheckBox.TabIndex = 3;
|
||||
this.FilterICMPCheckBox.Text = "Handle ICMP";
|
||||
this.FilterICMPCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DNSHijackLabel
|
||||
//
|
||||
this.DNSHijackLabel.AutoSize = true;
|
||||
this.DNSHijackLabel.Location = new System.Drawing.Point(48, 144);
|
||||
this.DNSHijackLabel.Name = "DNSHijackLabel";
|
||||
this.DNSHijackLabel.Size = new System.Drawing.Size(34, 17);
|
||||
this.DNSHijackLabel.TabIndex = 3;
|
||||
this.DNSHijackLabel.Text = "DNS";
|
||||
//
|
||||
// ICMPDelayLabel
|
||||
//
|
||||
this.ICMPDelayLabel.AutoSize = true;
|
||||
this.ICMPDelayLabel.Location = new System.Drawing.Point(30, 110);
|
||||
this.ICMPDelayLabel.Location = new System.Drawing.Point(48, 80);
|
||||
this.ICMPDelayLabel.Name = "ICMPDelayLabel";
|
||||
this.ICMPDelayLabel.Size = new System.Drawing.Size(100, 17);
|
||||
this.ICMPDelayLabel.TabIndex = 5;
|
||||
this.ICMPDelayLabel.Text = "ICMP Delay(ms)";
|
||||
this.ICMPDelayLabel.TabIndex = 3;
|
||||
this.ICMPDelayLabel.Text = "ICMP delay(ms)";
|
||||
//
|
||||
// ICMPDelayTextBox
|
||||
//
|
||||
this.ICMPDelayTextBox.Location = new System.Drawing.Point(237, 107);
|
||||
this.ICMPDelayTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.FilterICMPCheckBox, "Checked", true));
|
||||
this.ICMPDelayTextBox.Location = new System.Drawing.Point(216, 80);
|
||||
this.ICMPDelayTextBox.Name = "ICMPDelayTextBox";
|
||||
this.ICMPDelayTextBox.ReadOnly = true;
|
||||
this.ICMPDelayTextBox.Size = new System.Drawing.Size(98, 23);
|
||||
this.ICMPDelayTextBox.TabIndex = 6;
|
||||
this.ICMPDelayTextBox.TabIndex = 4;
|
||||
this.ICMPDelayTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// RedirectorSSCheckBox
|
||||
// FilterDNSCheckBox
|
||||
//
|
||||
this.RedirectorSSCheckBox.AutoSize = true;
|
||||
this.RedirectorSSCheckBox.Location = new System.Drawing.Point(15, 140);
|
||||
this.RedirectorSSCheckBox.Name = "RedirectorSSCheckBox";
|
||||
this.RedirectorSSCheckBox.Size = new System.Drawing.Size(265, 21);
|
||||
this.RedirectorSSCheckBox.TabIndex = 7;
|
||||
this.RedirectorSSCheckBox.Text = "Redirector built-in Shadowsocks support";
|
||||
this.RedirectorSSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.FilterDNSCheckBox.AutoSize = true;
|
||||
this.FilterDNSCheckBox.Location = new System.Drawing.Point(16, 112);
|
||||
this.FilterDNSCheckBox.Name = "FilterDNSCheckBox";
|
||||
this.FilterDNSCheckBox.Size = new System.Drawing.Size(85, 21);
|
||||
this.FilterDNSCheckBox.TabIndex = 5;
|
||||
this.FilterDNSCheckBox.Text = "Handle DNS (DNS hijacking)";
|
||||
this.FilterDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DNSHijackHostTextBox
|
||||
//
|
||||
this.DNSHijackHostTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.FilterDNSCheckBox, "Checked", true));
|
||||
this.DNSHijackHostTextBox.Location = new System.Drawing.Point(216, 144);
|
||||
this.DNSHijackHostTextBox.Name = "DNSHijackHostTextBox";
|
||||
this.DNSHijackHostTextBox.Size = new System.Drawing.Size(191, 23);
|
||||
this.DNSHijackHostTextBox.TabIndex = 6;
|
||||
this.DNSHijackHostTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// DNSProxyCheckBox
|
||||
//
|
||||
this.DNSProxyCheckBox.AutoSize = true;
|
||||
this.DNSProxyCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.FilterDNSCheckBox, "Checked", true));
|
||||
this.DNSProxyCheckBox.Location = new System.Drawing.Point(16, 208);
|
||||
this.DNSProxyCheckBox.Name = "DNSProxyCheckBox";
|
||||
this.DNSProxyCheckBox.Size = new System.Drawing.Size(184, 21);
|
||||
this.DNSProxyCheckBox.TabIndex = 8;
|
||||
this.DNSProxyCheckBox.Text = "Handle DNS through proxy";
|
||||
this.DNSProxyCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// HandleProcDNSCheckBox
|
||||
//
|
||||
this.HandleProcDNSCheckBox.AutoSize = true;
|
||||
this.HandleProcDNSCheckBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.FilterDNSCheckBox, "Checked", true));
|
||||
this.HandleProcDNSCheckBox.Location = new System.Drawing.Point(16, 176);
|
||||
this.HandleProcDNSCheckBox.Name = "HandleProcDNSCheckBox";
|
||||
this.HandleProcDNSCheckBox.Size = new System.Drawing.Size(203, 21);
|
||||
this.HandleProcDNSCheckBox.TabIndex = 7;
|
||||
this.HandleProcDNSCheckBox.Text = "Handle handled process's DNS";
|
||||
this.HandleProcDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ChildProcessHandleCheckBox
|
||||
//
|
||||
this.ChildProcessHandleCheckBox.AutoSize = true;
|
||||
this.ChildProcessHandleCheckBox.Enabled = false;
|
||||
this.ChildProcessHandleCheckBox.Location = new System.Drawing.Point(15, 170);
|
||||
this.ChildProcessHandleCheckBox.Location = new System.Drawing.Point(16, 240);
|
||||
this.ChildProcessHandleCheckBox.Name = "ChildProcessHandleCheckBox";
|
||||
this.ChildProcessHandleCheckBox.Size = new System.Drawing.Size(150, 21);
|
||||
this.ChildProcessHandleCheckBox.TabIndex = 8;
|
||||
this.ChildProcessHandleCheckBox.Text = "Child Process Handle";
|
||||
this.ChildProcessHandleCheckBox.TabIndex = 9;
|
||||
this.ChildProcessHandleCheckBox.Text = "Handle child process";
|
||||
this.ChildProcessHandleCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// WinTUNTabPage
|
||||
@@ -562,7 +556,7 @@ namespace Netch.Forms
|
||||
this.UseCustomDNSCheckBox.Name = "UseCustomDNSCheckBox";
|
||||
this.UseCustomDNSCheckBox.Size = new System.Drawing.Size(127, 21);
|
||||
this.UseCustomDNSCheckBox.TabIndex = 8;
|
||||
this.UseCustomDNSCheckBox.Text = "Use Custom DNS";
|
||||
this.UseCustomDNSCheckBox.Text = "Use custom DNS";
|
||||
this.UseCustomDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
this.UseCustomDNSCheckBox.Click += new System.EventHandler(this.TUNTAPUseCustomDNSCheckBox_CheckedChanged);
|
||||
//
|
||||
@@ -773,6 +767,7 @@ namespace Netch.Forms
|
||||
this.OtherTabPage.Controls.Add(this.MinimizeWhenStartedCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.RunAtStartupCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.CheckUpdateWhenOpenedCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.NoSupportDialogCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.CheckBetaUpdateCheckBox);
|
||||
this.OtherTabPage.Controls.Add(this.UpdateServersWhenOpenedCheckBox);
|
||||
this.OtherTabPage.Location = new System.Drawing.Point(4, 29);
|
||||
@@ -785,7 +780,7 @@ namespace Netch.Forms
|
||||
// ExitWhenClosedCheckBox
|
||||
//
|
||||
this.ExitWhenClosedCheckBox.AutoSize = true;
|
||||
this.ExitWhenClosedCheckBox.Location = new System.Drawing.Point(6, 6);
|
||||
this.ExitWhenClosedCheckBox.Location = new System.Drawing.Point(16, 16);
|
||||
this.ExitWhenClosedCheckBox.Name = "ExitWhenClosedCheckBox";
|
||||
this.ExitWhenClosedCheckBox.Size = new System.Drawing.Size(123, 21);
|
||||
this.ExitWhenClosedCheckBox.TabIndex = 0;
|
||||
@@ -796,7 +791,7 @@ namespace Netch.Forms
|
||||
// StopWhenExitedCheckBox
|
||||
//
|
||||
this.StopWhenExitedCheckBox.AutoSize = true;
|
||||
this.StopWhenExitedCheckBox.Location = new System.Drawing.Point(200, 6);
|
||||
this.StopWhenExitedCheckBox.Location = new System.Drawing.Point(224, 18);
|
||||
this.StopWhenExitedCheckBox.Name = "StopWhenExitedCheckBox";
|
||||
this.StopWhenExitedCheckBox.Size = new System.Drawing.Size(127, 21);
|
||||
this.StopWhenExitedCheckBox.TabIndex = 1;
|
||||
@@ -807,7 +802,7 @@ namespace Netch.Forms
|
||||
// StartWhenOpenedCheckBox
|
||||
//
|
||||
this.StartWhenOpenedCheckBox.AutoSize = true;
|
||||
this.StartWhenOpenedCheckBox.Location = new System.Drawing.Point(6, 28);
|
||||
this.StartWhenOpenedCheckBox.Location = new System.Drawing.Point(16, 48);
|
||||
this.StartWhenOpenedCheckBox.Name = "StartWhenOpenedCheckBox";
|
||||
this.StartWhenOpenedCheckBox.Size = new System.Drawing.Size(137, 21);
|
||||
this.StartWhenOpenedCheckBox.TabIndex = 2;
|
||||
@@ -818,7 +813,7 @@ namespace Netch.Forms
|
||||
// MinimizeWhenStartedCheckBox
|
||||
//
|
||||
this.MinimizeWhenStartedCheckBox.AutoSize = true;
|
||||
this.MinimizeWhenStartedCheckBox.Location = new System.Drawing.Point(200, 28);
|
||||
this.MinimizeWhenStartedCheckBox.Location = new System.Drawing.Point(224, 48);
|
||||
this.MinimizeWhenStartedCheckBox.Name = "MinimizeWhenStartedCheckBox";
|
||||
this.MinimizeWhenStartedCheckBox.Size = new System.Drawing.Size(158, 21);
|
||||
this.MinimizeWhenStartedCheckBox.TabIndex = 3;
|
||||
@@ -828,7 +823,7 @@ namespace Netch.Forms
|
||||
// RunAtStartupCheckBox
|
||||
//
|
||||
this.RunAtStartupCheckBox.AutoSize = true;
|
||||
this.RunAtStartupCheckBox.Location = new System.Drawing.Point(6, 50);
|
||||
this.RunAtStartupCheckBox.Location = new System.Drawing.Point(16, 80);
|
||||
this.RunAtStartupCheckBox.Name = "RunAtStartupCheckBox";
|
||||
this.RunAtStartupCheckBox.Size = new System.Drawing.Size(109, 21);
|
||||
this.RunAtStartupCheckBox.TabIndex = 4;
|
||||
@@ -838,7 +833,7 @@ namespace Netch.Forms
|
||||
// CheckUpdateWhenOpenedCheckBox
|
||||
//
|
||||
this.CheckUpdateWhenOpenedCheckBox.AutoSize = true;
|
||||
this.CheckUpdateWhenOpenedCheckBox.Location = new System.Drawing.Point(200, 50);
|
||||
this.CheckUpdateWhenOpenedCheckBox.Location = new System.Drawing.Point(224, 80);
|
||||
this.CheckUpdateWhenOpenedCheckBox.Name = "CheckUpdateWhenOpenedCheckBox";
|
||||
this.CheckUpdateWhenOpenedCheckBox.Size = new System.Drawing.Size(190, 21);
|
||||
this.CheckUpdateWhenOpenedCheckBox.TabIndex = 5;
|
||||
@@ -846,13 +841,23 @@ namespace Netch.Forms
|
||||
this.CheckUpdateWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.CheckUpdateWhenOpenedCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// NoSupportDialogCheckBox
|
||||
//
|
||||
this.NoSupportDialogCheckBox.AutoSize = true;
|
||||
this.NoSupportDialogCheckBox.Location = new System.Drawing.Point(16, 112);
|
||||
this.NoSupportDialogCheckBox.Name = "NoSupportDialogCheckBox";
|
||||
this.NoSupportDialogCheckBox.Size = new System.Drawing.Size(174, 21);
|
||||
this.NoSupportDialogCheckBox.TabIndex = 6;
|
||||
this.NoSupportDialogCheckBox.Text = "Disable Support Warning";
|
||||
this.NoSupportDialogCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// CheckBetaUpdateCheckBox
|
||||
//
|
||||
this.CheckBetaUpdateCheckBox.AutoSize = true;
|
||||
this.CheckBetaUpdateCheckBox.Location = new System.Drawing.Point(200, 72);
|
||||
this.CheckBetaUpdateCheckBox.Location = new System.Drawing.Point(224, 112);
|
||||
this.CheckBetaUpdateCheckBox.Name = "CheckBetaUpdateCheckBox";
|
||||
this.CheckBetaUpdateCheckBox.Size = new System.Drawing.Size(137, 21);
|
||||
this.CheckBetaUpdateCheckBox.TabIndex = 6;
|
||||
this.CheckBetaUpdateCheckBox.TabIndex = 7;
|
||||
this.CheckBetaUpdateCheckBox.Text = "Check Beta update";
|
||||
this.CheckBetaUpdateCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.CheckBetaUpdateCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -860,10 +865,10 @@ namespace Netch.Forms
|
||||
// UpdateServersWhenOpenedCheckBox
|
||||
//
|
||||
this.UpdateServersWhenOpenedCheckBox.AutoSize = true;
|
||||
this.UpdateServersWhenOpenedCheckBox.Location = new System.Drawing.Point(200, 94);
|
||||
this.UpdateServersWhenOpenedCheckBox.Location = new System.Drawing.Point(224, 144);
|
||||
this.UpdateServersWhenOpenedCheckBox.Name = "UpdateServersWhenOpenedCheckBox";
|
||||
this.UpdateServersWhenOpenedCheckBox.Size = new System.Drawing.Size(200, 21);
|
||||
this.UpdateServersWhenOpenedCheckBox.TabIndex = 7;
|
||||
this.UpdateServersWhenOpenedCheckBox.TabIndex = 8;
|
||||
this.UpdateServersWhenOpenedCheckBox.Text = "Update Servers when opened";
|
||||
this.UpdateServersWhenOpenedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.UpdateServersWhenOpenedCheckBox.UseVisualStyleBackColor = true;
|
||||
@@ -1008,11 +1013,8 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.TabPage v2rayTabPage;
|
||||
private System.Windows.Forms.GroupBox PortGroupBox;
|
||||
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 WinTUNGroupBox;
|
||||
private System.Windows.Forms.CheckBox ProxyDNSCheckBox;
|
||||
private System.Windows.Forms.CheckBox UseCustomDNSCheckBox;
|
||||
@@ -1025,7 +1027,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 DNSHijackCheckBox;
|
||||
private System.Windows.Forms.CheckBox FilterDNSCheckBox;
|
||||
private System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
||||
private System.Windows.Forms.TabPage OtherTabPage;
|
||||
@@ -1070,15 +1072,18 @@ namespace Netch.Forms
|
||||
private System.Windows.Forms.TextBox OtherDNSTextBox;
|
||||
private System.Windows.Forms.TextBox ChinaDNSTextBox;
|
||||
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 ProcessFilterProtocolComboBox;
|
||||
private System.Windows.Forms.Label ProcessFilterProtocolLabel;
|
||||
private System.Windows.Forms.CheckBox FilterICMPCheckBox;
|
||||
private System.Windows.Forms.CheckBox ChildProcessHandleCheckBox;
|
||||
private System.Windows.Forms.TextBox ICMPDelayTextBox;
|
||||
private System.Windows.Forms.Label ICMPDelayLabel;
|
||||
private System.Windows.Forms.CheckBox NoSupportDialogCheckBox;
|
||||
private System.Windows.Forms.Label DNSHijackLabel;
|
||||
private System.Windows.Forms.CheckBox HandleProcDNSCheckBox;
|
||||
private System.Windows.Forms.CheckBox FilterTCPCheckBox;
|
||||
private System.Windows.Forms.CheckBox FilterUDPCheckBox;
|
||||
private System.Windows.Forms.CheckBox DNSProxyCheckBox;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public partial class SettingForm : Form
|
||||
public partial class SettingForm : BindingForm
|
||||
{
|
||||
private readonly Dictionary<Control, Func<string, bool>> _checkActions = new();
|
||||
|
||||
private readonly Dictionary<Control, Action<Control>> _saveActions = new();
|
||||
|
||||
public SettingForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -26,29 +20,19 @@ namespace Netch.Forms
|
||||
|
||||
#region General
|
||||
|
||||
BindTextBox<ushort>(Socks5PortTextBox,
|
||||
p => p.ToString() != HTTPPortTextBox.Text,
|
||||
p => Global.Settings.Socks5LocalPort = p,
|
||||
Global.Settings.Socks5LocalPort);
|
||||
|
||||
BindTextBox<ushort>(HTTPPortTextBox,
|
||||
p => p.ToString() != Socks5PortTextBox.Text,
|
||||
p => Global.Settings.HTTPLocalPort = p,
|
||||
Global.Settings.HTTPLocalPort);
|
||||
BindTextBox<ushort>(Socks5PortTextBox, p => true, p => Global.Settings.Socks5LocalPort = p, Global.Settings.Socks5LocalPort);
|
||||
|
||||
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 });
|
||||
|
||||
BindCheckBox(ResolveServerHostnameCheckBox, c => Global.Settings.ResolveServerHostname = c, Global.Settings.ResolveServerHostname);
|
||||
|
||||
BindRadioBox(ICMPingRadioBtn, _ => { }, !Global.Settings.ServerTCPing);
|
||||
|
||||
BindRadioBox(TCPingRadioBtn, c => Global.Settings.ServerTCPing = c, Global.Settings.ServerTCPing);
|
||||
|
||||
BindTextBox<int>(ProfileCountTextBox, i => i > -1, i => Global.Settings.ProfileCount = i, Global.Settings.ProfileCount);
|
||||
BindTextBox<int>(DetectionTickTextBox,
|
||||
i => ServerHelper.DelayTestHelper.Range.InRange(i),
|
||||
i => DelayTestHelper.Range.InRange(i),
|
||||
i => Global.Settings.DetectionTick = i,
|
||||
Global.Settings.DetectionTick);
|
||||
|
||||
@@ -99,24 +83,25 @@ namespace Netch.Forms
|
||||
|
||||
#region Process Mode
|
||||
|
||||
BindListComboBox(ProcessFilterProtocolComboBox,
|
||||
s => Global.Settings.Redirector.FilterProtocol = (PortType)Enum.Parse(typeof(PortType), s.ToString(), false),
|
||||
Enum.GetNames(typeof(PortType)),
|
||||
Global.Settings.Redirector.FilterProtocol.ToString());
|
||||
BindCheckBox(FilterTCPCheckBox, b => Global.Settings.Redirector.FilterTCP = b, Global.Settings.Redirector.FilterTCP);
|
||||
|
||||
BindCheckBox(DNSHijackCheckBox, b => Global.Settings.Redirector.DNSHijack = b, Global.Settings.Redirector.DNSHijack);
|
||||
|
||||
BindTextBox(DNSHijackHostTextBox, s => true, s => Global.Settings.Redirector.DNSHijackHost = s, Global.Settings.Redirector.DNSHijackHost);
|
||||
BindCheckBox(FilterUDPCheckBox, b => Global.Settings.Redirector.FilterUDP = b, Global.Settings.Redirector.FilterUDP);
|
||||
|
||||
BindCheckBox(FilterICMPCheckBox, b => Global.Settings.Redirector.FilterICMP = b, Global.Settings.Redirector.FilterICMP);
|
||||
|
||||
BindTextBox(ICMPDelayTextBox, s => int.TryParse(s, out _), s => { }, Global.Settings.Redirector.ICMPDelay);
|
||||
BindTextBox<int>(ICMPDelayTextBox, s => true, s => Global.Settings.Redirector.ICMPDelay = s, Global.Settings.Redirector.ICMPDelay);
|
||||
|
||||
BindCheckBox(RedirectorSSCheckBox, s => Global.Settings.Redirector.RedirectorSS = s, Global.Settings.Redirector.RedirectorSS);
|
||||
BindCheckBox(FilterDNSCheckBox, b => Global.Settings.Redirector.FilterDNS = b, Global.Settings.Redirector.FilterDNS);
|
||||
|
||||
BindTextBox(DNSHijackHostTextBox, s => true, s => Global.Settings.Redirector.DNSHost = s, Global.Settings.Redirector.DNSHost);
|
||||
|
||||
BindCheckBox(ChildProcessHandleCheckBox,
|
||||
s => Global.Settings.Redirector.ChildProcessHandle = s,
|
||||
Global.Settings.Redirector.ChildProcessHandle);
|
||||
s => Global.Settings.Redirector.FilterParent = s,
|
||||
Global.Settings.Redirector.FilterParent);
|
||||
|
||||
BindCheckBox(DNSProxyCheckBox, b => Global.Settings.Redirector.DNSProxy = b, Global.Settings.Redirector.DNSProxy);
|
||||
|
||||
BindCheckBox(HandleProcDNSCheckBox, b => Global.Settings.Redirector.HandleOnlyDNS = b, Global.Settings.Redirector.HandleOnlyDNS);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -205,6 +190,8 @@ namespace Netch.Forms
|
||||
|
||||
BindCheckBox(UpdateServersWhenOpenedCheckBox, b => Global.Settings.UpdateServersWhenOpened = b, Global.Settings.UpdateServersWhenOpened);
|
||||
|
||||
BindCheckBox(NoSupportDialogCheckBox, b => Global.Settings.NoSupportDialog = b, Global.Settings.NoSupportDialog);
|
||||
|
||||
#endregion
|
||||
|
||||
#region AioDNS
|
||||
@@ -247,7 +234,7 @@ namespace Netch.Forms
|
||||
|
||||
#region Check
|
||||
|
||||
var checkNotPassControl = _checkActions.Where(pair => !pair.Value.Invoke(pair.Key.Text)).Select(pair => pair.Key).ToList();
|
||||
var checkNotPassControl = GetCheckFailedControls();
|
||||
foreach (Control control in checkNotPassControl)
|
||||
Utils.Utils.ChangeControlForeColor(control, Color.Red);
|
||||
|
||||
@@ -258,8 +245,7 @@ namespace Netch.Forms
|
||||
|
||||
#region Save
|
||||
|
||||
foreach (var pair in _saveActions)
|
||||
pair.Value.Invoke(pair.Key);
|
||||
SaveBinds();
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -269,71 +255,5 @@ namespace Netch.Forms
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Close();
|
||||
}
|
||||
|
||||
#region BindUtils
|
||||
|
||||
private void BindTextBox(TextBox control, Func<string, bool> check, Action<string> save, object value)
|
||||
{
|
||||
BindTextBox<string>(control, check, save, value);
|
||||
}
|
||||
|
||||
private void BindTextBox<T>(TextBox control, Func<T, bool> check, Action<T> save, object value)
|
||||
{
|
||||
control.Text = value.ToString();
|
||||
_checkActions.Add(control,
|
||||
s =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return check.Invoke((T)Convert.ChangeType(s, typeof(T)));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
_saveActions.Add(control, c => save.Invoke((T)Convert.ChangeType(((TextBox)c).Text, typeof(T))));
|
||||
}
|
||||
|
||||
private void BindCheckBox(CheckBox control, Action<bool> save, bool value)
|
||||
{
|
||||
control.Checked = value;
|
||||
_saveActions.Add(control, c => save.Invoke(((CheckBox)c).Checked));
|
||||
}
|
||||
|
||||
private void BindRadioBox(RadioButton control, Action<bool> save, bool value)
|
||||
{
|
||||
control.Checked = value;
|
||||
_saveActions.Add(control, c => save.Invoke(((RadioButton)c).Checked));
|
||||
}
|
||||
|
||||
private void BindListComboBox<T>(ComboBox comboBox, Action<T> save, IEnumerable<T> values, T value) where T : notnull
|
||||
{
|
||||
if (comboBox.DropDownStyle != ComboBoxStyle.DropDownList)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
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)
|
||||
{
|
||||
if (values != null)
|
||||
control.Items.AddRange(values);
|
||||
|
||||
_saveActions.Add(control, c => save.Invoke(((ComboBox)c).Text));
|
||||
_checkActions.Add(control, check.Invoke);
|
||||
|
||||
Load += (_, _) => { control.Text = value; };
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Netch.Forms
|
||||
{
|
||||
partial class SubscribeForm
|
||||
partial class SubscriptionForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -29,24 +29,23 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SubscribeForm));
|
||||
this.AddSubscriptionBox = new System.Windows.Forms.GroupBox();
|
||||
this.RemarkLabel = new System.Windows.Forms.Label();
|
||||
this.RemarkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.LinkLabel = new System.Windows.Forms.Label();
|
||||
this.LinkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.UserAgentLabel = new System.Windows.Forms.Label();
|
||||
this.UserAgentTextBox = new System.Windows.Forms.TextBox();
|
||||
this.UnselectButton = new System.Windows.Forms.Button();
|
||||
this.AddButton = new System.Windows.Forms.Button();
|
||||
this.UserAgentLabel = new System.Windows.Forms.Label();
|
||||
this.LinkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.LinkLabel = new System.Windows.Forms.Label();
|
||||
this.RemarkTextBox = new System.Windows.Forms.TextBox();
|
||||
this.RemarkLabel = new System.Windows.Forms.Label();
|
||||
this.SubscribeLinkListView = new System.Windows.Forms.ListView();
|
||||
this.SubscriptionLinkListView = new System.Windows.Forms.ListView();
|
||||
this.EnableColumnHeader = new System.Windows.Forms.ColumnHeader();
|
||||
this.RemarkColumnHeader = new System.Windows.Forms.ColumnHeader();
|
||||
this.LinkColumnHeader = new System.Windows.Forms.ColumnHeader();
|
||||
this.UserAgentHeader = new System.Windows.Forms.ColumnHeader();
|
||||
this.pContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.DeleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.deleteServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.DeleteServersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CopyLinkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MainTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.AddSubscriptionBox.SuspendLayout();
|
||||
@@ -56,14 +55,14 @@
|
||||
//
|
||||
// AddSubscriptionBox
|
||||
//
|
||||
this.AddSubscriptionBox.Controls.Add(this.RemarkLabel);
|
||||
this.AddSubscriptionBox.Controls.Add(this.RemarkTextBox);
|
||||
this.AddSubscriptionBox.Controls.Add(this.LinkLabel);
|
||||
this.AddSubscriptionBox.Controls.Add(this.LinkTextBox);
|
||||
this.AddSubscriptionBox.Controls.Add(this.UserAgentLabel);
|
||||
this.AddSubscriptionBox.Controls.Add(this.UserAgentTextBox);
|
||||
this.AddSubscriptionBox.Controls.Add(this.UnselectButton);
|
||||
this.AddSubscriptionBox.Controls.Add(this.AddButton);
|
||||
this.AddSubscriptionBox.Controls.Add(this.UserAgentLabel);
|
||||
this.AddSubscriptionBox.Controls.Add(this.LinkTextBox);
|
||||
this.AddSubscriptionBox.Controls.Add(this.LinkLabel);
|
||||
this.AddSubscriptionBox.Controls.Add(this.RemarkTextBox);
|
||||
this.AddSubscriptionBox.Controls.Add(this.RemarkLabel);
|
||||
this.AddSubscriptionBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.AddSubscriptionBox.Location = new System.Drawing.Point(8, 248);
|
||||
this.AddSubscriptionBox.Name = "AddSubscriptionBox";
|
||||
@@ -71,6 +70,47 @@
|
||||
this.AddSubscriptionBox.TabIndex = 1;
|
||||
this.AddSubscriptionBox.TabStop = false;
|
||||
//
|
||||
// RemarkLabel
|
||||
//
|
||||
this.RemarkLabel.AutoSize = true;
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(11, 19);
|
||||
this.RemarkLabel.Name = "RemarkLabel";
|
||||
this.RemarkLabel.Size = new System.Drawing.Size(53, 17);
|
||||
this.RemarkLabel.TabIndex = 1;
|
||||
this.RemarkLabel.Text = "Remark";
|
||||
//
|
||||
// RemarkTextBox
|
||||
//
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(109, 16);
|
||||
this.RemarkTextBox.Name = "RemarkTextBox";
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(545, 23);
|
||||
this.RemarkTextBox.TabIndex = 2;
|
||||
//
|
||||
// LinkLabel
|
||||
//
|
||||
this.LinkLabel.AutoSize = true;
|
||||
this.LinkLabel.Location = new System.Drawing.Point(11, 48);
|
||||
this.LinkLabel.Name = "LinkLabel";
|
||||
this.LinkLabel.Size = new System.Drawing.Size(31, 17);
|
||||
this.LinkLabel.TabIndex = 3;
|
||||
this.LinkLabel.Text = "Link";
|
||||
//
|
||||
// LinkTextBox
|
||||
//
|
||||
this.LinkTextBox.Location = new System.Drawing.Point(109, 45);
|
||||
this.LinkTextBox.Name = "LinkTextBox";
|
||||
this.LinkTextBox.Size = new System.Drawing.Size(545, 23);
|
||||
this.LinkTextBox.TabIndex = 4;
|
||||
//
|
||||
// UserAgentLabel
|
||||
//
|
||||
this.UserAgentLabel.AutoSize = true;
|
||||
this.UserAgentLabel.Location = new System.Drawing.Point(11, 77);
|
||||
this.UserAgentLabel.Name = "UserAgentLabel";
|
||||
this.UserAgentLabel.Size = new System.Drawing.Size(74, 17);
|
||||
this.UserAgentLabel.TabIndex = 5;
|
||||
this.UserAgentLabel.Text = "User-Agent";
|
||||
//
|
||||
// UserAgentTextBox
|
||||
//
|
||||
this.UserAgentTextBox.Location = new System.Drawing.Point(109, 74);
|
||||
@@ -98,68 +138,28 @@
|
||||
this.AddButton.UseVisualStyleBackColor = true;
|
||||
this.AddButton.Click += new System.EventHandler(this.AddButton_Click);
|
||||
//
|
||||
// UserAgentLabel
|
||||
// SubscriptionLinkListView
|
||||
//
|
||||
this.UserAgentLabel.AutoSize = true;
|
||||
this.UserAgentLabel.Location = new System.Drawing.Point(11, 77);
|
||||
this.UserAgentLabel.Name = "UserAgentLabel";
|
||||
this.UserAgentLabel.Size = new System.Drawing.Size(74, 17);
|
||||
this.UserAgentLabel.TabIndex = 5;
|
||||
this.UserAgentLabel.Text = "User-Agent";
|
||||
//
|
||||
// LinkTextBox
|
||||
//
|
||||
this.LinkTextBox.Location = new System.Drawing.Point(109, 45);
|
||||
this.LinkTextBox.Name = "LinkTextBox";
|
||||
this.LinkTextBox.Size = new System.Drawing.Size(545, 23);
|
||||
this.LinkTextBox.TabIndex = 4;
|
||||
//
|
||||
// LinkLabel
|
||||
//
|
||||
this.LinkLabel.AutoSize = true;
|
||||
this.LinkLabel.Location = new System.Drawing.Point(11, 48);
|
||||
this.LinkLabel.Name = "LinkLabel";
|
||||
this.LinkLabel.Size = new System.Drawing.Size(31, 17);
|
||||
this.LinkLabel.TabIndex = 3;
|
||||
this.LinkLabel.Text = "Link";
|
||||
//
|
||||
// RemarkTextBox
|
||||
//
|
||||
this.RemarkTextBox.Location = new System.Drawing.Point(109, 16);
|
||||
this.RemarkTextBox.Name = "RemarkTextBox";
|
||||
this.RemarkTextBox.Size = new System.Drawing.Size(545, 23);
|
||||
this.RemarkTextBox.TabIndex = 2;
|
||||
//
|
||||
// RemarkLabel
|
||||
//
|
||||
this.RemarkLabel.AutoSize = true;
|
||||
this.RemarkLabel.Location = new System.Drawing.Point(11, 19);
|
||||
this.RemarkLabel.Name = "RemarkLabel";
|
||||
this.RemarkLabel.Size = new System.Drawing.Size(53, 17);
|
||||
this.RemarkLabel.TabIndex = 1;
|
||||
this.RemarkLabel.Text = "Remark";
|
||||
//
|
||||
// SubscribeLinkListView
|
||||
//
|
||||
this.SubscribeLinkListView.AllowColumnReorder = true;
|
||||
this.SubscribeLinkListView.CheckBoxes = true;
|
||||
this.SubscribeLinkListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[]
|
||||
{
|
||||
this.EnableColumnHeader, this.RemarkColumnHeader, this.LinkColumnHeader, this.UserAgentHeader
|
||||
});
|
||||
this.SubscribeLinkListView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.SubscribeLinkListView.FullRowSelect = true;
|
||||
this.SubscribeLinkListView.HideSelection = false;
|
||||
this.SubscribeLinkListView.Location = new System.Drawing.Point(8, 8);
|
||||
this.SubscribeLinkListView.MultiSelect = false;
|
||||
this.SubscribeLinkListView.Name = "SubscribeLinkListView";
|
||||
this.SubscribeLinkListView.Size = new System.Drawing.Size(668, 234);
|
||||
this.SubscribeLinkListView.TabIndex = 0;
|
||||
this.SubscribeLinkListView.UseCompatibleStateImageBehavior = false;
|
||||
this.SubscribeLinkListView.View = System.Windows.Forms.View.Details;
|
||||
this.SubscribeLinkListView.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.SubscribeLinkListView_ItemChecked);
|
||||
this.SubscribeLinkListView.SelectedIndexChanged += new System.EventHandler(this.SubscribeLinkListView_SelectedIndexChanged);
|
||||
this.SubscribeLinkListView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.SubscribeLinkListView_MouseUp);
|
||||
this.SubscriptionLinkListView.AllowColumnReorder = true;
|
||||
this.SubscriptionLinkListView.CheckBoxes = true;
|
||||
this.SubscriptionLinkListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.EnableColumnHeader,
|
||||
this.RemarkColumnHeader,
|
||||
this.LinkColumnHeader,
|
||||
this.UserAgentHeader});
|
||||
this.SubscriptionLinkListView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.SubscriptionLinkListView.FullRowSelect = true;
|
||||
this.SubscriptionLinkListView.HideSelection = false;
|
||||
this.SubscriptionLinkListView.Location = new System.Drawing.Point(8, 8);
|
||||
this.SubscriptionLinkListView.MultiSelect = false;
|
||||
this.SubscriptionLinkListView.Name = "SubscriptionLinkListView";
|
||||
this.SubscriptionLinkListView.Size = new System.Drawing.Size(668, 234);
|
||||
this.SubscriptionLinkListView.TabIndex = 0;
|
||||
this.SubscriptionLinkListView.UseCompatibleStateImageBehavior = false;
|
||||
this.SubscriptionLinkListView.View = System.Windows.Forms.View.Details;
|
||||
this.SubscriptionLinkListView.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.SubscriptionLinkListView_ItemChecked);
|
||||
this.SubscriptionLinkListView.SelectedIndexChanged += new System.EventHandler(this.SubscriptionLinkListView_SelectedIndexChanged);
|
||||
this.SubscriptionLinkListView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.SubscriptionLinkListView_MouseUp);
|
||||
//
|
||||
// EnableColumnHeader
|
||||
//
|
||||
@@ -182,39 +182,39 @@
|
||||
//
|
||||
// pContextMenuStrip
|
||||
//
|
||||
this.pContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
|
||||
{
|
||||
this.DeleteToolStripMenuItem, this.deleteServerToolStripMenuItem, this.CopyLinkToolStripMenuItem
|
||||
});
|
||||
this.pContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.DeleteToolStripMenuItem,
|
||||
this.DeleteServersToolStripMenuItem,
|
||||
this.CopyLinkToolStripMenuItem});
|
||||
this.pContextMenuStrip.Name = "pContextMenuStrip";
|
||||
this.pContextMenuStrip.Size = new System.Drawing.Size(151, 70);
|
||||
this.pContextMenuStrip.Size = new System.Drawing.Size(161, 70);
|
||||
//
|
||||
// DeleteToolStripMenuItem
|
||||
//
|
||||
this.DeleteToolStripMenuItem.Name = "DeleteToolStripMenuItem";
|
||||
this.DeleteToolStripMenuItem.Size = new System.Drawing.Size(150, 22);
|
||||
this.DeleteToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.DeleteToolStripMenuItem.Text = "Delete";
|
||||
this.DeleteToolStripMenuItem.Click += new System.EventHandler(this.DeleteToolStripMenuItem_Click);
|
||||
//
|
||||
// deleteServerToolStripMenuItem
|
||||
// DeleteServersToolStripMenuItem
|
||||
//
|
||||
this.deleteServerToolStripMenuItem.Name = "deleteServerToolStripMenuItem";
|
||||
this.deleteServerToolStripMenuItem.Size = new System.Drawing.Size(150, 22);
|
||||
this.deleteServerToolStripMenuItem.Text = "DeleteServer";
|
||||
this.deleteServerToolStripMenuItem.Click += new System.EventHandler(this.deleteServerToolStripMenuItem_Click);
|
||||
this.DeleteServersToolStripMenuItem.Name = "DeleteServersToolStripMenuItem";
|
||||
this.DeleteServersToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.DeleteServersToolStripMenuItem.Text = "Delete Servers";
|
||||
this.DeleteServersToolStripMenuItem.Click += new System.EventHandler(this.DeleteServersToolStripMenuItem_Click);
|
||||
//
|
||||
// CopyLinkToolStripMenuItem
|
||||
//
|
||||
this.CopyLinkToolStripMenuItem.Name = "CopyLinkToolStripMenuItem";
|
||||
this.CopyLinkToolStripMenuItem.Size = new System.Drawing.Size(150, 22);
|
||||
this.CopyLinkToolStripMenuItem.Text = "CopyLink";
|
||||
this.CopyLinkToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
|
||||
this.CopyLinkToolStripMenuItem.Text = "Copy link";
|
||||
this.CopyLinkToolStripMenuItem.Click += new System.EventHandler(this.CopyLinkToolStripMenuItem_Click);
|
||||
//
|
||||
// MainTableLayoutPanel
|
||||
//
|
||||
this.MainTableLayoutPanel.ColumnCount = 1;
|
||||
this.MainTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.MainTableLayoutPanel.Controls.Add(this.SubscribeLinkListView, 0, 0);
|
||||
this.MainTableLayoutPanel.Controls.Add(this.SubscriptionLinkListView, 0, 0);
|
||||
this.MainTableLayoutPanel.Controls.Add(this.AddSubscriptionBox, 0, 1);
|
||||
this.MainTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.MainTableLayoutPanel.Location = new System.Drawing.Point(0, 0);
|
||||
@@ -227,25 +227,26 @@
|
||||
this.MainTableLayoutPanel.Size = new System.Drawing.Size(684, 391);
|
||||
this.MainTableLayoutPanel.TabIndex = 11;
|
||||
//
|
||||
// SubscribeForm
|
||||
// SubscriptionForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||
this.ClientSize = new System.Drawing.Size(684, 391);
|
||||
this.Controls.Add(this.MainTableLayoutPanel);
|
||||
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;
|
||||
this.Name = "SubscribeForm";
|
||||
this.Name = "SubscriptionForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Subscribe";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SubscribeForm_FormClosing);
|
||||
this.Text = "Subscription";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SubscriptionForm_FormClosing);
|
||||
this.AddSubscriptionBox.ResumeLayout(false);
|
||||
this.AddSubscriptionBox.PerformLayout();
|
||||
this.pContextMenuStrip.ResumeLayout(false);
|
||||
this.MainTableLayoutPanel.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
private System.Windows.Forms.ColumnHeader EnableColumnHeader;
|
||||
|
||||
@@ -257,7 +258,7 @@
|
||||
private System.Windows.Forms.Label LinkLabel;
|
||||
private System.Windows.Forms.TextBox RemarkTextBox;
|
||||
private System.Windows.Forms.Button AddButton;
|
||||
private System.Windows.Forms.ListView SubscribeLinkListView;
|
||||
private System.Windows.Forms.ListView SubscriptionLinkListView;
|
||||
private System.Windows.Forms.ColumnHeader RemarkColumnHeader;
|
||||
private System.Windows.Forms.ColumnHeader LinkColumnHeader;
|
||||
private System.Windows.Forms.ContextMenuStrip pContextMenuStrip;
|
||||
@@ -269,6 +270,6 @@
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolStripMenuItem deleteServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem DeleteServersToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public partial class SubscribeForm : Form
|
||||
public partial class SubscriptionForm : Form
|
||||
{
|
||||
public SubscribeForm()
|
||||
public SubscriptionForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
Icon = Resources.icon;
|
||||
@@ -17,33 +17,33 @@ namespace Netch.Forms
|
||||
i18N.TranslateForm(this);
|
||||
i18N.TranslateForm(pContextMenuStrip);
|
||||
|
||||
InitSubscribeLink();
|
||||
LoadSubscriptionLinks();
|
||||
}
|
||||
|
||||
private int SelectedIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SubscribeLinkListView.MultiSelect)
|
||||
if (SubscriptionLinkListView.MultiSelect)
|
||||
throw new Exception();
|
||||
|
||||
return SubscribeLinkListView.SelectedIndices.Count == 0 ? -1 : SubscribeLinkListView.SelectedIndices[0];
|
||||
return SubscriptionLinkListView.SelectedIndices.Count == 0 ? -1 : SubscriptionLinkListView.SelectedIndices[0];
|
||||
}
|
||||
}
|
||||
|
||||
#region EventHandler
|
||||
|
||||
private void SubscribeLinkListView_MouseUp(object sender, MouseEventArgs e)
|
||||
private void SubscriptionLinkListView_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right)
|
||||
if (SelectedIndex != -1)
|
||||
pContextMenuStrip.Show(SubscribeLinkListView, e.Location);
|
||||
pContextMenuStrip.Show(SubscriptionLinkListView, e.Location);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选中/取消选中
|
||||
/// </summary>
|
||||
private void SubscribeLinkListView_SelectedIndexChanged(object sender, EventArgs e)
|
||||
private void SubscriptionLinkListView_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SetEditingGroup(SelectedIndex);
|
||||
}
|
||||
@@ -51,13 +51,13 @@ namespace Netch.Forms
|
||||
/// <summary>
|
||||
/// 订阅启/禁用
|
||||
/// </summary>
|
||||
private void SubscribeLinkListView_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
private void SubscriptionLinkListView_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
var index = e.Item.Index;
|
||||
Global.Settings.SubscribeLink[index].Enable = SubscribeLinkListView.Items[index].Checked;
|
||||
Global.Settings.Subscription[index].Enable = SubscriptionLinkListView.Items[index].Checked;
|
||||
}
|
||||
|
||||
private async void SubscribeForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
private async void SubscriptionForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
await Configuration.SaveAsync();
|
||||
}
|
||||
@@ -94,13 +94,13 @@ namespace Netch.Forms
|
||||
|
||||
if (SelectedIndex == -1)
|
||||
{
|
||||
if (Global.Settings.SubscribeLink.Any(link => link.Remark.Equals(RemarkTextBox.Text)))
|
||||
if (Global.Settings.Subscription.Any(link => link.Remark.Equals(RemarkTextBox.Text)))
|
||||
{
|
||||
MessageBoxX.Show("Remark Name Duplicate!");
|
||||
MessageBoxX.Show(i18N.Translate("Subscription with the specified remark already exists"));
|
||||
return;
|
||||
}
|
||||
|
||||
Global.Settings.SubscribeLink.Add(new SubscribeLink
|
||||
Global.Settings.Subscription.Add(new Subscription
|
||||
{
|
||||
Enable = true,
|
||||
Remark = RemarkTextBox.Text,
|
||||
@@ -110,7 +110,7 @@ namespace Netch.Forms
|
||||
}
|
||||
else
|
||||
{
|
||||
var subscribeLink = Global.Settings.SubscribeLink[SelectedIndex];
|
||||
var subscribeLink = Global.Settings.Subscription[SelectedIndex];
|
||||
|
||||
RenameServers(subscribeLink.Remark, RemarkTextBox.Text);
|
||||
subscribeLink.Link = LinkTextBox.Text;
|
||||
@@ -118,7 +118,7 @@ namespace Netch.Forms
|
||||
subscribeLink.UserAgent = UserAgentTextBox.Text;
|
||||
}
|
||||
|
||||
InitSubscribeLink();
|
||||
LoadSubscriptionLinks();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -131,24 +131,24 @@ namespace Netch.Forms
|
||||
confirm: true) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var subscribeLink = Global.Settings.SubscribeLink[SelectedIndex];
|
||||
var subscribeLink = Global.Settings.Subscription[SelectedIndex];
|
||||
DeleteServers(subscribeLink.Remark);
|
||||
Global.Settings.SubscribeLink.Remove(subscribeLink);
|
||||
Global.Settings.Subscription.Remove(subscribeLink);
|
||||
|
||||
InitSubscribeLink();
|
||||
LoadSubscriptionLinks();
|
||||
}
|
||||
|
||||
private void deleteServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
private void DeleteServersToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (MessageBoxX.Show(i18N.Translate("Confirm deletion?"), confirm: true) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
DeleteServers(Global.Settings.SubscribeLink[SelectedIndex].Remark);
|
||||
DeleteServers(Global.Settings.Subscription[SelectedIndex].Remark);
|
||||
}
|
||||
|
||||
private void CopyLinkToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Clipboard.SetText(Global.Settings.SubscribeLink[SelectedIndex].Link);
|
||||
Clipboard.SetText(Global.Settings.Subscription[SelectedIndex].Link);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -166,12 +166,12 @@ namespace Netch.Forms
|
||||
server.Group = newGroup;
|
||||
}
|
||||
|
||||
private void InitSubscribeLink()
|
||||
private void LoadSubscriptionLinks()
|
||||
{
|
||||
SubscribeLinkListView.Items.Clear();
|
||||
SubscriptionLinkListView.Items.Clear();
|
||||
|
||||
foreach (var item in Global.Settings.SubscribeLink)
|
||||
SubscribeLinkListView.Items.Add(new ListViewItem(new[]
|
||||
foreach (var item in Global.Settings.Subscription)
|
||||
SubscriptionLinkListView.Items.Add(new ListViewItem(new[]
|
||||
{
|
||||
"",
|
||||
item.Remark,
|
||||
@@ -202,7 +202,7 @@ namespace Netch.Forms
|
||||
return;
|
||||
}
|
||||
|
||||
var item = Global.Settings.SubscribeLink[index];
|
||||
var item = Global.Settings.Subscription[index];
|
||||
AddSubscriptionBox.Text = item.Remark;
|
||||
RemarkTextBox.Text = item.Remark;
|
||||
LinkTextBox.Text = item.Link;
|
||||
63
Netch/Forms/SubscriptionForm.resx
Normal file
63
Netch/Forms/SubscriptionForm.resx
Normal file
@@ -0,0 +1,63 @@
|
||||
<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>
|
||||
<metadata name="pContextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
92
Netch/Forms/SyncGlobalCheckBox.cs
Normal file
92
Netch/Forms/SyncGlobalCheckBox.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public class SyncGlobalCheckBox : CheckBox
|
||||
{
|
||||
public SyncGlobalCheckBox()
|
||||
{
|
||||
AutoCheck = false;
|
||||
OnSyncGlobalChanged();
|
||||
}
|
||||
|
||||
private bool _syncGlobal;
|
||||
|
||||
private bool _globalValue;
|
||||
|
||||
public bool SyncGlobal
|
||||
{
|
||||
get => _syncGlobal;
|
||||
set
|
||||
{
|
||||
if (value == _syncGlobal)
|
||||
return;
|
||||
|
||||
_syncGlobal = value;
|
||||
|
||||
OnSyncGlobalChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool GlobalValue
|
||||
{
|
||||
get => _globalValue;
|
||||
set
|
||||
{
|
||||
if (value == _globalValue)
|
||||
return;
|
||||
|
||||
_globalValue = value;
|
||||
|
||||
if (SyncGlobal)
|
||||
Checked = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClick(EventArgs e)
|
||||
{
|
||||
if (Checked == GlobalValue)
|
||||
{
|
||||
SyncGlobal = !SyncGlobal;
|
||||
if (SyncGlobal)
|
||||
return;
|
||||
}
|
||||
|
||||
Checked = !Checked;
|
||||
base.OnClick(e);
|
||||
}
|
||||
|
||||
public bool? Value
|
||||
{
|
||||
get => _syncGlobal ? null : Checked;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
SyncGlobal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SyncGlobal = false;
|
||||
Checked = (bool)value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSyncGlobalChanged()
|
||||
{
|
||||
if (_syncGlobal)
|
||||
{
|
||||
Font = new Font(Font, FontStyle.Regular);
|
||||
BackColor = SystemColors.Control;
|
||||
}
|
||||
else
|
||||
{
|
||||
Font = new Font(Font, FontStyle.Bold | FontStyle.Italic);
|
||||
BackColor = Color.Yellow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,11 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
|
||||
namespace Netch
|
||||
{
|
||||
@@ -42,7 +44,7 @@ namespace Netch
|
||||
public static JsonSerializerOptions NewCustomJsonSerializerOptions() => new()
|
||||
{
|
||||
WriteIndented = true,
|
||||
IgnoreNullValues = true,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Servers;
|
||||
|
||||
namespace Netch.Interfaces
|
||||
{
|
||||
public interface IModeController : IController
|
||||
{
|
||||
public Task StartAsync(Server server, Mode mode);
|
||||
public ModeFeature Features { get; }
|
||||
|
||||
public Task StartAsync(Socks5Server server, Mode mode);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Netch.Interfaces
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public Task<Socks5> StartAsync(Server s);
|
||||
public Task<Socks5LocalServer> StartAsync(Server s);
|
||||
}
|
||||
|
||||
public static class ServerControllerExtension
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace Netch.Interops
|
||||
public enum NameList
|
||||
{
|
||||
TYPE_REST,
|
||||
TYPE_ADDR,
|
||||
TYPE_LIST,
|
||||
TYPE_LISN,
|
||||
TYPE_CDNS,
|
||||
TYPE_ODNS
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public static class NFAPI
|
||||
{
|
||||
private const string nfapinet_bin = "nfapinet.dll";
|
||||
|
||||
[DllImport(nfapinet_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern NF_STATUS nf_registerDriver(string driverName);
|
||||
|
||||
[DllImport(nfapinet_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern NF_STATUS nf_unRegisterDriver(string driverName);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Netch.Interops
|
||||
{
|
||||
public enum NF_STATUS : int
|
||||
{
|
||||
NF_STATUS_SUCCESS = 0,
|
||||
NF_STATUS_FAIL = -1,
|
||||
NF_STATUS_INVALID_ENDPOINT_ID = -2,
|
||||
NF_STATUS_NOT_INITIALIZED = -3,
|
||||
NF_STATUS_IO_ERROR = -4
|
||||
}
|
||||
}
|
||||
@@ -8,38 +8,35 @@ namespace Netch.Interops
|
||||
{
|
||||
public enum NameList
|
||||
{
|
||||
TYPE_FILTERLOOPBACK,
|
||||
TYPE_FILTERICMP,
|
||||
TYPE_FILTERTCP,
|
||||
TYPE_FILTERUDP,
|
||||
AIO_FILTERLOOPBACK,
|
||||
AIO_FILTERINTRANET, // LAN
|
||||
AIO_FILTERPARENT,
|
||||
AIO_FILTERICMP,
|
||||
AIO_FILTERTCP,
|
||||
AIO_FILTERUDP,
|
||||
AIO_FILTERDNS,
|
||||
|
||||
TYPE_CLRNAME,
|
||||
TYPE_ADDNAME,
|
||||
TYPE_BYPNAME,
|
||||
AIO_ICMPING,
|
||||
|
||||
TYPE_DNSHOST,
|
||||
AIO_DNSONLY,
|
||||
AIO_DNSPROX,
|
||||
AIO_DNSHOST,
|
||||
AIO_DNSPORT,
|
||||
|
||||
TYPE_TCPLISN,
|
||||
TYPE_TCPTYPE,
|
||||
TYPE_TCPHOST,
|
||||
TYPE_TCPUSER,
|
||||
TYPE_TCPPASS,
|
||||
TYPE_TCPMETH,
|
||||
TYPE_TCPPROT,
|
||||
TYPE_TCPPRPA,
|
||||
TYPE_TCPOBFS,
|
||||
TYPE_TCPOBPA,
|
||||
AIO_TGTHOST,
|
||||
AIO_TGTPORT,
|
||||
AIO_TGTUSER,
|
||||
AIO_TGTPASS,
|
||||
|
||||
TYPE_UDPLISN,
|
||||
TYPE_UDPTYPE,
|
||||
TYPE_UDPHOST,
|
||||
TYPE_UDPUSER,
|
||||
TYPE_UDPPASS,
|
||||
TYPE_UDPMETH,
|
||||
TYPE_UDPPROT,
|
||||
TYPE_UDPPRPA,
|
||||
TYPE_UDPOBFS,
|
||||
TYPE_UDPOBPA
|
||||
AIO_CLRNAME,
|
||||
AIO_ADDNAME,
|
||||
AIO_BYPNAME
|
||||
}
|
||||
|
||||
public static bool Dial(NameList name, bool value)
|
||||
{
|
||||
Log.Verbose($"[Redirector] Dial {name}: {value}");
|
||||
return aio_dial(name, value.ToString().ToLower());
|
||||
}
|
||||
|
||||
public static bool Dial(NameList name, string value)
|
||||
@@ -58,10 +55,14 @@ namespace Netch.Interops
|
||||
return await Task.Run(aio_free).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
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)]
|
||||
public static extern bool aio_register([MarshalAs(UnmanagedType.LPWStr)] string value);
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool aio_unregister([MarshalAs(UnmanagedType.LPWStr)] string value);
|
||||
|
||||
[DllImport(Redirector_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool aio_dial(NameList name, [MarshalAs(UnmanagedType.LPWStr)] string value);
|
||||
|
||||
|
||||
44
Netch/JsonConverter/ModeConverterWithTypeDiscriminator.cs
Normal file
44
Netch/JsonConverter/ModeConverterWithTypeDiscriminator.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Netch.Models.Modes;
|
||||
using Netch.Models.Modes.ProcessMode;
|
||||
using Netch.Models.Modes.ShareMode;
|
||||
using Netch.Models.Modes.TunMode;
|
||||
|
||||
namespace Netch.JsonConverter
|
||||
{
|
||||
public class ModeConverterWithTypeDiscriminator : JsonConverter<Mode>
|
||||
{
|
||||
public override Mode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var jsonElement = JsonSerializer.Deserialize<JsonElement>(ref reader);
|
||||
|
||||
var modeTypePropertyName = JsonNamingPolicy.CamelCase.ConvertName(nameof(Mode.Type));
|
||||
if (!jsonElement.TryGetProperty(modeTypePropertyName, out var modeTypeToken))
|
||||
throw new JsonException();
|
||||
|
||||
var modeTypeEnum = modeTypeToken.ValueKind switch
|
||||
{
|
||||
JsonValueKind.Number => (ModeType)modeTypeToken.GetInt32(),
|
||||
JsonValueKind.String => Enum.Parse<ModeType>(modeTypeToken.GetString()!),
|
||||
_ => throw new JsonException()
|
||||
};
|
||||
|
||||
var modeType = modeTypeEnum switch
|
||||
{
|
||||
ModeType.ProcessMode => typeof(Redirector),
|
||||
ModeType.TunMode => typeof(TunMode),
|
||||
ModeType.ShareMode => typeof(ShareMode),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
return (Mode?)jsonElement.Deserialize(modeType, options);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Mode value, JsonSerializerOptions options)
|
||||
{
|
||||
JsonSerializer.Serialize<object>(writer, value, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Netch/JsonConverter/ServerConverterWithTypeDiscriminator.cs
Normal file
23
Netch/JsonConverter/ServerConverterWithTypeDiscriminator.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.JsonConverter
|
||||
{
|
||||
public class ServerConverterWithTypeDiscriminator : JsonConverter<Server>
|
||||
{
|
||||
public override Server Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var jsonElement = JsonSerializer.Deserialize<JsonElement>(ref reader);
|
||||
var type = ServerHelper.GetTypeByTypeName(jsonElement.GetProperty("Type").GetString()!);
|
||||
return (Server)jsonElement.Deserialize(type)!;
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Server value, JsonSerializerOptions options)
|
||||
{
|
||||
JsonSerializer.Serialize<object>(writer, value, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Netch/Models/Arguments.cs
Normal file
49
Netch/Models/Arguments.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public static class Arguments
|
||||
{
|
||||
public static string Format(IEnumerable<object?> a)
|
||||
{
|
||||
var arguments = a.ToList();
|
||||
if (arguments.Count % 2 != 0)
|
||||
throw new FormatException("missing last argument value");
|
||||
|
||||
var tokens = new List<string>();
|
||||
|
||||
for (var i = 0; i < arguments.Count; i += 2)
|
||||
{
|
||||
var keyObj = arguments[i];
|
||||
var valueObj = arguments[i + 1];
|
||||
|
||||
if (keyObj is not string key)
|
||||
throw new FormatException($"argument key at array index {i} is not string");
|
||||
|
||||
switch (valueObj)
|
||||
{
|
||||
case SpecialArgument.Flag:
|
||||
tokens.Add(key);
|
||||
break;
|
||||
case null:
|
||||
case string value when value.IsNullOrWhiteSpace():
|
||||
continue;
|
||||
default:
|
||||
tokens.Add(key);
|
||||
tokens.Add(valueObj.ToString()!);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return string.Join(' ', tokens);
|
||||
}
|
||||
}
|
||||
|
||||
public enum SpecialArgument
|
||||
{
|
||||
Flag
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Models.GitHubRelease
|
||||
{
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Netch.Enums;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class Mode
|
||||
{
|
||||
private List<string>? _content;
|
||||
|
||||
public Mode(string? fullName)
|
||||
{
|
||||
FullName = fullName;
|
||||
if (FullName == null || !File.Exists(FullName))
|
||||
return;
|
||||
|
||||
Load();
|
||||
}
|
||||
|
||||
public string? FullName { get; }
|
||||
|
||||
public List<string> Content => _content ??= ReadContent();
|
||||
|
||||
public string Remark { get; set; } = "";
|
||||
|
||||
public ModeType Type { get; set; } = ModeType.Process;
|
||||
|
||||
public string? RelativePath => FullName == null ? null : ModeHelper.GetRelativePath(FullName);
|
||||
|
||||
private void Load()
|
||||
{
|
||||
if (FullName == null)
|
||||
return;
|
||||
|
||||
(Remark, Type) = ReadHead(FullName);
|
||||
_content = null;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetRules()
|
||||
{
|
||||
foreach (var s in Content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s))
|
||||
continue;
|
||||
|
||||
if (s.StartsWith("//"))
|
||||
continue;
|
||||
|
||||
const string include = "#include";
|
||||
if (s.StartsWith(include))
|
||||
{
|
||||
var relativePath = new StringBuilder(s[include.Length..].Trim());
|
||||
relativePath.Replace("<", "").Replace(">", "");
|
||||
relativePath.Replace(".h", ".txt");
|
||||
|
||||
var mode = Global.Modes.FirstOrDefault(m => m.RelativePath?.Equals(relativePath.ToString()) ?? false) ??
|
||||
throw new MessageException($"{relativePath} file included in {Remark} not found");
|
||||
|
||||
if (mode == this)
|
||||
throw new MessageException("Can't self-reference");
|
||||
|
||||
if (mode.Type != Type)
|
||||
throw new MessageException($"{mode.Remark}'s mode is not as same as {Remark}'s mode");
|
||||
|
||||
if (mode.Content.Any(rule => rule.StartsWith(include)))
|
||||
throw new Exception("Cannot reference mode that reference other mode");
|
||||
|
||||
foreach (var rule in mode.GetRules())
|
||||
yield return rule;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static (string, ModeType) ReadHead(string fileName)
|
||||
{
|
||||
var text = File.ReadLines(fileName).First();
|
||||
if (text.First() != '#')
|
||||
throw new FormatException($"{fileName} head not found at Line 0");
|
||||
|
||||
var strings = text[1..].SplitTrimEntries(',');
|
||||
|
||||
var remark = strings[0];
|
||||
var typeNumber = int.TryParse(strings.ElementAtOrDefault(1), out var type) ? type : 0;
|
||||
|
||||
if (!Enum.GetValues(typeof(ModeType)).Cast<int>().Contains(typeNumber))
|
||||
throw new NotSupportedException($"Not support mode \"{typeNumber}\".");
|
||||
|
||||
return (remark, (ModeType)typeNumber);
|
||||
}
|
||||
|
||||
private List<string> ReadContent()
|
||||
{
|
||||
if (FullName == null || !File.Exists(FullName))
|
||||
return new List<string>();
|
||||
|
||||
return File.ReadLines(FullName).Skip(1).ToList();
|
||||
}
|
||||
|
||||
public void WriteFile()
|
||||
{
|
||||
var dir = Path.GetDirectoryName(FullName)!;
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
var content = $"# {Remark}, {(int)Type}{Constants.EOF}{string.Join(Constants.EOF, Content)}";
|
||||
// 写入到模式文件里
|
||||
File.WriteAllText(FullName!, content);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[{(int)Type + 1}] {i18N.Translate(Remark)}";
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModeExtension
|
||||
{
|
||||
/// 是否会转发 UDP
|
||||
public static bool TestNatRequired(this Mode mode)
|
||||
{
|
||||
return mode.Type is ModeType.Process && Global.Settings.Redirector.FilterProtocol.HasFlag(PortType.UDP) ||
|
||||
mode.Type is ModeType.BypassRuleIPs;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Netch/Models/Modes/Mode.cs
Normal file
29
Netch/Models/Modes/Mode.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Models.Modes
|
||||
{
|
||||
public abstract class Mode
|
||||
{
|
||||
[JsonPropertyOrder(int.MinValue)]
|
||||
public abstract ModeType Type { get; }
|
||||
|
||||
public Dictionary<string, string> Remark { get; set; } = new();
|
||||
|
||||
[JsonIgnore]
|
||||
// File FullName
|
||||
// TODO maybe make it becomes mode dictionary key
|
||||
public string FullName { get; set; } = null!;
|
||||
|
||||
public override string ToString() => $"[{(int)Type + 1}] {i18NRemark}";
|
||||
|
||||
[JsonIgnore]
|
||||
public string i18NRemark
|
||||
{
|
||||
// TODO i18N.Culture to support fallback
|
||||
get => Remark.GetValueOrDefault(i18N.LangCode) ?? Remark.GetValueOrDefault("en") ?? "";
|
||||
set => Remark[i18N.LangCode] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Netch/Models/Modes/ModeFeature.cs
Normal file
13
Netch/Models/Modes/ModeFeature.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace Netch.Models.Modes
|
||||
{
|
||||
[Flags]
|
||||
public enum ModeFeature
|
||||
{
|
||||
SupportSocks5 = 0,
|
||||
SupportIPv4 = 0,
|
||||
SupportSocks5Auth = 0b_0001,
|
||||
SupportIPv6 = 0b_0100
|
||||
}
|
||||
}
|
||||
20
Netch/Models/Modes/ModeType.cs
Normal file
20
Netch/Models/Modes/ModeType.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
namespace Netch.Models.Modes
|
||||
{
|
||||
public enum ModeType
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程代理
|
||||
/// </summary>
|
||||
ProcessMode,
|
||||
|
||||
/// <summary>
|
||||
/// 网络共享
|
||||
/// </summary>
|
||||
ShareMode,
|
||||
|
||||
/// <summary>
|
||||
/// 网卡代理
|
||||
/// </summary>
|
||||
TunMode
|
||||
}
|
||||
}
|
||||
39
Netch/Models/Modes/ProcessMode/ProcessMode.cs
Normal file
39
Netch/Models/Modes/ProcessMode/ProcessMode.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Models.Modes.ProcessMode
|
||||
{
|
||||
public class Redirector : Mode
|
||||
{
|
||||
public override ModeType Type => ModeType.ProcessMode;
|
||||
|
||||
#region Base
|
||||
|
||||
public bool? FilterICMP { get; set; }
|
||||
|
||||
public bool? FilterTCP { get; set; }
|
||||
|
||||
public bool? FilterUDP { get; set; }
|
||||
|
||||
public bool? FilterDNS { get; set; }
|
||||
|
||||
public bool? FilterParent { get; set; }
|
||||
|
||||
public int? ICMPDelay { get; set; }
|
||||
|
||||
public bool? DNSProxy { get; set; }
|
||||
|
||||
public bool? HandleOnlyDNS { get; set; }
|
||||
|
||||
public string? DNSHost { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public bool FilterLoopback { get; set; } = false;
|
||||
|
||||
public bool FilterIntranet { get; set; } = true;
|
||||
|
||||
public List<string> Bypass { get; set; } = new();
|
||||
|
||||
public List<string> Handle { get; set; } = new();
|
||||
}
|
||||
}
|
||||
9
Netch/Models/Modes/ShareMode/ShareMode.cs
Normal file
9
Netch/Models/Modes/ShareMode/ShareMode.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Netch.Models.Modes.ShareMode
|
||||
{
|
||||
public class ShareMode : Mode
|
||||
{
|
||||
public override ModeType Type => ModeType.ShareMode;
|
||||
|
||||
public string Argument = "--preset uu";
|
||||
}
|
||||
}
|
||||
13
Netch/Models/Modes/TunMode/TunMode.cs
Normal file
13
Netch/Models/Modes/TunMode/TunMode.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Models.Modes.TunMode
|
||||
{
|
||||
public class TunMode : Mode
|
||||
{
|
||||
public override ModeType Type => ModeType.TunMode;
|
||||
|
||||
public List<string> Bypass { get; set; } = new();
|
||||
|
||||
public List<string> Handle { get; set; } = new();
|
||||
}
|
||||
}
|
||||
9
Netch/Models/NatTypeTestResult.cs
Normal file
9
Netch/Models/NatTypeTestResult.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public struct NatTypeTestResult
|
||||
{
|
||||
public string? Result;
|
||||
public string? LocalEnd;
|
||||
public string? PublicEnd;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public abstract class ParameterBase
|
||||
{
|
||||
// null value par
|
||||
|
||||
private readonly bool _full;
|
||||
|
||||
protected readonly string ParametersSeparate = " ";
|
||||
protected readonly string Separate = " ";
|
||||
protected readonly string VerbPrefix = "-";
|
||||
protected readonly string FullPrefix = "--";
|
||||
|
||||
protected ParameterBase()
|
||||
{
|
||||
_full = !GetType().IsDefined(typeof(VerbAttribute));
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var parameters = GetType().GetProperties().Select(PropToParameter).Where(s => s != null).Cast<string>();
|
||||
return string.Join(ParametersSeparate, parameters).Trim();
|
||||
}
|
||||
|
||||
private string? PropToParameter(PropertyInfo p)
|
||||
{
|
||||
// prefix
|
||||
bool full;
|
||||
if (p.IsDefined(typeof(VerbAttribute)))
|
||||
full = false;
|
||||
else if (p.IsDefined(typeof(FullAttribute)))
|
||||
full = true;
|
||||
else
|
||||
full = _full;
|
||||
|
||||
var prefix = full ? FullPrefix : VerbPrefix;
|
||||
// key
|
||||
var key = p.GetCustomAttribute<RealNameAttribute>()?.Name ?? p.Name;
|
||||
|
||||
// build
|
||||
var value = p.GetValue(this);
|
||||
switch (value)
|
||||
{
|
||||
case bool b:
|
||||
return b ? $"{prefix}{key}" : null;
|
||||
default:
|
||||
if (string.IsNullOrWhiteSpace(value?.ToString()))
|
||||
return p.IsDefined(typeof(OptionalAttribute)) ? null : throw new RequiredArgumentValueInvalidException(p.Name, this, null);
|
||||
|
||||
if (p.IsDefined(typeof(QuoteAttribute)))
|
||||
value = $"\"{value}\"";
|
||||
|
||||
return $"{prefix}{key}{Separate}{value}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
|
||||
public class VerbAttribute : Attribute
|
||||
{
|
||||
// Don't use verb and full both on one class or property
|
||||
// if you did, will take verb
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Class)]
|
||||
public class FullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class OptionalAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class QuoteAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class RealNameAttribute : Attribute
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public RealNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class RequiredArgumentValueInvalidException : Exception
|
||||
{
|
||||
public string? ArgumentName { get; }
|
||||
|
||||
public object? ArgumentObject { get; }
|
||||
|
||||
private readonly string? _message;
|
||||
|
||||
private const string DefaultMessage = "{0}'s Argument \"{1}\" value invalid. A required argument's value can't be null or empty.";
|
||||
|
||||
public override string Message => _message ?? string.Format(DefaultMessage, ArgumentObject!.GetType(), ArgumentName);
|
||||
|
||||
public RequiredArgumentValueInvalidException()
|
||||
{
|
||||
_message = "Some Argument value invalid. A required argument value's can't be null or empty.";
|
||||
}
|
||||
|
||||
public RequiredArgumentValueInvalidException(string argumentName, object argumentObject, string? message)
|
||||
{
|
||||
ArgumentName = argumentName;
|
||||
ArgumentObject = argumentObject;
|
||||
_message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Netch.Models
|
||||
using Netch.Models.Modes;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class Profile
|
||||
{
|
||||
@@ -13,7 +15,7 @@
|
||||
public Profile(Server server, Mode mode, string name, int index)
|
||||
{
|
||||
ServerRemark = server.Remark;
|
||||
ModeRemark = mode.Remark;
|
||||
ModeRemark = mode.i18NRemark;
|
||||
ProfileName = name;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Utils;
|
||||
@@ -42,11 +42,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 代理类型
|
||||
/// </summary>
|
||||
public virtual string Type { get; } = string.Empty;
|
||||
|
||||
[JsonExtensionData]
|
||||
// ReSharper disable once CollectionNeverUpdated.Global
|
||||
public Dictionary<string, object> ExtensionData { get; set; } = new();
|
||||
public abstract string Type { get; }
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
@@ -61,7 +57,7 @@ namespace Netch.Models
|
||||
{
|
||||
var remark = string.IsNullOrWhiteSpace(Remark) ? $"{Hostname}:{Port}" : Remark;
|
||||
|
||||
var shortName = Type.IsNullOrEmpty() ? "WTF" : ServerHelper.GetUtilByTypeName(Type).ShortName;
|
||||
var shortName = ServerHelper.GetUtilByTypeName(Type).ShortName;
|
||||
|
||||
return $"[{shortName}][{Group}] {remark}";
|
||||
}
|
||||
@@ -113,9 +109,10 @@ namespace Netch.Models
|
||||
|
||||
public static class ServerExtension
|
||||
{
|
||||
public static async Task<string> AutoResolveHostnameAsync(this Server server)
|
||||
public static async Task<string> AutoResolveHostnameAsync(this Server server, AddressFamily inet = AddressFamily.Unspecified)
|
||||
{
|
||||
return Global.Settings.ResolveServerHostname ? (await DnsUtils.LookupAsync(server.Hostname))!.ToString() : server.Hostname;
|
||||
// ! MainController cached
|
||||
return (await DnsUtils.LookupAsync(server.Hostname, inet))!.ToString();
|
||||
}
|
||||
|
||||
public static bool IsInGroup(this Server server)
|
||||
|
||||
11
Netch/Models/Settings/AioDNSConfig.cs
Normal file
11
Netch/Models/Settings/AioDNSConfig.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class AioDNSConfig
|
||||
{
|
||||
public string ChinaDNS { get; set; } = $"tcp://{Constants.DefaultCNPrimaryDNS}";
|
||||
|
||||
public string OtherDNS { get; set; } = $"tcp://{Constants.DefaultPrimaryDNS}";
|
||||
|
||||
public ushort ListenPort { get; set; } = 253;
|
||||
}
|
||||
}
|
||||
19
Netch/Models/Settings/KcpConfig.cs
Normal file
19
Netch/Models/Settings/KcpConfig.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class KcpConfig
|
||||
{
|
||||
public bool congestion { get; set; } = false;
|
||||
|
||||
public int downlinkCapacity { get; set; } = 100;
|
||||
|
||||
public int mtu { get; set; } = 1350;
|
||||
|
||||
public int readBufferSize { get; set; } = 2;
|
||||
|
||||
public int tti { get; set; } = 50;
|
||||
|
||||
public int uplinkCapacity { get; set; } = 12;
|
||||
|
||||
public int writeBufferSize { get; set; } = 2;
|
||||
}
|
||||
}
|
||||
23
Netch/Models/Settings/RedirectorConfig.cs
Normal file
23
Netch/Models/Settings/RedirectorConfig.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class RedirectorConfig
|
||||
{
|
||||
public bool FilterTCP { get; set; } = true;
|
||||
|
||||
public bool FilterUDP { get; set; } = true;
|
||||
|
||||
public bool FilterDNS { get; set; } = true;
|
||||
|
||||
public bool FilterParent { get; set; } = false;
|
||||
|
||||
public bool HandleOnlyDNS { get; set; } = true;
|
||||
|
||||
public bool DNSProxy { get; set; } = true;
|
||||
|
||||
public string DNSHost { get; set; } = Constants.DefaultPrimaryDNS;
|
||||
|
||||
public int ICMPDelay { get; set; } = 10;
|
||||
|
||||
public bool FilterICMP { get; set; } = false;
|
||||
}
|
||||
}
|
||||
@@ -1,122 +1,10 @@
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// TUN/TAP 适配器配置类
|
||||
/// </summary>
|
||||
public class TUNConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
public string Address { get; set; } = "10.0.236.10";
|
||||
|
||||
/// <summary>
|
||||
/// DNS
|
||||
/// </summary>
|
||||
public string HijackDNS { get; set; } = "tcp://1.1.1.1:53";
|
||||
|
||||
/// <summary>
|
||||
/// 网关
|
||||
/// </summary>
|
||||
public string Gateway { get; set; } = "10.0.236.1";
|
||||
|
||||
/// <summary>
|
||||
/// 掩码
|
||||
/// </summary>
|
||||
public string Netmask { get; set; } = "255.255.255.0";
|
||||
|
||||
/// <summary>
|
||||
/// 模式 2 下是否代理 DNS
|
||||
/// </summary>
|
||||
public bool ProxyDNS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 使用自定义 DNS 设置
|
||||
/// </summary>
|
||||
public bool UseCustomDNS { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 全局绕过 IP 列表
|
||||
/// </summary>
|
||||
public List<string> BypassIPs { get; set; } = new();
|
||||
}
|
||||
|
||||
public class KcpConfig
|
||||
{
|
||||
public bool congestion { get; set; } = false;
|
||||
|
||||
public int downlinkCapacity { get; set; } = 100;
|
||||
|
||||
public int mtu { get; set; } = 1350;
|
||||
|
||||
public int readBufferSize { get; set; } = 2;
|
||||
|
||||
public int tti { get; set; } = 50;
|
||||
|
||||
public int uplinkCapacity { get; set; } = 12;
|
||||
|
||||
public int writeBufferSize { get; set; } = 2;
|
||||
}
|
||||
|
||||
public class V2rayConfig
|
||||
{
|
||||
public bool AllowInsecure { get; set; } = false;
|
||||
|
||||
public KcpConfig KcpConfig { get; set; } = new();
|
||||
|
||||
public bool UseMux { get; set; } = false;
|
||||
|
||||
public bool V2rayNShareLink { get; set; } = true;
|
||||
|
||||
public bool XrayCone { get; set; } = false;
|
||||
}
|
||||
|
||||
public class AioDNSConfig
|
||||
{
|
||||
public string ChinaDNS { get; set; } = "tcp://223.5.5.5:53";
|
||||
|
||||
public string OtherDNS { get; set; } = "tcp://1.1.1.1:53";
|
||||
|
||||
public ushort ListenPort { get; set; } = 253;
|
||||
}
|
||||
|
||||
public class RedirectorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 不代理TCP
|
||||
/// </summary>
|
||||
public PortType FilterProtocol { 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";
|
||||
|
||||
[JsonIgnore]
|
||||
public int ICMPDelay { get; } = 0;
|
||||
|
||||
public bool FilterICMP { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否使用RDR内置SS
|
||||
/// </summary>
|
||||
public bool RedirectorSS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否代理子进程
|
||||
/// </summary>
|
||||
public bool ChildProcessHandle { get; set; } = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于读取和写入的配置的类
|
||||
/// </summary>
|
||||
@@ -196,11 +84,6 @@ namespace Netch.Models
|
||||
/// </summary>
|
||||
public int RequestTimeout { get; set; } = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// 解析服务器主机名
|
||||
/// </summary>
|
||||
public bool ResolveServerHostname { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否开机启动软件
|
||||
/// </summary>
|
||||
@@ -249,7 +132,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 订阅链接列表
|
||||
/// </summary>
|
||||
public List<SubscribeLink> SubscribeLink { get; set; } = new();
|
||||
public List<Subscription> Subscription { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// TUNTAP 适配器配置
|
||||
@@ -263,7 +146,23 @@ namespace Netch.Models
|
||||
|
||||
public V2rayConfig V2RayConfig { get; set; } = new();
|
||||
|
||||
public Setting Clone()
|
||||
public bool NoSupportDialog { get; set; } = false;
|
||||
|
||||
#region Migration
|
||||
|
||||
[Obsolete]
|
||||
public JsonElement SubscribeLink
|
||||
{
|
||||
set
|
||||
{
|
||||
if (Subscription == null! || !Subscription.Any())
|
||||
Subscription = value.Deserialize<List<Subscription>>()!;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Setting ShallowCopy()
|
||||
{
|
||||
return (Setting)MemberwiseClone();
|
||||
}
|
||||
45
Netch/Models/Settings/TUNConfig.cs
Normal file
45
Netch/Models/Settings/TUNConfig.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// TUN/TAP 适配器配置类
|
||||
/// </summary>
|
||||
public class TUNConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
public string Address { get; set; } = "10.0.236.10";
|
||||
|
||||
/// <summary>
|
||||
/// DNS
|
||||
/// </summary>
|
||||
public string HijackDNS { get; set; } = $"tcp://{Constants.DefaultPrimaryDNS}";
|
||||
|
||||
/// <summary>
|
||||
/// 网关
|
||||
/// </summary>
|
||||
public string Gateway { get; set; } = "10.0.236.1";
|
||||
|
||||
/// <summary>
|
||||
/// 掩码
|
||||
/// </summary>
|
||||
public string Netmask { get; set; } = "255.255.255.0";
|
||||
|
||||
/// <summary>
|
||||
/// 模式 2 下是否代理 DNS
|
||||
/// </summary>
|
||||
public bool ProxyDNS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 使用自定义 DNS 设置
|
||||
/// </summary>
|
||||
public bool UseCustomDNS { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Global bypass IPs
|
||||
/// </summary>
|
||||
public List<string> BypassIPs { get; set; } = new();
|
||||
}
|
||||
}
|
||||
15
Netch/Models/Settings/V2rayConfig.cs
Normal file
15
Netch/Models/Settings/V2rayConfig.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class V2rayConfig
|
||||
{
|
||||
public bool AllowInsecure { get; set; } = false;
|
||||
|
||||
public KcpConfig KcpConfig { get; set; } = new();
|
||||
|
||||
public bool UseMux { get; set; } = false;
|
||||
|
||||
public bool V2rayNShareLink { get; set; } = true;
|
||||
|
||||
public bool XrayCone { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class SubscribeLink
|
||||
public class Subscription
|
||||
{
|
||||
/// <summary>
|
||||
/// 启用状态
|
||||
@@ -1,30 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>true</UseWPF>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<StartupObject>Netch.Netch</StartupObject>
|
||||
<ApplicationManifest>App.manifest</ApplicationManifest>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<ApplicationIcon>Resources\Netch.ico</ApplicationIcon>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NoWarn>VSTHRD100</NoWarn>
|
||||
<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>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
@@ -39,57 +32,47 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HMBSbige.SingleInstance" Version="5.0.7" />
|
||||
<PackageReference Include="MaxMind.GeoIP2" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.70" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="16.10.56" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.506-beta">
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.73" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.0.63" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.588-beta">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Nullable.Extended.Analyzer" Version="1.2.4089">
|
||||
<PackageReference Include="Nullable.Extended.Analyzer" Version="1.10.4539">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Debug" Version="2.0.0" Condition="'$(Configuration)'=='Debug'" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.2" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
|
||||
<PackageReference Include="Stun.Net" Version="5.0.0" />
|
||||
<PackageReference Include="System.Management" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.9.1" />
|
||||
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
|
||||
<PackageReference Include="WindowsFirewallHelper" Version="2.0.4.70-beta2" />
|
||||
<PackageReference Include="System.Text.Json" Version="6.0.0-rc.2.21480.5" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.9.2" />
|
||||
<PackageReference Include="WindowsFirewallHelper" Version="2.1.4.81" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Forms\Mode\RouteForm.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Forms\SyncGlobalCheckBox.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Remove="NativeMethods.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Condition="'$(PublishSingleFile)' == 'true'" AfterTargets="_ComputeFilesToBundle" Name="RemoveDupeAssemblies">
|
||||
|
||||
@@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
@@ -10,6 +12,7 @@ using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
using Netch.Controllers;
|
||||
using Netch.Enums;
|
||||
using Netch.Forms;
|
||||
using Netch.Services;
|
||||
using Netch.Utils;
|
||||
@@ -22,9 +25,9 @@ using Windows.Win32.UI.WindowsAndMessaging;
|
||||
|
||||
namespace Netch
|
||||
{
|
||||
public static class Netch
|
||||
public static class Program
|
||||
{
|
||||
public static readonly SingleInstanceService SingleInstance = new($"Global\\{nameof(Netch)}");
|
||||
public static readonly SingleInstanceService SingleInstance = new($"Global\\{nameof(Program)}");
|
||||
|
||||
internal static HWND ConsoleHwnd { get; private set; }
|
||||
|
||||
@@ -42,6 +45,13 @@ namespace Netch
|
||||
var binPath = Path.Combine(Global.NetchDir, "bin");
|
||||
Environment.SetEnvironmentVariable("PATH", $"{Environment.GetEnvironmentVariable("PATH")};{binPath}");
|
||||
|
||||
if (!Directory.Exists("bin") || !Directory.EnumerateFileSystemEntries("bin").Any())
|
||||
{
|
||||
i18N.Load("System");
|
||||
MessageBoxX.Show(i18N.Translate("Please extract all files then run the program!"));
|
||||
Environment.Exit(2);
|
||||
}
|
||||
|
||||
Updater.CleanOld(Global.NetchDir);
|
||||
|
||||
// 预创建目录
|
||||
@@ -83,13 +93,9 @@ namespace Netch
|
||||
// 加载语言
|
||||
i18N.Load(Global.Settings.Language);
|
||||
|
||||
if (!Directory.Exists("bin") || !Directory.EnumerateFileSystemEntries("bin").Any())
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please extract all files then run the program!"));
|
||||
Environment.Exit(2);
|
||||
}
|
||||
|
||||
Task.Run(LogEnvironment).Forget();
|
||||
CheckClr();
|
||||
CheckOS();
|
||||
|
||||
// 绑定错误捕获
|
||||
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
||||
@@ -105,11 +111,54 @@ namespace Netch
|
||||
private static void LogEnvironment()
|
||||
{
|
||||
Log.Information("Netch Version: {Version}", $"{UpdateChecker.Owner}/{UpdateChecker.Repo}@{UpdateChecker.Version}");
|
||||
Log.Information("Environment: {OSVersion}", Environment.OSVersion);
|
||||
Log.Information("OS: {OSVersion}", Environment.OSVersion);
|
||||
Log.Information("SHA256: {Hash}", $"{Utils.Utils.SHA256CheckSum(Global.NetchExecutable)}");
|
||||
Log.Information("System Language: {Language}", CultureInfo.CurrentCulture.Name);
|
||||
|
||||
#if RELEASE
|
||||
if (Log.IsEnabled(LogEventLevel.Debug))
|
||||
Log.Debug("Third-party Drivers:\n{Drivers}", string.Join("\n", SystemInfo.SystemDrivers(false)));
|
||||
{
|
||||
// TODO log level setting
|
||||
Task.Run(() => Log.Debug("Third-party Drivers:\n{Drivers}", string.Join(Constants.EOF, SystemInfo.SystemDrivers(false)))).Forget();
|
||||
Task.Run(() => Log.Debug("Running Processes: \n{Processes}", string.Join(Constants.EOF, SystemInfo.Processes(false)))).Forget();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void CheckClr()
|
||||
{
|
||||
var framework = Assembly.GetExecutingAssembly().GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
|
||||
if (framework == null)
|
||||
{
|
||||
Log.Warning("TargetFrameworkAttribute null");
|
||||
return;
|
||||
}
|
||||
|
||||
var frameworkName = new FrameworkName(framework);
|
||||
|
||||
if (frameworkName.Version.Major != Environment.Version.Major)
|
||||
{
|
||||
Log.Information("CLR: {Version}", Environment.Version);
|
||||
Flags.NoSupport = true;
|
||||
if (!Global.Settings.NoSupportDialog)
|
||||
MessageBoxX.Show(
|
||||
i18N.TranslateFormat("{0} won't get developers' support, Please do not report any issues or seek help from developers.",
|
||||
"CLR " + Environment.Version),
|
||||
LogLevel.WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckOS()
|
||||
{
|
||||
if (Environment.OSVersion.Version.Build < 17763)
|
||||
{
|
||||
Flags.NoSupport = true;
|
||||
if (!Global.Settings.NoSupportDialog)
|
||||
MessageBoxX.Show(
|
||||
i18N.TranslateFormat("{0} won't get developers' support, Please do not report any issues or seek help from developers.",
|
||||
Environment.OSVersion),
|
||||
LogLevel.WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitConsole()
|
||||
@@ -127,13 +176,13 @@ namespace Netch
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
#if DEBUG
|
||||
.MinimumLevel.Verbose()
|
||||
.WriteTo.Async(c => c.Debug(outputTemplate: Constants.OutputTemplate))
|
||||
#else
|
||||
.MinimumLevel.Debug()
|
||||
#endif
|
||||
.WriteTo.Async(c => c.File(Path.Combine(Global.NetchDir, Constants.LogFile),
|
||||
outputTemplate: Constants.OutputTemplate,
|
||||
rollOnFileSizeLimit: false))
|
||||
.WriteTo.Console(outputTemplate: Constants.OutputTemplate)
|
||||
.MinimumLevel.Override(@"Microsoft", LogEventLevel.Information)
|
||||
.Enrich.FromLogContext()
|
||||
.CreateLogger();
|
||||
@@ -141,7 +190,7 @@ namespace Netch
|
||||
|
||||
private static void Application_OnException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
Log.Error(e.Exception, "未处理异常");
|
||||
Log.Error(e.Exception, "Unhandled error");
|
||||
}
|
||||
|
||||
private static void Application_OnExit(object? sender, EventArgs eventArgs)
|
||||
@@ -1,6 +1,6 @@
|
||||
using Netch.Controllers;
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Netch.Controllers;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
@@ -13,9 +13,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyCopyright(UpdateChecker.Copyright)]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
#if NET
|
||||
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
|
||||
#endif
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
|
||||
26
Netch/Properties/Settings.Designer.cs
generated
26
Netch/Properties/Settings.Designer.cs
generated
@@ -1,26 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Netch.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -15,12 +15,12 @@
|
||||
"Stopping": "正在停止中",
|
||||
"Stopped": "已停止",
|
||||
"Starting {0}": "正在启动 {0}",
|
||||
"Testing NAT": "正在测试 NAT",
|
||||
"Testing NAT Type": "正在测试 NAT 类型",
|
||||
"Setup Route Table Rule": "配置路由规则",
|
||||
"Test failed": "测试失败",
|
||||
"Starting update subscription": "正在更新订阅",
|
||||
"Subscription updated": "订阅更新完毕",
|
||||
"Register driver": "正在注册驱动",
|
||||
"Updating servers": "正在更新服务器",
|
||||
"Servers updated": "服务器更新完毕",
|
||||
"Installing netfilter2 driver": "正在安装 netfilter2 驱动",
|
||||
|
||||
"Server": "服务器",
|
||||
"Import Servers From Clipboard": "从剪贴板导入服务器",
|
||||
@@ -28,10 +28,10 @@
|
||||
"Netch is now minimized to the notification bar, double click this icon to restore.": "Netch 已最小化至通知栏,双击此图标恢复窗口",
|
||||
"New version available": "发现新版本",
|
||||
"Already latest version": "已经是最新版本",
|
||||
"New version found failed": "寻找新版本失败",
|
||||
"Check for update failed": "检查更新失败",
|
||||
"Mode": "模式",
|
||||
"Help": "帮助",
|
||||
"Check for updates": "检查更新",
|
||||
"Check for update": "检查更新",
|
||||
"Download and install now?": "立即下载并安装?",
|
||||
"Start downloading new version": "开始下载新版本",
|
||||
"Download update failed": "下载更新错误",
|
||||
@@ -39,6 +39,10 @@
|
||||
"Edit Process Mode": "修改进程模式",
|
||||
"Create Route Table Rule": "创建路由表规则",
|
||||
"Edit Route Table Rule": "修改路由表规则",
|
||||
"Reload Modes": "重新加载模式",
|
||||
"Handle rules": "处理规则",
|
||||
"Bypass rules": "分流规则",
|
||||
"Handle DNS through proxy": "经过代理处理 DNS",
|
||||
|
||||
"Address": "地址",
|
||||
"Username": "用户名",
|
||||
@@ -64,16 +68,16 @@
|
||||
"Plugin": "插件",
|
||||
"Plugin Options": "插件参数",
|
||||
|
||||
"Subscribe": "订阅",
|
||||
"Manage Subscribe Links": "管理订阅链接",
|
||||
"Update Servers From Subscribe Links": "从订阅链接更新服务器",
|
||||
"Subscription": "订阅",
|
||||
"Manage Subscriptions": "管理订阅",
|
||||
"Update Servers": "更新服务器",
|
||||
"No subscription link": "没有任何一条订阅链接",
|
||||
"Updating {0}": "正在更新 {0}",
|
||||
"Update {1} server(s) from {0}": "从 {0} 更新 {1} 个服务器",
|
||||
"Update servers error from {0}": "从 {0} 更新服务器失败",
|
||||
"Update {1} server(s) from {0}": "从 {0} 更新了 {1} 个服务器",
|
||||
"Update servers failed from {0}": "从 {0} 更新服务器失败",
|
||||
"Confirm deletion?": "确认删除?",
|
||||
"DeleteServer": "删除订阅节点",
|
||||
"CopyLink": "复制链接",
|
||||
"Delete Servers": "删除订阅节点",
|
||||
"Copy link": "复制链接",
|
||||
"Status": "状态",
|
||||
"Link": "链接",
|
||||
"Unselect": "取消选择",
|
||||
@@ -103,17 +107,20 @@
|
||||
"Please select a mode first": "请先选择一个模式",
|
||||
"Please enter a profile name first": "请先为该配置设置一个名称",
|
||||
"No saved profile here. Save a profile first by Ctrl+Click on the button": "当前按钮下没有保存配置,请先使用 CTRL + 左键 点击该按钮保存一个配置",
|
||||
"Lookup Server hostname failed": "解析服务器主机名失败",
|
||||
|
||||
"Used": "已使用",
|
||||
"Testing": "测试中",
|
||||
|
||||
"Remark": "备注",
|
||||
"Filename": "文件名",
|
||||
"Use Custom Filename": "使用自定义文件名",
|
||||
"Add": "添加",
|
||||
"Scan": "扫描",
|
||||
"Save": "保存",
|
||||
"Modify": "修改",
|
||||
"Select": "选择",
|
||||
"Validation": "验证",
|
||||
"Action": "动作",
|
||||
"Select a folder": "选择一个目录",
|
||||
"Please enter an process name (xxx.exe)": "请输入一个进程名(xxx.exe)",
|
||||
"Rule does not conform to C++ regular expression syntax": "规则不符合 C++ 正则表达式语法",
|
||||
@@ -124,6 +131,7 @@
|
||||
"Please enter a mode remark": "请输入模式的备注",
|
||||
"File already exists.\n Please Change the filename": "文件名已存在,请修改文件名",
|
||||
"Please enter a mode filename": "请输入模式的文件名",
|
||||
"Above rules does not conform to C++ regular expression syntax": "以上规则不符合 C++ 正则表达式语法",
|
||||
|
||||
"Proxy Rule IPs": "代理规则 IP",
|
||||
"Bypass Rule IPs": "绕过规则 IP",
|
||||
@@ -132,6 +140,7 @@
|
||||
"Delete or not ? Will clean up the corresponding group of items in the server list": "是否删除?将会清理服务器列表中对应组的项目",
|
||||
"Remark can not be empty": "备注不可为空",
|
||||
"Link can not be empty": "链接不可为空",
|
||||
"Subscription with the specified remark already exists": "带有指定备注的订阅已存在",
|
||||
"Link must start with http:// or https://": "链接必须以 http:// 或 https:// 开头",
|
||||
|
||||
"Settings": "设置",
|
||||
@@ -142,7 +151,7 @@
|
||||
"Allow other Devices to connect": "允许其他设备连入",
|
||||
"Netmask": "子网掩码",
|
||||
"Gateway": "网关",
|
||||
"Use Custom DNS": "使用自定义 DNS",
|
||||
"Use custom DNS": "使用自定义 DNS",
|
||||
"Proxy DNS in Proxy Rule IPs Mode": "在 代理规则IP 模式下代理 DNS",
|
||||
"Exit when closed": "关闭时退出",
|
||||
"Stop when exited": "退出时停止",
|
||||
@@ -150,19 +159,24 @@
|
||||
"Check update when opened": "打开软件时检查更新",
|
||||
"Check Beta update": "检查 Beta 更新",
|
||||
"Update Servers when opened": "打开软件时更新服务器",
|
||||
"Filter Protocol": "Filter 协议",
|
||||
"Handle process's DNS Hijack": "被代理进程 DNS 劫持",
|
||||
"Child Process Handle": "子进程代理",
|
||||
"ICMP Delay(ms)": "ICMP 延迟(毫秒)",
|
||||
"Redirector built-in Shadowsocks support": "Redirector 内建 Shadowsocks 支持",
|
||||
"Handle ICMP": "处理 ICMP",
|
||||
"Handle TCP": "处理 TCP",
|
||||
"Handle UDP": "处理 UDP",
|
||||
"Handle DNS (DNS hijacking)": "处理 DNS(DNS 劫持)",
|
||||
"Handle handled process's DNS": "处理被处理进程 DNS",
|
||||
"Handle local loopback": "处理本地回环",
|
||||
"Handle LAN": "处理局域网",
|
||||
"Handle child process": "处理子进程",
|
||||
"ICMP delay(ms)": "ICMP 延迟(毫秒)",
|
||||
"Mode specific options": "模式专用设置",
|
||||
"Profile Count": "快捷配置数量",
|
||||
"Delay test after start(sec)": "启动后延迟测试(秒)",
|
||||
"Ping Protocol": "延迟测试协议",
|
||||
"Detection Tick(sec)": "检测心跳(秒)",
|
||||
"STUN Server": "STUN 服务器",
|
||||
"Language": "语言",
|
||||
"Resolve Server Hostname": "解析服务器主机名",
|
||||
"FullCone Support (Required Server Xray-core v1.3.0+)": "FullCone 支持(需服务端 Xray-core v1.3.0+)",
|
||||
"Disable Support Warning": "停用支持警告",
|
||||
|
||||
"Profile": "配置名",
|
||||
"Profiles": "配置",
|
||||
@@ -172,5 +186,8 @@
|
||||
"Exit": "退出",
|
||||
|
||||
"The {0} port is in use.": "{0} 端口已被占用",
|
||||
"The {0} port is reserved by system.": "{0} 端口是系统保留端口"
|
||||
"The {0} port is reserved by system.": "{0} 端口是系统保留端口",
|
||||
|
||||
"{0} won't get developers' support, Please do not report any issues or seek help from developers.": "{0} 将不会得到开发者的支持,请不要报告任何问题或寻求开发人员的帮助。",
|
||||
"No Support": "不受支持"
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers.Shadowsocks
|
||||
{
|
||||
public class SSController : Guard, IServerController
|
||||
{
|
||||
public SSController() : base("Shadowsocks.exe")
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords => new[] { "listening at" };
|
||||
|
||||
protected override IEnumerable<string> FailedKeywords => new[] { "Invalid config path", "usage", "plugin service exit unexpectedly" };
|
||||
|
||||
public override string Name => "Shadowsocks";
|
||||
|
||||
public ushort? Socks5LocalPort { get; set; }
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public async Task<Socks5> StartAsync(Server s)
|
||||
{
|
||||
var server = (Shadowsocks)s;
|
||||
|
||||
var command = new SSParameter
|
||||
{
|
||||
s = await server.AutoResolveHostnameAsync(),
|
||||
p = server.Port,
|
||||
b = this.LocalAddress(),
|
||||
l = this.Socks5LocalPort(),
|
||||
m = server.EncryptMethod,
|
||||
k = server.Password,
|
||||
u = true,
|
||||
plugin = server.Plugin,
|
||||
plugin_opts = server.PluginOption
|
||||
};
|
||||
|
||||
await StartGuardAsync(command.ToString());
|
||||
return new Socks5Bridge(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), server.Hostname);
|
||||
}
|
||||
|
||||
[Verb]
|
||||
private class SSParameter : ParameterBase
|
||||
{
|
||||
public string? s { get; set; }
|
||||
|
||||
public ushort? p { get; set; }
|
||||
|
||||
public string? b { get; set; }
|
||||
|
||||
public ushort? l { get; set; }
|
||||
|
||||
public string? m { get; set; }
|
||||
|
||||
public string? k { get; set; }
|
||||
|
||||
public bool u { get; set; }
|
||||
|
||||
[Full] [Optional] public string? plugin { get; set; }
|
||||
|
||||
[Full]
|
||||
[Optional]
|
||||
[RealName("plugin-opts")]
|
||||
public string? plugin_opts { get; set; }
|
||||
|
||||
[Full] [Quote] [Optional] public string? acl { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Netch/Servers/Shadowsocks/ShadowsocksController.cs
Normal file
44
Netch/Servers/Shadowsocks/ShadowsocksController.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class ShadowsocksController : Guard, IServerController
|
||||
{
|
||||
public ShadowsocksController() : base("Shadowsocks.exe")
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords => new[] { "listening at" };
|
||||
|
||||
protected override IEnumerable<string> FailedKeywords => new[] { "error", "failed to start plguin" };
|
||||
|
||||
public override string Name => "Shadowsocks";
|
||||
|
||||
public ushort? Socks5LocalPort { get; set; }
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public async Task<Socks5LocalServer> StartAsync(Server s)
|
||||
{
|
||||
var server = (ShadowsocksServer)s;
|
||||
|
||||
var arguments = new object?[]
|
||||
{
|
||||
"-s", $"{await server.AutoResolveHostnameAsync()}:{server.Port}",
|
||||
"-b", $"{this.LocalAddress()}:{this.Socks5LocalPort()}",
|
||||
"-m", server.EncryptMethod,
|
||||
"-k", server.Password,
|
||||
"--plugin", server.Plugin,
|
||||
"--plugin-opts", server.PluginOption
|
||||
};
|
||||
|
||||
await StartGuardAsync(Arguments.Format(arguments));
|
||||
return new Socks5LocalServer(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), server.Hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Servers.Shadowsocks.Form
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class ShadowsocksForm : ServerForm
|
||||
{
|
||||
public ShadowsocksForm(Shadowsocks? server = default)
|
||||
public ShadowsocksForm(ShadowsocksServer? server = default)
|
||||
{
|
||||
server ??= new Shadowsocks();
|
||||
server ??= new ShadowsocksServer();
|
||||
Server = server;
|
||||
CreateTextBox("Password", "Password", s => !s.IsNullOrWhiteSpace(), s => server.Password = s, server.Password);
|
||||
CreateComboBox("EncryptMethod", "Encrypt Method", SSGlobal.EncryptMethods, s => server.EncryptMethod = s, server.EncryptMethod);
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers.Shadowsocks
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class Shadowsocks : Server
|
||||
public class ShadowsocksServer : Server
|
||||
{
|
||||
public override string Type { get; } = "SS";
|
||||
public override string MaskedData()
|
||||
@@ -6,14 +6,12 @@ using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Shadowsocks.Form;
|
||||
using Netch.Servers.Shadowsocks.Models.SSD;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
|
||||
namespace Netch.Servers.Shadowsocks
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class SSUtil : IServerUtil
|
||||
public class ShadowsocksUtil : IServerUtil
|
||||
{
|
||||
public ushort Priority { get; } = 1;
|
||||
|
||||
@@ -25,11 +23,11 @@ namespace Netch.Servers.Shadowsocks
|
||||
|
||||
public string[] UriScheme { get; } = { "ss", "ssd" };
|
||||
|
||||
public Type ServerType { get; } = typeof(Shadowsocks);
|
||||
public Type ServerType { get; } = typeof(ShadowsocksServer);
|
||||
|
||||
public void Edit(Server s)
|
||||
{
|
||||
new ShadowsocksForm((Shadowsocks)s).ShowDialog();
|
||||
new ShadowsocksForm((ShadowsocksServer)s).ShowDialog();
|
||||
}
|
||||
|
||||
public void Create()
|
||||
@@ -39,7 +37,7 @@ namespace Netch.Servers.Shadowsocks
|
||||
|
||||
public string GetShareLink(Server s)
|
||||
{
|
||||
var server = (Shadowsocks)s;
|
||||
var server = (ShadowsocksServer)s;
|
||||
// ss://method:password@server:port#Remark
|
||||
return "ss://" + ShareLink.URLSafeBase64Encode($"{server.EncryptMethod}:{server.Password}@{server.Hostname}:{server.Port}") + "#" +
|
||||
HttpUtility.UrlEncode(server.Remark);
|
||||
@@ -47,7 +45,7 @@ namespace Netch.Servers.Shadowsocks
|
||||
|
||||
public IServerController GetController()
|
||||
{
|
||||
return new SSController();
|
||||
return new ShadowsocksController();
|
||||
}
|
||||
|
||||
public IEnumerable<Server> ParseUri(string text)
|
||||
@@ -63,10 +61,10 @@ namespace Netch.Servers.Shadowsocks
|
||||
|
||||
public bool CheckServer(Server s)
|
||||
{
|
||||
var server = (Shadowsocks)s;
|
||||
var server = (ShadowsocksServer)s;
|
||||
if (!SSGlobal.EncryptMethods.Contains(server.EncryptMethod))
|
||||
{
|
||||
Log.Warning("不支持的 SS 加密方式:{Method}", server.EncryptMethod);
|
||||
Log.Warning("Unsupported SS Encrypt Method: {Method}", server.EncryptMethod);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -75,9 +73,9 @@ namespace Netch.Servers.Shadowsocks
|
||||
|
||||
public IEnumerable<Server> ParseSsdUri(string s)
|
||||
{
|
||||
var json = JsonSerializer.Deserialize<Main>(ShareLink.URLSafeBase64Decode(s.Substring(6)))!;
|
||||
var json = JsonSerializer.Deserialize<SSDJObject>(ShareLink.URLSafeBase64Decode(s.Substring(6)))!;
|
||||
|
||||
return json.servers.Select(server => new Shadowsocks
|
||||
return json.servers.Select(server => new ShadowsocksServer
|
||||
{
|
||||
Remark = server.remarks,
|
||||
Hostname = server.server,
|
||||
@@ -92,9 +90,9 @@ namespace Netch.Servers.Shadowsocks
|
||||
.Where(CheckServer);
|
||||
}
|
||||
|
||||
public Shadowsocks ParseSsUri(string text)
|
||||
public ShadowsocksServer ParseSsUri(string text)
|
||||
{
|
||||
var data = new Shadowsocks();
|
||||
var data = new ShadowsocksServer();
|
||||
|
||||
text = text.Replace("/?", "?");
|
||||
if (text.Contains("#"))
|
||||
@@ -1,9 +1,9 @@
|
||||
#nullable disable
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Servers.Shadowsocks.Models.SSD
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class Main
|
||||
public class SSDJObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 机场名
|
||||
@@ -38,6 +38,6 @@ namespace Netch.Servers.Shadowsocks.Models.SSD
|
||||
/// <summary>
|
||||
/// 服务器数组
|
||||
/// </summary>
|
||||
public List<SSDServer> servers;
|
||||
public List<SSDServerJObject> servers;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#nullable disable
|
||||
namespace Netch.Servers.Shadowsocks.Models.SSD
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class SSDServer
|
||||
public class SSDServerJObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 加密方式
|
||||
@@ -1,6 +1,10 @@
|
||||
#nullable disable
|
||||
namespace Netch.Servers.Shadowsocks.Models
|
||||
namespace Netch.Servers
|
||||
{
|
||||
/// <summary>
|
||||
/// Import Shadowsocks Server from Json Configuration
|
||||
/// <see cref="Utils.ShareLink.ParseText"/>
|
||||
/// </summary>
|
||||
public class ShadowsocksConfig
|
||||
{
|
||||
public string server { get; set; }
|
||||
@@ -1,88 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers.ShadowsocksR
|
||||
{
|
||||
public class SSRController : Guard, IServerController
|
||||
{
|
||||
public SSRController() : base("ShadowsocksR.exe")
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords => new[] { "listening at" };
|
||||
|
||||
protected override IEnumerable<string> FailedKeywords => new[] { "Invalid config path", "usage" };
|
||||
|
||||
public override string Name => "ShadowsocksR";
|
||||
|
||||
public ushort? Socks5LocalPort { get; set; }
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public async Task<Socks5> StartAsync(Server s)
|
||||
{
|
||||
var server = (ShadowsocksR)s;
|
||||
|
||||
var command = new SSRParameter
|
||||
{
|
||||
s = await server.AutoResolveHostnameAsync(),
|
||||
p = server.Port,
|
||||
k = server.Password,
|
||||
m = server.EncryptMethod,
|
||||
t = "120",
|
||||
O = server.Protocol,
|
||||
G = server.ProtocolParam,
|
||||
o = server.OBFS,
|
||||
g = server.OBFSParam,
|
||||
b = this.LocalAddress(),
|
||||
l = this.Socks5LocalPort(),
|
||||
u = true
|
||||
};
|
||||
|
||||
await StartGuardAsync(command.ToString());
|
||||
return new Socks5Bridge(IPAddress.Loopback.ToString(), this.Socks5LocalPort(),server.Hostname);
|
||||
}
|
||||
|
||||
[Verb]
|
||||
class SSRParameter : ParameterBase
|
||||
{
|
||||
public string? s { get; set; }
|
||||
|
||||
public ushort? p { get; set; }
|
||||
|
||||
[Quote]
|
||||
public string? k { get; set; }
|
||||
|
||||
public string? m { get; set; }
|
||||
|
||||
public string? t { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? O { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? G { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? o { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? g { get; set; }
|
||||
|
||||
public string? b { get; set; }
|
||||
|
||||
public ushort? l { get; set; }
|
||||
|
||||
public bool u { get; set; }
|
||||
|
||||
[Full]
|
||||
[Quote]
|
||||
[Optional]
|
||||
public string? acl { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
50
Netch/Servers/ShadowsocksR/ShadowsocksRController.cs
Normal file
50
Netch/Servers/ShadowsocksR/ShadowsocksRController.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class ShadowsocksRController : Guard, IServerController
|
||||
{
|
||||
public ShadowsocksRController() : base("ShadowsocksR.exe")
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords => new[] { "listening at" };
|
||||
|
||||
protected override IEnumerable<string> FailedKeywords => new[] { "Invalid config path", "usage" };
|
||||
|
||||
public override string Name => "ShadowsocksR";
|
||||
|
||||
public ushort? Socks5LocalPort { get; set; }
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public async Task<Socks5LocalServer> StartAsync(Server s)
|
||||
{
|
||||
var server = (ShadowsocksRServer)s;
|
||||
|
||||
var arguments = new object?[]
|
||||
{
|
||||
"-s", await server.AutoResolveHostnameAsync(),
|
||||
"-p", server.Port,
|
||||
"-k", server.Password,
|
||||
"-m", server.EncryptMethod,
|
||||
"-t", 120,
|
||||
"-O", server.Protocol,
|
||||
"-G", server.ProtocolParam,
|
||||
"-o", server.OBFS,
|
||||
"-g", server.OBFSParam,
|
||||
"-b", this.LocalAddress(),
|
||||
"-l", this.Socks5LocalPort(),
|
||||
"-u", SpecialArgument.Flag
|
||||
};
|
||||
|
||||
await StartGuardAsync(Arguments.Format(arguments));
|
||||
return new Socks5LocalServer(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), server.Hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Servers.ShadowsocksR.Form
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class ShadowsocksRForm : ServerForm
|
||||
{
|
||||
public ShadowsocksRForm(ShadowsocksR? server = default)
|
||||
public ShadowsocksRForm(ShadowsocksRServer? server = default)
|
||||
{
|
||||
server ??= new ShadowsocksR();
|
||||
server ??= new ShadowsocksRServer();
|
||||
Server = server;
|
||||
CreateTextBox("Password", "Password", s => !s.IsNullOrWhiteSpace(), s => server.Password = s, server.Password);
|
||||
CreateComboBox("EncryptMethod", "Encrypt Method", SSRGlobal.EncryptMethods, s => server.EncryptMethod = s, server.EncryptMethod);
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers.ShadowsocksR
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class ShadowsocksR : Server
|
||||
public class ShadowsocksRServer : Server
|
||||
{
|
||||
public override string Type { get; } = "SSR";
|
||||
public override string MaskedData()
|
||||
@@ -3,14 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Shadowsocks;
|
||||
using Netch.Servers.ShadowsocksR.Form;
|
||||
using Netch.Utils;
|
||||
using Serilog;
|
||||
|
||||
namespace Netch.Servers.ShadowsocksR
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class SSRUtil : IServerUtil
|
||||
public class ShadowsocksRUtil : IServerUtil
|
||||
{
|
||||
public ushort Priority { get; } = 1;
|
||||
|
||||
@@ -22,11 +20,11 @@ namespace Netch.Servers.ShadowsocksR
|
||||
|
||||
public string[] UriScheme { get; } = { "ssr" };
|
||||
|
||||
public Type ServerType { get; } = typeof(ShadowsocksR);
|
||||
public Type ServerType { get; } = typeof(ShadowsocksRServer);
|
||||
|
||||
public void Edit(Server s)
|
||||
{
|
||||
new ShadowsocksRForm((ShadowsocksR)s).ShowDialog();
|
||||
new ShadowsocksRForm((ShadowsocksRServer)s).ShowDialog();
|
||||
}
|
||||
|
||||
public void Create()
|
||||
@@ -36,7 +34,7 @@ namespace Netch.Servers.ShadowsocksR
|
||||
|
||||
public string GetShareLink(Server s)
|
||||
{
|
||||
var server = (ShadowsocksR)s;
|
||||
var server = (ShadowsocksRServer)s;
|
||||
|
||||
// https://github.com/shadowsocksr-backup/shadowsocks-rss/wiki/SSR-QRcode-scheme
|
||||
// ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
|
||||
@@ -50,7 +48,7 @@ namespace Netch.Servers.ShadowsocksR
|
||||
|
||||
public IServerController GetController()
|
||||
{
|
||||
return new SSRController();
|
||||
return new ShadowsocksRController();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,7 +111,7 @@ namespace Netch.Servers.ShadowsocksR
|
||||
if (SSGlobal.EncryptMethods.Contains(method) && protocol == "origin" && obfs == "plain")
|
||||
return new[]
|
||||
{
|
||||
new Shadowsocks.Shadowsocks
|
||||
new ShadowsocksServer
|
||||
{
|
||||
Hostname = serverAddr,
|
||||
Port = serverPort,
|
||||
@@ -126,7 +124,7 @@ namespace Netch.Servers.ShadowsocksR
|
||||
|
||||
return new[]
|
||||
{
|
||||
new ShadowsocksR
|
||||
new ShadowsocksRServer
|
||||
{
|
||||
Hostname = serverAddr,
|
||||
Port = serverPort,
|
||||
@@ -144,22 +142,22 @@ namespace Netch.Servers.ShadowsocksR
|
||||
|
||||
public bool CheckServer(Server s)
|
||||
{
|
||||
var server = (ShadowsocksR)s;
|
||||
var server = (ShadowsocksRServer)s;
|
||||
if (!SSRGlobal.EncryptMethods.Contains(server.EncryptMethod))
|
||||
{
|
||||
Log.Error("不支持的 SSR 加密方式:{Method}", server.EncryptMethod);
|
||||
Log.Error("Unsupported ShadowsocksR Encrypt method: {Method}", server.EncryptMethod);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SSRGlobal.Protocols.Contains(server.Protocol))
|
||||
{
|
||||
Log.Error("不支持的 SSR 协议:{Protocol}", server.Protocol);
|
||||
Log.Error("Unsupported ShadowsocksR Protocol: {Protocol}", server.Protocol);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SSRGlobal.OBFSs.Contains(server.OBFS))
|
||||
{
|
||||
Log.Error("不支持的 SSR 混淆:{Obfs}", server.OBFS);
|
||||
Log.Error("Unsupported ShadowsocksR Obfs: {Obfs}", server.OBFS);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class S5Controller : V2rayController
|
||||
{
|
||||
public override string Name { get; } = "Socks5";
|
||||
|
||||
public override async Task<Socks5> StartAsync(Server s)
|
||||
{
|
||||
var server = (Socks5)s;
|
||||
if (server.Auth())
|
||||
await base.StartAsync(s);
|
||||
|
||||
return server;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Netch/Servers/Socks5/Socks5Controller.cs
Normal file
20
Netch/Servers/Socks5/Socks5Controller.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class Socks5Controller : V2rayController
|
||||
{
|
||||
public override string Name { get; } = "Socks5";
|
||||
|
||||
public override async Task<Socks5LocalServer> StartAsync(Server s)
|
||||
{
|
||||
var server = (Socks5Server)s;
|
||||
if (!server.Auth())
|
||||
throw new ArgumentException();
|
||||
|
||||
return await base.StartAsync(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ namespace Netch.Servers
|
||||
{
|
||||
public class Socks5Form : ServerForm
|
||||
{
|
||||
public Socks5Form(Socks5? server = default)
|
||||
public Socks5Form(Socks5Server? server = default)
|
||||
{
|
||||
server ??= new Socks5();
|
||||
server ??= new Socks5Server();
|
||||
Server = server;
|
||||
CreateTextBox("Username", "Username", s => true, s => server.Username = s, server.Username);
|
||||
CreateTextBox("Password", "Password", s => true, s => server.Password = s, server.Password);
|
||||
@@ -5,10 +5,12 @@
|
||||
/// Encrypted proxy client's local socks5 server
|
||||
/// (<see cref="RemoteHostname"/> property is used for saving remote address/hostname for special use)
|
||||
/// </summary>
|
||||
public class Socks5Bridge : Socks5
|
||||
public class Socks5LocalServer : Socks5Server
|
||||
{
|
||||
public Socks5Bridge(string hostname, ushort port, string remoteHostname) : base(hostname, port)
|
||||
public Socks5LocalServer(string hostname, ushort port, string remoteHostname)
|
||||
{
|
||||
Hostname = hostname;
|
||||
Port = port;
|
||||
RemoteHostname = remoteHostname;
|
||||
}
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class Socks5 : Server
|
||||
public class Socks5Server : Server
|
||||
{
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string? Password;
|
||||
public string? Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账号
|
||||
/// </summary>
|
||||
public string? Username;
|
||||
public string? Username { get; set; }
|
||||
|
||||
public override string Type { get; } = "Socks5";
|
||||
|
||||
@@ -21,17 +21,17 @@ namespace Netch.Servers
|
||||
return $"Auth: {Auth()}";
|
||||
}
|
||||
|
||||
public Socks5()
|
||||
public Socks5Server()
|
||||
{
|
||||
}
|
||||
|
||||
public Socks5(string hostname, ushort port)
|
||||
public Socks5Server(string hostname, ushort port)
|
||||
{
|
||||
Hostname = hostname;
|
||||
Port = port;
|
||||
}
|
||||
|
||||
public Socks5(string hostname, ushort port, string username, string password) : this(hostname, port)
|
||||
public Socks5Server(string hostname, ushort port, string username, string password) : this(hostname, port)
|
||||
{
|
||||
Username = username;
|
||||
Password = password;
|
||||
@@ -6,7 +6,7 @@ using Netch.Models;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class S5Util : IServerUtil
|
||||
public class Socks5Util : IServerUtil
|
||||
{
|
||||
public ushort Priority { get; } = 0;
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace Netch.Servers
|
||||
|
||||
public string[] UriScheme { get; } = { };
|
||||
|
||||
public Type ServerType { get; } = typeof(Socks5);
|
||||
public Type ServerType { get; } = typeof(Socks5Server);
|
||||
|
||||
public void Edit(Server s)
|
||||
{
|
||||
new Socks5Form((Socks5)s).ShowDialog();
|
||||
new Socks5Form((Socks5Server)s).ShowDialog();
|
||||
}
|
||||
|
||||
public void Create()
|
||||
@@ -32,7 +32,7 @@ namespace Netch.Servers
|
||||
|
||||
public string GetShareLink(Server s)
|
||||
{
|
||||
var server = (Socks5)s;
|
||||
var server = (Socks5Server)s;
|
||||
// https://t.me/socks?server=1.1.1.1&port=443
|
||||
return $"https://t.me/socks?server={server.Hostname}&port={server.Port}" +
|
||||
$"{(!string.IsNullOrWhiteSpace(server.Username) ? $"&user={server.Username}" : "")}" +
|
||||
@@ -41,7 +41,7 @@ namespace Netch.Servers
|
||||
|
||||
public IServerController GetController()
|
||||
{
|
||||
return new S5Controller();
|
||||
return new Socks5Controller();
|
||||
}
|
||||
|
||||
public IEnumerable<Server> ParseUri(string text)
|
||||
@@ -55,7 +55,7 @@ namespace Netch.Servers
|
||||
if (!dict.ContainsKey("server") || !dict.ContainsKey("port"))
|
||||
throw new FormatException();
|
||||
|
||||
var data = new Socks5
|
||||
var data = new Socks5Server
|
||||
{
|
||||
Hostname = dict["server"],
|
||||
Port = ushort.Parse(dict["port"])
|
||||
@@ -1,7 +1,7 @@
|
||||
#nullable disable
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Servers.Models
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class TrojanConfig
|
||||
{
|
||||
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Servers
|
||||
@@ -27,9 +26,9 @@ namespace Netch.Servers
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public async Task<Socks5> StartAsync(Server s)
|
||||
public async Task<Socks5LocalServer> StartAsync(Server s)
|
||||
{
|
||||
var server = (Trojan)s;
|
||||
var server = (TrojanServer)s;
|
||||
var trojanConfig = new TrojanConfig
|
||||
{
|
||||
local_addr = this.LocalAddress(),
|
||||
@@ -42,7 +41,7 @@ namespace Netch.Servers
|
||||
},
|
||||
ssl = new TrojanSSL
|
||||
{
|
||||
sni = server.Host.ValueOrDefault() ?? (Global.Settings.ResolveServerHostname ? server.Hostname : "")
|
||||
sni = server.Host.ValueOrDefault() ?? server.Hostname
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,7 +51,7 @@ namespace Netch.Servers
|
||||
}
|
||||
|
||||
await StartGuardAsync("-c ..\\data\\last.json");
|
||||
return new Socks5Bridge(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), server.Hostname);
|
||||
return new Socks5LocalServer(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), server.Hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using Netch.Forms;
|
||||
|
||||
namespace Netch.Servers.Form
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class TrojanForm : ServerForm
|
||||
{
|
||||
public TrojanForm(Trojan? server = default)
|
||||
public TrojanForm(TrojanServer? server = default)
|
||||
{
|
||||
server ??= new Trojan();
|
||||
server ??= new TrojanServer();
|
||||
Server = server;
|
||||
CreateTextBox("Password", "Password", s => true, s => server.Password = s, server.Password);
|
||||
CreateTextBox("Host", "Host", s => true, s => server.Host = s, server.Host);
|
||||
@@ -2,7 +2,7 @@ using Netch.Models;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class Trojan : Server
|
||||
public class TrojanServer : Server
|
||||
{
|
||||
public override string Type { get; } = "Trojan";
|
||||
public override string MaskedData()
|
||||
@@ -4,7 +4,6 @@ using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Form;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
@@ -20,11 +19,11 @@ namespace Netch.Servers
|
||||
|
||||
public string[] UriScheme { get; } = { "trojan" };
|
||||
|
||||
public Type ServerType { get; } = typeof(Trojan);
|
||||
public Type ServerType { get; } = typeof(TrojanServer);
|
||||
|
||||
public void Edit(Server s)
|
||||
{
|
||||
new TrojanForm((Trojan)s).ShowDialog();
|
||||
new TrojanForm((TrojanServer)s).ShowDialog();
|
||||
}
|
||||
|
||||
public void Create()
|
||||
@@ -34,7 +33,7 @@ namespace Netch.Servers
|
||||
|
||||
public string GetShareLink(Server s)
|
||||
{
|
||||
var server = (Trojan)s;
|
||||
var server = (TrojanServer)s;
|
||||
return $"trojan://{HttpUtility.UrlEncode(server.Password)}@{server.Hostname}:{server.Port}#{server.Remark}";
|
||||
}
|
||||
|
||||
@@ -45,7 +44,7 @@ namespace Netch.Servers
|
||||
|
||||
public IEnumerable<Server> ParseUri(string text)
|
||||
{
|
||||
var data = new Trojan();
|
||||
var data = new TrojanServer();
|
||||
|
||||
text = text.Replace("/?", "?");
|
||||
if (text.Contains("#"))
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
namespace Netch.Servers.Models
|
||||
namespace Netch.Servers
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用 v2rayN 定义的 VMess 链接格式
|
||||
/// </summary>
|
||||
public class V2rayNSharing
|
||||
public class V2rayNJObject
|
||||
{
|
||||
/// <summary>
|
||||
/// 链接版本
|
||||
@@ -1,7 +1,7 @@
|
||||
#nullable disable
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
namespace Netch.Servers.V2ray.Models
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public struct V2rayConfig
|
||||
{
|
||||
@@ -1,12 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.V2ray.Models;
|
||||
using Netch.Utils;
|
||||
using V2rayConfig = Netch.Servers.V2ray.Models.V2rayConfig;
|
||||
|
||||
#pragma warning disable VSTHRD200
|
||||
|
||||
namespace Netch.Servers.Utils
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public static class V2rayConfigUtils
|
||||
{
|
||||
@@ -44,7 +42,7 @@ namespace Netch.Servers.Utils
|
||||
|
||||
switch (server)
|
||||
{
|
||||
case Socks5 socks5:
|
||||
case Socks5Server socks5:
|
||||
{
|
||||
outbound.protocol = "socks";
|
||||
outbound.settings.servers = new object[]
|
||||
@@ -71,7 +69,7 @@ namespace Netch.Servers.Utils
|
||||
outbound.mux.concurrency = -1;
|
||||
break;
|
||||
}
|
||||
case VLESS vless:
|
||||
case VLESSServer vless:
|
||||
{
|
||||
outbound.protocol = "vless";
|
||||
outbound.settings.vnext = new[]
|
||||
@@ -107,7 +105,7 @@ namespace Netch.Servers.Utils
|
||||
|
||||
break;
|
||||
}
|
||||
case VMess vmess:
|
||||
case VMessServer vmess:
|
||||
{
|
||||
outbound.protocol = "vmess";
|
||||
outbound.settings.vnext = new[]
|
||||
@@ -139,7 +137,7 @@ namespace Netch.Servers.Utils
|
||||
return outbound;
|
||||
}
|
||||
|
||||
private static StreamSettings boundStreamSettings(VMess server)
|
||||
private static StreamSettings boundStreamSettings(VMessServer server)
|
||||
{
|
||||
// https://xtls.github.io/config/transports
|
||||
|
||||
@@ -154,7 +152,7 @@ namespace Netch.Servers.Utils
|
||||
var tlsSettings = new TlsSettings
|
||||
{
|
||||
allowInsecure = Global.Settings.V2RayConfig.AllowInsecure,
|
||||
serverName = server.ServerName.ValueOrDefault() ?? server.Hostname
|
||||
serverName = server.ServerName.ValueOrDefault() ?? server.Host.SplitOrDefault()?[0]
|
||||
};
|
||||
|
||||
switch (server.TLSSecureType)
|
||||
@@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
||||
using Netch.Controllers;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers.Utils;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
@@ -28,7 +27,7 @@ namespace Netch.Servers
|
||||
|
||||
public string? LocalAddress { get; set; }
|
||||
|
||||
public virtual async Task<Socks5> StartAsync(Server s)
|
||||
public virtual async Task<Socks5LocalServer> StartAsync(Server s)
|
||||
{
|
||||
await using (var fileStream = new FileStream(Constants.TempConfig, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
@@ -36,7 +35,7 @@ namespace Netch.Servers
|
||||
}
|
||||
|
||||
await StartGuardAsync("-config ..\\data\\last.json");
|
||||
return new Socks5Bridge(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), s.Hostname);
|
||||
return new Socks5LocalServer(IPAddress.Loopback.ToString(), this.Socks5LocalPort(), s.Hostname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace Netch.Servers
|
||||
public static IEnumerable<Server> ParseVUri(string text)
|
||||
{
|
||||
var scheme = ShareLink.GetUriScheme(text).ToLower();
|
||||
var server = scheme switch { "vmess" => new VMess(), "vless" => new VLESS(), _ => throw new ArgumentOutOfRangeException() };
|
||||
var server = scheme switch { "vmess" => new VMessServer(), "vless" => new VLESSServer(), _ => throw new ArgumentOutOfRangeException() };
|
||||
if (text.Contains("#"))
|
||||
{
|
||||
server.Remark = Uri.UnescapeDataString(text.Split('#')[1]);
|
||||
@@ -58,7 +58,7 @@ namespace Netch.Servers
|
||||
{
|
||||
server.ServerName = parameter.Get("sni") ?? "";
|
||||
if (server.TLSSecureType == "xtls")
|
||||
((VLESS)server).Flow = parameter.Get("flow") ?? "";
|
||||
((VLESSServer)server).Flow = parameter.Get("flow") ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Netch.Servers
|
||||
public static string GetVShareLink(Server s, string scheme = "vmess")
|
||||
{
|
||||
// https://github.com/XTLS/Xray-core/issues/91
|
||||
var server = (VMess)s;
|
||||
var server = (VMessServer)s;
|
||||
var parameter = new Dictionary<string, string>();
|
||||
// protocol-specific fields
|
||||
parameter.Add("type", server.TransferProtocol);
|
||||
@@ -138,7 +138,7 @@ namespace Netch.Servers
|
||||
|
||||
if (server.TLSSecureType == "xtls")
|
||||
{
|
||||
var flow = ((VLESS)server).Flow;
|
||||
var flow = ((VLESSServer)server).Flow;
|
||||
if (!flow.IsNullOrWhiteSpace())
|
||||
parameter.Add("flow", flow!.Replace("-udp443", ""));
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using Netch.Forms;
|
||||
|
||||
namespace Netch.Servers.VLESSForm
|
||||
namespace Netch.Servers
|
||||
{
|
||||
internal class VLESSForm : ServerForm
|
||||
{
|
||||
public VLESSForm(VLESS? server = default)
|
||||
public VLESSForm(VLESSServer? server = default)
|
||||
{
|
||||
server ??= new VLESS();
|
||||
server ??= new VLESSServer();
|
||||
Server = server;
|
||||
CreateTextBox("Sni", "ServerName(Sni)", s => true, s => server.ServerName = s, server.ServerName);
|
||||
CreateTextBox("UUID", "UUID", s => true, s => server.UserID = s, server.UserID);
|
||||
@@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
public class VLESS : VMess
|
||||
public class VLESSServer : VMessServer
|
||||
{
|
||||
public override string Type { get; } = "VLESS";
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Netch.Interfaces;
|
||||
using Netch.Models;
|
||||
using Netch.Servers;
|
||||
|
||||
namespace Netch.Servers
|
||||
{
|
||||
@@ -18,16 +17,16 @@ namespace Netch.Servers
|
||||
|
||||
public string[] UriScheme { get; } = { "vless" };
|
||||
|
||||
public Type ServerType { get; } = typeof(VLESS);
|
||||
public Type ServerType { get; } = typeof(VLESSServer);
|
||||
|
||||
public void Edit(Server s)
|
||||
{
|
||||
new VLESSForm.VLESSForm((VLESS)s).ShowDialog();
|
||||
new VLESSForm((VLESSServer)s).ShowDialog();
|
||||
}
|
||||
|
||||
public void Create()
|
||||
{
|
||||
new VLESSForm.VLESSForm().ShowDialog();
|
||||
new VLESSForm().ShowDialog();
|
||||
}
|
||||
|
||||
public string GetShareLink(Server s)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user