/// <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 } }); }