mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
Compare commits
105 Commits
1.4.7
...
1.4.12-Bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbf9c5ed7c | ||
|
|
6174e78696 | ||
|
|
75045fe1a6 | ||
|
|
3da7451b9f | ||
|
|
27d68163a9 | ||
|
|
b1c0990ca5 | ||
|
|
7181db0376 | ||
|
|
7a15fa7375 | ||
|
|
e10c994e38 | ||
|
|
54a263ad06 | ||
|
|
8a56dd4582 | ||
|
|
cd891cec33 | ||
|
|
635a033434 | ||
|
|
6fd3aa48a5 | ||
|
|
a319833bd5 | ||
|
|
70e5d8324e | ||
|
|
1cecccb173 | ||
|
|
281c67aced | ||
|
|
a779295525 | ||
|
|
e665850fc9 | ||
|
|
2537fdd8fe | ||
|
|
cc459d3f59 | ||
|
|
7c051413d3 | ||
|
|
17165e4623 | ||
|
|
a6fd0764e1 | ||
|
|
d27c7c016c | ||
|
|
b5c1cdaf83 | ||
|
|
aa581b2586 | ||
|
|
6d6d747da9 | ||
|
|
8c07273e02 | ||
|
|
aa74948074 | ||
|
|
30b8ed9ac5 | ||
|
|
116b8de135 | ||
|
|
13ed6256d1 | ||
|
|
3c648ebc27 | ||
|
|
452b2c312b | ||
|
|
9f27c4bcf9 | ||
|
|
d2f886ef4b | ||
|
|
52ad3b3b80 | ||
|
|
77c3ae59de | ||
|
|
cdafa14ced | ||
|
|
4d66462416 | ||
|
|
3c0a0d5f80 | ||
|
|
3bdabd7acc | ||
|
|
f605bfa437 | ||
|
|
c8f28f29f1 | ||
|
|
525c9c40fa | ||
|
|
8f1f8de906 | ||
|
|
19fe0a5526 | ||
|
|
401e348402 | ||
|
|
6e4cb9a534 | ||
|
|
ccfb3fe4ce | ||
|
|
0a30ce1b52 | ||
|
|
797e34997f | ||
|
|
6439e8394c | ||
|
|
5ffb5a8235 | ||
|
|
eda75dd681 | ||
|
|
56a40665f1 | ||
|
|
394a56dd76 | ||
|
|
e76b0d5c13 | ||
|
|
c1ef32b420 | ||
|
|
f1e3cc505c | ||
|
|
47dd3e2208 | ||
|
|
bc2fa59672 | ||
|
|
6a6de3eeb8 | ||
|
|
ead8318cb0 | ||
|
|
f4b74092bf | ||
|
|
0d341d3766 | ||
|
|
1568c3b498 | ||
|
|
482eaf28b5 | ||
|
|
40f74252a9 | ||
|
|
47044548b1 | ||
|
|
2f74c36b26 | ||
|
|
9665e6c788 | ||
|
|
c2cf338931 | ||
|
|
b41ab4d25e | ||
|
|
be0770d81b | ||
|
|
6106cb4878 | ||
|
|
b1202b47eb | ||
|
|
da54abda3d | ||
|
|
d0f604eb42 | ||
|
|
957222cc7b | ||
|
|
6dd26574e0 | ||
|
|
9e8659a8ea | ||
|
|
e7daef1226 | ||
|
|
e77b551e68 | ||
|
|
16d9cb77ce | ||
|
|
6b872701a4 | ||
|
|
f1e39102f5 | ||
|
|
bd6e8d4d76 | ||
|
|
e893b4e5d4 | ||
|
|
d67b219e4a | ||
|
|
166bf6a53e | ||
|
|
577f69f33e | ||
|
|
c7d6dee6c3 | ||
|
|
d17a216fe3 | ||
|
|
8a75b86e95 | ||
|
|
04b18239d1 | ||
|
|
debfa76ea2 | ||
|
|
f71b319741 | ||
|
|
37f29128f1 | ||
|
|
dc4251c48f | ||
|
|
4a4dcd1537 | ||
|
|
48e3d6ee60 | ||
|
|
4d4bc0f050 |
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -47,10 +47,10 @@ jobs:
|
||||
C:\builtfiles\Netch.zip
|
||||
body: |
|
||||
[](https://t.me/Netch) [](https://t.me/Netch_Discuss_Group)
|
||||
|
||||
## 更新日志:
|
||||
|
||||
## 更新日志
|
||||
* 这是 GitHub Action 自动化部署,更新日志应该很快会手动更新
|
||||
|
||||
|
||||
## 校验和
|
||||
| 文件名 | SHA256 |
|
||||
| :- | :- |
|
||||
|
||||
@@ -1,83 +1,45 @@
|
||||
using Netch.Forms;
|
||||
using System;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class DNSController
|
||||
public class DNSController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
public DNSController()
|
||||
{
|
||||
Name = "DNS Service";
|
||||
MainFile = "unbound.exe";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动DNS服务
|
||||
/// 启动DNS服务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Start()
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Starting dns Service")}");
|
||||
Instance = GetProcess();
|
||||
Instance.StartInfo.Arguments = "-c unbound-service.conf -v";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
try
|
||||
{
|
||||
if (!File.Exists("bin\\unbound.exe") && !File.Exists("bin\\unbound-service.conf") && !File.Exists("bin\\forward-zone.conf"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\unbound.exe";
|
||||
|
||||
Instance.StartInfo.Arguments = "-c unbound-service.conf -v";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
Logging.Info("dns-unbound 启动完毕");
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info("dns-unbound 进程出错");
|
||||
Stop();
|
||||
Logging.Error("dns-unbound 进程出错:\n" + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
if (File.Exists("logging\\dns-unbound.log"))
|
||||
{
|
||||
File.Delete("logging\\dns-unbound.log");
|
||||
}
|
||||
File.AppendAllText("logging\\dns-unbound.log", $"{e.Data}\r\n");
|
||||
}
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
93
Netch/Controllers/EncryptedProxy/SSController.cs
Normal file
93
Netch/Controllers/EncryptedProxy/SSController.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSController : EncryptedProxy
|
||||
{
|
||||
public SSController()
|
||||
{
|
||||
Name = "Shadowsocks";
|
||||
MainFile = "Shadowsocks.exe";
|
||||
StartedKeywords("listening at");
|
||||
StoppedKeywords("Invalid config path","usage","plugin service exit unexpectedly");
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
//从DLL启动Shaowsocks
|
||||
if (Global.Settings.BootShadowsocksFromDLL && (mode.Type == 0 || mode.Type == 1 || mode.Type == 2 || mode.Type == 3))
|
||||
{
|
||||
State = State.Starting;
|
||||
var client = Encoding.UTF8.GetBytes($"0.0.0.0:{Global.Settings.Socks5LocalPort}");
|
||||
var remote = Encoding.UTF8.GetBytes($"{server.Hostname}:{server.Port}");
|
||||
var passwd = Encoding.UTF8.GetBytes($"{server.Password}");
|
||||
var method = Encoding.UTF8.GetBytes($"{server.EncryptMethod}");
|
||||
if (!NativeMethods.Shadowsocks.Info(client, remote, passwd, method))
|
||||
{
|
||||
State = State.Stopped;
|
||||
Logging.Error("DLL SS INFO 设置失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("DLL SS INFO 设置成功!");
|
||||
|
||||
if (!NativeMethods.Shadowsocks.Start())
|
||||
{
|
||||
State = State.Stopped;
|
||||
Logging.Error("DLL SS 启动失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("DLL SS 启动成功!");
|
||||
State = State.Started;
|
||||
return true;
|
||||
}
|
||||
|
||||
Instance = GetProcess();
|
||||
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u";
|
||||
if (!string.IsNullOrWhiteSpace(server.Plugin) && !string.IsNullOrWhiteSpace(server.PluginOption))
|
||||
Instance.StartInfo.Arguments += $" --plugin {server.Plugin} --plugin-opts \"{server.PluginOption}\"";
|
||||
if (mode.BypassChina) Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Error("SS 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Error("SS 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SSController 停止
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
{
|
||||
if (Global.Settings.BootShadowsocksFromDLL) NativeMethods.Shadowsocks.Stop();
|
||||
else
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
73
Netch/Controllers/EncryptedProxy/SSRController.cs
Normal file
73
Netch/Controllers/EncryptedProxy/SSRController.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.Threading;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSRController : EncryptedProxy
|
||||
{
|
||||
public SSRController()
|
||||
{
|
||||
Name = "ShadowsocksR";
|
||||
MainFile = "ShadowsocksR.exe";
|
||||
StartedKeywords("listening at");
|
||||
StoppedKeywords("Invalid config path","usage");
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
Instance = GetProcess();
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -k \"{server.Password}\" -m {server.EncryptMethod} -t 120";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.Protocol))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -O {server.Protocol}";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.ProtocolParam)) Instance.StartInfo.Arguments += $" -G \"{server.ProtocolParam}\"";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(server.OBFS))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -o {server.OBFS}";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.OBFSParam)) Instance.StartInfo.Arguments += $" -g \"{server.OBFSParam}\"";
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -u";
|
||||
|
||||
if (mode.BypassChina) Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Error("SSR 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Error("SSR 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Netch/Controllers/EncryptedProxy/TrojanController.cs
Normal file
69
Netch/Controllers/EncryptedProxy/TrojanController.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TrojanController : EncryptedProxy
|
||||
{
|
||||
public TrojanController()
|
||||
{
|
||||
Name = "Trojan";
|
||||
MainFile = "Trojan.exe";
|
||||
StartedKeywords("started");
|
||||
StoppedKeywords("exiting");
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
|
||||
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new Trojan
|
||||
{
|
||||
local_addr = Global.Settings.LocalAddress,
|
||||
local_port = Global.Settings.Socks5LocalPort,
|
||||
remote_addr = server.Hostname,
|
||||
remote_port = server.Port,
|
||||
password = new List<string>
|
||||
{
|
||||
server.Password
|
||||
}
|
||||
}));
|
||||
|
||||
Instance = GetProcess();
|
||||
Instance.StartInfo.Arguments = "-c ..\\data\\last.json";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Error("Trojan 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Error("Trojan 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
211
Netch/Controllers/EncryptedProxy/VMessController.cs
Normal file
211
Netch/Controllers/EncryptedProxy/VMessController.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using Newtonsoft.Json;
|
||||
using VMess = Netch.Models.Information.VMess;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class VMessController : EncryptedProxy
|
||||
{
|
||||
public VMessController()
|
||||
{
|
||||
Name = "V2Ray";
|
||||
MainFile = "v2ray.exe";
|
||||
StartedKeywords("started");
|
||||
StoppedKeywords("config file not readable", "failed to");
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new VMess.Config
|
||||
{
|
||||
inbounds = new List<VMess.Inbounds>
|
||||
{
|
||||
new VMess.Inbounds
|
||||
{
|
||||
settings = new VMess.InboundSettings(),
|
||||
port = Global.Settings.Socks5LocalPort,
|
||||
listen = Global.Settings.LocalAddress
|
||||
}
|
||||
},
|
||||
outbounds = new List<VMess.Outbounds>
|
||||
{
|
||||
new VMess.Outbounds
|
||||
{
|
||||
settings = new VMess.OutboundSettings
|
||||
{
|
||||
vnext = new List<VMess.VNext>
|
||||
{
|
||||
new VMess.VNext
|
||||
{
|
||||
address = server.Hostname,
|
||||
port = server.Port,
|
||||
users = new List<VMess.User>
|
||||
{
|
||||
new VMess.User
|
||||
{
|
||||
id = server.UserID,
|
||||
alterId = server.AlterID,
|
||||
security = server.EncryptMethod
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
streamSettings = new VMess.StreamSettings
|
||||
{
|
||||
network = server.TransferProtocol,
|
||||
security = server.TLSSecure ? "tls" : string.Empty,
|
||||
wsSettings = server.TransferProtocol == "ws"
|
||||
? new VMess.WebSocketSettings
|
||||
{
|
||||
path = server.Path == string.Empty ? "/" : server.Path,
|
||||
headers = new VMess.WSHeaders
|
||||
{
|
||||
Host = server.Host == string.Empty ? server.Hostname : server.Host
|
||||
}
|
||||
}
|
||||
: null,
|
||||
tcpSettings = server.FakeType == "http"
|
||||
? new VMess.TCPSettings
|
||||
{
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType,
|
||||
request = new VMess.TCPRequest
|
||||
{
|
||||
path = server.Path == string.Empty ? "/" : server.Path,
|
||||
headers = new VMess.TCPRequestHeaders
|
||||
{
|
||||
Host = server.Host == string.Empty ? server.Hostname : server.Host
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
: null,
|
||||
kcpSettings = server.TransferProtocol == "kcp"
|
||||
? new VMess.KCPSettings
|
||||
{
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType
|
||||
}
|
||||
}
|
||||
: null,
|
||||
quicSettings = server.TransferProtocol == "quic"
|
||||
? new VMess.QUICSettings
|
||||
{
|
||||
security = server.QUICSecure,
|
||||
key = server.QUICSecret,
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType
|
||||
}
|
||||
}
|
||||
: null,
|
||||
httpSettings = server.TransferProtocol == "h2"
|
||||
? new VMess.HTTPSettings
|
||||
{
|
||||
host = server.Host == "" ? server.Hostname : server.Host,
|
||||
path = server.Path == "" ? "/" : server.Path
|
||||
}
|
||||
: null,
|
||||
tlsSettings = new VMess.TLSSettings
|
||||
{
|
||||
allowInsecure = true,
|
||||
serverName = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
},
|
||||
mux = new VMess.OutboundMux
|
||||
{
|
||||
enabled = server.UseMux
|
||||
}
|
||||
},
|
||||
mode.Type == 0 || mode.Type == 1 || mode.Type == 2
|
||||
? new VMess.Outbounds
|
||||
{
|
||||
tag = "TUNTAP",
|
||||
protocol = "freedom"
|
||||
}
|
||||
: new VMess.Outbounds
|
||||
{
|
||||
tag = "direct",
|
||||
protocol = "freedom"
|
||||
}
|
||||
},
|
||||
routing = new VMess.Routing
|
||||
{
|
||||
rules = new List<VMess.RoutingRules>
|
||||
{
|
||||
mode.BypassChina
|
||||
? new VMess.RoutingRules
|
||||
{
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
},
|
||||
domain = new List<string>
|
||||
{
|
||||
"geosite:cn"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
}
|
||||
: new VMess.RoutingRules
|
||||
{
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:private"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Instance = GetProcess();
|
||||
Instance.StartInfo.Arguments = "-config ..\\data\\last.json";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
if (File.Exists("data\\last.json")) File.Delete("data\\last.json");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
Logging.Error("V2Ray 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Error("V2Ray 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class HTTPController
|
||||
{
|
||||
/// <summary>
|
||||
/// 实例
|
||||
/// </summary>
|
||||
public PrivoxyController pPrivoxyController = new PrivoxyController();
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
pPrivoxyController.Start(server, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
pPrivoxyController.Start(server, mode);
|
||||
}
|
||||
|
||||
if (mode.Type != 5)
|
||||
{
|
||||
NativeMethods.SetGlobal($"127.0.0.1:{Global.Settings.HTTPLocalPort}", "<local>");
|
||||
|
||||
// HTTP 系统代理模式,启动系统代理
|
||||
/*
|
||||
using (var registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true))
|
||||
{
|
||||
registry.SetValue("ProxyEnable", 1);
|
||||
registry.SetValue("ProxyServer", $"127.0.0.1:{Global.Settings.HTTPLocalPort}");
|
||||
|
||||
Win32Native.InternetSetOption(IntPtr.Zero, 39, IntPtr.Zero, 0);
|
||||
Win32Native.InternetSetOption(IntPtr.Zero, 37, IntPtr.Zero, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (System.Windows.Forms.MessageBox.Show(i18N.Translate("Failed to set the system proxy, it may be caused by the lack of dependent programs. Do you want to jump to Netch's official website to download dependent programs?"), i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://netch.org/#/?id=%e4%be%9d%e8%b5%96");
|
||||
}
|
||||
Utils.Logging.Info("设置系统代理失败"+e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
pPrivoxyController.Stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
|
||||
NativeMethods.SetDIRECT();
|
||||
|
||||
/*
|
||||
using (var registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", true))
|
||||
{
|
||||
registry.SetValue("ProxyEnable", 0);
|
||||
registry.DeleteValue("ProxyServer", false);
|
||||
|
||||
Win32Native.InternetSetOption(IntPtr.Zero, 39, IntPtr.Zero, 0);
|
||||
Win32Native.InternetSetOption(IntPtr.Zero, 37, IntPtr.Zero, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
177
Netch/Controllers/Interface/Controller.cs
Normal file
177
Netch/Controllers/Interface/Controller.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制器名
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 主程序名(不含扩展名)
|
||||
/// </summary>
|
||||
public string MainFile;
|
||||
|
||||
private List<string> _startedKeywords = new List<string>();
|
||||
|
||||
private List<string> _stoppedKeywords = new List<string>();
|
||||
|
||||
protected bool RedirectStd = true;
|
||||
|
||||
protected void StartedKeywords(params string[] texts)
|
||||
{
|
||||
foreach (var text in texts)
|
||||
{
|
||||
_startedKeywords.Add(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void StoppedKeywords(params string[] texts)
|
||||
{
|
||||
foreach (var text in texts)
|
||||
{
|
||||
_stoppedKeywords.Add(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
protected State State = State.Waiting;
|
||||
|
||||
public abstract void Stop();
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
protected void StopInstance()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance == null || Instance.HasExited) return;
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
Logging.Error($"停止 {MainFile} 错误:\n" + e);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ClearLog()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists($"logging\\{Name}.log")) File.Delete($"logging\\{Name}.log");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写日志
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns><see cref="s" />是否为空</returns>
|
||||
protected bool Write(string s)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s)) return false;
|
||||
try
|
||||
{
|
||||
File.AppendAllText($"logging\\{Name}.log", s + Global.EOF);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error($"写入{Name}日志错误:\n" + e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Process GetProcess()
|
||||
{
|
||||
var p = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
FileName = Path.GetFullPath($"bin\\{MainFile}"),
|
||||
WorkingDirectory = $"{Global.NetchDir}\\bin",
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardError = RedirectStd,
|
||||
RedirectStandardInput = RedirectStd,
|
||||
RedirectStandardOutput = RedirectStd,
|
||||
UseShellExecute = false
|
||||
},
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收输出数据
|
||||
/// </summary>
|
||||
/// <param name="sender">发送者</param>
|
||||
/// <param name="e">数据</param>
|
||||
protected void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
var str = Encoding.UTF8.GetString(Encoding.GetEncoding("gbk").GetBytes(e.Data??string.Empty));
|
||||
|
||||
// 写入日志
|
||||
if (!Write(str)) return;
|
||||
|
||||
// 检查启动
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = State.Stopped;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var s in _startedKeywords)
|
||||
{
|
||||
if (str.Contains(s))
|
||||
{
|
||||
State = State.Started;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var s in _stoppedKeywords)
|
||||
{
|
||||
if (str.Contains(s))
|
||||
{
|
||||
State = State.Stopped;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
15
Netch/Controllers/Interface/EncryptedProxy.cs
Normal file
15
Netch/Controllers/Interface/EncryptedProxy.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class EncryptedProxy : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public abstract bool Start(Server server, Mode mode);
|
||||
}
|
||||
}
|
||||
15
Netch/Controllers/Interface/ModeController.cs
Normal file
15
Netch/Controllers/Interface/ModeController.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class ModeController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public abstract bool Start(Server server, Mode mode);
|
||||
}
|
||||
}
|
||||
@@ -1,283 +1,177 @@
|
||||
using Netch.Forms;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class MainController
|
||||
{
|
||||
/// <summary>
|
||||
/// 记录当前使用的端口
|
||||
/// <see cref="MainForm.LocalPortText"/>
|
||||
/// </summary>
|
||||
public static readonly List<int> UsingPorts = new List<int>();
|
||||
|
||||
public EncryptedProxy pEncryptedProxyController;
|
||||
|
||||
public ModeController pModeController;
|
||||
|
||||
/// <summary>
|
||||
/// NTT 控制器
|
||||
/// </summary>
|
||||
public NTTController pNTTController = new NTTController();
|
||||
|
||||
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
|
||||
public static extern UInt32 FlushDNSResolverCache();
|
||||
public static Process GetProcess()
|
||||
{
|
||||
var process = new Process();
|
||||
process.StartInfo.WorkingDirectory = string.Format("{0}\\bin", Directory.GetCurrentDirectory());
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.StartInfo.RedirectStandardInput = true;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.EnableRaisingEvents = true;
|
||||
|
||||
return process;
|
||||
}
|
||||
public static extern uint FlushDNSResolverCache();
|
||||
|
||||
/// <summary>
|
||||
/// SS 控制器
|
||||
/// </summary>
|
||||
public SSController pSSController;
|
||||
|
||||
/// <summary>
|
||||
/// SSR 控制器
|
||||
/// </summary>
|
||||
public SSRController pSSRController;
|
||||
|
||||
/// <summary>
|
||||
/// V2Ray 控制器
|
||||
/// </summary>
|
||||
public VMessController pVMessController;
|
||||
|
||||
/// <summary>
|
||||
/// Trojan 控制器
|
||||
/// </summary>
|
||||
public TrojanController pTrojanController;
|
||||
|
||||
/// <summary>
|
||||
/// NF 控制器
|
||||
/// </summary>
|
||||
public NFController pNFController;
|
||||
|
||||
/// <summary>
|
||||
/// HTTP 控制器
|
||||
/// </summary>
|
||||
public HTTPController pHTTPController;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP 控制器
|
||||
/// </summary>
|
||||
public TUNTAPController pTUNTAPController;
|
||||
|
||||
/// <summary>
|
||||
/// NTT 控制器
|
||||
/// </summary>
|
||||
public NTTController pNTTController;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
public bool Start(Server server, Mode mode)
|
||||
{
|
||||
FlushDNSResolverCache();
|
||||
|
||||
var result = false;
|
||||
switch (server.Type)
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
case "Socks5":
|
||||
if (mode.Type == 4)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
case "SS":
|
||||
KillProcess("Shadowsocks");
|
||||
if (pSSController == null)
|
||||
{
|
||||
pSSController = new SSController();
|
||||
}
|
||||
result = pSSController.Start(server, mode);
|
||||
break;
|
||||
case "SSR":
|
||||
KillProcess("ShadowsocksR");
|
||||
if (pSSRController == null)
|
||||
{
|
||||
pSSRController = new SSRController();
|
||||
}
|
||||
result = pSSRController.Start(server, mode);
|
||||
break;
|
||||
case "VMess":
|
||||
KillProcess("v2ray");
|
||||
if (pVMessController == null)
|
||||
{
|
||||
pVMessController = new VMessController();
|
||||
}
|
||||
result = pVMessController.Start(server, mode);
|
||||
break;
|
||||
case "Trojan":
|
||||
KillProcess("Trojan");
|
||||
if (pTrojanController == null)
|
||||
{
|
||||
pTrojanController = new TrojanController();
|
||||
}
|
||||
result = pTrojanController.Start(server, mode);
|
||||
break;
|
||||
result = mode.Type != 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (server.Type)
|
||||
{
|
||||
case "SS":
|
||||
pEncryptedProxyController = new SSController();
|
||||
break;
|
||||
case "SSR":
|
||||
pEncryptedProxyController = new SSRController();
|
||||
break;
|
||||
case "VMess":
|
||||
pEncryptedProxyController = new VMessController();
|
||||
break;
|
||||
case "Trojan":
|
||||
pEncryptedProxyController = new TrojanController();
|
||||
break;
|
||||
}
|
||||
|
||||
KillProcessByName(pEncryptedProxyController.MainFile);
|
||||
|
||||
// 检查端口是否被占用
|
||||
if (PortHelper.PortInUse(Global.Settings.Socks5LocalPort))
|
||||
{
|
||||
MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", "Socks5"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PortHelper.PortInUse(Global.Settings.HTTPLocalPort))
|
||||
{
|
||||
MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", "HTTP"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PortHelper.PortInUse(Global.Settings.RedirectorTCPPort, PortType.TCP))
|
||||
{
|
||||
MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", "Redirector TCP"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Global.MainForm.StatusText(i18N.Translate("Starting ", pEncryptedProxyController.Name));
|
||||
result = pEncryptedProxyController.Start(server, mode);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (mode.Type == 0)
|
||||
Logging.Info("加密代理已启动");
|
||||
switch (mode.Type)
|
||||
{
|
||||
if (pNFController == null)
|
||||
{
|
||||
pNFController = new NFController();
|
||||
}
|
||||
if (pNTTController == null)
|
||||
{
|
||||
pNTTController = new NTTController();
|
||||
}
|
||||
// 进程代理模式,启动 NF 控制器
|
||||
result = pNFController.Start(server, mode, false);
|
||||
if (!result)
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Restarting Redirector")}");
|
||||
Utils.Logging.Info("正常启动失败后尝试停止驱动服务再重新启动");
|
||||
//正常启动失败后尝试停止驱动服务再重新启动
|
||||
result = pNFController.Start(server, mode, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(() => pNTTController.Start());
|
||||
}
|
||||
case 0: // 进程代理模式
|
||||
pModeController = new NFController();
|
||||
break;
|
||||
case 1: // TUN/TAP 黑名单代理模式
|
||||
case 2: // TUN/TAP 白名单代理模式
|
||||
pModeController = new TUNTAPController();
|
||||
break;
|
||||
case 3:
|
||||
case 5:
|
||||
pModeController = new HTTPController();
|
||||
break;
|
||||
case 4: // Socks5 代理模式,不需要启动额外的Server
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else if (mode.Type == 1)
|
||||
|
||||
if (pModeController != null)
|
||||
{
|
||||
if (pTUNTAPController == null)
|
||||
{
|
||||
pTUNTAPController = new TUNTAPController();
|
||||
}
|
||||
if (pNTTController == null)
|
||||
{
|
||||
pNTTController = new NTTController();
|
||||
}
|
||||
// TUN/TAP 黑名单代理模式,启动 TUN/TAP 控制器
|
||||
result = pTUNTAPController.Start(server, mode);
|
||||
if (result)
|
||||
{
|
||||
Task.Run(() => pNTTController.Start());
|
||||
}
|
||||
Global.MainForm.StatusText(i18N.Translate("Starting ", pModeController.Name));
|
||||
result = pModeController.Start(server, mode);
|
||||
}
|
||||
else if (mode.Type == 2)
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (pTUNTAPController == null)
|
||||
switch (mode.Type)
|
||||
{
|
||||
pTUNTAPController = new TUNTAPController();
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
Task.Run(() =>
|
||||
{
|
||||
Global.MainForm.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
||||
// Thread.Sleep(1000);
|
||||
var (nttResult, natType, localEnd, publicEnd) = pNTTController.Start();
|
||||
var country = Utils.Utils.GetCityCode(publicEnd);
|
||||
|
||||
if (nttResult) Global.MainForm.NatTypeStatusText(natType, country);
|
||||
});
|
||||
break;
|
||||
}
|
||||
if (pNTTController == null)
|
||||
{
|
||||
pNTTController = new NTTController();
|
||||
}
|
||||
// TUN/TAP 白名单代理模式,启动 TUN/TAP 控制器
|
||||
result = pTUNTAPController.Start(server, mode);
|
||||
if (result)
|
||||
{
|
||||
Task.Run(() => pNTTController.Start());
|
||||
}
|
||||
}
|
||||
else if (mode.Type == 3 || mode.Type == 5)
|
||||
{
|
||||
if (pHTTPController == null)
|
||||
{
|
||||
pHTTPController = new HTTPController();
|
||||
}
|
||||
// HTTP 系统代理和 Socks5 和 HTTP 代理模式,启动 HTTP 控制器
|
||||
result = pHTTPController.Start(server, mode);
|
||||
}
|
||||
else if (mode.Type == 4)
|
||||
{
|
||||
// Socks5 代理模式,不需要启动额外的控制器
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
if (!result) Stop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (pSSController != null)
|
||||
var tasks = new[]
|
||||
{
|
||||
pSSController.Stop();
|
||||
}
|
||||
else if (pSSRController != null)
|
||||
{
|
||||
pSSRController.Stop();
|
||||
}
|
||||
else if (pVMessController != null)
|
||||
{
|
||||
pVMessController.Stop();
|
||||
}
|
||||
else if (pTrojanController != null)
|
||||
{
|
||||
pTrojanController.Stop();
|
||||
}
|
||||
|
||||
if (pNFController != null)
|
||||
{
|
||||
pNFController.Stop();
|
||||
}
|
||||
else if (pTUNTAPController != null)
|
||||
{
|
||||
pTUNTAPController.Stop();
|
||||
}
|
||||
else if (pHTTPController != null)
|
||||
{
|
||||
pHTTPController.Stop();
|
||||
}
|
||||
|
||||
if (pNTTController != null)
|
||||
{
|
||||
pNTTController.Stop();
|
||||
}
|
||||
Task.Factory.StartNew(() => pEncryptedProxyController?.Stop()),
|
||||
Task.Factory.StartNew(() => UsingPorts.Clear()),
|
||||
Task.Factory.StartNew(() => pModeController?.Stop()),
|
||||
Task.Factory.StartNew(() => pNTTController.Stop())
|
||||
};
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
public void KillProcess(string name)
|
||||
public static void KillProcessByName(string name)
|
||||
{
|
||||
var processes = Process.GetProcessesByName(name);
|
||||
foreach (var p in processes)
|
||||
{
|
||||
if (IsChildProcess(p, name))
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsChildProcess(Process process, string name)
|
||||
{
|
||||
bool result;
|
||||
try
|
||||
{
|
||||
var FileName = (Directory.GetCurrentDirectory() + "\\bin\\" + name + ".exe").ToLower();
|
||||
var procFileName = process.MainModule.FileName.ToLower();
|
||||
result = FileName.Equals(procFileName, StringComparison.Ordinal);
|
||||
foreach (var p in Process.GetProcessesByName(name))
|
||||
if (p.MainModule != null && p.MainModule.FileName.StartsWith(Global.NetchDir))
|
||||
p.Kill();
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.Message);
|
||||
result = false;
|
||||
Logging.Error($"结束进程 {name} 错误:\n" + e);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
100
Netch/Controllers/Mode/HTTPController.cs
Normal file
100
Netch/Controllers/Mode/HTTPController.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class HTTPController : ModeController
|
||||
{
|
||||
/// <summary>
|
||||
/// 实例
|
||||
/// </summary>
|
||||
public PrivoxyController pPrivoxyController = new PrivoxyController();
|
||||
|
||||
private string prevBypass, prevHTTP, prevPAC;
|
||||
private bool prevEnabled;
|
||||
|
||||
public HTTPController()
|
||||
{
|
||||
Name = "HTTP";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
Task.Run(RecordPrevious);
|
||||
|
||||
try
|
||||
{
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password)) return false;
|
||||
|
||||
pPrivoxyController.Start(server, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
pPrivoxyController.Start(server, mode);
|
||||
}
|
||||
|
||||
if (mode.Type == 3) NativeMethods.SetGlobal($"127.0.0.1:{Global.Settings.HTTPLocalPort}", "<local>");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (MessageBoxX.Show(i18N.Translate("Failed to set the system proxy, it may be caused by the lack of dependent programs. Do you want to jump to Netch's official website to download dependent programs?"), confirm: true) == DialogResult.OK) Process.Start("https://netch.org/#/?id=%e4%be%9d%e8%b5%96");
|
||||
|
||||
Logging.Error("设置系统代理失败" + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RecordPrevious()
|
||||
{
|
||||
var registry = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
|
||||
if (registry == null)
|
||||
{
|
||||
prevEnabled = false;
|
||||
prevPAC = prevHTTP = prevBypass = "";
|
||||
return;
|
||||
}
|
||||
|
||||
prevPAC = registry.GetValue("AutoConfigURL")?.ToString() ?? "";
|
||||
if ((registry.GetValue("ProxyEnable")?.Equals(1) ?? false) || prevPAC != "") prevEnabled = true;
|
||||
|
||||
prevHTTP = registry.GetValue("ProxyServer")?.ToString() ?? "";
|
||||
prevBypass = registry.GetValue("ProxyOverride")?.ToString() ?? "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
Task.Factory.StartNew(pPrivoxyController.Stop),
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
NativeMethods.SetGlobal(prevHTTP, prevBypass);
|
||||
if (prevPAC != "")
|
||||
NativeMethods.SetURL(prevPAC);
|
||||
if (!prevEnabled)
|
||||
NativeMethods.SetDIRECT();
|
||||
prevEnabled = false;
|
||||
})
|
||||
};
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
}
|
||||
}
|
||||
293
Netch/Controllers/Mode/NFController.cs
Normal file
293
Netch/Controllers/Mode/NFController.cs
Normal file
@@ -0,0 +1,293 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using nfapinet;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NFController : ModeController
|
||||
{
|
||||
private static readonly ServiceController NFService = new ServiceController("netfilter2");
|
||||
|
||||
private static readonly string BinDriver = string.Empty;
|
||||
private static readonly string SystemDriver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys";
|
||||
private static string[] _sysDns = { };
|
||||
|
||||
static NFController()
|
||||
{
|
||||
switch ($"{Environment.OSVersion.Version.Major}.{Environment.OSVersion.Version.Minor}")
|
||||
{
|
||||
case "10.0":
|
||||
BinDriver = "Win-10.sys";
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
BinDriver = "Win-8.sys";
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
BinDriver = "Win-7.sys";
|
||||
break;
|
||||
default:
|
||||
Logging.Error($"不支持的系统版本:{Environment.OSVersion.Version}");
|
||||
return;
|
||||
}
|
||||
|
||||
BinDriver = "bin\\" + BinDriver;
|
||||
}
|
||||
|
||||
public NFController()
|
||||
{
|
||||
Name = "Redirector";
|
||||
MainFile = "Redirector.exe";
|
||||
StartedKeywords("Started");
|
||||
StoppedKeywords("Failed", "Unable");
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
Logging.Info("内置驱动版本: " + DriverVersion(BinDriver));
|
||||
if (DriverVersion(SystemDriver) != DriverVersion(BinDriver))
|
||||
{
|
||||
if (File.Exists(SystemDriver))
|
||||
{
|
||||
Logging.Info("系统驱动版本: " + DriverVersion(SystemDriver));
|
||||
Logging.Info("更新驱动");
|
||||
UninstallDriver();
|
||||
}
|
||||
|
||||
if (!InstallDriver())
|
||||
return false;
|
||||
}
|
||||
|
||||
var processList = "";
|
||||
foreach (var proc in mode.Rule)
|
||||
processList += proc + ",";
|
||||
processList += "NTT.exe";
|
||||
|
||||
Instance = GetProcess();
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
Instance.StartInfo.Arguments += $"-r 127.0.0.1:{Global.Settings.Socks5LocalPort} -p \"{processList}\"";
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var result = DNS.Lookup(server.Hostname);
|
||||
if (result == null)
|
||||
{
|
||||
Logging.Info("无法解析服务器 IP 地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $"-r {result}:{server.Port} -p \"{processList}\"";
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password)) Instance.StartInfo.Arguments += $" -username \"{server.Username}\" -password \"{server.Password}\"";
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -t {Global.Settings.RedirectorTCPPort}";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var j = 0; j < 40; j++)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
if (Global.Settings.ModifySystemDNS)
|
||||
{
|
||||
//备份并替换系统DNS
|
||||
_sysDns = DNS.getSystemDns();
|
||||
string[] dns = {"1.1.1.1", "8.8.8.8"};
|
||||
DNS.SetDNS(dns);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Error(Name + " 启动超时");
|
||||
Stop();
|
||||
if (!RestartService()) return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool RestartService()
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (NFService.Status)
|
||||
{
|
||||
// 启动驱动服务
|
||||
case ServiceControllerStatus.Running:
|
||||
// 防止其他程序占用 重置 NF 百万连接数限制
|
||||
NFService.Stop();
|
||||
NFService.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
Global.MainForm.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||
NFService.Start();
|
||||
break;
|
||||
case ServiceControllerStatus.Stopped:
|
||||
Global.MainForm.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||
NFService.Start();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("启动驱动服务失败:\n" + e);
|
||||
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result != NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Logging.Error($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("注册驱动成功");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string DriverVersion(string file)
|
||||
{
|
||||
return File.Exists(file) ? FileVersionInfo.GetVersionInfo(file).FileVersion : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卸载 NF 驱动
|
||||
/// </summary>
|
||||
/// <returns>是否成功卸载</returns>
|
||||
public static bool UninstallDriver()
|
||||
{
|
||||
Global.MainForm.StatusText(i18N.Translate("Uninstalling NF Service"));
|
||||
Logging.Info("卸载NF驱动");
|
||||
try
|
||||
{
|
||||
if (NFService.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
NFService.Stop();
|
||||
NFService.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!File.Exists(SystemDriver)) return true;
|
||||
|
||||
try
|
||||
{
|
||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error(e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
File.Delete(SystemDriver);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安装 NF 驱动
|
||||
/// </summary>
|
||||
/// <returns>驱动是否安装成功</returns>
|
||||
public static bool InstallDriver()
|
||||
{
|
||||
Logging.Info("安装NF驱动");
|
||||
try
|
||||
{
|
||||
File.Copy(BinDriver, SystemDriver);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("驱动复制失败\n" + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
Global.MainForm.StatusText(i18N.Translate("Register driver"));
|
||||
// 注册驱动文件
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result == NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Logging.Info($"驱动安装成功,当前驱动版本:{DriverVersion(SystemDriver)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// private new void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
// {
|
||||
// if (!Write(e.Data)) return;
|
||||
// if (State == State.Starting)
|
||||
// {
|
||||
// if (Instance.HasExited)
|
||||
// State = State.Stopped;
|
||||
// else if (e.Data.Contains("Started"))
|
||||
// State = State.Started;
|
||||
// else if (e.Data.Contains("Failed") || e.Data.Contains("Unable")) State = State.Stopped;
|
||||
// }
|
||||
// else if (State == State.Started)
|
||||
// {
|
||||
// if (e.Data.StartsWith("[APP][Bandwidth]"))
|
||||
// {
|
||||
// var splited = e.Data.Replace("[APP][Bandwidth]", "").Trim().Split(',');
|
||||
// if (splited.Length == 2)
|
||||
// {
|
||||
// var uploadSplited = splited[0].Split(':');
|
||||
// var downloadSplited = splited[1].Split(':');
|
||||
//
|
||||
// if (uploadSplited.Length == 2 && downloadSplited.Length == 2)
|
||||
// if (long.TryParse(uploadSplited[1], out var upload) && long.TryParse(downloadSplited[1], out var download))
|
||||
// Task.Run(() => OnBandwidthUpdated(upload, download));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
if (Global.Settings.ModifySystemDNS)
|
||||
//恢复系统DNS
|
||||
DNS.SetDNS(_sysDns);
|
||||
});
|
||||
StopInstance();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 流量变动事件
|
||||
/// </summary>
|
||||
public event BandwidthUpdateHandler OnBandwidthUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// 流量变动处理器
|
||||
/// </summary>
|
||||
/// <param name="upload">上传</param>
|
||||
/// <param name="download">下载</param>
|
||||
public delegate void BandwidthUpdateHandler(long upload, long download);
|
||||
}
|
||||
}
|
||||
@@ -1,88 +1,81 @@
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Properties;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNTAPController
|
||||
public class TUNTAPController : ModeController
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例(tun2socks)
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
// ByPassLan IP
|
||||
private readonly List<string> _bypassLanIPs = new List<string> {"10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16"};
|
||||
|
||||
private Mode _savedMode = new Mode();
|
||||
private Server _savedServer = new Server();
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
private IPAddress[] _serverAddresses = new IPAddress[0];
|
||||
|
||||
/// <summary>
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
public IPAddress[] ServerAddresses = new IPAddress[0];
|
||||
|
||||
/// <summary>
|
||||
/// 保存传入的规则
|
||||
/// </summary>
|
||||
public Models.Server SavedServer = new Models.Server();
|
||||
public Models.Mode SavedMode = new Models.Mode();
|
||||
|
||||
/// <summary>
|
||||
/// 本地 DNS 服务控制器
|
||||
/// 本地 DNS 服务控制器
|
||||
/// </summary>
|
||||
public DNSController pDNSController = new DNSController();
|
||||
|
||||
// ByPassLan IP
|
||||
List<string> BypassLanIPs = new List<string>() { "10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16" };
|
||||
public TUNTAPController()
|
||||
{
|
||||
Name = "Tap";
|
||||
MainFile = "tun2socks.exe";
|
||||
StartedKeywords("Running");
|
||||
StoppedKeywords("failed","invalid vconfig file");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 TUNTAP 适配器
|
||||
/// </summary>
|
||||
public bool Configure()
|
||||
private bool Configure()
|
||||
{
|
||||
// 查询服务器 IP 地址
|
||||
var destination = Dns.GetHostAddressesAsync(SavedServer.Hostname);
|
||||
var destination = Dns.GetHostAddressesAsync(_savedServer.Hostname);
|
||||
if (destination.Wait(1000))
|
||||
{
|
||||
if (destination.Result.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (destination.Result.Length == 0) return false;
|
||||
|
||||
ServerAddresses = destination.Result;
|
||||
_serverAddresses = destination.Result;
|
||||
}
|
||||
|
||||
// 搜索出口
|
||||
return Utils.Configuration.SearchOutbounds();
|
||||
return SearchOutbounds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置绕行规则
|
||||
/// </summary>
|
||||
public bool SetupBypass()
|
||||
private bool SetupBypass()
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("SetupBypass")}");
|
||||
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
|
||||
Logging.Info("设置绕行规则 → 设置让服务器 IP 走直连");
|
||||
// 让服务器 IP 走直连
|
||||
foreach (var address in ServerAddresses)
|
||||
{
|
||||
foreach (var address in _serverAddresses)
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
{
|
||||
NativeMethods.CreateRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理模式的绕过中国
|
||||
if (SavedMode.BypassChina)
|
||||
if (_savedMode.BypassChina)
|
||||
{
|
||||
Logging.Info("设置绕行规则 → 处理模式的绕过中国");
|
||||
using (var sr = new StringReader(Encoding.UTF8.GetString(Properties.Resources.CNIP)))
|
||||
using (var sr = new StringReader(Encoding.UTF8.GetString(Resources.CNIP)))
|
||||
{
|
||||
string text;
|
||||
|
||||
@@ -102,26 +95,20 @@ namespace Netch.Controllers
|
||||
var info = ip.Split('/');
|
||||
var address = IPAddress.Parse(info[0]);
|
||||
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
{
|
||||
NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
Logging.Info("设置绕行规则 → 处理绕过局域网 IP");
|
||||
// 处理绕过局域网 IP
|
||||
foreach (var ip in BypassLanIPs)
|
||||
foreach (var ip in _bypassLanIPs)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
var address = IPAddress.Parse(info[0]);
|
||||
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
{
|
||||
NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
if (SavedMode.Type == 2) // 处理仅规则内走直连
|
||||
if (_savedMode.Type == 2) // 处理仅规则内走直连
|
||||
{
|
||||
Logging.Info("设置绕行规则 → 处理仅规则内走直连");
|
||||
// 将 TUN/TAP 网卡权重放到最高
|
||||
@@ -142,74 +129,58 @@ namespace Netch.Controllers
|
||||
// 创建默认路由
|
||||
if (!NativeMethods.CreateRoute("0.0.0.0", 0, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index, 10))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
State = State.Stopped;
|
||||
|
||||
foreach (var address in ServerAddresses)
|
||||
{
|
||||
NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
foreach (var address in _serverAddresses) NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("设置绕行规则 → 创建规则路由");
|
||||
// 创建规则路由
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
if (info.Length == 2)
|
||||
{
|
||||
if (int.TryParse(info[1], out var prefix))
|
||||
{
|
||||
NativeMethods.CreateRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SavedMode.Type == 1) // 处理仅规则内走代理
|
||||
else if (_savedMode.Type == 1) // 处理仅规则内走代理
|
||||
{
|
||||
Logging.Info("设置绕行规则->处理仅规则内走代理");
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
if (info.Length == 2)
|
||||
{
|
||||
if (int.TryParse(info[1], out var prefix))
|
||||
{
|
||||
NativeMethods.CreateRoute(info[0], prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//处理 NAT 类型检测,由于协议的原因,无法仅通过域名确定需要代理的 IP,自己记录解析了返回的 IP,仅支持默认检测服务器
|
||||
if (Global.Settings.STUN_Server == "stun.stunprotocol.org")
|
||||
{
|
||||
try
|
||||
{
|
||||
var nttAddress = Dns.GetHostAddresses(Global.Settings.STUN_Server)[0];
|
||||
if (int.TryParse("32", out var prefix))
|
||||
{
|
||||
NativeMethods.CreateRoute(nttAddress.ToString(), prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.CreateRoute(nttAddress.ToString(), prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
|
||||
var nttrAddress = Dns.GetHostAddresses("stunresponse.coldthunder11.com")[0];
|
||||
if (int.TryParse("32", out var prefixr))
|
||||
{
|
||||
NativeMethods.CreateRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefixr)) NativeMethods.CreateRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logging.Info("NAT 类型测试域名解析失败,将不会被添加到代理列表");
|
||||
}
|
||||
}
|
||||
|
||||
//处理DNS代理
|
||||
if (Global.Settings.TUNTAP.ProxyDNS)
|
||||
{
|
||||
Logging.Info("设置绕行规则 → 处理自定义 DNS 代理");
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
{
|
||||
string dns = "";
|
||||
var dns = string.Empty;
|
||||
foreach (var value in Global.Settings.TUNTAP.DNS)
|
||||
{
|
||||
dns += value;
|
||||
@@ -218,20 +189,21 @@ namespace Netch.Controllers
|
||||
|
||||
dns = dns.Trim();
|
||||
dns = dns.Substring(0, dns.Length - 1);
|
||||
if (int.TryParse("32", out var prefix))
|
||||
{
|
||||
NativeMethods.CreateRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.CreateRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (int.TryParse("32", out var prefix))
|
||||
{
|
||||
NativeMethods.CreateRoute("1.1.1.1", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
NativeMethods.CreateRoute("8.8.8.8", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
NativeMethods.CreateRoute("9.9.9.9", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
NativeMethods.CreateRoute("185.222.222.222", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -241,59 +213,48 @@ namespace Netch.Controllers
|
||||
/// </summary>
|
||||
public bool ClearBypass()
|
||||
{
|
||||
if (SavedMode.Type == 2)
|
||||
if (_savedMode.Type == 2)
|
||||
{
|
||||
NativeMethods.DeleteRoute("0.0.0.0", 0, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index, 10);
|
||||
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
if (info.Length == 2)
|
||||
{
|
||||
if (int.TryParse(info[1], out var prefix))
|
||||
{
|
||||
NativeMethods.DeleteRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SavedMode.Type == 1)
|
||||
else if (_savedMode.Type == 1)
|
||||
{
|
||||
foreach (var ip in SavedMode.Rule)
|
||||
foreach (var ip in _savedMode.Rule)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
|
||||
if (info.Length == 2)
|
||||
{
|
||||
if (int.TryParse(info[1], out var prefix))
|
||||
{
|
||||
NativeMethods.DeleteRoute(info[0], prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Global.Settings.STUN_Server == "stun.stunprotocol.org")
|
||||
{
|
||||
try
|
||||
{
|
||||
var nttAddress = Dns.GetHostAddresses(Global.Settings.STUN_Server)[0];
|
||||
if (int.TryParse("32", out var prefix))
|
||||
{
|
||||
NativeMethods.DeleteRoute(nttAddress.ToString(), prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute(nttAddress.ToString(), prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
|
||||
var nttrAddress = Dns.GetHostAddresses("stunresponse.coldthunder11.com")[0];
|
||||
if (int.TryParse("32", out var prefixr))
|
||||
{
|
||||
NativeMethods.DeleteRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefixr)) NativeMethods.DeleteRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (Global.Settings.TUNTAP.ProxyDNS)
|
||||
{
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
{
|
||||
string dns = "";
|
||||
var dns = string.Empty;
|
||||
foreach (var value in Global.Settings.TUNTAP.DNS)
|
||||
{
|
||||
dns += value;
|
||||
@@ -302,17 +263,11 @@ namespace Netch.Controllers
|
||||
|
||||
dns = dns.Trim();
|
||||
dns = dns.Substring(0, dns.Length - 1);
|
||||
if (int.TryParse("32", out var prefix))
|
||||
{
|
||||
NativeMethods.DeleteRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (int.TryParse("32", out var prefix))
|
||||
{
|
||||
NativeMethods.DeleteRoute("1.1.1.1", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute("1.1.1.1", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,25 +277,19 @@ namespace Netch.Controllers
|
||||
var info = ip.Split('/');
|
||||
var address = IPAddress.Parse(info[0]);
|
||||
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
{
|
||||
NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
foreach (var ip in BypassLanIPs)
|
||||
|
||||
foreach (var ip in _bypassLanIPs)
|
||||
{
|
||||
var info = ip.Split('/');
|
||||
var address = IPAddress.Parse(info[0]);
|
||||
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
{
|
||||
NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
if (!IPAddress.IsLoopback(address)) NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
if (SavedMode.BypassChina)
|
||||
{
|
||||
using (var sr = new StringReader(Encoding.UTF8.GetString(Properties.Resources.CNIP)))
|
||||
if (_savedMode.BypassChina)
|
||||
using (var sr = new StringReader(Encoding.UTF8.GetString(Resources.CNIP)))
|
||||
{
|
||||
string text;
|
||||
|
||||
@@ -351,70 +300,38 @@ namespace Netch.Controllers
|
||||
NativeMethods.DeleteRoute(info[0], int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var address in ServerAddresses)
|
||||
{
|
||||
foreach (var address in _serverAddresses)
|
||||
if (!IPAddress.IsLoopback(address))
|
||||
{
|
||||
NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">配置</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting Tap")}");
|
||||
foreach (var proc in Process.GetProcessesByName("tun2socks"))
|
||||
{
|
||||
try
|
||||
{
|
||||
proc.Kill();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
Global.MainForm.StatusText(i18N.Translate("Starting Tap"));
|
||||
|
||||
if (!File.Exists("bin\\tun2socks.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_savedMode = mode;
|
||||
_savedServer = server;
|
||||
|
||||
if (File.Exists("logging\\tun2socks.log"))
|
||||
{
|
||||
File.Delete("logging\\tun2socks.log");
|
||||
}
|
||||
|
||||
SavedMode = mode;
|
||||
SavedServer = server;
|
||||
|
||||
if (!Configure())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Configure()) return false;
|
||||
|
||||
Logging.Info("设置绕行规则");
|
||||
SetupBypass();
|
||||
Logging.Info("设置绕行规则完毕");
|
||||
|
||||
Instance = new Process();
|
||||
Instance.StartInfo.WorkingDirectory = string.Format("{0}\\bin", Directory.GetCurrentDirectory());
|
||||
Instance.StartInfo.FileName = string.Format("{0}\\bin\\tun2socks.exe", Directory.GetCurrentDirectory());
|
||||
Instance = GetProcess();
|
||||
|
||||
var adapterName = TUNTAP.GetName(Global.TUNTAP.ComponentID);
|
||||
Logging.Info($"tun2sock使用适配器:{adapterName}");
|
||||
|
||||
string dns;
|
||||
//V2ray使用Unbound本地DNS会导致查询异常缓慢故此V2ray不启动unbound而是使用自定义DNS
|
||||
//if (Global.Settings.TUNTAP.UseCustomDNS || server.Type.Equals("VMess"))
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
{
|
||||
dns = "";
|
||||
dns = string.Empty;
|
||||
foreach (var value in Global.Settings.TUNTAP.DNS)
|
||||
{
|
||||
dns += value;
|
||||
@@ -428,34 +345,19 @@ namespace Netch.Controllers
|
||||
{
|
||||
pDNSController.Start();
|
||||
dns = "127.0.0.1";
|
||||
//dns = "1.1.1.1,1.0.0.1";
|
||||
}
|
||||
if (Global.Settings.TUNTAP.UseFakeDNS)
|
||||
{
|
||||
dns += " -fakeDns";
|
||||
}
|
||||
|
||||
if (Global.Settings.TUNTAP.UseFakeDNS) dns += " -fakeDns";
|
||||
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
Instance.StartInfo.Arguments = string.Format("-proxyServer {0}:{1} -tunAddr {2} -tunMask {3} -tunGw {4} -tunDns {5} -tunName \"{6}\"", server.Hostname, server.Port, Global.Settings.TUNTAP.Address, Global.Settings.TUNTAP.Netmask, Global.Settings.TUNTAP.Gateway, dns, adapterName);
|
||||
}
|
||||
Instance.StartInfo.Arguments = $"-proxyServer {server.Hostname}:{server.Port} -tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\"";
|
||||
else
|
||||
{
|
||||
Instance.StartInfo.Arguments = string.Format("-proxyServer 127.0.0.1:{0} -tunAddr {1} -tunMask {2} -tunGw {3} -tunDns {4} -tunName \"{5}\"", Global.Settings.Socks5LocalPort, Global.Settings.TUNTAP.Address, Global.Settings.TUNTAP.Netmask, Global.Settings.TUNTAP.Gateway, dns, adapterName);
|
||||
}
|
||||
Instance.StartInfo.Arguments = $"-proxyServer 127.0.0.1:{Global.Settings.Socks5LocalPort} -tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {dns} -tunName \"{adapterName}\"";
|
||||
|
||||
Instance.StartInfo.CreateNoWindow = true;
|
||||
Instance.StartInfo.RedirectStandardError = true;
|
||||
Instance.StartInfo.RedirectStandardInput = true;
|
||||
Instance.StartInfo.RedirectStandardOutput = true;
|
||||
Instance.StartInfo.UseShellExecute = false;
|
||||
Instance.EnableRaisingEvents = true;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
|
||||
Logging.Info(Instance.StartInfo.Arguments);
|
||||
|
||||
State = Models.State.Starting;
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginErrorReadLine();
|
||||
Instance.BeginOutputReadLine();
|
||||
@@ -465,13 +367,11 @@ namespace Netch.Controllers
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == Models.State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == Models.State.Stopped)
|
||||
switch (State)
|
||||
{
|
||||
case State.Started:
|
||||
return true;
|
||||
case State.Stopped:
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
@@ -481,46 +381,125 @@ namespace Netch.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
try
|
||||
var tasks = new[]
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
}
|
||||
|
||||
//pDNSController.Stop();
|
||||
//修复点击停止按钮后再启动,DNS服务没监听的BUG
|
||||
ClearBypass();
|
||||
pDNSController.Stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
Task.Factory.StartNew(StopInstance),
|
||||
Task.Factory.StartNew(ClearBypass),
|
||||
Task.Factory.StartNew(pDNSController.Stop)
|
||||
};
|
||||
Task.WaitAll(tasks);
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
/// <summary>
|
||||
/// 搜索出口
|
||||
/// </summary>
|
||||
public static bool SearchOutbounds()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\tun2socks.log", string.Format("{0}\r\n", e.Data.Trim()));
|
||||
Logging.Info("正在搜索出口中");
|
||||
|
||||
if (State == Models.State.Starting)
|
||||
if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
|
||||
{
|
||||
Global.Adapter.Index = pRoute.dwForwardIfIndex;
|
||||
Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
|
||||
Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error("GetBestRoute 搜索失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info($"搜索适配器index:{Global.Adapter.Index}");
|
||||
var AddressGot = false;
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
try
|
||||
{
|
||||
if (e.Data.Contains("Running"))
|
||||
var adapterProperties = adapter.GetIPProperties();
|
||||
var p = adapterProperties.GetIPv4Properties();
|
||||
Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}");
|
||||
|
||||
// 通过索引查找对应适配器的 IPv4 地址
|
||||
if (p.Index == Global.Adapter.Index)
|
||||
{
|
||||
State = Models.State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("failed") || e.Data.Contains("invalid vconfig file"))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
var AdapterIPs = string.Empty;
|
||||
|
||||
foreach (var ip in adapterProperties.UnicastAddresses)
|
||||
{
|
||||
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
AddressGot = true;
|
||||
Global.Adapter.Address = ip.Address;
|
||||
Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
|
||||
break;
|
||||
}
|
||||
|
||||
AdapterIPs = $"{ip.Address} | ";
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
if (AdapterIPs.Length > 3)
|
||||
{
|
||||
AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
|
||||
Logging.Info($"所有出口地址:{AdapterIPs}");
|
||||
}
|
||||
|
||||
Logging.Error("出口无 IPv4 地址,当前只支持 IPv4 地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
Logging.Error("无法找到当前使用适配器");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 搜索 TUN/TAP 适配器的索引
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
|
||||
{
|
||||
Logging.Error("未找到可用 TUN/TAP 适配器");
|
||||
if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), confirm: true) == DialogResult.OK)
|
||||
{
|
||||
Configuration.addtap();
|
||||
//给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID
|
||||
Thread.Sleep(1000);
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//MessageBoxX.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"));
|
||||
// return false;
|
||||
}
|
||||
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
if (adapter.Id == Global.TUNTAP.ComponentID)
|
||||
{
|
||||
Global.TUNTAP.Adapter = adapter;
|
||||
Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index;
|
||||
|
||||
Logging.Info($"找到适配器TUN/TAP:{adapter.Id}");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.Error("无法找到出口");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
using Netch.Forms;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NFController
|
||||
{
|
||||
/// <summary>
|
||||
/// 流量变动事件
|
||||
/// </summary>
|
||||
public event BandwidthUpdateHandler OnBandwidthUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// 流量变动处理器
|
||||
/// </summary>
|
||||
/// <param name="upload">上传</param>
|
||||
/// <param name="download">下载</param>
|
||||
public delegate void BandwidthUpdateHandler(long upload, long download);
|
||||
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
|
||||
// 生成驱动文件路径
|
||||
public string driverPath = string.Format("{0}\\drivers\\netfilter2.sys", Environment.SystemDirectory);
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <param name="StopServiceAndRestart">先停止驱动服务再重新启动</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode, bool StopServiceAndRestart)
|
||||
{
|
||||
if (!StopServiceAndRestart)
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting Redirector")}");
|
||||
|
||||
if (!File.Exists("bin\\Redirector.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查驱动是否存在
|
||||
if (File.Exists(driverPath))
|
||||
{
|
||||
// 生成系统版本
|
||||
var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
var driverName = "";
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case "10.0":
|
||||
driverName = "Win-10.sys";
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
driverName = "Win-8.sys";
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
driverName = "Win-7.sys";
|
||||
break;
|
||||
default:
|
||||
Utils.Logging.Info($"不支持的系统版本:{version}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查驱动版本号
|
||||
FileVersionInfo SystemfileVerInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(driverPath);
|
||||
FileVersionInfo BinFileVerInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(string.Format("bin\\{0}", driverName));
|
||||
|
||||
if (!SystemfileVerInfo.FileVersion.Equals(BinFileVerInfo.FileVersion))
|
||||
{
|
||||
Utils.Logging.Info("开始更新驱动");
|
||||
// 需要更新驱动
|
||||
try
|
||||
{
|
||||
var service = new ServiceController("netfilter2");
|
||||
if (service.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
nfapinet.NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
|
||||
//删除老驱动
|
||||
File.Delete(driverPath);
|
||||
if (!InstallDriver())
|
||||
return false;
|
||||
|
||||
Utils.Logging.Info($"驱动更新完毕,当前驱动版本:{BinFileVerInfo.FileVersion}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Utils.Logging.Info($"更新驱动出错");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!InstallDriver())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 启动驱动服务
|
||||
var service = new ServiceController("netfilter2");
|
||||
if (service.Status == ServiceControllerStatus.Running && StopServiceAndRestart)
|
||||
{
|
||||
// 防止其他程序占用 重置 NF 百万连接数限制
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting netfilter2 Service")}");
|
||||
service.Start();
|
||||
}
|
||||
else if (service.Status == ServiceControllerStatus.Stopped)
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting netfilter2 Service")}");
|
||||
service.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
|
||||
var result = nfapinet.NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result != nfapinet.NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Utils.Logging.Info($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var processes = "";
|
||||
foreach (var proc in mode.Rule)
|
||||
{
|
||||
processes += proc;
|
||||
processes += ",";
|
||||
}
|
||||
processes += "NTT.exe";
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\Redirector.exe";
|
||||
Instance.StartInfo.Arguments = "";
|
||||
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
Instance.StartInfo.Arguments += $"-r 127.0.0.1:{Global.Settings.Socks5LocalPort} -p \"{processes}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Utils.DNS.Lookup(server.Hostname);
|
||||
if (result == null)
|
||||
{
|
||||
Utils.Logging.Info("无法解析服务器 IP 地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $"-r {result}:{server.Port} -p \"{processes}\"";
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -username \"{server.Username}\" -password \"{server.Password}\"";
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists("logging\\redirector.log"))
|
||||
{
|
||||
File.Delete("logging\\redirector.log");
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -t {Global.Settings.RedirectorTCPPort}";
|
||||
Utils.Logging.Info(Instance.StartInfo.Arguments);
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
State = Models.State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
|
||||
if (State == Models.State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Utils.Logging.Info("NF 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
public bool InstallDriver()
|
||||
{
|
||||
|
||||
Utils.Logging.Info("安装驱动中");
|
||||
// 生成系统版本
|
||||
var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
|
||||
// 检查系统版本并复制对应驱动
|
||||
try
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case "10.0":
|
||||
File.Copy("bin\\Win-10.sys", driverPath);
|
||||
Utils.Logging.Info("已复制 Win10 驱动");
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
File.Copy("bin\\Win-8.sys", driverPath);
|
||||
Utils.Logging.Info("已复制 Win8 驱动");
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
File.Copy("bin\\Win-7.sys", driverPath);
|
||||
Utils.Logging.Info("已复制 Win7 驱动");
|
||||
break;
|
||||
default:
|
||||
Utils.Logging.Info($"不支持的系统版本:{version}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info("复制驱动文件失败");
|
||||
Utils.Logging.Info(e.ToString());
|
||||
return false;
|
||||
}
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Register driver")}");
|
||||
// 注册驱动文件
|
||||
var result = nfapinet.NFAPI.nf_registerDriver("netfilter2");
|
||||
if (result != nfapinet.NF_STATUS.NF_STATUS_SUCCESS)
|
||||
{
|
||||
Utils.Logging.Info($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\redirector.log", string.Format("{0}\r\n", e.Data));
|
||||
|
||||
if (State == Models.State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("Started"))
|
||||
{
|
||||
State = Models.State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("Failed") || e.Data.Contains("Unable"))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
}
|
||||
else if (State == Models.State.Started)
|
||||
{
|
||||
if (e.Data.StartsWith("[APP][Bandwidth]"))
|
||||
{
|
||||
var splited = e.Data.Replace("[APP][Bandwidth]", "").Trim().Split(',');
|
||||
if (splited.Length == 2)
|
||||
{
|
||||
var uploadSplited = splited[0].Split(':');
|
||||
var downloadSplited = splited[1].Split(':');
|
||||
|
||||
if (uploadSplited.Length == 2 && downloadSplited.Length == 2)
|
||||
{
|
||||
if (long.TryParse(uploadSplited[1], out var upload) && long.TryParse(downloadSplited[1], out var download))
|
||||
{
|
||||
Task.Run(() => OnBandwidthUpdated(upload, download));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +1,65 @@
|
||||
using Netch.Forms;
|
||||
using System;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NTTController
|
||||
public class NTTController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
private string _lastResult;
|
||||
|
||||
public NTTController()
|
||||
{
|
||||
Name = "NTT";
|
||||
MainFile = "NTT.exe";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动NatTypeTester
|
||||
/// 启动 NatTypeTester
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public (bool, string, string, string) Start()
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
MainForm.Instance.NatTypeStatusText($"{Utils.i18N.Translate("Starting NatTester")}");
|
||||
try
|
||||
{
|
||||
if (!File.Exists("bin\\NTT.exe"))
|
||||
{
|
||||
return (false, null, null, null);
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\NTT.exe";
|
||||
Instance = GetProcess();
|
||||
|
||||
Instance.StartInfo.Arguments = $" {Global.Settings.STUN_Server} {Global.Settings.STUN_Server_Port}";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = Models.State.Starting;
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
Instance.WaitForExit();
|
||||
|
||||
string[] result = File.ReadAllText("logging\\NTT.log").ToString().Split('#');
|
||||
var result = _lastResult.Split('#');
|
||||
var natType = result[0];
|
||||
var localEnd = result[1];
|
||||
var publicEnd = result[2];
|
||||
MainForm.Instance.NatTypeStatusText(natType);
|
||||
|
||||
return (true, natType, localEnd, publicEnd);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info("NTT 进程出错");
|
||||
Logging.Error("NTT 进程出错\n" + e);
|
||||
Stop();
|
||||
return (false, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
private new void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
_lastResult = e.Data;
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
public override void Stop()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
if (File.Exists("logging\\NTT.log"))
|
||||
{
|
||||
File.Delete("logging\\NTT.log");
|
||||
}
|
||||
|
||||
File.AppendAllText("logging\\NTT.log", $"{e.Data}\r\n");
|
||||
}
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +1,50 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class PrivoxyController
|
||||
public class PrivoxyController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
public PrivoxyController()
|
||||
{
|
||||
foreach (var proc in Process.GetProcessesByName("Privoxy"))
|
||||
{
|
||||
try
|
||||
{
|
||||
proc.Kill();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
Name = "Privoxy";
|
||||
MainFile = "Privoxy.exe";
|
||||
RedirectStd = false;
|
||||
}
|
||||
|
||||
if (!File.Exists("bin\\Privoxy.exe") || !File.Exists("bin\\default.conf"))
|
||||
public bool Start(Server server, Mode mode)
|
||||
{
|
||||
var isSocks5 = server.Type == "Socks5";
|
||||
var socks5Port = isSocks5 ? server.Port : Global.Settings.Socks5LocalPort;
|
||||
var text = File.ReadAllText("bin\\default.conf")
|
||||
.Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString())
|
||||
.Replace("_DEST_PORT_", socks5Port.ToString())
|
||||
.Replace("0.0.0.0", Global.Settings.LocalAddress);
|
||||
if (isSocks5)
|
||||
text = text.Replace("/ 127.0.0.1", $"/ {server.Hostname}");
|
||||
File.WriteAllText("data\\privoxy.conf", text);
|
||||
|
||||
Instance = GetProcess();
|
||||
Instance.StartInfo.Arguments = "..\\data\\privoxy.conf";
|
||||
Instance.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
Instance.StartInfo.UseShellExecute = true;
|
||||
try
|
||||
{
|
||||
Instance.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
File.WriteAllText("data\\privoxy.conf", File.ReadAllText("bin\\default.conf").Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString()).Replace("_DEST_PORT_", Global.Settings.Socks5LocalPort.ToString()).Replace("0.0.0.0", Global.Settings.LocalAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText("data\\privoxy.conf", File.ReadAllText("bin\\default.conf").Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString()).Replace("_DEST_PORT_", server.Port.ToString()).Replace("s 0.0.0.0", $"s {Global.Settings.LocalAddress}").Replace("/ 127.0.0.1", $"/ {server.Hostname}"));
|
||||
}
|
||||
|
||||
|
||||
Instance = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
FileName = string.Format("{0}\\bin\\Privoxy.exe", Directory.GetCurrentDirectory()),
|
||||
Arguments = "..\\data\\privoxy.conf",
|
||||
WorkingDirectory = string.Format("{0}\\bin", Directory.GetCurrentDirectory()),
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = true,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
Instance.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
StopInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSController
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting Shadowsocks")}");
|
||||
|
||||
File.Delete("logging\\shadowsocks.log");
|
||||
//从DLL启动Shaowsocks
|
||||
if (Global.Settings.BootShadowsocksFromDLL && (mode.Type == 0 || mode.Type == 1 || mode.Type == 2 || mode.Type == 3))
|
||||
{
|
||||
State = Models.State.Starting;
|
||||
var client = Encoding.UTF8.GetBytes($"0.0.0.0:{Global.Settings.Socks5LocalPort}");
|
||||
var remote = Encoding.UTF8.GetBytes($"{server.Hostname}:{server.Port}");
|
||||
var passwd = Encoding.UTF8.GetBytes($"{server.Password}");
|
||||
var method = Encoding.UTF8.GetBytes($"{server.EncryptMethod}");
|
||||
if (!NativeMethods.Shadowsocks.Info(client, remote, passwd, method))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
Logging.Info("DLL SS INFO 设置失败!");
|
||||
return false;
|
||||
}
|
||||
Logging.Info("DLL SS INFO 设置成功!");
|
||||
|
||||
if (!NativeMethods.Shadowsocks.Start())
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
Logging.Info("DLL SS 启动失败!");
|
||||
return false;
|
||||
}
|
||||
Logging.Info("DLL SS 启动成功!");
|
||||
State = Models.State.Started;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!File.Exists("bin\\Shadowsocks.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\Shadowsocks.exe";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(server.Plugin) && !string.IsNullOrWhiteSpace(server.PluginOption))
|
||||
{
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u --plugin {server.Plugin} --plugin-opts \"{server.PluginOption}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u";
|
||||
}
|
||||
|
||||
if (mode.BypassChina)
|
||||
{
|
||||
Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
}
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = Models.State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == Models.State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == Models.State.Stopped)
|
||||
{
|
||||
Utils.Logging.Info("SS 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Utils.Logging.Info("SS 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Global.Settings.BootShadowsocksFromDLL)
|
||||
{
|
||||
NativeMethods.Shadowsocks.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\shadowsocks.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == Models.State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("listening at"))
|
||||
{
|
||||
State = Models.State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage") || e.Data.Contains("plugin service exit unexpectedly"))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
using Netch.Forms;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSRController
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting ShadowsocksR")}");
|
||||
|
||||
File.Delete("logging\\shadowsocksr.log");
|
||||
|
||||
if (!File.Exists("bin\\ShadowsocksR.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\ShadowsocksR.exe";
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -k \"{server.Password}\" -m {server.EncryptMethod} -t 120";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.Protocol))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -O {server.Protocol}";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.ProtocolParam))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -G \"{server.ProtocolParam}\"";
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(server.OBFS))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -o {server.OBFS}";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.OBFSParam))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -g \"{server.OBFSParam}\"";
|
||||
}
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -u";
|
||||
|
||||
if (mode.BypassChina)
|
||||
{
|
||||
Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
}
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = Models.State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == Models.State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == Models.State.Stopped)
|
||||
{
|
||||
Utils.Logging.Info("SSR 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Utils.Logging.Info("SSR 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\shadowsocksr.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == Models.State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("listening at"))
|
||||
{
|
||||
State = Models.State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage"))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
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;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TrojanController
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
{
|
||||
Forms.MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting Trojan")}");
|
||||
|
||||
File.Delete("logging\\trojan.log");
|
||||
if (!File.Exists("bin\\Trojan.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
File.WriteAllText("data\\last.json", Newtonsoft.Json.JsonConvert.SerializeObject(new Models.Trojan()
|
||||
{
|
||||
local_addr = Global.Settings.LocalAddress,
|
||||
local_port = Global.Settings.Socks5LocalPort,
|
||||
remote_addr = server.Hostname,
|
||||
remote_port = server.Port,
|
||||
password = new List<string>()
|
||||
{
|
||||
server.Password
|
||||
}
|
||||
}));
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\Trojan.exe";
|
||||
Instance.StartInfo.Arguments = "-c ..\\data\\last.json";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = Models.State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == Models.State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == Models.State.Stopped)
|
||||
{
|
||||
Utils.Logging.Info("Trojan 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Utils.Logging.Info("Trojan 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\trojan.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == Models.State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("started"))
|
||||
{
|
||||
State = Models.State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("exiting"))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
using Netch.Models.GitHubRelease;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Netch.Models.GitHubRelease;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
@@ -14,8 +14,12 @@ namespace Netch.Controllers
|
||||
|
||||
private const int DefaultGetTimeout = 30000;
|
||||
|
||||
private const string Owner = @"NetchX";
|
||||
private const string Repo = @"Netch";
|
||||
public const string Owner = @"NetchX";
|
||||
public const string Repo = @"Netch";
|
||||
|
||||
public const string Name = @"Netch";
|
||||
public const string Copyright = @"Copyright © 2019 - 2020";
|
||||
public const string Version = @"1.4.12";
|
||||
|
||||
public string LatestVersionNumber;
|
||||
public string LatestVersionUrl;
|
||||
@@ -24,10 +28,6 @@ namespace Netch.Controllers
|
||||
public event EventHandler NewVersionFoundFailed;
|
||||
public event EventHandler NewVersionNotFound;
|
||||
|
||||
public const string Name = @"Netch";
|
||||
public const string Copyright = @"Copyright © 2019 - 2020";
|
||||
public const string Version = @"1.4.7";
|
||||
|
||||
public async void Check(bool notifyNoFound, bool isPreRelease)
|
||||
{
|
||||
try
|
||||
@@ -48,19 +48,13 @@ namespace Netch.Controllers
|
||||
else
|
||||
{
|
||||
LatestVersionNumber = latestRelease.tag_name;
|
||||
if (notifyNoFound)
|
||||
{
|
||||
NewVersionNotFound?.Invoke(this, new EventArgs());
|
||||
}
|
||||
if (notifyNoFound) NewVersionNotFound?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
if (notifyNoFound)
|
||||
{
|
||||
NewVersionFoundFailed?.Invoke(this, new EventArgs());
|
||||
}
|
||||
Debug.WriteLine(e.ToString());
|
||||
if (notifyNoFound) NewVersionFoundFailed?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
using Netch.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class VMessController
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public Models.State State = Models.State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Models.Server server, Models.Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText($"{Utils.i18N.Translate("Status")}{Utils.i18N.Translate(": ")}{Utils.i18N.Translate("Starting V2ray")}");
|
||||
if (!File.Exists("bin\\v2ray.exe") || !File.Exists("bin\\v2ctl.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
File.WriteAllText("data\\last.json", Newtonsoft.Json.JsonConvert.SerializeObject(new Models.Information.VMess.Config
|
||||
{
|
||||
inbounds = new List<Models.Information.VMess.Inbounds>
|
||||
{
|
||||
new Models.Information.VMess.Inbounds
|
||||
{
|
||||
settings = new Models.Information.VMess.InboundSettings(),
|
||||
port = Global.Settings.Socks5LocalPort,
|
||||
listen = Global.Settings.LocalAddress
|
||||
}
|
||||
},
|
||||
outbounds = new List<Models.Information.VMess.Outbounds>
|
||||
{
|
||||
new Models.Information.VMess.Outbounds
|
||||
{
|
||||
settings = new Models.Information.VMess.OutboundSettings
|
||||
{
|
||||
vnext = new List<Models.Information.VMess.VNext>
|
||||
{
|
||||
new Models.Information.VMess.VNext
|
||||
{
|
||||
address = server.Hostname,
|
||||
port = server.Port,
|
||||
users = new List<Models.Information.VMess.User>
|
||||
{
|
||||
new Models.Information.VMess.User
|
||||
{
|
||||
id = server.UserID,
|
||||
alterId = server.AlterID,
|
||||
security = server.EncryptMethod
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
streamSettings = new Models.Information.VMess.StreamSettings
|
||||
{
|
||||
network = server.TransferProtocol,
|
||||
security = server.TLSSecure ? "tls" : "",
|
||||
wsSettings = server.TransferProtocol == "ws" ? new Models.Information.VMess.WebSocketSettings
|
||||
{
|
||||
path = server.Path == "" ? "/" : server.Path,
|
||||
headers = new Models.Information.VMess.WSHeaders
|
||||
{
|
||||
Host = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
} : null,
|
||||
tcpSettings = server.FakeType == "http" ? new Models.Information.VMess.TCPSettings
|
||||
{
|
||||
header = new Models.Information.VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType,
|
||||
request = new Models.Information.VMess.TCPRequest
|
||||
{
|
||||
path = server.Path == "" ? "/" : server.Path,
|
||||
headers = new Models.Information.VMess.TCPRequestHeaders
|
||||
{
|
||||
Host = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
}
|
||||
}
|
||||
} : null,
|
||||
kcpSettings = server.TransferProtocol == "kcp" ? new Models.Information.VMess.KCPSettings
|
||||
{
|
||||
header = new Models.Information.VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType
|
||||
}
|
||||
} : null,
|
||||
quicSettings = server.TransferProtocol == "quic" ? new Models.Information.VMess.QUICSettings
|
||||
{
|
||||
security = server.QUICSecure,
|
||||
key = server.QUICSecret,
|
||||
header = new Models.Information.VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType
|
||||
}
|
||||
} : null,
|
||||
httpSettings = server.TransferProtocol == "h2" ? new Models.Information.VMess.HTTPSettings
|
||||
{
|
||||
host = server.Host == "" ? server.Hostname : server.Host,
|
||||
path = server.Path == "" ? "/" : server.Path
|
||||
} : null,
|
||||
tlsSettings = new Models.Information.VMess.TLSSettings
|
||||
{
|
||||
allowInsecure = true,
|
||||
serverName = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
},
|
||||
mux = new Models.Information.VMess.OutboundMux
|
||||
{
|
||||
enabled = server.UseMux
|
||||
}
|
||||
}
|
||||
},
|
||||
routing = new Models.Information.VMess.Routing
|
||||
{
|
||||
rules = new List<Models.Information.VMess.RoutingRules>
|
||||
{
|
||||
mode.BypassChina ? new Models.Information.VMess.RoutingRules
|
||||
{
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
|
||||
},
|
||||
domain = new List<string>
|
||||
{
|
||||
"geosite:cn"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
} : new Models.Information.VMess.RoutingRules
|
||||
{
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:private"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// 清理上一次的日志文件,防止淤积占用磁盘空间
|
||||
if (Directory.Exists("logging"))
|
||||
{
|
||||
if (File.Exists("logging\\v2ray.log"))
|
||||
{
|
||||
File.Delete("logging\\v2ray.log");
|
||||
}
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\v2ray.exe";
|
||||
Instance.StartInfo.Arguments = "-config ..\\data\\last.json";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = Models.State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == Models.State.Started)
|
||||
{
|
||||
if (File.Exists("data\\last.json"))
|
||||
{
|
||||
File.Delete("data\\last.json");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (State == Models.State.Stopped)
|
||||
{
|
||||
Utils.Logging.Info("V2Ray 进程启动失败");
|
||||
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Utils.Logging.Info("V2Ray 进程启动超时");
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Utils.Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\v2ray.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == Models.State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("started"))
|
||||
{
|
||||
State = Models.State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("config file not readable") || e.Data.Contains("failed to"))
|
||||
{
|
||||
State = Models.State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
@@ -13,9 +14,9 @@ namespace Netch.Forms
|
||||
|
||||
private void AboutForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Text = Utils.i18N.Translate(Text);
|
||||
ChannelLabel.Text = Utils.i18N.Translate(ChannelLabel.Text);
|
||||
SponsorGroupBox.Text = Utils.i18N.Translate(SponsorGroupBox.Text);
|
||||
Text = i18N.Translate(Text);
|
||||
ChannelLabel.Text = i18N.Translate(ChannelLabel.Text);
|
||||
SponsorGroupBox.Text = i18N.Translate(SponsorGroupBox.Text);
|
||||
}
|
||||
|
||||
private void AboutForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
@@ -13,10 +14,10 @@ namespace Netch.Forms
|
||||
|
||||
private void GlobalBypassIPForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Text = Utils.i18N.Translate(Text);
|
||||
AddButton.Text = Utils.i18N.Translate(AddButton.Text);
|
||||
DeleteButton.Text = Utils.i18N.Translate(DeleteButton.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
Text = i18N.Translate(Text);
|
||||
AddButton.Text = i18N.Translate(AddButton.Text);
|
||||
DeleteButton.Text = i18N.Translate(DeleteButton.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
IPListBox.Items.AddRange(Global.Settings.BypassIPs.ToArray());
|
||||
|
||||
@@ -42,12 +43,12 @@ namespace Netch.Forms
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Please enter a correct IP address"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a correct IP address"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Please enter an IP"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Please enter an IP"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +60,7 @@ namespace Netch.Forms
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Please select an IP"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Please select an IP"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,8 +72,8 @@ namespace Netch.Forms
|
||||
Global.Settings.BypassIPs.Add(ip as string);
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
211
Netch/Forms/MainForm.Control.cs
Normal file
211
Netch/Forms/MainForm.Control.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public partial class Dummy
|
||||
{
|
||||
}
|
||||
|
||||
partial class MainForm
|
||||
{
|
||||
private bool _isFirstCloseWindow = true;
|
||||
|
||||
private void ControlFun()
|
||||
{
|
||||
if (State == State.Waiting || State == State.Stopped)
|
||||
{
|
||||
// 服务器、模式 需选择
|
||||
if (ServerComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a server first"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ModeComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a mode first"));
|
||||
return;
|
||||
}
|
||||
|
||||
State = State.Starting;
|
||||
|
||||
// 清除模式搜索框文本选择
|
||||
ModeComboBox.Select(0, 0);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
Task.Run(Firewall.AddNetchFwRules);
|
||||
|
||||
var server = ServerComboBox.SelectedItem as Models.Server;
|
||||
var mode = ModeComboBox.SelectedItem as Models.Mode;
|
||||
|
||||
if (_mainController.Start(server, mode))
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
State = State.Started;
|
||||
StatusTextAppend(LocalPortText(server.Type, mode.Type));
|
||||
Bandwidth.NetTraffic(server, mode, _mainController);
|
||||
});
|
||||
// 如果勾选启动后最小化
|
||||
if (Global.Settings.MinimizeWhenStarted)
|
||||
{
|
||||
WindowState = FormWindowState.Minimized;
|
||||
|
||||
if (_isFirstCloseWindow)
|
||||
{
|
||||
// 显示提示语
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name,
|
||||
i18N.Translate(
|
||||
"Netch is now minimized to the notification bar, double click this icon to restore."),
|
||||
ToolTipIcon.Info);
|
||||
|
||||
_isFirstCloseWindow = false;
|
||||
}
|
||||
|
||||
Hide();
|
||||
}
|
||||
|
||||
if (Global.Settings.StartedTcping)
|
||||
{
|
||||
// 自动检测延迟
|
||||
Task.Run(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (State == State.Started)
|
||||
{
|
||||
server.Test();
|
||||
// 重载服务器列表
|
||||
InitServer();
|
||||
|
||||
Thread.Sleep(Global.Settings.StartedTcping_Interval * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
State = State.Stopped;
|
||||
StatusText(i18N.Translate("Start failed"));
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
// 停止
|
||||
State = State.Stopping;
|
||||
_mainController.Stop();
|
||||
State = State.Stopped;
|
||||
});
|
||||
Task.Run(TestServer);
|
||||
}
|
||||
}
|
||||
|
||||
private static string LocalPortText(string serverType, int modeType)
|
||||
{
|
||||
var text = new StringBuilder(" (");
|
||||
if (Global.Settings.LocalAddress == "0.0.0.0")
|
||||
text.Append(i18N.Translate("Allow other Devices to connect") + " ");
|
||||
if (serverType == "Socks5")
|
||||
{
|
||||
// 不可控Socks5
|
||||
if (modeType == 3 || modeType == 5)
|
||||
{
|
||||
// 可控HTTP
|
||||
MainController.UsingPorts.Add(Global.Settings.HTTPLocalPort);
|
||||
text.Append($"HTTP {i18N.Translate("Local Port", ": ")}{Global.Settings.HTTPLocalPort}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 不可控HTTP
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 可控Socks5
|
||||
MainController.UsingPorts.Add(Global.Settings.Socks5LocalPort);
|
||||
text.Append($"Socks5 {i18N.Translate("Local Port", ": ")}{Global.Settings.Socks5LocalPort}");
|
||||
if (modeType == 3 || modeType == 5)
|
||||
{
|
||||
// 有HTTP
|
||||
MainController.UsingPorts.Add(Global.Settings.HTTPLocalPort);
|
||||
text.Append($" | HTTP {i18N.Translate("Local Port", ": ")}{Global.Settings.HTTPLocalPort}");
|
||||
}
|
||||
}
|
||||
|
||||
if (modeType == 0)
|
||||
MainController.UsingPorts.Add(Global.Settings.RedirectorTCPPort);
|
||||
|
||||
text.Append(")");
|
||||
return text.ToString();
|
||||
}
|
||||
|
||||
|
||||
public void OnBandwidthUpdated(long download)
|
||||
{
|
||||
try
|
||||
{
|
||||
UsedBandwidthLabel.Text = $"{i18N.Translate("Used", ": ")}{Bandwidth.Compute(download)}";
|
||||
//UploadSpeedLabel.Text = $"↑: {Utils.Bandwidth.Compute(upload - LastUploadBandwidth)}/s";
|
||||
DownloadSpeedLabel.Text = $"↑↓: {Bandwidth.Compute(download - LastDownloadBandwidth)}/s";
|
||||
|
||||
//LastUploadBandwidth = upload;
|
||||
LastDownloadBandwidth = download;
|
||||
Refresh();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void OnBandwidthUpdated(long upload, long download)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (upload < 1 || download < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UsedBandwidthLabel.Text =
|
||||
$"{i18N.Translate("Used", ": ")}{Bandwidth.Compute(upload + download)}";
|
||||
UploadSpeedLabel.Text = $"↑: {Bandwidth.Compute(upload - LastUploadBandwidth)}/s";
|
||||
DownloadSpeedLabel.Text = $"↓: {Bandwidth.Compute(download - LastDownloadBandwidth)}/s";
|
||||
|
||||
LastUploadBandwidth = upload;
|
||||
LastDownloadBandwidth = download;
|
||||
Refresh();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上一次上传的流量
|
||||
/// </summary>
|
||||
public long LastUploadBandwidth;
|
||||
|
||||
/// <summary>
|
||||
/// 上一次下载的流量
|
||||
/// </summary>
|
||||
public long LastDownloadBandwidth;
|
||||
}
|
||||
}
|
||||
300
Netch/Forms/MainForm.Designer.cs
generated
300
Netch/Forms/MainForm.Designer.cs
generated
@@ -39,23 +39,24 @@ namespace Netch.Forms
|
||||
this.AddShadowsocksServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.AddShadowsocksRServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.AddVMessServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.AddTrojanServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CreateProcessModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ManageProcessModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ReloadModesToolStripMenuItem = 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.OptionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ReloadModesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.RestartServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.OpenDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.CleanDNSCacheToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UpdateACLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.updateACLWithProxyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.reinstallTapDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.AboutToolStripButton = new System.Windows.Forms.ToolStripButton();
|
||||
this.VersionLabel = new System.Windows.Forms.ToolStripLabel();
|
||||
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.RelyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ConfigurationGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.configLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.ProfileLabel = new System.Windows.Forms.Label();
|
||||
@@ -65,9 +66,9 @@ namespace Netch.Forms
|
||||
this.ModeComboBox = new System.Windows.Forms.SearchComboBox();
|
||||
this.ServerComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.EditPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.EditServerPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.CopyLinkPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.DeletePictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.DeleteServerPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.SpeedPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.EditModePictureBox = new System.Windows.Forms.PictureBox();
|
||||
@@ -77,7 +78,9 @@ namespace Netch.Forms
|
||||
this.UsedBandwidthLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.DownloadSpeedLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.UploadSpeedLabel = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.blankToolStripStatusLabel = 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();
|
||||
this.NotifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
|
||||
this.NotifyMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
@@ -86,14 +89,13 @@ namespace Netch.Forms
|
||||
this.SettingsButton = new System.Windows.Forms.Button();
|
||||
this.ProfileGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.ProfileTable = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.AddTrojanServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MenuStrip.SuspendLayout();
|
||||
this.ConfigurationGroupBox.SuspendLayout();
|
||||
this.configLayoutPanel.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditServerPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.CopyLinkPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeletePictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeleteServerPictureBox)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.SpeedPictureBox)).BeginInit();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditModePictureBox)).BeginInit();
|
||||
@@ -114,11 +116,12 @@ namespace Netch.Forms
|
||||
this.OptionsToolStripMenuItem,
|
||||
this.AboutToolStripButton,
|
||||
this.VersionLabel,
|
||||
this.exitToolStripMenuItem});
|
||||
this.exitToolStripMenuItem,
|
||||
this.RelyToolStripMenuItem});
|
||||
this.MenuStrip.Location = new System.Drawing.Point(0, 0);
|
||||
this.MenuStrip.Name = "MenuStrip";
|
||||
this.MenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
|
||||
this.MenuStrip.Size = new System.Drawing.Size(629, 26);
|
||||
this.MenuStrip.Size = new System.Drawing.Size(733, 26);
|
||||
this.MenuStrip.TabIndex = 0;
|
||||
//
|
||||
// ServerToolStripMenuItem
|
||||
@@ -170,11 +173,18 @@ namespace Netch.Forms
|
||||
this.AddVMessServerToolStripMenuItem.Text = "Add [VMess] Server";
|
||||
this.AddVMessServerToolStripMenuItem.Click += new System.EventHandler(this.AddVMessServerToolStripMenuItem_Click);
|
||||
//
|
||||
// AddTrojanServerToolStripMenuItem
|
||||
//
|
||||
this.AddTrojanServerToolStripMenuItem.Name = "AddTrojanServerToolStripMenuItem";
|
||||
this.AddTrojanServerToolStripMenuItem.Size = new System.Drawing.Size(259, 22);
|
||||
this.AddTrojanServerToolStripMenuItem.Text = "Add [Trojan] Server";
|
||||
this.AddTrojanServerToolStripMenuItem.Click += new System.EventHandler(this.AddTrojanServerToolStripMenuItem_Click);
|
||||
//
|
||||
// ModeToolStripMenuItem
|
||||
//
|
||||
this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.CreateProcessModeToolStripMenuItem,
|
||||
this.ManageProcessModeToolStripMenuItem});
|
||||
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);
|
||||
@@ -183,16 +193,16 @@ namespace Netch.Forms
|
||||
// CreateProcessModeToolStripMenuItem
|
||||
//
|
||||
this.CreateProcessModeToolStripMenuItem.Name = "CreateProcessModeToolStripMenuItem";
|
||||
this.CreateProcessModeToolStripMenuItem.Size = new System.Drawing.Size(212, 22);
|
||||
this.CreateProcessModeToolStripMenuItem.Size = new System.Drawing.Size(202, 22);
|
||||
this.CreateProcessModeToolStripMenuItem.Text = "Create Process Mode";
|
||||
this.CreateProcessModeToolStripMenuItem.Click += new System.EventHandler(this.CreateProcessModeToolStripButton_Click);
|
||||
//
|
||||
// ManageProcessModeToolStripMenuItem
|
||||
// ReloadModesToolStripMenuItem
|
||||
//
|
||||
this.ManageProcessModeToolStripMenuItem.Name = "ManageProcessModeToolStripMenuItem";
|
||||
this.ManageProcessModeToolStripMenuItem.Size = new System.Drawing.Size(212, 22);
|
||||
this.ManageProcessModeToolStripMenuItem.Text = "Manage Process Mode";
|
||||
this.ManageProcessModeToolStripMenuItem.Click += new System.EventHandler(this.ManageProcessModeToolStripMenuItem_Click);
|
||||
this.ReloadModesToolStripMenuItem.Name = "ReloadModesToolStripMenuItem";
|
||||
this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(202, 22);
|
||||
this.ReloadModesToolStripMenuItem.Text = "Reload Modes";
|
||||
this.ReloadModesToolStripMenuItem.Click += new System.EventHandler(this.ReloadModesToolStripMenuItem_Click);
|
||||
//
|
||||
// SubscribeToolStripMenuItem
|
||||
//
|
||||
@@ -221,64 +231,56 @@ namespace Netch.Forms
|
||||
// OptionsToolStripMenuItem
|
||||
//
|
||||
this.OptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.ReloadModesToolStripMenuItem,
|
||||
this.RestartServiceToolStripMenuItem,
|
||||
this.UninstallServiceToolStripMenuItem,
|
||||
this.OpenDirectoryToolStripMenuItem,
|
||||
this.CleanDNSCacheToolStripMenuItem,
|
||||
this.UpdateACLToolStripMenuItem,
|
||||
this.updateACLWithProxyToolStripMenuItem,
|
||||
this.UninstallServiceToolStripMenuItem,
|
||||
this.reinstallTapDriverToolStripMenuItem});
|
||||
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);
|
||||
this.OptionsToolStripMenuItem.Text = "Options";
|
||||
//
|
||||
// ReloadModesToolStripMenuItem
|
||||
// OpenDirectoryToolStripMenuItem
|
||||
//
|
||||
this.ReloadModesToolStripMenuItem.Name = "ReloadModesToolStripMenuItem";
|
||||
this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.ReloadModesToolStripMenuItem.Text = "Reload Modes";
|
||||
this.ReloadModesToolStripMenuItem.Click += new System.EventHandler(this.ReloadModesToolStripMenuItem_Click);
|
||||
//
|
||||
// RestartServiceToolStripMenuItem
|
||||
//
|
||||
this.RestartServiceToolStripMenuItem.Name = "RestartServiceToolStripMenuItem";
|
||||
this.RestartServiceToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.RestartServiceToolStripMenuItem.Text = "Restart Service";
|
||||
this.RestartServiceToolStripMenuItem.Click += new System.EventHandler(this.RestartServiceToolStripMenuItem_Click);
|
||||
//
|
||||
// UninstallServiceToolStripMenuItem
|
||||
//
|
||||
this.UninstallServiceToolStripMenuItem.Name = "UninstallServiceToolStripMenuItem";
|
||||
this.UninstallServiceToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.UninstallServiceToolStripMenuItem.Text = "Uninstall Service";
|
||||
this.UninstallServiceToolStripMenuItem.Click += new System.EventHandler(this.UninstallServiceToolStripMenuItem_Click);
|
||||
this.OpenDirectoryToolStripMenuItem.Name = "OpenDirectoryToolStripMenuItem";
|
||||
this.OpenDirectoryToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
this.OpenDirectoryToolStripMenuItem.Text = "Open Directory";
|
||||
this.OpenDirectoryToolStripMenuItem.Click += new System.EventHandler(this.OpenDirectoryToolStripMenuItem_Click);
|
||||
//
|
||||
// CleanDNSCacheToolStripMenuItem
|
||||
//
|
||||
this.CleanDNSCacheToolStripMenuItem.Name = "CleanDNSCacheToolStripMenuItem";
|
||||
this.CleanDNSCacheToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.CleanDNSCacheToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
this.CleanDNSCacheToolStripMenuItem.Text = "Clean DNS Cache";
|
||||
this.CleanDNSCacheToolStripMenuItem.Click += new System.EventHandler(this.CleanDNSCacheToolStripMenuItem_Click);
|
||||
//
|
||||
// UpdateACLToolStripMenuItem
|
||||
//
|
||||
this.UpdateACLToolStripMenuItem.Name = "UpdateACLToolStripMenuItem";
|
||||
this.UpdateACLToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.UpdateACLToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
this.UpdateACLToolStripMenuItem.Text = "Update ACL";
|
||||
this.UpdateACLToolStripMenuItem.Click += new System.EventHandler(this.updateACLToolStripMenuItem_Click);
|
||||
//
|
||||
// updateACLWithProxyToolStripMenuItem
|
||||
//
|
||||
this.updateACLWithProxyToolStripMenuItem.Name = "updateACLWithProxyToolStripMenuItem";
|
||||
this.updateACLWithProxyToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.updateACLWithProxyToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
this.updateACLWithProxyToolStripMenuItem.Text = "Update ACL with proxy";
|
||||
this.updateACLWithProxyToolStripMenuItem.Click += new System.EventHandler(this.updateACLWithProxyToolStripMenuItem_Click);
|
||||
//
|
||||
// UninstallServiceToolStripMenuItem
|
||||
//
|
||||
this.UninstallServiceToolStripMenuItem.Name = "UninstallServiceToolStripMenuItem";
|
||||
this.UninstallServiceToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
this.UninstallServiceToolStripMenuItem.Text = "Uninstall NF Service";
|
||||
this.UninstallServiceToolStripMenuItem.Click += new System.EventHandler(this.UninstallServiceToolStripMenuItem_Click);
|
||||
//
|
||||
// reinstallTapDriverToolStripMenuItem
|
||||
//
|
||||
this.reinstallTapDriverToolStripMenuItem.Name = "reinstallTapDriverToolStripMenuItem";
|
||||
this.reinstallTapDriverToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
|
||||
this.reinstallTapDriverToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
|
||||
this.reinstallTapDriverToolStripMenuItem.Text = "Reinstall TUN/TAP driver";
|
||||
this.reinstallTapDriverToolStripMenuItem.Click += new System.EventHandler(this.reinstallTapDriverToolStripMenuItem_Click);
|
||||
//
|
||||
@@ -300,8 +302,8 @@ namespace Netch.Forms
|
||||
this.VersionLabel.IsLink = true;
|
||||
this.VersionLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline;
|
||||
this.VersionLabel.Name = "VersionLabel";
|
||||
this.VersionLabel.Size = new System.Drawing.Size(32, 19);
|
||||
this.VersionLabel.Text = "x.x.x";
|
||||
this.VersionLabel.Size = new System.Drawing.Size(26, 19);
|
||||
this.VersionLabel.Text = "xxx";
|
||||
this.VersionLabel.Click += new System.EventHandler(this.VersionLabel_Click);
|
||||
//
|
||||
// exitToolStripMenuItem
|
||||
@@ -311,12 +313,21 @@ namespace Netch.Forms
|
||||
this.exitToolStripMenuItem.Text = "Exit";
|
||||
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
|
||||
//
|
||||
// RelyToolStripMenuItem
|
||||
//
|
||||
this.RelyToolStripMenuItem.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.RelyToolStripMenuItem.ForeColor = System.Drawing.Color.Red;
|
||||
this.RelyToolStripMenuItem.Name = "RelyToolStripMenuItem";
|
||||
this.RelyToolStripMenuItem.Size = new System.Drawing.Size(244, 22);
|
||||
this.RelyToolStripMenuItem.Text = "Unable to start? Click me to download";
|
||||
this.RelyToolStripMenuItem.Click += new System.EventHandler(this.RelyToolStripMenuItem_Click);
|
||||
//
|
||||
// ConfigurationGroupBox
|
||||
//
|
||||
this.ConfigurationGroupBox.Controls.Add(this.configLayoutPanel);
|
||||
this.ConfigurationGroupBox.Location = new System.Drawing.Point(12, 28);
|
||||
this.ConfigurationGroupBox.Name = "ConfigurationGroupBox";
|
||||
this.ConfigurationGroupBox.Size = new System.Drawing.Size(605, 115);
|
||||
this.ConfigurationGroupBox.Size = new System.Drawing.Size(709, 115);
|
||||
this.ConfigurationGroupBox.TabIndex = 1;
|
||||
this.ConfigurationGroupBox.TabStop = false;
|
||||
this.ConfigurationGroupBox.Text = "Configuration";
|
||||
@@ -325,7 +336,7 @@ namespace Netch.Forms
|
||||
//
|
||||
this.configLayoutPanel.ColumnCount = 3;
|
||||
this.configLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.configLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.configLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.configLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.configLayoutPanel.Controls.Add(this.ProfileLabel, 0, 2);
|
||||
this.configLayoutPanel.Controls.Add(this.ModeLabel, 0, 1);
|
||||
@@ -342,7 +353,7 @@ namespace Netch.Forms
|
||||
this.configLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.configLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.configLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.configLayoutPanel.Size = new System.Drawing.Size(599, 93);
|
||||
this.configLayoutPanel.Size = new System.Drawing.Size(703, 93);
|
||||
this.configLayoutPanel.TabIndex = 15;
|
||||
//
|
||||
// ProfileLabel
|
||||
@@ -380,7 +391,7 @@ namespace Netch.Forms
|
||||
this.ProfileNameText.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ProfileNameText.Location = new System.Drawing.Point(54, 65);
|
||||
this.ProfileNameText.Name = "ProfileNameText";
|
||||
this.ProfileNameText.Size = new System.Drawing.Size(442, 23);
|
||||
this.ProfileNameText.Size = new System.Drawing.Size(546, 23);
|
||||
this.ProfileNameText.TabIndex = 11;
|
||||
//
|
||||
// ModeComboBox
|
||||
@@ -392,7 +403,7 @@ namespace Netch.Forms
|
||||
this.ModeComboBox.IntegralHeight = false;
|
||||
this.ModeComboBox.Location = new System.Drawing.Point(54, 34);
|
||||
this.ModeComboBox.Name = "ModeComboBox";
|
||||
this.ModeComboBox.Size = new System.Drawing.Size(442, 24);
|
||||
this.ModeComboBox.Size = new System.Drawing.Size(546, 24);
|
||||
this.ModeComboBox.TabIndex = 2;
|
||||
this.ModeComboBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ComboBox_DrawItem);
|
||||
//
|
||||
@@ -406,7 +417,7 @@ namespace Netch.Forms
|
||||
this.ServerComboBox.Location = new System.Drawing.Point(54, 3);
|
||||
this.ServerComboBox.MaxDropDownItems = 16;
|
||||
this.ServerComboBox.Name = "ServerComboBox";
|
||||
this.ServerComboBox.Size = new System.Drawing.Size(442, 24);
|
||||
this.ServerComboBox.Size = new System.Drawing.Size(546, 24);
|
||||
this.ServerComboBox.TabIndex = 1;
|
||||
this.ServerComboBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.ComboBox_DrawItem);
|
||||
//
|
||||
@@ -417,27 +428,28 @@ namespace Netch.Forms
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.EditPictureBox, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.EditServerPictureBox, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.CopyLinkPictureBox, 3, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.DeletePictureBox, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.DeleteServerPictureBox, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.SpeedPictureBox, 2, 0);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(502, 3);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(606, 3);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 1;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(94, 24);
|
||||
this.tableLayoutPanel2.TabIndex = 12;
|
||||
//
|
||||
// EditPictureBox
|
||||
// EditServerPictureBox
|
||||
//
|
||||
this.EditPictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.EditPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("EditPictureBox.Image")));
|
||||
this.EditPictureBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.EditPictureBox.Name = "EditPictureBox";
|
||||
this.EditPictureBox.Size = new System.Drawing.Size(16, 16);
|
||||
this.EditPictureBox.TabIndex = 7;
|
||||
this.EditPictureBox.TabStop = false;
|
||||
this.EditPictureBox.Click += new System.EventHandler(this.EditPictureBox_Click);
|
||||
this.EditServerPictureBox.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.EditServerPictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.EditServerPictureBox.Image = global::Netch.Properties.Resources.edit;
|
||||
this.EditServerPictureBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.EditServerPictureBox.Name = "EditServerPictureBox";
|
||||
this.EditServerPictureBox.Size = new System.Drawing.Size(16, 16);
|
||||
this.EditServerPictureBox.TabIndex = 7;
|
||||
this.EditServerPictureBox.TabStop = false;
|
||||
this.EditServerPictureBox.Click += new System.EventHandler(this.EditServerPictureBox_Click);
|
||||
//
|
||||
// CopyLinkPictureBox
|
||||
//
|
||||
@@ -450,21 +462,21 @@ namespace Netch.Forms
|
||||
this.CopyLinkPictureBox.TabStop = false;
|
||||
this.CopyLinkPictureBox.Click += new System.EventHandler(this.CopyLinkPictureBox_Click);
|
||||
//
|
||||
// DeletePictureBox
|
||||
// DeleteServerPictureBox
|
||||
//
|
||||
this.DeletePictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.DeletePictureBox.Image = ((System.Drawing.Image)(resources.GetObject("DeletePictureBox.Image")));
|
||||
this.DeletePictureBox.Location = new System.Drawing.Point(26, 3);
|
||||
this.DeletePictureBox.Name = "DeletePictureBox";
|
||||
this.DeletePictureBox.Size = new System.Drawing.Size(16, 16);
|
||||
this.DeletePictureBox.TabIndex = 8;
|
||||
this.DeletePictureBox.TabStop = false;
|
||||
this.DeletePictureBox.Click += new System.EventHandler(this.DeletePictureBox_Click);
|
||||
this.DeleteServerPictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.DeleteServerPictureBox.Image = global::Netch.Properties.Resources.delete;
|
||||
this.DeleteServerPictureBox.Location = new System.Drawing.Point(26, 3);
|
||||
this.DeleteServerPictureBox.Name = "DeleteServerPictureBox";
|
||||
this.DeleteServerPictureBox.Size = new System.Drawing.Size(16, 16);
|
||||
this.DeleteServerPictureBox.TabIndex = 8;
|
||||
this.DeleteServerPictureBox.TabStop = false;
|
||||
this.DeleteServerPictureBox.Click += new System.EventHandler(this.DeleteServerPictureBox_Click);
|
||||
//
|
||||
// SpeedPictureBox
|
||||
//
|
||||
this.SpeedPictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.SpeedPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("SpeedPictureBox.Image")));
|
||||
this.SpeedPictureBox.Image = global::Netch.Properties.Resources.speed;
|
||||
this.SpeedPictureBox.Location = new System.Drawing.Point(49, 3);
|
||||
this.SpeedPictureBox.Name = "SpeedPictureBox";
|
||||
this.SpeedPictureBox.Size = new System.Drawing.Size(16, 16);
|
||||
@@ -481,7 +493,7 @@ namespace Netch.Forms
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
|
||||
this.tableLayoutPanel3.Controls.Add(this.EditModePictureBox, 0, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.DeleteModePictureBox, 1, 0);
|
||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(502, 34);
|
||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(606, 34);
|
||||
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
this.tableLayoutPanel3.RowCount = 1;
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
@@ -491,9 +503,7 @@ namespace Netch.Forms
|
||||
// EditModePictureBox
|
||||
//
|
||||
this.EditModePictureBox.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.EditModePictureBox.ErrorImage = global::Netch.Properties.Resources.edit;
|
||||
this.EditModePictureBox.Image = global::Netch.Properties.Resources.edit;
|
||||
this.EditModePictureBox.InitialImage = global::Netch.Properties.Resources.edit;
|
||||
this.EditModePictureBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.EditModePictureBox.Name = "EditModePictureBox";
|
||||
this.EditModePictureBox.Size = new System.Drawing.Size(16, 16);
|
||||
@@ -520,10 +530,12 @@ namespace Netch.Forms
|
||||
this.UsedBandwidthLabel,
|
||||
this.DownloadSpeedLabel,
|
||||
this.UploadSpeedLabel,
|
||||
this.NatTypeStatusLabel});
|
||||
this.blankToolStripStatusLabel,
|
||||
this.NatTypeStatusLabel,
|
||||
this.NatTypeStatusLightLabel});
|
||||
this.StatusStrip.Location = new System.Drawing.Point(0, 250);
|
||||
this.StatusStrip.Name = "StatusStrip";
|
||||
this.StatusStrip.Size = new System.Drawing.Size(629, 22);
|
||||
this.StatusStrip.Size = new System.Drawing.Size(733, 22);
|
||||
this.StatusStrip.SizingGrip = false;
|
||||
this.StatusStrip.TabIndex = 2;
|
||||
//
|
||||
@@ -555,15 +567,34 @@ namespace Netch.Forms
|
||||
this.UploadSpeedLabel.Text = "↑: 0 KB/s";
|
||||
this.UploadSpeedLabel.Visible = false;
|
||||
//
|
||||
// blankToolStripStatusLabel
|
||||
//
|
||||
this.blankToolStripStatusLabel.Name = "blankToolStripStatusLabel";
|
||||
this.blankToolStripStatusLabel.Size = new System.Drawing.Size(268, 17);
|
||||
this.blankToolStripStatusLabel.Spring = true;
|
||||
//
|
||||
// NatTypeStatusLabel
|
||||
//
|
||||
this.NatTypeStatusLabel.Name = "NatTypeStatusLabel";
|
||||
this.NatTypeStatusLabel.Size = new System.Drawing.Size(0, 17);
|
||||
this.NatTypeStatusLabel.Size = new System.Drawing.Size(36, 17);
|
||||
this.NatTypeStatusLabel.Text = "NAT:";
|
||||
this.NatTypeStatusLabel.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
|
||||
//
|
||||
// NatTypeStatusLightLabel
|
||||
//
|
||||
this.NatTypeStatusLightLabel.ActiveLinkColor = System.Drawing.Color.Red;
|
||||
this.NatTypeStatusLightLabel.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
|
||||
this.NatTypeStatusLightLabel.ForeColor = System.Drawing.Color.Red;
|
||||
this.NatTypeStatusLightLabel.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.NatTypeStatusLightLabel.Name = "NatTypeStatusLightLabel";
|
||||
this.NatTypeStatusLightLabel.Size = new System.Drawing.Size(18, 21);
|
||||
this.NatTypeStatusLightLabel.Text = "⬤";
|
||||
this.NatTypeStatusLightLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
|
||||
//
|
||||
// ControlButton
|
||||
//
|
||||
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.ControlButton.Location = new System.Drawing.Point(542, 215);
|
||||
this.ControlButton.Location = new System.Drawing.Point(646, 214);
|
||||
this.ControlButton.Name = "ControlButton";
|
||||
this.ControlButton.Size = new System.Drawing.Size(75, 27);
|
||||
this.ControlButton.TabIndex = 3;
|
||||
@@ -619,7 +650,7 @@ namespace Netch.Forms
|
||||
this.ProfileGroupBox.Controls.Add(this.ProfileTable);
|
||||
this.ProfileGroupBox.Location = new System.Drawing.Point(12, 146);
|
||||
this.ProfileGroupBox.Name = "ProfileGroupBox";
|
||||
this.ProfileGroupBox.Size = new System.Drawing.Size(605, 65);
|
||||
this.ProfileGroupBox.Size = new System.Drawing.Size(709, 65);
|
||||
this.ProfileGroupBox.TabIndex = 13;
|
||||
this.ProfileGroupBox.TabStop = false;
|
||||
this.ProfileGroupBox.Text = "Profiles";
|
||||
@@ -637,21 +668,14 @@ namespace Netch.Forms
|
||||
this.ProfileTable.RowCount = 1;
|
||||
this.ProfileTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.ProfileTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.ProfileTable.Size = new System.Drawing.Size(599, 43);
|
||||
this.ProfileTable.Size = new System.Drawing.Size(703, 43);
|
||||
this.ProfileTable.TabIndex = 0;
|
||||
//
|
||||
// AddTrojanServerToolStripMenuItem
|
||||
//
|
||||
this.AddTrojanServerToolStripMenuItem.Name = "AddTrojanServerToolStripMenuItem";
|
||||
this.AddTrojanServerToolStripMenuItem.Size = new System.Drawing.Size(259, 22);
|
||||
this.AddTrojanServerToolStripMenuItem.Text = "Add [Trojan] Server";
|
||||
this.AddTrojanServerToolStripMenuItem.Click += new System.EventHandler(this.AddTrojanServerToolStripMenuItem_Click);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
|
||||
this.ClientSize = new System.Drawing.Size(629, 272);
|
||||
this.ClientSize = new System.Drawing.Size(733, 272);
|
||||
this.Controls.Add(this.ProfileGroupBox);
|
||||
this.Controls.Add(this.SettingsButton);
|
||||
this.Controls.Add(this.ControlButton);
|
||||
@@ -668,15 +692,16 @@ namespace Netch.Forms
|
||||
this.Text = "Netch";
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
|
||||
this.Load += new System.EventHandler(this.MainForm_Load);
|
||||
this.VisibleChanged += new System.EventHandler(this.MainForm_VisibleChanged);
|
||||
this.MenuStrip.ResumeLayout(false);
|
||||
this.MenuStrip.PerformLayout();
|
||||
this.ConfigurationGroupBox.ResumeLayout(false);
|
||||
this.configLayoutPanel.ResumeLayout(false);
|
||||
this.configLayoutPanel.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditServerPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.CopyLinkPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeletePictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DeleteServerPictureBox)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.SpeedPictureBox)).EndInit();
|
||||
this.tableLayoutPanel3.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.EditModePictureBox)).EndInit();
|
||||
@@ -691,62 +716,65 @@ namespace Netch.Forms
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.MenuStrip MenuStrip;
|
||||
private System.Windows.Forms.ToolStripMenuItem ServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SubscribeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripLabel VersionLabel;
|
||||
private System.Windows.Forms.GroupBox ConfigurationGroupBox;
|
||||
private System.Windows.Forms.Label ServerLabel;
|
||||
private System.Windows.Forms.Label ModeLabel;
|
||||
private System.Windows.Forms.SearchComboBox ModeComboBox;
|
||||
private System.Windows.Forms.ComboBox ServerComboBox;
|
||||
private System.Windows.Forms.StatusStrip StatusStrip;
|
||||
private System.Windows.Forms.ToolStripStatusLabel StatusLabel;
|
||||
private System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddSocks5ServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddShadowsocksServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripButton AboutToolStripButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddShadowsocksRServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddShadowsocksServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddSocks5ServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddTrojanServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddVMessServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem CleanDNSCacheToolStripMenuItem;
|
||||
private System.Windows.Forms.TableLayoutPanel configLayoutPanel;
|
||||
private System.Windows.Forms.GroupBox ConfigurationGroupBox;
|
||||
private System.Windows.Forms.Button ControlButton;
|
||||
private System.Windows.Forms.PictureBox CopyLinkPictureBox;
|
||||
private System.Windows.Forms.ToolStripMenuItem CreateProcessModeToolStripMenuItem;
|
||||
private System.Windows.Forms.PictureBox DeleteModePictureBox;
|
||||
private System.Windows.Forms.PictureBox DeleteServerPictureBox;
|
||||
private System.Windows.Forms.ToolStripStatusLabel DownloadSpeedLabel;
|
||||
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 ImportServersFromClipboardToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ManageSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.PictureBox SpeedPictureBox;
|
||||
private System.Windows.Forms.PictureBox DeletePictureBox;
|
||||
private System.Windows.Forms.PictureBox EditPictureBox;
|
||||
private System.Windows.Forms.ToolStripMenuItem RestartServiceToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UninstallServiceToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem OptionsToolStripMenuItem;
|
||||
private System.Windows.Forms.MenuStrip MenuStrip;
|
||||
private System.Windows.Forms.SearchComboBox ModeComboBox;
|
||||
private System.Windows.Forms.Label ModeLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem ModeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem CreateProcessModeToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ReloadModesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripStatusLabel NatTypeStatusLabel;
|
||||
private System.Windows.Forms.NotifyIcon NotifyIcon;
|
||||
private System.Windows.Forms.ContextMenuStrip NotifyMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem ShowMainFormToolStripButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem ExitToolStripButton;
|
||||
private System.Windows.Forms.Button SettingsButton;
|
||||
private System.Windows.Forms.ToolStripButton AboutToolStripButton;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UsedBandwidthLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UploadSpeedLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel DownloadSpeedLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem CleanDNSCacheToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem OpenDirectoryToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem OptionsToolStripMenuItem;
|
||||
private System.Windows.Forms.GroupBox ProfileGroupBox;
|
||||
private System.Windows.Forms.Label ProfileLabel;
|
||||
private System.Windows.Forms.TextBox ProfileNameText;
|
||||
private System.Windows.Forms.GroupBox ProfileGroupBox;
|
||||
private System.Windows.Forms.TableLayoutPanel ProfileTable;
|
||||
private System.Windows.Forms.ToolStripMenuItem ManageProcessModeToolStripMenuItem;
|
||||
private System.Windows.Forms.PictureBox EditModePictureBox;
|
||||
private System.Windows.Forms.PictureBox DeleteModePictureBox;
|
||||
private System.Windows.Forms.PictureBox CopyLinkPictureBox;
|
||||
private System.Windows.Forms.ToolStripStatusLabel NatTypeStatusLabel;
|
||||
private System.Windows.Forms.TableLayoutPanel configLayoutPanel;
|
||||
private System.Windows.Forms.ToolStripMenuItem reinstallTapDriverToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ReloadModesToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem RelyToolStripMenuItem;
|
||||
private System.Windows.Forms.ComboBox ServerComboBox;
|
||||
private System.Windows.Forms.Label ServerLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem ServerToolStripMenuItem;
|
||||
private System.Windows.Forms.Button SettingsButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem ShowMainFormToolStripButton;
|
||||
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.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
|
||||
private System.Windows.Forms.ToolStripMenuItem UninstallServiceToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateACLToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem updateACLWithProxyToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem reinstallTapDriverToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem AddTrojanServerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem UpdateServersFromSubscribeLinksToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UploadSpeedLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel UsedBandwidthLabel;
|
||||
private System.Windows.Forms.ToolStripLabel VersionLabel;
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolStripStatusLabel NatTypeStatusLightLabel;
|
||||
private System.Windows.Forms.ToolStripStatusLabel blankToolStripStatusLabel;
|
||||
}
|
||||
}
|
||||
433
Netch/Forms/MainForm.MenuStrip.cs
Normal file
433
Netch/Forms/MainForm.MenuStrip.cs
Normal file
@@ -0,0 +1,433 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.ServiceProcess;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Forms.Mode;
|
||||
using Netch.Forms.Server;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using nfapinet;
|
||||
using Trojan = Netch.Forms.Server.Trojan;
|
||||
using VMess = Netch.Forms.Server.VMess;
|
||||
using WebClient = Netch.Override.WebClient;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
partial class Dummy
|
||||
{
|
||||
}
|
||||
|
||||
partial class MainForm
|
||||
{
|
||||
#region MenuStrip
|
||||
|
||||
#region 服务器
|
||||
|
||||
private void ImportServersFromClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var texts = Clipboard.GetText();
|
||||
if (!string.IsNullOrWhiteSpace(texts))
|
||||
{
|
||||
var result = ShareLink.Parse(texts);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
Global.Settings.Server.AddRange(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Import servers error!"), info: false);
|
||||
}
|
||||
|
||||
InitServer();
|
||||
Configuration.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSocks5ServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new Socks5().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void AddShadowsocksServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new Shadowsocks().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void AddShadowsocksRServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new ShadowsocksR().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void AddVMessServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new VMess().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void AddTrojanServerToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new Trojan().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 模式
|
||||
|
||||
private void CreateProcessModeToolStripButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
new Process().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 订阅
|
||||
|
||||
private void ManageSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
new SubscribeForm().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var bak_State = State;
|
||||
var bak_StateText = StatusLabel.Text;
|
||||
|
||||
if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1)
|
||||
Global.Settings.UseProxyToUpdateSubscription = false;
|
||||
|
||||
if (Global.Settings.UseProxyToUpdateSubscription)
|
||||
{
|
||||
// 当前 ServerComboBox 中至少有一项
|
||||
if (ServerComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a server first"));
|
||||
return;
|
||||
}
|
||||
|
||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false;
|
||||
ControlButton.Text = "...";
|
||||
}
|
||||
|
||||
if (Global.Settings.SubscribeLink.Count > 0)
|
||||
{
|
||||
StatusText(i18N.Translate("Starting update subscription"));
|
||||
DeleteServerPictureBox.Enabled = false;
|
||||
|
||||
UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = false;
|
||||
Task.Run(() =>
|
||||
{
|
||||
if (Global.Settings.UseProxyToUpdateSubscription)
|
||||
{
|
||||
var mode = new Models.Mode
|
||||
{
|
||||
Remark = "ProxyUpdate",
|
||||
Type = 5
|
||||
};
|
||||
_mainController = new MainController();
|
||||
_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
||||
}
|
||||
|
||||
foreach (var item in Global.Settings.SubscribeLink)
|
||||
{
|
||||
using var client = new WebClient();
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.UserAgent))
|
||||
{
|
||||
client.Headers.Add("User-Agent", item.UserAgent);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36");
|
||||
}
|
||||
|
||||
if (Global.Settings.UseProxyToUpdateSubscription)
|
||||
{
|
||||
client.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
|
||||
}
|
||||
|
||||
var response = client.DownloadString(item.Link);
|
||||
|
||||
try
|
||||
{
|
||||
response = ShareLink.URLSafeBase64Decode(response);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
|
||||
var result = ShareLink.Parse(response);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
foreach (var x in result)
|
||||
{
|
||||
x.Group = item.Remark;
|
||||
}
|
||||
|
||||
Global.Settings.Server.AddRange(result);
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name,
|
||||
string.Format(i18N.Translate("Update {1} server(s) from {0}"), item.Remark, result.Count),
|
||||
ToolTipIcon.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name,
|
||||
string.Format(i18N.Translate("Update servers error from {0}"), item.Remark),
|
||||
ToolTipIcon.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
InitServer();
|
||||
DeleteServerPictureBox.Enabled = true;
|
||||
if (Global.Settings.UseProxyToUpdateSubscription)
|
||||
{
|
||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
||||
ControlButton.Text = i18N.Translate("Start");
|
||||
_mainController.Stop();
|
||||
NatTypeStatusLabel.Text = "";
|
||||
}
|
||||
|
||||
Configuration.Save();
|
||||
StatusText(i18N.Translate("Subscription updated"));
|
||||
|
||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
||||
State = bak_State;
|
||||
StatusLabel.Text = bak_StateText;
|
||||
}).ContinueWith(task => { BeginInvoke(new Action(() => { UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true; })); });
|
||||
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name,
|
||||
i18N.Translate("Updating in the background"),
|
||||
ToolTipIcon.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("No subscription link"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 选项
|
||||
|
||||
private void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
StatusText(i18N.Translate("Uninstalling NF Service"));
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (NFController.UninstallDriver())
|
||||
{
|
||||
StatusText(i18N.Translate("Service has been uninstalled"));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBoxX.Show(e.ToString(),info:false);
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
Enabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Enabled = false;
|
||||
SaveConfigs();
|
||||
Task.Run(() =>
|
||||
{
|
||||
InitMode();
|
||||
|
||||
MessageBoxX.Show(i18N.Translate("Modes have been reload"), owner: this);
|
||||
Enabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
private void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var bak_State = State;
|
||||
var bak_StateText = StatusLabel.Text;
|
||||
|
||||
try
|
||||
{
|
||||
Enabled = false;
|
||||
DNS.Cache.Clear();
|
||||
|
||||
MessageBoxX.Show(i18N.Translate("DNS cache cleanup succeeded"), owner: this);
|
||||
StatusText(i18N.Translate("DNS cache cleanup succeeded"));
|
||||
Enabled = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
State = bak_State;
|
||||
StatusLabel.Text = bak_StateText;
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Utils.Utils.OpenDir(@".\");
|
||||
}
|
||||
|
||||
private void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
StatusText(i18N.Translate("Reinstalling TUN/TAP driver"));
|
||||
Enabled = false;
|
||||
try
|
||||
{
|
||||
Configuration.deltapall();
|
||||
Configuration.addtap();
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name, i18N.Translate("Reinstall TUN/TAP driver successfully"),
|
||||
ToolTipIcon.Info);
|
||||
}
|
||||
catch
|
||||
{
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name, i18N.Translate("Reinstall TUN/TAP driver failed"),
|
||||
ToolTipIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
State = State.Waiting;
|
||||
Enabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
updateACLWithProxyToolStripMenuItem.Enabled = false;
|
||||
|
||||
// 当前 ServerComboBox 中至少有一项
|
||||
if (ServerComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a server first"));
|
||||
return;
|
||||
}
|
||||
|
||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false;
|
||||
ControlButton.Text = "...";
|
||||
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var mode = new Models.Mode
|
||||
{
|
||||
Remark = "ProxyUpdate",
|
||||
Type = 5
|
||||
};
|
||||
_mainController = new MainController();
|
||||
_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
||||
|
||||
using var client = new WebClient();
|
||||
|
||||
client.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
|
||||
|
||||
StatusText(i18N.Translate("Updating in the background"));
|
||||
try
|
||||
{
|
||||
client.DownloadFile(Global.Settings.ACL, "bin\\default.acl");
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name, i18N.Translate("ACL updated successfully"),
|
||||
ToolTipIcon.Info);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Error("使用代理更新 ACL 失败!" + e);
|
||||
MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
State = State.Waiting;
|
||||
_mainController.Stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
Exit(true);
|
||||
}
|
||||
|
||||
private void RelyToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://mega.nz/file/9OQ1EazJ#0pjJ3xt57AVLr29vYEEv15GSACtXVQOGlEOPpi_2Ico");
|
||||
}
|
||||
|
||||
private void VersionLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases");
|
||||
}
|
||||
|
||||
private void AboutToolStripButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
new AboutForm().Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void updateACLToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var bak_State = State;
|
||||
var bak_StateText = StatusLabel.Text;
|
||||
|
||||
StatusText(i18N.Translate("Starting update ACL"));
|
||||
using var client = new WebClient();
|
||||
|
||||
client.DownloadFileTaskAsync(Global.Settings.ACL, "bin\\default.acl");
|
||||
client.DownloadFileCompleted += ((sender, args) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (args.Error == null)
|
||||
{
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name, i18N.Translate("ACL updated successfully"),
|
||||
ToolTipIcon.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Error("ACL 更新失败!" + args.Error);
|
||||
MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + args.Error);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
State = bak_State;
|
||||
StatusLabel.Text = bak_StateText;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
32
Netch/Forms/MainForm.Misc.cs
Normal file
32
Netch/Forms/MainForm.Misc.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
/// <summary lang="en">
|
||||
/// this class is used to disable Designer <para />
|
||||
/// </summary>
|
||||
/// <summary lang="zh">
|
||||
/// 此类用于禁用设计器
|
||||
/// </summary>
|
||||
[DesignerCategory("")] public partial class Dummy { }
|
||||
partial class MainForm
|
||||
{
|
||||
private void CheckUpdate()
|
||||
{
|
||||
var updater = new UpdateChecker();
|
||||
updater.NewVersionFound += (o, args) =>
|
||||
{
|
||||
NotifyIcon.ShowBalloonTip(5,
|
||||
UpdateChecker.Name,
|
||||
$"{i18N.Translate(@"New version available",": ")}{updater.LatestVersionNumber}",
|
||||
ToolTipIcon.Info);
|
||||
};
|
||||
updater.Check(false, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
211
Netch/Forms/MainForm.Profile.cs
Normal file
211
Netch/Forms/MainForm.Profile.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public partial class Dummy { }
|
||||
partial class MainForm
|
||||
{
|
||||
/// init at <see cref="MainForm_Load"/>
|
||||
private int _sizeHeight;
|
||||
|
||||
private int _profileConfigurationHeight;
|
||||
private int _profileGroupboxHeight;
|
||||
private int _configurationGroupBoxHeight;
|
||||
|
||||
private void InitProfile()
|
||||
{
|
||||
// Clear
|
||||
foreach (var button in ProfileButtons)
|
||||
button.Dispose();
|
||||
|
||||
ProfileButtons.Clear();
|
||||
ProfileTable.ColumnStyles.Clear();
|
||||
ProfileTable.RowStyles.Clear();
|
||||
|
||||
var numProfile = Global.Settings.ProfileCount;
|
||||
if (numProfile == 0)
|
||||
{
|
||||
// Hide Profile GroupBox, Change window size
|
||||
configLayoutPanel.RowStyles[2].SizeType = SizeType.Percent;
|
||||
configLayoutPanel.RowStyles[2].Height = 0;
|
||||
ProfileGroupBox.Visible = false;
|
||||
|
||||
ConfigurationGroupBox.Size = new Size(ConfigurationGroupBox.Size.Width, _configurationGroupBoxHeight - _profileConfigurationHeight);
|
||||
Size = new Size(Size.Width, _sizeHeight - (_profileConfigurationHeight + _profileGroupboxHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load Profiles
|
||||
ProfileTable.ColumnCount = numProfile;
|
||||
|
||||
while (Global.Settings.Profiles.Count < numProfile)
|
||||
{
|
||||
Global.Settings.Profiles.Add(new Profile());
|
||||
}
|
||||
|
||||
for (var i = 0; i < numProfile; ++i)
|
||||
{
|
||||
var b = new Button();
|
||||
b.Click += ProfileButton_Click;
|
||||
b.Dock = DockStyle.Fill;
|
||||
b.Text = !Global.Settings.Profiles[i].IsDummy ? Global.Settings.Profiles[i].ProfileName : i18N.Translate("None");
|
||||
|
||||
ProfileTable.Controls.Add(b, i, 0);
|
||||
ProfileButtons.Add(b);
|
||||
}
|
||||
|
||||
// equal column
|
||||
for (var i = 1; i <= ProfileTable.RowCount; i++)
|
||||
{
|
||||
ProfileTable.RowStyles.Add(new RowStyle(SizeType.Percent, 1));
|
||||
}
|
||||
|
||||
for (var i = 1; i <= ProfileTable.ColumnCount; i++)
|
||||
{
|
||||
ProfileTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1));
|
||||
}
|
||||
|
||||
if (Size.Height == _sizeHeight) return;
|
||||
configLayoutPanel.RowStyles[2].SizeType = SizeType.AutoSize;
|
||||
ProfileGroupBox.Visible = true;
|
||||
ConfigurationGroupBox.Size = new Size(ConfigurationGroupBox.Size.Width, _configurationGroupBoxHeight);
|
||||
Size = new Size(Size.Width, _sizeHeight);
|
||||
}
|
||||
}
|
||||
|
||||
private string LoadProfile(int index)
|
||||
{
|
||||
var p = Global.Settings.Profiles[index];
|
||||
|
||||
if (p.IsDummy)
|
||||
throw new Exception("Profile not found.");
|
||||
|
||||
var result = false;
|
||||
|
||||
foreach (Models.Server server in ServerComboBox.Items)
|
||||
{
|
||||
if (server.Remark.Equals(p.ServerRemark))
|
||||
{
|
||||
ServerComboBox.SelectedItem = server;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
throw new Exception("Server not found.");
|
||||
|
||||
result = false;
|
||||
foreach (Models.Mode mode in ModeComboBox.Items)
|
||||
{
|
||||
if (mode.Remark.Equals(p.ModeRemark))
|
||||
{
|
||||
ModeComboBox.SelectedItem = mode;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
throw new Exception("Mode not found.");
|
||||
|
||||
return p.ProfileName;
|
||||
}
|
||||
|
||||
private void SaveProfile(int index)
|
||||
{
|
||||
var selectedServer = (Models.Server) ServerComboBox.SelectedItem;
|
||||
var selectedMode = (Models.Mode) ModeComboBox.SelectedItem;
|
||||
var name = ProfileNameText.Text;
|
||||
|
||||
Global.Settings.Profiles[index] = new Profile(selectedServer, selectedMode, name);
|
||||
}
|
||||
|
||||
private void RemoveProfile(int index)
|
||||
{
|
||||
Global.Settings.Profiles[index] = new Profile();
|
||||
}
|
||||
|
||||
|
||||
private List<Button> ProfileButtons = new List<Button>();
|
||||
|
||||
private void ProfileButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var index = ProfileButtons.IndexOf((Button) sender);
|
||||
|
||||
if (ModifierKeys == Keys.Control)
|
||||
{
|
||||
if (ServerComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a server first"));
|
||||
}
|
||||
else if (ModeComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please select a mode first"));
|
||||
}
|
||||
else if (ProfileNameText.Text == "")
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a profile name first"));
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveProfile(index);
|
||||
ProfileButtons[index].Text = ProfileNameText.Text;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Global.Settings.Profiles[index].IsDummy)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("No saved profile here. Save a profile first by Ctrl+Click on the button"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ModifierKeys == Keys.Shift)
|
||||
{
|
||||
if (MessageBoxX.Show(i18N.Translate("Remove this Profile?"), confirm: true) != DialogResult.OK) return;
|
||||
RemoveProfile(index);
|
||||
ProfileButtons[index].Text = i18N.Translate("None");
|
||||
MessageBoxX.Show(i18N.Translate("Profile Removed!"));
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProfileNameText.Text = LoadProfile(index);
|
||||
|
||||
// start the profile
|
||||
ControlFun();
|
||||
if (State == State.Stopping || State == State.Stopped)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
while (State != State.Stopped)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
ControlFun();
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Logging.Info(ee.ToString());
|
||||
ProfileButtons[index].Text = i18N.Translate("Error");
|
||||
Thread.Sleep(1200);
|
||||
ProfileButtons[index].Text = i18N.Translate("None");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
249
Netch/Forms/MainForm.Server_Mode.cs
Normal file
249
Netch/Forms/MainForm.Server_Mode.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public partial class Dummy
|
||||
{
|
||||
}
|
||||
|
||||
partial class MainForm
|
||||
{
|
||||
#region Server
|
||||
|
||||
private static void TestServer()
|
||||
{
|
||||
try
|
||||
{
|
||||
Parallel.ForEach(Global.Settings.Server, new ParallelOptions {MaxDegreeOfParallelism = 16},
|
||||
server => { server.Test(); });
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public void InitServer()
|
||||
{
|
||||
ServerComboBox.Items.Clear();
|
||||
ServerComboBox.Items.AddRange(Global.Settings.Server.ToArray());
|
||||
|
||||
// 如果值合法,选中该位置
|
||||
if (Global.Settings.ServerComboBoxSelectedIndex > 0 &&
|
||||
Global.Settings.ServerComboBoxSelectedIndex < ServerComboBox.Items.Count)
|
||||
{
|
||||
ServerComboBox.SelectedIndex = Global.Settings.ServerComboBoxSelectedIndex;
|
||||
}
|
||||
// 如果值非法,且当前 ServerComboBox 中有元素,选择第一个位置
|
||||
else if (ServerComboBox.Items.Count > 0)
|
||||
{
|
||||
ServerComboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
// 如果当前 ServerComboBox 中没元素,不做处理
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mode
|
||||
|
||||
private void InitMode()
|
||||
{
|
||||
ModeComboBox.Items.Clear();
|
||||
Global.ModeFiles.Clear();
|
||||
|
||||
if (Directory.Exists("mode"))
|
||||
{
|
||||
foreach (var name in Directory.GetFiles("mode", "*.txt"))
|
||||
{
|
||||
var ok = true;
|
||||
var mode = new Models.Mode();
|
||||
|
||||
using (var sr = new StringReader(File.ReadAllText(name)))
|
||||
{
|
||||
var i = 0;
|
||||
string text;
|
||||
|
||||
while ((text = sr.ReadLine()) != null)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var splited = text.Trim().Substring(1).Split(',');
|
||||
|
||||
if (splited.Length == 0)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (splited.Length >= 1)
|
||||
{
|
||||
mode.Remark = i18N.Translate(splited[0].Trim());
|
||||
}
|
||||
|
||||
if (splited.Length >= 2)
|
||||
{
|
||||
if (int.TryParse(splited[1], out var result))
|
||||
{
|
||||
mode.Type = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (splited.Length >= 3)
|
||||
{
|
||||
if (int.TryParse(splited[2], out var result))
|
||||
{
|
||||
mode.BypassChina = result == 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!text.StartsWith("#") && !string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
mode.Rule.Add(text.Trim());
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
mode.FileName = Path.GetFileNameWithoutExtension(name);
|
||||
Global.ModeFiles.Add(mode);
|
||||
}
|
||||
}
|
||||
|
||||
var array = Global.ModeFiles.ToArray();
|
||||
Array.Sort(array, (a, b) => string.Compare(a.Remark, b.Remark, StringComparison.Ordinal));
|
||||
|
||||
ModeComboBox.Items.AddRange(array);
|
||||
|
||||
SelectLastMode();
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectLastMode()
|
||||
{
|
||||
// 如果值合法,选中该位置
|
||||
if (Global.Settings.ModeComboBoxSelectedIndex > 0 &&
|
||||
Global.Settings.ModeComboBoxSelectedIndex < ModeComboBox.Items.Count)
|
||||
{
|
||||
ModeComboBox.SelectedIndex = Global.Settings.ModeComboBoxSelectedIndex;
|
||||
}
|
||||
// 如果值非法,且当前 ModeComboBox 中有元素,选择第一个位置
|
||||
else if (ModeComboBox.Items.Count > 0)
|
||||
{
|
||||
ModeComboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
// 如果当前 ModeComboBox 中没元素,不做处理
|
||||
}
|
||||
|
||||
public void AddMode(Models.Mode mode)
|
||||
{
|
||||
ModeComboBox.Items.Clear();
|
||||
Global.ModeFiles.Add(mode);
|
||||
var array = Global.ModeFiles.ToArray();
|
||||
Array.Sort(array, (a, b) => string.Compare(a.Remark, b.Remark, StringComparison.Ordinal));
|
||||
ModeComboBox.Items.AddRange(array);
|
||||
|
||||
SelectLastMode();
|
||||
}
|
||||
|
||||
public void UpdateMode(Models.Mode NewMode, Models.Mode OldMode)
|
||||
{
|
||||
ModeComboBox.Items.Clear();
|
||||
Global.ModeFiles.Remove(OldMode);
|
||||
Global.ModeFiles.Add(NewMode);
|
||||
var array = Global.ModeFiles.ToArray();
|
||||
Array.Sort(array, (a, b) => string.Compare(a.Remark, b.Remark, StringComparison.Ordinal));
|
||||
ModeComboBox.Items.AddRange(array);
|
||||
|
||||
SelectLastMode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Init at <see cref="MainForm_Load"/>
|
||||
/// </summary>
|
||||
private int _eWidth;
|
||||
|
||||
private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(sender is ComboBox cbx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 绘制背景颜色
|
||||
e.Graphics.FillRectangle(new SolidBrush(Color.White), e.Bounds);
|
||||
|
||||
if (e.Index < 0) return;
|
||||
|
||||
// 绘制 备注/名称 字符串
|
||||
e.Graphics.DrawString(cbx.Items[e.Index].ToString(), cbx.Font, new SolidBrush(Color.Black), e.Bounds);
|
||||
|
||||
switch (cbx.Items[e.Index])
|
||||
{
|
||||
case Models.Server item:
|
||||
{
|
||||
// 计算延迟底色
|
||||
SolidBrush brush;
|
||||
if (item.Delay > 200)
|
||||
brush = new SolidBrush(Color.Red);
|
||||
else if (item.Delay > 80)
|
||||
brush = new SolidBrush(Color.Yellow);
|
||||
else if (item.Delay >= 0)
|
||||
brush = new SolidBrush(Color.FromArgb(50, 255, 56));
|
||||
else
|
||||
brush = new SolidBrush(Color.Gray);
|
||||
|
||||
// 绘制延迟底色
|
||||
e.Graphics.FillRectangle(brush, _eWidth * 9, e.Bounds.Y, _eWidth, e.Bounds.Height);
|
||||
|
||||
// 绘制延迟字符串
|
||||
e.Graphics.DrawString(item.Delay.ToString(), cbx.Font, new SolidBrush(Color.Black),
|
||||
_eWidth * 9 + _eWidth / 30, e.Bounds.Y);
|
||||
break;
|
||||
}
|
||||
case Models.Mode item:
|
||||
{
|
||||
// 绘制 模式Box 底色
|
||||
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), _eWidth * 9, e.Bounds.Y, _eWidth,
|
||||
e.Bounds.Height);
|
||||
|
||||
// 绘制 模式行数 字符串
|
||||
e.Graphics.DrawString(item.Rule.Count.ToString(), cbx.Font, new SolidBrush(Color.Black),
|
||||
_eWidth * 9 + _eWidth / 30, e.Bounds.Y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
171
Netch/Forms/MainForm.Status.cs
Normal file
171
Netch/Forms/MainForm.Status.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
public partial class Dummy
|
||||
{
|
||||
}
|
||||
|
||||
partial class MainForm
|
||||
{
|
||||
private State _state = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State
|
||||
{
|
||||
get => _state;
|
||||
private set
|
||||
{
|
||||
_state = value;
|
||||
if (IsDisposed)
|
||||
return;
|
||||
StatusText(i18N.Translate(StateExtension.GetStatusString(value)));
|
||||
switch (value)
|
||||
{
|
||||
case State.Waiting:
|
||||
ControlButton.Enabled = true;
|
||||
ControlButton.Text = i18N.Translate("Start");
|
||||
|
||||
break;
|
||||
case State.Starting:
|
||||
ControlButton.Enabled = false;
|
||||
ControlButton.Text = "...";
|
||||
|
||||
ConfigurationGroupBox.Enabled = false;
|
||||
|
||||
MenuStripsEnabled(false);
|
||||
break;
|
||||
case State.Started:
|
||||
ControlButton.Enabled = true;
|
||||
ControlButton.Text = i18N.Translate("Stop");
|
||||
|
||||
LastUploadBandwidth = 0;
|
||||
//LastDownloadBandwidth = 0;
|
||||
//UploadSpeedLabel.Text = "↑: 0 KB/s";
|
||||
DownloadSpeedLabel.Text = @"↑↓: 0 KB/s";
|
||||
UsedBandwidthLabel.Text = $@"{i18N.Translate("Used", ": ")}0 KB";
|
||||
UsedBandwidthLabel.Visible /*= UploadSpeedLabel.Visible*/ = DownloadSpeedLabel.Visible = true;
|
||||
break;
|
||||
case State.Stopping:
|
||||
ControlButton.Enabled = false;
|
||||
ControlButton.Text = "...";
|
||||
|
||||
ProfileGroupBox.Enabled = false;
|
||||
|
||||
UsedBandwidthLabel.Visible /*= UploadSpeedLabel.Visible*/ = DownloadSpeedLabel.Visible = false;
|
||||
NatTypeStatusText();
|
||||
break;
|
||||
case State.Stopped:
|
||||
ControlButton.Enabled = true;
|
||||
ControlButton.Text = i18N.Translate("Start");
|
||||
|
||||
LastUploadBandwidth = 0;
|
||||
LastDownloadBandwidth = 0;
|
||||
|
||||
ProfileGroupBox.Enabled = true;
|
||||
ConfigurationGroupBox.Enabled = true;
|
||||
|
||||
MenuStripsEnabled(true);
|
||||
break;
|
||||
case State.Terminating:
|
||||
Dispose();
|
||||
Environment.Exit(Environment.ExitCode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NatTypeStatusText(string text = "", string country = "")
|
||||
{
|
||||
if (State != State.Started)
|
||||
{
|
||||
NatTypeStatusLabel.Text = "";
|
||||
NatTypeStatusLabel.Visible = NatTypeStatusLightLabel.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
if (country != "")
|
||||
{
|
||||
NatTypeStatusLabel.Text = String.Format("NAT{0}{1}[{2}]", i18N.Translate(": "), text, country);
|
||||
}
|
||||
else
|
||||
{
|
||||
NatTypeStatusLabel.Text = String.Format("NAT{0}{1}", i18N.Translate(": "), text);
|
||||
}
|
||||
if (Enum.TryParse(text, false, out STUN_Client.NatType natType))
|
||||
{
|
||||
NatTypeStatusLightLabel.Visible = true;
|
||||
UpdateNatTypeLight(natType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NatTypeStatusLabel.Text = $@"NAT{i18N.Translate(": ", "Test failed")}";
|
||||
}
|
||||
|
||||
NatTypeStatusLabel.Visible = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新 NAT指示灯颜色
|
||||
/// </summary>
|
||||
/// <param name="natType"></param>
|
||||
private void UpdateNatTypeLight(STUN_Client.NatType natType)
|
||||
{
|
||||
Color c;
|
||||
switch (natType)
|
||||
{
|
||||
case STUN_Client.NatType.UdpBlocked:
|
||||
case STUN_Client.NatType.SymmetricUdpFirewall:
|
||||
case STUN_Client.NatType.Symmetric:
|
||||
c = Color.Red;
|
||||
break;
|
||||
case STUN_Client.NatType.RestrictedCone:
|
||||
case STUN_Client.NatType.PortRestrictedCone:
|
||||
c = Color.Yellow;
|
||||
break;
|
||||
case STUN_Client.NatType.OpenInternet:
|
||||
case STUN_Client.NatType.FullCone:
|
||||
c = Color.LimeGreen;
|
||||
break;
|
||||
default:
|
||||
c = Color.Black;
|
||||
break;
|
||||
}
|
||||
|
||||
NatTypeStatusLightLabel.ForeColor = c;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 更新状态栏文本
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
public void StatusText(string text)
|
||||
{
|
||||
StatusLabel.Text = i18N.Translate("Status", ": ") + text;
|
||||
}
|
||||
|
||||
public void StatusTextAppend(string text)
|
||||
{
|
||||
StatusLabel.Text += text;
|
||||
}
|
||||
|
||||
public void MenuStripsEnabled(bool enabled)
|
||||
{
|
||||
// 需要禁用的菜单项
|
||||
UninstallServiceToolStripMenuItem.Enabled =
|
||||
updateACLWithProxyToolStripMenuItem.Enabled =
|
||||
UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
|
||||
reinstallTapDriverToolStripMenuItem.Enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -120,51 +120,6 @@
|
||||
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="EditPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAg9JREFUOE+F
|
||||
U81uElEYnTdw58qFunBlYnwAE7e+QhMT38CNcefWxKWufADjiqqtmsZIW2gRulBTY4fGGGmLMFOGn5aB
|
||||
GYa5c+f4nTsINKF6kkPIxz3nO/f7Llas1IXXGyW8Wi9h+T/kmVx+C7WGA8F14S2LxR8HdfjDAMMwFI7O
|
||||
YQg/CI14pVDGKIoGYnDZomMgB4gk0VAqgUoWkxjHMd5t7eCkTz2uWIxGd601nHYPR66H+nH7LKXW9LrG
|
||||
JBrHeL+9g1N/gDRNl4wBoxHhKDJxmWierPG3lGeiaGrQ9DpPjMFADJjA7fSko4ff0nWerDntWQJegQbl
|
||||
XRsLEiweZMAEEoFn1opl9GXopa97sFaLlWmCY0nAjo2WdCYn3ednIGvHodPCSIw+2z9hrRQqZoWzBLOu
|
||||
jBvJ1MlYyARK+LGl8LCWYq+vsyvMttA17oduiwOaru4vEhGvdzSuVRUu2THu7KvJDCYJxrHKugr5XdZk
|
||||
6kSsgWJXo+pr7J5q3K7GeFoXA75EDuRfYOyCdLZFTDhhipyboDsIv2QGg6H5YREorvSyzgTFH7wEnh8g
|
||||
0frxdAbn4Vs/xYtmNguK10TcCXjF+JmUrlpvNj/lDxqu2cDZFxialb1sKly0FZYl8oZc4yRK+CYeiPie
|
||||
8IYlH3dz+W3zuub5Vv5x33/V8VwG9aimsCniMEl92dZN0SxRB+D+Hw2grtB8iuYFAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="DeletePictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAglJREFUOE+V
|
||||
k81PE1EUxUcXunEFS02MJibsZGfc6L6iazGaGI07QXcaE+PClf+ECxP/CKWwUFJqpVNKodAPGgtiW2g7
|
||||
03am89WZ47mvTdwUhJv8mua9e+7cd995GoAL5Cq5SB42jQ7S+RIWf2TwNZFWxJM6fm4U0GgZN5kzQc6T
|
||||
KXJNCpwjb/1gMJMt7GBhJY217TJqhy2YPUtRb7aRK1WkULC6WTRdz/9IzQ1yWQqcpXhqJZvHdz2nBEeF
|
||||
1Xcged/S62CROJeuSIGYfFnEfhCoxONiEIZIskgqt40oimY1nvnzQmIVHcsepfw/+p6HOI+6f9D8oMnA
|
||||
9HJ1tHXyyFf3kVjbhCbT/tM0hqtOH1G9huigPh7uwR7OqNXpceA6tC/86crgAh/u+zew79+FPXtvPNxz
|
||||
X88j6nXhOC4WU9lhgV6P5+e53FdzsO7chj0zHit2C87cE0Qd81+BeDKDettUbcFoI9wpIayUx1MusvdD
|
||||
ldruWspkmjgsW9lTi6eJwl4Ny/oGNNpTXYnNlk4anh9gicPfrTU+aVGEGO2pHDYYhKOUo4Pm4Vspqiuk
|
||||
qd6JE5/SlsqeyfWtYzuRPBEvpTJi6xdcUlaeJPOO5/liT3l5W5VdtMyu8r5g8M6Lv34roXx5JH5MrkuB
|
||||
R+QMmWB7l2jP55IkExaBIP+X+VaqtcbLMAynmftgqMOzv61mlBRRiHFjAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="SpeedPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAk9JREFUOE9N
|
||||
k19ojWEcx8+xsRgzbSlaJouGRCNuXIyMXJ1LpVyYFAttqylEsdKQC1yZpF24oJQrN0q5UJKUlP3DWTPz
|
||||
pzmm2Tk753nf9+fzfd/3nJ2nPr3v8z7P7/d7nu/v+ybMbBUsA703wwk/sKcPJz07POzszOg8HXAKBr55
|
||||
bLMmWKOgxZCEBfH7zg9/fev55Gw8G9jUXGC/IFMI7HXGt7ZBZ9fGHNtsJVQogYIrQMFVOc8GLn5x4eby
|
||||
UWB6k8AXU75N5gJ9aoBkMYGqL4JLbHB9bFRA+Xj207Pr0fcbTNtgC1QWE1TC6t/5INvF0UdmwgqlkZ4N
|
||||
rJvvP3JBmul6OArSrloJ6mAz3H383bMHE6FApZFlqitpbcbZhTnfWrzA9rNUDfVKsAFSY1Q5+9mFopWP
|
||||
IU6TGnJ2nrXetCslY6hwnRLo/q1XWVTr/iHwdCECQS2PFpl81IUnBLZ+LNit8bALRyA8gTTY0f816vVl
|
||||
Klwh2UneH5GweJ53076d5pv04SrSQiLWKkEVbFUl9VtItPYRZ6/iVr7549sx5sORuP2wBw5BgxIsgY2w
|
||||
DVZAlwLVc21/GwdTWRfvhXp4Cbv1rgRrQRbeDge466xaplO8x5FxMEvWCctBRTpgH4RGWgdyoRZuSyiJ
|
||||
qcrSIQ5+DgtBCXQCuXAphFaWjfVsnMD752iX2tQ5b6g7sAv0w20CiV50b3gCuTDB1ub7mGjvYCF0XRzc
|
||||
B/rrGkGqK7BYVI5MaFILSdzVdI9WHuRvG42Cj4Mc2g4toEJKUAMZSJlZzX8eY2N9ZDKIEQAAAABJRU5E
|
||||
rkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="StatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>122, 17</value>
|
||||
</metadata>
|
||||
@@ -174,6 +129,7 @@
|
||||
<metadata name="NotifyMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>393, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="NotifyIcon.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAMAAAAAAAEAIAAoIAQANgAAAEBAAAABACAAKEIAAF4gBAAgIAAAAQAgAKgQAACGYgQAKAAAAAAB
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
using Microsoft.WindowsAPICodePack.Dialogs;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.WindowsAPICodePack.Dialogs;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.Mode
|
||||
{
|
||||
public partial class Process : Form
|
||||
{
|
||||
//用于判断当前窗口是否为编辑模式
|
||||
private Boolean EditMode = false;
|
||||
private bool EditMode;
|
||||
//被编辑模式坐标
|
||||
private Models.Mode EditMode_Old = null;
|
||||
private Models.Mode EditMode_Old;
|
||||
/// <summary>
|
||||
/// 编辑模式
|
||||
/// </summary>
|
||||
@@ -23,7 +25,7 @@ namespace Netch.Forms.Mode
|
||||
CheckForIllegalCrossThreadCalls = false;
|
||||
|
||||
EditMode_Old = mode;
|
||||
this.Text = "Edit Process Mode";
|
||||
Text = "Edit Process Mode";
|
||||
//循环填充已有规则
|
||||
mode.Rule.ForEach(i => RuleListBox.Items.Add(i));
|
||||
|
||||
@@ -67,7 +69,7 @@ namespace Netch.Forms.Mode
|
||||
return;
|
||||
}
|
||||
|
||||
var DirStack = new System.Collections.Generic.Stack<string>();
|
||||
var DirStack = new Stack<string>();
|
||||
DirStack.Push(DirName);
|
||||
|
||||
while (DirStack.Count > 0)
|
||||
@@ -89,16 +91,16 @@ namespace Netch.Forms.Mode
|
||||
|
||||
private void ModeForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Text = Utils.i18N.Translate(Text);
|
||||
ConfigurationGroupBox.Text = Utils.i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
FilenameLabel.Text = Utils.i18N.Translate(FilenameLabel.Text);
|
||||
UseCustomFilenameBox.Text = Utils.i18N.Translate(UseCustomFilenameBox.Text);
|
||||
StaySameButton.Text = Utils.i18N.Translate(StaySameButton.Text);
|
||||
TimeDataButton.Text = Utils.i18N.Translate(TimeDataButton.Text);
|
||||
AddButton.Text = Utils.i18N.Translate(AddButton.Text);
|
||||
ScanButton.Text = Utils.i18N.Translate(ScanButton.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
Text = i18N.Translate(Text);
|
||||
ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
FilenameLabel.Text = i18N.Translate(FilenameLabel.Text);
|
||||
UseCustomFilenameBox.Text = i18N.Translate(UseCustomFilenameBox.Text);
|
||||
StaySameButton.Text = i18N.Translate(StaySameButton.Text);
|
||||
TimeDataButton.Text = i18N.Translate(TimeDataButton.Text);
|
||||
AddButton.Text = i18N.Translate(AddButton.Text);
|
||||
ScanButton.Text = i18N.Translate(ScanButton.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
if (Global.Settings.ModeFileNameType == 0)
|
||||
{
|
||||
@@ -130,12 +132,12 @@ namespace Netch.Forms.Mode
|
||||
/// </summary>
|
||||
private void RuleListBox_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
ContextMenuStrip strip = new ContextMenuStrip();
|
||||
strip.Items.Add(Utils.i18N.Translate("Delete"));
|
||||
var strip = new ContextMenuStrip();
|
||||
strip.Items.Add(i18N.Translate("Delete"));
|
||||
if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
strip.Show(this.RuleListBox, e.Location);//鼠标右键按下弹出菜单
|
||||
strip.MouseClick += new MouseEventHandler(deleteRule_Click);
|
||||
strip.Show(RuleListBox, e.Location);//鼠标右键按下弹出菜单
|
||||
strip.MouseClick += deleteRule_Click;
|
||||
}
|
||||
}
|
||||
void deleteRule_Click(object sender, EventArgs e)
|
||||
@@ -165,7 +167,7 @@ namespace Netch.Forms.Mode
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Please enter an process name (xxx.exe)"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Please enter an process name (xxx.exe)"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +177,7 @@ namespace Netch.Forms.Mode
|
||||
{
|
||||
IsFolderPicker = true,
|
||||
Multiselect = false,
|
||||
Title = Utils.i18N.Translate("Select a folder"),
|
||||
Title = i18N.Translate("Select a folder"),
|
||||
AddToMostRecentlyUsedList = false,
|
||||
EnsurePathExists = true,
|
||||
NavigateToShortcut = true
|
||||
@@ -183,7 +185,7 @@ namespace Netch.Forms.Mode
|
||||
if (dialog.ShowDialog(Win32Native.GetForegroundWindow()) == CommonFileDialogResult.Ok)
|
||||
{
|
||||
ScanDirectory(dialog.FileName);
|
||||
MessageBox.Show(Utils.i18N.Translate("Scan completed"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Scan completed"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,14 +222,14 @@ namespace Netch.Forms.Mode
|
||||
|
||||
File.WriteAllText(Path.Combine("mode", FilenameTextBox.Text) + ".txt", text);
|
||||
|
||||
MessageBox.Show(Utils.i18N.Translate("Mode updated successfully"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Mode updated successfully"));
|
||||
|
||||
Global.MainForm.UpdateMode(mode, EditMode_Old);
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Unable to add empty rule"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Unable to add empty rule"));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -250,13 +252,13 @@ namespace Netch.Forms.Mode
|
||||
FilenameTextBox.Text = ((long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds).ToString();
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
Configuration.Save();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(RemarkTextBox.Text))
|
||||
{
|
||||
if (Global.Settings.ModeFileNameType == 0 && string.IsNullOrWhiteSpace(FilenameTextBox.Text))
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Please enter a mode filename"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a mode filename"));
|
||||
return;
|
||||
}
|
||||
var ModeFilename = Path.Combine("mode", FilenameTextBox.Text);
|
||||
@@ -264,7 +266,7 @@ namespace Netch.Forms.Mode
|
||||
// 如果文件已存在,返回
|
||||
if (File.Exists(ModeFilename + ".txt"))
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("File already exists.\n Please Change the filename"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("File already exists.\n Please Change the filename"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -273,7 +275,7 @@ namespace Netch.Forms.Mode
|
||||
var mode = new Models.Mode
|
||||
{
|
||||
BypassChina = false,
|
||||
FileName = ModeFilename,
|
||||
FileName = FilenameTextBox.Text,
|
||||
Type = 0,
|
||||
Remark = RemarkTextBox.Text
|
||||
};
|
||||
@@ -295,19 +297,19 @@ namespace Netch.Forms.Mode
|
||||
|
||||
File.WriteAllText(ModeFilename + ".txt", text);
|
||||
|
||||
MessageBox.Show(Utils.i18N.Translate("Mode added successfully"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Mode added successfully"));
|
||||
|
||||
Global.MainForm.AddMode(mode);
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Unable to add empty rule"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Unable to add empty rule"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Please enter a mode remark"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Please enter a mode remark"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.Server
|
||||
{
|
||||
@@ -22,14 +23,14 @@ namespace Netch.Forms.Server
|
||||
|
||||
private void Shadowsocks_Load(object sender, EventArgs e)
|
||||
{
|
||||
ConfigurationGroupBox.Text = Utils.i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = Utils.i18N.Translate(AddressLabel.Text);
|
||||
PasswordLabel.Text = Utils.i18N.Translate(PasswordLabel.Text);
|
||||
EncryptMethodLabel.Text = Utils.i18N.Translate(EncryptMethodLabel.Text);
|
||||
PluginLabel.Text = Utils.i18N.Translate(PluginLabel.Text);
|
||||
PluginOptionsLabel.Text = Utils.i18N.Translate(PluginOptionsLabel.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = i18N.Translate(AddressLabel.Text);
|
||||
PasswordLabel.Text = i18N.Translate(PasswordLabel.Text);
|
||||
EncryptMethodLabel.Text = i18N.Translate(EncryptMethodLabel.Text);
|
||||
PluginLabel.Text = i18N.Translate(PluginLabel.Text);
|
||||
PluginOptionsLabel.Text = i18N.Translate(PluginOptionsLabel.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
foreach (var encrypt in Global.EncryptMethods.SS)
|
||||
{
|
||||
@@ -119,8 +120,8 @@ namespace Netch.Forms.Server
|
||||
};
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Global.MainForm.InitServer();
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.Server
|
||||
{
|
||||
@@ -22,16 +23,16 @@ namespace Netch.Forms.Server
|
||||
|
||||
private void ShadowsocksR_Load(object sender, EventArgs e)
|
||||
{
|
||||
ConfigurationGroupBox.Text = Utils.i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = Utils.i18N.Translate(AddressLabel.Text);
|
||||
PasswordLabel.Text = Utils.i18N.Translate(PasswordLabel.Text);
|
||||
EncryptMethodLabel.Text = Utils.i18N.Translate(EncryptMethodLabel.Text);
|
||||
ProtocolLabel.Text = Utils.i18N.Translate(ProtocolLabel.Text);
|
||||
ProtocolParamLabel.Text = Utils.i18N.Translate(ProtocolParamLabel.Text);
|
||||
OBFSLabel.Text = Utils.i18N.Translate(OBFSLabel.Text);
|
||||
OBFSParamLabel.Text = Utils.i18N.Translate(OBFSParamLabel.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = i18N.Translate(AddressLabel.Text);
|
||||
PasswordLabel.Text = i18N.Translate(PasswordLabel.Text);
|
||||
EncryptMethodLabel.Text = i18N.Translate(EncryptMethodLabel.Text);
|
||||
ProtocolLabel.Text = i18N.Translate(ProtocolLabel.Text);
|
||||
ProtocolParamLabel.Text = i18N.Translate(ProtocolParamLabel.Text);
|
||||
OBFSLabel.Text = i18N.Translate(OBFSLabel.Text);
|
||||
OBFSParamLabel.Text = i18N.Translate(OBFSParamLabel.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
foreach (var encrypt in Global.EncryptMethods.SSR)
|
||||
{
|
||||
@@ -139,8 +140,8 @@ namespace Netch.Forms.Server
|
||||
};
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Global.MainForm.InitServer();
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.Server
|
||||
{
|
||||
@@ -22,12 +23,12 @@ namespace Netch.Forms.Server
|
||||
|
||||
private void Shadowsocks_Load(object sender, EventArgs e)
|
||||
{
|
||||
ConfigurationGroupBox.Text = Utils.i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = Utils.i18N.Translate(AddressLabel.Text);
|
||||
UsernameLabel.Text = Utils.i18N.Translate(UsernameLabel.Text);
|
||||
PasswordLabel.Text = Utils.i18N.Translate(PasswordLabel.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = i18N.Translate(AddressLabel.Text);
|
||||
UsernameLabel.Text = i18N.Translate(UsernameLabel.Text);
|
||||
PasswordLabel.Text = i18N.Translate(PasswordLabel.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
if (Index != -1)
|
||||
{
|
||||
@@ -102,8 +103,8 @@ namespace Netch.Forms.Server
|
||||
};
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Global.MainForm.InitServer();
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.Server
|
||||
{
|
||||
@@ -22,11 +23,11 @@ namespace Netch.Forms.Server
|
||||
|
||||
private void Trojan_Load(object sender, EventArgs e)
|
||||
{
|
||||
ConfigurationGroupBox.Text = Utils.i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = Utils.i18N.Translate(AddressLabel.Text);
|
||||
PasswordLabel.Text = Utils.i18N.Translate(PasswordLabel.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = i18N.Translate(AddressLabel.Text);
|
||||
PasswordLabel.Text = i18N.Translate(PasswordLabel.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
if (Index != -1)
|
||||
{
|
||||
@@ -98,8 +99,8 @@ namespace Netch.Forms.Server
|
||||
};
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Global.MainForm.InitServer();
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Drawing;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms.Server
|
||||
{
|
||||
@@ -43,21 +44,21 @@ namespace Netch.Forms.Server
|
||||
|
||||
private void VMess_Load(object sender, EventArgs e)
|
||||
{
|
||||
ConfigurationGroupBox.Text = Utils.i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = Utils.i18N.Translate(AddressLabel.Text);
|
||||
UserIDLabel.Text = Utils.i18N.Translate(UserIDLabel.Text);
|
||||
AlterIDLabel.Text = Utils.i18N.Translate(AlterIDLabel.Text);
|
||||
EncryptMethodLabel.Text = Utils.i18N.Translate(EncryptMethodLabel.Text);
|
||||
TransferProtocolLabel.Text = Utils.i18N.Translate(TransferProtocolLabel.Text);
|
||||
FakeTypeLabel.Text = Utils.i18N.Translate(FakeTypeLabel.Text);
|
||||
HostLabel.Text = Utils.i18N.Translate(HostLabel.Text);
|
||||
PathLabel.Text = Utils.i18N.Translate(PathLabel.Text);
|
||||
QUICSecurityLabel.Text = Utils.i18N.Translate(QUICSecurityLabel.Text);
|
||||
QUICSecretLabel.Text = Utils.i18N.Translate(QUICSecretLabel.Text);
|
||||
TLSSecureCheckBox.Text = Utils.i18N.Translate(TLSSecureCheckBox.Text);
|
||||
UseMuxCheckBox.Text = Utils.i18N.Translate(UseMuxCheckBox.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
ConfigurationGroupBox.Text = i18N.Translate(ConfigurationGroupBox.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
AddressLabel.Text = i18N.Translate(AddressLabel.Text);
|
||||
UserIDLabel.Text = i18N.Translate(UserIDLabel.Text);
|
||||
AlterIDLabel.Text = i18N.Translate(AlterIDLabel.Text);
|
||||
EncryptMethodLabel.Text = i18N.Translate(EncryptMethodLabel.Text);
|
||||
TransferProtocolLabel.Text = i18N.Translate(TransferProtocolLabel.Text);
|
||||
FakeTypeLabel.Text = i18N.Translate(FakeTypeLabel.Text);
|
||||
HostLabel.Text = i18N.Translate(HostLabel.Text);
|
||||
PathLabel.Text = i18N.Translate(PathLabel.Text);
|
||||
QUICSecurityLabel.Text = i18N.Translate(QUICSecurityLabel.Text);
|
||||
QUICSecretLabel.Text = i18N.Translate(QUICSecretLabel.Text);
|
||||
TLSSecureCheckBox.Text = i18N.Translate(TLSSecureCheckBox.Text);
|
||||
UseMuxCheckBox.Text = i18N.Translate(UseMuxCheckBox.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
foreach (var encrypt in Global.EncryptMethods.VMess)
|
||||
{
|
||||
@@ -116,6 +117,11 @@ namespace Netch.Forms.Server
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (AlterIDTextBox.Text == "")
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Please fill in alterID"));
|
||||
return;
|
||||
}
|
||||
if (Index == -1)
|
||||
{
|
||||
Global.Settings.Server.Add(new Models.Server
|
||||
@@ -160,8 +166,8 @@ namespace Netch.Forms.Server
|
||||
};
|
||||
}
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Global.MainForm.InitServer();
|
||||
Close();
|
||||
}
|
||||
|
||||
206
Netch/Forms/SettingForm.Designer.cs
generated
206
Netch/Forms/SettingForm.Designer.cs
generated
@@ -52,25 +52,27 @@
|
||||
this.ControlButton = new System.Windows.Forms.Button();
|
||||
this.GlobalBypassIPsButton = new System.Windows.Forms.Button();
|
||||
this.BehaviorGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.LanguageLabel = new System.Windows.Forms.Label();
|
||||
this.LanguageComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.BootShadowsocksFromDLLCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.AclAddr = new System.Windows.Forms.TextBox();
|
||||
this.AclAddrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.AclLabel = new System.Windows.Forms.Label();
|
||||
this.DetectionInterval_Label = new System.Windows.Forms.Label();
|
||||
this.DetectionInterval_TextBox = new System.Windows.Forms.TextBox();
|
||||
this.EnableStartedTcping_CheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.DelayTestAfterStartup_Label = new System.Windows.Forms.Label();
|
||||
this.DetectionIntervalLabel = new System.Windows.Forms.Label();
|
||||
this.DetectionIntervalTextBox = new System.Windows.Forms.TextBox();
|
||||
this.TcpingAtStartedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.STUN_ServerPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.STUNServerPortLabel = new System.Windows.Forms.Label();
|
||||
this.StunTextBoxSplitLabel = new System.Windows.Forms.Label();
|
||||
this.STUNServerLabel = new System.Windows.Forms.Label();
|
||||
this.RunAtStartup = new System.Windows.Forms.CheckBox();
|
||||
this.RunAtStartupCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.STUN_ServerTextBox = new System.Windows.Forms.TextBox();
|
||||
this.MinimizeWhenStartedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ProfileCount_Label = new System.Windows.Forms.Label();
|
||||
this.ProfileCount_TextBox = new System.Windows.Forms.TextBox();
|
||||
this.ProfileCountLabel = new System.Windows.Forms.Label();
|
||||
this.ProfileCountTextBox = new System.Windows.Forms.TextBox();
|
||||
this.CheckUpdateWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.StartWhenOpenedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.StopWhenExitedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ExitWhenClosedCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.ModifySystemDNSCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.PortGroupBox.SuspendLayout();
|
||||
this.TUNTAPGroupBox.SuspendLayout();
|
||||
this.BehaviorGroupBox.SuspendLayout();
|
||||
@@ -297,21 +299,23 @@
|
||||
//
|
||||
// BehaviorGroupBox
|
||||
//
|
||||
this.BehaviorGroupBox.Controls.Add(this.LanguageLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.LanguageComboBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.ModifySystemDNSCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.BootShadowsocksFromDLLCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.AclAddr);
|
||||
this.BehaviorGroupBox.Controls.Add(this.AclAddrTextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.AclLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.DetectionInterval_Label);
|
||||
this.BehaviorGroupBox.Controls.Add(this.DetectionInterval_TextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.EnableStartedTcping_CheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.DelayTestAfterStartup_Label);
|
||||
this.BehaviorGroupBox.Controls.Add(this.DetectionIntervalLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.DetectionIntervalTextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.TcpingAtStartedCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.STUN_ServerPortTextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.STUNServerPortLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.StunTextBoxSplitLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.STUNServerLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.RunAtStartup);
|
||||
this.BehaviorGroupBox.Controls.Add(this.RunAtStartupCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.STUN_ServerTextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.MinimizeWhenStartedCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.ProfileCount_Label);
|
||||
this.BehaviorGroupBox.Controls.Add(this.ProfileCount_TextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.ProfileCountLabel);
|
||||
this.BehaviorGroupBox.Controls.Add(this.ProfileCountTextBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.CheckUpdateWhenOpenedCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.StartWhenOpenedCheckBox);
|
||||
this.BehaviorGroupBox.Controls.Add(this.StopWhenExitedCheckBox);
|
||||
@@ -323,6 +327,24 @@
|
||||
this.BehaviorGroupBox.TabStop = false;
|
||||
this.BehaviorGroupBox.Text = "Behavior";
|
||||
//
|
||||
// LanguageLabel
|
||||
//
|
||||
this.LanguageLabel.AutoSize = true;
|
||||
this.LanguageLabel.Location = new System.Drawing.Point(12, 305);
|
||||
this.LanguageLabel.Name = "LanguageLabel";
|
||||
this.LanguageLabel.Size = new System.Drawing.Size(65, 17);
|
||||
this.LanguageLabel.TabIndex = 23;
|
||||
this.LanguageLabel.Text = "Language";
|
||||
//
|
||||
// LanguageComboBox
|
||||
//
|
||||
this.LanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.LanguageComboBox.FormattingEnabled = true;
|
||||
this.LanguageComboBox.Location = new System.Drawing.Point(120, 302);
|
||||
this.LanguageComboBox.Name = "LanguageComboBox";
|
||||
this.LanguageComboBox.Size = new System.Drawing.Size(121, 25);
|
||||
this.LanguageComboBox.TabIndex = 22;
|
||||
//
|
||||
// BootShadowsocksFromDLLCheckBox
|
||||
//
|
||||
this.BootShadowsocksFromDLLCheckBox.AutoSize = true;
|
||||
@@ -335,16 +357,16 @@
|
||||
//
|
||||
// AclAddr
|
||||
//
|
||||
this.AclAddr.Location = new System.Drawing.Point(120, 302);
|
||||
this.AclAddr.Name = "AclAddr";
|
||||
this.AclAddr.Size = new System.Drawing.Size(315, 23);
|
||||
this.AclAddr.TabIndex = 19;
|
||||
this.AclAddr.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.AclAddrTextBox.Location = new System.Drawing.Point(120, 273);
|
||||
this.AclAddrTextBox.Name = "AclAddrTextBox";
|
||||
this.AclAddrTextBox.Size = new System.Drawing.Size(315, 23);
|
||||
this.AclAddrTextBox.TabIndex = 19;
|
||||
this.AclAddrTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// AclLabel
|
||||
//
|
||||
this.AclLabel.AutoSize = true;
|
||||
this.AclLabel.Location = new System.Drawing.Point(12, 305);
|
||||
this.AclLabel.Location = new System.Drawing.Point(12, 276);
|
||||
this.AclLabel.Name = "AclLabel";
|
||||
this.AclLabel.Size = new System.Drawing.Size(78, 17);
|
||||
this.AclLabel.TabIndex = 20;
|
||||
@@ -352,61 +374,53 @@
|
||||
//
|
||||
// DetectionInterval_Label
|
||||
//
|
||||
this.DetectionInterval_Label.AutoSize = true;
|
||||
this.DetectionInterval_Label.Location = new System.Drawing.Point(229, 221);
|
||||
this.DetectionInterval_Label.Name = "DetectionInterval_Label";
|
||||
this.DetectionInterval_Label.Size = new System.Drawing.Size(136, 17);
|
||||
this.DetectionInterval_Label.TabIndex = 18;
|
||||
this.DetectionInterval_Label.Text = "Detection interval(sec)";
|
||||
this.DetectionIntervalLabel.AutoSize = true;
|
||||
this.DetectionIntervalLabel.Location = new System.Drawing.Point(228, 215);
|
||||
this.DetectionIntervalLabel.Name = "DetectionIntervalLabel";
|
||||
this.DetectionIntervalLabel.Size = new System.Drawing.Size(136, 17);
|
||||
this.DetectionIntervalLabel.TabIndex = 18;
|
||||
this.DetectionIntervalLabel.Text = "Detection interval(sec)";
|
||||
//
|
||||
// DetectionInterval_TextBox
|
||||
//
|
||||
this.DetectionInterval_TextBox.Location = new System.Drawing.Point(367, 218);
|
||||
this.DetectionInterval_TextBox.Name = "DetectionInterval_TextBox";
|
||||
this.DetectionInterval_TextBox.Size = new System.Drawing.Size(68, 23);
|
||||
this.DetectionInterval_TextBox.TabIndex = 17;
|
||||
this.DetectionInterval_TextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.DetectionIntervalTextBox.Location = new System.Drawing.Point(366, 212);
|
||||
this.DetectionIntervalTextBox.Name = "DetectionIntervalTextBox";
|
||||
this.DetectionIntervalTextBox.Size = new System.Drawing.Size(68, 23);
|
||||
this.DetectionIntervalTextBox.TabIndex = 17;
|
||||
this.DetectionIntervalTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// EnableStartedTcping_CheckBox
|
||||
//
|
||||
this.EnableStartedTcping_CheckBox.AutoSize = true;
|
||||
this.EnableStartedTcping_CheckBox.Location = new System.Drawing.Point(144, 220);
|
||||
this.EnableStartedTcping_CheckBox.Name = "EnableStartedTcping_CheckBox";
|
||||
this.EnableStartedTcping_CheckBox.Size = new System.Drawing.Size(66, 21);
|
||||
this.EnableStartedTcping_CheckBox.TabIndex = 15;
|
||||
this.EnableStartedTcping_CheckBox.Text = "Enable";
|
||||
this.EnableStartedTcping_CheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DelayTestAfterStartup_Label
|
||||
//
|
||||
this.DelayTestAfterStartup_Label.AutoSize = true;
|
||||
this.DelayTestAfterStartup_Label.Location = new System.Drawing.Point(12, 221);
|
||||
this.DelayTestAfterStartup_Label.Name = "DelayTestAfterStartup_Label";
|
||||
this.DelayTestAfterStartup_Label.Size = new System.Drawing.Size(126, 17);
|
||||
this.DelayTestAfterStartup_Label.TabIndex = 16;
|
||||
this.DelayTestAfterStartup_Label.Text = "Delay test after start";
|
||||
this.TcpingAtStartedCheckBox.AutoSize = true;
|
||||
this.TcpingAtStartedCheckBox.Location = new System.Drawing.Point(15, 214);
|
||||
this.TcpingAtStartedCheckBox.Name = "TcpingAtStartedCheckBox";
|
||||
this.TcpingAtStartedCheckBox.Size = new System.Drawing.Size(145, 21);
|
||||
this.TcpingAtStartedCheckBox.TabIndex = 15;
|
||||
this.TcpingAtStartedCheckBox.TabStop = false;
|
||||
this.TcpingAtStartedCheckBox.Text = "Delay test after start";
|
||||
this.TcpingAtStartedCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// STUN_ServerPortTextBox
|
||||
//
|
||||
this.STUN_ServerPortTextBox.Location = new System.Drawing.Point(120, 273);
|
||||
this.STUN_ServerPortTextBox.Location = new System.Drawing.Point(366, 241);
|
||||
this.STUN_ServerPortTextBox.Name = "STUN_ServerPortTextBox";
|
||||
this.STUN_ServerPortTextBox.Size = new System.Drawing.Size(315, 23);
|
||||
this.STUN_ServerPortTextBox.Size = new System.Drawing.Size(68, 23);
|
||||
this.STUN_ServerPortTextBox.TabIndex = 8;
|
||||
this.STUN_ServerPortTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// STUNServerPortLabel
|
||||
// StunTextBoxSplitLabel
|
||||
//
|
||||
this.STUNServerPortLabel.AutoSize = true;
|
||||
this.STUNServerPortLabel.Location = new System.Drawing.Point(12, 276);
|
||||
this.STUNServerPortLabel.Name = "STUNServerPortLabel";
|
||||
this.STUNServerPortLabel.Size = new System.Drawing.Size(110, 17);
|
||||
this.STUNServerPortLabel.TabIndex = 12;
|
||||
this.STUNServerPortLabel.Text = "STUN Server Port";
|
||||
this.StunTextBoxSplitLabel.AutoSize = true;
|
||||
this.StunTextBoxSplitLabel.Location = new System.Drawing.Point(353, 244);
|
||||
this.StunTextBoxSplitLabel.Name = "StunTextBoxSplitLabel";
|
||||
this.StunTextBoxSplitLabel.Size = new System.Drawing.Size(11, 17);
|
||||
this.StunTextBoxSplitLabel.TabIndex = 12;
|
||||
this.StunTextBoxSplitLabel.Text = ":";
|
||||
//
|
||||
// STUNServerLabel
|
||||
//
|
||||
this.STUNServerLabel.AutoSize = true;
|
||||
this.STUNServerLabel.Location = new System.Drawing.Point(12, 250);
|
||||
this.STUNServerLabel.Location = new System.Drawing.Point(12, 244);
|
||||
this.STUNServerLabel.Name = "STUNServerLabel";
|
||||
this.STUNServerLabel.Size = new System.Drawing.Size(82, 17);
|
||||
this.STUNServerLabel.TabIndex = 10;
|
||||
@@ -414,19 +428,19 @@
|
||||
//
|
||||
// RunAtStartup
|
||||
//
|
||||
this.RunAtStartup.AutoSize = true;
|
||||
this.RunAtStartup.Location = new System.Drawing.Point(12, 75);
|
||||
this.RunAtStartup.Name = "RunAtStartup";
|
||||
this.RunAtStartup.Size = new System.Drawing.Size(109, 21);
|
||||
this.RunAtStartup.TabIndex = 11;
|
||||
this.RunAtStartup.Text = "Run at startup";
|
||||
this.RunAtStartup.UseVisualStyleBackColor = true;
|
||||
this.RunAtStartupCheckBox.AutoSize = true;
|
||||
this.RunAtStartupCheckBox.Location = new System.Drawing.Point(12, 75);
|
||||
this.RunAtStartupCheckBox.Name = "RunAtStartupCheckBox";
|
||||
this.RunAtStartupCheckBox.Size = new System.Drawing.Size(109, 21);
|
||||
this.RunAtStartupCheckBox.TabIndex = 11;
|
||||
this.RunAtStartupCheckBox.Text = "Run at startup";
|
||||
this.RunAtStartupCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// STUN_ServerTextBox
|
||||
//
|
||||
this.STUN_ServerTextBox.Location = new System.Drawing.Point(120, 244);
|
||||
this.STUN_ServerTextBox.Location = new System.Drawing.Point(120, 241);
|
||||
this.STUN_ServerTextBox.Name = "STUN_ServerTextBox";
|
||||
this.STUN_ServerTextBox.Size = new System.Drawing.Size(315, 23);
|
||||
this.STUN_ServerTextBox.Size = new System.Drawing.Size(233, 23);
|
||||
this.STUN_ServerTextBox.TabIndex = 11;
|
||||
this.STUN_ServerTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
@@ -442,20 +456,20 @@
|
||||
//
|
||||
// ProfileCount_Label
|
||||
//
|
||||
this.ProfileCount_Label.AutoSize = true;
|
||||
this.ProfileCount_Label.Location = new System.Drawing.Point(12, 196);
|
||||
this.ProfileCount_Label.Name = "ProfileCount_Label";
|
||||
this.ProfileCount_Label.Size = new System.Drawing.Size(79, 17);
|
||||
this.ProfileCount_Label.TabIndex = 8;
|
||||
this.ProfileCount_Label.Text = "ProfileCount";
|
||||
this.ProfileCountLabel.AutoSize = true;
|
||||
this.ProfileCountLabel.Location = new System.Drawing.Point(12, 188);
|
||||
this.ProfileCountLabel.Name = "ProfileCountLabel";
|
||||
this.ProfileCountLabel.Size = new System.Drawing.Size(79, 17);
|
||||
this.ProfileCountLabel.TabIndex = 8;
|
||||
this.ProfileCountLabel.Text = "ProfileCount";
|
||||
//
|
||||
// ProfileCount_TextBox
|
||||
//
|
||||
this.ProfileCount_TextBox.Location = new System.Drawing.Point(209, 193);
|
||||
this.ProfileCount_TextBox.Name = "ProfileCount_TextBox";
|
||||
this.ProfileCount_TextBox.Size = new System.Drawing.Size(226, 23);
|
||||
this.ProfileCount_TextBox.TabIndex = 9;
|
||||
this.ProfileCount_TextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.ProfileCountTextBox.Location = new System.Drawing.Point(120, 185);
|
||||
this.ProfileCountTextBox.Name = "ProfileCountTextBox";
|
||||
this.ProfileCountTextBox.Size = new System.Drawing.Size(90, 23);
|
||||
this.ProfileCountTextBox.TabIndex = 9;
|
||||
this.ProfileCountTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// CheckUpdateWhenOpenedCheckBox
|
||||
//
|
||||
@@ -501,6 +515,16 @@
|
||||
this.ExitWhenClosedCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.ExitWhenClosedCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ModifySystemDNSCheckBox
|
||||
//
|
||||
this.ModifySystemDNSCheckBox.AutoSize = true;
|
||||
this.ModifySystemDNSCheckBox.Location = new System.Drawing.Point(12, 129);
|
||||
this.ModifySystemDNSCheckBox.Name = "ModifySystemDNSCheckBox";
|
||||
this.ModifySystemDNSCheckBox.Size = new System.Drawing.Size(143, 21);
|
||||
this.ModifySystemDNSCheckBox.TabIndex = 21;
|
||||
this.ModifySystemDNSCheckBox.Text = "Modify System DNS";
|
||||
this.ModifySystemDNSCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// SettingForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
|
||||
@@ -556,24 +580,26 @@
|
||||
private System.Windows.Forms.CheckBox StopWhenExitedCheckBox;
|
||||
private System.Windows.Forms.CheckBox StartWhenOpenedCheckBox;
|
||||
private System.Windows.Forms.CheckBox CheckUpdateWhenOpenedCheckBox;
|
||||
private System.Windows.Forms.Label ProfileCount_Label;
|
||||
private System.Windows.Forms.TextBox ProfileCount_TextBox;
|
||||
private System.Windows.Forms.Label ProfileCountLabel;
|
||||
private System.Windows.Forms.TextBox ProfileCountTextBox;
|
||||
private System.Windows.Forms.CheckBox MinimizeWhenStartedCheckBox;
|
||||
private System.Windows.Forms.CheckBox RunAtStartup;
|
||||
private System.Windows.Forms.Label STUNServerPortLabel;
|
||||
private System.Windows.Forms.CheckBox RunAtStartupCheckBox;
|
||||
private System.Windows.Forms.Label StunTextBoxSplitLabel;
|
||||
private System.Windows.Forms.Label STUNServerLabel;
|
||||
private System.Windows.Forms.TextBox STUN_ServerTextBox;
|
||||
private System.Windows.Forms.TextBox STUN_ServerPortTextBox;
|
||||
private System.Windows.Forms.CheckBox ProxyDNSCheckBox;
|
||||
private System.Windows.Forms.TextBox DetectionInterval_TextBox;
|
||||
private System.Windows.Forms.CheckBox EnableStartedTcping_CheckBox;
|
||||
private System.Windows.Forms.Label DelayTestAfterStartup_Label;
|
||||
private System.Windows.Forms.Label DetectionInterval_Label;
|
||||
private System.Windows.Forms.TextBox DetectionIntervalTextBox;
|
||||
private System.Windows.Forms.CheckBox TcpingAtStartedCheckBox;
|
||||
private System.Windows.Forms.Label DetectionIntervalLabel;
|
||||
private System.Windows.Forms.Label RedirectorLabel;
|
||||
private System.Windows.Forms.TextBox RedirectorTextBox;
|
||||
private System.Windows.Forms.TextBox AclAddr;
|
||||
private System.Windows.Forms.TextBox AclAddrTextBox;
|
||||
private System.Windows.Forms.Label AclLabel;
|
||||
private System.Windows.Forms.CheckBox UseFakeDNSCheckBox;
|
||||
private System.Windows.Forms.CheckBox BootShadowsocksFromDLLCheckBox;
|
||||
private System.Windows.Forms.Label LanguageLabel;
|
||||
private System.Windows.Forms.ComboBox LanguageComboBox;
|
||||
private System.Windows.Forms.CheckBox ModifySystemDNSCheckBox;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using TaskScheduler;
|
||||
|
||||
namespace Netch.Forms
|
||||
@@ -31,6 +34,7 @@ namespace Netch.Forms
|
||||
dns += ip;
|
||||
dns += ',';
|
||||
}
|
||||
|
||||
dns = dns.Trim();
|
||||
TUNTAPDNSTextBox.Text = dns.Substring(0, dns.Length - 1);
|
||||
}
|
||||
@@ -42,65 +46,33 @@ namespace Netch.Forms
|
||||
}
|
||||
}
|
||||
|
||||
private void SettingForm_Load(object sender, EventArgs e)
|
||||
private void InitValue()
|
||||
{
|
||||
Text = Utils.i18N.Translate(Text);
|
||||
PortGroupBox.Text = Utils.i18N.Translate(PortGroupBox.Text);
|
||||
AllowDevicesCheckBox.Text = Utils.i18N.Translate(AllowDevicesCheckBox.Text);
|
||||
TUNTAPAddressLabel.Text = Utils.i18N.Translate(TUNTAPAddressLabel.Text);
|
||||
TUNTAPNetmaskLabel.Text = Utils.i18N.Translate(TUNTAPNetmaskLabel.Text);
|
||||
TUNTAPGatewayLabel.Text = Utils.i18N.Translate(TUNTAPGatewayLabel.Text);
|
||||
UseCustomDNSCheckBox.Text = Utils.i18N.Translate(UseCustomDNSCheckBox.Text);
|
||||
ProxyDNSCheckBox.Text = Utils.i18N.Translate(ProxyDNSCheckBox.Text);
|
||||
UseFakeDNSCheckBox.Text = Utils.i18N.Translate(UseFakeDNSCheckBox.Text);
|
||||
GlobalBypassIPsButton.Text = Utils.i18N.Translate(GlobalBypassIPsButton.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
BootShadowsocksFromDLLCheckBox.Text = Utils.i18N.Translate(BootShadowsocksFromDLLCheckBox.Text);
|
||||
|
||||
ExitWhenClosedCheckBox.Checked = Global.Settings.ExitWhenClosed;
|
||||
StopWhenExitedCheckBox.Checked = Global.Settings.StopWhenExited;
|
||||
StartWhenOpenedCheckBox.Checked = Global.Settings.StartWhenOpened;
|
||||
CheckUpdateWhenOpenedCheckBox.Checked = Global.Settings.CheckUpdateWhenOpened;
|
||||
MinimizeWhenStartedCheckBox.Checked = Global.Settings.MinimizeWhenStarted;
|
||||
RunAtStartup.Checked = Global.Settings.RunAtStartup;
|
||||
EnableStartedTcping_CheckBox.Checked = Global.Settings.StartedTcping;
|
||||
DetectionInterval_TextBox.Text = Global.Settings.StartedTcping_Interval.ToString();
|
||||
BootShadowsocksFromDLLCheckBox.Checked = Global.Settings.BootShadowsocksFromDLL;
|
||||
|
||||
// Local Port
|
||||
Socks5PortTextBox.Text = Global.Settings.Socks5LocalPort.ToString();
|
||||
HTTPPortTextBox.Text = Global.Settings.HTTPLocalPort.ToString();
|
||||
RedirectorTextBox.Text = Global.Settings.RedirectorTCPPort.ToString();
|
||||
switch (Global.Settings.LocalAddress)
|
||||
{
|
||||
case "127.0.0.1":
|
||||
AllowDevicesCheckBox.Checked = false;
|
||||
break;
|
||||
case "0.0.0.0":
|
||||
AllowDevicesCheckBox.Checked = true;
|
||||
break;
|
||||
default:
|
||||
Global.Settings.LocalAddress = "127.0.0.1";
|
||||
AllowDevicesCheckBox.Checked = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// TUN/TAP
|
||||
TUNTAPAddressTextBox.Text = Global.Settings.TUNTAP.Address;
|
||||
TUNTAPNetmaskTextBox.Text = Global.Settings.TUNTAP.Netmask;
|
||||
TUNTAPGatewayTextBox.Text = Global.Settings.TUNTAP.Gateway;
|
||||
|
||||
UseCustomDNSCheckBox.Checked = Global.Settings.TUNTAP.UseCustomDNS;
|
||||
ProxyDNSCheckBox.Checked = Global.Settings.TUNTAP.ProxyDNS;
|
||||
UseFakeDNSCheckBox.Checked = Global.Settings.TUNTAP.UseFakeDNS;
|
||||
|
||||
BehaviorGroupBox.Text = Utils.i18N.Translate(BehaviorGroupBox.Text);
|
||||
ExitWhenClosedCheckBox.Text = Utils.i18N.Translate(ExitWhenClosedCheckBox.Text);
|
||||
StopWhenExitedCheckBox.Text = Utils.i18N.Translate(StopWhenExitedCheckBox.Text);
|
||||
StartWhenOpenedCheckBox.Text = Utils.i18N.Translate(StartWhenOpenedCheckBox.Text);
|
||||
MinimizeWhenStartedCheckBox.Text = Utils.i18N.Translate(MinimizeWhenStartedCheckBox.Text);
|
||||
RunAtStartup.Text = Utils.i18N.Translate(RunAtStartup.Text);
|
||||
CheckUpdateWhenOpenedCheckBox.Text = Utils.i18N.Translate(CheckUpdateWhenOpenedCheckBox.Text);
|
||||
ProfileCount_Label.Text = Utils.i18N.Translate(ProfileCount_Label.Text);
|
||||
DelayTestAfterStartup_Label.Text = Utils.i18N.Translate(DelayTestAfterStartup_Label.Text);
|
||||
EnableStartedTcping_CheckBox.Text = Utils.i18N.Translate(EnableStartedTcping_CheckBox.Text);
|
||||
DetectionInterval_Label.Text = Utils.i18N.Translate(DetectionInterval_Label.Text);
|
||||
DelayTestAfterStartup_Label.Text = Utils.i18N.Translate(DelayTestAfterStartup_Label.Text);
|
||||
STUNServerLabel.Text = Utils.i18N.Translate(STUNServerLabel.Text);
|
||||
STUNServerPortLabel.Text = Utils.i18N.Translate(STUNServerPortLabel.Text);
|
||||
|
||||
ProfileCount_TextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
STUN_ServerTextBox.Text = Global.Settings.STUN_Server.ToString();
|
||||
STUN_ServerPortTextBox.Text = Global.Settings.STUN_Server_Port.ToString();
|
||||
|
||||
AclLabel.Text = Utils.i18N.Translate(AclLabel.Text);
|
||||
AclAddr.Text = Global.Settings.ACL.ToString();
|
||||
|
||||
if (Global.Settings.TUNTAP.DNS.Count > 0)
|
||||
{
|
||||
var dns = "";
|
||||
@@ -109,12 +81,13 @@ namespace Netch.Forms
|
||||
dns += ip;
|
||||
dns += ',';
|
||||
}
|
||||
|
||||
dns = dns.Trim();
|
||||
TUNTAPDNSTextBox.Text = dns.Substring(0, dns.Length - 1);
|
||||
}
|
||||
// 如果 DNS 为空,设置为默认 DNS 1.1.1.1
|
||||
else
|
||||
{
|
||||
// 如果 DNS 为空,设置为默认 DNS 1.1.1.1
|
||||
Global.Settings.TUNTAP.DNS.Add("1.1.1.1");
|
||||
TUNTAPDNSTextBox.Text = "1.1.1.1";
|
||||
}
|
||||
@@ -124,20 +97,63 @@ namespace Netch.Forms
|
||||
TUNTAPDNSTextBox.Enabled = false;
|
||||
}
|
||||
|
||||
// 设置本地代理是否允许其他设备连接
|
||||
if (Global.Settings.LocalAddress == "127.0.0.1")
|
||||
{
|
||||
AllowDevicesCheckBox.Checked = false;
|
||||
}
|
||||
else if (Global.Settings.LocalAddress == "0.0.0.0")
|
||||
{
|
||||
AllowDevicesCheckBox.Checked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Global.Settings.LocalAddress = "127.0.0.1";
|
||||
AllowDevicesCheckBox.Checked = false;
|
||||
}
|
||||
// Behavior
|
||||
ExitWhenClosedCheckBox.Checked = Global.Settings.ExitWhenClosed;
|
||||
StopWhenExitedCheckBox.Checked = Global.Settings.StopWhenExited;
|
||||
StartWhenOpenedCheckBox.Checked = Global.Settings.StartWhenOpened;
|
||||
MinimizeWhenStartedCheckBox.Checked = Global.Settings.MinimizeWhenStarted;
|
||||
RunAtStartupCheckBox.Checked = Global.Settings.RunAtStartup;
|
||||
CheckUpdateWhenOpenedCheckBox.Checked = Global.Settings.CheckUpdateWhenOpened;
|
||||
BootShadowsocksFromDLLCheckBox.Checked = Global.Settings.BootShadowsocksFromDLL;
|
||||
ModifySystemDNSCheckBox.Checked = Global.Settings.ModifySystemDNS;
|
||||
|
||||
ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
TcpingAtStartedCheckBox.Checked = Global.Settings.StartedTcping;
|
||||
DetectionIntervalTextBox.Text = Global.Settings.StartedTcping_Interval.ToString();
|
||||
STUN_ServerTextBox.Text = Global.Settings.STUN_Server;
|
||||
STUN_ServerPortTextBox.Text = Global.Settings.STUN_Server_Port.ToString();
|
||||
AclAddrTextBox.Text = Global.Settings.ACL;
|
||||
LanguageComboBox.Items.AddRange(i18N.GetTranslateList().ToArray());
|
||||
LanguageComboBox.SelectedItem = Global.Settings.Language;
|
||||
}
|
||||
|
||||
private void InitText()
|
||||
{
|
||||
Text = i18N.Translate(Text);
|
||||
|
||||
PortGroupBox.Text = i18N.Translate(PortGroupBox.Text);
|
||||
AllowDevicesCheckBox.Text = i18N.Translate(AllowDevicesCheckBox.Text);
|
||||
TUNTAPAddressLabel.Text = i18N.Translate(TUNTAPAddressLabel.Text);
|
||||
TUNTAPNetmaskLabel.Text = i18N.Translate(TUNTAPNetmaskLabel.Text);
|
||||
TUNTAPGatewayLabel.Text = i18N.Translate(TUNTAPGatewayLabel.Text);
|
||||
UseCustomDNSCheckBox.Text = i18N.Translate(UseCustomDNSCheckBox.Text);
|
||||
ProxyDNSCheckBox.Text = i18N.Translate(ProxyDNSCheckBox.Text);
|
||||
UseFakeDNSCheckBox.Text = i18N.Translate(UseFakeDNSCheckBox.Text);
|
||||
GlobalBypassIPsButton.Text = i18N.Translate(GlobalBypassIPsButton.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
BootShadowsocksFromDLLCheckBox.Text = i18N.Translate(BootShadowsocksFromDLLCheckBox.Text);
|
||||
ModifySystemDNSCheckBox.Text = i18N.Translate(ModifySystemDNSCheckBox.Text);
|
||||
BehaviorGroupBox.Text = i18N.Translate(BehaviorGroupBox.Text);
|
||||
ExitWhenClosedCheckBox.Text = i18N.Translate(ExitWhenClosedCheckBox.Text);
|
||||
StopWhenExitedCheckBox.Text = i18N.Translate(StopWhenExitedCheckBox.Text);
|
||||
StartWhenOpenedCheckBox.Text = i18N.Translate(StartWhenOpenedCheckBox.Text);
|
||||
MinimizeWhenStartedCheckBox.Text = i18N.Translate(MinimizeWhenStartedCheckBox.Text);
|
||||
RunAtStartupCheckBox.Text = i18N.Translate(RunAtStartupCheckBox.Text);
|
||||
CheckUpdateWhenOpenedCheckBox.Text = i18N.Translate(CheckUpdateWhenOpenedCheckBox.Text);
|
||||
ProfileCountLabel.Text = i18N.Translate(ProfileCountLabel.Text);
|
||||
TcpingAtStartedCheckBox.Text = i18N.Translate(TcpingAtStartedCheckBox.Text);
|
||||
DetectionIntervalLabel.Text = i18N.Translate(DetectionIntervalLabel.Text);
|
||||
STUNServerLabel.Text = i18N.Translate(STUNServerLabel.Text);
|
||||
StunTextBoxSplitLabel.Text = i18N.Translate(StunTextBoxSplitLabel.Text);
|
||||
AclLabel.Text = i18N.Translate(AclLabel.Text);
|
||||
LanguageLabel.Text = i18N.Translate(LanguageLabel.Text);
|
||||
}
|
||||
|
||||
private void SettingForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
InitText();
|
||||
|
||||
InitValue();
|
||||
}
|
||||
|
||||
private void SettingForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
@@ -158,42 +174,45 @@ namespace Netch.Forms
|
||||
Global.Settings.StartWhenOpened = StartWhenOpenedCheckBox.Checked;
|
||||
Global.Settings.CheckUpdateWhenOpened = CheckUpdateWhenOpenedCheckBox.Checked;
|
||||
Global.Settings.MinimizeWhenStarted = MinimizeWhenStartedCheckBox.Checked;
|
||||
Global.Settings.RunAtStartup = RunAtStartup.Checked;
|
||||
Global.Settings.RunAtStartup = RunAtStartupCheckBox.Checked;
|
||||
Global.Settings.BootShadowsocksFromDLL = BootShadowsocksFromDLLCheckBox.Checked;
|
||||
|
||||
Global.Settings.Language = LanguageComboBox.SelectedItem.ToString();
|
||||
|
||||
// 开机自启判断
|
||||
TaskSchedulerClass scheduler = new TaskSchedulerClass();
|
||||
scheduler.Connect(null, null, null, null);
|
||||
ITaskFolder folder = scheduler.GetFolder("\\");
|
||||
bool taskIsExists = false;
|
||||
var scheduler = new TaskSchedulerClass();
|
||||
scheduler.Connect();
|
||||
var folder = scheduler.GetFolder("\\");
|
||||
var taskIsExists = false;
|
||||
try
|
||||
{
|
||||
folder.GetTask("Netch Startup");
|
||||
taskIsExists = true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
if (RunAtStartup.Checked)
|
||||
if (RunAtStartupCheckBox.Checked)
|
||||
{
|
||||
if (taskIsExists)
|
||||
folder.DeleteTask("Netch Startup", 0);
|
||||
|
||||
ITaskDefinition task = scheduler.NewTask(0);
|
||||
var task = scheduler.NewTask(0);
|
||||
task.RegistrationInfo.Author = "Netch";
|
||||
task.RegistrationInfo.Description = "Netch run at startup.";
|
||||
task.Principal.RunLevel = _TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST;
|
||||
|
||||
task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON);
|
||||
IExecAction action = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);
|
||||
action.Path = System.Windows.Forms.Application.ExecutablePath;
|
||||
var action = (IExecAction) task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);
|
||||
action.Path = Application.ExecutablePath;
|
||||
|
||||
|
||||
task.Settings.ExecutionTimeLimit = "PT0S";
|
||||
task.Settings.DisallowStartIfOnBatteries = false;
|
||||
task.Settings.RunOnlyIfIdle = false;
|
||||
|
||||
folder.RegisterTaskDefinition("Netch Startup", task, (int)_TASK_CREATION.TASK_CREATE, null, null, _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
|
||||
folder.RegisterTaskDefinition("Netch Startup", task, (int) _TASK_CREATION.TASK_CREATE, null, null, _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -201,77 +220,15 @@ namespace Netch.Forms
|
||||
folder.DeleteTask("Netch Startup", 0);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var Socks5Port = int.Parse(Socks5PortTextBox.Text);
|
||||
|
||||
if (Socks5Port > 0 && Socks5Port < 65536)
|
||||
{
|
||||
Global.Settings.Socks5LocalPort = Socks5Port;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
Socks5PortTextBox.Text = Global.Settings.Socks5LocalPort.ToString();
|
||||
MessageBox.Show(Utils.i18N.Translate("Port value illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
// 端口检查
|
||||
if (!CheckPortText("Socks5", ref Socks5PortTextBox, ref Global.Settings.Socks5LocalPort))
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var HTTPPort = int.Parse(HTTPPortTextBox.Text);
|
||||
|
||||
if (HTTPPort > 0 && HTTPPort < 65536)
|
||||
{
|
||||
Global.Settings.HTTPLocalPort = HTTPPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
HTTPPortTextBox.Text = Global.Settings.HTTPLocalPort.ToString();
|
||||
MessageBox.Show(Utils.i18N.Translate("Port value illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
if (!CheckPortText("HTTP", ref HTTPPortTextBox, ref Global.Settings.HTTPLocalPort))
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var RedirectorPort = int.Parse(RedirectorTextBox.Text);
|
||||
|
||||
if (RedirectorPort > 0 && RedirectorPort < 65536)
|
||||
{
|
||||
Global.Settings.RedirectorTCPPort = RedirectorPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
RedirectorTextBox.Text = Global.Settings.RedirectorTCPPort.ToString();
|
||||
MessageBox.Show(Utils.i18N.Translate("Port value illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
if (!CheckPortText("RedirectorTCP", ref RedirectorTextBox, ref Global.Settings.RedirectorTCPPort, PortType.TCP))
|
||||
return;
|
||||
}
|
||||
|
||||
if (AllowDevicesCheckBox.Checked)
|
||||
{
|
||||
Global.Settings.LocalAddress = "0.0.0.0";
|
||||
}
|
||||
else
|
||||
{
|
||||
Global.Settings.LocalAddress = "127.0.0.1";
|
||||
}
|
||||
Global.Settings.LocalAddress = AllowDevicesCheckBox.Checked ? "0.0.0.0" : "127.0.0.1";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -279,7 +236,7 @@ namespace Netch.Forms
|
||||
var Netmask = IPAddress.Parse(TUNTAPNetmaskTextBox.Text);
|
||||
var Gateway = IPAddress.Parse(TUNTAPGatewayTextBox.Text);
|
||||
|
||||
var DNS = new System.Collections.Generic.List<IPAddress>();
|
||||
var DNS = new List<IPAddress>();
|
||||
foreach (var ip in TUNTAPDNSTextBox.Text.Split(','))
|
||||
{
|
||||
DNS.Add(IPAddress.Parse(ip));
|
||||
@@ -287,7 +244,7 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("IP address format illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("IP address format illegal. Try again."));
|
||||
|
||||
TUNTAPAddressTextBox.Text = Global.Settings.TUNTAP.Address;
|
||||
TUNTAPNetmaskTextBox.Text = Global.Settings.TUNTAP.Netmask;
|
||||
@@ -299,15 +256,17 @@ namespace Netch.Forms
|
||||
DNS += ip;
|
||||
DNS += ',';
|
||||
}
|
||||
|
||||
DNS = DNS.Trim();
|
||||
TUNTAPDNSTextBox.Text = DNS.Substring(0, DNS.Length - 1);
|
||||
UseCustomDNSCheckBox.Checked = Global.Settings.TUNTAP.UseCustomDNS;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var ProfileCount = int.Parse(ProfileCount_TextBox.Text);
|
||||
var ProfileCount = int.Parse(ProfileCountTextBox.Text);
|
||||
|
||||
if (ProfileCount > -1)
|
||||
{
|
||||
@@ -320,11 +279,12 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
ProfileCount_TextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
MessageBox.Show(Utils.i18N.Translate("ProfileCount value illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
MessageBoxX.Show(i18N.Translate("ProfileCount value illegal. Try again."));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var STUN_Server = STUN_ServerTextBox.Text;
|
||||
@@ -343,16 +303,17 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
ProfileCount_TextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
MessageBox.Show(Utils.i18N.Translate("STUN_ServerPort value illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
MessageBoxX.Show(i18N.Translate("STUN_ServerPort value illegal. Try again."));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Global.Settings.StartedTcping = EnableStartedTcping_CheckBox.Checked;
|
||||
Global.Settings.StartedTcping = TcpingAtStartedCheckBox.Checked;
|
||||
|
||||
var DetectionInterval = int.Parse(DetectionInterval_TextBox.Text);
|
||||
var DetectionInterval = int.Parse(DetectionIntervalTextBox.Text);
|
||||
|
||||
if (DetectionInterval > 0)
|
||||
{
|
||||
@@ -365,13 +326,13 @@ namespace Netch.Forms
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
ProfileCount_TextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
MessageBox.Show(Utils.i18N.Translate("Detection interval value illegal. Try again."), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
ProfileCountTextBox.Text = Global.Settings.ProfileCount.ToString();
|
||||
MessageBoxX.Show(i18N.Translate("Detection interval value illegal. Try again."));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Global.Settings.ACL = AclAddr.Text;
|
||||
Global.Settings.ACL = AclAddrTextBox.Text;
|
||||
|
||||
Global.Settings.TUNTAP.Address = TUNTAPAddressTextBox.Text;
|
||||
Global.Settings.TUNTAP.Netmask = TUNTAPNetmaskTextBox.Text;
|
||||
@@ -387,9 +348,54 @@ namespace Netch.Forms
|
||||
Global.Settings.TUNTAP.ProxyDNS = ProxyDNSCheckBox.Checked;
|
||||
Global.Settings.TUNTAP.UseFakeDNS = UseFakeDNSCheckBox.Checked;
|
||||
|
||||
Utils.Configuration.Save();
|
||||
MessageBox.Show(Utils.i18N.Translate("Saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
Global.Settings.ModifySystemDNS = ModifySystemDNSCheckBox.Checked;
|
||||
|
||||
Configuration.Save();
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="portName"></param>
|
||||
/// <param name="portTextBox"></param>
|
||||
/// <param name="originPort"></param>
|
||||
/// <param name="portType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="FormatException"></exception>
|
||||
private bool CheckPortText(string portName, ref TextBox portTextBox, ref int originPort, PortType portType = PortType.Both)
|
||||
{
|
||||
// 端口检查
|
||||
try
|
||||
{
|
||||
var port = int.Parse(portTextBox.Text);
|
||||
|
||||
if (port <= 0 || port >= 65536)
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
if (port == originPort)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PortHelper.PortInUse(port, portType))
|
||||
{
|
||||
MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", portName));
|
||||
return false;
|
||||
}
|
||||
|
||||
originPort = port;
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
MessageBoxX.Show(i18N.Translate("Port value illegal. Try again."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
using Netch.Utils;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Forms
|
||||
{
|
||||
@@ -38,16 +38,16 @@ namespace Netch.Forms
|
||||
|
||||
private void SubscribeForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Text = Utils.i18N.Translate(Text);
|
||||
RemarkColumnHeader.Text = Utils.i18N.Translate(RemarkColumnHeader.Text);
|
||||
LinkColumnHeader.Text = Utils.i18N.Translate(LinkColumnHeader.Text);
|
||||
UseSelectedServerCheckBox.Text = Utils.i18N.Translate(UseSelectedServerCheckBox.Text);
|
||||
DeleteToolStripMenuItem.Text = Utils.i18N.Translate(DeleteToolStripMenuItem.Text);
|
||||
CopyLinkToolStripMenuItem.Text = Utils.i18N.Translate(CopyLinkToolStripMenuItem.Text);
|
||||
RemarkLabel.Text = Utils.i18N.Translate(RemarkLabel.Text);
|
||||
LinkLabel.Text = Utils.i18N.Translate(LinkLabel.Text);
|
||||
AddButton.Text = Utils.i18N.Translate(AddButton.Text);
|
||||
ControlButton.Text = Utils.i18N.Translate(ControlButton.Text);
|
||||
Text = i18N.Translate(Text);
|
||||
RemarkColumnHeader.Text = i18N.Translate(RemarkColumnHeader.Text);
|
||||
LinkColumnHeader.Text = i18N.Translate(LinkColumnHeader.Text);
|
||||
UseSelectedServerCheckBox.Text = i18N.Translate(UseSelectedServerCheckBox.Text);
|
||||
DeleteToolStripMenuItem.Text = i18N.Translate(DeleteToolStripMenuItem.Text);
|
||||
CopyLinkToolStripMenuItem.Text = i18N.Translate(CopyLinkToolStripMenuItem.Text);
|
||||
RemarkLabel.Text = i18N.Translate(RemarkLabel.Text);
|
||||
LinkLabel.Text = i18N.Translate(LinkLabel.Text);
|
||||
AddButton.Text = i18N.Translate(AddButton.Text);
|
||||
ControlButton.Text = i18N.Translate(ControlButton.Text);
|
||||
|
||||
UserAgentTextBox.Text = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36";
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Netch.Forms
|
||||
}
|
||||
private void DeleteToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (MessageBox.Show(Utils.i18N.Translate("Delete or not ? Will clean up the corresponding group of items in the server list"), Utils.i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
|
||||
if (MessageBoxX.Show(i18N.Translate("Delete or not ? Will clean up the corresponding group of items in the server list"), confirm: true) == DialogResult.OK)
|
||||
{
|
||||
if (SubscribeLinkListView.SelectedItems.Count > 0)
|
||||
{
|
||||
@@ -128,14 +128,14 @@ namespace Netch.Forms
|
||||
{
|
||||
//是否为新增订阅
|
||||
var saveFlag = true;
|
||||
Global.Settings.SubscribeLink.ForEach((subitem) =>
|
||||
Global.Settings.SubscribeLink.ForEach(subitem =>
|
||||
{
|
||||
if (subitem.Link.Equals(LinkTextBox.Text))
|
||||
{
|
||||
if (!subitem.Remark.Equals(RemarkTextBox.Text))
|
||||
{
|
||||
//修改了订阅备注,修改旧订阅服务器
|
||||
Global.Settings.Server.ForEach((serverItem) =>
|
||||
Global.Settings.Server.ForEach(serverItem =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -159,16 +159,14 @@ namespace Netch.Forms
|
||||
subitem.UserAgent = UserAgentTextBox.Text;
|
||||
saveFlag = false;
|
||||
|
||||
Utils.Configuration.Save();
|
||||
Configuration.Save();
|
||||
Global.Settings.UseProxyToUpdateSubscription = UseSelectedServerCheckBox.Checked;
|
||||
MessageBox.Show(Utils.i18N.Translate("Successfully saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
return;
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
}
|
||||
});
|
||||
if (saveFlag)
|
||||
{
|
||||
Global.Settings.SubscribeLink.Add(new Models.SubscribeLink
|
||||
Global.Settings.SubscribeLink.Add(new SubscribeLink
|
||||
{
|
||||
Remark = RemarkTextBox.Text,
|
||||
Link = LinkTextBox.Text,
|
||||
@@ -184,25 +182,25 @@ namespace Netch.Forms
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Links must start with http:// or https://"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Links must start with http:// or https://"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Link can not be empty"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Link can not be empty"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(Utils.i18N.Translate("Remark can not be empty"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Remark can not be empty"));
|
||||
}
|
||||
}
|
||||
|
||||
private void ControlButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Utils.Configuration.Save();
|
||||
Configuration.Save();
|
||||
Global.Settings.UseProxyToUpdateSubscription = UseSelectedServerCheckBox.Checked;
|
||||
MessageBox.Show(Utils.i18N.Translate("Successfully saved"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Saved"));
|
||||
Close();
|
||||
}
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
@@ -6,8 +7,16 @@ namespace Netch
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体
|
||||
/// 换行
|
||||
/// </summary>
|
||||
public static string EOF = "\r\n";
|
||||
|
||||
public static readonly string NetchDir = (AppDomain.CurrentDomain.BaseDirectory).TrimEnd();
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体的静态实例
|
||||
/// </summary>
|
||||
public static Forms.MainForm MainForm;
|
||||
|
||||
|
||||
16
Netch/Models/STUN.Client.cs
Normal file
16
Netch/Models/STUN.Client.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Netch.Models
|
||||
{
|
||||
public class STUN_Client
|
||||
{
|
||||
public enum NatType
|
||||
{
|
||||
UdpBlocked,
|
||||
OpenInternet,
|
||||
SymmetricUdpFirewall,
|
||||
FullCone,
|
||||
RestrictedCone,
|
||||
PortRestrictedCone,
|
||||
Symmetric
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,35 +156,10 @@ namespace Netch.Models
|
||||
|
||||
if (Country == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var databaseReader = new DatabaseReader("bin\\GeoLite2-Country.mmdb");
|
||||
|
||||
if (IPAddress.TryParse(Hostname, out _) == true)
|
||||
{
|
||||
Country = databaseReader.Country(Hostname).Country.IsoCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
var DnsResult = DNS.Lookup(Hostname);
|
||||
|
||||
if (DnsResult != null)
|
||||
{
|
||||
Country = databaseReader.Country(DnsResult).Country.IsoCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
Country = "UN";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Country = "UN";
|
||||
}
|
||||
Country = Utils.Utils.GetCityCode(Hostname);
|
||||
}
|
||||
|
||||
Group = Group.Equals("None") ? Group.ToUpper() : Group;
|
||||
Group = Group.Equals("None") || Group.Equals("") ? "NONE" : Group;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
|
||||
@@ -88,6 +88,11 @@ namespace Netch.Models
|
||||
/// </summary>
|
||||
public bool CheckUpdateWhenOpened = true;
|
||||
|
||||
/// <summary>
|
||||
/// 修改系统 DNS
|
||||
/// </summary>
|
||||
public bool ModifySystemDNS = false;
|
||||
|
||||
/// <summary>
|
||||
/// 使用何种模式文件名
|
||||
/// 0 为自定义文件名,1 为使用和备注一致的文件名,2 为使用时间数据作为文件名
|
||||
@@ -142,7 +147,7 @@ namespace Netch.Models
|
||||
/// <summary>
|
||||
/// 已保存的快捷配置
|
||||
/// </summary>
|
||||
public List<Profile> profiles = new List<Profile>();
|
||||
public List<Profile> Profiles = new List<Profile>();
|
||||
|
||||
/// <summary>
|
||||
/// 快捷配置数量
|
||||
@@ -178,5 +183,10 @@ namespace Netch.Models
|
||||
/// 是否使用DLL启动Shadowsocks
|
||||
/// </summary>
|
||||
public bool BootShadowsocksFromDLL = false;
|
||||
|
||||
/// <summary>
|
||||
/// 语言设置
|
||||
/// </summary>
|
||||
public string Language = "System";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,14 @@
|
||||
/// </summary>
|
||||
Terminating
|
||||
}
|
||||
}
|
||||
|
||||
public static class StateExtension
|
||||
{
|
||||
public static string GetStatusString(State state)
|
||||
{
|
||||
if (state == State.Waiting)
|
||||
return "Waiting for command";
|
||||
return state.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace Netch.Models
|
||||
public string cert;
|
||||
public string cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA";
|
||||
public string cipher_tls13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384";
|
||||
public string sni;
|
||||
public string sni = string.Empty;
|
||||
public List<string> alpn = new List<string>()
|
||||
{
|
||||
"h2",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Controllers;
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch
|
||||
{
|
||||
@@ -25,14 +25,14 @@ namespace Netch
|
||||
// 清理上一次的日志文件,防止淤积占用磁盘空间
|
||||
if (Directory.Exists("logging"))
|
||||
{
|
||||
DirectoryInfo directory = new DirectoryInfo("logging");
|
||||
var directory = new DirectoryInfo("logging");
|
||||
|
||||
foreach (FileInfo file in directory.GetFiles())
|
||||
foreach (var file in directory.GetFiles())
|
||||
{
|
||||
file.Delete();
|
||||
}
|
||||
|
||||
foreach (DirectoryInfo dir in directory.GetDirectories())
|
||||
foreach (var dir in directory.GetDirectories())
|
||||
{
|
||||
dir.Delete(true);
|
||||
}
|
||||
@@ -50,61 +50,22 @@ namespace Netch
|
||||
}
|
||||
}
|
||||
|
||||
// 得到当前线程语言代码
|
||||
var culture = CultureInfo.CurrentCulture.Name;
|
||||
// 加载配置
|
||||
Configuration.Load();
|
||||
|
||||
// 如果命令行参数只有一个,且传入有效语言代码,那么覆盖掉已得到的语言代码
|
||||
if (args.Length == 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
culture = CultureInfo.GetCultureInfo(args[0]).Name;
|
||||
}
|
||||
catch (CultureNotFoundException)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
// 加载语言
|
||||
i18N.Load(Global.Settings.Language);
|
||||
|
||||
// 记录当前系统语言
|
||||
Utils.Logging.Info($"当前系统语言:{culture}");
|
||||
|
||||
// 尝试加载内置中文语言
|
||||
if (culture == "zh-CN")
|
||||
{
|
||||
// 加载语言
|
||||
Utils.i18N.Load(Encoding.UTF8.GetString(Properties.Resources.zh_CN));
|
||||
}
|
||||
|
||||
// 记录当前程序语言
|
||||
Utils.Logging.Info($"当前程序语言:{culture}");
|
||||
|
||||
// 从外置文件中加载语言
|
||||
if (File.Exists($"i18n\\{culture}"))
|
||||
{
|
||||
// 加载语言
|
||||
Utils.i18N.Load(File.ReadAllText($"i18n\\{culture}"));
|
||||
}
|
||||
Logging.Info($"当前语言:{Global.Settings.Language}");
|
||||
Logging.Info($"版本:{UpdateChecker.Owner}/{UpdateChecker.Repo} {UpdateChecker.Version}");
|
||||
Logging.Info($"主程序创建日期:{File.GetCreationTime(Global.NetchDir + "\\Netch.exe"):yyyy-M-d HH:mm}");
|
||||
|
||||
// 检查是否已经运行
|
||||
if (!mutex.WaitOne(0, false))
|
||||
{
|
||||
// 弹出提示
|
||||
MessageBox.Show(Utils.i18N.Translate("Netch is already running"), Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
||||
// 退出进程
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
var OS = Environment.Is64BitOperatingSystem ? "x64" : "x86";
|
||||
var PROC = Environment.Is64BitProcess ? "x64" : "x86";
|
||||
|
||||
// 如果系统位数与程序位数不一致
|
||||
if (OS != PROC)
|
||||
{
|
||||
|
||||
// 弹出提示
|
||||
MessageBox.Show($"{Utils.i18N.Translate("Netch is not compatible with your system.")}\n{Utils.i18N.Translate("Current arch of Netch:")} {PROC}\n{Utils.i18N.Translate("Current arch of system:")} {OS}", Utils.i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessageBoxX.Show(i18N.Translate("Netch is already running"));
|
||||
|
||||
// 退出进程
|
||||
Environment.Exit(1);
|
||||
@@ -116,14 +77,17 @@ namespace Netch
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(Global.MainForm = new Forms.MainForm());
|
||||
Application.Run(Global.MainForm = new MainForm());
|
||||
}
|
||||
}
|
||||
|
||||
public static void Application_OnException(object sender, ThreadExceptionEventArgs e)
|
||||
{
|
||||
MessageBox.Show(e.Exception.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
Application.Exit();
|
||||
if (!e.Exception.ToString().Contains("ComboBox"))
|
||||
{
|
||||
MessageBox.Show(e.Exception.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
//Application.Exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,20 @@
|
||||
<Isolated>false</Isolated>
|
||||
<EmbedInteropTypes>false</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="NetFwTypeLib.dll">
|
||||
<Guid>58fbcf7c-e7a9-467c-80b3-fc65e8fcca08</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>false</Isolated>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ini-parser" Version="2.5.2" />
|
||||
<PackageReference Include="MaxMind.GeoIP2" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.56" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="System.Buffers" Version="4.5.1" />
|
||||
<PackageReference Include="WindowsAPICodePack-Shell" Version="1.1.1" />
|
||||
@@ -61,6 +70,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Web" />
|
||||
@@ -97,6 +107,6 @@
|
||||
</ItemGroup>
|
||||
<ProjectExtensions><VisualStudio><UserProperties /></VisualStudio></ProjectExtensions>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="@ECHO OFF
RD /S /Q $(TargetDir)bin > NUL 2>&1
RD /S /Q $(TargetDir)i18n > NUL 2>&1
RD /S /Q $(TargetDir)mode > NUL 2>&1

MKDIR $(TargetDir)bin > NUL 2>&1
MKDIR $(TargetDir)i18n > NUL 2>&1
MKDIR $(TargetDir)mode > NUL 2>&1

COPY /Y $(SolutionDir)binaries\* $(TargetDir)bin > NUL 2>&1
COPY /Y $(SolutionDir)translations\i18n\* $(TargetDir)i18n > NUL 2>&1
COPY /Y $(SolutionDir)modes\mode\* $(TargetDir)mode > NUL 2>&1
MKDIR $(TargetDir)bin\tap-driver > NUL 2>&1
COPY /Y $(SolutionDir)binaries\tap-driver\* $(TargetDir)bin\tap-driver > NUL 2>&1

DEL / f $(TargetDir)\*.config
DEL / f $(TargetDir)\*.pdb" />
|
||||
<Exec Command="@ECHO OFF
RD /S /Q $(TargetDir)bin > NUL 2>&1
RD /S /Q $(TargetDir)i18n > NUL 2>&1
RD /S /Q $(TargetDir)mode > NUL 2>&1

MKDIR $(TargetDir)bin > NUL 2>&1
MKDIR $(TargetDir)i18n > NUL 2>&1
MKDIR $(TargetDir)mode > NUL 2>&1

COPY /Y $(SolutionDir)binaries\* $(TargetDir)bin > NUL 2>&1
COPY /Y $(SolutionDir)translations\i18n\* $(TargetDir)i18n > NUL 2>&1
COPY /Y $(SolutionDir)modes\mode\* $(TargetDir)mode > NUL 2>&1
MKDIR $(TargetDir)bin\tap-driver > NUL 2>&1
COPY /Y $(SolutionDir)binaries\tap-driver\* $(TargetDir)bin\tap-driver > NUL 2>&1

DEL / f $(TargetDir)\*.config
DEL / f $(TargetDir)\*.pdb
RD /s /Q $(TargetDir)\x86" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{
|
||||
protected override void OnRenderToolStripBorder(System.Windows.Forms.ToolStripRenderEventArgs e)
|
||||
{
|
||||
// 跳过
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
"Information": "信息",
|
||||
"Error": "错误",
|
||||
|
||||
"If this is your first time using this software,\n please check https://netch.org to install supports first,\n or the program may report errors.": "如果你是第一次使用本软件,\n请务必前往https://netch.org安装程序所需依赖,\n否则程序将无法正常运行!",
|
||||
"Netch is already running": "Netch 已经在运行中",
|
||||
"Netch is not compatible with your system.": "Netch 和你的系统不兼容",
|
||||
"Current arch of Netch:": "当前 Netch 架构:",
|
||||
"Current arch of system:": "当前系统架构:",
|
||||
|
||||
"Start": "启动",
|
||||
"Stop": "停止",
|
||||
@@ -16,15 +14,12 @@
|
||||
"Started": "已启动",
|
||||
"Stopping": "正在停止中",
|
||||
"Stopped": "已停止",
|
||||
"Starting Shadowsocks": "正在启动 Shadowsocks",
|
||||
"Starting ShadowsocksR": "正在启动 ShadowsocksR",
|
||||
"Starting V2ray": "正在启动 V2Ray",
|
||||
"Starting Trojan": "正在启动 Trojan",
|
||||
"Starting ": "正在启动 ",
|
||||
"Starting Tap": "正在启动 TUN/TAP",
|
||||
"Starting NatTester": "正在启动 NAT 测试",
|
||||
"Starting LocalDns service": "正在启动本地 DNS 服务",
|
||||
"Starting Redirector": "正在启动 Redirector",
|
||||
"ReStarting Redirector": "正常启动失败,正在尝试重新启动 Redirector",
|
||||
"Restarting Redirector": "正常启动失败,正在尝试重新启动 Redirector",
|
||||
"Starting netfilter2 Service": "正在启动 netfilter2 服务",
|
||||
"Starting dns Service": "正在启动 DNS 服务",
|
||||
"SetupBypass": "设置绕行规则",
|
||||
@@ -42,12 +37,10 @@
|
||||
"Add [ShadowsocksR] Server": "添加 [ShadowsocksR] 服务器",
|
||||
"Add [VMess] Server": "添加 [VMess] 服务器",
|
||||
"Add [Trojan] Server": "添加 [Trojan] 服务器",
|
||||
"VMess is currently not supported. For more information, please see our Github releases\n\nPress OK will redirect": "当前不支持 VMess 服务器。需要更多信息请查看我们的 Github 发布页\n\n点击 OK 将会跳转",
|
||||
"Netch is now minimized to the notification bar, double click this icon to restore.": "Netch 已最小化至通知栏,双击此图标恢复窗口。",
|
||||
"New version available": "发现新版本",
|
||||
"Mode": "模式",
|
||||
"Create Process Mode": "创建进程模式",
|
||||
"Manage Process Mode": "管理进程模式",
|
||||
"Edit Process Mode": "修改进程模式",
|
||||
|
||||
"Address": "地址",
|
||||
@@ -81,11 +74,8 @@
|
||||
"Update servers error from {0}": "从 {0} 更新服务器失败",
|
||||
|
||||
"Options": "选项",
|
||||
"Restart Service": "重启服务",
|
||||
"Restarting service": "正在重启服务中",
|
||||
"Service has been restarted": "服务已重启",
|
||||
"Uninstall Service": "卸载服务",
|
||||
"Uninstalling Service": "正在卸载服务中",
|
||||
"Uninstall NF Service": "卸载 NF 服务",
|
||||
"Uninstalling NF Service": "正在卸载 NF 服务中",
|
||||
"Service has been uninstalled": "服务已卸载",
|
||||
"Reload Modes": "重载模式",
|
||||
"Modes have been reload": "模式已重载",
|
||||
@@ -99,6 +89,7 @@
|
||||
"Reinstall TUN/TAP driver successfully": "重装 TUN/TAP 驱动成功",
|
||||
"Reinstall TUN/TAP driver failed": "重装 TUN/TAP 驱动失败",
|
||||
"Reinstalling TUN/TAP driver": "正在重装 TUN/TAP 驱动",
|
||||
"Open Directory": "打开目录",
|
||||
|
||||
"About": "关于",
|
||||
"Telegram Channel": "Telegram 频道",
|
||||
@@ -108,9 +99,11 @@
|
||||
|
||||
"Please press Stop button first": "请先点击停止按钮",
|
||||
"Please select a server first": "请先选择一个服务器",
|
||||
"Please select an mode first": "请先选择一个模式",
|
||||
"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 + 左键 点击该按钮保存一个配置",
|
||||
"Remove this Profile?": "删除此配置?",
|
||||
"Profile Removed!": "配置已删除!",
|
||||
|
||||
"Used": "已使用",
|
||||
"Status": "状态",
|
||||
@@ -144,7 +137,7 @@
|
||||
"Remark can not be empty": "备注不可为空",
|
||||
"Link can not be empty": "链接不可为空",
|
||||
"Link must start with http:// or https://": "链接必须以 http:// 或 https:// 开头",
|
||||
"Successfully saved": "保存成功",
|
||||
"Please fill in alterID": "请填写额外ID",
|
||||
|
||||
"Settings": "设置",
|
||||
"Start when opened": "打开软件时启动加速",
|
||||
@@ -164,19 +157,20 @@
|
||||
"Port value illegal. Try again.": "端口值非法。请重试。",
|
||||
"Check update when opened": "打开软件时检查更新",
|
||||
"Start Shadowsocks from DLL (No support for ACL)": "SS DLL(推荐使用,不支持 ACL)",
|
||||
"ProfileCount": "快捷配置数量(重启软件生效)",
|
||||
"Modify System DNS": "修改系统 DNS",
|
||||
"ProfileCount": "快捷配置数量",
|
||||
"ProfileCount value illegal. Try again.": "快捷配置数值非法。请重试。",
|
||||
"STUN_ServerPort value illegal. Try again.": "STUN 端口数值非法。请重试。",
|
||||
"Detection interval value illegal. Try again.": "检测间隔值非法。请重试。",
|
||||
"TUN/TAP driver is not detected. Is it installed now?": "未检测到 TUN/TAP 驱动,是否现在安装?",
|
||||
"Failed to set the system proxy, it may be caused by the lack of dependent programs. Do you want to jump to Netch's official website to download dependent programs?": "设置系统代理失败,可能是缺少依赖导致,是否跳转 Netch 官网下载依赖程序?",
|
||||
"Experimental function": "实验性功能",
|
||||
"Delay test after start": "启动后延迟测试",
|
||||
"Enable": "启用",
|
||||
"Detection interval(sec)": "检测间隔(秒)",
|
||||
"STUN Server": "STUN 服务器",
|
||||
"STUN Server Port": "STUN 服务器端口",
|
||||
"Custom ACL": "自定义 ACL 规则",
|
||||
"Language": "语言",
|
||||
|
||||
"Profile": "配置名",
|
||||
"Profiles": "配置",
|
||||
@@ -184,6 +178,9 @@
|
||||
|
||||
"Show": "显示",
|
||||
"Exit": "退出",
|
||||
"Unable to start? Click me to download": "无法启动?点我下载依赖",
|
||||
|
||||
"The {0} port is in use.": "{0} 端口已被占用",
|
||||
|
||||
"Bypass LAN": "[网页代理] 绕过局域网",
|
||||
"Bypass LAN (Non System Proxy)": "[网页代理] 绕过局域网(不设置系统代理)",
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
namespace Netch.Utils
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Diagnostics.Tracing.Parsers;
|
||||
using Microsoft.Diagnostics.Tracing.Session;
|
||||
using Netch.Controllers;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class Bandwidth
|
||||
{
|
||||
public static int received;
|
||||
|
||||
/// <summary>
|
||||
/// 计算流量
|
||||
/// </summary>
|
||||
/// <param name="bandwidth">流量</param>
|
||||
/// <returns>带单位的流量字符串</returns>
|
||||
public static string Compute(long bandwidth)
|
||||
/// 计算流量
|
||||
/// </summary>
|
||||
/// <param name="bandwidth">流量</param>
|
||||
/// <returns>带单位的流量字符串</returns>
|
||||
public static string Compute(long bandwidth)
|
||||
{
|
||||
string[] units = { "KB", "MB", "GB", "TB", "PB" };
|
||||
string[] units = {"KB", "MB", "GB", "TB", "PB"};
|
||||
double result = bandwidth;
|
||||
var i = -1;
|
||||
|
||||
@@ -18,7 +31,91 @@
|
||||
i++;
|
||||
} while ((result /= 1024) > 1024);
|
||||
|
||||
return string.Format("{0} {1}", System.Math.Round(result, 2), units[i]);
|
||||
if (result < 0)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return string.Format("{0} {1}", Math.Round(result, 2), units[i]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据程序名统计流量
|
||||
/// </summary>
|
||||
/// <param name="ProcessName"></param>
|
||||
public static void NetTraffic(Server server, Mode mode, MainController mainController)
|
||||
{
|
||||
var counterLock = new object();
|
||||
//int sent = 0;
|
||||
|
||||
//var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet();
|
||||
var instances = new List<Process>();
|
||||
if (server.Type.Equals("Socks5") && mainController.pModeController.Name == "HTTP")
|
||||
{
|
||||
instances.Add(((HTTPController) mainController.pModeController).pPrivoxyController.Instance);
|
||||
}
|
||||
else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL)
|
||||
{
|
||||
instances.Add(Process.GetCurrentProcess());
|
||||
}
|
||||
else if (mainController.pEncryptedProxyController != null)
|
||||
{
|
||||
instances.Add(mainController.pEncryptedProxyController.Instance);
|
||||
}
|
||||
else if (mainController.pModeController != null)
|
||||
{
|
||||
instances.Add(mainController.pModeController.Instance);
|
||||
}
|
||||
|
||||
var processList = instances.Select(instance => instance.Id).ToList();
|
||||
|
||||
Logging.Info("流量统计进程:" + string.Join(",", instances.Select(instance => $"({instance.Id})"+instance.ProcessName).ToArray()));
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
using (var session = new TraceEventSession("KernelAndClrEventsSession"))
|
||||
{
|
||||
session.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);
|
||||
|
||||
//这玩意儿上传和下载得到的data是一样的:)
|
||||
//所以暂时没办法区分上传下载流量
|
||||
session.Source.Kernel.TcpIpRecv += data =>
|
||||
{
|
||||
if (processList.Contains(data.ProcessID))
|
||||
{
|
||||
lock (counterLock)
|
||||
received += data.size;
|
||||
//Logging.Info($"TcpIpRecv: {Compute(data.size)}");
|
||||
}
|
||||
};
|
||||
session.Source.Kernel.UdpIpRecv += data =>
|
||||
{
|
||||
if (processList.Contains(data.ProcessID))
|
||||
{
|
||||
lock (counterLock)
|
||||
received += data.size;
|
||||
//Logging.Info($"UdpIpRecv: {Compute(data.size)}");
|
||||
}
|
||||
};
|
||||
|
||||
session.Source.Process();
|
||||
}
|
||||
});
|
||||
|
||||
if ((Convert.ToInt32(Global.MainForm.LastDownloadBandwidth) - Convert.ToInt32(received)) == 0)
|
||||
{
|
||||
Global.MainForm.OnBandwidthUpdated(0);
|
||||
received = 0;
|
||||
}
|
||||
|
||||
while (Global.MainForm.State != State.Stopped)
|
||||
{
|
||||
Task.Delay(1000).Wait();
|
||||
lock (counterLock)
|
||||
{
|
||||
Global.MainForm.OnBandwidthUpdated(Convert.ToInt64(received));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Netch.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
@@ -26,49 +28,50 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void Load()
|
||||
{
|
||||
if (Directory.Exists(DATA_DIR))
|
||||
if (Directory.Exists(DATA_DIR) && File.Exists(SETTINGS_JSON))
|
||||
{
|
||||
if (File.Exists(SETTINGS_JSON))
|
||||
try
|
||||
{
|
||||
try
|
||||
Global.Settings = JsonConvert.DeserializeObject<Setting>(File.ReadAllText(SETTINGS_JSON));
|
||||
if (Global.Settings.Server != null && Global.Settings.Server.Count > 0)
|
||||
{
|
||||
Global.Settings = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Setting>(File.ReadAllText(SETTINGS_JSON));
|
||||
if (Global.Settings.Server != null && Global.Settings.Server.Count > 0)
|
||||
// 如果是旧版 Server 类,使用旧版 Server 类进行读取
|
||||
if (Global.Settings.Server[0].Hostname == null)
|
||||
{
|
||||
// 如果是旧版 Server 类,使用旧版 Server 类进行读取
|
||||
if (Global.Settings.Server[0].Hostname == null)
|
||||
var LegacySettingConfig = JsonConvert.DeserializeObject<LegacySetting>(File.ReadAllText(SETTINGS_JSON));
|
||||
for (var i = 0; i < LegacySettingConfig.Server.Count; i++)
|
||||
{
|
||||
var LegacySettingConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.LegacySetting>(File.ReadAllText(SETTINGS_JSON));
|
||||
for (var i = 0; i < LegacySettingConfig.Server.Count; i++)
|
||||
Global.Settings.Server[i].Hostname = LegacySettingConfig.Server[i].Address;
|
||||
if (Global.Settings.Server[i].Type == "Shadowsocks")
|
||||
{
|
||||
Global.Settings.Server[i].Hostname = LegacySettingConfig.Server[i].Address;
|
||||
if (Global.Settings.Server[i].Type == "Shadowsocks")
|
||||
{
|
||||
Global.Settings.Server[i].Type = "SS";
|
||||
Global.Settings.Server[i].Plugin = LegacySettingConfig.Server[i].OBFS;
|
||||
Global.Settings.Server[i].PluginOption = LegacySettingConfig.Server[i].OBFSParam;
|
||||
}
|
||||
else if (Global.Settings.Server[i].Type == "ShadowsocksR")
|
||||
{
|
||||
Global.Settings.Server[i].Type = "SSR";
|
||||
}
|
||||
else if (Global.Settings.Server[i].Type == "VMess")
|
||||
{
|
||||
Global.Settings.Server[i].QUICSecure = LegacySettingConfig.Server[i].QUICSecurity;
|
||||
}
|
||||
Global.Settings.Server[i].Type = "SS";
|
||||
Global.Settings.Server[i].Plugin = LegacySettingConfig.Server[i].OBFS;
|
||||
Global.Settings.Server[i].PluginOption = LegacySettingConfig.Server[i].OBFSParam;
|
||||
}
|
||||
else if (Global.Settings.Server[i].Type == "ShadowsocksR")
|
||||
{
|
||||
Global.Settings.Server[i].Type = "SSR";
|
||||
}
|
||||
else if (Global.Settings.Server[i].Type == "VMess")
|
||||
{
|
||||
Global.Settings.Server[i].QUICSecure = LegacySettingConfig.Server[i].QUICSecurity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (Newtonsoft.Json.JsonException)
|
||||
{
|
||||
catch (JsonException)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 弹出提示
|
||||
i18N.Load("System");
|
||||
MessageBoxX.Show(i18N.Translate("If this is your first time using this software,\n please check https://netch.org to install supports first,\n or the program may report errors."));
|
||||
|
||||
// 创建 data 文件夹并保存默认设置
|
||||
Save();
|
||||
}
|
||||
@@ -84,115 +87,9 @@ namespace Netch.Utils
|
||||
{
|
||||
Directory.CreateDirectory(DATA_DIR);
|
||||
}
|
||||
File.WriteAllText(SETTINGS_JSON, Newtonsoft.Json.JsonConvert.SerializeObject(Global.Settings, Newtonsoft.Json.Formatting.Indented));
|
||||
File.WriteAllText(SETTINGS_JSON, JsonConvert.SerializeObject(Global.Settings, Formatting.Indented));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 搜索出口
|
||||
/// </summary>
|
||||
public static bool SearchOutbounds()
|
||||
{
|
||||
Logging.Info("正在搜索出口中");
|
||||
|
||||
if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0)
|
||||
{
|
||||
Global.Adapter.Index = pRoute.dwForwardIfIndex;
|
||||
Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop);
|
||||
Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Info("GetBestRoute 搜索失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info($"搜索适配器index:{Global.Adapter.Index}");
|
||||
var AddressGot = false;
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
try
|
||||
{
|
||||
var adapterProperties = adapter.GetIPProperties();
|
||||
var p = adapterProperties.GetIPv4Properties();
|
||||
Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}");
|
||||
|
||||
// 通过索引查找对应适配器的 IPv4 地址
|
||||
if (p.Index == Global.Adapter.Index)
|
||||
{
|
||||
var AdapterIPs = "";
|
||||
|
||||
foreach (var ip in adapterProperties.UnicastAddresses)
|
||||
{
|
||||
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
AddressGot = true;
|
||||
Global.Adapter.Address = ip.Address;
|
||||
Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}");
|
||||
break;
|
||||
}
|
||||
AdapterIPs = $"{ip.Address} | ";
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
if (AdapterIPs.Length > 3)
|
||||
{
|
||||
AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3);
|
||||
Logging.Info($"所有出口地址:{AdapterIPs}");
|
||||
}
|
||||
Logging.Info("出口无 IPv4 地址,当前只支持 IPv4 地址");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
|
||||
if (!AddressGot)
|
||||
{
|
||||
Logging.Info("无法找到当前使用适配器");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 搜索 TUN/TAP 适配器的索引
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
|
||||
{
|
||||
Logging.Info("未找到可用 TUN/TAP 适配器");
|
||||
if (MessageBox.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
|
||||
{
|
||||
addtap();
|
||||
//给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID
|
||||
Thread.Sleep(1000);
|
||||
Global.TUNTAP.ComponentID = TUNTAP.GetComponentID();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
// return false;
|
||||
}
|
||||
|
||||
foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
if (adapter.Id == Global.TUNTAP.ComponentID)
|
||||
{
|
||||
Global.TUNTAP.Adapter = adapter;
|
||||
Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index;
|
||||
|
||||
Logging.Info($"找到适配器:{adapter.Id}");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Info("无法找到出口");
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 安装tap网卡
|
||||
/// </summary>
|
||||
@@ -200,7 +97,7 @@ namespace Netch.Utils
|
||||
{
|
||||
Logging.Info("正在安装 TUN/TAP 适配器");
|
||||
//安装Tap Driver
|
||||
Process installProcess = new Process();
|
||||
var installProcess = new Process();
|
||||
installProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
installProcess.StartInfo.FileName = Path.Combine("bin/tap-driver", "addtap.bat");
|
||||
installProcess.Start();
|
||||
@@ -213,7 +110,7 @@ namespace Netch.Utils
|
||||
public static void deltapall()
|
||||
{
|
||||
Logging.Info("正在卸载 TUN/TAP 适配器");
|
||||
Process installProcess = new Process();
|
||||
var installProcess = new Process();
|
||||
installProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
installProcess.StartInfo.FileName = Path.Combine("bin/tap-driver", "deltapall.bat");
|
||||
installProcess.Start();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
@@ -45,5 +48,51 @@ namespace Netch.Utils
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置DNS
|
||||
/// </summary>
|
||||
/// <param name="dns"></param>
|
||||
public static void SetDNS(string[] dns)
|
||||
{
|
||||
ManagementClass wmi = new ManagementClass("Win32_NetworkAdapterConfiguration");
|
||||
ManagementObjectCollection moc = wmi.GetInstances();
|
||||
ManagementBaseObject inPar = null;
|
||||
ManagementBaseObject outPar = null;
|
||||
foreach (ManagementObject mo in moc)
|
||||
{
|
||||
//如果没有启用IP设置的网络设备则跳过,如果是虚拟机网卡也跳过
|
||||
if (!(bool)mo["IPEnabled"] ||
|
||||
mo["Description"].ToString().Contains("Virtual") ||
|
||||
mo["Description"].ToString().Contains("VMware") ||
|
||||
mo["Description"].ToString().Contains("TAP"))
|
||||
continue;
|
||||
|
||||
//设置DNS地址
|
||||
if (dns != null)
|
||||
{
|
||||
inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
|
||||
inPar["DNSServerSearchOrder"] = dns;
|
||||
outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 从网卡获取ip设置信息
|
||||
/// </summary>
|
||||
public static string[] getSystemDns()
|
||||
{
|
||||
var systemDns = new[] { "223.5.5.5", "1.1.1.1" };
|
||||
foreach (var network in NetworkInterface.GetAllNetworkInterfaces())
|
||||
if (!network.Description.Contains("Virtual") &&
|
||||
!network.Description.Contains("VMware") &&
|
||||
!network.Description.Contains("TAP") &&
|
||||
network.OperationalStatus == OperationalStatus.Up &&
|
||||
network.GetIPProperties()?.GatewayAddresses.Count != 0)
|
||||
{
|
||||
systemDns = network.GetIPProperties().DnsAddresses.Select(dns => dns.ToString()).ToArray();
|
||||
}
|
||||
|
||||
return systemDns;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
146
Netch/Utils/Firewall.cs
Normal file
146
Netch/Utils/Firewall.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NetFwTypeLib;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public class Firewall
|
||||
{
|
||||
private static readonly string[] ProgramPath =
|
||||
{
|
||||
"bin/NTT.exe",
|
||||
"bin/Privoxy.exe",
|
||||
"bin/Redirector.exe",
|
||||
"bin/Shadowsocks.exe",
|
||||
"bin/ShadowsocksR.exe",
|
||||
"bin/Trojan.exe",
|
||||
"bin/tun2socks.exe",
|
||||
"bin/unbound.exe",
|
||||
"bin/v2ray.exe",
|
||||
"Netch.exe"
|
||||
};
|
||||
|
||||
private const string Netch = "Netch";
|
||||
private const string NetchAutoRule = "NetchAutoRule";
|
||||
|
||||
/// <summary>
|
||||
/// 添加防火墙规则 (非 Netch 自带程序)
|
||||
/// </summary>
|
||||
/// <param name="exeFullPath"></param>
|
||||
public static void AddFwRule(string exeFullPath)
|
||||
{
|
||||
AddFwRule(NetchAutoRule, exeFullPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除防火墙规则 (非 Netch 自带程序)
|
||||
/// </summary>
|
||||
public static void RemoveFwRules()
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveFwRules(NetchAutoRule);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning("添加防火墙规则错误\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Netch 自带程序添加防火墙
|
||||
/// </summary>
|
||||
public static void AddNetchFwRules()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (GetFwRulePath(Netch).StartsWith(Global.NetchDir) && GetFwRulesNumber(Netch) >= ProgramPath.Length) return;
|
||||
RemoveNetchFwRules();
|
||||
foreach (var p in ProgramPath)
|
||||
{
|
||||
var path = Path.GetFullPath(p);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
AddFwRule("Netch", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning("添加防火墙规则错误(如已关闭防火墙则可无视此错误)\n" + e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除防火墙规则 (Netch 自带程序)
|
||||
/// </summary>
|
||||
private static void RemoveNetchFwRules()
|
||||
{
|
||||
try
|
||||
{
|
||||
RemoveFwRules(Netch);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Warning("清除防火墙规则错误\n" + e);
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
#region 封装
|
||||
|
||||
private static readonly INetFwPolicy2 FwPolicy = (INetFwPolicy2) Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
|
||||
|
||||
private static void AddFwRule(string ruleName, string exeFullPath)
|
||||
{
|
||||
var rule = NewFwRule();
|
||||
|
||||
rule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
|
||||
// ApplicationName 大小不敏感
|
||||
rule.ApplicationName = exeFullPath;
|
||||
// rule.Description = "";
|
||||
rule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
|
||||
rule.Enabled = true;
|
||||
rule.InterfaceTypes = "All";
|
||||
rule.Name = ruleName;
|
||||
|
||||
FwPolicy.Rules.Add(rule);
|
||||
}
|
||||
|
||||
private static void RemoveFwRules(string ruleName)
|
||||
{
|
||||
var c = GetFwRulesNumber(ruleName);
|
||||
foreach (var _ in new bool[c])
|
||||
{
|
||||
FwPolicy.Rules.Remove(ruleName);
|
||||
}
|
||||
}
|
||||
|
||||
private static INetFwRule NewFwRule()
|
||||
{
|
||||
return (INetFwRule) Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
|
||||
}
|
||||
|
||||
|
||||
private static string GetFwRulePath(string ruleName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var rule = (INetFwRule2) FwPolicy.Rules.Item(ruleName);
|
||||
return rule.ApplicationName;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetFwRulesNumber(string ruleName)
|
||||
{
|
||||
return FwPolicy.Rules.Cast<INetFwRule2>().Count(rule => rule.Name == ruleName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,7 @@ namespace Netch.Utils
|
||||
{
|
||||
public static class Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// 换行
|
||||
/// </summary>
|
||||
public static string EOF = "\r\n";
|
||||
private const string LogFile = "logging\\application.log";
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
@@ -16,7 +13,25 @@ namespace Netch.Utils
|
||||
/// <param name="text">内容</param>
|
||||
public static void Info(string text)
|
||||
{
|
||||
File.AppendAllText("logging\\application.log", string.Format("[{0}] {1}{2}", DateTime.Now, text, EOF));
|
||||
File.AppendAllText(LogFile, $@"[{DateTime.Now}][INFO] {text}{Global.EOF}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
public static void Warning(string text)
|
||||
{
|
||||
File.AppendAllText(LogFile, $@"[{DateTime.Now}][WARNING] {text}{Global.EOF}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
public static void Error(string text)
|
||||
{
|
||||
File.AppendAllText(LogFile, $@"[{DateTime.Now}][ERROR] {text}{Global.EOF}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Netch/Utils/MessageBoxX.cs
Normal file
24
Netch/Utils/MessageBoxX.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
class MessageBoxX
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
/// <param name="title">自定义标题</param>
|
||||
/// <param name="info">弹窗等级 (标题, 图标)</param>
|
||||
/// <param name="confirm">需要确认</param>
|
||||
/// <param name="owner">阻止 owner Focus() 直到 Messageox 被关闭</param>
|
||||
public static DialogResult Show(string text, string title = "", bool info = true, bool confirm = false,IWin32Window owner = null)
|
||||
{
|
||||
return MessageBox.Show(
|
||||
owner: owner,
|
||||
text: text,
|
||||
caption: i18N.Translate(string.IsNullOrWhiteSpace(title) ? (info ? "Information" : "Error") : title),
|
||||
buttons: confirm ? MessageBoxButtons.OKCancel : MessageBoxButtons.OK,
|
||||
icon: info ? MessageBoxIcon.Information : MessageBoxIcon.Exclamation);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Netch/Utils/PortHelper.cs
Normal file
34
Netch/Utils/PortHelper.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using Netch.Controllers;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class PortHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 指定类型的端口是否已经被使用了
|
||||
/// </summary>
|
||||
/// <param name="port">端口</param>
|
||||
/// <param name="type">检查端口类型</param>
|
||||
/// <returns>是否被占用</returns>
|
||||
public static bool PortInUse(int port, PortType type = PortType.Both)
|
||||
{
|
||||
var netInfo = IPGlobalProperties.GetIPGlobalProperties();
|
||||
var tcpResult = type != PortType.UDP && netInfo.GetActiveTcpListeners().Any(ipEndPoint => !MainController.UsingPorts.Contains(ipEndPoint.Port) && ipEndPoint.Port == port);
|
||||
var udpResult = type != PortType.TCP && netInfo.GetActiveUdpListeners().Any(ipEndPoint => !MainController.UsingPorts.Contains(ipEndPoint.Port) && ipEndPoint.Port == port);
|
||||
|
||||
return tcpResult || udpResult;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查端口类型
|
||||
/// </summary>
|
||||
public enum PortType
|
||||
{
|
||||
TCP,
|
||||
UDP,
|
||||
Both
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
using Netch.Models;
|
||||
using Netch.Models.SS;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Netch.Models;
|
||||
using Netch.Models.SS;
|
||||
using Netch.Models.SSD;
|
||||
using Newtonsoft.Json;
|
||||
using Server = Netch.Models.Server;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
@@ -36,9 +38,9 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
/// <param name="server">需要获取分享链接的服务器</param>
|
||||
/// <returns>解码后的字符串</returns>
|
||||
public static string GetShareLink(Models.Server server)
|
||||
public static string GetShareLink(Server server)
|
||||
{
|
||||
string retLinkStr = "";
|
||||
var retLinkStr = "";
|
||||
switch (server.Type)
|
||||
{
|
||||
case "Socks5":
|
||||
@@ -54,12 +56,12 @@ namespace Netch.Utils
|
||||
case "SSR":
|
||||
// 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)
|
||||
string paraStr = string.Format("/?obfsparam={0}&protoparam={1}&remarks={2}", URLSafeBase64Encode(server.OBFSParam), URLSafeBase64Encode(server.ProtocolParam), URLSafeBase64Encode(server.Remark));
|
||||
var paraStr = string.Format("/?obfsparam={0}&protoparam={1}&remarks={2}", URLSafeBase64Encode(server.OBFSParam), URLSafeBase64Encode(server.ProtocolParam), URLSafeBase64Encode(server.Remark));
|
||||
retLinkStr = "ssr://" + URLSafeBase64Encode(string.Format("{0}:{1}:{2}:{3}:{4}:{5}{6}", server.Hostname, server.Port, server.Protocol, server.EncryptMethod, server.OBFS, URLSafeBase64Encode(server.Password), paraStr));
|
||||
|
||||
break;
|
||||
case "VMess":
|
||||
string vmessJson = Newtonsoft.Json.JsonConvert.SerializeObject(new
|
||||
var vmessJson = JsonConvert.SerializeObject(new
|
||||
{
|
||||
v = "2",
|
||||
ps = server.Remark,
|
||||
@@ -121,7 +123,7 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
Logging.Error(e.ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -254,7 +256,7 @@ namespace Netch.Utils
|
||||
|
||||
if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod));
|
||||
Logging.Error($"不支持的 SS 加密方式:{data.EncryptMethod}");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -267,7 +269,7 @@ namespace Netch.Utils
|
||||
}
|
||||
else if (text.StartsWith("ssd://"))
|
||||
{
|
||||
var json = JsonConvert.DeserializeObject<Models.SSD.Main>(URLSafeBase64Decode(text.Substring(6)));
|
||||
var json = JsonConvert.DeserializeObject<Main>(URLSafeBase64Decode(text.Substring(6)));
|
||||
|
||||
foreach (var server in json.servers)
|
||||
{
|
||||
@@ -293,85 +295,6 @@ namespace Netch.Utils
|
||||
|
||||
list.Add(SsrServerFromLink(text));
|
||||
|
||||
/* var data = new Server();
|
||||
data.Type = "SSR";
|
||||
|
||||
text = text.Substring(6);
|
||||
|
||||
var parser = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$");
|
||||
var parser2 = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/$");
|
||||
var match = parser2.Match(URLSafeBase64Decode(text));
|
||||
if (!match.Success)
|
||||
{
|
||||
match = parser2.Match(UnBase64String(text));
|
||||
}
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
data.Hostname = match.Groups["server"].Value;
|
||||
data.Port = int.Parse(match.Groups["port"].Value);
|
||||
if (data.Port < 0)
|
||||
{
|
||||
data.Port += 65536;
|
||||
}
|
||||
data.Password = URLSafeBase64Decode(match.Groups["password"].Value);
|
||||
|
||||
data.EncryptMethod = match.Groups["method"].Value;
|
||||
if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod));
|
||||
return null;
|
||||
}
|
||||
|
||||
data.Protocol = match.Groups["protocol"].Value;
|
||||
if (!Global.Protocols.Contains(data.Protocol))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 SSR 协议:{0}", data.Protocol));
|
||||
return null;
|
||||
}
|
||||
|
||||
data.OBFS = match.Groups["obfs"].Value;
|
||||
if (data.OBFS == @"tls1.2_ticket_fastauth")
|
||||
{
|
||||
data.OBFS = @"tls1.2_ticket_auth";
|
||||
}
|
||||
if (!Global.OBFSs.Contains(data.OBFS))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 SSR 混淆:{0}", data.OBFS));
|
||||
return null;
|
||||
}
|
||||
|
||||
var info = match.Groups["info"].Value;
|
||||
var dict = new Dictionary<string, string>();
|
||||
foreach (var str in info.Split('&'))
|
||||
{
|
||||
var splited = str.Split('=');
|
||||
dict.Add(splited[0], splited[1]);
|
||||
}
|
||||
|
||||
if (dict.ContainsKey("remarks"))
|
||||
{
|
||||
data.Remark = URLSafeBase64Decode(dict["remarks"]);
|
||||
}
|
||||
|
||||
if (dict.ContainsKey("protoparam"))
|
||||
{
|
||||
data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]);
|
||||
}
|
||||
|
||||
if (dict.ContainsKey("obfsparam"))
|
||||
{
|
||||
data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]);
|
||||
}
|
||||
|
||||
if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain")
|
||||
{
|
||||
data.OBFS = "";
|
||||
data.Type = "SS";
|
||||
}
|
||||
list.Add(data);
|
||||
}*/
|
||||
|
||||
}
|
||||
else if (text.StartsWith("vmess://"))
|
||||
{
|
||||
@@ -390,14 +313,14 @@ namespace Netch.Utils
|
||||
data.TransferProtocol = vmess.net;
|
||||
if (!Global.TransferProtocols.Contains(data.TransferProtocol))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 VMess 传输协议:{0}", data.TransferProtocol));
|
||||
Logging.Error($"不支持的 VMess 传输协议:{data.TransferProtocol}");
|
||||
return null;
|
||||
}
|
||||
|
||||
data.FakeType = vmess.type;
|
||||
if (!Global.FakeTypes.Contains(data.FakeType))
|
||||
if (data.FakeType.Length != 0 && !Global.FakeTypes.Contains(data.FakeType))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 VMess 伪装类型:{0}", data.FakeType));
|
||||
Logging.Error($"不支持的 VMess 伪装类型:{data.FakeType}");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -414,7 +337,7 @@ namespace Netch.Utils
|
||||
{
|
||||
if (!Global.EncryptMethods.VMessQUIC.Contains(vmess.host))
|
||||
{
|
||||
Logging.Info(string.Format("不支持的 VMess QUIC 加密方式:{0}", vmess.host));
|
||||
Logging.Error($"不支持的 VMess QUIC 加密方式:{vmess.host}");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -470,43 +393,43 @@ namespace Netch.Utils
|
||||
case "SS":
|
||||
if (!Global.EncryptMethods.SS.Contains(NetchLink.EncryptMethod))
|
||||
{
|
||||
Logging.Info($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}");
|
||||
Logging.Error($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}");
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "SSR":
|
||||
if (!Global.EncryptMethods.SSR.Contains(NetchLink.EncryptMethod))
|
||||
{
|
||||
Logging.Info($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}");
|
||||
Logging.Error($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}");
|
||||
return null;
|
||||
}
|
||||
if (!Global.Protocols.Contains(NetchLink.Protocol))
|
||||
{
|
||||
Logging.Info($"不支持的 SSR 协议:{NetchLink.Protocol}");
|
||||
Logging.Error($"不支持的 SSR 协议:{NetchLink.Protocol}");
|
||||
return null;
|
||||
}
|
||||
if (!Global.OBFSs.Contains(NetchLink.OBFS))
|
||||
{
|
||||
Logging.Info($"不支持的 SSR 混淆:{NetchLink.OBFS}");
|
||||
Logging.Error($"不支持的 SSR 混淆:{NetchLink.OBFS}");
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "VMess":
|
||||
if (!Global.TransferProtocols.Contains(NetchLink.TransferProtocol))
|
||||
{
|
||||
Logging.Info($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}");
|
||||
Logging.Error($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}");
|
||||
return null;
|
||||
}
|
||||
if (!Global.FakeTypes.Contains(NetchLink.FakeType))
|
||||
{
|
||||
Logging.Info($"不支持的 VMess 伪装类型:{NetchLink.FakeType}");
|
||||
Logging.Error($"不支持的 VMess 伪装类型:{NetchLink.FakeType}");
|
||||
return null;
|
||||
}
|
||||
if (NetchLink.TransferProtocol == "quic")
|
||||
{
|
||||
if (!Global.EncryptMethods.VMessQUIC.Contains(NetchLink.QUICSecure))
|
||||
{
|
||||
Logging.Info($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}");
|
||||
Logging.Error($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -516,7 +439,7 @@ namespace Netch.Utils
|
||||
}
|
||||
list.Add(NetchLink);
|
||||
}
|
||||
else if(text.StartsWith("trojan://"))
|
||||
else if (text.StartsWith("trojan://"))
|
||||
{
|
||||
var data = new Server();
|
||||
data.Type = "Trojan";
|
||||
@@ -552,7 +475,7 @@ namespace Netch.Utils
|
||||
var match = finder.Match(text);
|
||||
if (!match.Success)
|
||||
{
|
||||
throw new FormatException();
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
data.Password = match.Groups["psk"].Value;
|
||||
@@ -569,10 +492,20 @@ namespace Netch.Utils
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
Logging.Error(e.ToString());
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] emoji_bytes = { 240, 159 };
|
||||
foreach (var node in list)
|
||||
{
|
||||
var remark = Encoding.UTF8.GetBytes(node.Remark);
|
||||
var start_index = 0;
|
||||
while (remark.Length > start_index + 1 && remark[start_index] == emoji_bytes[0] && remark[start_index + 1] == emoji_bytes[1])
|
||||
start_index += 4;
|
||||
node.Remark = Encoding.UTF8.GetString(remark.Skip(start_index).ToArray()).Trim();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
public static string UnBase64String(string value)
|
||||
@@ -581,7 +514,7 @@ namespace Netch.Utils
|
||||
{
|
||||
return "";
|
||||
}
|
||||
byte[] bytes = Convert.FromBase64String(value);
|
||||
var bytes = Convert.FromBase64String(value);
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
public static string ToBase64String(string value)
|
||||
@@ -590,7 +523,7 @@ namespace Netch.Utils
|
||||
{
|
||||
return "";
|
||||
}
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
||||
var bytes = Encoding.UTF8.GetBytes(value);
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
|
||||
@@ -663,7 +596,7 @@ namespace Netch.Utils
|
||||
{
|
||||
Server_Udp_Port = ushort.Parse(params_dict["udpport"]);
|
||||
}*/
|
||||
Server server = new Server();
|
||||
var server = new Server();
|
||||
server.Type = "SSR";
|
||||
server.Hostname = serverAddr;
|
||||
server.Port = Server_Port;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using MaxMind.GeoIP2;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
@@ -64,5 +65,41 @@ namespace Netch.Utils
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public static string GetCityCode(string Hostname)
|
||||
{
|
||||
if (Hostname.Contains(":"))
|
||||
{
|
||||
Hostname = Hostname.Split(':')[0];
|
||||
}
|
||||
string Country;
|
||||
try
|
||||
{
|
||||
var databaseReader = new DatabaseReader("bin\\GeoLite2-Country.mmdb");
|
||||
|
||||
if (IPAddress.TryParse(Hostname, out _) == true)
|
||||
{
|
||||
Country = databaseReader.Country(Hostname).Country.IsoCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
var DnsResult = DNS.Lookup(Hostname);
|
||||
|
||||
if (DnsResult != null)
|
||||
{
|
||||
Country = databaseReader.Country(DnsResult).Country.IsoCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
Country = "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Country = "Unknown";
|
||||
}
|
||||
return Country == null ? "Unknown" : Country;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,64 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Netch.Properties;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Netch.Utils
|
||||
{
|
||||
public static class i18N
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public static Hashtable Data = new Hashtable();
|
||||
|
||||
public static string LangCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加载
|
||||
/// </summary>
|
||||
/// <param name="text">语言文件</param>
|
||||
public static void Load(string text)
|
||||
/// <param name="langCode">语言代码</param>
|
||||
public static void Load(string langCode)
|
||||
{
|
||||
var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
|
||||
LangCode = langCode;
|
||||
|
||||
if (data != null)
|
||||
var text = "";
|
||||
if (langCode.Equals("System"))
|
||||
{
|
||||
Data = new Hashtable();
|
||||
foreach (var v in data)
|
||||
{
|
||||
Data.Add(v.Key, v.Value);
|
||||
}
|
||||
// 加载系统语言
|
||||
langCode = CultureInfo.CurrentCulture.Name;
|
||||
}
|
||||
|
||||
if (langCode == "zh-CN")
|
||||
{
|
||||
// 尝试加载内置中文语言
|
||||
text = Encoding.UTF8.GetString(Resources.zh_CN);
|
||||
}
|
||||
else if (langCode.Equals("en-US"))
|
||||
{
|
||||
// 清除得到英文
|
||||
Data.Clear();
|
||||
return;
|
||||
}
|
||||
else if (File.Exists($"i18n\\{langCode}"))
|
||||
{
|
||||
// 从外置文件中加载语言
|
||||
text = File.ReadAllText($"i18n\\{langCode}");
|
||||
}
|
||||
|
||||
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
|
||||
|
||||
if (data == null) return;
|
||||
|
||||
Data = new Hashtable();
|
||||
foreach (var v in data)
|
||||
{
|
||||
Data.Add(v.Key, v.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,14 +67,37 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
/// <param name="text">需要翻译的文本</param>
|
||||
/// <returns>翻译完毕的文本</returns>
|
||||
public static string Translate(string text)
|
||||
public static string Translate(params object[] text)
|
||||
{
|
||||
if (Data.Contains(text))
|
||||
var a = new StringBuilder();
|
||||
foreach (var t in text)
|
||||
if (t is string)
|
||||
a.Append(Data.Contains(t) ? Data[t].ToString() : t);
|
||||
else
|
||||
a.Append(t);
|
||||
return a.ToString();
|
||||
}
|
||||
|
||||
public static string TranslateFormat(string format, params object[] args)
|
||||
{
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
return Data[text].ToString();
|
||||
if (args[i] is string)
|
||||
{
|
||||
args[i] = Translate((string) args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
return string.Format(Translate(format), args);
|
||||
}
|
||||
|
||||
public static List<string> GetTranslateList()
|
||||
{
|
||||
var translateFile = new List<string> {"System", "zh-CN", "en-US"};
|
||||
|
||||
if (!Directory.Exists("i18n")) return translateFile;
|
||||
translateFile.AddRange(Directory.GetFiles("i18n", "*").Select(fileName => fileName.Substring(5)));
|
||||
return translateFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,7 +281,7 @@ namespace Netch
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
// ignored
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -82,69 +82,76 @@ namespace System.Windows.Forms
|
||||
private object[] newList;
|
||||
private void ReevaluateCompletionList()
|
||||
{
|
||||
var currentSearchTerm = Text.ToLowerInvariant();
|
||||
if (currentSearchTerm == _previousSearchTerm) return;
|
||||
|
||||
_previousSearchTerm = currentSearchTerm;
|
||||
try
|
||||
{
|
||||
SuspendLayout();
|
||||
|
||||
var originalList = (object[])Tag;
|
||||
if (originalList == null)
|
||||
{
|
||||
Tag = originalList = Items.Cast<object>().ToArray();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(currentSearchTerm))
|
||||
{
|
||||
if (Items.Count == originalList.Length) return;
|
||||
|
||||
newList = originalList;
|
||||
}
|
||||
else
|
||||
{
|
||||
newList = originalList.Where(x => x.ToString().ToLowerInvariant().Contains(currentSearchTerm)).ToArray();
|
||||
}
|
||||
var currentSearchTerm = Text.ToLowerInvariant();
|
||||
if (currentSearchTerm == _previousSearchTerm) return;
|
||||
|
||||
_previousSearchTerm = currentSearchTerm;
|
||||
try
|
||||
{
|
||||
while (Items.Count > 0)
|
||||
SuspendLayout();
|
||||
|
||||
var originalList = (object[])Tag;
|
||||
if (originalList == null)
|
||||
{
|
||||
Items.RemoveAt(0);
|
||||
Tag = originalList = Items.Cast<object>().ToArray();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(currentSearchTerm))
|
||||
{
|
||||
if (Items.Count == originalList.Length) return;
|
||||
|
||||
newList = originalList;
|
||||
}
|
||||
else
|
||||
{
|
||||
newList = originalList.Where(x => x.ToString().ToLowerInvariant().Contains(currentSearchTerm)).ToArray();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Items.Clear();
|
||||
while (Items.Count > 0)
|
||||
{
|
||||
Items.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
try
|
||||
{
|
||||
Items.Clear();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Items.AddRange(newList.ToArray());
|
||||
Items.AddRange(newList.ToArray());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (currentSearchTerm.Length >= 2 && !DroppedDown)
|
||||
{
|
||||
DroppedDown = true;
|
||||
Cursor.Current = Cursors.Default;
|
||||
Text = currentSearchTerm;
|
||||
Select(currentSearchTerm.Length, 0);
|
||||
}
|
||||
|
||||
if (Items.Count > 0)
|
||||
{
|
||||
DroppedDown = false;
|
||||
DroppedDown = true;
|
||||
}
|
||||
|
||||
ResumeLayout(true);
|
||||
}
|
||||
}
|
||||
finally
|
||||
catch
|
||||
{
|
||||
if (currentSearchTerm.Length >= 2 && !DroppedDown)
|
||||
{
|
||||
DroppedDown = true;
|
||||
Cursor.Current = Cursors.Default;
|
||||
Text = currentSearchTerm;
|
||||
Select(currentSearchTerm.Length, 0);
|
||||
}
|
||||
|
||||
if (Items.Count > 0)
|
||||
{
|
||||
DroppedDown = false;
|
||||
DroppedDown = true;
|
||||
}
|
||||
|
||||
ResumeLayout(true);
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
README.md
18
README.md
@@ -1,12 +1,18 @@
|
||||
# Netch
|
||||
[](https://t.me/Netch) [](https://t.me/Netch_Discuss_Group) 
|
||||
|
||||
[](https://github.com/NetchX/Netch)
|
||||
[](https://github.com/NetchX/Netch/releases)
|
||||
[](https://github.com/NetchX/Netch/releases)
|
||||
[](https://github.com/NetchX/Netch/actions)
|
||||
[](LICENSE)
|
||||
[](https://t.me/Netch) [](https://t.me/Netch_Discuss_Group)
|
||||
[](https://netch.org/)
|
||||
|
||||
[中文说明](/docs/README.zh-CN.md)
|
||||
|
||||
[FAQ/常见问题](https://netch.org/#/docs/zh-CN/faq)
|
||||
|
||||
Game accelerator
|
||||
|
||||
[简体中文](docs/README.zh-CN.md) (此版本内容更丰富)
|
||||
|
||||
[Website](https://netch.org/)
|
||||
|
||||
## TOC
|
||||
- [Netch](#netch)
|
||||
- [TOC](#toc)
|
||||
|
||||
2
binaries
2
binaries
Submodule binaries updated: 54d5fcd465...2adb17a398
221
docs/Advanced_Usage.zh-CN.md
Normal file
221
docs/Advanced_Usage.zh-CN.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# Netch 模式
|
||||
|
||||
用于存储 Netch 模式文件的仓库
|
||||
|
||||
|
||||
|
||||
## 目录
|
||||
|
||||
1. [模式介绍](#模式介绍)
|
||||
- 1.1 [模式 1 进程代理模式](#模式-1-进程代理模式)
|
||||
- 1.2 [模式 2(需要自己新建模式文件) TUN/TAP IP 黑名单代理模式](#模式-2需要自己新建模式文件-tuntap-ip-黑名单代理模式)
|
||||
- 1.3 [模式 3 TUN/TAP (IP 白名单)全局代理模式](#模式-3-tuntap-ip-白名单全局代理模式)
|
||||
- 1.4 [模式 4 HTTP 系统代理](#模式-4-http-系统代理)
|
||||
- 1.5 [模式 5 本地 Socks5 代理](#模式-5-本地-socks5-代理)
|
||||
- 1.6 [模式 6 本地 Socks5 和 HTTP 代理](#模式-6-本地-socks5-和-http-代理)
|
||||
2. [Socks 5 代理中转](#socks-5-代理中转)
|
||||
3. [新建进程代理模式](#新建进程代理模式)
|
||||
- 3.1 [模式](#模式)
|
||||
- 3.2 [扫描](#扫描)
|
||||
- 3.3 [启动](#启动)
|
||||
|
||||
## 模式介绍
|
||||
|
||||
目前 Netch 所有模式文件都在 `mode` 文件夹下。模式号即模式菜单中最左边中括号内数字
|
||||
|
||||
内置的模式中,如果模式名中有 Bypass China 的部分,即该模式会绕过中国 IP 段
|
||||
|
||||
模式 1 和模式 2 里面除了第一行格式不同,其他内容和 [SSTap-Rule](https://github.com/FQrabbit/SSTap-Rule) 相同。是否绕过中国的功能依赖于 [CNIP 文件](https://github.com/NetchX/Netch/blob/master/Netch/Resources/CNIP)
|
||||
|
||||
模式 3 到模式 5 的是否绕过中国的功能依赖于 [acl 文件](https://github.com/NetchX/Netch/blob/master/binaries/default.acl)
|
||||
|
||||
第一行格式均为如下样式,不同模式之间第一行的具体区别可以参照后面的内容
|
||||
|
||||
```Python
|
||||
# 备注, 类型(是主项目 USAGE.zh-CN.md 里提到的模式类型的值减一), 是否绕过中国(1 为是, 0 为否)
|
||||
```
|
||||
|
||||
### 模式 1 进程代理模式
|
||||
|
||||
- 根据进程名进行代理
|
||||
- 底层依赖于 [NetFilter SDK](https://netfiltersdk.com) 和 Redirector.exe(未开源)等
|
||||
- 对于第一次使用 Netch 的用户而言,不需要做多余的事情
|
||||
- 若 [NetFilter SDK](https://netfiltersdk.com) 的驱动不存在,会自动安装
|
||||
- 自动安装驱动时不会判断旧驱动是否需要更新
|
||||
- 对于老用户而言,版本更新日志里如果提到要更新驱动,或者你发现无法使用本模式时,可以通过运行 `DriverUpdater.exe` 的方式强制覆盖旧驱动
|
||||
- 相关代码 [NFController.cs](..\Netch\Controllers\NFController.cs)
|
||||
|
||||
范例文件
|
||||
|
||||
在这个模式里,第一行只有备注是有用的
|
||||
|
||||
```
|
||||
# 备注
|
||||
进程名 1(会被代理)
|
||||
进程名 2
|
||||
...
|
||||
```
|
||||
|
||||
### 模式 2(需要自己新建模式文件) TUN/TAP IP 黑名单代理模式
|
||||
|
||||
- 黑名单代理指的是,除了名单内的 IP 走代理,其他连接都不走代理
|
||||
- 需要自己新建模式文件,第一行写法同模式 3,只是需要把 2 改成 1
|
||||
- 后续内容的格式同 [SSTap-rules](https://github.com/FQrabbit/SSTap-Rule),任何规则问题建议到那边去提
|
||||
- 可以通过左下角的`设置`来配置 IP 地址,子网掩码,网关,DNS
|
||||
- 该模式下直连 IP 段无效,暂时没有代码实现
|
||||
- 底层依赖于 [Tap-Windows](https://github.com/OpenVPN/tap-windows) 适配器等
|
||||
- 如果 Netch 提示没有该适配器,可以直接安装 [Tap-Windows](https://build.openvpn.net/downloads/releases/latest/tap-windows-latest-stable.exe) 或者通过安装 [OpenVPN](https://openvpn.net/community-downloads/),[SSTap](https://github.com/mayunbaba2/SSTap-beta-setup) 的方式获得该适配器
|
||||
|
||||
范例文件
|
||||
|
||||
在这个模式里,是否绕过中国的值是无效的
|
||||
|
||||
```
|
||||
# 备注, 1
|
||||
无类别域间路由写法 1(目的 IP 在这个子网内的网络请求都会被代理)
|
||||
无类别域间路由写法 2
|
||||
...
|
||||
```
|
||||
|
||||
### 模式 3 TUN/TAP (IP 白名单)全局代理模式
|
||||
|
||||
- 白名单代理指的是,除了名单内的 IP 不走代理,其他连接都走代理
|
||||
- 可以通过左下角的`设置`来配置 IP 地址,子网掩码,网关,DNS,直连 IP 段
|
||||
- 底层依赖于 [Tap-Windows](https://github.com/OpenVPN/tap-windows) 适配器,tun2socks 等
|
||||
- 如果 Netch 提示没有该适配器,可以直接安装 [Tap-Windows](https://build.openvpn.net/downloads/releases/latest/tap-windows-latest-stable.exe) 或者通过安装 [OpenVPN](https://openvpn.net/community-downloads/),[SSTap](https://github.com/mayunbaba2/SSTap-beta-setup) 的方式获得该适配器
|
||||
|
||||
范例文件
|
||||
|
||||
```
|
||||
# 备注, 2, 是否绕过中国(1 为是, 0 为否)
|
||||
无类别域间路由写法 1(目的 IP 只有在这个子网内的网络请求不会被代理,其他的都会被代理)
|
||||
无类别域间路由写法 2
|
||||
...
|
||||
```
|
||||
|
||||
### 模式 4 HTTP 系统代理
|
||||
|
||||
- 默认地址和端口为 127.0.0.1:2802
|
||||
- 端口可以在左下角设置里面更改
|
||||
- 会被设置为系统代理
|
||||
|
||||
范例文件
|
||||
|
||||
```
|
||||
# 备注, 3, 是否绕过中国(1 为是, 0 为否)
|
||||
(目前只有第一行是有效的)
|
||||
```
|
||||
|
||||
### 模式 5 本地 Socks5 代理
|
||||
|
||||
- 默认地址和端口为 127.0.0.1:2801
|
||||
- 端口可以在左下角设置里面更改
|
||||
- 不会被设置为系统代理,对于 Chrome 之类使用系统代理的浏览器需要设置使用插件 SwitchyOmega 之后才能被正常代理
|
||||
- 注意如果是使用 Firefox 的网络设置,请仅设置 Socks5 代理,清除其他代理配置,并取消勾选`为所有协议使用相同的代理服务器`
|
||||
- 其他模式均含 Socks5 代理,本模式可以理解为仅 Socks5 代理\
|
||||
|
||||
范例文件
|
||||
|
||||
```
|
||||
# 备注, 4, 是否绕过中国(1 为是, 0 为否)
|
||||
(目前只有第一行是有效的)
|
||||
```
|
||||
|
||||
### 模式 6 本地 Socks5 和 HTTP 代理
|
||||
|
||||
- Socks5 代理的默认地址和端口为 127.0.0.1:2801
|
||||
- HTTP 代理的默认地址和端口为 127.0.0.1:2802
|
||||
- 端口可以在左下角设置里面更改
|
||||
- 不会被设置为系统代理
|
||||
|
||||
范例文件
|
||||
|
||||
```
|
||||
# 备注, 5, 是否绕过中国(1 为是, 0 为否)
|
||||
(目前只有第一行是有效的)
|
||||
```
|
||||
|
||||
## Socks 5 代理中转
|
||||
|
||||
说明一下,Netch 并非是以网页代理为目的开发的程序,如果需要网络代理为目的的程序,需要 PAC,规则分流,订阅管理等功能的,请参考使用以下软件而非 Netch(均为 Windows 平台)
|
||||
|
||||
ShadowsocksR
|
||||
|
||||
- [HMBSbige/ShadowsocksR-Windows](https://github.com/HMBSbige/ShadowsocksR-Windows/releases)
|
||||
|
||||
Shadowsocks
|
||||
|
||||
- [Clash for Windows](https://github.com/Fndroid/clash_for_windows_pkg/releases)
|
||||
|
||||
V2Ray
|
||||
|
||||
- [V2RayN](https://github.com/2dust/v2rayN/releases)
|
||||
|
||||
如果你想使用的代理工具目前 Netch 还不支持,或者需要一些 Netch 目前没有的功能,如 V2Ray 自定义配置,Socks5 本地代理规则分流的,可以在 Netch 里添加对应工具的本地 Socks5 代理端口后使用,注意如果你用的是模式 3 TUN/TAP (IP 白名单)全局代理模式,记得在`设置 - 全局直连 IP`中添加你的服务器 IP 地址,否则会产生代理回环
|
||||
|
||||
## 新建进程代理模式
|
||||
|
||||
- 现在软件还处在早期开发阶段,可能后续版本会发生很大变化,操作仅供参考
|
||||
|
||||
当前版本已添加配置编辑功能,根据自己的情况,使用订阅或者别的方法添加代理配置,我这里使用的是剪贴板导入
|
||||
|
||||

|
||||
|
||||
如果你发现你的程序没我截图的看起来清晰,可以右键 `Netch.exe - 属性 - 兼容性 - 更改高 DPI 设置 - 替代高 DPI 缩放执行 - 系统(增强)`
|
||||
|
||||
### 模式
|
||||
|
||||
如果你的游戏的模式已经被收录,也可以考虑在模式菜单中,选择使用已收录的模式。所有模式的文件,都在 `./mode/` 文件夹下,如果你需要多个模式的合并文件,可以使用记事本将其打开,将多个文件合并
|
||||
|
||||
ping 的值未必准确,因为这只是你本地到代理服务器而非游戏服务器的延迟
|
||||
|
||||
如果你的游戏的模式没被收录,可以看接下来的扫描步骤来手动创建模式
|
||||
|
||||
接着点击菜单栏上的`模式 - 创建进程模式`
|
||||
|
||||

|
||||
|
||||
### 扫描
|
||||
|
||||
在弹出的窗口中点击`扫描`
|
||||
|
||||

|
||||
|
||||
选择你要加速的游戏的安装路径,根据游戏不同,可能需要选择多个不同的目录进行扫描,参见[萌鹰的 Netch 教程](https://www.eaglemoe.com/archives/142)(包括 GTAOL 和 R6S 的配置方法)
|
||||
|
||||
>4. 选定 GTA5 游戏目录,点击确定,软件会自动扫描目录下的 exe 程式并填写进去
|
||||
>5. 再次点击扫描,选择 SocialClub 的安装地址(一般为 C:\Program Files\Rockstar Games\Social Club),点击确定,点击保存
|
||||
>
|
||||
>注意:加入游戏时请不要忘记加入社交组件,比如说 GTA 不要忘记 SocialClub ,彩虹六号不要忘记 Uplay
|
||||
|
||||
这里以战争雷霆为例,只需添加战争雷霆游戏根目录即可
|
||||
|
||||

|
||||
|
||||
扫描时可能需要稍等片刻,扫描后记得填写备注
|
||||
|
||||
如果需要添加单个程序,也可以在添加按钮左侧的编辑栏中手动输入并添加
|
||||
|
||||
之后点保存进行`保存`
|
||||
|
||||

|
||||
|
||||
### 启动
|
||||
|
||||
最后确认服务器一栏和模式一栏均为之前自己添加并需要使用的,没问题后点击`启动`即可
|
||||
|
||||

|
||||
|
||||
启动后,你再去游戏根目录或者别的启动器如 Steam,Uplay 启动游戏即可。此时游戏就已经被代理了
|
||||
|
||||
如果在 Netch 启动前就启动了游戏,建议重启游戏
|
||||
|
||||
如果需要 Steam,Uplay 等启动器也被代理,参照前面的方式对 Steam,Uplay 根目录也进行扫描即可
|
||||
|
||||
如果出现了启动失败,或者无法代理成功的情况,请先尝试`选项 - 重启服务`或`选项 - 卸载服务`,或者在退出 Netch 以后,点击运行在 Netch 根目录下的 `DriverUpdater.exe` 程序进行驱动更新
|
||||
|
||||
|
||||
|
||||
## 语言支持
|
||||
|
||||
Netch 支持多种语言,在启动时会根据系统语言选择自身语言。如果需要手动切换语言,可以在启动时加入命令行参数,命令行参数为目前支持的语言代码,可以去 [NetchTranslation/i18n](https://github.com/NetchX/NetchTranslation/tree/master/i18n) 文件夹下查看外部支持的语言代码文件。Netch 目前内置 en-US,zh-CN,外置 zh-TW。欢迎大家为 [NetchTranslation](https://github.com/NetchX/NetchTranslation) 提供其他语言的翻译
|
||||
@@ -1,5 +1,5 @@
|
||||
# 新手入门
|
||||
**Version : 1.3.7**
|
||||
**Version : 1.4.10**
|
||||
|
||||
[下载地址](https://github.com/NetchX/Netch/releases)
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
|
||||
## 添加服务器
|
||||
|
||||
> Netch 目前仅支持以下代理协议:Shadowsocks,VMess,Socks5,ShadowsockR。
|
||||
> Netch 目前仅支持以下代理协议:Shadowsocks,VMess,Socks5,ShadowsockR,Trojan。
|
||||
|
||||
首先,点击`服务器`增加所需服务器
|
||||
|
||||
<img width="50%" height="50%" src="screenshots/Add-server.png">
|
||||
<img width="50%" height="50%" src="screenshots/addServer.zh-CN.png">
|
||||
|
||||
可手动添加单个服务器,或者通过剪切板链接添加单个服务器。也可通过订阅链接批量添加。
|
||||
|
||||
点击 `订阅` ` 管理订阅链接` 进入以下界面。
|
||||
|
||||
<img width="50%" height="50%" src="screenshots/Add-link.jpg">
|
||||
<img width="50%" height="50%" src="screenshots/addLink.zh-CN.png">
|
||||
|
||||
填写备注与链接,点击添加,然后保存。保存后点击 `订阅` ` 从订阅链接更新服务器`。完成服务器添加。添加完服务器后可对服务器进行修改,删除和测速。
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
- [简介](#简介)
|
||||
- [捐赠](#捐赠)
|
||||
- [新手入门](Quickstart.zh-CN.md)
|
||||
- [进阶用法](https://github.com/NormanBB/NetchMode/blob/master/docs/README.zh-CN.md)
|
||||
- [进阶用法](Advanced_Usage.zh-CN.md)
|
||||
- [依赖](#依赖)
|
||||
- [语言支持](#语言支持)
|
||||
|
||||
@@ -20,14 +20,17 @@ Netch 是一款 Windows 平台的开源游戏加速工具,Netch 可以实现
|
||||
|
||||
与此同时 Netch 避免了 SSTap 的 NAT 问题 ,检查 NAT 类型即可知道是否有 NAT 问题。使用 SSTap 加速部分 P2P 联机,对 NAT 类型有要求的游戏时,可能会因为 NAT 类型严格遇到无法加入联机,或者其他影响游戏体验的情况
|
||||
|
||||
|
||||
需要更多特性请移步魔改仓库 [Netch-ForOwnUse](https://github.com/AmazingDM/Netch-ForOwnUse),
|
||||
|
||||
## 捐赠
|
||||
- XMR *48ju3ELNZEa6wwPBMexCJ9G218BGY2XwhH6B6bmkFuJ3QgM4hPw2Pra35jPtuBZSc7SLNWeBpiWJZWjQeMAiLnTx2tH2Efx*
|
||||
|
||||
## 新手入门
|
||||
[新手入门教程](Basic-usage.md)
|
||||
[新手入门教程](Quickstart.zh-CN.md)
|
||||
|
||||
## 进阶用法
|
||||
[进阶教程](https://github.com/NormanBB/NetchMode/blob/master/docs/README.zh-CN.md)
|
||||
[进阶教程](Advanced_Usage.zh-CN.md)
|
||||
## 依赖
|
||||
- [Visual C++ 运行库合集](https://www.google.com/search?q=Visual+C%2B%2B+%E8%BF%90%E8%A1%8C%E5%BA%93%E5%90%88%E9%9B%86)
|
||||
- [.NET Framework 4.8](https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net48-offline-installer)
|
||||
|
||||
2
modes
2
modes
Submodule modes updated: 20884a02f7...f0327e9399
Submodule translations updated: db0c5ae291...06e77dc2b1
Reference in New Issue
Block a user