diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index 148e1d0..09d8e74 100644 --- a/src/speedtestutil.cpp +++ b/src/speedtestutil.cpp @@ -39,6 +39,11 @@ template T safe_as (const YAML::Node& node) return T(); }; +template void operator >>= (const YAML::Node& node, T& i) +{ + i = safe_as(node); +}; + void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &node) { std::string version, ps, add, port, type, id, aid, net, path, host, tls; @@ -978,23 +983,22 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s void explodeClash(Node yamlnode, const std::string &custom_port, std::vector &nodes, bool ss_libev, bool ssr_libev) { + std::string proxytype, ps, server, port, cipher, group, password; //common + std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls; //vmess + std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss + std::string protocol, protoparam, obfs, obfsparam; //ssr + std::string user; //socks + tribool udp, tfo, scv; nodeInfo node; Node singleproxy; unsigned int index = nodes.size(); const std::string section = yamlnode["proxies"].IsDefined() ? "proxies" : "Proxy"; for(unsigned int i = 0; i < yamlnode[section].size(); i++) { - std::string proxytype, ps, server, port, cipher, group, password; //common - std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls; //vmess - std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss - std::string protocol, protoparam, obfs, obfsparam; //ssr - std::string user; //socks - tribool udp, tfo, scv; - singleproxy = yamlnode[section][i]; - singleproxy["type"] >> proxytype; - singleproxy["name"] >> ps; - singleproxy["server"] >> server; + singleproxy["type"] >>= proxytype; + singleproxy["name"] >>= ps; + singleproxy["server"] >>= server; port = custom_port.empty() ? safe_as(singleproxy["port"]) : custom_port; if(port.empty()) continue; @@ -1005,23 +1009,14 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> id; - singleproxy["alterId"] >> aid; - singleproxy["cipher"] >> cipher; + singleproxy["uuid"] >>= id; + singleproxy["alterId"] >>= aid; + singleproxy["cipher"] >>= cipher; net = singleproxy["network"].IsDefined() ? safe_as(singleproxy["network"]) : "tcp"; path = singleproxy["ws-path"].IsDefined() ? safe_as(singleproxy["ws-path"]) : "/"; - if(singleproxy["tls"].IsDefined()) - tls = safe_as(singleproxy["tls"]) == "true" ? "tls" : ""; - else - tls.clear(); - if(singleproxy["ws-headers"].IsDefined()) - { - singleproxy["ws-headers"]["Host"] >> host; - singleproxy["ws-headers"]["Edge"] >> edge; - } - else - host.clear(); - + tls = safe_as(singleproxy["tls"]) == "true" ? "tls" : ""; + singleproxy["ws-headers"]["Host"] >>= host; + singleproxy["ws-headers"]["Edge"] >>= edge; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.proxyStr = vmessConstruct(server, port, type, id, aid, net, cipher, path, host, edge, tls, udp, tfo, scv); @@ -1029,8 +1024,8 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> cipher; - singleproxy["password"] >> password; + singleproxy["cipher"] >>= cipher; + singleproxy["password"] >>= password; if(singleproxy["plugin"].IsDefined()) { switch(hash_(safe_as(singleproxy["plugin"]))) @@ -1039,34 +1034,19 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> pluginopts_mode; - if(singleproxy["plugin-opts"]["host"].IsDefined()) - singleproxy["plugin-opts"]["host"] >> pluginopts_host; - else - pluginopts_host.clear(); + singleproxy["plugin-opts"]["mode"] >>= pluginopts_mode; + singleproxy["plugin-opts"]["host"] >>= pluginopts_host; } break; case "v2ray-plugin"_hash: plugin = "v2ray-plugin"; if(singleproxy["plugin-opts"].IsDefined()) { - singleproxy["plugin-opts"]["mode"] >> pluginopts_mode; - if(singleproxy["plugin-opts"]["host"].IsDefined()) - singleproxy["plugin-opts"]["host"] >> pluginopts_host; - else - pluginopts_host.clear(); - if(singleproxy["plugin-opts"]["tls"].IsDefined()) - tls = safe_as(singleproxy["plugin-opts"]["tls"]) ? "tls;" : ""; - else - tls.clear(); - if(singleproxy["plugin-opts"]["path"].IsDefined()) - singleproxy["plugin-opts"]["path"] >> path; - else - path.clear(); - if(singleproxy["plugin-opts"]["mux"].IsDefined()) - pluginopts_mux = safe_as(singleproxy["plugin-opts"]["mux"]) ? "mux=4;" : ""; - else - pluginopts_mux.clear(); + singleproxy["plugin-opts"]["mode"] >>= pluginopts_mode; + singleproxy["plugin-opts"]["host"] >>= pluginopts_host; + tls = safe_as(singleproxy["plugin-opts"]["tls"]) ? "tls;" : ""; + singleproxy["plugin-opts"]["path"] >>= path; + pluginopts_mux = safe_as(singleproxy["plugin-opts"]["mux"]) ? "mux=4;" : ""; } break; default: break; @@ -1075,10 +1055,12 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> pluginopts_mode; + singleproxy["obfs"] >>= pluginopts_mode; if(singleproxy["obfs-host"].IsDefined()) - singleproxy["obfs-host"] >> pluginopts_host; + singleproxy["obfs-host"] >>= pluginopts_host; } + else + plugin.clear(); switch(hash_(plugin)) { @@ -1113,8 +1095,8 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> user; - singleproxy["password"] >> password; + singleproxy["username"] >>= user; + singleproxy["password"] >>= password; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.proxyStr = socksConstruct(ps, server, port, user, password); @@ -1122,12 +1104,12 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> cipher; - singleproxy["password"] >> password; - singleproxy["protocol"] >> protocol; - singleproxy["protocolparam"] >> protoparam; - singleproxy["obfs"] >> obfs; - singleproxy["obfsparam"] >> obfsparam; + singleproxy["cipher"] >>= cipher; + singleproxy["password"] >>= password; + singleproxy["protocol"] >>= protocol; + singleproxy["protocolparam"] >>= protoparam; + singleproxy["obfs"] >>= obfs; + singleproxy["obfsparam"] >>= obfsparam; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; node.proxyStr = ssrConstruct(group, ps, base64_encode(ps), server, port, protocol, cipher, obfs, password, obfsparam, protoparam, ssr_libev, udp, tfo, scv); @@ -1135,17 +1117,17 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> user; - singleproxy["password"] >> password; - singleproxy["tls"] >> tls; + singleproxy["username"] >>= user; + singleproxy["password"] >>= password; + singleproxy["tls"] >>= tls; node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; node.proxyStr = httpConstruct(ps, server, port, user, password, tls == "true", scv); break; case "trojan"_hash: group = TROJAN_DEFAULT_GROUP; - singleproxy["password"] >> password; - singleproxy["sni"] >> host; + singleproxy["password"] >>= password; + singleproxy["sni"] >>= host; node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; node.proxyStr = trojanConstruct(ps, server, port, password, host, true, udp, tfo, scv); @@ -1153,11 +1135,8 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> password; - if(singleproxy["obfs-opts"].IsDefined()) - { - singleproxy["obfs-opts"]["mode"] >> obfs; - singleproxy["obfs-opts"]["host"] >> host; - } + singleproxy["obfs-opts"]["mode"] >>= obfs; + singleproxy["obfs-opts"]["host"] >>= host; node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL; node.proxyStr = snellConstruct(ps, server, port, password, obfs, host, udp, tfo, scv); @@ -1507,12 +1486,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.group = HTTP_DEFAULT_GROUP; server = trim(configs[1]); port = custom_port.empty() ? trim(configs[2]) : custom_port; - if(configs.size() >= 5) - { - username = trim(configs[2]); - password = trim(configs[3]); - } - for(i = 5; i < configs.size(); i++) + for(i = 3; i < configs.size(); i++) { vArray = split(configs[i], "="); if(vArray.size() < 2) @@ -1521,6 +1495,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector itemVal = trim(vArray[1]); switch(hash_(itemName)) { + case "username"_hash: username = itemVal; break; + case "password"_hash: password = itemVal; break; case "skip-cert-verify"_hash: scv = itemVal; break; default: continue; } @@ -1979,6 +1955,7 @@ void explodeSub(std::string sub, bool sslibev, bool ssrlibev, const std::string { if(!processed && (strFind(sub, "Proxy:") || strFind(sub, "proxies:"))) { + regGetMatch(sub, R"(^(?:Proxy|proxies):$\s(?:(?:^ +?.*$| *?-.*$|)\s)+)", 1, &sub); Node yamlnode = Load(sub); if(yamlnode.size() && (yamlnode["Proxy"].IsDefined() || yamlnode["proxies"].IsDefined())) { diff --git a/src/subexport.cpp b/src/subexport.cpp index b66fc4c..d1634d3 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -604,7 +604,7 @@ void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset */ if(lineSize) { - strLine = regTrim(strLine); + strLine = trim(trim_of(strLine, '\r')); lineSize = strLine.size(); } if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored @@ -688,7 +688,7 @@ std::string rulesetToClashStr(YAML::Node &base_rule, std::vector= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored @@ -846,7 +846,7 @@ void rulesetToSurge(INIReader &base_rule, std::vector &ruleset_ */ if(lineSize) { - strLine = regTrim(strLine); + strLine = trim(trim_of(strLine, '\r')); lineSize = strLine.size(); } if(!lineSize || strLine[0] == ';' || strLine[0] == '#' || (lineSize >= 2 && strLine[0] == '/' && strLine[1] == '/')) //empty lines and comments are ignored @@ -1448,12 +1448,20 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s local_port++; break; case SPEEDTEST_MESSAGE_FOUNDSOCKS: - proxy = "socks5, " + hostname + ", " + port + ", " + username + ", " + password; + proxy = "socks5, " + hostname + ", " + port; + if(username.size()) + proxy += ", username=" + username; + if(password.size()) + proxy += ", password=" + password; if(scv) proxy += ", skip-cert-verify=1"; break; case SPEEDTEST_MESSAGE_FOUNDHTTP: - proxy = "http, " + hostname + ", " + port + ", " + username + ", " + password; + proxy = "http, " + hostname + ", " + port; + if(username.size()) + proxy += ", username=" + username; + if(password.size()) + proxy += ", password=" + password; proxy += std::string(", tls=") + (type == "HTTPS" ? "true" : "false"); if(scv) proxy += ", skip-cert-verify=1"; @@ -1610,7 +1618,7 @@ std::string netchToSS(std::vector &nodes, extra_settings &ext) proxyStr = "ss://" + urlsafe_base64_encode(method + ":" + password) + "@" + hostname + ":" + port; if(plugin.size() && pluginopts.size()) { - proxyStr += "/?plugin=" + UrlEncode(plugin + ";" +pluginopts); + proxyStr += "/?plugin=" + UrlEncode(plugin + ";" + pluginopts); } proxyStr += "#" + UrlEncode(remark); break; @@ -2098,6 +2106,7 @@ std::string netchToQuanX(std::vector &nodes, std::string &base_conf, s ini.AddDirectSaveSection("rewrite_local"); ini.AddDirectSaveSection("task_local"); ini.AddDirectSaveSection("mitm"); + ini.AddDirectSaveSection("server_remote"); if(!ext.nodelist && ini.Parse(base_conf) != 0) return std::string();