From cf04b229bd5120ecc9e4c744ca13423a7a3643a3 Mon Sep 17 00:00:00 2001 From: Sui Date: Mon, 22 Dec 2014 18:32:11 +0800 Subject: [PATCH] Merge remote-tracking branch 2.1.4 and add URI parse modelless dialog for user. Conflicts: shadowsocks-csharp/View/ConfigForm.Designer.cs --- shadowsocks-csharp/Data/cn.txt | 8 +- shadowsocks-csharp/Model/Configuration.cs | 67 ++++ shadowsocks-csharp/View/ConfigForm.Designer.cs | 121 ++++-- shadowsocks-csharp/View/ConfigForm.cs | 20 + shadowsocks-csharp/View/URIParseForm.Designer.cs | 163 ++++++++ shadowsocks-csharp/View/URIParseForm.cs | 61 +++ shadowsocks-csharp/View/URIParseForm.resx | 449 +++++++++++++++++++++++ shadowsocks-csharp/shadowsocks-csharp.csproj | 9 + 8 files changed, 856 insertions(+), 42 deletions(-) create mode 100644 shadowsocks-csharp/View/URIParseForm.Designer.cs create mode 100644 shadowsocks-csharp/View/URIParseForm.cs create mode 100644 shadowsocks-csharp/View/URIParseForm.resx diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt index 3feaeb98..e845cb3f 100644 --- a/shadowsocks-csharp/Data/cn.txt +++ b/shadowsocks-csharp/Data/cn.txt @@ -4,7 +4,7 @@ Mode=代理模式 PAC=PAC 模式 Global=全局模式 Servers=服务器选择 -Edit Servers...=编辑服务器... +Edit Servers...=编辑Shadowsocks服务器... Start on Boot=自动启动 Share over LAN=在局域网共享代理 Edit PAC File...=编辑 PAC 文件... @@ -12,7 +12,7 @@ Show QRCode...=显示二维码... Show Logs...=显示日志... About...=关于... Quit=退出 -Edit Servers=编辑服务器 +Edit Servers=编辑Shadowsocks服务器 &Add=添加(&A) &Delete=删除(&D) Server=服务器 @@ -39,3 +39,7 @@ Shadowsocks is here=Shadowsocks 在这里 You can turn on/off Shadowsocks in the context menu=可以在右键菜单中开关 Shadowsocks Enabled=已启用代理 Disabled=已禁用代理 +&Parse=解析(&P) +Shadowsocks URI=Shadowsocks URI +Shadowsocks URI Parse=Shadowsocks URI解析 +URI Parse=URI解析 diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 63b4c750..bb50b381 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; +using System.Text.RegularExpressions; namespace Shadowsocks.Model { @@ -136,6 +137,72 @@ namespace Shadowsocks.Model throw new ArgumentException(I18N.GetString("Server IP can not be blank")); } } + private static Server parse_ss_uri(string uri) + { + string[] sArray = uri.Split(new char[2] { ':', '@' }); + + Server server = Configuration.GetDefaultServer(); + server.method = sArray[0].ToString(); + server.password = sArray[1].ToString(); + server.server = sArray[2].ToString(); + server.server_port = int.Parse(sArray[3].ToString()); + return server; + } + public static bool parse_uri(string uri, ref Server server) + { + Regex regex_ss_head = new Regex("^(?i:(ss://))"); + Regex regex_ss = new Regex("^(?i:(aes-256-cfb|aes-128-cfb|aes-192-cfb|aes-256-ofb|aes-128-ofb|aes-192-ofb|aes-128-ctr|aes-192-ctr|aes-256-ctr|aes-128-cfb8|aes-192-cfb8|aes-256-cfb8|aes-128-cfb1|aes-192-cfb1|aes-256-cfb1|bf-cfb|camellia-128-cfb|camellia-192-cfb|camellia-256-cfb|cast5-cfb|des-cfb|idea-cfb|rc2-cfb|rc4-md5|seed-cfb|salsa20-ctr|rc4|table)):[a-zA-Z0-9\\.\\-]+@((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))\\:[0-9]+"); + Regex regexbase64 = new Regex("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?"); + + string uri_core = ""; + + try + { + + if (regex_ss_head.IsMatch(uri)) + { + string[] sArray = Regex.Split(uri, "://", RegexOptions.IgnoreCase); + uri_core = sArray[1].ToString(); + } + else + { + uri_core = uri; + } + + if (regex_ss.IsMatch(uri_core)) + { + server = parse_ss_uri(uri_core); + return true; + } + else + { + if (regexbase64.IsMatch(uri_core)) + { + byte[] arr = System.Convert.FromBase64String(uri_core); + string uri_core2 = System.Text.Encoding.UTF8.GetString(arr); + if (regex_ss.IsMatch(uri_core2)) + { + server = parse_ss_uri(uri_core2); + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + } + catch (IOException e) + { + Console.Error.WriteLine(e); + } + return false; + + } private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy { diff --git a/shadowsocks-csharp/View/ConfigForm.Designer.cs b/shadowsocks-csharp/View/ConfigForm.Designer.cs index 57e1441b..ef5c0a27 100755 --- a/shadowsocks-csharp/View/ConfigForm.Designer.cs +++ b/shadowsocks-csharp/View/ConfigForm.Designer.cs @@ -51,11 +51,14 @@ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel(); + this.URIButton = new System.Windows.Forms.Button(); this.tableLayoutPanel1.SuspendLayout(); this.ServerGroupBox.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); this.tableLayoutPanel4.SuspendLayout(); + this.tableLayoutPanel5.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel1 @@ -88,16 +91,16 @@ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel1.Size = new System.Drawing.Size(238, 163); + this.tableLayoutPanel1.Size = new System.Drawing.Size(249, 167); this.tableLayoutPanel1.TabIndex = 0; // // RemarksTextBox // this.RemarksTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.RemarksTextBox.Location = new System.Drawing.Point(72, 137); + this.RemarksTextBox.Location = new System.Drawing.Point(83, 140); this.RemarksTextBox.MaxLength = 32; this.RemarksTextBox.Name = "RemarksTextBox"; - this.RemarksTextBox.Size = new System.Drawing.Size(160, 20); + this.RemarksTextBox.Size = new System.Drawing.Size(160, 21); this.RemarksTextBox.TabIndex = 10; this.RemarksTextBox.WordWrap = false; // @@ -105,9 +108,9 @@ // this.RemarksLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.RemarksLabel.AutoSize = true; - this.RemarksLabel.Location = new System.Drawing.Point(17, 140); + this.RemarksLabel.Location = new System.Drawing.Point(30, 144); this.RemarksLabel.Name = "RemarksLabel"; - this.RemarksLabel.Size = new System.Drawing.Size(49, 13); + this.RemarksLabel.Size = new System.Drawing.Size(47, 12); this.RemarksLabel.TabIndex = 9; this.RemarksLabel.Text = "Remarks"; // @@ -115,9 +118,9 @@ // this.IPLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.IPLabel.AutoSize = true; - this.IPLabel.Location = new System.Drawing.Point(15, 9); + this.IPLabel.Location = new System.Drawing.Point(18, 10); this.IPLabel.Name = "IPLabel"; - this.IPLabel.Size = new System.Drawing.Size(51, 13); + this.IPLabel.Size = new System.Drawing.Size(59, 12); this.IPLabel.TabIndex = 0; this.IPLabel.Text = "Server IP"; // @@ -125,19 +128,19 @@ // this.ServerPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ServerPortLabel.AutoSize = true; - this.ServerPortLabel.Location = new System.Drawing.Point(6, 35); + this.ServerPortLabel.Location = new System.Drawing.Point(6, 37); this.ServerPortLabel.Name = "ServerPortLabel"; - this.ServerPortLabel.Size = new System.Drawing.Size(60, 13); + this.ServerPortLabel.Size = new System.Drawing.Size(71, 12); this.ServerPortLabel.TabIndex = 1; this.ServerPortLabel.Text = "Server Port"; // // ProxyPortTextBox // this.ProxyPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ProxyPortTextBox.Location = new System.Drawing.Point(72, 111); + this.ProxyPortTextBox.Location = new System.Drawing.Point(83, 113); this.ProxyPortTextBox.MaxLength = 10; this.ProxyPortTextBox.Name = "ProxyPortTextBox"; - this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 20); + this.ProxyPortTextBox.Size = new System.Drawing.Size(160, 21); this.ProxyPortTextBox.TabIndex = 4; this.ProxyPortTextBox.WordWrap = false; // @@ -145,9 +148,9 @@ // this.ProxyPortLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.ProxyPortLabel.AutoSize = true; - this.ProxyPortLabel.Location = new System.Drawing.Point(11, 114); + this.ProxyPortLabel.Location = new System.Drawing.Point(12, 117); this.ProxyPortLabel.Name = "ProxyPortLabel"; - this.ProxyPortLabel.Size = new System.Drawing.Size(55, 13); + this.ProxyPortLabel.Size = new System.Drawing.Size(65, 12); this.ProxyPortLabel.TabIndex = 3; this.ProxyPortLabel.Text = "Proxy Port"; // @@ -155,40 +158,40 @@ // this.PasswordLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.PasswordLabel.AutoSize = true; - this.PasswordLabel.Location = new System.Drawing.Point(13, 61); + this.PasswordLabel.Location = new System.Drawing.Point(24, 64); this.PasswordLabel.Name = "PasswordLabel"; - this.PasswordLabel.Size = new System.Drawing.Size(53, 13); + this.PasswordLabel.Size = new System.Drawing.Size(53, 12); this.PasswordLabel.TabIndex = 2; this.PasswordLabel.Text = "Password"; // // IPTextBox // this.IPTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.IPTextBox.Location = new System.Drawing.Point(72, 6); + this.IPTextBox.Location = new System.Drawing.Point(83, 6); this.IPTextBox.MaxLength = 512; this.IPTextBox.Name = "IPTextBox"; - this.IPTextBox.Size = new System.Drawing.Size(160, 20); + this.IPTextBox.Size = new System.Drawing.Size(160, 21); this.IPTextBox.TabIndex = 0; this.IPTextBox.WordWrap = false; // // ServerPortTextBox // this.ServerPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.ServerPortTextBox.Location = new System.Drawing.Point(72, 32); + this.ServerPortTextBox.Location = new System.Drawing.Point(83, 33); this.ServerPortTextBox.MaxLength = 10; this.ServerPortTextBox.Name = "ServerPortTextBox"; - this.ServerPortTextBox.Size = new System.Drawing.Size(160, 20); + this.ServerPortTextBox.Size = new System.Drawing.Size(160, 21); this.ServerPortTextBox.TabIndex = 1; this.ServerPortTextBox.WordWrap = false; // // PasswordTextBox // this.PasswordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.PasswordTextBox.Location = new System.Drawing.Point(72, 58); + this.PasswordTextBox.Location = new System.Drawing.Point(83, 60); this.PasswordTextBox.MaxLength = 256; this.PasswordTextBox.Name = "PasswordTextBox"; this.PasswordTextBox.PasswordChar = '*'; - this.PasswordTextBox.Size = new System.Drawing.Size(160, 20); + this.PasswordTextBox.Size = new System.Drawing.Size(160, 21); this.PasswordTextBox.TabIndex = 2; this.PasswordTextBox.WordWrap = false; // @@ -196,9 +199,9 @@ // this.EncryptionLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; this.EncryptionLabel.AutoSize = true; - this.EncryptionLabel.Location = new System.Drawing.Point(9, 88); + this.EncryptionLabel.Location = new System.Drawing.Point(12, 91); this.EncryptionLabel.Name = "EncryptionLabel"; - this.EncryptionLabel.Size = new System.Drawing.Size(57, 13); + this.EncryptionLabel.Size = new System.Drawing.Size(65, 12); this.EncryptionLabel.TabIndex = 8; this.EncryptionLabel.Text = "Encryption"; // @@ -209,7 +212,7 @@ this.EncryptionSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EncryptionSelect.FormattingEnabled = true; this.EncryptionSelect.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.EncryptionSelect.ItemHeight = 13; + this.EncryptionSelect.ItemHeight = 12; this.EncryptionSelect.Items.AddRange(new object[] { "table", "rc4-md5", @@ -219,9 +222,9 @@ "aes-192-cfb", "aes-128-cfb", "rc4"}); - this.EncryptionSelect.Location = new System.Drawing.Point(72, 84); + this.EncryptionSelect.Location = new System.Drawing.Point(83, 87); this.EncryptionSelect.Name = "EncryptionSelect"; - this.EncryptionSelect.Size = new System.Drawing.Size(160, 21); + this.EncryptionSelect.Size = new System.Drawing.Size(160, 20); this.EncryptionSelect.TabIndex = 3; // // panel2 @@ -262,11 +265,10 @@ // // DeleteButton // - this.DeleteButton.Dock = System.Windows.Forms.DockStyle.Right; - this.DeleteButton.Location = new System.Drawing.Point(86, 6); - this.DeleteButton.Margin = new System.Windows.Forms.Padding(3, 6, 0, 3); + this.DeleteButton.AutoSize = true; + this.DeleteButton.Location = new System.Drawing.Point(89, 3); this.DeleteButton.Name = "DeleteButton"; - this.DeleteButton.Size = new System.Drawing.Size(80, 23); + this.DeleteButton.Size = new System.Drawing.Size(80, 32); this.DeleteButton.TabIndex = 7; this.DeleteButton.Text = "&Delete"; this.DeleteButton.UseVisualStyleBackColor = true; @@ -274,11 +276,11 @@ // // AddButton // + this.AddButton.AutoSize = true; this.AddButton.Dock = System.Windows.Forms.DockStyle.Left; - this.AddButton.Location = new System.Drawing.Point(0, 6); - this.AddButton.Margin = new System.Windows.Forms.Padding(0, 6, 3, 3); + this.AddButton.Location = new System.Drawing.Point(3, 3); this.AddButton.Name = "AddButton"; - this.AddButton.Size = new System.Drawing.Size(80, 23); + this.AddButton.Size = new System.Drawing.Size(80, 32); this.AddButton.TabIndex = 6; this.AddButton.Text = "&Add"; this.AddButton.UseVisualStyleBackColor = true; @@ -289,10 +291,10 @@ this.ServerGroupBox.AutoSize = true; this.ServerGroupBox.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.ServerGroupBox.Controls.Add(this.tableLayoutPanel1); - this.ServerGroupBox.Location = new System.Drawing.Point(178, 0); + this.ServerGroupBox.Location = new System.Drawing.Point(184, 0); this.ServerGroupBox.Margin = new System.Windows.Forms.Padding(12, 0, 0, 0); this.ServerGroupBox.Name = "ServerGroupBox"; - this.ServerGroupBox.Size = new System.Drawing.Size(249, 200); + this.ServerGroupBox.Size = new System.Drawing.Size(260, 205); this.ServerGroupBox.TabIndex = 6; this.ServerGroupBox.TabStop = false; this.ServerGroupBox.Text = "Server"; @@ -301,6 +303,7 @@ // this.ServersListBox.FormattingEnabled = true; this.ServersListBox.IntegralHeight = false; + this.ServersListBox.ItemHeight = 12; this.ServersListBox.Location = new System.Drawing.Point(0, 0); this.ServersListBox.Margin = new System.Windows.Forms.Padding(0); this.ServersListBox.Name = "ServersListBox"; @@ -319,6 +322,7 @@ this.tableLayoutPanel2.Controls.Add(this.ServersListBox, 0, 0); this.tableLayoutPanel2.Controls.Add(this.ServerGroupBox, 1, 0); this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel5, 1, 1); this.tableLayoutPanel2.Location = new System.Drawing.Point(12, 12); this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; @@ -326,7 +330,7 @@ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel2.Size = new System.Drawing.Size(427, 264); + this.tableLayoutPanel2.Size = new System.Drawing.Size(444, 278); this.tableLayoutPanel2.TabIndex = 7; // // tableLayoutPanel3 @@ -340,7 +344,7 @@ this.tableLayoutPanel3.Controls.Add(this.MyCancelButton, 1, 0); this.tableLayoutPanel3.Controls.Add(this.OKButton, 0, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Right; - this.tableLayoutPanel3.Location = new System.Drawing.Point(268, 235); + this.tableLayoutPanel3.Location = new System.Drawing.Point(285, 249); this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.RowCount = 1; @@ -355,17 +359,49 @@ this.tableLayoutPanel4.ColumnCount = 2; this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); this.tableLayoutPanel4.Controls.Add(this.AddButton, 0, 0); + this.tableLayoutPanel4.Controls.Add(this.DeleteButton, 1, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Top; - this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 200); + this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 205); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel4.Size = new System.Drawing.Size(166, 32); + this.tableLayoutPanel4.Size = new System.Drawing.Size(172, 38); this.tableLayoutPanel4.TabIndex = 8; // + // tableLayoutPanel5 + // + this.tableLayoutPanel5.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel5.AutoSize = true; + this.tableLayoutPanel5.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel5.ColumnCount = 3; + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F)); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 40F)); + this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F)); + this.tableLayoutPanel5.Controls.Add(this.URIButton, 1, 0); + this.tableLayoutPanel5.Location = new System.Drawing.Point(175, 208); + this.tableLayoutPanel5.Name = "tableLayoutPanel5"; + this.tableLayoutPanel5.RowCount = 1; + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 29F)); + this.tableLayoutPanel5.Size = new System.Drawing.Size(266, 35); + this.tableLayoutPanel5.TabIndex = 9; + // + // URIButton + // + this.URIButton.AutoSize = true; + this.URIButton.Dock = System.Windows.Forms.DockStyle.Left; + this.URIButton.Location = new System.Drawing.Point(82, 3); + this.URIButton.Name = "URIButton"; + this.URIButton.Size = new System.Drawing.Size(100, 29); + this.URIButton.TabIndex = 0; + this.URIButton.Text = "URI Parse"; + this.URIButton.UseVisualStyleBackColor = true; + this.URIButton.Click += new System.EventHandler(this.URIButton_Click); + // // ConfigForm // this.AcceptButton = this.OKButton; @@ -395,6 +431,9 @@ this.tableLayoutPanel2.PerformLayout(); this.tableLayoutPanel3.ResumeLayout(false); this.tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel4.PerformLayout(); + this.tableLayoutPanel5.ResumeLayout(false); + this.tableLayoutPanel5.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -425,6 +464,8 @@ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5; + private System.Windows.Forms.Button URIButton; } } diff --git a/shadowsocks-csharp/View/ConfigForm.cs b/shadowsocks-csharp/View/ConfigForm.cs index ecc9bf1f..92f07fed 100755 --- a/shadowsocks-csharp/View/ConfigForm.cs +++ b/shadowsocks-csharp/View/ConfigForm.cs @@ -51,6 +51,7 @@ namespace Shadowsocks.View ServerGroupBox.Text = I18N.GetString("Server"); OKButton.Text = I18N.GetString("OK"); MyCancelButton.Text = I18N.GetString("Cancel"); + URIButton.Text = I18N.GetString("URI Parse"); this.Text = I18N.GetString("Edit Servers"); } @@ -221,5 +222,24 @@ namespace Shadowsocks.View controller.ConfigChanged -= controller_ConfigChanged; } + private void URIButton_Click(object sender, EventArgs e) + { + URIParseForm uriParseForm = new URIParseForm(); + uriParseForm.ShowDialog(this); + if(uriParseForm.Parsed) + { + if (!SaveOldSelectedServer()) + { + return; + } + + _modifiedConfiguration.configs.Add(uriParseForm.server); + LoadConfiguration(_modifiedConfiguration); + ServersListBox.SelectedIndex = _modifiedConfiguration.configs.Count - 1; + _oldSelectedIndex = ServersListBox.SelectedIndex; + } + + } + } } diff --git a/shadowsocks-csharp/View/URIParseForm.Designer.cs b/shadowsocks-csharp/View/URIParseForm.Designer.cs new file mode 100644 index 00000000..c65e4699 --- /dev/null +++ b/shadowsocks-csharp/View/URIParseForm.Designer.cs @@ -0,0 +1,163 @@ +namespace Shadowsocks.View +{ + partial class URIParseForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(URIParseForm)); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.URILable = new System.Windows.Forms.Label(); + this.URITextBox = new System.Windows.Forms.TextBox(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.URIParseButton = new System.Windows.Forms.Button(); + this.URIParseExit = new System.Windows.Forms.Button(); + this.tableLayoutPanel1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.AutoSize = true; + this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 80F)); + this.tableLayoutPanel1.Controls.Add(this.URILable, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.URITextBox, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 1); + this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(505, 62); + this.tableLayoutPanel1.TabIndex = 0; + // + // URILable + // + this.URILable.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.URILable.AutoSize = true; + this.URILable.Location = new System.Drawing.Point(3, 0); + this.URILable.Name = "URILable"; + this.URILable.Size = new System.Drawing.Size(95, 27); + this.URILable.TabIndex = 2; + this.URILable.Text = "Shadowsocks URI"; + this.URILable.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // URITextBox + // + this.URITextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.URITextBox.Location = new System.Drawing.Point(104, 3); + this.URITextBox.Name = "URITextBox"; + this.URITextBox.Size = new System.Drawing.Size(398, 21); + this.URITextBox.TabIndex = 0; + this.URITextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel2.AutoSize = true; + this.tableLayoutPanel2.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel2.ColumnCount = 4; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F)); + this.tableLayoutPanel2.Controls.Add(this.URIParseExit, 2, 0); + this.tableLayoutPanel2.Controls.Add(this.URIParseButton, 1, 0); + this.tableLayoutPanel2.Location = new System.Drawing.Point(104, 30); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 1; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.Size = new System.Drawing.Size(398, 29); + this.tableLayoutPanel2.TabIndex = 3; + // + // URIParseButton + // + this.URIParseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.URIParseButton.Location = new System.Drawing.Point(102, 3); + this.URIParseButton.Name = "URIParseButton"; + this.URIParseButton.Size = new System.Drawing.Size(93, 23); + this.URIParseButton.TabIndex = 0; + this.URIParseButton.Text = "&Parse"; + this.URIParseButton.UseVisualStyleBackColor = true; + this.URIParseButton.Click += new System.EventHandler(this.URIParseButton_Click); + // + // URIParseExit + // + this.URIParseExit.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.URIParseExit.AutoSize = true; + this.URIParseExit.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.URIParseExit.Location = new System.Drawing.Point(201, 3); + this.URIParseExit.Name = "URIParseExit"; + this.URIParseExit.Size = new System.Drawing.Size(93, 23); + this.URIParseExit.TabIndex = 1; + this.URIParseExit.Text = "Quit"; + this.URIParseExit.UseVisualStyleBackColor = true; + this.URIParseExit.Click += new System.EventHandler(this.URIParseExit_Click); + // + // URIParseForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.ClientSize = new System.Drawing.Size(582, 71); + this.Controls.Add(this.tableLayoutPanel1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "URIParseForm"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Shadowsocks URI Parse"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Label URILable; + private System.Windows.Forms.TextBox URITextBox; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.Button URIParseButton; + private System.Windows.Forms.Button URIParseExit; + } +} \ No newline at end of file diff --git a/shadowsocks-csharp/View/URIParseForm.cs b/shadowsocks-csharp/View/URIParseForm.cs new file mode 100644 index 00000000..d98e7ff2 --- /dev/null +++ b/shadowsocks-csharp/View/URIParseForm.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; +using Microsoft.Win32; +using Shadowsocks.Controller; +using Shadowsocks.Model; +using Shadowsocks.Properties; + + +namespace Shadowsocks.View +{ + public partial class URIParseForm : Form + { + public bool Parsed { get; set; } + public Server server; + public URIParseForm() + { + Parsed = false; + + server = Configuration.GetDefaultServer(); + + this.Font = System.Drawing.SystemFonts.MessageBoxFont; + InitializeComponent(); + + // a dirty hack + this.PerformLayout(); + + UpdateTexts(); + this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); + } + private void UpdateTexts() + { + this.URIParseButton.Text = I18N.GetString("&Parse"); + this.URIParseExit.Text = I18N.GetString("Quit"); + this.URILable.Text = I18N.GetString("Shadowsocks URI"); + this.Text = I18N.GetString("Shadowsocks URI Parse"); + } + + private void URIParseButton_Click(object sender, EventArgs e) + { + Parsed = Configuration.parse_uri(URITextBox.Text, ref server); + + if (!Parsed) + server = null; + + this.Close(); + } + + private void URIParseExit_Click(object sender, EventArgs e) + { + Parsed = false; + server = null; + this.Close(); + } + } +} diff --git a/shadowsocks-csharp/View/URIParseForm.resx b/shadowsocks-csharp/View/URIParseForm.resx new file mode 100644 index 00000000..a7094c64 --- /dev/null +++ b/shadowsocks-csharp/View/URIParseForm.resx @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAQAEBAAAAEAIABoBAAARgAAACAgAAABACAAqBAAAK4EAAAwMAAAAQAgAKglAABWFQAAAAAAAAEA + IADNEAAA/joAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA1qtqDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMKDJIvXrm8EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAfxy/w4YpewAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwoMjuMOFJ6Po0a4DAAAAAM+dUxPFijBf3bmEBQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAODBkQbMl0ckw4UocsGCIsDAfxz8v30Z/8eN + NTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADTpmEHzJdHKwAAAADFiS+Fv30a/799Gf+/fRn/v30Z/799 + Gf/Dhil3AAAAAAAAAAAAAAAA4cKUAseNNUPChCWdwIAe8MB+G/zFiS5v0KBWC8GCIc6/fRn/v30Z/799 + Gf+/fRn/woIjswAAAAAAAAAAzZlLGcKEJcy/fRn/v30Z/799Gf+/fRn/v30Z/8SHK5fOm04iwYAf5799 + Gf+/fRn/v30Z/8CAHu7r17cCAAAAAAAAAADXrW4MxYoweMGBIOu/fRn/v30Z/799Gf+/fRn/woQlusqT + QUjAfxz2v30Z/799Gf+/fRn/ypNAMAAAAAAAAAAAAAAAAAAAAADXrW4MxYkueMGAH+u/fRn/v30Z/799 + Gf/BgSHWx4w0e79+Gv6/fRn/v30Z/8OFJ2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADTpmEMxIgseMGA + H+u/fRn/v30Z/8CAHuvFii++v30Z/799Gf/CgySqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADPnlMMw4YoeMCAHuu/fRn/wH8d+sKDI/y/fRn/wYEg5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAADPnlMMw4UneMB/Heu/fRn/v30Z/799Gf/Ml0YmAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLlUQMwoMkeMB/Heu/fRn/xIcrZAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADSpF4PxYkvf8WJL5AAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADmzKQD/v8AAP5/ + AAD+fwAA/iMAAP4DAADyAwAAgAMAAAABAACAAQAA4AEAAPgBAAD+AQAA/4AAAP/gAAD/+AAA//4AACgA + AAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1qtqMAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAfx1/zJdHTAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL99 + GX/BgiLj165vEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + Gf+/fRn/v30Z/799Gf/BgSH7y5ZFYM+eUyjCgyTzv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/w4UotwAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANOmYTDGjDOvwIAe/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/Afhv/yZE9h82ZS0jAfx37v30Z/799Gf+/fRn/v30Z/799 + Gf/CgyPz9+/iBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AADTpmEwxowzr8CAHv+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/x401r82aTHy/fRr/v30Z/799 + Gf+/fRn/v30Z/799Gf/So104AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA06ZhMMaMM6/Afx3/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/xIYqy8qT + QLO/fRn/v30Z/799Gf+/fRn/v30Z/8eON3QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM+eUzDFiS6vwH8d/799Gf+/fRn/v30Z/799 + Gf+/fRn/xIcq68iPOvO/fRn/v30Z/799Gf+/fRn/xIcqrwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADPnlMwxYkur8B/ + Hf+/fRn/v30Z/799Gf+/fRn/wYEh/799Gf+/fRn/v30Z/799Gf/DhSjvAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAz55TMMWJLq/Afx3/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/XrW4wAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMuVRDDDhimvwH8c/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/8eM + NGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLlUQww4Ypr8B/HP+/fRn/v30Z/799 + Gf+/fRn/xYgtpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAy5VEMMOG + Ka/Afxz/v30Z/799Gf/EhirnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAANKkXjzHjTa/wH4b/799Gv/ZsXYkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADVqWdAx402v8mSPmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5sykDAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////9 + /////P////x////8f////D////wf///8PB///eAf//8AH//8AB//jAAP/AYAD+ADAA+AAIAPgABAB+AA + AAf4AAAH/gAAB/+AAAP/4AAD//gAA//+AAP//4AD///gAf//+AH///4B////gf///+D////4/////v// + //8oAAAAMAAAAGAAAAABACAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1qxtSNSoZiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv30ZQMeMNMPp07AEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv30ZQL99 + Gv/MmElwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAv30ZQL99Gf/BgiHz165vJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAv30ZQL99Gf+/fRn/x4w0w9++jAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyJA7QL99Gf+/fRn/v34a/82ZSnEAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAy5ZFQL99Gf+/fRn/v30Z/8KD + I/TXrnAnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADnzqgDzJdHT8SHK8+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/GizLb2LBzJAAA + AAAAAAAA2K9yQ8KDI/m/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf/BgiL/69e3EgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv38QbVqWZmyI844b9+ + Gv+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/xIcr8NWqaEQAAAAAAAAAANOlYWbAgB7+v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/z55TTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9OnYCNSpZmjIjzjfv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/8KDJPvPnVJiAAAAAAAAAADPnVKPv30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/ypNAjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt278G1atqasiOOOG/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/AgB7/zZpNifv38Qbz59QDyZA7rr99 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/yI850QAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPv38QbVqWZmyI844b9+ + Gv+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30a/8qU + QrHcuIEK6NCsD8WILcq/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/woIj9uTH + nA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA9OnYCNSnY2jGizLfv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf/IjzjS2rR7G969iiXChCXiv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/8+dUkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADnz6kG0qRdasaLMuG/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/xoox6dCgVy3ZsnY/wYIh9r99Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/8qUQoUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPfv4gbRoVlmxowz4b99 + Gv+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/8OGKPnQoFdS0qReYMB/ + Hf2/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/8eNNsQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA79/GCNGiWmjGizLfv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf/BgiH/zpxQeM6cUIi/fhr/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/8OGKfXlyqILAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADnz6kG0qRdasaLMuG/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/v34b/syYSKPLlkW0v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf/WrGw9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO/exQbNmkxmxYku4b99 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/LlUTSyZI95L99Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf/LlUN8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA586pCM2aTWjFiC3fv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/yZI+/8SH + K/+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/GjDO3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADfvowGzpxQasWILeG/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/79+G/+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf/EiCzzAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO/exQbNmkxmxYku4b99 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/376NPAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA586pCM2ZS2jDhSjfv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/ypRBbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXrm8Gy5VDasOFJ+G/fRn/v30Z/799Gf+/fRn/v30Z/799 + Gf+/fRn/v30Z/799Gf+/fRn/xosxqgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOfOqAbJkj5mw4Yp4b99 + Gf+/fRn/v30Z/799Gf+/fRn/v30Z/799Gf+/fRn/xIcq5/Pn1AIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA376MCMqTQGjDhSjfv30Z/799Gf+/fRn/v30Z/799Gf+/fRn/wIAd/9y5gy8AAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADXrm8Gy5VDasOFJ+G/fRn/v30Z/799Gf+/fRn/v30Z/86b + T2sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN++jAbSo1yAxYov7b99 + Gf+/fRn/v30Z/8iPOaYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA69W2EdGhWX/GijHuv30Z/8SHKt3v3sUCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt278S0KBXf8eON/DduoUiAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPDgyQ/ZsncMAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP//+f///wAA///4////AAD///j///8AAP// + +H///wAA///4P///AAD///g///8AAP//+B///wAA///4D///AAD///gP+f8AAP//+D/A/wAA///5/AD/ + AAD////gAP8AAP///wAA/wAA///4AAB/AAD///gAAH8AAP/8PAAAfwAA/8AeAAA/AAD/AA8AAD8AAPgA + BwAAPwAAwAABgAA/AACAAADAAD8AAMAAAGAAHwAA8AAAMAAfAAD8AAAYAB8AAP8AAAAAHwAA/8AAAAAP + AAD/8AAAAA8AAP/8AAAADwAA//8AAAAPAAD//8AAAAcAAP//8AAABwAA///8AAAHAAD///8AAAcAAP// + /8AABwAA////8AADAAD////8AAMAAP////8AAwAA/////8ABAAD/////8AEAAP/////8AQAA//////8B + AAD//////8AAAP//////8AAA///////8AAD///////8AAP///////wAAiVBORw0KGgoAAAANSUhEUgAA + AQAAAAEACAYAAABccqhmAAAQlElEQVR42u3dP0xcZ7rH8R8riikQoqCYlWzJlijMhcJIWwQrxbqIFkrH + 2Vh2t1bcbBXWXRqL7Z11lcYR6TbC+4cSoi24FdyVIkERBIUlkEBXUyDdEaKYAuncwn69h+M5M+fM+ff+ + +X66WEQ54/D8zvM+553zjkVRJABh+lXTFwCgOQQAEDACAAgYAQAEjAAAAkYAAAEjAICAEQBAwAgAIGAE + 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 + sP8HnX+c8U4DeOMAAAAASUVORK5CYII= + + + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 1444ca66..71369aa6 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -108,6 +108,12 @@ QRCodeForm.cs + + Form + + + URIParseForm.cs + ConfigForm.cs Designer @@ -125,6 +131,9 @@ QRCodeForm.cs + + URIParseForm.cs + Designer