diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 81b2f97..db46feb 100644 --- a/src/interfaces.cpp +++ b/src/interfaces.cpp @@ -1143,6 +1143,7 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) std::string ext_quan_base = quan_rule_base, ext_quanx_base = quanx_rule_base, ext_loon_base = loon_rule_base, ext_sssub_base = sssub_rule_base; //validate urls + add_insert.define(true); if(!url.size() && (!api_mode || authorized)) url = default_url; if(insert_url.size() && add_insert) @@ -1191,10 +1192,10 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) } ext.append_proxy_type = append_type.get(append_proxy_type); - ext.tfo = tfo.get(tfo_flag); - ext.udp = udp.get(udp_flag); + ext.tfo = tfo; + ext.udp = udp; + ext.skip_cert_verify = scv; ext.sort_flag = sort_flag.get(do_sort); - ext.skip_cert_verify = scv.get(scv_flag); ext.filter_deprecated = fdn.get(filter_deprecated); ext.clash_new_field_name = clash_new_field.get(clash_use_new_field_name); ext.clash_script = clash_script.get(); @@ -1609,7 +1610,7 @@ std::string simpleToClashR(RESPONSE_CALLBACK_ARGS) refreshRulesets(rulesets, ruleset_content_array); rca = ruleset_content_array; - extra_settings ext = {true, overwrite_original_rules, safe_get_renames(), safe_get_emojis(), add_emoji, remove_old_emoji, append_proxy_type, udp_flag, tfo_flag, false, do_sort, scv_flag, filter_deprecated, clash_use_new_field_name, "", "", ""}; + extra_settings ext = {true, overwrite_original_rules, safe_get_renames(), safe_get_emojis(), add_emoji, remove_old_emoji, append_proxy_type, false, do_sort, filter_deprecated, clash_use_new_field_name, false, "", "", ""}; std::string proxy = parseProxy(proxy_subscription); @@ -1787,7 +1788,7 @@ std::string surgeConfToClash(RESPONSE_CALLBACK_ARGS) return "No nodes were found!"; } - extra_settings ext = {true, true, dummy_str_array, dummy_str_array, false, false, false, udp_flag, tfo_flag, false, do_sort, scv_flag, filter_deprecated, clash_use_new_field_name, "", "", ""}; + extra_settings ext = {true, true, dummy_str_array, dummy_str_array, false, false, false, false, do_sort, filter_deprecated, clash_use_new_field_name, false, "", "", ""}; netchToClash(nodes, clash, dummy_str_array, false, ext); diff --git a/src/misc.h b/src/misc.h index abd13a7..c16d4f3 100644 --- a/src/misc.h +++ b/src/misc.h @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include @@ -42,13 +40,11 @@ private: public: - tribool() { _M_VALUE = -1; } + tribool() { clear(); } - tribool(const std::string &src) { set(src); } + template tribool(const T &value) { set(value); } - tribool(const bool &src) { set(src); } - - tribool(const int &src) { set(src); } + tribool(const tribool &value) { *this = value; } ~tribool() = default; @@ -58,22 +54,22 @@ public: return *this; } - tribool& operator=(const std::string &src) + template tribool& operator=(const T &value) { - set(src); + set(value); return *this; } operator bool() const { return _M_VALUE == 1; } - tribool& operator=(const bool &src) - { - _M_VALUE = src; - return *this; - } - bool is_undef() { return _M_VALUE == -1; } + template void define(const T &value) + { + if(_M_VALUE == -1) + set(value); + } + bool get(const bool &def_value = false) { if(_M_VALUE == -1) @@ -81,23 +77,15 @@ public: return _M_VALUE; } - bool set(const bool &value) + template bool set(const T &value) { _M_VALUE = value; return _M_VALUE; } - bool set(const int &value) - { - _M_VALUE = value != 0; - return _M_VALUE; - } - bool set(const std::string &str) { - std::string temp = str; - std::transform(temp.begin(), temp.end(), temp.begin(), [](unsigned char c){ return std::tolower(c); }); - switch(hash_(temp)) + switch(hash_(str)) { case "true"_hash: _M_VALUE = 1; @@ -111,6 +99,8 @@ public: } return _M_VALUE; } + + void clear() { _M_VALUE = -1; } }; std::string UrlEncode(const std::string& str); diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index 5d87d82..e626457 100644 --- a/src/speedtestutil.cpp +++ b/src/speedtestutil.cpp @@ -43,6 +43,7 @@ template T safe_as (const YAML::Node& 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; + tribool udp, tfo, scv; Document jsondata; std::vector vArray; if(regMatch(vmess, "vmess://(.*?)\\?(.*)")) //shadowrocket style link @@ -104,7 +105,7 @@ void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &n node.remarks = ps; node.server = add; node.port = to_int(port, 0); - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, "auto", path, host, "", tls); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, "auto", path, host, "", tls, udp, tfo, scv); } void explodeVmessConf(std::string content, const std::string &custom_port, bool libev, std::vector &nodes) @@ -113,6 +114,7 @@ void explodeVmessConf(std::string content, const std::string &custom_port, bool Document json; rapidjson::Value nodejson, settings; std::string group, ps, add, port, type, id, aid, net, path, host, edge, tls, cipher, subid; + tribool udp, tfo, scv; int configType, index = nodes.size(); std::map subdata; std::map::iterator iter; @@ -177,7 +179,7 @@ void explodeVmessConf(std::string content, const std::string &custom_port, bool } } node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, edge, tls); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, edge, tls, udp, tfo, scv); node.group = V2RAY_DEFAULT_GROUP; node.remarks = add + ":" + port; node.server = add; @@ -213,6 +215,7 @@ void explodeVmessConf(std::string content, const std::string &custom_port, bool if(ps.empty()) ps = add + ":" + port; + scv = GetMember(json["vmess"][i], "allowInsecure"); json["vmess"][i]["configType"] >> configType; switch(configType) { @@ -227,19 +230,19 @@ void explodeVmessConf(std::string content, const std::string &custom_port, bool json["vmess"][i]["security"] >> cipher; group = V2RAY_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; - node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls); + node.proxyStr = vmessConstruct(add, port, type, id, aid, net, cipher, path, host, "", tls, udp, tfo, scv); break; case 3: //ss config json["vmess"][i]["id"] >> id; json["vmess"][i]["security"] >> cipher; group = SS_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; - node.proxyStr = ssConstruct(add, port, id, cipher, "", "", ps, libev); + node.proxyStr = ssConstruct(add, port, id, cipher, "", "", ps, libev, udp, tfo, scv); break; case 4: //socks config group = SOCKS_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; - node.proxyStr = socksConstruct(ps, add, port, "", ""); + node.proxyStr = socksConstruct(ps, add, port, "", "", udp, tfo, scv); break; default: continue; @@ -316,7 +319,7 @@ void explodeSSD(std::string link, bool libev, const std::string &custom_port, st { Document jsondata; nodeInfo node; - unsigned int index = nodes.size(), listType = 0, listCount = 0;; + unsigned int index = nodes.size(), listType = 0, listCount = 0; std::string group, port, method, password, server, remarks; std::string plugin, pluginopts; std::map node_map; @@ -839,6 +842,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s { Document json; std::string type, remark, address, port, username, password, method, plugin, pluginopts, protocol, protoparam, obfs, obfsparam, id, aid, transprot, faketype, host, edge, path, tls; + tribool udp, tfo, scv; netch = urlsafe_base64_decode(netch.substr(8)); json.Parse(netch.data()); @@ -847,6 +851,9 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s json["Type"] >> type; json["Remark"] >> remark; json["Hostname"] >> address; + udp = GetMember(json, "EnableUDP"); + tfo = GetMember(json, "EnableTFO"); + scv = GetMember(json, "AllowInsecure"); port = custom_port.size() ? custom_port : GetMember(json, "Port"); method = GetMember(json, "EncryptMethod"); password = GetMember(json, "Password"); @@ -859,7 +866,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s pluginopts = GetMember(json, "PluginOption"); node.group = SS_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; - node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, ss_libev); + node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, ss_libev, udp, tfo, scv); break; case "SSR"_hash: protocol = GetMember(json, "Protocol"); @@ -870,7 +877,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s pluginopts = GetMember(json, "PluginOption"); node.group = SS_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; - node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, ss_libev); + node.proxyStr = ssConstruct(address, port, password, method, plugin, pluginopts, remark, ss_libev, udp, tfo, scv); } else { @@ -878,7 +885,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s obfsparam = GetMember(json, "OBFSParam"); node.group = SSR_DEFAULT_GROUP; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; - node.proxyStr = ssrConstruct(SSR_DEFAULT_GROUP, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, ssr_libev); + node.proxyStr = ssrConstruct(SSR_DEFAULT_GROUP, remark, base64_encode(remark), address, port, protocol, method, obfs, password, obfsparam, protoparam, ssr_libev, udp, tfo, scv); } break; case "VMess"_hash: @@ -889,16 +896,37 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s host = GetMember(json, "Host"); path = GetMember(json, "Path"); edge = GetMember(json, "Edge"); - tls = GetMember(json, "TLSSecure") == "true" ? "tls" : ""; + tls = GetMember(json, "TLSSecure"); node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.group = V2RAY_DEFAULT_GROUP; - node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, edge, tls); + node.proxyStr = vmessConstruct(address, port, faketype, id, aid, transprot, method, path, host, edge, tls, udp, tfo, scv); break; case "Socks5"_hash: username = GetMember(json, "Username"); node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; node.group = SOCKS_DEFAULT_GROUP; - node.proxyStr = socksConstruct(remark, address, port, username, password); + node.proxyStr = socksConstruct(remark, address, port, username, password, udp, tfo, scv); + break; + case "HTTP"_hash: + case "HTTPS"_hash: + node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; + node.group = HTTP_DEFAULT_GROUP; + node.proxyStr = httpConstruct(remark, address, port, username, password, type == "HTTPS", scv); + break; + case "Trojan"_hash: + host = GetMember(json, "Host"); + tls = GetMember(json, "TLSSecure"); + node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; + node.group = TROJAN_DEFAULT_GROUP; + node.proxyStr = trojanConstruct(remark, address, port, username, password, tls == "true", udp, tfo, scv); + break; + case "Snell"_hash: + obfs = GetMember(json, "OBFS"); + host = GetMember(json, "Host"); + node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL; + node.group = SNELL_DEFAULT_GROUP; + node.proxyStr = snellConstruct(remark, address, port, password, obfs, host, udp, tfo, scv); + break; default: return; } @@ -921,6 +949,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> proxytype; @@ -929,6 +958,8 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector(singleproxy["port"]) : custom_port; if(port.empty()) continue; + udp = safe_as(singleproxy["udp"]); + scv = safe_as(singleproxy["skip-cert-verify"]); switch(hash_(proxytype)) { case "vmess"_hash: @@ -953,7 +984,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> obfsparam; node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; - node.proxyStr = ssrConstruct(group, ps, base64_encode(ps), server, port, protocol, cipher, obfs, password, obfsparam, protoparam, ssr_libev); + node.proxyStr = ssrConstruct(group, ps, base64_encode(ps), server, port, protocol, cipher, obfs, password, obfsparam, protoparam, ssr_libev, udp, tfo, scv); break; case "http"_hash: group = HTTP_DEFAULT_GROUP; @@ -1069,7 +1100,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> tls; node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; - node.proxyStr = httpConstruct(ps, server, port, user, password, tls == "true"); + node.proxyStr = httpConstruct(ps, server, port, user, password, tls == "true", scv); break; case "trojan"_hash: group = TROJAN_DEFAULT_GROUP; @@ -1077,7 +1108,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector> host; node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; - node.proxyStr = trojanConstruct(ps, server, port, password, host, true); + node.proxyStr = trojanConstruct(ps, server, port, password, host, true, udp, tfo, scv); break; case "snell"_hash: group = SNELL_DEFAULT_GROUP; @@ -1089,7 +1120,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector configs, vArray, headers, header; + tribool udp, tfo, scv; remarks = regReplace(x.second, proxystr, "$1"); configs = split(regReplace(x.second, proxystr, "$2"), ","); @@ -1289,6 +1321,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector pluginopts_mode = itemVal; break; case "obfs-host"_hash: pluginopts_host = itemVal; break; + case "udp-relay"_hash: udp = itemVal; break; + case "tfo"_hash: tfo = itemVal; break; default: continue; } } @@ -1300,7 +1334,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; node.group = SS_DEFAULT_GROUP; - node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev); + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev, udp, tfo, scv); } //else // continue; @@ -1325,6 +1359,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector pluginopts_mode = itemVal; break; case "obfs-host"_hash: pluginopts_host = itemVal; break; + case "udp-relay"_hash: udp = itemVal; break; + case "tfo"_hash: tfo = itemVal; break; default: continue; } } @@ -1336,7 +1372,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; node.group = SS_DEFAULT_GROUP; - node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev); + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev, udp, tfo, scv); break; case "socks5"_hash: //surge 3 style socks5 proxy node.linkType = SPEEDTEST_MESSAGE_FOUNDSOCKS; @@ -1345,10 +1381,25 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector port = custom_port.empty() ? trim(configs[2]) : custom_port; if(configs.size() >= 5) { - username = trim(configs[2]); - password = trim(configs[3]); + username = trim(configs[3]); + password = trim(configs[4]); } - node.proxyStr = socksConstruct(remarks, server, port, username, password); + for(i = 5; i < configs.size(); i++) + { + vArray = split(configs[i], "="); + if(vArray.size() < 2) + continue; + itemName = trim(vArray[0]); + itemVal = trim(vArray[1]); + switch(hash_(itemName)) + { + case "udp-relay"_hash: udp = itemVal; break; + case "tfo"_hash: tfo = itemVal; break; + case "skip-cert-verify"_hash: scv = itemVal; break; + default: continue; + } + } + node.proxyStr = socksConstruct(remarks, server, port, username, password, udp, tfo, scv); break; case "vmess"_hash: //surge 4 style vmess proxy server = trim(configs[1]); @@ -1383,6 +1434,9 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector edge = trim_quote(header[1]); } break; + case "udp-relay"_hash: udp = itemVal; break; + case "tfo"_hash: tfo = itemVal; break; + case "skip-cert-verify"_hash: scv = itemVal; break; default: continue; } } @@ -1391,7 +1445,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.group = V2RAY_DEFAULT_GROUP; - node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, edge, tls); + node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, edge, tls, udp, tfo, scv); break; case "http"_hash: //http proxy node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; @@ -1403,7 +1457,20 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector username = trim(configs[2]); password = trim(configs[3]); } - node.proxyStr = httpConstruct(remarks, server, port, username, password); + for(i = 5; i < configs.size(); i++) + { + vArray = split(configs[i], "="); + if(vArray.size() < 2) + continue; + itemName = trim(vArray[0]); + itemVal = trim(vArray[1]); + switch(hash_(itemName)) + { + case "skip-cert-verify"_hash: scv = itemVal; break; + default: continue; + } + } + node.proxyStr = httpConstruct(remarks, server, port, username, password, false, scv); break; case "trojan"_hash: // surge 4 style trojan proxy node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; @@ -1422,13 +1489,16 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector { case "password"_hash: password = itemVal; break; case "sni"_hash: host = itemVal; break; + case "udp-relay"_hash: udp = itemVal; break; + case "tfo"_hash: tfo = itemVal; break; + case "skip-cert-verify"_hash: scv = itemVal; break; default: continue; } } if(host.empty() && !isIPv4(server) && !isIPv6(server)) host = server; - node.proxyStr = trojanConstruct(remarks, server, port, password, host, true); + node.proxyStr = trojanConstruct(remarks, server, port, password, host, true, udp, tfo, scv); break; case "snell"_hash: node.linkType = SPEEDTEST_MESSAGE_FOUNDSNELL; @@ -1449,13 +1519,16 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector case "psk"_hash: password = itemVal; break; case "obfs"_hash: plugin = itemVal; break; case "obfs-host"_hash: host = itemVal; break; + case "udp-relay"_hash: udp = itemVal; break; + case "tfo"_hash: tfo = itemVal; break; + case "skip-cert-verify"_hash: scv = itemVal; break; default: continue; } } if(host.empty() && !isIPv4(server) && !isIPv6(server)) host = server; - node.proxyStr = snellConstruct(remarks, server, port, password, plugin, host); + node.proxyStr = snellConstruct(remarks, server, port, password, plugin, host, udp, tfo, scv); break; default: switch(hash_(remarks)) @@ -1483,6 +1556,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector pluginopts_mode = itemVal; break; case "obfs-host"_hash: pluginopts_host = itemVal; break; + case "udp-relay"_hash: udp = itemVal; break; + case "fast-open"_hash: tfo = itemVal; break; default: continue; } } @@ -1499,13 +1574,13 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector { node.linkType = SPEEDTEST_MESSAGE_FOUNDSSR; node.group = SSR_DEFAULT_GROUP; - node.proxyStr = ssrConstruct(node.group, remarks, base64_encode(remarks), server, port, protocol, method, pluginopts_mode, password, pluginopts_host, protoparam, libev); + node.proxyStr = ssrConstruct(node.group, remarks, base64_encode(remarks), server, port, protocol, method, pluginopts_mode, password, pluginopts_host, protoparam, libev, udp, tfo, scv); } else { node.linkType = SPEEDTEST_MESSAGE_FOUNDSS; node.group = SS_DEFAULT_GROUP; - node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev); + node.proxyStr = ssConstruct(server, port, password, method, plugin, pluginopts, remarks, libev, udp, tfo, scv); } break; case "vmess"_hash: //quantumult x style vmess link @@ -1535,6 +1610,8 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector case "obfs-host"_hash: host = itemVal; break; case "obfs-uri"_hash: path = itemVal; break; case "over-tls"_hash: tls = itemVal == "true" ? "tls" : ""; break; + case "udp-relay"_hash: udp = itemVal; break; + case "fast-open"_hash: tfo = itemVal; break; default: continue; } } @@ -1546,7 +1623,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.linkType = SPEEDTEST_MESSAGE_FOUNDVMESS; node.group = V2RAY_DEFAULT_GROUP; - node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls); + node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls, udp, tfo, scv); break; case "trojan"_hash: //quantumult x style trojan link server = trim(configs[0].substr(0, configs[0].rfind(":"))); @@ -1565,6 +1642,9 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector case "tag"_hash: remarks = itemVal; break; case "over-tls"_hash: tls = itemVal; break; case "tls-host"_hash: host = itemVal; break; + case "udp-relay"_hash: udp = itemVal; break; + case "fast-open"_hash: tfo = itemVal; break; + case "tls-verification"_hash: scv = itemVal == "false"; break; default: continue; } } @@ -1576,7 +1656,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; node.group = TROJAN_DEFAULT_GROUP; - node.proxyStr = trojanConstruct(remarks, server, port, password, host, tls == "true"); + node.proxyStr = trojanConstruct(remarks, server, port, password, host, tls == "true", udp, tfo, scv); break; case "http"_hash: //quantumult x style http links server = trim(configs[0].substr(0, configs[0].rfind(":"))); @@ -1595,6 +1675,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector case "password"_hash: password = itemVal; break; case "tag"_hash: remarks = itemVal; break; case "over-tls"_hash: tls = itemVal; break; + case "tls-verification"_hash: scv = itemVal == "false"; break; default: continue; } } @@ -1611,7 +1692,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP; node.group = HTTP_DEFAULT_GROUP; - node.proxyStr = httpConstruct(remarks, server, port, username, password, tls == "true"); + node.proxyStr = httpConstruct(remarks, server, port, username, password, tls == "true", scv); break; default: continue; diff --git a/src/speedtestutil.h b/src/speedtestutil.h index e7406c1..2bb3076 100644 --- a/src/speedtestutil.h +++ b/src/speedtestutil.h @@ -7,13 +7,13 @@ #include "misc.h" #include "nodeinfo.h" -std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls); -std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, bool libev); -std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, bool libev); -std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password); -std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls = false); -std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure); -std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host); +std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); +std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); +std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); +std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); +std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls, tribool scv = tribool()); +std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); +std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool()); void explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &node); void explodeSSR(std::string ssr, bool ss_libev, bool libev, const std::string &custom_port, nodeInfo &node); void explodeSS(std::string ss, bool libev, const std::string &custom_port, nodeInfo &node); diff --git a/src/subexport.cpp b/src/subexport.cpp index f9d065a..b690123 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -76,7 +76,7 @@ std::string hostnameToIPAddr(const std::string &host) return retAddr; } -std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls) +std::string vmessConstruct(std::string add, std::string port, std::string type, std::string id, std::string aid, std::string net, std::string cipher, std::string path, std::string host, std::string edge, std::string tls, tribool udp, tribool tfo, tribool scv) { if(!path.size()) path = "/"; @@ -129,11 +129,26 @@ std::string vmessConstruct(std::string add, std::string port, std::string type, } writer.Key("TLSSecure"); writer.Bool(tls == "tls"); + if(!udp.is_undef()) + { + writer.Key("EnableUDP"); + writer.Bool(udp); + } + if(!tfo.is_undef()) + { + writer.Key("EnableTFO"); + writer.Bool(tfo); + } + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } -std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, bool libev) +std::string ssrConstruct(std::string group, std::string remarks, std::string remarks_base64, std::string server, std::string port, std::string protocol, std::string method, std::string obfs, std::string password, std::string obfsparam, std::string protoparam, bool libev, tribool udp, tribool tfo, tribool scv) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -158,11 +173,26 @@ std::string ssrConstruct(std::string group, std::string remarks, std::string rem writer.String(obfs.data()); writer.Key("OBFSParam"); writer.String(obfsparam.data()); + if(!udp.is_undef()) + { + writer.Key("EnableUDP"); + writer.Bool(udp); + } + if(!tfo.is_undef()) + { + writer.Key("EnableTFO"); + writer.Bool(tfo); + } + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } -std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, bool libev) +std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, bool libev, tribool udp, tribool tfo, tribool scv) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -183,11 +213,26 @@ std::string ssConstruct(std::string server, std::string port, std::string passwo writer.String(plugin.data()); writer.Key("PluginOption"); writer.String(pluginopts.data()); + if(!udp.is_undef()) + { + writer.Key("EnableUDP"); + writer.Bool(udp); + } + if(!tfo.is_undef()) + { + writer.Key("EnableTFO"); + writer.Bool(tfo); + } + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } -std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password) +std::string socksConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, tribool udp, tribool tfo, tribool scv) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -204,11 +249,26 @@ std::string socksConstruct(std::string remarks, std::string server, std::string writer.String(username.data()); writer.Key("Password"); writer.String(password.data()); + if(!udp.is_undef()) + { + writer.Key("EnableUDP"); + writer.Bool(udp); + } + if(!tfo.is_undef()) + { + writer.Key("EnableTFO"); + writer.Bool(tfo); + } + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } -std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls) +std::string httpConstruct(std::string remarks, std::string server, std::string port, std::string username, std::string password, bool tls, tribool scv) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -225,11 +285,16 @@ std::string httpConstruct(std::string remarks, std::string server, std::string p writer.String(username.data()); writer.Key("Password"); writer.String(password.data()); + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } -std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure) +std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure, tribool udp, tribool tfo, tribool scv) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -248,11 +313,26 @@ std::string trojanConstruct(std::string remarks, std::string server, std::string writer.String(host.data()); writer.Key("TLSSecure"); writer.Bool(tlssecure); + if(!udp.is_undef()) + { + writer.Key("EnableUDP"); + writer.Bool(udp); + } + if(!tfo.is_undef()) + { + writer.Key("EnableTFO"); + writer.Bool(tfo); + } + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } -std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host) +std::string snellConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string obfs, std::string host, tribool udp, tribool tfo, tribool scv) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -271,6 +351,21 @@ std::string snellConstruct(std::string remarks, std::string server, std::string writer.String(obfs.data()); writer.Key("Host"); writer.String(host.data()); + if(!udp.is_undef()) + { + writer.Key("EnableUDP"); + writer.Bool(udp); + } + if(!tfo.is_undef()) + { + writer.Key("EnableTFO"); + writer.Bool(tfo); + } + if(!scv.is_undef()) + { + writer.Key("AllowInsecure"); + writer.Bool(scv); + } writer.EndObject(); return sb.GetString(); } @@ -889,6 +984,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr std::string plugin, pluginopts; std::string protocol, protoparam, obfs, obfsparam; std::string id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; + tribool udp, scv; std::vector nodelist; bool tlssecure, replace_flag; string_array vArray, remarks_list, filtered_nodelist; @@ -910,6 +1006,11 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr password = GetMember(json, "Password"); method = GetMember(json, "EncryptMethod"); + udp = ext.udp; + scv = ext.skip_cert_verify; + udp.define(GetMember(json, "EnableUDP")); + scv.define(GetMember(json, "AllowInsecure")); + singleproxy["name"] = remark; singleproxy["server"] = hostname; singleproxy["port"] = (unsigned short)stoi(port); @@ -960,7 +1061,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["alterId"] = stoi(aid); singleproxy["cipher"] = method; singleproxy["tls"] = tlssecure; - if(ext.skip_cert_verify) + if(scv) singleproxy["skip-cert-verify"] = true; switch(hash_(transproto)) { @@ -1018,7 +1119,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["password"] = password; if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty()) singleproxy["password"].SetTag("str"); - if(ext.skip_cert_verify) + if(scv) singleproxy["skip-cert-verify"] = true; break; case SPEEDTEST_MESSAGE_FOUNDHTTP: @@ -1028,7 +1129,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty()) singleproxy["password"].SetTag("str"); singleproxy["tls"] = type == "HTTPS"; - if(ext.skip_cert_verify) + if(scv) singleproxy["skip-cert-verify"] = true; break; case SPEEDTEST_MESSAGE_FOUNDTROJAN: @@ -1039,7 +1140,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["sni"] = host; if(std::all_of(password.begin(), password.end(), ::isdigit) && !password.empty()) singleproxy["password"].SetTag("str"); - if(ext.skip_cert_verify) + if(scv) singleproxy["skip-cert-verify"] = true; break; case SPEEDTEST_MESSAGE_FOUNDSNELL: @@ -1059,7 +1160,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr continue; } - if(ext.udp) + if(udp) singleproxy["udp"] = true; singleproxy.SetStyle(YAML::EmitterStyle::Flow); proxies.push_back(singleproxy); @@ -1194,6 +1295,7 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s std::string protocol, protoparam, obfs, obfsparam; std::string id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; std::string output_nodelist; + tribool udp, tfo, scv; std::vector nodelist; unsigned short local_port = 1080; bool tlssecure; @@ -1231,6 +1333,14 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s username = GetMember(json, "Username"); password = GetMember(json, "Password"); method = GetMember(json, "EncryptMethod"); + + udp = ext.udp; + tfo = ext.tfo; + scv = ext.skip_cert_verify; + udp.define(GetMember(json, "EnableUDP")); + tfo.define(GetMember(json, "EnableTFO")); + scv.define(GetMember(json, "AllowInsecure")); + proxy.clear(); switch(x.linkType) @@ -1272,7 +1382,7 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s default: continue; } - if(ext.skip_cert_verify) + if(scv) proxy += ", skip-cert-verify=1"; break; case SPEEDTEST_MESSAGE_FOUNDSSR: @@ -1304,13 +1414,13 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s break; case SPEEDTEST_MESSAGE_FOUNDSOCKS: proxy = "socks5, " + hostname + ", " + port + ", " + username + ", " + password; - if(ext.skip_cert_verify) + if(scv) proxy += ", skip-cert-verify=1"; break; case SPEEDTEST_MESSAGE_FOUNDHTTP: proxy = "http, " + hostname + ", " + port + ", " + username + ", " + password; proxy += std::string(", tls=") + (type == "HTTPS" ? "true" : "false"); - if(ext.skip_cert_verify) + if(scv) proxy += ", skip-cert-verify=1"; break; case SPEEDTEST_MESSAGE_FOUNDTROJAN: @@ -1320,7 +1430,7 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s proxy = "trojan, " + hostname + ", " + port + ", password=" + password; if(host.size()) proxy += ", sni=" + host; - if(ext.skip_cert_verify) + if(scv) proxy += ", skip-cert-verify=1"; break; case SPEEDTEST_MESSAGE_FOUNDSNELL: @@ -1334,9 +1444,9 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s continue; } - if(ext.tfo) + if(tfo) proxy += ", tfo=true"; - if(ext.udp) + if(udp) proxy += ", udp-relay=true"; remarks_list.emplace_back(remark); @@ -2023,6 +2133,7 @@ void netchToQuanX(std::vector &nodes, INIReader &ini, std::vector nodelist; string_array remarks_list; @@ -2043,6 +2154,13 @@ void netchToQuanX(std::vector &nodes, INIReader &ini, std::vector &nodes, INIReader &ini, std::vector &nodes, std::string &base_conf, st std::string protocol, protoparam, obfs, obfsparam; std::string id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; std::string output_nodelist; + tribool scv; std::vector nodelist; bool tlssecure; //group pref @@ -2583,6 +2702,10 @@ std::string netchToLoon(std::vector &nodes, std::string &base_conf, st username = GetMember(json, "Username"); password = GetMember(json, "Password"); method = GetMember(json, "EncryptMethod"); + + scv = GetMember(json, "AllowInsecure"); + scv.define(ext.skip_cert_verify); + proxy.clear(); switch(x.linkType) @@ -2625,7 +2748,7 @@ std::string netchToLoon(std::vector &nodes, std::string &base_conf, st default: continue; } - if(ext.skip_cert_verify) + if(scv) proxy += ",skip-cert-verify:1"; break; case SPEEDTEST_MESSAGE_FOUNDSSR: diff --git a/src/subexport.h b/src/subexport.h index c818cf5..9395185 100644 --- a/src/subexport.h +++ b/src/subexport.h @@ -25,17 +25,17 @@ struct extra_settings bool add_emoji = false; bool remove_emoji = false; bool append_proxy_type = false; - bool udp = false; - bool tfo = false; bool nodelist = false; bool sort_flag = false; - bool skip_cert_verify = false; bool filter_deprecated = false; bool clash_new_field_name = false; bool clash_script = false; std::string surge_ssr_path; std::string managed_config_prefix; std::string quanx_dev_id; + tribool udp = false; + tribool tfo = false; + tribool skip_cert_verify = false; }; void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset_content_array, bool overwrite_original_rules, bool new_field_name);