mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
细节修缮
This commit is contained in:
@@ -8,7 +8,7 @@ namespace Netch.Controllers
|
|||||||
{
|
{
|
||||||
public DNSController()
|
public DNSController()
|
||||||
{
|
{
|
||||||
AkaName = "dns Service";
|
Name = "dns Service";
|
||||||
MainFile = "unbound";
|
MainFile = "unbound";
|
||||||
ExtFiles = new[] {"unbound-service.conf", "forward-zone.conf"};
|
ExtFiles = new[] {"unbound-service.conf", "forward-zone.conf"};
|
||||||
InitCheck();
|
InitCheck();
|
||||||
@@ -44,7 +44,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
WriteLog(e);
|
Write(e.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop()
|
public override void Stop()
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!WriteLog(e)) return;
|
if (!Write(e.Data)) return;
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
{
|
{
|
||||||
if (Instance.HasExited)
|
if (Instance.HasExited)
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ namespace Netch.Controllers
|
|||||||
if (!Ready) return false;
|
if (!Ready) return false;
|
||||||
|
|
||||||
Instance = GetProcess("bin\\ShadowsocksR.exe");
|
Instance = GetProcess("bin\\ShadowsocksR.exe");
|
||||||
Instance.StartInfo.FileName = "bin\\ShadowsocksR.exe";
|
|
||||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||||
|
|
||||||
@@ -69,7 +68,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!WriteLog(e)) return;
|
if (!Write(e.Data)) return;
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
{
|
{
|
||||||
if (Instance.HasExited)
|
if (Instance.HasExited)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!WriteLog(e)) return;
|
if (!Write(e.Data)) return;
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
{
|
{
|
||||||
if (Instance.HasExited)
|
if (Instance.HasExited)
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!WriteLog(e)) return;
|
if (!Write(e.Data)) return;
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
{
|
{
|
||||||
if (Instance.HasExited)
|
if (Instance.HasExited)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Netch.Controllers
|
|||||||
/// <param />
|
/// <param />
|
||||||
/// 未赋值会在 <see cref="InitCheck" /> 赋值为 <see cref="MainFile" />
|
/// 未赋值会在 <see cref="InitCheck" /> 赋值为 <see cref="MainFile" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AkaName;
|
public string Name;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 其他需要文件
|
/// 其他需要文件
|
||||||
@@ -66,7 +66,7 @@ namespace Netch.Controllers
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected void InitCheck()
|
protected void InitCheck()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(AkaName)) AkaName = MainFile;
|
if (string.IsNullOrEmpty(Name)) Name = MainFile;
|
||||||
|
|
||||||
var result = false;
|
var result = false;
|
||||||
// 杀残留
|
// 杀残留
|
||||||
@@ -74,7 +74,7 @@ namespace Netch.Controllers
|
|||||||
// 清日志
|
// 清日志
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (File.Exists($"logging\\{AkaName}.log")) File.Delete($"logging\\{AkaName}.log");
|
if (File.Exists($"logging\\{Name}.log")) File.Delete($"logging\\{Name}.log");
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@@ -90,38 +90,37 @@ namespace Netch.Controllers
|
|||||||
Logging.Error($"主程序 bin\\{MainFile}.exe 不存在");
|
Logging.Error($"主程序 bin\\{MainFile}.exe 不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExtFiles == null)
|
if (ExtFiles != null)
|
||||||
extResult = true;
|
{
|
||||||
else
|
foreach (var file in ExtFiles)
|
||||||
foreach (var f in ExtFiles)
|
if (!File.Exists($"bin\\{file}"))
|
||||||
if (!File.Exists($"bin\\{f}"))
|
|
||||||
{
|
{
|
||||||
extResult = false;
|
extResult = false;
|
||||||
Logging.Error($"附加文件 bin\\{f} 不存在");
|
Logging.Error($"附加文件 bin\\{file} 不存在");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = extResult && mainResult;
|
result = extResult && mainResult;
|
||||||
if (!result)
|
if (!result)
|
||||||
Logging.Error(AkaName + " 未就绪");
|
Logging.Error(Name + " 未就绪");
|
||||||
Ready = result;
|
Ready = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 写日志
|
/// 写日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="std"></param>
|
/// <param name="s"></param>
|
||||||
/// <returns><see cref="std" />是否为空</returns>
|
/// <returns><see cref="s" />是否为空</returns>
|
||||||
protected bool WriteLog(DataReceivedEventArgs std)
|
protected bool Write(string s)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(std.Data)) return false;
|
if (string.IsNullOrWhiteSpace(s)) return false;
|
||||||
try
|
try
|
||||||
|
|
||||||
{
|
{
|
||||||
File.AppendAllText($"logging\\{AkaName}.log", $@"{std.Data}{Global.EOF}");
|
File.AppendAllText($"logging\\{Name}.log", s + Global.EOF);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logging.Error($"写入{AkaName}日志错误:\n" + e);
|
Logging.Error($"写入{Name}日志错误:\n" + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace Netch.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// NTT 控制器
|
/// NTT 控制器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NTTController pNTTController;
|
public NTTController pNTTController = new NTTController();
|
||||||
|
|
||||||
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
|
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
|
||||||
public static extern uint FlushDNSResolverCache();
|
public static extern uint FlushDNSResolverCache();
|
||||||
@@ -31,7 +31,6 @@ namespace Netch.Controllers
|
|||||||
/// <returns>是否启动成功</returns>
|
/// <returns>是否启动成功</returns>
|
||||||
public bool Start(Server server, Mode mode)
|
public bool Start(Server server, Mode mode)
|
||||||
{
|
{
|
||||||
pNTTController ??= new NTTController();
|
|
||||||
FlushDNSResolverCache();
|
FlushDNSResolverCache();
|
||||||
|
|
||||||
var result = false;
|
var result = false;
|
||||||
@@ -57,12 +56,13 @@ namespace Netch.Controllers
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainForm.Instance.StatusText(i18N.Translate("Starting ", pEncryptedProxyController.AkaName));
|
Global.MainForm.StatusText(i18N.Translate("Starting ", pEncryptedProxyController.Name));
|
||||||
if (pEncryptedProxyController.Ready) result = pEncryptedProxyController.Start(server, mode);
|
if (pEncryptedProxyController.Ready) result = pEncryptedProxyController.Start(server, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
|
Logging.Info("加密代理已启动");
|
||||||
// 加密代理已启动
|
// 加密代理已启动
|
||||||
switch (mode.Type)
|
switch (mode.Type)
|
||||||
{
|
{
|
||||||
@@ -84,26 +84,29 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
if (pModeController != null && pModeController.Ready)
|
if (pModeController != null && pModeController.Ready)
|
||||||
{
|
{
|
||||||
MainForm.Instance.StatusText(i18N.Translate("Starting ", pModeController.AkaName));
|
Global.MainForm.StatusText(i18N.Translate("Starting ", pModeController.Name));
|
||||||
result = pModeController.Start(server, mode);
|
result = pModeController.Start(server, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mode.Type)
|
if (result)
|
||||||
{
|
{
|
||||||
case 0:
|
Logging.Info("模式已启动");
|
||||||
case 1:
|
switch (mode.Type)
|
||||||
case 2:
|
{
|
||||||
if (result)
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
MainForm.Instance.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
Global.MainForm.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
||||||
// Thread.Sleep(1000);
|
// Thread.Sleep(1000);
|
||||||
var (nttResult, natType, localEnd, publicEnd) = pNTTController.Start();
|
var (nttResult, natType, localEnd, publicEnd) = pNTTController.Start();
|
||||||
var country = Utils.Utils.GetCityCode(publicEnd);
|
var country = Utils.Utils.GetCityCode(publicEnd);
|
||||||
|
|
||||||
if (nttResult) MainForm.Instance.NatTypeStatusText(natType, country);
|
if (nttResult) Global.MainForm.NatTypeStatusText(natType, country);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
public HTTPController()
|
public HTTPController()
|
||||||
{
|
{
|
||||||
AkaName = "HTTP";
|
Name = "HTTP";
|
||||||
Ready = true;
|
Ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
static NFController()
|
static NFController()
|
||||||
{
|
{
|
||||||
// 生成系统版本
|
switch ($"{Environment.OSVersion.Version.Major}.{Environment.OSVersion.Version.Minor}")
|
||||||
var winNTver = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
|
||||||
switch (winNTver)
|
|
||||||
{
|
{
|
||||||
case "10.0":
|
case "10.0":
|
||||||
BinDriver = "Win-10.sys";
|
BinDriver = "Win-10.sys";
|
||||||
@@ -41,7 +39,7 @@ namespace Netch.Controllers
|
|||||||
BinDriver = "Win-7.sys";
|
BinDriver = "Win-7.sys";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Logging.Error($"不支持的系统版本:{winNTver}");
|
Logging.Error($"不支持的系统版本:{Environment.OSVersion.Version}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,11 +129,11 @@ namespace Netch.Controllers
|
|||||||
// 防止其他程序占用 重置 NF 百万连接数限制
|
// 防止其他程序占用 重置 NF 百万连接数限制
|
||||||
NFService.Stop();
|
NFService.Stop();
|
||||||
NFService.WaitForStatus(ServiceControllerStatus.Stopped);
|
NFService.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||||
MainForm.Instance.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
Global.MainForm.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||||
NFService.Start();
|
NFService.Start();
|
||||||
break;
|
break;
|
||||||
case ServiceControllerStatus.Stopped:
|
case ServiceControllerStatus.Stopped:
|
||||||
MainForm.Instance.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
Global.MainForm.StatusText(i18N.Translate("Starting netfilter2 Service"));
|
||||||
NFService.Start();
|
NFService.Start();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -208,12 +206,12 @@ namespace Netch.Controllers
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainForm.Instance.StatusText(i18N.Translate("Register driver"));
|
Global.MainForm.StatusText(i18N.Translate("Register driver"));
|
||||||
// 注册驱动文件
|
// 注册驱动文件
|
||||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||||
if (result == NF_STATUS.NF_STATUS_SUCCESS)
|
if (result == NF_STATUS.NF_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
Logging.Info($"驱动安装成功,当前驱动版本:{DriverVersion(DriverVersion(SystemDriver))}");
|
Logging.Info($"驱动安装成功,当前驱动版本:{DriverVersion(SystemDriver)}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -226,7 +224,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!WriteLog(e)) return;
|
if (!Write(e.Data)) return;
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
{
|
{
|
||||||
if (Instance.HasExited)
|
if (Instance.HasExited)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace Netch.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SetupBypass()
|
public bool SetupBypass()
|
||||||
{
|
{
|
||||||
MainForm.Instance.StatusText(i18N.Translate("SetupBypass"));
|
Global.MainForm.StatusText(i18N.Translate("SetupBypass"));
|
||||||
Logging.Info("设置绕行规则 → 设置让服务器 IP 走直连");
|
Logging.Info("设置绕行规则 → 设置让服务器 IP 走直连");
|
||||||
// 让服务器 IP 走直连
|
// 让服务器 IP 走直连
|
||||||
foreach (var address in _serverAddresses)
|
foreach (var address in _serverAddresses)
|
||||||
@@ -310,7 +310,7 @@ namespace Netch.Controllers
|
|||||||
{
|
{
|
||||||
if (!Ready) return false;
|
if (!Ready) return false;
|
||||||
|
|
||||||
MainForm.Instance.StatusText(i18N.Translate("Starting Tap"));
|
Global.MainForm.StatusText(i18N.Translate("Starting Tap"));
|
||||||
|
|
||||||
_savedMode = mode;
|
_savedMode = mode;
|
||||||
_savedServer = server;
|
_savedServer = server;
|
||||||
@@ -391,7 +391,7 @@ namespace Netch.Controllers
|
|||||||
|
|
||||||
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
private void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!WriteLog(e)) return;
|
if (!Write(e.Data)) return;
|
||||||
if (State == State.Starting)
|
if (State == State.Starting)
|
||||||
{
|
{
|
||||||
if (e.Data.Contains("Running"))
|
if (e.Data.Contains("Running"))
|
||||||
|
|||||||
@@ -15,9 +15,13 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
partial class MainForm
|
partial class MainForm
|
||||||
{
|
{
|
||||||
public void ControlFun()
|
private bool _isFirstCloseWindow = true;
|
||||||
|
|
||||||
|
private void ControlFun()
|
||||||
{
|
{
|
||||||
SaveConfigs();
|
//防止模式选择框变成蓝色:D
|
||||||
|
ModeComboBox.Select(0, 0);
|
||||||
|
|
||||||
if (State == State.Waiting || State == State.Stopped)
|
if (State == State.Waiting || State == State.Stopped)
|
||||||
{
|
{
|
||||||
// 服务器、模式 需选择
|
// 服务器、模式 需选择
|
||||||
@@ -33,36 +37,23 @@ namespace Netch.Forms
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false;
|
|
||||||
|
|
||||||
UpdateStatus(State.Starting);
|
UpdateStatus(State.Starting);
|
||||||
|
|
||||||
Firewall.AddNetchFwRules();
|
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
Task.Run(Firewall.AddNetchFwRules);
|
||||||
|
|
||||||
var server = ServerComboBox.SelectedItem as Models.Server;
|
var server = ServerComboBox.SelectedItem as Models.Server;
|
||||||
var mode = ModeComboBox.SelectedItem as Models.Mode;
|
var mode = ModeComboBox.SelectedItem as Models.Mode;
|
||||||
|
|
||||||
MainController ??= new MainController();
|
if (_mainController.Start(server, mode))
|
||||||
|
|
||||||
var startResult = MainController.Start(server, mode);
|
|
||||||
|
|
||||||
if (startResult)
|
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
UpdateStatus(State.Started);
|
UpdateStatus(State.Started,
|
||||||
StatusText(i18N.Translate(StateExtension.GetStatusString(State)) + PortText(server.Type,mode.Type));
|
i18N.Translate(StateExtension.GetStatusString(State.Started)) + PortText(server.Type, mode.Type));
|
||||||
|
|
||||||
LastUploadBandwidth = 0;
|
Bandwidth.NetTraffic(server, mode, _mainController);
|
||||||
//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;
|
|
||||||
UploadSpeedLabel.Visible = false;
|
|
||||||
Bandwidth.NetTraffic(server, mode, MainController);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 如果勾选启动后最小化
|
// 如果勾选启动后最小化
|
||||||
@@ -71,7 +62,7 @@ namespace Netch.Forms
|
|||||||
WindowState = FormWindowState.Minimized;
|
WindowState = FormWindowState.Minimized;
|
||||||
NotifyIcon.Visible = true;
|
NotifyIcon.Visible = true;
|
||||||
|
|
||||||
if (IsFirstOpened)
|
if (_isFirstCloseWindow)
|
||||||
{
|
{
|
||||||
// 显示提示语
|
// 显示提示语
|
||||||
NotifyIcon.ShowBalloonTip(5,
|
NotifyIcon.ShowBalloonTip(5,
|
||||||
@@ -80,7 +71,7 @@ namespace Netch.Forms
|
|||||||
"Netch is now minimized to the notification bar, double click this icon to restore."),
|
"Netch is now minimized to the notification bar, double click this icon to restore."),
|
||||||
ToolTipIcon.Info);
|
ToolTipIcon.Info);
|
||||||
|
|
||||||
IsFirstOpened = false;
|
_isFirstCloseWindow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hide();
|
Hide();
|
||||||
@@ -111,8 +102,7 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UpdateStatus(State.Stopped);
|
UpdateStatus(State.Stopped, i18N.Translate("Start failed"));
|
||||||
StatusText(i18N.Translate("Start failed"));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -120,17 +110,17 @@ namespace Netch.Forms
|
|||||||
{
|
{
|
||||||
// 停止
|
// 停止
|
||||||
UpdateStatus(State.Stopping);
|
UpdateStatus(State.Stopping);
|
||||||
MainController.Stop();
|
|
||||||
UpdateStatus(State.Stopped);
|
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
_mainController.Stop();
|
||||||
|
UpdateStatus(State.Stopped);
|
||||||
|
|
||||||
TestServer();
|
TestServer();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string PortText(string serverType,int modeType)
|
private string PortText(string serverType, int modeType)
|
||||||
{
|
{
|
||||||
var text = new StringBuilder(" (");
|
var text = new StringBuilder(" (");
|
||||||
text.Append(Global.Settings.LocalAddress == "0.0.0.0"
|
text.Append(Global.Settings.LocalAddress == "0.0.0.0"
|
||||||
@@ -148,7 +138,7 @@ namespace Netch.Forms
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 不可控HTTP
|
// 不可控HTTP
|
||||||
text.Clear();
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -163,14 +153,12 @@ namespace Netch.Forms
|
|||||||
$" | HTTP {i18N.Translate("Local Port", ": ")}{Global.Settings.HTTPLocalPort}");
|
$" | HTTP {i18N.Translate("Local Port", ": ")}{Global.Settings.HTTPLocalPort}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (text.Length > 0)
|
|
||||||
{
|
|
||||||
text.Append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
text.Append(")");
|
||||||
return text.ToString();
|
return text.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void OnBandwidthUpdated(long download)
|
public void OnBandwidthUpdated(long download)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -198,7 +186,7 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
|
|
||||||
UsedBandwidthLabel.Text =
|
UsedBandwidthLabel.Text =
|
||||||
$"{i18N.Translate("Used",": ")}{Bandwidth.Compute(upload + download)}";
|
$"{i18N.Translate("Used", ": ")}{Bandwidth.Compute(upload + download)}";
|
||||||
UploadSpeedLabel.Text = $"↑: {Bandwidth.Compute(upload - LastUploadBandwidth)}/s";
|
UploadSpeedLabel.Text = $"↑: {Bandwidth.Compute(upload - LastUploadBandwidth)}/s";
|
||||||
DownloadSpeedLabel.Text = $"↓: {Bandwidth.Compute(download - LastDownloadBandwidth)}/s";
|
DownloadSpeedLabel.Text = $"↓: {Bandwidth.Compute(download - LastDownloadBandwidth)}/s";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
@@ -134,8 +133,8 @@ namespace Netch.Forms
|
|||||||
Remark = "ProxyUpdate",
|
Remark = "ProxyUpdate",
|
||||||
Type = 5
|
Type = 5
|
||||||
};
|
};
|
||||||
MainController = new MainController();
|
_mainController = new MainController();
|
||||||
MainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var item in Global.Settings.SubscribeLink)
|
foreach (var item in Global.Settings.SubscribeLink)
|
||||||
@@ -165,8 +164,8 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
|
Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
|
||||||
var result = ShareLink.Parse(response);
|
var result = ShareLink.Parse(response);
|
||||||
@@ -203,7 +202,7 @@ namespace Netch.Forms
|
|||||||
{
|
{
|
||||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
||||||
ControlButton.Text = i18N.Translate("Start");
|
ControlButton.Text = i18N.Translate("Start");
|
||||||
MainController.Stop();
|
_mainController.Stop();
|
||||||
NatTypeStatusLabel.Text = "";
|
NatTypeStatusLabel.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +212,6 @@ namespace Netch.Forms
|
|||||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
||||||
UpdateStatus(bak_State);
|
UpdateStatus(bak_State);
|
||||||
StatusLabel.Text = bak_StateText;
|
StatusLabel.Text = bak_StateText;
|
||||||
|
|
||||||
}).ContinueWith(task => { BeginInvoke(new Action(() => { UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true; })); });
|
}).ContinueWith(task => { BeginInvoke(new Action(() => { UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true; })); });
|
||||||
|
|
||||||
NotifyIcon.ShowBalloonTip(5,
|
NotifyIcon.ShowBalloonTip(5,
|
||||||
@@ -380,8 +378,8 @@ namespace Netch.Forms
|
|||||||
Remark = "ProxyUpdate",
|
Remark = "ProxyUpdate",
|
||||||
Type = 5
|
Type = 5
|
||||||
};
|
};
|
||||||
MainController = new MainController();
|
_mainController = new MainController();
|
||||||
MainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
|
||||||
|
|
||||||
using var client = new WebClient();
|
using var client = new WebClient();
|
||||||
|
|
||||||
@@ -403,7 +401,7 @@ namespace Netch.Forms
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
UpdateStatus(State.Waiting);
|
UpdateStatus(State.Waiting);
|
||||||
MainController.Stop();
|
_mainController.Stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,19 +12,18 @@ namespace Netch.Forms
|
|||||||
public partial class Dummy { }
|
public partial class Dummy { }
|
||||||
partial class MainForm
|
partial class MainForm
|
||||||
{
|
{
|
||||||
|
|
||||||
/// init at <see cref="MainForm_Load"/>
|
/// init at <see cref="MainForm_Load"/>
|
||||||
private int _sizeHeight;
|
private int _sizeHeight;
|
||||||
private int _controlHeight;
|
|
||||||
private int _profileBoxHeight;
|
private int _profileConfigurationHeight;
|
||||||
|
private int _profileGroupboxHeight;
|
||||||
private int _configurationGroupBoxHeight;
|
private int _configurationGroupBoxHeight;
|
||||||
|
|
||||||
private void InitProfile()
|
private void InitProfile()
|
||||||
{
|
{
|
||||||
|
// Clear
|
||||||
foreach (var button in ProfileButtons)
|
foreach (var button in ProfileButtons)
|
||||||
{
|
|
||||||
button.Dispose();
|
button.Dispose();
|
||||||
}
|
|
||||||
|
|
||||||
ProfileButtons.Clear();
|
ProfileButtons.Clear();
|
||||||
ProfileTable.ColumnStyles.Clear();
|
ProfileTable.ColumnStyles.Clear();
|
||||||
@@ -33,51 +32,51 @@ namespace Netch.Forms
|
|||||||
var numProfile = Global.Settings.ProfileCount;
|
var numProfile = Global.Settings.ProfileCount;
|
||||||
if (numProfile == 0)
|
if (numProfile == 0)
|
||||||
{
|
{
|
||||||
|
// Hide Profile GroupBox, Change window size
|
||||||
configLayoutPanel.RowStyles[2].SizeType = SizeType.Percent;
|
configLayoutPanel.RowStyles[2].SizeType = SizeType.Percent;
|
||||||
configLayoutPanel.RowStyles[2].Height = 0;
|
configLayoutPanel.RowStyles[2].Height = 0;
|
||||||
ProfileGroupBox.Visible = false;
|
ProfileGroupBox.Visible = false;
|
||||||
|
|
||||||
ConfigurationGroupBox.Size = new Size(ConfigurationGroupBox.Size.Width, _configurationGroupBoxHeight - _controlHeight);
|
ConfigurationGroupBox.Size = new Size(ConfigurationGroupBox.Size.Width, _configurationGroupBoxHeight - _profileConfigurationHeight);
|
||||||
Size = new Size(Size.Width, _sizeHeight - (_controlHeight + _profileBoxHeight));
|
Size = new Size(Size.Width, _sizeHeight - (_profileConfigurationHeight + _profileGroupboxHeight));
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
configLayoutPanel.RowStyles[2].SizeType = SizeType.AutoSize;
|
|
||||||
ProfileGroupBox.Visible = true;
|
|
||||||
ConfigurationGroupBox.Size = new Size(ConfigurationGroupBox.Size.Width, _configurationGroupBoxHeight);
|
|
||||||
Size = new Size(Size.Width, _sizeHeight);
|
|
||||||
|
|
||||||
|
|
||||||
ProfileTable.ColumnCount = numProfile;
|
|
||||||
|
|
||||||
while (Global.Settings.Profiles.Count < numProfile)
|
|
||||||
{
|
{
|
||||||
Global.Settings.Profiles.Add(new Profile());
|
// Load Profiles
|
||||||
}
|
ProfileTable.ColumnCount = numProfile;
|
||||||
|
|
||||||
// buttons
|
while (Global.Settings.Profiles.Count < numProfile)
|
||||||
for (var i = 0; i < numProfile; ++i)
|
{
|
||||||
{
|
Global.Settings.Profiles.Add(new Profile());
|
||||||
var b = new Button();
|
}
|
||||||
ProfileTable.Controls.Add(b, i, 0);
|
|
||||||
b.Location = new Point(i * 100, 0);
|
|
||||||
b.Click += ProfileButton_Click;
|
|
||||||
b.Dock = DockStyle.Fill;
|
|
||||||
b.Text = !Global.Settings.Profiles[i].IsDummy ? Global.Settings.Profiles[i].ProfileName : i18N.Translate("None");
|
|
||||||
|
|
||||||
ProfileButtons.Add(b);
|
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");
|
||||||
|
|
||||||
// equal column
|
ProfileTable.Controls.Add(b, i, 0);
|
||||||
for (var i = 1; i <= ProfileTable.RowCount; i++)
|
ProfileButtons.Add(b);
|
||||||
{
|
}
|
||||||
ProfileTable.RowStyles.Add(new RowStyle(SizeType.Percent, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 1; i <= ProfileTable.ColumnCount; i++)
|
// equal column
|
||||||
{
|
for (var i = 1; i <= ProfileTable.RowCount; i++)
|
||||||
ProfileTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1));
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,14 +128,18 @@ namespace Netch.Forms
|
|||||||
Global.Settings.Profiles[index] = new Profile(selectedServer, selectedMode, name);
|
Global.Settings.Profiles[index] = new Profile(selectedServer, selectedMode, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Button> ProfileButtons = new List<Button>();
|
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)
|
private void ProfileButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var index = ProfileButtons.IndexOf((Button) sender);
|
var index = ProfileButtons.IndexOf((Button) sender);
|
||||||
|
|
||||||
//Utils.Logging.Info(String.Format("Button no.{0} clicked", index));
|
|
||||||
|
|
||||||
if (ModifierKeys == Keys.Control)
|
if (ModifierKeys == Keys.Control)
|
||||||
{
|
{
|
||||||
if (ServerComboBox.SelectedIndex == -1)
|
if (ServerComboBox.SelectedIndex == -1)
|
||||||
@@ -157,11 +160,21 @@ namespace Netch.Forms
|
|||||||
ProfileButtons[index].Text = ProfileNameText.Text;
|
ProfileButtons[index].Text = ProfileNameText.Text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ModifierKeys == Keys.Shift)
|
||||||
|
{
|
||||||
|
if (MessageBoxX.Show(i18N.Translate("Remove this Profile?"), confirm: true) == DialogResult.OK)
|
||||||
|
{
|
||||||
|
RemoveProfile(index);
|
||||||
|
ProfileButtons[index].Text = i18N.Translate("None");
|
||||||
|
MessageBoxX.Show(i18N.Translate("Profile Removed!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ProfileButtons[index].Text == i18N.Translate("Error") || ProfileButtons[index].Text == i18N.Translate("None"))
|
if (Global.Settings.Profiles[index].IsDummy)
|
||||||
{
|
{
|
||||||
MessageBoxX.Show(i18N.Translate("No saved profile here. Save a profile first by Ctrl+Click on the button"));
|
MessageBoxX.Show(i18N.Translate("No saved profile here. Save a profile first by Ctrl+Click on the button"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -169,21 +182,14 @@ namespace Netch.Forms
|
|||||||
ProfileNameText.Text = LoadProfile(index);
|
ProfileNameText.Text = LoadProfile(index);
|
||||||
|
|
||||||
// start the profile
|
// start the profile
|
||||||
var need2ndStart = true;
|
ControlFun();
|
||||||
if (State == State.Waiting || State == State.Stopped)
|
if (State == State.Stopping || State == State.Stopped)
|
||||||
{
|
|
||||||
need2ndStart = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlButton.PerformClick();
|
|
||||||
|
|
||||||
if (need2ndStart)
|
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
while (State != State.Stopped)
|
while (State != State.Stopped)
|
||||||
{
|
{
|
||||||
Thread.Sleep(200);
|
Thread.Sleep(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlButton.PerformClick();
|
ControlButton.PerformClick();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Netch.Forms
|
|||||||
{
|
{
|
||||||
#region Server
|
#region Server
|
||||||
|
|
||||||
public void TestServer()
|
private static void TestServer()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -24,6 +24,7 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
#region Mode
|
#region Mode
|
||||||
|
|
||||||
public void InitMode()
|
private void InitMode()
|
||||||
{
|
{
|
||||||
ModeComboBox.Items.Clear();
|
ModeComboBox.Items.Clear();
|
||||||
Global.ModeFiles.Clear();
|
Global.ModeFiles.Clear();
|
||||||
@@ -139,7 +140,7 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectLastMode()
|
private void SelectLastMode()
|
||||||
{
|
{
|
||||||
// 如果值合法,选中该位置
|
// 如果值合法,选中该位置
|
||||||
if (Global.Settings.ModeComboBoxSelectedIndex > 0 &&
|
if (Global.Settings.ModeComboBoxSelectedIndex > 0 &&
|
||||||
@@ -182,7 +183,7 @@ namespace Netch.Forms
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Init at MainForm_Load()
|
/// Init at <see cref="MainForm_Load"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private int _eWidth;
|
private int _eWidth;
|
||||||
|
|
||||||
@@ -205,32 +206,18 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
switch (cbx.Items[e.Index])
|
switch (cbx.Items[e.Index])
|
||||||
{
|
{
|
||||||
case Models.Server _:
|
case Models.Server item:
|
||||||
{
|
{
|
||||||
var item = cbx.Items[e.Index] as Models.Server;
|
|
||||||
|
|
||||||
// 计算延迟底色
|
// 计算延迟底色
|
||||||
SolidBrush brush;
|
SolidBrush brush;
|
||||||
if (item.Delay > 200)
|
if (item.Delay > 200)
|
||||||
{
|
|
||||||
// 红色
|
|
||||||
brush = new SolidBrush(Color.Red);
|
brush = new SolidBrush(Color.Red);
|
||||||
}
|
|
||||||
else if (item.Delay > 80)
|
else if (item.Delay > 80)
|
||||||
{
|
|
||||||
// 黄色
|
|
||||||
brush = new SolidBrush(Color.Yellow);
|
brush = new SolidBrush(Color.Yellow);
|
||||||
}
|
|
||||||
else if (item.Delay >= 0)
|
else if (item.Delay >= 0)
|
||||||
{
|
|
||||||
// 绿色
|
|
||||||
brush = new SolidBrush(Color.FromArgb(50, 255, 56));
|
brush = new SolidBrush(Color.FromArgb(50, 255, 56));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// 灰色
|
|
||||||
brush = new SolidBrush(Color.Gray);
|
brush = new SolidBrush(Color.Gray);
|
||||||
}
|
|
||||||
|
|
||||||
// 绘制延迟底色
|
// 绘制延迟底色
|
||||||
e.Graphics.FillRectangle(brush, _eWidth * 9, e.Bounds.Y, _eWidth, e.Bounds.Height);
|
e.Graphics.FillRectangle(brush, _eWidth * 9, e.Bounds.Y, _eWidth, e.Bounds.Height);
|
||||||
@@ -240,10 +227,8 @@ namespace Netch.Forms
|
|||||||
_eWidth * 9 + _eWidth / 30, e.Bounds.Y);
|
_eWidth * 9 + _eWidth / 30, e.Bounds.Y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Models.Mode _:
|
case Models.Mode item:
|
||||||
{
|
{
|
||||||
var item = cbx.Items[e.Index] as Models.Mode;
|
|
||||||
|
|
||||||
// 绘制 模式Box 底色
|
// 绘制 模式Box 底色
|
||||||
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), _eWidth * 9, e.Bounds.Y, _eWidth,
|
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), _eWidth * 9, e.Bounds.Y, _eWidth,
|
||||||
e.Bounds.Height);
|
e.Bounds.Height);
|
||||||
@@ -257,6 +242,7 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Netch.Forms
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public State State { get; private set; } = State.Waiting;
|
public State State { get; private set; } = State.Waiting;
|
||||||
|
|
||||||
public void NatTypeStatusText(string text = "",string Country = "")
|
public void NatTypeStatusText(string text = "", string country = "")
|
||||||
{
|
{
|
||||||
if (State != State.Started)
|
if (State != State.Started)
|
||||||
{
|
{
|
||||||
@@ -27,9 +27,9 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(text))
|
if (!string.IsNullOrEmpty(text))
|
||||||
{
|
{
|
||||||
if (Country != "")
|
if (country != "")
|
||||||
{
|
{
|
||||||
NatTypeStatusLabel.Text = String.Format("NAT{0}{1}[{2}]", i18N.Translate(": "), text, Country);
|
NatTypeStatusLabel.Text = String.Format("NAT{0}{1}[{2}]", i18N.Translate(": "), text, country);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -43,12 +43,16 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NatTypeStatusLabel.Text = "NAT" + i18N.Translate(": ") + i18N.Translate("Test failed");
|
NatTypeStatusLabel.Text = $@"NAT{i18N.Translate(": ", "Test failed")}";
|
||||||
}
|
}
|
||||||
|
|
||||||
NatTypeStatusLabel.Visible = true;
|
NatTypeStatusLabel.Visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新 NAT指示灯颜色
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="natType"></param>
|
||||||
private void UpdateNatTypeLight(STUN_Client.NatType natType)
|
private void UpdateNatTypeLight(STUN_Client.NatType natType)
|
||||||
{
|
{
|
||||||
Color c;
|
Color c;
|
||||||
@@ -76,19 +80,34 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新状态栏文本
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
public void StatusText(string text)
|
public void StatusText(string text)
|
||||||
{
|
{
|
||||||
StatusLabel.Text = i18N.Translate("Status", ": ") + text;
|
StatusLabel.Text = i18N.Translate("Status", ": ") + text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update UI, Status, Status Label
|
/// 更新 UI, 状态栏文本, 状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="state"></param>
|
/// <param name="state"></param>
|
||||||
public void UpdateStatus(State state)
|
/// <param name="text"></param>
|
||||||
|
private void UpdateStatus(State state, string text = "")
|
||||||
{
|
{
|
||||||
State = state;
|
State = state;
|
||||||
StatusText(i18N.Translate(StateExtension.GetStatusString(state)));
|
StatusText(text == "" ? i18N.Translate(StateExtension.GetStatusString(state)) : text);
|
||||||
|
|
||||||
|
void MenuStripsEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
// 需要禁用的菜单项
|
||||||
|
UninstallServiceToolStripMenuItem.Enabled =
|
||||||
|
updateACLWithProxyToolStripMenuItem.Enabled =
|
||||||
|
UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
|
||||||
|
reinstallTapDriverToolStripMenuItem.Enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO 补充
|
// TODO 补充
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
@@ -96,34 +115,33 @@ namespace Netch.Forms
|
|||||||
ControlButton.Enabled = true;
|
ControlButton.Enabled = true;
|
||||||
ControlButton.Text = i18N.Translate("Start");
|
ControlButton.Text = i18N.Translate("Start");
|
||||||
|
|
||||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
|
|
||||||
updateACLWithProxyToolStripMenuItem.Enabled = true;
|
|
||||||
|
|
||||||
NatTypeStatusText();
|
|
||||||
break;
|
break;
|
||||||
case State.Starting:
|
case State.Starting:
|
||||||
ControlButton.Enabled = false;
|
ControlButton.Enabled = false;
|
||||||
ControlButton.Text = "...";
|
ControlButton.Text = "...";
|
||||||
|
|
||||||
ServerComboBox.Enabled = false;
|
ConfigurationGroupBox.Enabled = false;
|
||||||
ModeComboBox.Enabled = false;
|
|
||||||
|
|
||||||
UninstallServiceToolStripMenuItem.Enabled = false;
|
MenuStripsEnabled(false);
|
||||||
updateACLWithProxyToolStripMenuItem.Enabled = false;
|
|
||||||
UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = false;
|
|
||||||
reinstallTapDriverToolStripMenuItem.Enabled = false;
|
|
||||||
break;
|
break;
|
||||||
case State.Started:
|
case State.Started:
|
||||||
ControlButton.Enabled = true;
|
ControlButton.Enabled = true;
|
||||||
ControlButton.Text = i18N.Translate("Stop");
|
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;
|
break;
|
||||||
case State.Stopping:
|
case State.Stopping:
|
||||||
ControlButton.Enabled = false;
|
ControlButton.Enabled = false;
|
||||||
ControlButton.Text = "...";
|
ControlButton.Text = "...";
|
||||||
|
|
||||||
ProfileGroupBox.Enabled = false;
|
ProfileGroupBox.Enabled = false;
|
||||||
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = SettingsButton.Enabled = true;
|
|
||||||
UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = false;
|
UsedBandwidthLabel.Visible /*= UploadSpeedLabel.Visible*/ = DownloadSpeedLabel.Visible = false;
|
||||||
NatTypeStatusText();
|
NatTypeStatusText();
|
||||||
break;
|
break;
|
||||||
case State.Stopped:
|
case State.Stopped:
|
||||||
@@ -133,14 +151,10 @@ namespace Netch.Forms
|
|||||||
LastUploadBandwidth = 0;
|
LastUploadBandwidth = 0;
|
||||||
LastDownloadBandwidth = 0;
|
LastDownloadBandwidth = 0;
|
||||||
|
|
||||||
ServerComboBox.Enabled = true;
|
|
||||||
ModeComboBox.Enabled = true;
|
|
||||||
ProfileGroupBox.Enabled = true;
|
ProfileGroupBox.Enabled = true;
|
||||||
|
ConfigurationGroupBox.Enabled = true;
|
||||||
|
|
||||||
UninstallServiceToolStripMenuItem.Enabled = true;
|
MenuStripsEnabled(true);
|
||||||
updateACLWithProxyToolStripMenuItem.Enabled = true;
|
|
||||||
UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true;
|
|
||||||
reinstallTapDriverToolStripMenuItem.Enabled = true;
|
|
||||||
break;
|
break;
|
||||||
case State.Terminating:
|
case State.Terminating:
|
||||||
|
|
||||||
@@ -148,7 +162,10 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateStatus()
|
/// <summary>
|
||||||
|
/// 刷新 UI
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateStatus()
|
||||||
{
|
{
|
||||||
UpdateStatus(State);
|
UpdateStatus(State);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,18 +19,7 @@ namespace Netch.Forms
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 主控制器
|
/// 主控制器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MainController MainController;
|
private MainController _mainController = new MainController();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否第一次打开
|
|
||||||
/// </summary>
|
|
||||||
public bool IsFirstOpened = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 主窗体的静态实例
|
|
||||||
/// </summary>
|
|
||||||
public static MainForm Instance;
|
|
||||||
|
|
||||||
|
|
||||||
public MainForm()
|
public MainForm()
|
||||||
{
|
{
|
||||||
@@ -40,8 +29,6 @@ namespace Netch.Forms
|
|||||||
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
|
||||||
|
|
||||||
CheckForIllegalCrossThreadCalls = false;
|
CheckForIllegalCrossThreadCalls = false;
|
||||||
// MenuStrip.Renderer = new Override.ToolStripProfessionalRender();
|
|
||||||
Instance = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveConfigs()
|
private void SaveConfigs()
|
||||||
@@ -64,6 +51,9 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
private void MainForm_Load(object sender, EventArgs e)
|
private void MainForm_Load(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
// 计算 ComboBox绘制 目标宽度
|
||||||
|
_eWidth = ServerComboBox.Width / 10;
|
||||||
|
|
||||||
// 加载服务器
|
// 加载服务器
|
||||||
InitServer();
|
InitServer();
|
||||||
|
|
||||||
@@ -73,18 +63,16 @@ namespace Netch.Forms
|
|||||||
// 加载翻译
|
// 加载翻译
|
||||||
InitText();
|
InitText();
|
||||||
|
|
||||||
//
|
// 隐藏 NatTypeStatusLabel
|
||||||
NatTypeStatusText();
|
NatTypeStatusText();
|
||||||
|
|
||||||
// 加载快速配置
|
|
||||||
_sizeHeight = Size.Height;
|
_sizeHeight = Size.Height;
|
||||||
_controlHeight = ConfigurationGroupBox.Controls[0].Height / 3;
|
|
||||||
_profileBoxHeight = ProfileGroupBox.Height;
|
|
||||||
_configurationGroupBoxHeight = ConfigurationGroupBox.Height;
|
_configurationGroupBoxHeight = ConfigurationGroupBox.Height;
|
||||||
|
_profileConfigurationHeight = ConfigurationGroupBox.Controls[0].Height / 3; // 因为 AutoSize, 所以得到的是Controls的总高度
|
||||||
|
_profileGroupboxHeight = ProfileGroupBox.Height;
|
||||||
|
// 加载快速配置
|
||||||
InitProfile();
|
InitProfile();
|
||||||
|
|
||||||
// 为 ComboBox绘制 收集宽度数据
|
|
||||||
_eWidth = ServerComboBox.Width / 10;
|
|
||||||
|
|
||||||
// 自动检测延迟
|
// 自动检测延迟
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
@@ -132,7 +120,7 @@ namespace Netch.Forms
|
|||||||
WindowState = FormWindowState.Minimized;
|
WindowState = FormWindowState.Minimized;
|
||||||
NotifyIcon.Visible = true;
|
NotifyIcon.Visible = true;
|
||||||
|
|
||||||
if (IsFirstOpened)
|
if (_isFirstCloseWindow)
|
||||||
{
|
{
|
||||||
// 显示提示语
|
// 显示提示语
|
||||||
NotifyIcon.ShowBalloonTip(5,
|
NotifyIcon.ShowBalloonTip(5,
|
||||||
@@ -140,7 +128,7 @@ namespace Netch.Forms
|
|||||||
i18N.Translate("Netch is now minimized to the notification bar, double click this icon to restore."),
|
i18N.Translate("Netch is now minimized to the notification bar, double click this icon to restore."),
|
||||||
ToolTipIcon.Info);
|
ToolTipIcon.Info);
|
||||||
|
|
||||||
IsFirstOpened = false;
|
_isFirstCloseWindow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hide();
|
Hide();
|
||||||
@@ -155,8 +143,6 @@ namespace Netch.Forms
|
|||||||
|
|
||||||
private void ControlButton_Click(object sender, EventArgs e)
|
private void ControlButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
//防止模式选择框变成蓝色:D
|
|
||||||
ModeComboBox.Select(0, 0);
|
|
||||||
ControlFun();
|
ControlFun();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +170,7 @@ namespace Netch.Forms
|
|||||||
InitProfile();
|
InitProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitText()
|
private void InitText()
|
||||||
{
|
{
|
||||||
ServerToolStripMenuItem.Text = i18N.Translate("Server");
|
ServerToolStripMenuItem.Text = i18N.Translate("Server");
|
||||||
ImportServersFromClipboardToolStripMenuItem.Text = i18N.Translate("Import Servers From Clipboard");
|
ImportServersFromClipboardToolStripMenuItem.Text = i18N.Translate("Import Servers From Clipboard");
|
||||||
@@ -207,16 +193,16 @@ namespace Netch.Forms
|
|||||||
reinstallTapDriverToolStripMenuItem.Text = i18N.Translate("Reinstall TUN/TAP driver");
|
reinstallTapDriverToolStripMenuItem.Text = i18N.Translate("Reinstall TUN/TAP driver");
|
||||||
OpenDirectoryToolStripMenuItem.Text = i18N.Translate("Open Directory");
|
OpenDirectoryToolStripMenuItem.Text = i18N.Translate("Open Directory");
|
||||||
AboutToolStripButton.Text = i18N.Translate("About");
|
AboutToolStripButton.Text = i18N.Translate("About");
|
||||||
VersionLabel.Text = i18N.Translate("xxx");
|
// VersionLabel.Text = i18N.Translate("xxx");
|
||||||
exitToolStripMenuItem.Text = i18N.Translate("Exit");
|
exitToolStripMenuItem.Text = i18N.Translate("Exit");
|
||||||
RelyToolStripMenuItem.Text = i18N.Translate("Unable to start? Click me to download");
|
RelyToolStripMenuItem.Text = i18N.Translate("Unable to start? Click me to download");
|
||||||
ConfigurationGroupBox.Text = i18N.Translate("Configuration");
|
ConfigurationGroupBox.Text = i18N.Translate("Configuration");
|
||||||
ProfileLabel.Text = i18N.Translate("Profile");
|
ProfileLabel.Text = i18N.Translate("Profile");
|
||||||
ModeLabel.Text = i18N.Translate("Mode");
|
ModeLabel.Text = i18N.Translate("Mode");
|
||||||
ServerLabel.Text = i18N.Translate("Server");
|
ServerLabel.Text = i18N.Translate("Server");
|
||||||
UsedBandwidthLabel.Text = i18N.Translate("Used: 0 KB");
|
// UsedBandwidthLabel.Text = i18N.Translate("Used: 0 KB");
|
||||||
DownloadSpeedLabel.Text = i18N.Translate("↓: 0 KB/s");
|
// DownloadSpeedLabel.Text = i18N.Translate("↓: 0 KB/s");
|
||||||
UploadSpeedLabel.Text = i18N.Translate("↑: 0 KB/s");
|
// UploadSpeedLabel.Text = i18N.Translate("↑: 0 KB/s");
|
||||||
NotifyIcon.Text = i18N.Translate("Netch");
|
NotifyIcon.Text = i18N.Translate("Netch");
|
||||||
ShowMainFormToolStripButton.Text = i18N.Translate("Show");
|
ShowMainFormToolStripButton.Text = i18N.Translate("Show");
|
||||||
ExitToolStripButton.Text = i18N.Translate("Exit");
|
ExitToolStripButton.Text = i18N.Translate("Exit");
|
||||||
@@ -303,7 +289,6 @@ namespace Netch.Forms
|
|||||||
Enabled = true;
|
Enabled = true;
|
||||||
StatusText(i18N.Translate("Test done"));
|
StatusText(i18N.Translate("Test done"));
|
||||||
Refresh();
|
Refresh();
|
||||||
Configuration.Save();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +353,7 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
// ignored
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -399,23 +385,9 @@ namespace Netch.Forms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region NotifyIcon
|
|
||||||
|
|
||||||
private void ShowMainFormToolStripButton_Click(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (WindowState == FormWindowState.Minimized)
|
|
||||||
{
|
|
||||||
Visible = true;
|
|
||||||
ShowInTaskbar = true; // 显示在系统任务栏
|
|
||||||
WindowState = FormWindowState.Normal; // 还原窗体
|
|
||||||
NotifyIcon.Visible = true; // 托盘图标隐藏
|
|
||||||
}
|
|
||||||
|
|
||||||
Activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Exit(bool forceExit = false)
|
private void Exit(bool forceExit = false)
|
||||||
{
|
{
|
||||||
|
if(IsDisposed) return;
|
||||||
// 已启动
|
// 已启动
|
||||||
if (State != State.Waiting && State != State.Stopped)
|
if (State != State.Waiting && State != State.Stopped)
|
||||||
{
|
{
|
||||||
@@ -457,6 +429,21 @@ namespace Netch.Forms
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region NotifyIcon
|
||||||
|
|
||||||
|
private void ShowMainFormToolStripButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (WindowState == FormWindowState.Minimized)
|
||||||
|
{
|
||||||
|
Visible = true;
|
||||||
|
ShowInTaskbar = true; // 显示在系统任务栏
|
||||||
|
WindowState = FormWindowState.Normal; // 还原窗体
|
||||||
|
NotifyIcon.Visible = true; // 托盘图标隐藏
|
||||||
|
}
|
||||||
|
|
||||||
|
Activate();
|
||||||
|
}
|
||||||
|
|
||||||
private void ExitToolStripButton_Click(object sender, EventArgs e)
|
private void ExitToolStripButton_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Exit();
|
Exit();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Netch
|
|||||||
public static readonly string NetchDir = (AppDomain.CurrentDomain.BaseDirectory).TrimEnd();
|
public static readonly string NetchDir = (AppDomain.CurrentDomain.BaseDirectory).TrimEnd();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 主窗体
|
/// 主窗体的静态实例
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Forms.MainForm MainForm;
|
public static Forms.MainForm MainForm;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Diagnostics.Tracing.Parsers;
|
using Microsoft.Diagnostics.Tracing.Parsers;
|
||||||
using Microsoft.Diagnostics.Tracing.Session;
|
using Microsoft.Diagnostics.Tracing.Session;
|
||||||
@@ -48,27 +49,27 @@ namespace Netch.Utils
|
|||||||
//int sent = 0;
|
//int sent = 0;
|
||||||
|
|
||||||
//var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet();
|
//var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet();
|
||||||
var processList = new List<int>();
|
var instances = new List<Process>();
|
||||||
|
if (server.Type.Equals("Socks5") && mainController.pModeController.Name == "HTTP")
|
||||||
if (server.Type.Equals("Socks5") && mainController.pModeController.AkaName == "HTTP")
|
|
||||||
{
|
{
|
||||||
processList.Add(((HTTPController) mainController.pModeController).pPrivoxyController.Instance.Id);
|
instances.Add(((HTTPController) mainController.pModeController).pPrivoxyController.Instance);
|
||||||
}
|
}
|
||||||
else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL)
|
else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL)
|
||||||
{
|
{
|
||||||
processList.Add(Process.GetCurrentProcess().Id);
|
instances.Add(Process.GetCurrentProcess());
|
||||||
}
|
}
|
||||||
else if (mainController.pEncryptedProxyController != null)
|
else if (mainController.pEncryptedProxyController != null)
|
||||||
{
|
{
|
||||||
// mainController.pServerClientController.Instance
|
instances.Add(mainController.pEncryptedProxyController.Instance);
|
||||||
processList.Add(mainController.pEncryptedProxyController.Instance.Id);
|
|
||||||
}
|
}
|
||||||
else if (mainController.pModeController != null)
|
else if (mainController.pModeController != null)
|
||||||
{
|
{
|
||||||
processList.Add(mainController.pModeController.Instance.Id);
|
instances.Add(mainController.pModeController.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.Info("启动流量统计 PID:" + string.Join(",", processList.ToArray()));
|
var processList = instances.Select(instance => instance.Id).ToList();
|
||||||
|
|
||||||
|
Logging.Info("流量统计进程:" + string.Join(",", instances.Select(instance => $"({instance.Id})"+instance.ProcessName).ToArray()));
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
@@ -101,18 +102,18 @@ namespace Netch.Utils
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if ((Convert.ToInt32(MainForm.Instance.LastDownloadBandwidth) - Convert.ToInt32(received)) == 0)
|
if ((Convert.ToInt32(Global.MainForm.LastDownloadBandwidth) - Convert.ToInt32(received)) == 0)
|
||||||
{
|
{
|
||||||
MainForm.Instance.OnBandwidthUpdated(0);
|
Global.MainForm.OnBandwidthUpdated(0);
|
||||||
received = 0;
|
received = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (MainForm.Instance.State != State.Stopped)
|
while (Global.MainForm.State != State.Stopped)
|
||||||
{
|
{
|
||||||
Task.Delay(1000).Wait();
|
Task.Delay(1000).Wait();
|
||||||
lock (counterLock)
|
lock (counterLock)
|
||||||
{
|
{
|
||||||
MainForm.Instance.OnBandwidthUpdated(Convert.ToInt64(received));
|
Global.MainForm.OnBandwidthUpdated(Convert.ToInt64(received));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Netch.Utils
|
|||||||
{
|
{
|
||||||
return MessageBox.Show(
|
return MessageBox.Show(
|
||||||
owner: owner,
|
owner: owner,
|
||||||
text: i18N.Translate(text: text),
|
text: text,
|
||||||
caption: i18N.Translate(string.IsNullOrWhiteSpace(title) ? (info ? "Information" : "Error") : title),
|
caption: i18N.Translate(string.IsNullOrWhiteSpace(title) ? (info ? "Information" : "Error") : title),
|
||||||
buttons: confirm ? MessageBoxButtons.OKCancel : MessageBoxButtons.OK,
|
buttons: confirm ? MessageBoxButtons.OKCancel : MessageBoxButtons.OK,
|
||||||
icon: info ? MessageBoxIcon.Information : MessageBoxIcon.Exclamation);
|
icon: info ? MessageBoxIcon.Information : MessageBoxIcon.Exclamation);
|
||||||
|
|||||||
Reference in New Issue
Block a user