diff --git a/.github/issue_template.md b/.github/issue_template.md deleted file mode 100644 index 79efbbc9..00000000 --- a/.github/issue_template.md +++ /dev/null @@ -1,25 +0,0 @@ -在提出问题前请先自行排除服务器端问题和升级到最新客户端,同时也请通过搜索确认是否有人提出过相同问题。 - -### 预期行为 -描述你认为应该发生什么 - -### 实际行为 -描述实际发生了什么 - -### 复现方法 -1. -2. -3. - -### 日志信息,位置在当前目录下的guiLogs -
- -``` -在这里粘贴日志 -``` -
- -### 环境信息(客户端请升级至最新正式版) - -### 额外信息(可选) - diff --git a/.gitignore b/.gitignore deleted file mode 100644 index afeea2ed..00000000 --- a/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -################################################################################ -# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 -################################################################################ - -/v2rayN/.vs/ -/v2rayN/v2rayN/bin/Debug/app.publish -/v2rayN/v2rayN/bin/Debug -/v2rayN/v2rayN/bin/Release -/v2rayN/v2rayN/obj/ -/v2rayN/.vs/v2rayN/DesignTimeBuild -/v2rayN/packages -.vs/ProjectSettings.json -.vs/slnx.sqlite -.vs/VSWorkspaceState.json -/v2rayN/v2rayUpgrade/bin/Debug -/v2rayN/v2rayUpgrade/obj/Debug -/v2rayN/v2rayUpgrade/bin/Release -/v2rayN/v2rayUpgrade/obj/Release \ No newline at end of file diff --git a/v2rayN/v2rayN.sln b/v2rayN/v2rayN.sln index 64cf71f4..fac26a3c 100644 --- a/v2rayN/v2rayN.sln +++ b/v2rayN/v2rayN.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28010.2050 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31321.278 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "v2rayN", "v2rayN\v2rayN.csproj", "{0A9785E6-D256-4B73-9757-4EF59955FD1E}" EndProject @@ -22,6 +22,7 @@ Global {0A9785E6-D256-4B73-9757-4EF59955FD1E}.Release|Any CPU.ActiveCfg = Release|Any CPU {0A9785E6-D256-4B73-9757-4EF59955FD1E}.Release|Any CPU.Build.0 = Release|Any CPU {0A9785E6-D256-4B73-9757-4EF59955FD1E}.Release|x86.ActiveCfg = Release|Any CPU + {0A9785E6-D256-4B73-9757-4EF59955FD1E}.Release|x86.Build.0 = Release|Any CPU {F82BE52A-155C-492C-9E0A-1E917EC62C78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F82BE52A-155C-492C-9E0A-1E917EC62C78}.Debug|Any CPU.Build.0 = Debug|Any CPU {F82BE52A-155C-492C-9E0A-1E917EC62C78}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -35,7 +36,7 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - RESX_SortFileContentOnSave = True SolutionGuid = {56B88873-C9CC-4069-A1E5-DABD6C6E865E} + RESX_SortFileContentOnSave = True EndGlobalSection EndGlobal diff --git a/v2rayN/v2rayN/Forms/MainForm.cs b/v2rayN/v2rayN/Forms/MainForm.cs index 830fff4f..3969c27a 100644 --- a/v2rayN/v2rayN/Forms/MainForm.cs +++ b/v2rayN/v2rayN/Forms/MainForm.cs @@ -1,1484 +1,1484 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Windows.Forms; -using v2rayN.Handler; -using v2rayN.HttpProxyHandler; -using v2rayN.Mode; -using v2rayN.Base; -using v2rayN.Tool; -using System.Diagnostics; -using System.Drawing; -using System.Net; - -namespace v2rayN.Forms -{ - public partial class MainForm : BaseForm - { - private V2rayHandler v2rayHandler; - private List lvSelecteds = new List(); - private StatisticsHandler statistics = null; - private string MsgFilter = string.Empty; - - #region Window 事件 - - public MainForm() - { - InitializeComponent(); - this.ShowInTaskbar = false; - this.WindowState = FormWindowState.Minimized; - HideForm(); - this.Text = Utils.GetVersion(); - Global.processJob = new Job(); - - Application.ApplicationExit += (sender, args) => - { - MyAppExit(false); - }; - } - - private void MainForm_Load(object sender, EventArgs e) - { - ConfigHandler.LoadConfig(ref config); - ConfigHandler.InitBuiltinRouting(ref config); - v2rayHandler = new V2rayHandler(); - v2rayHandler.ProcessEvent += v2rayHandler_ProcessEvent; - - if (config.enableStatistics) - { - statistics = new StatisticsHandler(config, UpdateStatisticsHandler); - } - } - - private void MainForm_VisibleChanged(object sender, EventArgs e) - { - if (statistics == null || !statistics.Enable) return; - if ((sender as Form).Visible) - { - statistics.UpdateUI = true; - } - else - { - statistics.UpdateUI = false; - } - } - - private void MainForm_Shown(object sender, EventArgs e) - { - InitServersView(); - RefreshServers(); - RefreshRoutingsMenu(); - RestoreUI(); - - LoadV2ray(); - - HideForm(); - - } - - private void MainForm_FormClosing(object sender, FormClosingEventArgs e) - { - switch (e.CloseReason) - { - case CloseReason.UserClosing: - StorageUI(); - e.Cancel = true; - HideForm(); - break; - case CloseReason.ApplicationExitCall: - case CloseReason.FormOwnerClosing: - case CloseReason.TaskManagerClosing: - MyAppExit(false); - break; - case CloseReason.WindowsShutDown: - MyAppExit(true); - break; - } - } - - private void MainForm_Resize(object sender, EventArgs e) - { - //if (this.WindowState == FormWindowState.Minimized) - //{ - // HideForm(); - //} - //else - //{ - - //} - } - private void MyAppExit(bool blWindowsShutDown) - { - try - { - v2rayHandler.V2rayStop(); - - //HttpProxyHandle.CloseHttpAgent(config); - if (blWindowsShutDown) - { - HttpProxyHandle.ResetIEProxy4WindowsShutDown(); - } - else - { - HttpProxyHandle.UpdateSysProxy(config, true); - } - - ConfigHandler.SaveConfig(ref config); - statistics?.SaveToFile(); - statistics?.Close(); - } - catch { } - } - - private void RestoreUI() - { - scMain.Panel2Collapsed = true; - - if (!config.uiItem.mainSize.IsEmpty) - { - this.Width = config.uiItem.mainSize.Width; - this.Height = config.uiItem.mainSize.Height; - } - - for (int k = 0; k < lvServers.Columns.Count; k++) - { - var width = ConfigHandler.GetformMainLvColWidth(ref config, ((EServerColName)k).ToString(), lvServers.Columns[k].Width); - lvServers.Columns[k].Width = width; - } - } - - private void StorageUI() - { - config.uiItem.mainSize = new Size(this.Width, this.Height); - - for (int k = 0; k < lvServers.Columns.Count; k++) - { - ConfigHandler.AddformMainLvColWidth(ref config, ((EServerColName)k).ToString(), lvServers.Columns[k].Width); - } - } - - #endregion - - #region 显示服务器 listview 和 menu - - /// - /// 刷新服务器 - /// - private void RefreshServers() - { - RefreshServersView(); - //lvServers.AutoResizeColumns(); - RefreshServersMenu(); - } - - /// - /// 初始化服务器列表 - /// - private void InitServersView() - { - lvServers.BeginUpdate(); - lvServers.Items.Clear(); - - lvServers.GridLines = true; - lvServers.FullRowSelect = true; - lvServers.View = View.Details; - lvServers.Scrollable = true; - lvServers.MultiSelect = true; - lvServers.HeaderStyle = ColumnHeaderStyle.Clickable; - - lvServers.Columns.Add("", 30); - lvServers.Columns.Add(UIRes.I18N("LvServiceType"), 80); - lvServers.Columns.Add(UIRes.I18N("LvAlias"), 100); - lvServers.Columns.Add(UIRes.I18N("LvAddress"), 120); - lvServers.Columns.Add(UIRes.I18N("LvPort"), 50); - lvServers.Columns.Add(UIRes.I18N("LvEncryptionMethod"), 90); - lvServers.Columns.Add(UIRes.I18N("LvTransportProtocol"), 70); - lvServers.Columns.Add(UIRes.I18N("LvSubscription"), 50); - lvServers.Columns.Add(UIRes.I18N("LvTestResults"), 70, HorizontalAlignment.Right); - - if (statistics != null && statistics.Enable) - { - lvServers.Columns.Add(UIRes.I18N("LvTodayDownloadDataAmount"), 70); - lvServers.Columns.Add(UIRes.I18N("LvTodayUploadDataAmount"), 70); - lvServers.Columns.Add(UIRes.I18N("LvTotalDownloadDataAmount"), 70); - lvServers.Columns.Add(UIRes.I18N("LvTotalUploadDataAmount"), 70); - } - lvServers.EndUpdate(); - } - - /// - /// 刷新服务器列表 - /// - private void RefreshServersView() - { - int index = lvServers.SelectedIndices.Count > 0 ? lvServers.SelectedIndices[0] : -1; - - lvServers.BeginUpdate(); - lvServers.Items.Clear(); - - for (int k = 0; k < config.vmess.Count; k++) - { - string def = string.Empty; - string totalUp = string.Empty, - totalDown = string.Empty, - todayUp = string.Empty, - todayDown = string.Empty; - if (config.index.Equals(k)) - { - def = "√"; - } - - VmessItem item = config.vmess[k]; - - bool stats = statistics != null && statistics.Enable; - if (stats) - { - ServerStatItem sItem = statistics.Statistic.Find(item_ => item_.itemId == item.getItemId()); - if (sItem != null) - { - totalUp = Utils.HumanFy(sItem.totalUp); - totalDown = Utils.HumanFy(sItem.totalDown); - todayUp = Utils.HumanFy(sItem.todayUp); - todayDown = Utils.HumanFy(sItem.todayDown); - } - } - ListViewItem lvItem = new ListViewItem(def); - Utils.AddSubItem(lvItem, EServerColName.configType.ToString(), ((EConfigType)item.configType).ToString()); - Utils.AddSubItem(lvItem, EServerColName.remarks.ToString(), item.remarks); - Utils.AddSubItem(lvItem, EServerColName.address.ToString(), item.address); - Utils.AddSubItem(lvItem, EServerColName.port.ToString(), item.port.ToString()); - Utils.AddSubItem(lvItem, EServerColName.security.ToString(), item.security); - Utils.AddSubItem(lvItem, EServerColName.network.ToString(), item.network); - Utils.AddSubItem(lvItem, EServerColName.subRemarks.ToString(), item.getSubRemarks(config)); - Utils.AddSubItem(lvItem, EServerColName.testResult.ToString(), item.testResult); - if (stats) - { - Utils.AddSubItem(lvItem, EServerColName.todayDown.ToString(), todayDown); - Utils.AddSubItem(lvItem, EServerColName.todayUp.ToString(), todayUp); - Utils.AddSubItem(lvItem, EServerColName.totalDown.ToString(), totalDown); - Utils.AddSubItem(lvItem, EServerColName.totalUp.ToString(), totalUp); - } - - if (k % 2 == 1) // 隔行着色 - { - lvItem.BackColor = Color.WhiteSmoke; - } - if (config.index.Equals(k)) - { - //lvItem.Checked = true; - lvItem.ForeColor = Color.DodgerBlue; - lvItem.Font = new Font(lvItem.Font, FontStyle.Bold); - } - - if (lvItem != null) lvServers.Items.Add(lvItem); - } - lvServers.EndUpdate(); - - if (index >= 0 && index < lvServers.Items.Count && lvServers.Items.Count > 0) - { - lvServers.Items[index].Selected = true; - lvServers.EnsureVisible(index); // workaround - } - } - - /// - /// 刷新托盘服务器菜单 - /// - private void RefreshServersMenu() - { - menuServers.DropDownItems.Clear(); - - List lst = new List(); - for (int k = 0; k < config.vmess.Count; k++) - { - VmessItem item = config.vmess[k]; - string name = item.getSummary(); - - ToolStripMenuItem ts = new ToolStripMenuItem(name) - { - Tag = k - }; - if (config.index.Equals(k)) - { - ts.Checked = true; - } - ts.Click += new EventHandler(ts_Click); - lst.Add(ts); - } - menuServers.DropDownItems.AddRange(lst.ToArray()); - } - - private void ts_Click(object sender, EventArgs e) - { - try - { - ToolStripItem ts = (ToolStripItem)sender; - int index = Utils.ToInt(ts.Tag); - SetDefaultServer(index); - } - catch - { - } - } - - private void lvServers_SelectedIndexChanged(object sender, EventArgs e) - { - int index = -1; - try - { - if (lvServers.SelectedIndices.Count > 0) - { - index = lvServers.SelectedIndices[0]; - } - } - catch - { - } - if (index < 0) - { - return; - } - //qrCodeControl.showQRCode(index, config); - } - - private void DisplayToolStatus() - { - toolSslSocksPort.Text = $"{Global.Loopback}:{config.inbound[0].localPort}"; - toolSslHttpPort.Text = $"{Global.Loopback}:{Global.httpPort}"; - - notifyMain.Icon = MainFormHandler.Instance.GetNotifyIcon(config, this.Icon); - } - private void ssMain_ItemClicked(object sender, ToolStripItemClickedEventArgs e) - { - if (!Utils.IsNullOrEmpty(e.ClickedItem.Text)) - { - Utils.SetClipboardData(e.ClickedItem.Text); - } - } - - private void lvServers_ColumnClick(object sender, ColumnClickEventArgs e) - { - if (e.Column < 0) - { - return; - } - - try - { - var tag = lvServers.Columns[e.Column].Tag?.ToString(); - bool asc = Utils.IsNullOrEmpty(tag) ? true : !Convert.ToBoolean(tag); - if (ConfigHandler.SortServers(ref config, (EServerColName)e.Column, asc) != 0) - { - return; - } - lvServers.Columns[e.Column].Tag = Convert.ToString(asc); - RefreshServers(); - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - - if (e.Column < 0) - { - return; - } - - } - #endregion - - #region v2ray 操作 - - /// - /// 载入V2ray - /// - private void LoadV2ray() - { - tsbReload.Enabled = false; - - if (Global.reloadV2ray) - { - ClearMsg(); - } - v2rayHandler.LoadV2ray(config); - Global.reloadV2ray = false; - ConfigHandler.SaveConfig(ref config, false); - statistics?.SaveToFile(); - - ChangePACButtonStatus(config.sysProxyType); - - tsbReload.Enabled = true; - } - - /// - /// 关闭V2ray - /// - private void CloseV2ray() - { - ConfigHandler.SaveConfig(ref config, false); - statistics?.SaveToFile(); - - ChangePACButtonStatus(0); - - v2rayHandler.V2rayStop(); - } - - #endregion - - #region 功能按钮 - - private void lvServers_Click(object sender, EventArgs e) - { - int index = -1; - try - { - if (lvServers.SelectedIndices.Count > 0) - { - index = lvServers.SelectedIndices[0]; - } - } - catch - { - } - if (index < 0) - { - return; - } - qrCodeControl.showQRCode(index, config); - } - - private void lvServers_DoubleClick(object sender, EventArgs e) - { - int index = GetLvSelectedIndex(); - if (index < 0) - { - return; - } - ShowServerForm(config.vmess[index].configType, index); - } - private void ShowServerForm(int configType, int index) - { - BaseServerForm fm; - switch (configType) - { - case (int)EConfigType.Vmess: - fm = new AddServerForm(); - break; - case (int)EConfigType.Shadowsocks: - fm = new AddServer3Form(); - break; - case (int)EConfigType.Socks: - fm = new AddServer4Form(); - break; - case (int)EConfigType.VLESS: - fm = new AddServer5Form(); - break; - case (int)EConfigType.Trojan: - fm = new AddServer6Form(); - break; - default: - fm = new AddServer2Form(); - break; - } - fm.EditIndex = index; - if (fm.ShowDialog() == DialogResult.OK) - { - RefreshServers(); - LoadV2ray(); - } - } - - - private void lvServers_KeyDown(object sender, KeyEventArgs e) - { - if (e.Control) - { - switch (e.KeyCode) - { - case Keys.A: - menuSelectAll_Click(null, null); - break; - case Keys.C: - menuExport2ShareUrl_Click(null, null); - break; - case Keys.V: - menuAddServers_Click(null, null); - break; - case Keys.P: - menuPingServer_Click(null, null); - break; - case Keys.O: - menuTcpingServer_Click(null, null); - break; - case Keys.R: - menuRealPingServer_Click(null, null); - break; - case Keys.S: - menuScanScreen_Click(null, null); - break; - case Keys.T: - menuSpeedServer_Click(null, null); - break; - } - } - else - { - switch (e.KeyCode) - { - case Keys.Enter: - menuSetDefaultServer_Click(null, null); - break; - case Keys.Delete: - menuRemoveServer_Click(null, null); - break; - case Keys.T: - menuMoveTop_Click(null, null); - break; - case Keys.B: - menuMoveBottom_Click(null, null); - break; - case Keys.U: - menuMoveUp_Click(null, null); - break; - case Keys.D: - menuMoveDown_Click(null, null); - break; - } - } - } - - private void menuAddVmessServer_Click(object sender, EventArgs e) - { - ShowServerForm((int)EConfigType.Vmess, -1); - } - - private void menuAddVlessServer_Click(object sender, EventArgs e) - { - ShowServerForm((int)EConfigType.VLESS, -1); - } - - private void menuRemoveServer_Click(object sender, EventArgs e) - { - - int index = GetLvSelectedIndex(); - if (index < 0) - { - return; - } - if (UI.ShowYesNo(UIRes.I18N("RemoveServer")) == DialogResult.No) - { - return; - } - for (int k = lvSelecteds.Count - 1; k >= 0; k--) - { - ConfigHandler.RemoveServer(ref config, lvSelecteds[k]); - } - RefreshServers(); - LoadV2ray(); - - } - - private void menuRemoveDuplicateServer_Click(object sender, EventArgs e) - { - Utils.DedupServerList(config.vmess, out List servers, config.keepOlderDedupl); - int oldCount = config.vmess.Count; - int newCount = servers.Count; - if (servers != null) - { - config.vmess = servers; - } - RefreshServers(); - LoadV2ray(); - UI.Show(string.Format(UIRes.I18N("RemoveDuplicateServerResult"), oldCount, newCount)); - } - - private void menuCopyServer_Click(object sender, EventArgs e) - { - int index = GetLvSelectedIndex(); - if (index < 0) - { - return; - } - if (ConfigHandler.CopyServer(ref config, index) == 0) - { - RefreshServers(); - } - } - - private void menuSetDefaultServer_Click(object sender, EventArgs e) - { - int index = GetLvSelectedIndex(); - if (index < 0) - { - return; - } - SetDefaultServer(index); - } - - - private void menuPingServer_Click(object sender, EventArgs e) - { - Speedtest("ping"); - } - private void menuTcpingServer_Click(object sender, EventArgs e) - { - Speedtest("tcping"); - } - - private void menuRealPingServer_Click(object sender, EventArgs e) - { - //if (!config.sysAgentEnabled) - //{ - // UI.Show(UIRes.I18N("NeedHttpGlobalProxy")); - // return; - //} - - //UI.Show(UIRes.I18N("SpeedServerTips")); - - Speedtest("realping"); - } - - private void menuSpeedServer_Click(object sender, EventArgs e) - { - //if (!config.sysAgentEnabled) - //{ - // UI.Show(UIRes.I18N("NeedHttpGlobalProxy")); - // return; - //} - - //UI.Show(UIRes.I18N("SpeedServerTips")); - - Speedtest("speedtest"); - } - private void Speedtest(string actionType) - { - if (GetLvSelectedIndex() < 0) return; - ClearTestResult(); - SpeedtestHandler statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, actionType, UpdateSpeedtestHandler); - } - - private void tsbTestMe_Click(object sender, EventArgs e) - { - SpeedtestHandler statistics = new SpeedtestHandler(ref config); - string result = statistics.RunAvailabilityCheck() + "ms"; - AppendText(false, string.Format(UIRes.I18N("TestMeOutput"), result)); - } - - private void menuClearStatistic_Click(object sender, EventArgs e) - { - if (statistics != null) - { - statistics.ClearAllServerStatistics(); - } - } - - private void menuExport2ClientConfig_Click(object sender, EventArgs e) - { - int index = GetLvSelectedIndex(); - MainFormHandler.Instance.Export2ClientConfig(index, config); - } - - private void menuExport2ServerConfig_Click(object sender, EventArgs e) - { - int index = GetLvSelectedIndex(); - MainFormHandler.Instance.Export2ServerConfig(index, config); - } - - private void menuExport2ShareUrl_Click(object sender, EventArgs e) - { - GetLvSelectedIndex(); - - StringBuilder sb = new StringBuilder(); - foreach (int v in lvSelecteds) - { - string url = ShareHandler.GetShareUrl(config, v); - if (Utils.IsNullOrEmpty(url)) - { - continue; - } - sb.Append(url); - sb.AppendLine(); - } - if (sb.Length > 0) - { - Utils.SetClipboardData(sb.ToString()); - AppendText(false, UIRes.I18N("BatchExportURLSuccessfully")); - //UI.Show(UIRes.I18N("BatchExportURLSuccessfully")); - } - } - - private void menuExport2SubContent_Click(object sender, EventArgs e) - { - GetLvSelectedIndex(); - - StringBuilder sb = new StringBuilder(); - foreach (int v in lvSelecteds) - { - string url = ShareHandler.GetShareUrl(config, v); - if (Utils.IsNullOrEmpty(url)) - { - continue; - } - sb.Append(url); - sb.AppendLine(); - } - if (sb.Length > 0) - { - Utils.SetClipboardData(Utils.Base64Encode(sb.ToString())); - UI.Show(UIRes.I18N("BatchExportSubscriptionSuccessfully")); - } - } - - private void tsbOptionSetting_Click(object sender, EventArgs e) - { - OptionSettingForm fm = new OptionSettingForm(); - if (fm.ShowDialog() == DialogResult.OK) - { - RefreshServers(); - LoadV2ray(); - } - } - - private void tsbRoutingSetting_Click(object sender, EventArgs e) - { - var fm = new RoutingSettingForm(); - if (fm.ShowDialog() == DialogResult.OK) - { - RefreshRoutingsMenu(); - RefreshServers(); - LoadV2ray(); - } - } - - private void tsbReload_Click(object sender, EventArgs e) - { - Global.reloadV2ray = true; - LoadV2ray(); - } - - private void tsbClose_Click(object sender, EventArgs e) - { - HideForm(); - //this.WindowState = FormWindowState.Minimized; - } - - /// - /// 设置活动服务器 - /// - /// - /// - private int SetDefaultServer(int index) - { - if (index < 0) - { - UI.Show(UIRes.I18N("PleaseSelectServer")); - return -1; - } - if (ConfigHandler.SetDefaultServer(ref config, index) == 0) - { - RefreshServers(); - LoadV2ray(); - } - return 0; - } - - /// - /// 取得ListView选中的行 - /// - /// - private int GetLvSelectedIndex() - { - int index = -1; - lvSelecteds.Clear(); - try - { - if (lvServers.SelectedIndices.Count <= 0) - { - UI.Show(UIRes.I18N("PleaseSelectServer")); - return index; - } - - index = lvServers.SelectedIndices[0]; - foreach (int i in lvServers.SelectedIndices) - { - lvSelecteds.Add(i); - } - return index; - } - catch - { - return index; - } - } - - private void menuAddCustomServer_Click(object sender, EventArgs e) - { - UI.Show(UIRes.I18N("CustomServerTips")); - - OpenFileDialog fileDialog = new OpenFileDialog - { - Multiselect = false, - Filter = "Config|*.json|All|*.*" - }; - if (fileDialog.ShowDialog() != DialogResult.OK) - { - return; - } - string fileName = fileDialog.FileName; - if (Utils.IsNullOrEmpty(fileName)) - { - return; - } - - if (ConfigHandler.AddCustomServer(ref config, fileName) == 0) - { - RefreshServers(); - //LoadV2ray(); - UI.Show(UIRes.I18N("SuccessfullyImportedCustomServer")); - } - else - { - UI.ShowWarning(UIRes.I18N("FailedImportedCustomServer")); - } - } - - private void menuAddShadowsocksServer_Click(object sender, EventArgs e) - { - ShowServerForm((int)EConfigType.Shadowsocks, -1); - ShowForm(); - } - - private void menuAddSocksServer_Click(object sender, EventArgs e) - { - ShowServerForm((int)EConfigType.Socks, -1); - ShowForm(); - } - - private void menuAddTrojanServer_Click(object sender, EventArgs e) - { - ShowServerForm((int)EConfigType.Trojan, -1); - ShowForm(); - } - - private void menuAddServers_Click(object sender, EventArgs e) - { - string clipboardData = Utils.GetClipboardData(); - int ret = MainFormHandler.Instance.AddBatchServers(config, clipboardData); - if (ret > 0) - { - RefreshServers(); - UI.Show(string.Format(UIRes.I18N("SuccessfullyImportedServerViaClipboard"), ret)); - } - } - - private void menuScanScreen_Click(object sender, EventArgs e) - { - HideForm(); - bgwScan.RunWorkerAsync(); - } - - private void menuUpdateSubscriptions_Click(object sender, EventArgs e) - { - UpdateSubscriptionProcess(); - } - - private void tsbBackupGuiNConfig_Click(object sender, EventArgs e) - { - MainFormHandler.Instance.BackupGuiNConfig(config); - } - #endregion - - - #region 提示信息 - - /// - /// 消息委托 - /// - /// - /// - void v2rayHandler_ProcessEvent(bool notify, string msg) - { - AppendText(notify, msg); - } - - delegate void AppendTextDelegate(string text); - void AppendText(bool notify, string msg) - { - try - { - AppendText(msg); - if (notify) - { - notifyMsg(msg); - } - } - catch - { - } - } - - void AppendText(string text) - { - if (this.txtMsgBox.InvokeRequired) - { - Invoke(new AppendTextDelegate(AppendText), new object[] { text }); - } - else - { - if (!Utils.IsNullOrEmpty(MsgFilter)) - { - if (!text.Contains(MsgFilter)) - { - return; - } - } - //this.txtMsgBox.AppendText(text); - ShowMsg(text); - } - } - - /// - /// 提示信息 - /// - /// - private void ShowMsg(string msg) - { - if (txtMsgBox.Lines.Length > 999) - { - ClearMsg(); - } - this.txtMsgBox.AppendText(msg); - if (!msg.EndsWith(Environment.NewLine)) - { - this.txtMsgBox.AppendText(Environment.NewLine); - } - } - - /// - /// 清除信息 - /// - private void ClearMsg() - { - this.txtMsgBox.Clear(); - } - - /// - /// 托盘信息 - /// - /// - private void notifyMsg(string msg) - { - notifyMain.Text = msg; - } - - #endregion - - - #region 托盘事件 - - private void notifyMain_MouseClick(object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Left) - { - ShowForm(); - } - } - - private void menuExit_Click(object sender, EventArgs e) - { - this.Visible = false; - this.Close(); - - Application.Exit(); - } - - - private void ShowForm() - { - this.Show(); - this.WindowState = FormWindowState.Normal; - this.Activate(); - this.ShowInTaskbar = true; - //this.notifyIcon1.Visible = false; - this.txtMsgBox.ScrollToCaret(); - //if (config.index >= 0 && config.index < lvServers.Items.Count) - //{ - // lvServers.Items[config.index].Selected = true; - // lvServers.EnsureVisible(config.index); // workaround - //} - - SetVisibleCore(true); - } - - private void HideForm() - { - //this.WindowState = FormWindowState.Minimized; - this.Hide(); - //this.notifyMain.Icon = this.Icon; - this.notifyMain.Visible = true; - this.ShowInTaskbar = false; - - SetVisibleCore(false); - } - - #endregion - - #region 后台测速 - - private void SetTestResult(int k, string txt) - { - if (k < lvServers.Items.Count) - { - config.vmess[k].testResult = txt; - lvServers.Items[k].SubItems["testResult"].Text = txt; - } - } - private void ClearTestResult() - { - foreach (int s in lvSelecteds) - { - SetTestResult(s, ""); - } - } - private void UpdateSpeedtestHandler(int index, string msg) - { - lvServers.Invoke((MethodInvoker)delegate - { - SetTestResult(index, msg); - }); - } - - private void UpdateStatisticsHandler(ulong up, ulong down, List statistics) - { - try - { - up /= (ulong)(config.statisticsFreshRate / 1000f); - down /= (ulong)(config.statisticsFreshRate / 1000f); - toolSslServerSpeed.Text = string.Format("{0}/s↑ | {1}/s↓", Utils.HumanFy(up), Utils.HumanFy(down)); - - List datas = new List(); - for (int i = 0; i < config.vmess.Count; i++) - { - int index = statistics.FindIndex(item_ => item_.itemId == config.vmess[i].getItemId()); - if (index != -1) - { - lvServers.Invoke((MethodInvoker)delegate - { - lvServers.BeginUpdate(); - - lvServers.Items[i].SubItems["todayDown"].Text = Utils.HumanFy(statistics[index].todayDown); - lvServers.Items[i].SubItems["todayUp"].Text = Utils.HumanFy(statistics[index].todayUp); - lvServers.Items[i].SubItems["totalDown"].Text = Utils.HumanFy(statistics[index].totalDown); - lvServers.Items[i].SubItems["totalUp"].Text = Utils.HumanFy(statistics[index].totalUp); - - lvServers.EndUpdate(); - }); - } - } - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - } - - #endregion - - #region 移动服务器 - - private void menuMoveTop_Click(object sender, EventArgs e) - { - MoveServer(EMove.Top); - } - - private void menuMoveUp_Click(object sender, EventArgs e) - { - MoveServer(EMove.Up); - } - - private void menuMoveDown_Click(object sender, EventArgs e) - { - MoveServer(EMove.Down); - } - - private void menuMoveBottom_Click(object sender, EventArgs e) - { - MoveServer(EMove.Bottom); - } - - private void MoveServer(EMove eMove) - { - int index = GetLvSelectedIndex(); - if (index < 0) - { - UI.Show(UIRes.I18N("PleaseSelectServer")); - return; - } - if (ConfigHandler.MoveServer(ref config, index, eMove) == 0) - { - //TODO: reload is not good. - RefreshServers(); - //LoadV2ray(); - } - } - private void menuSelectAll_Click(object sender, EventArgs e) - { - foreach (ListViewItem item in lvServers.Items) - { - item.Selected = true; - } - } - - #endregion - - #region 系统代理相关 - private void menuKeepClear_Click(object sender, EventArgs e) - { - SetListenerType(ESysProxyType.ForcedClear); - } - private void menuGlobal_Click(object sender, EventArgs e) - { - SetListenerType(ESysProxyType.ForcedChange); - } - - private void menuKeepNothing_Click(object sender, EventArgs e) - { - SetListenerType(ESysProxyType.Unchanged); - } - private void SetListenerType(ESysProxyType type) - { - config.sysProxyType = type; - ChangePACButtonStatus(type); - } - - private void ChangePACButtonStatus(ESysProxyType type) - { - HttpProxyHandle.UpdateSysProxy(config, false); - //if (type != ListenerType.noHttpProxy) - //{ - // HttpProxyHandle.RestartHttpAgent(config, false); - //} - //else - //{ - // HttpProxyHandle.CloseHttpAgent(config); - //} - - for (int k = 0; k < menuSysAgentMode.DropDownItems.Count; k++) - { - ToolStripMenuItem item = ((ToolStripMenuItem)menuSysAgentMode.DropDownItems[k]); - item.Checked = ((int)type == k); - } - - ConfigHandler.SaveConfig(ref config, false); - DisplayToolStatus(); - } - - #endregion - - - #region CheckUpdate - - private void tsbCheckUpdateN_Click(object sender, EventArgs e) - { - void _updateUI(bool success, string msg) - { - AppendText(false, msg); - if (success) - { - menuExit_Click(null, null); - } - }; - (new UpdateHandle()).CheckUpdateGuiN(config, _updateUI); - } - - private void tsbCheckUpdateCore_Click(object sender, EventArgs e) - { - CheckUpdateCore("v2fly"); - } - - private void tsbCheckUpdateXrayCore_Click(object sender, EventArgs e) - { - CheckUpdateCore("xray"); - } - - private void CheckUpdateCore(string type) - { - void _updateUI(bool success, string msg) - { - AppendText(false, msg); - if (success) - { - CloseV2ray(); - - string fileName = Global.DownloadFileName; - fileName = Utils.GetPath(fileName); - FileManager.ZipExtractToFile(fileName, config.ignoreGeoUpdateCore ? "geo" : ""); - - AppendText(false, UIRes.I18N("MsgUpdateV2rayCoreSuccessfullyMore")); - - Global.reloadV2ray = true; - LoadV2ray(); - - AppendText(false, UIRes.I18N("MsgUpdateV2rayCoreSuccessfully")); - } - }; - (new UpdateHandle()).CheckUpdateCore(type, config, _updateUI); - } - - private void tsbCheckUpdateGeoSite_Click(object sender, EventArgs e) - { - (new UpdateHandle()).UpdateGeoFile("geosite", config, (bool success, string msg) => - { - AppendText(false, msg); - if (success) - { - Global.reloadV2ray = true; - LoadV2ray(); - } - }); - } - - private void tsbCheckUpdateGeoIP_Click(object sender, EventArgs e) - { - (new UpdateHandle()).UpdateGeoFile("geoip", config, (bool success, string msg) => - { - AppendText(false, msg); - if (success) - { - Global.reloadV2ray = true; - LoadV2ray(); - } - }); - } - #endregion - - #region Help - - - private void tsbAbout_Click(object sender, EventArgs e) - { - Process.Start(Global.AboutUrl); - } - - private void tsbV2rayWebsite_Click(object sender, EventArgs e) - { - Process.Start(Global.v2rayWebsiteUrl); - } - - private void tsbPromotion_Click(object sender, EventArgs e) - { - Process.Start($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}"); - } - #endregion - - #region ScanScreen - - - private void bgwScan_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) - { - string ret = Utils.ScanScreen(); - bgwScan.ReportProgress(0, ret); - } - - private void bgwScan_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) - { - ShowForm(); - - string result = Convert.ToString(e.UserState); - if (Utils.IsNullOrEmpty(result)) - { - UI.ShowWarning(UIRes.I18N("NoValidQRcodeFound")); - } - else - { - int ret = MainFormHandler.Instance.AddBatchServers(config, result); - if (ret > 0) - { - RefreshServers(); - UI.Show(UIRes.I18N("SuccessfullyImportedServerViaScan")); - } - } - } - - #endregion - - #region 订阅 - private void tsbSubSetting_Click(object sender, EventArgs e) - { - SubSettingForm fm = new SubSettingForm(); - if (fm.ShowDialog() == DialogResult.OK) - { - RefreshServers(); - } - } - - private void tsbSubUpdate_Click(object sender, EventArgs e) - { - UpdateSubscriptionProcess(); - } - - /// - /// the subscription update process - /// - private void UpdateSubscriptionProcess() - { - void _updateUI(bool success, string msg) - { - AppendText(false, msg); - if (success) - { - RefreshServers(); - } - }; - - (new UpdateHandle()).UpdateSubscriptionProcess(config, _updateUI); - } - - private void tsbQRCodeSwitch_CheckedChanged(object sender, EventArgs e) - { - bool bShow = tsbQRCodeSwitch.Checked; - scMain.Panel2Collapsed = !bShow; - } - #endregion - - #region Language - - private void tsbLanguageDef_Click(object sender, EventArgs e) - { - SetCurrentLanguage("en"); - } - - private void tsbLanguageZhHans_Click(object sender, EventArgs e) - { - SetCurrentLanguage("zh-Hans"); - } - private void SetCurrentLanguage(string value) - { - Utils.RegWriteValue(Global.MyRegPath, Global.MyRegKeyLanguage, value); - //Application.Restart(); - } - - - - - - #endregion - - - #region RoutingsMenu - - /// - /// - /// - private void RefreshRoutingsMenu() - { - menuRoutings.Visible = config.enableRoutingAdvanced; - if (!config.enableRoutingAdvanced) - { - return; - } - - menuRoutings.DropDownItems.Clear(); - - List lst = new List(); - for (int k = 0; k < config.routings.Count; k++) - { - var item = config.routings[k]; - if (item.locked == true) - { - continue; - } - string name = item.remarks; - - ToolStripMenuItem ts = new ToolStripMenuItem(name) - { - Tag = k - }; - if (config.routingIndex.Equals(k)) - { - ts.Checked = true; - } - ts.Click += new EventHandler(ts_Routing_Click); - lst.Add(ts); - } - menuRoutings.DropDownItems.AddRange(lst.ToArray()); - } - - private void ts_Routing_Click(object sender, EventArgs e) - { - try - { - ToolStripItem ts = (ToolStripItem)sender; - int index = Utils.ToInt(ts.Tag); - - if (ConfigHandler.SetDefaultRouting(ref config, index) == 0) - { - RefreshRoutingsMenu(); - LoadV2ray(); - } - } - catch - { - } - } - #endregion - - #region MsgBoxMenu - private void menuMsgBoxSelectAll_Click(object sender, EventArgs e) - { - this.txtMsgBox.Focus(); - this.txtMsgBox.SelectAll(); - } - - private void menuMsgBoxCopy_Click(object sender, EventArgs e) - { - var data = this.txtMsgBox.SelectedText.TrimEx(); - Utils.SetClipboardData(data); - } - - private void menuMsgBoxCopyAll_Click(object sender, EventArgs e) - { - var data = this.txtMsgBox.Text; - Utils.SetClipboardData(data); - } - private void menuMsgBoxAddRoutingRule_Click(object sender, EventArgs e) - { - menuMsgBoxCopy_Click(null, null); - tsbRoutingSetting_Click(null, null); - } - - private void txtMsgBox_KeyDown(object sender, KeyEventArgs e) - { - if (e.Control) - { - switch (e.KeyCode) - { - case Keys.A: - menuMsgBoxSelectAll_Click(null, null); - break; - case Keys.C: - menuMsgBoxCopy_Click(null, null); - break; - case Keys.V: - menuMsgBoxAddRoutingRule_Click(null, null); - break; - - } - } - - } - private void menuMsgBoxFilter_Click(object sender, EventArgs e) - { - var fm = new MsgFilterSetForm(); - fm.MsgFilter = MsgFilter; - if (fm.ShowDialog() == DialogResult.OK) - { - MsgFilter = fm.MsgFilter; - gbMsgTitle.Text = string.Format(UIRes.I18N("MsgInformationTitle"), MsgFilter); - } - } - #endregion - - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Windows.Forms; +using v2rayN.Handler; +using v2rayN.HttpProxyHandler; +using v2rayN.Mode; +using v2rayN.Base; +using v2rayN.Tool; +using System.Diagnostics; +using System.Drawing; +using System.Net; + +namespace v2rayN.Forms +{ + public partial class MainForm : BaseForm + { + private V2rayHandler v2rayHandler; + private List lvSelecteds = new List(); + private StatisticsHandler statistics = null; + private string MsgFilter = string.Empty; + + #region Window 事件 + + public MainForm() + { + InitializeComponent(); + this.ShowInTaskbar = false; + this.WindowState = FormWindowState.Minimized; + HideForm(); + this.Text = Utils.GetVersion(); + Global.processJob = new Job(); + + Application.ApplicationExit += (sender, args) => + { + MyAppExit(false); + }; + } + + private void MainForm_Load(object sender, EventArgs e) + { + ConfigHandler.LoadConfig(ref config); + ConfigHandler.InitBuiltinRouting(ref config); + v2rayHandler = new V2rayHandler(); + v2rayHandler.ProcessEvent += v2rayHandler_ProcessEvent; + + if (config.enableStatistics) + { + statistics = new StatisticsHandler(config, UpdateStatisticsHandler); + } + } + + private void MainForm_VisibleChanged(object sender, EventArgs e) + { + if (statistics == null || !statistics.Enable) return; + if ((sender as Form).Visible) + { + statistics.UpdateUI = true; + } + else + { + statistics.UpdateUI = false; + } + } + + private void MainForm_Shown(object sender, EventArgs e) + { + InitServersView(); + RefreshServers(); + RefreshRoutingsMenu(); + RestoreUI(); + + LoadV2ray(); + + HideForm(); + + } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + switch (e.CloseReason) + { + case CloseReason.UserClosing: + StorageUI(); + e.Cancel = true; + HideForm(); + break; + case CloseReason.ApplicationExitCall: + case CloseReason.FormOwnerClosing: + case CloseReason.TaskManagerClosing: + MyAppExit(false); + break; + case CloseReason.WindowsShutDown: + MyAppExit(true); + break; + } + } + + private void MainForm_Resize(object sender, EventArgs e) + { + //if (this.WindowState == FormWindowState.Minimized) + //{ + // HideForm(); + //} + //else + //{ + + //} + } + private void MyAppExit(bool blWindowsShutDown) + { + try + { + v2rayHandler.V2rayStop(); + + //HttpProxyHandle.CloseHttpAgent(config); + if (blWindowsShutDown) + { + HttpProxyHandle.ResetIEProxy4WindowsShutDown(); + } + else + { + HttpProxyHandle.UpdateSysProxy(config, true); + } + + ConfigHandler.SaveConfig(ref config); + statistics?.SaveToFile(); + statistics?.Close(); + } + catch { } + } + + private void RestoreUI() + { + scMain.Panel2Collapsed = true; + + if (!config.uiItem.mainSize.IsEmpty) + { + this.Width = config.uiItem.mainSize.Width; + this.Height = config.uiItem.mainSize.Height; + } + + for (int k = 0; k < lvServers.Columns.Count; k++) + { + var width = ConfigHandler.GetformMainLvColWidth(ref config, ((EServerColName)k).ToString(), lvServers.Columns[k].Width); + lvServers.Columns[k].Width = width; + } + } + + private void StorageUI() + { + config.uiItem.mainSize = new Size(this.Width, this.Height); + + for (int k = 0; k < lvServers.Columns.Count; k++) + { + ConfigHandler.AddformMainLvColWidth(ref config, ((EServerColName)k).ToString(), lvServers.Columns[k].Width); + } + } + + #endregion + + #region 显示服务器 listview 和 menu + + /// + /// 刷新服务器 + /// + private void RefreshServers() + { + RefreshServersView(); + //lvServers.AutoResizeColumns(); + RefreshServersMenu(); + } + + /// + /// 初始化服务器列表 + /// + private void InitServersView() + { + lvServers.BeginUpdate(); + lvServers.Items.Clear(); + + lvServers.GridLines = true; + lvServers.FullRowSelect = true; + lvServers.View = View.Details; + lvServers.Scrollable = true; + lvServers.MultiSelect = true; + lvServers.HeaderStyle = ColumnHeaderStyle.Clickable; + + lvServers.Columns.Add("", 30); + lvServers.Columns.Add(UIRes.I18N("LvServiceType"), 80); + lvServers.Columns.Add(UIRes.I18N("LvAlias"), 100); + lvServers.Columns.Add(UIRes.I18N("LvAddress"), 120); + lvServers.Columns.Add(UIRes.I18N("LvPort"), 50); + lvServers.Columns.Add(UIRes.I18N("LvEncryptionMethod"), 90); + lvServers.Columns.Add(UIRes.I18N("LvTransportProtocol"), 70); + lvServers.Columns.Add(UIRes.I18N("LvSubscription"), 50); + lvServers.Columns.Add(UIRes.I18N("LvTestResults"), 70, HorizontalAlignment.Right); + + if (statistics != null && statistics.Enable) + { + lvServers.Columns.Add(UIRes.I18N("LvTodayDownloadDataAmount"), 70); + lvServers.Columns.Add(UIRes.I18N("LvTodayUploadDataAmount"), 70); + lvServers.Columns.Add(UIRes.I18N("LvTotalDownloadDataAmount"), 70); + lvServers.Columns.Add(UIRes.I18N("LvTotalUploadDataAmount"), 70); + } + lvServers.EndUpdate(); + } + + /// + /// 刷新服务器列表 + /// + private void RefreshServersView() + { + int index = lvServers.SelectedIndices.Count > 0 ? lvServers.SelectedIndices[0] : -1; + + lvServers.BeginUpdate(); + lvServers.Items.Clear(); + + for (int k = 0; k < config.vmess.Count; k++) + { + string def = string.Empty; + string totalUp = string.Empty, + totalDown = string.Empty, + todayUp = string.Empty, + todayDown = string.Empty; + if (config.index.Equals(k)) + { + def = "√"; + } + + VmessItem item = config.vmess[k]; + + bool stats = statistics != null && statistics.Enable; + if (stats) + { + ServerStatItem sItem = statistics.Statistic.Find(item_ => item_.itemId == item.getItemId()); + if (sItem != null) + { + totalUp = Utils.HumanFy(sItem.totalUp); + totalDown = Utils.HumanFy(sItem.totalDown); + todayUp = Utils.HumanFy(sItem.todayUp); + todayDown = Utils.HumanFy(sItem.todayDown); + } + } + ListViewItem lvItem = new ListViewItem(def); + Utils.AddSubItem(lvItem, EServerColName.configType.ToString(), ((EConfigType)item.configType).ToString()); + Utils.AddSubItem(lvItem, EServerColName.remarks.ToString(), item.remarks); + Utils.AddSubItem(lvItem, EServerColName.address.ToString(), item.address); + Utils.AddSubItem(lvItem, EServerColName.port.ToString(), item.port.ToString()); + Utils.AddSubItem(lvItem, EServerColName.security.ToString(), item.security); + Utils.AddSubItem(lvItem, EServerColName.network.ToString(), item.network); + Utils.AddSubItem(lvItem, EServerColName.subRemarks.ToString(), item.getSubRemarks(config)); + Utils.AddSubItem(lvItem, EServerColName.testResult.ToString(), item.testResult); + if (stats) + { + Utils.AddSubItem(lvItem, EServerColName.todayDown.ToString(), todayDown); + Utils.AddSubItem(lvItem, EServerColName.todayUp.ToString(), todayUp); + Utils.AddSubItem(lvItem, EServerColName.totalDown.ToString(), totalDown); + Utils.AddSubItem(lvItem, EServerColName.totalUp.ToString(), totalUp); + } + + if (k % 2 == 1) // 隔行着色 + { + lvItem.BackColor = Color.WhiteSmoke; + } + if (config.index.Equals(k)) + { + //lvItem.Checked = true; + lvItem.ForeColor = Color.DodgerBlue; + lvItem.Font = new Font(lvItem.Font, FontStyle.Bold); + } + + if (lvItem != null) lvServers.Items.Add(lvItem); + } + lvServers.EndUpdate(); + + if (index >= 0 && index < lvServers.Items.Count && lvServers.Items.Count > 0) + { + lvServers.Items[index].Selected = true; + lvServers.EnsureVisible(index); // workaround + } + } + + /// + /// 刷新托盘服务器菜单 + /// + private void RefreshServersMenu() + { + menuServers.DropDownItems.Clear(); + + List lst = new List(); + for (int k = 0; k < config.vmess.Count; k++) + { + VmessItem item = config.vmess[k]; + string name = item.getSummary(); + + ToolStripMenuItem ts = new ToolStripMenuItem(name) + { + Tag = k + }; + if (config.index.Equals(k)) + { + ts.Checked = true; + } + ts.Click += new EventHandler(ts_Click); + lst.Add(ts); + } + menuServers.DropDownItems.AddRange(lst.ToArray()); + } + + private void ts_Click(object sender, EventArgs e) + { + try + { + ToolStripItem ts = (ToolStripItem)sender; + int index = Utils.ToInt(ts.Tag); + SetDefaultServer(index); + } + catch + { + } + } + + private void lvServers_SelectedIndexChanged(object sender, EventArgs e) + { + int index = -1; + try + { + if (lvServers.SelectedIndices.Count > 0) + { + index = lvServers.SelectedIndices[0]; + } + } + catch + { + } + if (index < 0) + { + return; + } + //qrCodeControl.showQRCode(index, config); + } + + private void DisplayToolStatus() + { + toolSslSocksPort.Text = $"{Global.Loopback}:{config.inbound[0].localPort}"; + toolSslHttpPort.Text = $"{Global.Loopback}:{Global.httpPort}"; + + notifyMain.Icon = MainFormHandler.Instance.GetNotifyIcon(config, this.Icon); + } + private void ssMain_ItemClicked(object sender, ToolStripItemClickedEventArgs e) + { + if (!Utils.IsNullOrEmpty(e.ClickedItem.Text)) + { + Utils.SetClipboardData(e.ClickedItem.Text); + } + } + + private void lvServers_ColumnClick(object sender, ColumnClickEventArgs e) + { + if (e.Column < 0) + { + return; + } + + try + { + var tag = lvServers.Columns[e.Column].Tag?.ToString(); + bool asc = Utils.IsNullOrEmpty(tag) ? true : !Convert.ToBoolean(tag); + if (ConfigHandler.SortServers(ref config, (EServerColName)e.Column, asc) != 0) + { + return; + } + lvServers.Columns[e.Column].Tag = Convert.ToString(asc); + RefreshServers(); + } + catch (Exception ex) + { + Utils.SaveLog(ex.Message, ex); + } + + if (e.Column < 0) + { + return; + } + + } + #endregion + + #region v2ray 操作 + + /// + /// 载入V2ray + /// + private void LoadV2ray() + { + tsbReload.Enabled = false; + + if (Global.reloadV2ray) + { + ClearMsg(); + } + v2rayHandler.LoadV2ray(config); + Global.reloadV2ray = false; + ConfigHandler.SaveConfig(ref config, false); + statistics?.SaveToFile(); + + ChangePACButtonStatus(config.sysProxyType); + + tsbReload.Enabled = true; + } + + /// + /// 关闭V2ray + /// + private void CloseV2ray() + { + ConfigHandler.SaveConfig(ref config, false); + statistics?.SaveToFile(); + + ChangePACButtonStatus(0); + + v2rayHandler.V2rayStop(); + } + + #endregion + + #region 功能按钮 + + private void lvServers_Click(object sender, EventArgs e) + { + int index = -1; + try + { + if (lvServers.SelectedIndices.Count > 0) + { + index = lvServers.SelectedIndices[0]; + } + } + catch + { + } + if (index < 0) + { + return; + } + qrCodeControl.showQRCode(index, config); + } + + private void lvServers_DoubleClick(object sender, EventArgs e) + { + int index = GetLvSelectedIndex(); + if (index < 0) + { + return; + } + ShowServerForm(config.vmess[index].configType, index); + } + private void ShowServerForm(int configType, int index) + { + BaseServerForm fm; + switch (configType) + { + case (int)EConfigType.Vmess: + fm = new AddServerForm(); + break; + case (int)EConfigType.Shadowsocks: + fm = new AddServer3Form(); + break; + case (int)EConfigType.Socks: + fm = new AddServer4Form(); + break; + case (int)EConfigType.VLESS: + fm = new AddServer5Form(); + break; + case (int)EConfigType.Trojan: + fm = new AddServer6Form(); + break; + default: + fm = new AddServer2Form(); + break; + } + fm.EditIndex = index; + if (fm.ShowDialog() == DialogResult.OK) + { + RefreshServers(); + LoadV2ray(); + } + } + + + private void lvServers_KeyDown(object sender, KeyEventArgs e) + { + if (e.Control) + { + switch (e.KeyCode) + { + case Keys.A: + menuSelectAll_Click(null, null); + break; + case Keys.C: + menuExport2ShareUrl_Click(null, null); + break; + case Keys.V: + menuAddServers_Click(null, null); + break; + case Keys.P: + menuPingServer_Click(null, null); + break; + case Keys.O: + menuTcpingServer_Click(null, null); + break; + case Keys.R: + menuRealPingServer_Click(null, null); + break; + case Keys.S: + menuScanScreen_Click(null, null); + break; + case Keys.T: + menuSpeedServer_Click(null, null); + break; + } + } + else + { + switch (e.KeyCode) + { + case Keys.Enter: + menuSetDefaultServer_Click(null, null); + break; + case Keys.Delete: + menuRemoveServer_Click(null, null); + break; + case Keys.T: + menuMoveTop_Click(null, null); + break; + case Keys.B: + menuMoveBottom_Click(null, null); + break; + case Keys.U: + menuMoveUp_Click(null, null); + break; + case Keys.D: + menuMoveDown_Click(null, null); + break; + } + } + } + + private void menuAddVmessServer_Click(object sender, EventArgs e) + { + ShowServerForm((int)EConfigType.Vmess, -1); + } + + private void menuAddVlessServer_Click(object sender, EventArgs e) + { + ShowServerForm((int)EConfigType.VLESS, -1); + } + + private void menuRemoveServer_Click(object sender, EventArgs e) + { + + int index = GetLvSelectedIndex(); + if (index < 0) + { + return; + } + if (UI.ShowYesNo(UIRes.I18N("RemoveServer")) == DialogResult.No) + { + return; + } + for (int k = lvSelecteds.Count - 1; k >= 0; k--) + { + ConfigHandler.RemoveServer(ref config, lvSelecteds[k]); + } + RefreshServers(); + LoadV2ray(); + + } + + private void menuRemoveDuplicateServer_Click(object sender, EventArgs e) + { + Utils.DedupServerList(config.vmess, out List servers, config.keepOlderDedupl); + int oldCount = config.vmess.Count; + int newCount = servers.Count; + if (servers != null) + { + config.vmess = servers; + } + RefreshServers(); + LoadV2ray(); + UI.Show(string.Format(UIRes.I18N("RemoveDuplicateServerResult"), oldCount, newCount)); + } + + private void menuCopyServer_Click(object sender, EventArgs e) + { + int index = GetLvSelectedIndex(); + if (index < 0) + { + return; + } + if (ConfigHandler.CopyServer(ref config, index) == 0) + { + RefreshServers(); + } + } + + private void menuSetDefaultServer_Click(object sender, EventArgs e) + { + int index = GetLvSelectedIndex(); + if (index < 0) + { + return; + } + SetDefaultServer(index); + } + + + private void menuPingServer_Click(object sender, EventArgs e) + { + Speedtest("ping"); + } + private void menuTcpingServer_Click(object sender, EventArgs e) + { + Speedtest("tcping"); + } + + private void menuRealPingServer_Click(object sender, EventArgs e) + { + //if (!config.sysAgentEnabled) + //{ + // UI.Show(UIRes.I18N("NeedHttpGlobalProxy")); + // return; + //} + + //UI.Show(UIRes.I18N("SpeedServerTips")); + + Speedtest("realping"); + } + + private void menuSpeedServer_Click(object sender, EventArgs e) + { + //if (!config.sysAgentEnabled) + //{ + // UI.Show(UIRes.I18N("NeedHttpGlobalProxy")); + // return; + //} + + //UI.Show(UIRes.I18N("SpeedServerTips")); + + Speedtest("speedtest"); + } + private void Speedtest(string actionType) + { + if (GetLvSelectedIndex() < 0) return; + ClearTestResult(); + SpeedtestHandler statistics = new SpeedtestHandler(ref config, ref v2rayHandler, lvSelecteds, actionType, UpdateSpeedtestHandler); + } + + private void tsbTestMe_Click(object sender, EventArgs e) + { + SpeedtestHandler statistics = new SpeedtestHandler(ref config); + string result = statistics.RunAvailabilityCheck() + "ms"; + AppendText(false, string.Format(UIRes.I18N("TestMeOutput"), result)); + } + + private void menuClearStatistic_Click(object sender, EventArgs e) + { + if (statistics != null) + { + statistics.ClearAllServerStatistics(); + } + } + + private void menuExport2ClientConfig_Click(object sender, EventArgs e) + { + int index = GetLvSelectedIndex(); + MainFormHandler.Instance.Export2ClientConfig(index, config); + } + + private void menuExport2ServerConfig_Click(object sender, EventArgs e) + { + int index = GetLvSelectedIndex(); + MainFormHandler.Instance.Export2ServerConfig(index, config); + } + + private void menuExport2ShareUrl_Click(object sender, EventArgs e) + { + GetLvSelectedIndex(); + + StringBuilder sb = new StringBuilder(); + foreach (int v in lvSelecteds) + { + string url = ShareHandler.GetShareUrl(config, v); + if (Utils.IsNullOrEmpty(url)) + { + continue; + } + sb.Append(url); + sb.AppendLine(); + } + if (sb.Length > 0) + { + Utils.SetClipboardData(sb.ToString()); + AppendText(false, UIRes.I18N("BatchExportURLSuccessfully")); + //UI.Show(UIRes.I18N("BatchExportURLSuccessfully")); + } + } + + private void menuExport2SubContent_Click(object sender, EventArgs e) + { + GetLvSelectedIndex(); + + StringBuilder sb = new StringBuilder(); + foreach (int v in lvSelecteds) + { + string url = ShareHandler.GetShareUrl(config, v); + if (Utils.IsNullOrEmpty(url)) + { + continue; + } + sb.Append(url); + sb.AppendLine(); + } + if (sb.Length > 0) + { + Utils.SetClipboardData(Utils.Base64Encode(sb.ToString())); + UI.Show(UIRes.I18N("BatchExportSubscriptionSuccessfully")); + } + } + + private void tsbOptionSetting_Click(object sender, EventArgs e) + { + OptionSettingForm fm = new OptionSettingForm(); + if (fm.ShowDialog() == DialogResult.OK) + { + RefreshServers(); + LoadV2ray(); + } + } + + private void tsbRoutingSetting_Click(object sender, EventArgs e) + { + var fm = new RoutingSettingForm(); + if (fm.ShowDialog() == DialogResult.OK) + { + RefreshRoutingsMenu(); + RefreshServers(); + LoadV2ray(); + } + } + + private void tsbReload_Click(object sender, EventArgs e) + { + Global.reloadV2ray = true; + LoadV2ray(); + } + + private void tsbClose_Click(object sender, EventArgs e) + { + HideForm(); + //this.WindowState = FormWindowState.Minimized; + } + + /// + /// 设置活动服务器 + /// + /// + /// + private int SetDefaultServer(int index) + { + if (index < 0) + { + UI.Show(UIRes.I18N("PleaseSelectServer")); + return -1; + } + if (ConfigHandler.SetDefaultServer(ref config, index) == 0) + { + RefreshServers(); + LoadV2ray(); + } + return 0; + } + + /// + /// 取得ListView选中的行 + /// + /// + private int GetLvSelectedIndex() + { + int index = -1; + lvSelecteds.Clear(); + try + { + if (lvServers.SelectedIndices.Count <= 0) + { + UI.Show(UIRes.I18N("PleaseSelectServer")); + return index; + } + + index = lvServers.SelectedIndices[0]; + foreach (int i in lvServers.SelectedIndices) + { + lvSelecteds.Add(i); + } + return index; + } + catch + { + return index; + } + } + + private void menuAddCustomServer_Click(object sender, EventArgs e) + { + UI.Show(UIRes.I18N("CustomServerTips")); + + OpenFileDialog fileDialog = new OpenFileDialog + { + Multiselect = false, + Filter = "Config|*.json|All|*.*" + }; + if (fileDialog.ShowDialog() != DialogResult.OK) + { + return; + } + string fileName = fileDialog.FileName; + if (Utils.IsNullOrEmpty(fileName)) + { + return; + } + + if (ConfigHandler.AddCustomServer(ref config, fileName) == 0) + { + RefreshServers(); + //LoadV2ray(); + UI.Show(UIRes.I18N("SuccessfullyImportedCustomServer")); + } + else + { + UI.ShowWarning(UIRes.I18N("FailedImportedCustomServer")); + } + } + + private void menuAddShadowsocksServer_Click(object sender, EventArgs e) + { + ShowServerForm((int)EConfigType.Shadowsocks, -1); + ShowForm(); + } + + private void menuAddSocksServer_Click(object sender, EventArgs e) + { + ShowServerForm((int)EConfigType.Socks, -1); + ShowForm(); + } + + private void menuAddTrojanServer_Click(object sender, EventArgs e) + { + ShowServerForm((int)EConfigType.Trojan, -1); + ShowForm(); + } + + private void menuAddServers_Click(object sender, EventArgs e) + { + string clipboardData = Utils.GetClipboardData(); + int ret = MainFormHandler.Instance.AddBatchServers(config, clipboardData); + if (ret > 0) + { + RefreshServers(); + UI.Show(string.Format(UIRes.I18N("SuccessfullyImportedServerViaClipboard"), ret)); + } + } + + private void menuScanScreen_Click(object sender, EventArgs e) + { + HideForm(); + bgwScan.RunWorkerAsync(); + } + + private void menuUpdateSubscriptions_Click(object sender, EventArgs e) + { + UpdateSubscriptionProcess(); + } + + private void tsbBackupGuiNConfig_Click(object sender, EventArgs e) + { + MainFormHandler.Instance.BackupGuiNConfig(config); + } + #endregion + + + #region 提示信息 + + /// + /// 消息委托 + /// + /// + /// + void v2rayHandler_ProcessEvent(bool notify, string msg) + { + AppendText(notify, msg); + } + + delegate void AppendTextDelegate(string text); + void AppendText(bool notify, string msg) + { + try + { + AppendText(msg); + if (notify) + { + notifyMsg(msg); + } + } + catch + { + } + } + + void AppendText(string text) + { + if (this.txtMsgBox.InvokeRequired) + { + Invoke(new AppendTextDelegate(AppendText), new object[] { text }); + } + else + { + if (!Utils.IsNullOrEmpty(MsgFilter)) + { + if (!text.Contains(MsgFilter)) + { + return; + } + } + //this.txtMsgBox.AppendText(text); + ShowMsg(text); + } + } + + /// + /// 提示信息 + /// + /// + private void ShowMsg(string msg) + { + if (txtMsgBox.Lines.Length > 999) + { + ClearMsg(); + } + this.txtMsgBox.AppendText(msg); + if (!msg.EndsWith(Environment.NewLine)) + { + this.txtMsgBox.AppendText(Environment.NewLine); + } + } + + /// + /// 清除信息 + /// + private void ClearMsg() + { + this.txtMsgBox.Clear(); + } + + /// + /// 托盘信息 + /// + /// + private void notifyMsg(string msg) + { + notifyMain.Text = msg; + } + + #endregion + + + #region 托盘事件 + + private void notifyMain_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + { + ShowForm(); + } + } + + private void menuExit_Click(object sender, EventArgs e) + { + this.Visible = false; + this.Close(); + + Application.Exit(); + } + + + private void ShowForm() + { + this.Show(); + this.WindowState = FormWindowState.Normal; + this.Activate(); + this.ShowInTaskbar = true; + //this.notifyIcon1.Visible = false; + this.txtMsgBox.ScrollToCaret(); + //if (config.index >= 0 && config.index < lvServers.Items.Count) + //{ + // lvServers.Items[config.index].Selected = true; + // lvServers.EnsureVisible(config.index); // workaround + //} + + SetVisibleCore(true); + } + + private void HideForm() + { + //this.WindowState = FormWindowState.Minimized; + this.Hide(); + //this.notifyMain.Icon = this.Icon; + this.notifyMain.Visible = true; + this.ShowInTaskbar = false; + + SetVisibleCore(false); + } + + #endregion + + #region 后台测速 + + private void SetTestResult(int k, string txt) + { + if (k < lvServers.Items.Count) + { + config.vmess[k].testResult = txt; + lvServers.Items[k].SubItems["testResult"].Text = txt; + } + } + private void ClearTestResult() + { + foreach (int s in lvSelecteds) + { + SetTestResult(s, ""); + } + } + private void UpdateSpeedtestHandler(int index, string msg) + { + lvServers.Invoke((MethodInvoker)delegate + { + SetTestResult(index, msg); + }); + } + + private void UpdateStatisticsHandler(ulong up, ulong down, List statistics) + { + try + { + up /= (ulong)(config.statisticsFreshRate / 1000f); + down /= (ulong)(config.statisticsFreshRate / 1000f); + toolSslServerSpeed.Text = string.Format("{0}/s↑ | {1}/s↓", Utils.HumanFy(up), Utils.HumanFy(down)); + + List datas = new List(); + for (int i = 0; i < config.vmess.Count; i++) + { + int index = statistics.FindIndex(item_ => item_.itemId == config.vmess[i].getItemId()); + if (index != -1) + { + lvServers.Invoke((MethodInvoker)delegate + { + lvServers.BeginUpdate(); + + lvServers.Items[i].SubItems["todayDown"].Text = Utils.HumanFy(statistics[index].todayDown); + lvServers.Items[i].SubItems["todayUp"].Text = Utils.HumanFy(statistics[index].todayUp); + lvServers.Items[i].SubItems["totalDown"].Text = Utils.HumanFy(statistics[index].totalDown); + lvServers.Items[i].SubItems["totalUp"].Text = Utils.HumanFy(statistics[index].totalUp); + + lvServers.EndUpdate(); + }); + } + } + } + catch (Exception ex) + { + Utils.SaveLog(ex.Message, ex); + } + } + + #endregion + + #region 移动服务器 + + private void menuMoveTop_Click(object sender, EventArgs e) + { + MoveServer(EMove.Top); + } + + private void menuMoveUp_Click(object sender, EventArgs e) + { + MoveServer(EMove.Up); + } + + private void menuMoveDown_Click(object sender, EventArgs e) + { + MoveServer(EMove.Down); + } + + private void menuMoveBottom_Click(object sender, EventArgs e) + { + MoveServer(EMove.Bottom); + } + + private void MoveServer(EMove eMove) + { + int index = GetLvSelectedIndex(); + if (index < 0) + { + UI.Show(UIRes.I18N("PleaseSelectServer")); + return; + } + if (ConfigHandler.MoveServer(ref config, index, eMove) == 0) + { + //TODO: reload is not good. + RefreshServers(); + //LoadV2ray(); + } + } + private void menuSelectAll_Click(object sender, EventArgs e) + { + foreach (ListViewItem item in lvServers.Items) + { + item.Selected = true; + } + } + + #endregion + + #region 系统代理相关 + private void menuKeepClear_Click(object sender, EventArgs e) + { + SetListenerType(ESysProxyType.ForcedClear); + } + private void menuGlobal_Click(object sender, EventArgs e) + { + SetListenerType(ESysProxyType.ForcedChange); + } + + private void menuKeepNothing_Click(object sender, EventArgs e) + { + SetListenerType(ESysProxyType.Unchanged); + } + private void SetListenerType(ESysProxyType type) + { + config.sysProxyType = type; + ChangePACButtonStatus(type); + } + + private void ChangePACButtonStatus(ESysProxyType type) + { + HttpProxyHandle.UpdateSysProxy(config, false); + //if (type != ListenerType.noHttpProxy) + //{ + // HttpProxyHandle.RestartHttpAgent(config, false); + //} + //else + //{ + // HttpProxyHandle.CloseHttpAgent(config); + //} + + for (int k = 0; k < menuSysAgentMode.DropDownItems.Count; k++) + { + ToolStripMenuItem item = ((ToolStripMenuItem)menuSysAgentMode.DropDownItems[k]); + item.Checked = ((int)type == k); + } + + ConfigHandler.SaveConfig(ref config, false); + DisplayToolStatus(); + } + + #endregion + + + #region CheckUpdate + + private void tsbCheckUpdateN_Click(object sender, EventArgs e) + { + void _updateUI(bool success, string msg) + { + AppendText(false, msg); + if (success) + { + menuExit_Click(null, null); + } + }; + (new UpdateHandle()).CheckUpdateGuiN(config, _updateUI); + } + + private void tsbCheckUpdateCore_Click(object sender, EventArgs e) + { + CheckUpdateCore("v2fly"); + } + + private void tsbCheckUpdateXrayCore_Click(object sender, EventArgs e) + { + CheckUpdateCore("xray"); + } + + private void CheckUpdateCore(string type) + { + void _updateUI(bool success, string msg) + { + AppendText(false, msg); + if (success) + { + CloseV2ray(); + + string fileName = Global.DownloadFileName; + fileName = Utils.GetPath(fileName); + FileManager.ZipExtractToFile(fileName, config.ignoreGeoUpdateCore ? "geo" : ""); + + AppendText(false, UIRes.I18N("MsgUpdateV2rayCoreSuccessfullyMore")); + + Global.reloadV2ray = true; + LoadV2ray(); + + AppendText(false, UIRes.I18N("MsgUpdateV2rayCoreSuccessfully")); + } + }; + (new UpdateHandle()).CheckUpdateCore(type, config, _updateUI); + } + + private void tsbCheckUpdateGeoSite_Click(object sender, EventArgs e) + { + (new UpdateHandle()).UpdateGeoFile("geosite", config, (bool success, string msg) => + { + AppendText(false, msg); + if (success) + { + Global.reloadV2ray = true; + LoadV2ray(); + } + }); + } + + private void tsbCheckUpdateGeoIP_Click(object sender, EventArgs e) + { + (new UpdateHandle()).UpdateGeoFile("geoip", config, (bool success, string msg) => + { + AppendText(false, msg); + if (success) + { + Global.reloadV2ray = true; + LoadV2ray(); + } + }); + } + #endregion + + #region Help + + + private void tsbAbout_Click(object sender, EventArgs e) + { + Process.Start(Global.AboutUrl); + } + + private void tsbV2rayWebsite_Click(object sender, EventArgs e) + { + Process.Start(Global.v2rayWebsiteUrl); + } + + private void tsbPromotion_Click(object sender, EventArgs e) + { + Process.Start($"{Utils.Base64Decode(Global.PromotionUrl)}?t={DateTime.Now.Ticks}"); + } + #endregion + + #region ScanScreen + + + private void bgwScan_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) + { + string ret = Utils.ScanScreen(); + bgwScan.ReportProgress(0, ret); + } + + private void bgwScan_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) + { + ShowForm(); + + string result = Convert.ToString(e.UserState); + if (Utils.IsNullOrEmpty(result)) + { + UI.ShowWarning(UIRes.I18N("NoValidQRcodeFound")); + } + else + { + int ret = MainFormHandler.Instance.AddBatchServers(config, result); + if (ret > 0) + { + RefreshServers(); + UI.Show(UIRes.I18N("SuccessfullyImportedServerViaScan")); + } + } + } + + #endregion + + #region 订阅 + private void tsbSubSetting_Click(object sender, EventArgs e) + { + SubSettingForm fm = new SubSettingForm(); + if (fm.ShowDialog() == DialogResult.OK) + { + RefreshServers(); + } + } + + private void tsbSubUpdate_Click(object sender, EventArgs e) + { + UpdateSubscriptionProcess(); + } + + /// + /// the subscription update process + /// + private void UpdateSubscriptionProcess() + { + void _updateUI(bool success, string msg) + { + AppendText(false, msg); + if (success) + { + RefreshServers(); + } + }; + + (new UpdateHandle()).UpdateSubscriptionProcess(config, _updateUI); + } + + private void tsbQRCodeSwitch_CheckedChanged(object sender, EventArgs e) + { + bool bShow = tsbQRCodeSwitch.Checked; + scMain.Panel2Collapsed = !bShow; + } + #endregion + + #region Language + + private void tsbLanguageDef_Click(object sender, EventArgs e) + { + SetCurrentLanguage("en"); + } + + private void tsbLanguageZhHans_Click(object sender, EventArgs e) + { + SetCurrentLanguage("zh-Hans"); + } + private void SetCurrentLanguage(string value) + { + Utils.RegWriteValue(Global.MyRegPath, Global.MyRegKeyLanguage, value); + //Application.Restart(); + } + + + + + + #endregion + + + #region RoutingsMenu + + /// + /// + /// + private void RefreshRoutingsMenu() + { + menuRoutings.Visible = config.enableRoutingAdvanced; + if (!config.enableRoutingAdvanced) + { + return; + } + + menuRoutings.DropDownItems.Clear(); + + List lst = new List(); + for (int k = 0; k < config.routings.Count; k++) + { + var item = config.routings[k]; + if (item.locked == true) + { + continue; + } + string name = item.remarks; + + ToolStripMenuItem ts = new ToolStripMenuItem(name) + { + Tag = k + }; + if (config.routingIndex.Equals(k)) + { + ts.Checked = true; + } + ts.Click += new EventHandler(ts_Routing_Click); + lst.Add(ts); + } + menuRoutings.DropDownItems.AddRange(lst.ToArray()); + } + + private void ts_Routing_Click(object sender, EventArgs e) + { + try + { + ToolStripItem ts = (ToolStripItem)sender; + int index = Utils.ToInt(ts.Tag); + + if (ConfigHandler.SetDefaultRouting(ref config, index) == 0) + { + RefreshRoutingsMenu(); + LoadV2ray(); + } + } + catch + { + } + } + #endregion + + #region MsgBoxMenu + private void menuMsgBoxSelectAll_Click(object sender, EventArgs e) + { + this.txtMsgBox.Focus(); + this.txtMsgBox.SelectAll(); + } + + private void menuMsgBoxCopy_Click(object sender, EventArgs e) + { + var data = this.txtMsgBox.SelectedText.TrimEx(); + Utils.SetClipboardData(data); + } + + private void menuMsgBoxCopyAll_Click(object sender, EventArgs e) + { + var data = this.txtMsgBox.Text; + Utils.SetClipboardData(data); + } + private void menuMsgBoxAddRoutingRule_Click(object sender, EventArgs e) + { + menuMsgBoxCopy_Click(null, null); + tsbRoutingSetting_Click(null, null); + } + + private void txtMsgBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.Control) + { + switch (e.KeyCode) + { + case Keys.A: + menuMsgBoxSelectAll_Click(null, null); + break; + case Keys.C: + menuMsgBoxCopy_Click(null, null); + break; + case Keys.V: + menuMsgBoxAddRoutingRule_Click(null, null); + break; + + } + } + + } + private void menuMsgBoxFilter_Click(object sender, EventArgs e) + { + var fm = new MsgFilterSetForm(); + fm.MsgFilter = MsgFilter; + if (fm.ShowDialog() == DialogResult.OK) + { + MsgFilter = fm.MsgFilter; + gbMsgTitle.Text = string.Format(UIRes.I18N("MsgInformationTitle"), MsgFilter); + } + } + #endregion + + } +} diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs index a44cc1ee..64b84854 100644 --- a/v2rayN/v2rayN/Global.cs +++ b/v2rayN/v2rayN/Global.cs @@ -189,6 +189,8 @@ namespace v2rayN } public const string StatisticLogOverall = "StatisticLogOverall.json"; + public const string CustomProxyExceptions = "ProxyExceptions.txt"; + public const string IEProxyExceptions = "localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*"; public const string RoutingRuleComma = ""; diff --git a/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs index 890352dc..f6a8ccb1 100644 --- a/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs +++ b/v2rayN/v2rayN/HttpProxyHandler/HttpProxyHandle.cs @@ -1,198 +1,198 @@ -using System; -using v2rayN.Mode; - -namespace v2rayN.HttpProxyHandler -{ - /// - /// 系统代理(http)模式 - /// - public enum ListenerType - { - noHttpProxy = 0, - GlobalHttp = 1, - HttpOpenAndClear = 2, - HttpOpenOnly = 3, - } - /// - /// 系统代理(http)总处理 - /// 启动privoxy提供http协议 - /// 设置IE系统代理 - /// - class HttpProxyHandle - { - private static bool Update(Config config, bool forceDisable) - { - // ListenerType type = config.listenerType; - var type = ListenerType.noHttpProxy; - if (forceDisable) - { - type = ListenerType.noHttpProxy; - } - - try - { - if (type != ListenerType.noHttpProxy) - { - int port = Global.httpPort; - if (port <= 0) - { - return false; - } - if (type == ListenerType.GlobalHttp) - { - //ProxySetting.SetProxy($"{Global.Loopback}:{port}", Global.IEProxyExceptions, 2); - SysProxyHandle.SetIEProxy(true, true, $"{Global.Loopback}:{port}"); - } - else if (type == ListenerType.HttpOpenAndClear) - { - SysProxyHandle.ResetIEProxy(); - } - else if (type == ListenerType.HttpOpenOnly) - { - //SysProxyHandle.ResetIEProxy(); - } - } - else - { - SysProxyHandle.ResetIEProxy(); - } - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - return true; - } - - /// - /// 启用系统代理(http) - /// - /// - private static void StartHttpAgent(Config config) - { - try - { - int localPort = config.GetLocalPort(Global.InboundSocks); - if (localPort > 0) - { - PrivoxyHandler.Instance.Restart(localPort, config); - if (PrivoxyHandler.Instance.RunningPort > 0) - { - Global.sysAgent = true; - Global.socksPort = localPort; - Global.httpPort = PrivoxyHandler.Instance.RunningPort; - } - } - } - catch - { - } - } - - /// - /// 关闭系统代理 - /// - /// - public static void CloseHttpAgent(Config config) - { - try - { - //if (config.listenerType != ListenerType.HttpOpenOnly) - //{ - // Update(config, true); - //} - - PrivoxyHandler.Instance.Stop(); - - Global.sysAgent = false; - Global.socksPort = 0; - Global.httpPort = 0; - } - catch - { - } - } - - /// - /// 重启系统代理(http) - /// - /// - /// - public static void RestartHttpAgent(Config config, bool forced) - { - bool isRestart = false; - //if (config.listenerType == ListenerType.noHttpProxy) - //{ - // // 关闭http proxy时,直接返回 - // return; - //} - //强制重启或者socks端口变化 - if (forced) - { - isRestart = true; - } - else - { - int localPort = config.GetLocalPort(Global.InboundSocks); - if (localPort != Global.socksPort) - { - isRestart = true; - } - } - if (isRestart) - { - CloseHttpAgent(config); - StartHttpAgent(config); - } - Update(config, false); - } - - public static bool UpdateSysProxy(Config config, bool forceDisable) - { - var type = config.sysProxyType; - - if (forceDisable && type == ESysProxyType.ForcedChange) - { - type = ESysProxyType.ForcedClear; - } - - try - { - Global.httpPort = config.GetLocalPort(Global.InboundHttp); - int port = Global.httpPort; - if (port <= 0) - { - return false; - } - if (type == ESysProxyType.ForcedChange) - { - SysProxyHandle.SetIEProxy(true, true, $"{Global.Loopback}:{port}"); - } - else if (type == ESysProxyType.ForcedClear) - { - SysProxyHandle.ResetIEProxy(); - } - else if (type == ESysProxyType.Unchanged) - { - } - } - catch (Exception ex) - { - Utils.SaveLog(ex.Message, ex); - } - return true; - } - - public static void ResetIEProxy4WindowsShutDown() - { - try - { - //TODO To be verified - Utils.RegWriteValue(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable", 0); - } - catch - { - } - } - } -} +using System; +using v2rayN.Mode; + +namespace v2rayN.HttpProxyHandler +{ + /// + /// 系统代理(http)模式 + /// + public enum ListenerType + { + noHttpProxy = 0, + GlobalHttp = 1, + HttpOpenAndClear = 2, + HttpOpenOnly = 3, + } + /// + /// 系统代理(http)总处理 + /// 启动privoxy提供http协议 + /// 设置IE系统代理 + /// + class HttpProxyHandle + { + private static bool Update(Config config, bool forceDisable) + { + // ListenerType type = config.listenerType; + var type = ListenerType.noHttpProxy; + if (forceDisable) + { + type = ListenerType.noHttpProxy; + } + + try + { + if (type != ListenerType.noHttpProxy) + { + int port = Global.httpPort; + if (port <= 0) + { + return false; + } + if (type == ListenerType.GlobalHttp) + { + //ProxySetting.SetProxy($"{Global.Loopback}:{port}", Global.IEProxyExceptions, 2); + SysProxyHandle.SetIEProxy(true, true, $"{Global.Loopback}:{port}"); + } + else if (type == ListenerType.HttpOpenAndClear) + { + SysProxyHandle.ResetIEProxy(); + } + else if (type == ListenerType.HttpOpenOnly) + { + //SysProxyHandle.ResetIEProxy(); + } + } + else + { + SysProxyHandle.ResetIEProxy(); + } + } + catch (Exception ex) + { + Utils.SaveLog(ex.Message, ex); + } + return true; + } + + /// + /// 启用系统代理(http) + /// + /// + private static void StartHttpAgent(Config config) + { + try + { + int localPort = config.GetLocalPort(Global.InboundSocks); + if (localPort > 0) + { + PrivoxyHandler.Instance.Restart(localPort, config); + if (PrivoxyHandler.Instance.RunningPort > 0) + { + Global.sysAgent = true; + Global.socksPort = localPort; + Global.httpPort = PrivoxyHandler.Instance.RunningPort; + } + } + } + catch + { + } + } + + /// + /// 关闭系统代理 + /// + /// + public static void CloseHttpAgent(Config config) + { + try + { + //if (config.listenerType != ListenerType.HttpOpenOnly) + //{ + // Update(config, true); + //} + + PrivoxyHandler.Instance.Stop(); + + Global.sysAgent = false; + Global.socksPort = 0; + Global.httpPort = 0; + } + catch + { + } + } + + /// + /// 重启系统代理(http) + /// + /// + /// + public static void RestartHttpAgent(Config config, bool forced) + { + bool isRestart = false; + //if (config.listenerType == ListenerType.noHttpProxy) + //{ + // // 关闭http proxy时,直接返回 + // return; + //} + //强制重启或者socks端口变化 + if (forced) + { + isRestart = true; + } + else + { + int localPort = config.GetLocalPort(Global.InboundSocks); + if (localPort != Global.socksPort) + { + isRestart = true; + } + } + if (isRestart) + { + CloseHttpAgent(config); + StartHttpAgent(config); + } + Update(config, false); + } + + public static bool UpdateSysProxy(Config config, bool forceDisable) + { + var type = config.sysProxyType; + + if (forceDisable && type == ESysProxyType.ForcedChange) + { + type = ESysProxyType.ForcedClear; + } + + try + { + Global.httpPort = config.GetLocalPort(Global.InboundHttp); + int port = Global.httpPort; + if (port <= 0) + { + return false; + } + if (type == ESysProxyType.ForcedChange) + { + SysProxyHandle.SetIEProxy(true, true, $"{Global.Loopback}:{port}"); + } + else if (type == ESysProxyType.ForcedClear) + { + SysProxyHandle.ResetIEProxy(); + } + else if (type == ESysProxyType.Unchanged) + { + } + } + catch (Exception ex) + { + Utils.SaveLog(ex.Message, ex); + } + return true; + } + + public static void ResetIEProxy4WindowsShutDown() + { + try + { + //TODO To be verified + Utils.RegWriteValue(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings", "ProxyEnable", 0); + } + catch + { + } + } + } +} diff --git a/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs b/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs index 7c5410ca..13e65afd 100644 --- a/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs +++ b/v2rayN/v2rayN/HttpProxyHandler/SysProxyHandle.cs @@ -59,10 +59,14 @@ namespace v2rayN.HttpProxyHandler //} string arguments; - if (enable) - { + if (enable) { + var customProxyException = Utils.LoadResource(Utils.GetPath(Global.CustomProxyExceptions)); + var finalProxyExceptions = Global.IEProxyExceptions; + if (customProxyException != null && customProxyException.Trim() != string.Empty) { + finalProxyExceptions = finalProxyExceptions + ';' + customProxyException.Trim(); + } arguments = global - ? $"global {strProxy} {Global.IEProxyExceptions}" + ? $"global {strProxy} {finalProxyExceptions}" : $"pac {strProxy}"; } else diff --git a/v2rayN/v2rayN/Properties/Resources.Designer.cs b/v2rayN/v2rayN/Properties/Resources.Designer.cs index 672c250f..ed337e15 100644 --- a/v2rayN/v2rayN/Properties/Resources.Designer.cs +++ b/v2rayN/v2rayN/Properties/Resources.Designer.cs @@ -47,8 +47,8 @@ namespace v2rayN.Properties { } /// - /// 重写当前线程的 CurrentUICulture 属性 - /// 重写当前线程的 CurrentUICulture 属性。 + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { diff --git a/v2rayN/v2rayN/Properties/Settings.Designer.cs b/v2rayN/v2rayN/Properties/Settings.Designer.cs index 62dd9b42..630e019d 100644 --- a/v2rayN/v2rayN/Properties/Settings.Designer.cs +++ b/v2rayN/v2rayN/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace v2rayN.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/v2rayN/v2rayN/Resx/ResUI.Designer.cs b/v2rayN/v2rayN/Resx/ResUI.Designer.cs index 1ad602d9..b09eff16 100644 --- a/v2rayN/v2rayN/Resx/ResUI.Designer.cs +++ b/v2rayN/v2rayN/Resx/ResUI.Designer.cs @@ -47,8 +47,8 @@ namespace v2rayN.Resx { } /// - /// 重写当前线程的 CurrentUICulture 属性 - /// 重写当前线程的 CurrentUICulture 属性。 + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { diff --git a/v2rayN/v2rayN/app.config b/v2rayN/v2rayN/app.config index 620ddb42..2132be05 100644 --- a/v2rayN/v2rayN/app.config +++ b/v2rayN/v2rayN/app.config @@ -1,7 +1,7 @@ - - + + diff --git a/v2rayN/v2rayN/v2rayN.csproj b/v2rayN/v2rayN/v2rayN.csproj index 3d925fa0..51c43109 100644 --- a/v2rayN/v2rayN/v2rayN.csproj +++ b/v2rayN/v2rayN/v2rayN.csproj @@ -9,7 +9,7 @@ Properties v2rayN v2rayN - v4.6 + v4.6.1 512 false diff --git a/v2rayN/v2rayUpgrade/App.config b/v2rayN/v2rayUpgrade/App.config index 2d2a12d8..bae5d6d8 100644 --- a/v2rayN/v2rayUpgrade/App.config +++ b/v2rayN/v2rayUpgrade/App.config @@ -1,6 +1,6 @@ - + diff --git a/v2rayN/v2rayUpgrade/Properties/Resources.Designer.cs b/v2rayN/v2rayUpgrade/Properties/Resources.Designer.cs index 5ad1ac66..e06b9866 100644 --- a/v2rayN/v2rayUpgrade/Properties/Resources.Designer.cs +++ b/v2rayN/v2rayUpgrade/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace v2rayUpgrade.Properties { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -47,8 +47,8 @@ namespace v2rayUpgrade.Properties { } /// - /// 重写当前线程的 CurrentUICulture 属性 - /// 重写当前线程的 CurrentUICulture 属性。 + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { diff --git a/v2rayN/v2rayUpgrade/Properties/Settings.Designer.cs b/v2rayN/v2rayUpgrade/Properties/Settings.Designer.cs index 5656cdc6..537585d9 100644 --- a/v2rayN/v2rayUpgrade/Properties/Settings.Designer.cs +++ b/v2rayN/v2rayUpgrade/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace v2rayUpgrade.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/v2rayN/v2rayUpgrade/v2rayUpgrade.csproj b/v2rayN/v2rayUpgrade/v2rayUpgrade.csproj index b7d6307f..463ac517 100644 --- a/v2rayN/v2rayUpgrade/v2rayUpgrade.csproj +++ b/v2rayN/v2rayUpgrade/v2rayUpgrade.csproj @@ -8,7 +8,7 @@ WinExe v2rayUpgrade v2rayUpgrade - v4.6 + v4.6.1 512 true true