Refactor: Merge MainForm

This commit is contained in:
ChsBuffer
2021-01-15 16:24:59 +08:00
parent 5ff26e97b4
commit c9da7197ba
9 changed files with 1210 additions and 1309 deletions

View File

@@ -1,7 +1,7 @@
root = true
# http://editorconfig.org/
# top-most EditorConfig file
root = true
# all files
[*]
@@ -32,6 +32,7 @@ resharper_csharp_blank_lines_around_field = 0
resharper_csharp_blank_lines_around_invocable = 0
resharper_csharp_blank_lines_around_type = 0
resharper_csharp_int_align_comments = true
resharper_csharp_keep_blank_lines_in_declarations = 1
resharper_csharp_max_line_length = 368
resharper_csharp_wrap_lines = false
resharper_place_expr_accessor_on_single_line = true

View File

@@ -97,8 +97,8 @@ namespace Netch.Controllers
if (!await StartMode(mode))
throw new StartFailedException();
if (mode.TestNatRequired())
NatTest();
_ = Task.Run(Bandwidth.NetTraffic);
_ = Task.Run(NatTest);
return true;
}
@@ -210,7 +210,6 @@ namespace Netch.Controllers
ServerController = null;
}
/// <summary>
/// 检查端口是否被占用,
/// 被占用则弹窗提示, 确认后抛出异常
@@ -239,6 +238,8 @@ namespace Netch.Controllers
/// </summary>
public static void NatTest()
{
if (!Mode.TestNatRequired())
return;
NttTested = false;
Task.Run(() =>
{

View File

@@ -1,124 +0,0 @@
using System;
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;
/// <summary>
/// 上一次下载的流量
/// </summary>
public ulong LastDownloadBandwidth;
/// <summary>
/// 上一次上传的流量
/// </summary>
public ulong LastUploadBandwidth;
private async void ControlFun()
{
Configuration.Save();
if (State == State.Waiting || State == State.Stopped)
{
// 服务器、模式 需选择
if (!(ServerComboBox.SelectedItem is Server server))
{
MessageBoxX.Show(i18N.Translate("Please select a server first"));
return;
}
if (!(ModeComboBox.SelectedItem is Models.Mode mode))
{
MessageBoxX.Show(i18N.Translate("Please select a mode first"));
return;
}
// 清除模式搜索框文本选择
ModeComboBox.Select(0, 0);
State = State.Starting;
if (await MainController.Start(server, mode))
{
State = State.Started;
_ = Task.Run(() => { Bandwidth.NetTraffic(); });
// 如果勾选启动后最小化
if (Global.Settings.MinimizeWhenStarted)
{
WindowState = FormWindowState.Minimized;
if (_isFirstCloseWindow)
{
// 显示提示语
NotifyTip(i18N.Translate("Netch is now minimized to the notification bar, double click this icon to restore."));
_isFirstCloseWindow = false;
}
Hide();
}
if (Global.Settings.StartedTcping)
// 自动检测延迟
_ = Task.Run(() =>
{
while (State == State.Started)
{
server.Test();
// 重绘 ServerComboBox
ServerComboBox.Invalidate();
Thread.Sleep(Global.Settings.StartedTcping_Interval * 1000);
}
});
}
else
{
State = State.Stopped;
StatusText(i18N.Translate("Start failed"));
}
}
else
{
// 停止
State = State.Stopping;
await MainController.Stop();
State = State.Stopped;
}
}
public void OnBandwidthUpdated(ulong download)
{
if (InvokeRequired)
{
BeginInvoke(new Action<ulong>(OnBandwidthUpdated), download);
return;
}
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
{
// ignored
}
}
}
}

View File

@@ -1,375 +0,0 @@
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
using Netch.Controllers;
using Netch.Forms.Mode;
using Netch.Models;
using Netch.Utils;
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 servers = ShareLink.ParseText(texts);
Global.Settings.Server.AddRange(servers);
NotifyTip(i18N.TranslateFormat("Import {0} server(s) form Clipboard", servers.Count));
InitServer();
Configuration.Save();
}
}
private void AddServerToolStripMenuItem_Click(object sender, EventArgs e)
{
var s = ((ToolStripMenuItem) sender).Text;
var start = s.IndexOf("[", StringComparison.Ordinal) + 1;
var end = s.IndexOf("]", start, StringComparison.Ordinal);
var result = s.Substring(start, end - start);
Hide();
ServerHelper.GetUtilByFullName(result).Create();
InitServer();
Configuration.Save();
Show();
}
#endregion
#region
private void CreateProcessModeToolStripButton_Click(object sender, EventArgs e)
{
Hide();
new Process().ShowDialog();
Show();
}
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
{
Enabled = false;
try
{
ModeHelper.Load();
InitMode();
NotifyTip(i18N.Translate("Modes have been reload"));
}
catch (Exception)
{
// ignored
}
finally
{
Enabled = true;
}
}
#endregion
#region
private void ManageSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
{
Hide();
new SubscribeForm().ShowDialog();
InitServer();
Show();
}
private async void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Settings.UseProxyToUpdateSubscription = false;
await UpdateServersFromSubscribe();
}
private async void UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Settings.UseProxyToUpdateSubscription = true;
await UpdateServersFromSubscribe(true);
}
private async Task UpdateServersFromSubscribe(bool useProxy = false)
{
void DisableItems(bool v)
{
MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ProfileGroupBox.Enabled = ControlButton.Enabled = v;
}
if (useProxy && ServerComboBox.SelectedIndex == -1)
{
MessageBoxX.Show(i18N.Translate("Please select a server first"));
return;
}
if (Global.Settings.SubscribeLink.Count <= 0)
{
MessageBoxX.Show(i18N.Translate("No subscription link"));
return;
}
StatusText(i18N.Translate("Starting update subscription"));
DisableItems(false);
try
{
string proxyServer = null;
if (useProxy)
{
var mode = new Models.Mode
{
Remark = "ProxyUpdate",
Type = 5
};
await MainController.Start(ServerComboBox.SelectedItem as Server, mode);
proxyServer = $"http://127.0.0.1:{Global.Settings.HTTPLocalPort}";
}
await Subscription.UpdateServersAsync(proxyServer);
InitServer();
Configuration.Save();
StatusText(i18N.Translate("Subscription updated"));
}
catch (Exception)
{
// ignored
}
finally
{
if (useProxy)
try
{
await MainController.Stop();
}
catch
{
// ignored
}
DisableItems(true);
}
}
#endregion
#region
private void CheckForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
void OnNewVersionNotFound(object o, EventArgs args)
{
UpdateChecker.NewVersionNotFound -= OnNewVersionNotFound;
NotifyTip(i18N.Translate("Already latest version"));
}
void OnNewVersionFoundFailed(object o, EventArgs args)
{
UpdateChecker.NewVersionFoundFailed -= OnNewVersionFoundFailed;
NotifyTip(i18N.Translate("New version found failed"), info: false);
}
UpdateChecker.NewVersionNotFound += OnNewVersionNotFound;
UpdateChecker.NewVersionFoundFailed += OnNewVersionFoundFailed;
CheckUpdate();
});
}
private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
{
Utils.Utils.Open(".\\");
}
private async void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
await Task.Run(() =>
{
NativeMethods.FlushDNSResolverCache();
DNS.Cache.Clear();
});
NotifyTip(i18N.Translate("DNS cache cleanup succeeded"));
}
catch (Exception)
{
// ignored
}
finally
{
StatusText();
}
}
private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateACL(true);
}
private void updateACLToolStripMenuItem_Click(object sender, EventArgs e)
{
UpdateACL(false);
}
private async void UpdateACL(bool useProxy)
{
if (useProxy && ServerComboBox.SelectedIndex == -1)
{
MessageBoxX.Show(i18N.Translate("Please select a server first"));
return;
}
Enabled = false;
StatusText(i18N.TranslateFormat("Updating {0}", "ACL"));
try
{
if (useProxy)
{
var mode = new Models.Mode
{
Remark = "ProxyUpdate",
Type = 5
};
State = State.Starting;
await MainController.Start(ServerComboBox.SelectedItem as Server, mode);
}
var req = WebUtil.CreateRequest(Global.Settings.ACL);
if (useProxy)
req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, "bin\\default.acl"));
NotifyTip(i18N.Translate("ACL updated successfully"));
}
catch (Exception e)
{
NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false);
Logging.Error("更新 ACL 失败!" + e);
}
finally
{
if (useProxy)
{
await MainController.Stop();
State = State.Stopped;
}
StatusText();
Enabled = true;
}
}
private async void updatePACToolStripMenuItem_Click(object sender, EventArgs eventArgs)
{
Enabled = false;
StatusText(i18N.TranslateFormat("Updating {0}", "PAC"));
try
{
var req = WebUtil.CreateRequest(Global.Settings.PAC);
var pac = Path.Combine(Global.NetchDir, "bin\\pac.txt");
await WebUtil.DownloadFileAsync(req, pac);
NotifyTip(i18N.Translate("PAC updated successfully"));
}
catch (Exception e)
{
NotifyTip(i18N.Translate("PAC update failed") + "\n" + e.Message, info: false);
Logging.Error("更新 PAC 失败!" + e);
}
finally
{
StatusText();
Enabled = true;
}
}
private async void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e)
{
Enabled = false;
StatusText(i18N.TranslateFormat("Uninstalling {0}", "NF Service"));
try
{
await Task.Run(() =>
{
if (NFController.UninstallDriver())
NotifyTip(i18N.TranslateFormat("{0} has been uninstalled", "NF Service"));
});
}
finally
{
StatusText();
Enabled = true;
}
}
private async void UninstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e)
{
Enabled = false;
StatusText(i18N.TranslateFormat("Uninstalling {0}", "TUN/TAP driver"));
try
{
await Task.Run(TUNTAP.deltapall);
NotifyTip(i18N.TranslateFormat("{0} has been uninstalled", "TUN/TAP driver"));
}
catch (Exception exception)
{
Logging.Error($"卸载 TUN/TAP 适配器失败: {exception}");
}
finally
{
StatusText();
Enabled = true;
}
}
#endregion
/// <summary>
/// 菜单栏强制退出
/// </summary>
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Exit(true);
}
private void VersionLabel_Click(object sender, EventArgs e)
{
Utils.Utils.Open($"https://github.com/{UpdateChecker.Owner}/{UpdateChecker.Repo}/releases");
}
private void AboutToolStripButton_Click(object sender, EventArgs e)
{
Hide();
new AboutForm().ShowDialog();
Show();
}
private void fAQToolStripMenuItem_Click(object sender, EventArgs e)
{
Utils.Utils.Open("https://netch.org/#/docs/zh-CN/faq");
}
#endregion
}
}

View File

@@ -1,52 +0,0 @@
using System;
using System.Linq;
using System.Net;
using System.Windows.Forms;
using Netch.Controllers;
using Netch.Utils;
namespace Netch.Forms
{
partial class MainForm
{
private void CheckUpdate()
{
UpdateChecker.NewVersionFound += (_, _) =>
{
NotifyTip($"{i18N.Translate(@"New version available", ": ")}{UpdateChecker.LatestVersionNumber}");
NewVersionLabel.Visible = true;
};
UpdateChecker.Check(Global.Settings.CheckBetaUpdate);
}
private async void NewVersionLabel_Click(object sender, EventArgs e)
{
if (!UpdateChecker.LatestRelease.assets.Any())
{
Utils.Utils.Open(UpdateChecker.LatestVersionUrl);
return;
}
if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK)
return;
NotifyTip(i18N.Translate("Start downloading new version"));
NewVersionLabel.Enabled = false;
NewVersionLabel.Text = "...";
try
{
void OnDownloadProgressChanged(object o1, DownloadProgressChangedEventArgs args)
{
BeginInvoke(new Action(() => { NewVersionLabel.Text = $"{args.ProgressPercentage}%"; }));
}
await UpdateChecker.UpdateNetch(OnDownloadProgressChanged);
}
catch (Exception exception)
{
Logging.Error(exception.Message);
NotifyTip(exception.Message);
}
}
}
}

View File

@@ -1,187 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Netch.Models;
using Netch.Utils;
namespace Netch.Forms
{
public partial class Dummy
{
}
partial class MainForm
{
private int _configurationGroupBoxHeight;
private int _profileConfigurationHeight;
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);
}
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));
}
configLayoutPanel.RowStyles[2].SizeType = SizeType.AutoSize;
ProfileGroupBox.Visible = true;
ConfigurationGroupBox.Size = new Size(ConfigurationGroupBox.Size.Width, _configurationGroupBoxHeight);
}
}
private void LoadProfile(int index)
{
var p = Global.Settings.Profiles[index];
ProfileNameText.Text = p.ProfileName;
ModeComboBox.ResetCompletionList();
if (p.IsDummy)
throw new Exception("Profile not found.");
var server = ServerComboBox.Items.Cast<Server>().FirstOrDefault(s => s.Remark.Equals(p.ServerRemark));
var mode = ModeComboBox.Items.Cast<Models.Mode>().FirstOrDefault(m => m.Remark.Equals(p.ModeRemark));
if (server == null)
{
throw new Exception("Server not found.");
}
if (mode == null)
{
throw new Exception("Mode not found.");
}
ServerComboBox.SelectedItem = server;
ModeComboBox.SelectedItem = mode;
}
private void SaveProfile(int index)
{
var selectedServer = (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 async 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");
return;
}
try
{
LoadProfile(index);
}
catch (Exception exception)
{
MessageBoxX.Show(exception.Message, LogLevel.ERROR);
return;
}
// start the profile
ControlFun();
if (State == State.Stopping || State == State.Stopped)
{
while (State != State.Stopped)
{
await Task.Delay(250);
}
ControlFun();
}
}
}
}

View File

@@ -1,152 +0,0 @@
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Netch.Models;
using Netch.Utils;
namespace Netch.Forms
{
public partial class Dummy
{
}
partial class MainForm
{
/// <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 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
}
}
private void AddAddServerToolStripMenuItems()
{
foreach (var serversUtil in ServerHelper.ServerUtils.Where(i => !string.IsNullOrEmpty(i.FullName)))
{
var fullName = serversUtil.FullName;
var control = new ToolStripMenuItem
{
Name = $"Add{fullName}ServerToolStripMenuItem",
Size = new Size(259, 22),
Text = i18N.TranslateFormat("Add [{0}] Server", fullName)
};
_mainFormText.Add(control.Name, new[] {"Add [{0}] Server", fullName});
control.Click += AddServerToolStripMenuItem_Click;
ServerToolStripMenuItem.DropDownItems.Add(control);
}
}
#region Server
private void InitServer()
{
var comboBoxInitialized = _comboBoxInitialized;
_comboBoxInitialized = false;
ServerComboBox.Items.Clear();
ServerComboBox.Items.AddRange(Global.Settings.Server.ToArray());
SelectLastServer();
_comboBoxInitialized = comboBoxInitialized;
}
public void SelectLastServer()
{
// 如果值合法,选中该位置
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
public void InitMode()
{
var comboBoxInitialized = _comboBoxInitialized;
_comboBoxInitialized = false;
ModeComboBox.Items.Clear();
ModeComboBox.Items.AddRange(Global.Modes.ToArray());
ModeComboBox.Tag = null;
SelectLastMode();
_comboBoxInitialized = comboBoxInitialized;
}
public 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 中没元素,不做处理
}
#endregion
}
}

View File

@@ -1,247 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
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
{
void StartDisableItems(bool enabled)
{
ServerComboBox.Enabled =
ModeComboBox.Enabled =
EditModePictureBox.Enabled =
EditServerPictureBox.Enabled =
DeleteModePictureBox.Enabled =
DeleteServerPictureBox.Enabled = enabled;
// 启动需要禁用的控件
UninstallServiceToolStripMenuItem.Enabled =
UpdateACLToolStripMenuItem.Enabled =
updateACLWithProxyToolStripMenuItem.Enabled =
updatePACToolStripMenuItem.Enabled =
UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
UninstallTapDriverToolStripMenuItem.Enabled =
ReloadModesToolStripMenuItem.Enabled = enabled;
}
_state = value;
ServerHelper.Timer.Enabled = IsWaiting(_state);
StatusText();
switch (value)
{
case State.Waiting:
ControlButton.Enabled = true;
ControlButton.Text = i18N.Translate("Start");
break;
case State.Starting:
ControlButton.Enabled = false;
ControlButton.Text = "...";
ProfileGroupBox.Enabled = false;
StartDisableItems(false);
break;
case State.Started:
ControlButton.Enabled = true;
ControlButton.Text = i18N.Translate("Stop");
StatusTextAppend(StatusPortInfoText.Value);
ProfileGroupBox.Enabled = true;
break;
case State.Stopping:
ControlButton.Enabled = false;
ControlButton.Text = "...";
ProfileGroupBox.Enabled = false;
BandwidthState(false);
NatTypeStatusText();
break;
case State.Stopped:
ControlButton.Enabled = true;
ControlButton.Text = i18N.Translate("Start");
LastUploadBandwidth = 0;
LastDownloadBandwidth = 0;
Bandwidth.Stop();
ProfileGroupBox.Enabled = true;
StartDisableItems(true);
break;
case State.Terminating:
Dispose();
Environment.Exit(Environment.ExitCode);
return;
}
}
}
private bool IsWaiting()
{
return State == State.Waiting || State == State.Stopped;
}
private static bool IsWaiting(State state)
{
return state == State.Waiting || state == State.Stopped;
}
public void BandwidthState(bool state)
{
UsedBandwidthLabel.Visible /*= UploadSpeedLabel.Visible*/ = DownloadSpeedLabel.Visible = state;
}
public void NatTypeStatusText(string text = "", string country = "")
{
if (InvokeRequired)
{
BeginInvoke(new Action<string, string>(NatTypeStatusText), text, country);
return;
}
if (State != State.Started)
{
NatTypeStatusLabel.Text = "";
NatTypeStatusLabel.Visible = NatTypeStatusLightLabel.Visible = false;
return;
}
if (!string.IsNullOrEmpty(text))
{
NatTypeStatusLabel.Text = $"NAT{i18N.Translate(": ")}{text} {(country != string.Empty ? $"[{country}]" : "")}";
UpdateNatTypeLight(int.TryParse(text, out var natType) ? natType : -1);
}
else
{
NatTypeStatusLabel.Text = $@"NAT{i18N.Translate(": ", "Test failed")}";
}
NatTypeStatusLabel.Visible = true;
}
/// <summary>
/// 更新 NAT指示灯颜色
/// </summary>
/// <param name="natType"></param>
private void UpdateNatTypeLight(int natType = -1)
{
if (natType > 0 && natType < 5)
{
NatTypeStatusLightLabel.Visible = Global.Flags.IsWindows10Upper;
Color c;
switch (natType)
{
case 1:
c = Color.LimeGreen;
break;
case 2:
c = Color.Yellow;
break;
case 3:
c = Color.Red;
break;
case 4:
c = Color.Black;
break;
default:
c = Color.Black;
break;
}
NatTypeStatusLightLabel.ForeColor = c;
}
else
{
NatTypeStatusLightLabel.Visible = false;
}
}
/// <summary>
/// 更新状态栏文本
/// </summary>
/// <param name="text"></param>
public void StatusText(string text = null)
{
if (InvokeRequired)
{
BeginInvoke(new Action<string>(StatusText), text);
return;
}
text ??= i18N.Translate(StateExtension.GetStatusString(State));
StatusLabel.Text = i18N.Translate("Status", ": ") + text;
}
public void StatusTextAppend(string text)
{
StatusLabel.Text += text;
}
public static class StatusPortInfoText
{
private static ushort? _socks5Port;
private static ushort? _httpPort;
private static bool _shareLan;
public static ushort HttpPort
{
set => _httpPort = value;
}
public static ushort Socks5Port
{
set => _socks5Port = value;
}
public static string Value
{
get
{
var strings = new List<string>();
if (_socks5Port != null)
strings.Add($"Socks5 {i18N.Translate("Local Port", ": ")}{_socks5Port}");
if (_httpPort != null)
strings.Add($"HTTP {i18N.Translate("Local Port", ": ")}{_httpPort}");
if (!strings.Any())
return string.Empty;
return $" ({(_shareLan ? i18N.Translate("Allow other Devices to connect") + " " : "")}{string.Join(" | ", strings)})";
}
}
public static void UpdateShareLan()
{
_shareLan = Global.Settings.LocalAddress != "127.0.0.1";
}
public static void Reset()
{
_httpPort = _socks5Port = null;
}
}
}
}

File diff suppressed because it is too large Load Diff