public static List <Models.Server> Parse(string text) { var list = new List <Models.Server>(); try { if (text.StartsWith("tg://socks?") || text.StartsWith("https://t.me/socks?")) { var data = new Models.Server(); data.Type = "Socks5"; var dict = new Dictionary <string, string>(); foreach (var str in text.Replace("tg://socks?", "").Replace("https://t.me/socks?", "").Split('&')) { var splited = str.Split('='); dict.Add(splited[0], splited[1]); } if (!dict.ContainsKey("server") || !dict.ContainsKey("port")) { return(null); } data.Hostname = dict["server"]; data.Port = int.Parse(dict["port"]); if (dict.ContainsKey("user") && !String.IsNullOrWhiteSpace(dict["user"])) { data.Username = dict["user"]; } if (dict.ContainsKey("pass") && !String.IsNullOrWhiteSpace(dict["pass"])) { data.Password = dict["pass"]; } list.Add(data); } else if (text.StartsWith("ss://")) { var data = new Models.Server(); data.Type = "SS"; /* * try * { * if(!text.Contains("/?")) * { * var finder = new Regex(@"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\S+))?", RegexOptions.IgnoreCase); * var parser = new Regex(@"^((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\d+?))$", RegexOptions.IgnoreCase); * var match = finder.Match(text); * if (!match.Success) * { * throw new FormatException(); * } * * var base64 = match.Groups["base64"].Value.TrimEnd('/'); * var tag = match.Groups["tag"].Value; * if (!String.IsNullOrEmpty(tag)) * { * data.Remark = HttpUtility.UrlDecode(tag); * } * * match = parser.Match(URLSafeBase64Decode(base64)); * if (!match.Success) * { * throw new FormatException(); * } * * data.Address = match.Groups["hostname"].Value; * data.Port = int.Parse(match.Groups["port"].Value); * data.Password = match.Groups["password"].Value; * data.EncryptMethod = match.Groups["method"].Value; * } * else * { * if (text.Contains("#")) * { * data.Remark = HttpUtility.UrlDecode(text.Split('#')[1]); * text = text.Split('#')[0]; * } * var finder = new Regex(@"ss://(?<base64>.+?)@(?<server>.+?):(?<port>\d+?)/\?plugin=(?<plugin>.+)"); * var parser = new Regex(@"^(?<method>.+?):(?<password>.+)$"); * var match = finder.Match(text); * if (!match.Success) * { * throw new FormatException(); * } * * data.Address = match.Groups["server"].Value; * data.Port = int.Parse(match.Groups["port"].Value); * var plugins = HttpUtility.UrlDecode(match.Groups["plugin"].Value).Split(';'); * if (plugins[0] == "obfs-local") * plugins[0] = "simple-obfs"; * * var base64 = 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; * data.Plugin = plugins[0]; * data.PluginOption = plugins[1]; * } * * if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod)) * { * Logging.Info(String.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod)); * return null; * } * * list.Add(data); * } * catch (FormatException) * { * try * { * var uri = new Uri(text); * var userinfo = URLSafeBase64Decode(uri.UserInfo).Split(new char[] { ':' }, 2); * if (userinfo.Length != 2) * { * return null; * } * * data.Remark = uri.GetComponents(UriComponents.Fragment, UriFormat.Unescaped); * data.Address = uri.IdnHost; * data.Port = uri.Port; * data.Password = userinfo[1]; * data.EncryptMethod = userinfo[0]; * * if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod)) * { * Logging.Info(String.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod)); * return null; * } * * list.Add(data); * } * catch (UriFormatException) * { * return null; * } * } */ text = text.Replace("/?", "?"); try { 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) { var plugins = HttpUtility.UrlDecode(HttpUtility.ParseQueryString(new Uri(text).Query).Get("plugin")); var plugin = plugins.Substring(0, plugins.IndexOf(";")); var pluginopts = plugins.Substring(plugins.IndexOf(";") + 1); if (plugin == "obfs-local" || plugin == "simple-obfs") { plugin = "simple-obfs"; if (!pluginopts.Contains("obfs=")) { pluginopts = "obfs=http;obfs-host=" + pluginopts; } } else if (plugin == "simple-obfs-tls") { plugin = "simple-obfs"; if (!pluginopts.Contains("obfs=")) { pluginopts = "obfs=tls;obfs-host=" + pluginopts; } } data.Plugin = plugin; data.PluginOption = pluginopts; text = match.Groups["data"].Value; } else { throw new FormatException(); } } 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 = int.Parse(match.Groups["port"].Value); var base64 = 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(URLSafeBase64Decode(text.Replace("ss://", ""))); if (!match.Success) { throw new FormatException(); } data.Hostname = match.Groups["server"].Value; data.Port = int.Parse(match.Groups["port"].Value); data.EncryptMethod = match.Groups["method"].Value; data.Password = match.Groups["password"].Value; } if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod)) { Logging.Info(String.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod)); return(null); } list.Add(data); } catch (FormatException) { return(null); } } else if (text.StartsWith("ssd://")) { var json = Newtonsoft.Json.JsonConvert.DeserializeObject <Models.SSD.Main>(URLSafeBase64Decode(text.Substring(6))); foreach (var server in json.servers) { var data = new Models.Server(); data.Type = "SS"; data.Remark = server.remarks; data.Hostname = server.server; data.Port = (server.port != 0) ? server.port : json.port; data.Password = (server.password != null) ? server.password : json.password; data.EncryptMethod = (server.encryption != null) ? server.encryption : json.encryption; data.Plugin = (String.IsNullOrEmpty(json.plugin)) ? (String.IsNullOrEmpty(server.plugin) ? null : server.plugin) : json.plugin; data.PluginOption = (String.IsNullOrEmpty(json.plugin_options)) ? (String.IsNullOrEmpty(server.plugin_options) ? null : server.plugin_options) : json.plugin_options; if (Global.EncryptMethods.SS.Contains(data.EncryptMethod)) { list.Add(data); } } } else if (text.StartsWith("ssr://")) { var data = new Models.Server(); data.Type = "SSR"; text = text.Substring(6); /* * var shadowsocksr = URLSafeBase64Decode(text).Split(':'); * * if (shadowsocksr.Length > 6) * { * var buff = ""; * * for (int i = 0; i < shadowsocksr.Length - 5; i++) * { * buff += shadowsocksr[i]; * buff += ":"; * } * * data.Address = buff.Substring(0, buff.Length - 1).Trim(); * } * else * { * data.Address = shadowsocksr[0]; * } * data.Port = int.Parse(shadowsocksr[shadowsocksr.Length - 5]); * data.Protocol = shadowsocksr[shadowsocksr.Length - 4]; * if (!Global.Protocols.Contains(data.Protocol)) * { * Logging.Info(String.Format("不支持的 SSR 协议:{0}", data.Protocol)); * return null; * } * * data.EncryptMethod = shadowsocksr[shadowsocksr.Length - 3]; * if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod)) * { * Logging.Info(String.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod)); * return null; * } * * data.OBFS = shadowsocksr[shadowsocksr.Length - 2]; * if (!Global.OBFSs.Contains(data.OBFS)) * { * Logging.Info(String.Format("不支持的 SSR 混淆:{0}", data.OBFS)); * return null; * } * * var info = shadowsocksr[shadowsocksr.Length - 1].Split('/'); * data.Password = URLSafeBase64Decode(info[0]); * * var dict = new Dictionary<string, string>(); * if (info.Length > 1 && info[1].Length > 1) * { * foreach (var str in info[1].Substring(1).Split('&')) * { * var splited = str.Split('='); * * dict.Add(splited[0], splited[1]); * } * } * * if (dict.ContainsKey("remarks")) * { * data.Remark = URLSafeBase64Decode(dict["remarks"]); * } * * if (dict.ContainsKey("protoparam")) * { * data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]); * } * * if (dict.ContainsKey("obfsparam")) * { * data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]); * } * * if (data.EncryptMethod != "none" && data.Protocol == "origin" && data.OBFS == "plain") * { * data.Type = "SS"; * } */ var parser = new Regex(@"^(?<server>.+):(?<port>\d+?):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$"); var match = parser.Match(URLSafeBase64Decode(text)); if (match.Success) { data.Hostname = match.Groups["server"].Value; data.Port = int.Parse(match.Groups["port"].Value); data.Password = URLSafeBase64Decode(match.Groups["password"].Value); data.EncryptMethod = match.Groups["method"].Value; if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod)) { Logging.Info(String.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod)); return(null); } data.Protocol = match.Groups["protocol"].Value; if (!Global.Protocols.Contains(data.Protocol)) { Logging.Info(String.Format("不支持的 SSR 协议:{0}", data.Protocol)); return(null); } data.OBFS = match.Groups["obfs"].Value; if (!Global.OBFSs.Contains(data.OBFS)) { Logging.Info(String.Format("不支持的 SSR 混淆:{0}", data.OBFS)); return(null); } var info = match.Groups["info"].Value; var dict = new Dictionary <string, string>(); foreach (var str in info.Split('&')) { var splited = str.Split('='); dict.Add(splited[0], splited[1]); } if (dict.ContainsKey("remarks")) { data.Remark = URLSafeBase64Decode(dict["remarks"]); } if (dict.ContainsKey("protoparam")) { data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]); } if (dict.ContainsKey("obfsparam")) { data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]); } if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain") { data.OBFS = ""; data.Type = "SS"; } } list.Add(data); } else if (text.StartsWith("vmess://")) { var data = new Models.Server(); data.Type = "VMess"; text = text.Substring(8); var vmess = Newtonsoft.Json.JsonConvert.DeserializeObject <Models.VMess>(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; if (!Global.TransferProtocols.Contains(data.TransferProtocol)) { Logging.Info(String.Format("不支持的 VMess 传输协议:{0}", data.TransferProtocol)); return(null); } data.FakeType = vmess.type; if (!Global.FakeTypes.Contains(data.FakeType)) { Logging.Info(String.Format("不支持的 VMess 伪装类型:{0}", data.FakeType)); return(null); } 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 (!Global.EncryptMethods.VMessQUIC.Contains(vmess.host)) { Logging.Info(String.Format("不支持的 VMess QUIC 加密方式:{0}", vmess.host)); return(null); } else { 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 加密方式不包括在链接中,主动添加一个 list.Add(data); } else if (text.StartsWith("Netch://")) { text = text.Substring(8); var NetchLink = Newtonsoft.Json.JsonConvert.DeserializeObject <Models.Server>(URLSafeBase64Decode(text)); if (!String.IsNullOrEmpty(NetchLink.Hostname) || NetchLink.Port > 65536 || NetchLink.Port > 0) { return(null); } switch (NetchLink.Type) { case "Socks5": list.Add(NetchLink); break; case "SS": if (!Global.EncryptMethods.SS.Contains(NetchLink.EncryptMethod)) { Logging.Info($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}"); return(null); } break; case "SSR": if (!Global.EncryptMethods.SSR.Contains(NetchLink.EncryptMethod)) { Logging.Info($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}"); return(null); } if (!Global.Protocols.Contains(NetchLink.Protocol)) { Logging.Info($"不支持的 SSR 协议:{NetchLink.Protocol}"); return(null); } if (!Global.OBFSs.Contains(NetchLink.OBFS)) { Logging.Info($"不支持的 SSR 混淆:{NetchLink.OBFS}"); return(null); } break; case "VMess": if (!Global.TransferProtocols.Contains(NetchLink.TransferProtocol)) { Logging.Info($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}"); return(null); } if (!Global.FakeTypes.Contains(NetchLink.FakeType)) { Logging.Info($"不支持的 VMess 伪装类型:{NetchLink.FakeType}"); return(null); } if (NetchLink.TransferProtocol == "quic") { if (!Global.EncryptMethods.VMessQUIC.Contains(NetchLink.QUICSecure)) { Logging.Info($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}"); return(null); } } break; default: return(null); } list.Add(NetchLink); } else { System.Windows.Forms.MessageBox.Show("未找到可导入的链接!", "错误", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation); return(null); } } catch (Exception e) { Logging.Info(e.ToString()); return(null); } return(list); }
/// <summary> /// 根据程序名统计流量 /// </summary> /// <param name="ProcessName"></param> public static void NetTraffic(Server server, Mode mode, MainController mainController) { var counterLock = new object(); //int sent = 0; //var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet(); var processList = new List <int>(); if (server.Type.Equals("Socks5") && mainController.pHTTPController != null) { processList.Add(mainController.pHTTPController.pPrivoxyController.Instance.Id); } else if (server.Type.Equals("SS") && Global.Settings.BootShadowsocksFromDLL) { processList.Add(Process.GetCurrentProcess().Id); } else if (server.Type.Equals("SS") && mainController.pSSController != null) { processList.Add(mainController.pSSController.Instance.Id); } else if (server.Type.Equals("SSR") && mainController.pSSRController != null) { processList.Add(mainController.pSSRController.Instance.Id); } else if (server.Type.Equals("VMess") && mainController.pVMessController != null) { processList.Add(mainController.pVMessController.Instance.Id); } else if (server.Type.Equals("TR") && mainController.pTrojanController != null) { processList.Add(mainController.pTrojanController.Instance.Id); } else if (mainController.pTUNTAPController != null) { processList.Add(mainController.pTUNTAPController.Instance.Id); } else if (mainController.pNFController != null) { processList.Add(mainController.pNFController.Instance.Id); } Logging.Info("启动流量统计 PID:" + string.Join(",", processList.ToArray())); Task.Run(() => { using (var session = new TraceEventSession("KernelAndClrEventsSession")) { session.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP); //这玩意儿上传和下载得到的data是一样的:) //所以暂时没办法区分上传下载流量 session.Source.Kernel.TcpIpRecv += data => { if (processList.Contains(data.ProcessID)) { lock (counterLock) received += data.size; //Logging.Info($"TcpIpRecv: {Compute(data.size)}"); } }; session.Source.Kernel.UdpIpRecv += data => { if (processList.Contains(data.ProcessID)) { lock (counterLock) received += data.size; //Logging.Info($"UdpIpRecv: {Compute(data.size)}"); } }; session.Source.Process(); } }); //if ((Convert.ToInt32(MainForm.Instance.LastDownloadBandwidth) - Convert.ToInt32(received)) == 0) //{ // MainForm.Instance.OnBandwidthUpdated(0); // received = 0; //} //while (MainForm.Instance.State != State.Stopped) //{ // Task.Delay(1000).Wait(); // lock (counterLock) // { // MainForm.Instance.OnBandwidthUpdated(Convert.ToInt64(received)); // } //} }
/// <summary> /// 搜索出口 /// </summary> public static bool SearchOutbounds() { Logging.Info("正在搜索出口中"); if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0) { Global.Adapter.Index = pRoute.dwForwardIfIndex; Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop); Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}"); } else { Logging.Info("GetBestRoute 搜索失败"); return(false); } Logging.Info($"搜索适配器index:{Global.Adapter.Index}"); var AddressGot = false; foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) { try { var adapterProperties = adapter.GetIPProperties(); var p = adapterProperties.GetIPv4Properties(); Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}"); // 通过索引查找对应适配器的 IPv4 地址 if (p.Index == Global.Adapter.Index) { var AdapterIPs = ""; foreach (var ip in adapterProperties.UnicastAddresses) { if (ip.Address.AddressFamily == AddressFamily.InterNetwork) { AddressGot = true; Global.Adapter.Address = ip.Address; Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}"); break; } AdapterIPs = $"{ip.Address} | "; } if (!AddressGot) { if (AdapterIPs.Length > 3) { AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3); Logging.Info($"所有出口地址:{AdapterIPs}"); } Logging.Info("出口无 IPv4 地址,当前只支持 IPv4 地址"); return(false); } break; } } catch (Exception) { } } if (!AddressGot) { Logging.Info("无法找到当前使用适配器"); return(false); } // 搜索 TUN/TAP 适配器的索引 Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID)) { Logging.Info("未找到可用 TUN/TAP 适配器"); if (MessageBox.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK) { addtap(); //给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID Thread.Sleep(1000); Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); } else { return(false); } //MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); // return false; } foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) { if (adapter.Id == Global.TUNTAP.ComponentID) { Global.TUNTAP.Adapter = adapter; Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index; Logging.Info($"找到适配器:{adapter.Id}"); return(true); } } Logging.Info("无法找到出口"); return(false); }
/// <summary> /// 搜索出口 /// </summary> public static bool SearchOutbounds() { Logging.Info("正在搜索出口中"); if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0) { Global.Adapter.Index = pRoute.dwForwardIfIndex; Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop); Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}"); } else { Logging.Info("GetBestRoute 搜索失败"); return(false); } foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) { var adapterProperties = adapter.GetIPProperties(); var p = adapterProperties.GetIPv4Properties(); // 通过索引查找对应适配器的 IPv4 地址 if (p.Index == Global.Adapter.Index) { var AddressGot = false; var AdapterIPs = ""; foreach (var ip in adapterProperties.UnicastAddresses) { if (ip.Address.AddressFamily == AddressFamily.InterNetwork) { AddressGot = true; Global.Adapter.Address = ip.Address; Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}"); break; } AdapterIPs = $"{ip.Address} | "; } if (!AddressGot) { if (AdapterIPs.Length > 3) { AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3); Logging.Info($"所有出口地址:{AdapterIPs}"); } Logging.Info("出口无 IPv4 地址,当前只支持 IPv4 地址"); return(false); } break; } } // 搜索 TUN/TAP 适配器的索引 Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID)) { if (MessageBox.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), i18N.Translate("Information"), MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK) { //安装Tap Driver Process installProcess = new Process(); installProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; installProcess.StartInfo.FileName = Path.Combine("bin/tap-driver", "install.bat"); installProcess.Start(); installProcess.WaitForExit(); installProcess.Close(); Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); } else { return(false); } //MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); // return false; } foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) { if (adapter.Id == Global.TUNTAP.ComponentID) { Global.TUNTAP.Adapter = adapter; Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index; return(true); } } Logging.Info("无法找到出口"); return(false); }
/// <summary> /// 搜索出口 /// </summary> public static bool SearchOutbounds() { Logging.Info("正在搜索出口中"); if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0) { Global.Adapter.Index = pRoute.dwForwardIfIndex; Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop); Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}"); } else { Logging.Info($"GetBestRoute 搜索失败"); return(false); } foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) { IPInterfaceProperties adapterProperties = adapter.GetIPProperties(); IPv4InterfaceProperties p = adapterProperties.GetIPv4Properties(); // 通过索引查找对应适配器的 IPv4 地址 if (p.Index == Global.Adapter.Index) { var AddressGot = false; String AdapterIPs = ""; foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses) { if (ip.Address.AddressFamily == AddressFamily.InterNetwork) { AddressGot = true; Global.Adapter.Address = ip.Address; Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}"); break; } AdapterIPs = $"{ip.Address.ToString()} | "; } if (!AddressGot) { if (AdapterIPs.Length > 3) { AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3); Logging.Info($"所有出口地址:{AdapterIPs}"); } Logging.Info($"出口无 IPv4 地址,当前只支持 IPv4 地址"); return(false); } break; } } // 搜索 TUN/TAP 适配器的索引 Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); if (String.IsNullOrEmpty(Global.TUNTAP.ComponentID)) { MessageBox.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually"), i18N.Translate("Information"), MessageBoxButtons.OK, MessageBoxIcon.Information); return(false); } var name = TUNTAP.GetName(Global.TUNTAP.ComponentID); foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) { if (adapter.Name == name) { Global.TUNTAP.Adapter = adapter; Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index; break; } } return(true); }
private static IEnumerable <Server> ParseLine(string text) { var list = new List <Server>(); try { if (text.StartsWith("tg://socks?") || text.StartsWith("https://t.me/socks?")) { var data = new Server(); data.Type = "Socks5"; var dict = new Dictionary <string, string>(); foreach (var str in text.Replace("tg://socks?", "").Replace("https://t.me/socks?", "").Split('&')) { var splited = str.Split('='); dict.Add(splited[0], splited[1]); } if (!dict.ContainsKey("server") || !dict.ContainsKey("port")) { return(null); } data.Hostname = dict["server"]; data.Port = int.Parse(dict["port"]); if (dict.ContainsKey("user") && !string.IsNullOrWhiteSpace(dict["user"])) { data.Username = dict["user"]; } if (dict.ContainsKey("pass") && !string.IsNullOrWhiteSpace(dict["pass"])) { data.Password = dict["pass"]; } list.Add(data); } else if (text.StartsWith("ss://")) { var data = new Server(); data.Type = "SS"; text = text.Replace("/?", "?"); try { 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) { 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); if (plugin == "obfs-local" || plugin == "simple-obfs") { plugin = "simple-obfs"; if (!pluginopts.Contains("obfs=")) { pluginopts = "obfs=http;obfs-host=" + pluginopts; } } else if (plugin == "simple-obfs-tls") { plugin = "simple-obfs"; if (!pluginopts.Contains("obfs=")) { pluginopts = "obfs=tls;obfs-host=" + pluginopts; } } data.Plugin = plugin; data.PluginOption = pluginopts; } text = match.Groups["data"].Value; } else { throw new FormatException(); } } 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 = int.Parse(match.Groups["port"].Value); var base64 = 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(URLSafeBase64Decode(text.Replace("ss://", ""))); if (!match.Success) { throw new FormatException(); } data.Hostname = match.Groups["server"].Value; data.Port = int.Parse(match.Groups["port"].Value); data.EncryptMethod = match.Groups["method"].Value; data.Password = match.Groups["password"].Value; } if (!Global.EncryptMethods.SS.Contains(data.EncryptMethod)) { Logging.Info(string.Format("不支持的 SS 加密方式:{0}", data.EncryptMethod)); return(null); } list.Add(data); } catch (FormatException) { return(null); } } else if (text.StartsWith("ssd://")) { var json = JsonConvert.DeserializeObject <Models.SSD.Main>(URLSafeBase64Decode(text.Substring(6))); foreach (var server in json.servers) { var data = new Server(); data.Type = "SS"; data.Remark = server.remarks; data.Hostname = server.server; data.Port = server.port != 0 ? server.port : json.port; data.Password = server.password != null ? server.password : json.password; data.EncryptMethod = server.encryption != null ? server.encryption : json.encryption; data.Plugin = string.IsNullOrEmpty(json.plugin) ? string.IsNullOrEmpty(server.plugin) ? null : server.plugin : json.plugin; data.PluginOption = string.IsNullOrEmpty(json.plugin_options) ? string.IsNullOrEmpty(server.plugin_options) ? null : server.plugin_options : json.plugin_options; if (Global.EncryptMethods.SS.Contains(data.EncryptMethod)) { list.Add(data); } } } else if (text.StartsWith("ssr://")) { var data = new Server(); data.Type = "SSR"; text = text.Substring(6); var parser = new Regex(@"^(?<server>.+):(?<port>(-?\d+?)):(?<protocol>.+?):(?<method>.+?):(?<obfs>.+?):(?<password>.+?)/\?(?<info>.*)$"); var match = parser.Match(URLSafeBase64Decode(text)); if (match.Success) { data.Hostname = match.Groups["server"].Value; data.Port = int.Parse(match.Groups["port"].Value); if (data.Port < 0) { data.Port += 65536; } data.Password = URLSafeBase64Decode(match.Groups["password"].Value); data.EncryptMethod = match.Groups["method"].Value; if (!Global.EncryptMethods.SSR.Contains(data.EncryptMethod)) { Logging.Info(string.Format("不支持的 SSR 加密方式:{0}", data.EncryptMethod)); return(null); } data.Protocol = match.Groups["protocol"].Value; if (!Global.Protocols.Contains(data.Protocol)) { Logging.Info(string.Format("不支持的 SSR 协议:{0}", data.Protocol)); return(null); } data.OBFS = match.Groups["obfs"].Value; if (data.OBFS == @"tls1.2_ticket_fastauth") { data.OBFS = @"tls1.2_ticket_auth"; } if (!Global.OBFSs.Contains(data.OBFS)) { Logging.Info(string.Format("不支持的 SSR 混淆:{0}", data.OBFS)); return(null); } var info = match.Groups["info"].Value; var dict = new Dictionary <string, string>(); foreach (var str in info.Split('&')) { var splited = str.Split('='); dict.Add(splited[0], splited[1]); } if (dict.ContainsKey("remarks")) { data.Remark = URLSafeBase64Decode(dict["remarks"]); } if (dict.ContainsKey("protoparam")) { data.ProtocolParam = URLSafeBase64Decode(dict["protoparam"]); } if (dict.ContainsKey("obfsparam")) { data.OBFSParam = URLSafeBase64Decode(dict["obfsparam"]); } if (Global.EncryptMethods.SS.Contains(data.EncryptMethod) && data.Protocol == "origin" && data.OBFS == "plain") { data.OBFS = ""; data.Type = "SS"; } } list.Add(data); } else if (text.StartsWith("vmess://")) { var data = new Server(); data.Type = "VMess"; text = text.Substring(8); var vmess = JsonConvert.DeserializeObject <VMess>(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; if (!Global.TransferProtocols.Contains(data.TransferProtocol)) { Logging.Info(string.Format("不支持的 VMess 传输协议:{0}", data.TransferProtocol)); return(null); } data.FakeType = vmess.type; if (!Global.FakeTypes.Contains(data.FakeType)) { Logging.Info(string.Format("不支持的 VMess 伪装类型:{0}", data.FakeType)); return(null); } 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 (!Global.EncryptMethods.VMessQUIC.Contains(vmess.host)) { Logging.Info(string.Format("不支持的 VMess QUIC 加密方式:{0}", vmess.host)); return(null); } 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 加密方式不包括在链接中,主动添加一个 list.Add(data); } else if (text.StartsWith("Netch://")) { text = text.Substring(8); var NetchLink = JsonConvert.DeserializeObject <Server>(URLSafeBase64Decode(text)); if (!string.IsNullOrEmpty(NetchLink.Hostname) || NetchLink.Port > 65536 || NetchLink.Port > 0) { return(null); } switch (NetchLink.Type) { case "Socks5": list.Add(NetchLink); break; case "SS": if (!Global.EncryptMethods.SS.Contains(NetchLink.EncryptMethod)) { Logging.Info($"不支持的 SS 加密方式:{NetchLink.EncryptMethod}"); return(null); } break; case "SSR": if (!Global.EncryptMethods.SSR.Contains(NetchLink.EncryptMethod)) { Logging.Info($"不支持的 SSR 加密方式:{NetchLink.EncryptMethod}"); return(null); } if (!Global.Protocols.Contains(NetchLink.Protocol)) { Logging.Info($"不支持的 SSR 协议:{NetchLink.Protocol}"); return(null); } if (!Global.OBFSs.Contains(NetchLink.OBFS)) { Logging.Info($"不支持的 SSR 混淆:{NetchLink.OBFS}"); return(null); } break; case "VMess": if (!Global.TransferProtocols.Contains(NetchLink.TransferProtocol)) { Logging.Info($"不支持的 VMess 传输协议:{NetchLink.TransferProtocol}"); return(null); } if (!Global.FakeTypes.Contains(NetchLink.FakeType)) { Logging.Info($"不支持的 VMess 伪装类型:{NetchLink.FakeType}"); return(null); } if (NetchLink.TransferProtocol == "quic") { if (!Global.EncryptMethods.VMessQUIC.Contains(NetchLink.QUICSecure)) { Logging.Info($"不支持的 VMess QUIC 加密方式:{NetchLink.QUICSecure}"); return(null); } } break; default: return(null); } list.Add(NetchLink); } } catch (Exception e) { Logging.Info(e.ToString()); return(null); } return(list); }