コード例 #1
0
ファイル: SSUtil.cs プロジェクト: yakasukanakata/Netch
        public IEnumerable <Server> ParseSsdUri(string s)
        {
            var json = JsonConvert.DeserializeObject <Main>(ShareLink.URLSafeBase64Decode(s.Substring(6)));

            return(json.servers.Select(server => new Shadowsocks
            {
                Remark = server.remarks,
                Hostname = server.server,
                Port = server.port != 0 ? server.port : json.port,
                Password = server.password ?? json.password,
                EncryptMethod = server.encryption ?? json.encryption,
                Plugin = string.IsNullOrEmpty(json.plugin) ? string.IsNullOrEmpty(server.plugin) ? null : server.plugin : json.plugin,
                PluginOption = string.IsNullOrEmpty(json.plugin_options) ? string.IsNullOrEmpty(server.plugin_options) ? null : server.plugin_options : json.plugin_options
            })
                   .Where(CheckServer));
        }
コード例 #2
0
ファイル: VMessUtil.cs プロジェクト: skyenqa/Netch-XD
        public IEnumerable <Server> ParseUri(string text)
        {
            var data = new VMess();

            string s;

            try
            {
                s = ShareLink.URLSafeBase64Decode(text.Substring(8));
            }
            catch
            {
                return(V2rayUtils.ParseVUri(text));
            }

            V2rayNSharing vmess = JsonSerializer.Deserialize <V2rayNSharing>(s,
                                                                             new JsonSerializerOptions {
                NumberHandling = JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowReadingFromString
            }) !;

            data.Remark           = vmess.ps;
            data.Hostname         = vmess.add;
            data.Port             = vmess.port;
            data.UserID           = vmess.id;
            data.AlterID          = vmess.aid;
            data.TransferProtocol = vmess.net;
            data.FakeType         = vmess.type;

            if (data.TransferProtocol == "quic")
            {
                if (VMessGlobal.QUIC.Contains(vmess.host !))
                {
                    data.QUICSecure = vmess.host;
                    data.QUICSecret = vmess.path;
                }
            }
            else
            {
                data.Host = vmess.host;
                data.Path = vmess.path;
            }

            data.TLSSecureType = vmess.tls;
            data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个

            return(new[] { data });
        }
コード例 #3
0
ファイル: VMessUtil.cs プロジェクト: utenkekkou/Netch
    public IEnumerable <Server> ParseUri(string text)
    {
        var data = new VMessServer();

        string s;

        try
        {
            s = ShareLink.URLSafeBase64Decode(text.Substring(8));
        }
        catch
        {
            return(V2rayUtils.ParseVUri(text));
        }

        V2rayNJObject vmess = JsonSerializer.Deserialize <V2rayNJObject>(s,
                                                                         new JsonSerializerOptions {
            NumberHandling = JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowReadingFromString
        }) !;

        data.Remark           = vmess.ps;
        data.Hostname         = vmess.add;
        data.EncryptMethod    = vmess.scy;
        data.Port             = vmess.port;
        data.UserID           = vmess.id;
        data.AlterID          = vmess.aid;
        data.TransferProtocol = vmess.net;
        data.FakeType         = vmess.type;
        data.ServerName       = vmess.sni;

        if (data.TransferProtocol == "quic")
        {
            data.QUICSecure = vmess.host;
            data.QUICSecret = vmess.path;
        }
        else
        {
            data.Host = vmess.host;
            data.Path = vmess.path;
        }

        data.TLSSecureType = vmess.tls;

        return(new[] { data });
    }
コード例 #4
0
ファイル: VMessUtil.cs プロジェクト: xxzbg/Netch
        public IEnumerable <Server> ParseUri(string text)
        {
            var data = new VMess();

            text = text.Substring(8);
            V2rayNSharing vmess;

            try
            {
                vmess = JsonConvert.DeserializeObject <V2rayNSharing>(ShareLink.URLSafeBase64Decode(text));
            }
            catch (Exception e)
            {
                Logging.Warning(e.ToString());
                return(null);
            }

            data.Remark           = vmess.ps;
            data.Hostname         = vmess.add;
            data.Port             = ushort.Parse(vmess.port);
            data.UserID           = vmess.id;
            data.AlterID          = int.Parse(vmess.aid);
            data.TransferProtocol = vmess.net;
            data.FakeType         = vmess.type;

            if (data.TransferProtocol == "quic")
            {
                if (VMessGlobal.QUIC.Contains(vmess.host))
                {
                    data.QUICSecure = vmess.host;
                    data.QUICSecret = vmess.path;
                }
            }
            else
            {
                data.Host = vmess.host;
                data.Path = vmess.path;
            }

            data.TLSSecure     = vmess.tls == "tls";
            data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个

            return(CheckServer(data) ? new[] { data } : null);
        }
コード例 #5
0
        public IEnumerable <Server> ParseUri(string text)
        {
            var data = new VMess();

            V2rayNSharing vmess;

            try
            {
                vmess = JsonSerializer.Deserialize <V2rayNSharing>(ShareLink.URLSafeBase64Decode(text.Substring(8)));
            }
            catch
            {
                return(V2rayUtils.ParseVUri(text));
            }

            data.Remark           = vmess.ps;
            data.Hostname         = vmess.add;
            data.Port             = ushort.Parse(vmess.port);
            data.UserID           = vmess.id;
            data.AlterID          = int.Parse(vmess.aid);
            data.TransferProtocol = vmess.net;
            data.FakeType         = vmess.type;

            if (data.TransferProtocol == "quic")
            {
                if (VMessGlobal.QUIC.Contains(vmess.host))
                {
                    data.QUICSecure = vmess.host;
                    data.QUICSecret = vmess.path;
                }
            }
            else
            {
                data.Host = vmess.host;
                data.Path = vmess.path;
            }

            data.TLSSecureType = vmess.tls;
            data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个

            return(new[] { data });
        }
コード例 #6
0
ファイル: SSUtil.cs プロジェクト: zu1kbackup/Netch
        public Shadowsocks ParseSsUri(string text)
        {
            var data = new Shadowsocks();

            text = text.Replace("/?", "?");
            if (text.Contains("#"))
            {
                data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]);
                text        = text.Split('#')[0];
            }

            if (text.Contains("?"))
            {
                var finder = new Regex(@"^(?<data>.+?)\?(.+)$");
                var match  = finder.Match(text);

                if (!match.Success)
                {
                    throw new FormatException();
                }

                var plugins = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("plugin"));
                if (plugins != null)
                {
                    var plugin     = plugins.Substring(0, plugins.IndexOf(";", StringComparison.Ordinal));
                    var pluginopts = plugins.Substring(plugins.IndexOf(";", StringComparison.Ordinal) + 1);
                    switch (plugin)
                    {
                    case "obfs-local":
                    case "simple-obfs":
                        plugin = "simple-obfs";
                        if (!pluginopts.Contains("obfs="))
                        {
                            pluginopts = "obfs=http;obfs-host=" + pluginopts;
                        }

                        break;

                    case "simple-obfs-tls":
                        plugin = "simple-obfs";
                        if (!pluginopts.Contains("obfs="))
                        {
                            pluginopts = "obfs=tls;obfs-host=" + pluginopts;
                        }

                        break;
                    }

                    data.Plugin       = plugin;
                    data.PluginOption = pluginopts;
                }

                text = match.Groups["data"].Value;
            }

            if (text.Contains("@"))
            {
                var finder = new Regex(@"^ss://(?<base64>.+?)@(?<server>.+):(?<port>\d+)");
                var parser = new Regex(@"^(?<method>.+?):(?<password>.+)$");
                var match  = finder.Match(text);
                if (!match.Success)
                {
                    throw new FormatException();
                }

                data.Hostname = match.Groups["server"].Value;
                data.Port     = ushort.Parse(match.Groups["port"].Value);

                var base64 = ShareLink.URLSafeBase64Decode(match.Groups["base64"].Value);
                match = parser.Match(base64);
                if (!match.Success)
                {
                    throw new FormatException();
                }

                data.EncryptMethod = match.Groups["method"].Value;
                data.Password      = match.Groups["password"].Value;
            }
            else
            {
                var parser = new Regex(@"^((?<method>.+?):(?<password>.+)@(?<server>.+):(?<port>\d+))");
                var match  = parser.Match(ShareLink.URLSafeBase64Decode(text.Replace("ss://", "")));
                if (!match.Success)
                {
                    throw new FormatException();
                }

                data.Hostname      = match.Groups["server"].Value;
                data.Port          = ushort.Parse(match.Groups["port"].Value);
                data.EncryptMethod = match.Groups["method"].Value;
                data.Password      = match.Groups["password"].Value;
            }

            return(CheckServer(data) ? data : throw new FormatException());
        }
コード例 #7
0
        private void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var bak_State     = State;
            var bak_StateText = StatusLabel.Text;

            if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1)
            {
                Global.Settings.UseProxyToUpdateSubscription = false;
            }

            if (Global.Settings.UseProxyToUpdateSubscription)
            {
                // 当前 ServerComboBox 中至少有一项
                if (ServerComboBox.SelectedIndex == -1)
                {
                    MessageBoxX.Show(i18N.Translate("Please select a server first"));
                    return;
                }

                MenuStrip.Enabled  = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false;
                ControlButton.Text = "...";
            }

            if (Global.Settings.SubscribeLink.Count > 0)
            {
                StatusText(i18N.Translate("Starting update subscription"));
                DeleteServerPictureBox.Enabled = false;

                UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = false;
                Task.Run(() =>
                {
                    if (Global.Settings.UseProxyToUpdateSubscription)
                    {
                        var mode = new Models.Mode
                        {
                            Remark = "ProxyUpdate",
                            Type   = 5
                        };
                        _mainController = new MainController();
                        _mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
                    }

                    foreach (var item in Global.Settings.SubscribeLink)
                    {
                        using var client = new WebClient();
                        try
                        {
                            if (!string.IsNullOrEmpty(item.UserAgent))
                            {
                                client.Headers.Add("User-Agent", item.UserAgent);
                            }
                            else
                            {
                                client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36");
                            }

                            if (Global.Settings.UseProxyToUpdateSubscription)
                            {
                                client.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
                            }

                            var response = client.DownloadString(item.Link);

                            try
                            {
                                response = ShareLink.URLSafeBase64Decode(response);
                            }
                            catch (Exception)
                            {
                                // ignored
                            }

                            Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
                            var result             = ShareLink.Parse(response);

                            if (result != null)
                            {
                                foreach (var x in result)
                                {
                                    x.Group = item.Remark;
                                }

                                Global.Settings.Server.AddRange(result);
                                NotifyIcon.ShowBalloonTip(5,
                                                          UpdateChecker.Name,
                                                          string.Format(i18N.Translate("Update {1} server(s) from {0}"), item.Remark, result.Count),
                                                          ToolTipIcon.Info);
                            }
                            else
                            {
                                NotifyIcon.ShowBalloonTip(5,
                                                          UpdateChecker.Name,
                                                          string.Format(i18N.Translate("Update servers error from {0}"), item.Remark),
                                                          ToolTipIcon.Error);
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }

                    InitServer();
                    DeleteServerPictureBox.Enabled = true;
                    if (Global.Settings.UseProxyToUpdateSubscription)
                    {
                        MenuStrip.Enabled  = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
                        ControlButton.Text = i18N.Translate("Start");
                        _mainController.Stop();
                        NatTypeStatusLabel.Text = "";
                    }

                    Configuration.Save();
                    StatusText(i18N.Translate("Subscription updated"));

                    MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
                    State             = bak_State;
                    StatusLabel.Text  = bak_StateText;
                }).ContinueWith(task => { BeginInvoke(new Action(() => { UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true; })); });

                NotifyIcon.ShowBalloonTip(5,
                                          UpdateChecker.Name,
                                          i18N.Translate("Updating in the background"),
                                          ToolTipIcon.Info);
            }
            else
            {
                MessageBoxX.Show(i18N.Translate("No subscription link"));
            }
        }
コード例 #8
0
ファイル: VMessUtil.cs プロジェクト: tdw525/Netch
        public IEnumerable <Server> ParseUri(string text)
        {
            var data = new VMess();

            text = text.Substring(8);
            var vmess = JsonConvert.DeserializeObject <VMessJObject>(ShareLink.URLSafeBase64Decode(text));

            data.Remark           = vmess.ps;
            data.Hostname         = vmess.add;
            data.Port             = vmess.port;
            data.UserID           = vmess.id;
            data.AlterID          = vmess.aid;
            data.TransferProtocol = vmess.net;
            data.FakeType         = vmess.type;

            if (vmess.v == null || vmess.v == "1")
            {
                var info = vmess.host.Split(';');
                if (info.Length == 2)
                {
                    vmess.host = info[0];
                    vmess.path = info[1];
                }
            }

            if (data.TransferProtocol == "quic")
            {
                if (VMessGlobal.QUIC.Contains(vmess.host))
                {
                    data.QUICSecure = vmess.host;
                    data.QUICSecret = vmess.path;
                }
            }
            else
            {
                data.Host = vmess.host;
                data.Path = vmess.path;
            }

            data.TLSSecure = vmess.tls == "tls";

            if (vmess.mux == null)
            {
                data.UseMux = false;
            }
            else
            {
                if (vmess.mux.enabled is bool enabled)
                {
                    data.UseMux = enabled;
                }
                else if (vmess.mux.enabled is string muxEnabled)
                {
                    data.UseMux = muxEnabled == "true"; // 针对使用字符串当作布尔值的情况
                }
                else
                {
                    data.UseMux = false;
                }
            }

            data.EncryptMethod = "auto"; // V2Ray 加密方式不包括在链接中,主动添加一个
            return(CheckServer(data) ? new[] { data } : null);
        }
コード例 #9
0
        private async void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            void DisableItems(bool v)
            {
                MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ProfileGroupBox.Enabled = ControlButton.Enabled = v;
            }

            if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1)
            {
                Global.Settings.UseProxyToUpdateSubscription = false;
            }

            if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1)
            {
                MessageBoxX.Show(i18N.Translate("Please select a server first"));
                return;
            }

            if (Global.Settings.SubscribeLink.Count <= 0)
            {
                MessageBoxX.Show(i18N.Translate("No subscription link"));
                return;
            }

            StatusText(i18N.Translate("Starting update subscription"));
            DisableItems(false);
            try
            {
                if (Global.Settings.UseProxyToUpdateSubscription)
                {
                    var mode = new Models.Mode
                    {
                        Remark = "ProxyUpdate",
                        Type   = 5
                    };
                    await MainController.Start(ServerComboBox.SelectedItem as Models.Server, mode);
                }

                var serverLock = new object();

                await Task.WhenAll(Global.Settings.SubscribeLink.Select(async item => await Task.Run(async() =>
                {
                    try
                    {
                        var request = WebUtil.CreateRequest(item.Link);

                        if (!string.IsNullOrEmpty(item.UserAgent))
                        {
                            request.UserAgent = item.UserAgent;
                        }
                        if (Global.Settings.UseProxyToUpdateSubscription)
                        {
                            request.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
                        }

                        var str = await WebUtil.DownloadStringAsync(request);

                        try
                        {
                            str = ShareLink.URLSafeBase64Decode(str);
                        }
                        catch
                        {
                            // ignored
                        }

                        lock (serverLock)
                        {
                            Global.Settings.Server.RemoveAll(server => server.Group == item.Remark);

                            var result = ShareLink.Parse(str);
                            if (result != null)
                            {
                                foreach (var server in result)
                                {
                                    server.Group = item.Remark;
                                    Global.Settings.Server.Add(server);
                                }
                            }

                            NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, result?.Count ?? 0));
                        }
                    }
                    catch (WebException e)
                    {
                        NotifyTip($"{i18N.TranslateFormat("Update servers error from {0}", item.Remark)}\n{e.Message}", info: false);
                    }
                    catch (Exception e)
                    {
                        Logging.Error(e.ToString());
                    }
                })).ToArray());

                InitServer();
                Configuration.Save();
                StatusText(i18N.Translate("Subscription updated"));
            }
            catch (Exception)
            {
                // ignored
            }
            finally
            {
                if (Global.Settings.UseProxyToUpdateSubscription)
                {
                    await MainController.Stop();
                }

                DisableItems(true);
            }
        }
コード例 #10
0
ファイル: MainForm.MenuStrip.cs プロジェクト: terranZY/Netch
        private void UpdateServersFromSubscribeLinksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1)
            {
                Global.Settings.UseProxyToUpdateSubscription = false;
            }

            if (Global.Settings.UseProxyToUpdateSubscription && ServerComboBox.SelectedIndex == -1)
            {
                MessageBoxX.Show(i18N.Translate("Please select a server first"));
                return;
            }

            if (Global.Settings.SubscribeLink.Count > 0)
            {
                DeleteServerPictureBox.Enabled = false;
                UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = false;

                Task.Run(() =>
                {
                    if (Global.Settings.UseProxyToUpdateSubscription)
                    {
                        var mode = new Models.Mode
                        {
                            Remark = "ProxyUpdate",
                            Type   = 5
                        };
                        State = State.Starting;
                        if (_mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode))
                        {
                            StatusText(i18N.Translate("Starting update subscription"));
                        }
                    }
                    else
                    {
                        StatusText(i18N.Translate("Starting update subscription"));
                    }

                    Task.WaitAll(Global.Settings.SubscribeLink.Select(item => Task.Factory.StartNew(() =>
                    {
                        try
                        {
                            var request = WebUtil.CreateRequest(item.Link);

                            if (!string.IsNullOrEmpty(item.UserAgent))
                            {
                                request.UserAgent = item.UserAgent;
                            }
                            if (Global.Settings.UseProxyToUpdateSubscription)
                            {
                                request.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
                            }

                            var str = WebUtil.DownloadString(request);

                            try
                            {
                                str = ShareLink.URLSafeBase64Decode(str);
                            }
                            catch
                            {
                                // ignored
                            }

                            Global.Settings.Server = Global.Settings.Server.Where(server => server.Group != item.Remark).ToList();
                            var result             = ShareLink.Parse(str);

                            if (result != null)
                            {
                                foreach (var x in result)
                                {
                                    x.Group = item.Remark;
                                }

                                Global.Settings.Server.AddRange(result);
                                NotifyTip(i18N.TranslateFormat("Update {1} server(s) from {0}", item.Remark, result.Count));
                            }
                        }
                        catch (WebException e)
                        {
                            NotifyTip($"{i18N.TranslateFormat("Update servers error from {0}", item.Remark)}\n{e.Message}", info: false);
                        }
                    })).ToArray());

                    InitServer();

                    Configuration.Save();
                    NotifyTip(i18N.Translate("Subscription updated"));

                    if (Global.Settings.UseProxyToUpdateSubscription)
                    {
                        _mainController.Stop();
                        State = State.Stopped;
                    }

                    State = State.Waiting;
                    DeleteModePictureBox.Enabled = true;
                    MenuStrip.Enabled            = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = true;
                    UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled = true;
                });

                NotifyTip(i18N.Translate("Updating in the background"));
            }
            else
            {
                MessageBoxX.Show(i18N.Translate("No subscription link"));
            }
        }
コード例 #11
0
ファイル: SSRUtil.cs プロジェクト: skyenqa/Netch-XD
        /// <summary>
        ///     SSR链接解析器
        ///     Copy From
        ///     https://github.com/HMBSbige/ShadowsocksR-Windows/blob/d9dc8d032a6e04c14b9dc6c8f673c9cc5aa9f607/shadowsocks-csharp/Model/Server.cs#L428
        ///     Thx :D
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public IEnumerable <Server> ParseUri(string text)
        {
            // ssr://host:port:protocol:method:obfs:base64pass/?obfsparam=base64&remarks=base64&group=base64&udpport=0&uot=1
            var ssr = Regex.Match(text, "ssr://([A-Za-z0-9_-]+)", RegexOptions.IgnoreCase);

            if (!ssr.Success)
            {
                throw new FormatException();
            }

            var data       = ShareLink.URLSafeBase64Decode(ssr.Groups[1].Value);
            var paramsDict = new Dictionary <string, string>();

            var paramStartPos = data.IndexOf("?", StringComparison.Ordinal);

            if (paramStartPos > 0)
            {
                paramsDict = ShareLink.ParseParam(data.Substring(paramStartPos + 1));
                data       = data.Substring(0, paramStartPos);
            }

            if (data.IndexOf("/", StringComparison.Ordinal) >= 0)
            {
                data = data.Substring(0, data.LastIndexOf("/", StringComparison.Ordinal));
            }

            var urlFinder = new Regex("^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)");
            var match     = urlFinder.Match(data);

            if (match == null || !match.Success)
            {
                throw new FormatException();
            }

            var serverAddr = match.Groups[1].Value;
            var serverPort = ushort.Parse(match.Groups[2].Value);
            var protocol   = match.Groups[3].Value.Length == 0 ? "origin" : match.Groups[3].Value;

            protocol = protocol.Replace("_compatible", "");
            var method = match.Groups[4].Value;
            var obfs   = match.Groups[5].Value.Length == 0 ? "plain" : match.Groups[5].Value;

            obfs = obfs.Replace("_compatible", "");
            var password      = ShareLink.URLSafeBase64Decode(match.Groups[6].Value);
            var protocolParam = "";
            var obfsParam     = "";
            var remarks       = "";

            if (paramsDict.ContainsKey("protoparam"))
            {
                protocolParam = ShareLink.URLSafeBase64Decode(paramsDict["protoparam"]);
            }

            if (paramsDict.ContainsKey("obfsparam"))
            {
                obfsParam = ShareLink.URLSafeBase64Decode(paramsDict["obfsparam"]);
            }

            if (paramsDict.ContainsKey("remarks"))
            {
                remarks = ShareLink.URLSafeBase64Decode(paramsDict["remarks"]);
            }

            var group = paramsDict.ContainsKey("group") ? ShareLink.URLSafeBase64Decode(paramsDict["group"]) : string.Empty;

            if (SSGlobal.EncryptMethods.Contains(method) && protocol == "origin" && obfs == "plain")
            {
                return new[]
                       {
                           new Shadowsocks.Shadowsocks
                           {
                               Hostname      = serverAddr,
                               Port          = serverPort,
                               EncryptMethod = method,
                               Password      = password,
                               Remark        = remarks,
                               Group         = group
                           }
                       }
            }
            ;

            return(new[]
            {
                new ShadowsocksR
                {
                    Hostname = serverAddr,
                    Port = serverPort,
                    Protocol = protocol,
                    EncryptMethod = method,
                    OBFS = obfs,
                    Password = password,
                    ProtocolParam = protocolParam,
                    OBFSParam = obfsParam,
                    Remark = remarks,
                    Group = group
                }
            });
        }