diff --git a/Netch/Forms/MainForm.Designer.cs b/Netch/Forms/MainForm.Designer.cs index 952c9bc6..77b6a3c5 100644 --- a/Netch/Forms/MainForm.Designer.cs +++ b/Netch/Forms/MainForm.Designer.cs @@ -35,6 +35,7 @@ this.ImportServersFromClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CreateProcessModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.CreateRouteTableRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ReloadModesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.SubscribeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ManageSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -49,6 +50,7 @@ this.UninstallServiceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.UninstallTapDriverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeNetchFirewallRulesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AttachConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.HelpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CheckForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.fAQToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -90,7 +92,6 @@ this.ProfileTable = new System.Windows.Forms.TableLayoutPanel(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.ButtomControlContainerControl = new System.Windows.Forms.ContainerControl(); - this.AttachConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.MenuStrip.SuspendLayout(); this.ConfigurationGroupBox.SuspendLayout(); this.configLayoutPanel.SuspendLayout(); @@ -142,7 +143,7 @@ // // ModeToolStripMenuItem // - this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.CreateProcessModeToolStripMenuItem, this.ReloadModesToolStripMenuItem}); + this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.CreateProcessModeToolStripMenuItem, this.CreateRouteTableRuleToolStripMenuItem, this.ReloadModesToolStripMenuItem}); this.ModeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1); this.ModeToolStripMenuItem.Name = "ModeToolStripMenuItem"; this.ModeToolStripMenuItem.Size = new System.Drawing.Size(55, 21); @@ -151,14 +152,21 @@ // CreateProcessModeToolStripMenuItem // this.CreateProcessModeToolStripMenuItem.Name = "CreateProcessModeToolStripMenuItem"; - this.CreateProcessModeToolStripMenuItem.Size = new System.Drawing.Size(202, 22); + this.CreateProcessModeToolStripMenuItem.Size = new System.Drawing.Size(217, 22); this.CreateProcessModeToolStripMenuItem.Text = "Create Process Mode"; this.CreateProcessModeToolStripMenuItem.Click += new System.EventHandler(this.CreateProcessModeToolStripButton_Click); // + // CreateRouteTableRuleToolStripMenuItem + // + this.CreateRouteTableRuleToolStripMenuItem.Name = "CreateRouteTableRuleToolStripMenuItem"; + this.CreateRouteTableRuleToolStripMenuItem.Size = new System.Drawing.Size(217, 22); + this.CreateRouteTableRuleToolStripMenuItem.Text = "Create Route Table Rule"; + this.CreateRouteTableRuleToolStripMenuItem.Click += new System.EventHandler(this.createRouteTableModeToolStripMenuItem_Click); + // // ReloadModesToolStripMenuItem // this.ReloadModesToolStripMenuItem.Name = "ReloadModesToolStripMenuItem"; - this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(202, 22); + this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(217, 22); this.ReloadModesToolStripMenuItem.Text = "Reload Modes"; this.ReloadModesToolStripMenuItem.Click += new System.EventHandler(this.ReloadModesToolStripMenuItem_Click); // @@ -260,6 +268,13 @@ this.removeNetchFirewallRulesToolStripMenuItem.Text = "Remove Netch Firewall Rules"; this.removeNetchFirewallRulesToolStripMenuItem.Click += new System.EventHandler(this.RemoveNetchFirewallRulesToolStripMenuItem_Click); // + // AttachConsoleToolStripMenuItem + // + this.AttachConsoleToolStripMenuItem.Name = "AttachConsoleToolStripMenuItem"; + this.AttachConsoleToolStripMenuItem.Size = new System.Drawing.Size(243, 22); + this.AttachConsoleToolStripMenuItem.Text = "Attach Console"; + this.AttachConsoleToolStripMenuItem.Click += new System.EventHandler(this.AttachConsoleToolStripMenuItem_Click); + // // HelpToolStripMenuItem // this.HelpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.CheckForUpdatesToolStripMenuItem, this.fAQToolStripMenuItem}); @@ -701,13 +716,6 @@ this.ButtomControlContainerControl.TabStop = false; this.ButtomControlContainerControl.Text = "groupBox1"; // - // AttachConsoleToolStripMenuItem - // - this.AttachConsoleToolStripMenuItem.Name = "AttachConsoleToolStripMenuItem"; - this.AttachConsoleToolStripMenuItem.Size = new System.Drawing.Size(243, 22); - this.AttachConsoleToolStripMenuItem.Text = "Attach Console"; - this.AttachConsoleToolStripMenuItem.Click += new System.EventHandler(this.AttachConsoleToolStripMenuItem_Click); - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); @@ -753,6 +761,8 @@ this.PerformLayout(); } + private System.Windows.Forms.ToolStripMenuItem CreateRouteTableRuleToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem AttachConsoleToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeNetchFirewallRulesToolStripMenuItem; diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index 88d87f24..cc152e94 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -862,6 +862,12 @@ namespace Netch.Forms new Process(mode).ShowDialog(); Show(); break; + case 1: + case 2: + Hide(); + new Route(mode).ShowDialog(); + Show(); + break; default: Utils.Utils.Open(ModeHelper.GetFullPath(mode.RelativePath)); break; @@ -1581,5 +1587,12 @@ namespace Netch.Forms if (!NativeMethods.AttachConsole(-1)) NativeMethods.AllocConsole(); } + + private void createRouteTableModeToolStripMenuItem_Click(object sender, EventArgs e) + { + Hide(); + new Route().ShowDialog(); + Show(); + } } } \ No newline at end of file diff --git a/Netch/Forms/Mode/ModeEditorUtils.cs b/Netch/Forms/Mode/ModeEditorUtils.cs new file mode 100644 index 00000000..a6cced32 --- /dev/null +++ b/Netch/Forms/Mode/ModeEditorUtils.cs @@ -0,0 +1,17 @@ +using System.IO; +using System.Text; + +namespace Netch.Forms.Mode +{ + public static class ModeEditorUtils + { + public static string ToSafeFileName(string text) + { + var fileName = new StringBuilder(text); + foreach (var c in Path.GetInvalidFileNameChars()) + fileName.Replace(c, '_'); + + return fileName.ToString(); + } + } +} \ No newline at end of file diff --git a/Netch/Forms/Mode/Process.Designer.cs b/Netch/Forms/Mode/Process.Designer.cs index bd19387e..55f87d44 100644 --- a/Netch/Forms/Mode/Process.Designer.cs +++ b/Netch/Forms/Mode/Process.Designer.cs @@ -80,7 +80,6 @@ namespace Netch.Forms.Mode this.UseCustomFilenameBox.TabIndex = 9; this.UseCustomFilenameBox.Text = "Use Custom Filename"; this.UseCustomFilenameBox.UseVisualStyleBackColor = true; - this.UseCustomFilenameBox.CheckedChanged += new System.EventHandler(this.UseCustomFilenameBox_CheckedChanged); // // FilenameLabel // @@ -97,6 +96,7 @@ namespace Netch.Forms.Mode this.FilenameTextBox.Name = "FilenameTextBox"; this.FilenameTextBox.Size = new System.Drawing.Size(250, 23); this.FilenameTextBox.TabIndex = 5; + this.FilenameTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", this.UseCustomFilenameBox, "Checked", true));; // // ScanButton // diff --git a/Netch/Forms/Mode/Process.cs b/Netch/Forms/Mode/Process.cs index d41cb325..785aa566 100644 --- a/Netch/Forms/Mode/Process.cs +++ b/Netch/Forms/Mode/Process.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.WindowsAPICodePack.Dialogs; using Netch.Controllers; +using Netch.Properties; using Netch.Utils; namespace Netch.Forms.Mode @@ -21,35 +22,26 @@ namespace Netch.Forms.Mode /// 编辑模式 /// /// 模式 - public Process(Models.Mode mode) + public Process(Models.Mode mode = null) { - if (mode.Type != 0) - throw new Exception("请传入进程模式"); + if ((mode?.Type ?? 0) is not 0) + throw new ArgumentOutOfRangeException(); InitializeComponent(); CheckForIllegalCrossThreadCalls = false; - Text = "Edit Process Mode"; _mode = mode; - RuleListBox.Items.AddRange(mode.Rule.ToArray()); + if (mode != null) + { + Text = "Edit Process Mode"; - #region 禁用文件名更改 + RemarkTextBox.TextChanged -= RemarkTextBox_TextChanged; + FilenameTextBox.Enabled = UseCustomFilenameBox.Enabled = false; - RemarkTextBox.TextChanged -= RemarkTextBox_TextChanged; - FilenameTextBox.Enabled = UseCustomFilenameBox.Enabled = false; - - #endregion - - FilenameTextBox.Text = mode.RelativePath; - RemarkTextBox.Text = mode.Remark; - } - - public Process() - { - InitializeComponent(); - CheckForIllegalCrossThreadCalls = false; - - FilenameTextBox.Enabled = false; + RemarkTextBox.Text = mode.Remark; + FilenameTextBox.Text = mode.RelativePath; + RuleListBox.Items.AddRange(mode.Rule.ToArray()); + } } /// @@ -213,19 +205,9 @@ namespace Netch.Forms.Mode { if (!UseCustomFilenameBox.Checked) { - var invalidFileChars = Path.GetInvalidFileNameChars(); - var fileName = new StringBuilder(RemarkTextBox.Text); - foreach (var c in invalidFileChars) - fileName.Replace(c, '_'); - - FilenameTextBox.Text = fileName.ToString(); + FilenameTextBox.Text = ModeEditorUtils.ToSafeFileName(RemarkTextBox.Text); } }); } - - private void UseCustomFilenameBox_CheckedChanged(object sender, EventArgs e) - { - FilenameTextBox.Enabled = UseCustomFilenameBox.Checked; - } } } \ No newline at end of file diff --git a/Netch/Forms/Mode/Route.cs b/Netch/Forms/Mode/Route.cs new file mode 100644 index 00000000..3be2f30f --- /dev/null +++ b/Netch/Forms/Mode/Route.cs @@ -0,0 +1,128 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Forms; +using Netch.Properties; +using Netch.Utils; + +namespace Netch.Forms.Mode +{ + public partial class Route : Form + { + class Item + { + private string _text; + + public Item(int value, string text) + { + Text = text; + Value = value; + } + + public string Text + { + get => i18N.Translate(_text); + set => _text = value; + } + + public int Value { get; set; } + } + + private Item[] _items = {new(1, "Proxy Rule IPs"), new(2, "Bypass Rule IPs")}; + + private readonly Models.Mode _mode; + + public Route(Models.Mode mode = null) + { + if ((mode?.Type ?? 1) is not (1 or 2)) + throw new ArgumentOutOfRangeException(); + + _mode = mode; + + InitializeComponent(); + comboBox1.DataSource = _items; + comboBox1.ValueMember = "Value"; + comboBox1.DisplayMember = "Text"; + + i18N.TranslateForm(this); + } + + private void Route_Load(object sender, EventArgs e) + { + if (_mode != null) + { + Text = "Edit Route Table Rule"; + + RemarkTextBox.TextChanged -= RemarkTextBox_TextChanged; + FilenameTextBox.Enabled = UseCustomFilenameBox.Enabled = false; + + RemarkTextBox.Text = _mode.Remark; + comboBox1.SelectedValue = _mode.Type; // ComboBox SelectedValue worked after ctor + FilenameTextBox.Text = _mode.RelativePath; + richTextBox1.Lines = _mode.Rule.ToArray(); + } + } + + private void ControlButton_Click(object sender, EventArgs e) + { + if (string.IsNullOrWhiteSpace(RemarkTextBox.Text)) + { + MessageBoxX.Show(i18N.Translate("Please enter a mode remark")); + return; + } + + if (string.IsNullOrWhiteSpace(FilenameTextBox.Text)) + { + MessageBoxX.Show(i18N.Translate("Please enter a mode filename")); + return; + } + + if (_mode != null) + { + _mode.Remark = RemarkTextBox.Text; + _mode.Rule.Clear(); + _mode.Rule.AddRange(richTextBox1.Lines); + _mode.Type = (int) comboBox1.SelectedValue; + + _mode.WriteFile(); + Global.MainForm.LoadModes(); + MessageBoxX.Show(i18N.Translate("Mode updated successfully")); + } + else + { + var relativePath = $"Custom\\{FilenameTextBox.Text}.txt"; + var fullName = ModeHelper.GetFullPath(relativePath); + if (File.Exists(fullName)) + { + MessageBoxX.Show(i18N.Translate("File already exists.\n Please Change the filename")); + return; + } + + var mode = new Models.Mode(fullName) + { + Type = (int) comboBox1.SelectedValue, + Remark = RemarkTextBox.Text + }; + + mode.Rule.AddRange(richTextBox1.Lines); + + mode.WriteFile(); + ModeHelper.Add(mode); + MessageBoxX.Show(i18N.Translate("Mode added successfully")); + } + + Close(); + } + + private async void RemarkTextBox_TextChanged(object sender, EventArgs e) + { + await Task.Run(() => + { + if (!UseCustomFilenameBox.Checked) + { + FilenameTextBox.Text = ModeEditorUtils.ToSafeFileName(RemarkTextBox.Text); + } + }); + } + } +} \ No newline at end of file diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index 649709bc..e16f5b04 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -90,6 +90,9 @@ True Settings.settings + + Form + diff --git a/Netch/Resources/zh-CN b/Netch/Resources/zh-CN index a9332306..c533ea78 100644 --- a/Netch/Resources/zh-CN +++ b/Netch/Resources/zh-CN @@ -41,6 +41,8 @@ "Download update failed": "下载更新错误", "Create Process Mode": "创建进程模式", "Edit Process Mode": "修改进程模式", + "Create Route Table Rule": "创建路由表规则", + "Edit Route Table Rule": "修改路由表规则", "Address": "地址", "Username": "用户名", @@ -140,6 +142,10 @@ "Please enter a mode remark": "请输入模式的备注", "File already exists.\n Please Change the filename": "文件名已存在,请修改文件名", "Please enter a mode filename": "请输入模式的文件名", + + "Proxy Rule IPs": "代理规则 IP", + "Bypass Rule IPs": "绕过规则 IP", + "Link": "链接", "Use Selected Server To Update Subscription": "使用选中的服务器更新订阅",