diff --git a/src/interfaces.cpp b/src/interfaces.cpp index 5352798..d864e40 100644 --- a/src/interfaces.cpp +++ b/src/interfaces.cpp @@ -1194,6 +1194,9 @@ std::string subconverter(RESPONSE_CALLBACK_ARGS) if(subInfo.size() && (append_sub_userinfo.size() ? append_sub_userinfo == "true" : append_userinfo)) extra_headers.emplace("Subscription-UserInfo", subInfo); + //do pre-process now + preprocessNodes(nodes, ext); + string_array dummy_group; std::vector dummy_ruleset; diff --git a/src/speedtestutil.cpp b/src/speedtestutil.cpp index 12ec6a2..4f0855c 100644 --- a/src/speedtestutil.cpp +++ b/src/speedtestutil.cpp @@ -14,6 +14,7 @@ #include "webget.h" #include "rapidjson_extra.h" #include "ini_reader.h" +#include "string_hash.h" using namespace rapidjson; using namespace YAML; @@ -634,7 +635,7 @@ void explodeTrojan(std::string trojan, const std::string &custom_port, int local node.remarks = remark; node.server = server; node.port = to_int(port, 0); - node.proxyStr = trojanConstruct(remark, server, port, psk); + node.proxyStr = trojanConstruct(remark, server, port, psk, "", false); } void explodeQuan(std::string quan, const std::string &custom_port, int local_port, nodeInfo &node) @@ -1135,13 +1136,15 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p continue; itemName = trim(vArray[0]); itemVal = trim(vArray[1]); - if(itemName == "obfs") + switch(hash_(itemName)) { - plugin = "simple-obfs"; - pluginopts_mode = itemVal; + case "obfs"_hash: + plugin = "simple-obfs"; + pluginopts_mode = itemVal; + break; + case "obfs-host"_hash: pluginopts_host = itemVal; break; + default: continue; } - else if(itemName == "obfs-host") - pluginopts_host = itemVal; } if(plugin.size()) { @@ -1168,17 +1171,17 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p continue; itemName = trim(vArray[0]); itemVal = trim(vArray[1]); - if(itemName == "encrypt-method") - method = itemVal; - else if(itemName == "password") - password = itemVal; - else if(itemName == "obfs") + switch(hash_(itemName)) { - plugin = "simple-obfs"; - pluginopts_mode = itemVal; + case "encrypt-method"_hash: method = itemVal; break; + case "password"_hash: id = itemVal; break; + case "obfs"_hash: + plugin = "simple-obfs"; + pluginopts_mode = itemVal; + break; + case "obfs-host"_hash: pluginopts_host = itemVal; break; + default: continue; } - else if(itemName == "obfs-host") - pluginopts_host = itemVal; } if(plugin.size()) { @@ -1217,29 +1220,25 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p continue; itemName = trim(vArray[0]); itemVal = trim(vArray[1]); - if(itemName == "username") - id = itemVal; - else if(itemName == "ws") + switch(hash_(itemName)) { - net = itemVal == "true" ? "ws" : "tcp"; - } - else if(itemName == "tls") - { - tls = itemVal == "true" ? "tls" : ""; - } - else if(itemName == "ws-path") - path = itemVal; - else if(itemName == "ws-headers") - { - headers = split(itemVal, "|"); - for(auto &y : headers) - { - header = split(trim(y), ":"); - if(regMatch(header[0], "(?i)host")) - host = trim_quote(header[1]); - else if(regMatch(header[0], "(?i)edge")) - edge = trim_quote(header[1]); - } + case "username"_hash: id = itemVal; break; + case "ws"_hash: net = itemVal == "true" ? "ws" : "tcp"; break; + case "tls"_hash: tls = itemVal == "true" ? "tls" : ""; break; + case "ws-path"_hash: path = itemVal; break; + case "obfs-host"_hash: host = itemVal; break; + case "ws-headers"_hash: + headers = split(itemVal, "|"); + for(auto &y : headers) + { + header = split(trim(y), ":"); + if(regMatch(header[0], "(?i)host")) + host = trim_quote(header[1]); + else if(regMatch(header[0], "(?i)edge")) + edge = trim_quote(header[1]); + } + break; + default: continue; } } if(host.empty() && !isIPv4(server) && !isIPv6(server)) @@ -1279,7 +1278,10 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p if(itemName == "password") password = itemVal; } - node.proxyStr = trojanConstruct(remarks, server, port, password); + if(host.empty() && !isIPv4(server) && !isIPv6(server)) + host = server; + + node.proxyStr = trojanConstruct(remarks, server, port, password, host, false); } else if(remarks == "shadowsocks") //quantumult x style ss/ssr link { @@ -1293,23 +1295,20 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p continue; itemName = trim(vArray[0]); itemVal = trim(vArray[1]); - if(itemName == "method") - method = itemVal; - else if(itemName == "password") - password = itemVal; - else if(itemName == "tag") - remarks = itemVal; - else if(itemName == "ssr-protocol") - protocol = itemVal; - else if(itemName == "ssr-protocol-param") - protoparam = itemVal; - else if(itemName == "obfs") + switch(hash_(itemName)) { - plugin = "simple-obfs"; - pluginopts_mode = itemVal; + case "method"_hash: method = itemVal; break; + case "password"_hash: id = itemVal; break; + case "tag"_hash: remarks = itemVal; break; + case "ssr-protocol"_hash: protocol = itemVal; break; + case "ssr-protocol-param"_hash: protoparam = itemVal; break; + case "obfs"_hash: + plugin = "simple-obfs"; + pluginopts_mode = itemVal; + break; + case "obfs-host"_hash: pluginopts_host = itemVal; break; + default: continue; } - else if(itemName == "obfs-host") - pluginopts_host = itemVal; } if(remarks.empty()) remarks = server + ":" + port; @@ -1346,25 +1345,23 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p continue; itemName = trim(vArray[0]); itemVal = trim(vArray[1]); - if(itemName == "method") - method = itemVal; - else if(itemName == "password") - id = itemVal; - else if(itemName == "tag") - remarks = itemVal; - else if(itemName == "obfs") + switch(hash_(itemName)) { - if(itemVal == "ws") - net = "ws"; - else if(itemVal == "over-tls") - tls = "tls"; + case "method"_hash: method = itemVal; break; + case "password"_hash: id = itemVal; break; + case "tag"_hash: remarks = itemVal; break; + case "obfs"_hash: + switch(hash_(itemVal)) + { + case "ws"_hash: net = "ws"; break; + case "over-tls"_hash: tls = "tls"; break; + } + break; + case "obfs-host"_hash: host = itemVal; break; + case "obfs-uri"_hash: path = itemVal; break; + case "over-tls"_hash: tls = itemVal == "true" ? "tls" : ""; break; + default: continue; } - else if(itemName == "obfs-host") - host = itemVal; - else if(itemName == "obfs-uri") - path = itemVal; - else if(itemName == "over-tls") - tls = itemVal == "true" ? "tls" : ""; } if(remarks.empty()) remarks = server + ":" + port; @@ -1376,6 +1373,37 @@ bool explodeSurge(std::string surge, const std::string &custom_port, int local_p node.group = V2RAY_DEFAULT_GROUP; node.proxyStr = vmessConstruct(server, port, "", id, "0", net, method, path, host, "", tls, local_port); } + else if(remarks == "trojan") //quantumult x style trojan link + { + server = trim(configs[0].substr(0, configs[0].rfind(":"))); + port = custom_port.empty() ? trim(configs[0].substr(configs[0].rfind(":") + 1)) : custom_port; + + for(i = 1; i < configs.size(); i++) + { + vArray = split(trim(configs[i]), "="); + if(vArray.size() != 2) + continue; + itemName = trim(vArray[0]); + itemVal = trim(vArray[1]); + switch(hash_(itemName)) + { + case "password"_hash: password = itemVal; break; + case "tag"_hash: remarks = itemVal; break; + case "over-tls"_hash: tls = itemVal; break; + case "tls-host"_hash: host = itemVal; break; + default: continue; + } + } + if(remarks.empty()) + remarks = server + ":" + port; + + if(host.empty() && !isIPv4(server) && !isIPv6(server)) + host = server; + + node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN; + node.group = TROJAN_DEFAULT_GROUP; + node.proxyStr = trojanConstruct(remarks, server, port, password, host, tls == "true"); + } else continue; diff --git a/src/speedtestutil.h b/src/speedtestutil.h index 5650f96..5955955 100644 --- a/src/speedtestutil.h +++ b/src/speedtestutil.h @@ -12,7 +12,7 @@ std::string ssrConstruct(std::string group, std::string remarks, std::string rem std::string ssConstruct(std::string server, std::string port, std::string password, std::string method, std::string plugin, std::string pluginopts, std::string remarks, int local_port, 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 trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure); void explodeVmess(std::string vmess, const std::string &custom_port, int local_port, nodeInfo &node); void explodeSSR(std::string ssr, bool ss_libev, bool libev, const std::string &custom_port, int local_port, nodeInfo &node); void explodeSS(std::string ss, bool libev, const std::string &custom_port, int local_port, nodeInfo &node); diff --git a/src/subexport.cpp b/src/subexport.cpp index 64e9b0f..74f5628 100644 --- a/src/subexport.cpp +++ b/src/subexport.cpp @@ -215,7 +215,7 @@ std::string httpConstruct(std::string remarks, std::string server, std::string p return sb.GetString(); } -std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password) +std::string trojanConstruct(std::string remarks, std::string server, std::string port, std::string password, std::string host, bool tlssecure) { rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); @@ -230,6 +230,10 @@ std::string trojanConstruct(std::string remarks, std::string server, std::string writer.Int(to_int(port)); writer.Key("Password"); writer.String(password.data()); + writer.Key("Host"); + writer.String(host.data()); + writer.Key("TLSSecure"); + writer.Bool(tlssecure); writer.EndObject(); return sb.GetString(); } @@ -674,18 +678,8 @@ void groupGenerate(std::string &rule, std::vector &nodelist, std::vect } } -void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_array &extra_proxy_group, bool clashR, extra_settings &ext) +void preprocessNodes(std::vector &nodes, extra_settings &ext) { - YAML::Node proxies, singleproxy, singlegroup, original_groups; - rapidjson::Document json; - std::string type, remark, hostname, port, username, password, method; - std::string plugin, pluginopts; - std::string protocol, protoparam, obfs, obfsparam; - std::string id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; - std::vector nodelist; - bool tlssecure, replace_flag; - string_array vArray, remarks_list, filtered_nodelist; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) { x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); @@ -703,6 +697,19 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr return a.remarks < b.remarks; }); } +} + +void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_array &extra_proxy_group, bool clashR, extra_settings &ext) +{ + YAML::Node proxies, singleproxy, singlegroup, original_groups; + rapidjson::Document json; + std::string type, remark, hostname, port, username, password, method; + std::string plugin, pluginopts; + std::string protocol, protoparam, obfs, obfsparam; + std::string id, aid, transproto, faketype, host, edge, path, quicsecure, quicsecret; + std::vector nodelist; + bool tlssecure, replace_flag; + string_array vArray, remarks_list, filtered_nodelist; for(nodeInfo &x : nodes) { @@ -740,14 +747,15 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["password"] = password; if(std::all_of(password.begin(), password.end(), ::isdigit)) singleproxy["password"].SetTag("str"); - if(plugin == "simple-obfs" || plugin == "obfs-local") + switch(hash_(plugin)) { + case "simple-obfs"_hash: + case "obfs-local"_hash: singleproxy["plugin"] = "obfs"; singleproxy["plugin-opts"]["mode"] = UrlDecode(getUrlArg(pluginopts, "obfs")); singleproxy["plugin-opts"]["host"] = UrlDecode(getUrlArg(pluginopts, "obfs-host")); - } - else if(plugin == "v2ray-plugin") - { + break; + case "v2ray-plugin"_hash: singleproxy["plugin"] = "v2ray-plugin"; singleproxy["plugin-opts"]["mode"] = getUrlArg(pluginopts, "mode"); singleproxy["plugin-opts"]["host"] = getUrlArg(pluginopts, "host"); @@ -756,6 +764,7 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["plugin-opts"]["mux"] = pluginopts.find("mux") != pluginopts.npos; if(ext.skip_cert_verify) singleproxy["plugin-opts"]["skip-cert-verify"] = true; + break; } break; case SPEEDTEST_MESSAGE_FOUNDVMESS: @@ -773,8 +782,11 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["tls"] = tlssecure; if(ext.skip_cert_verify) singleproxy["skip-cert-verify"] = true; - if(transproto == "ws") + switch(hash_(transproto)) { + case "tcp"_hash: + break; + case "ws"_hash: singleproxy["network"] = transproto; singleproxy["ws-path"] = path; singleproxy["ws-headers"]["Host"] = host; @@ -784,9 +796,10 @@ void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_arr singleproxy["ws-headers"]["Edge"] = edge; singleproxy["headers"]["Edge"] = edge; } - } - else if(transproto == "kcp" || transproto == "h2" || transproto == "quic") + break; + default: continue; + } break; case SPEEDTEST_MESSAGE_FOUNDSSR: if(!clashR) @@ -973,24 +986,6 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s ini.EraseSection(); ini.Set("{NONAME}", "DIRECT = direct"); - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -1038,16 +1033,20 @@ std::string netchToSurge(std::vector &nodes, std::string &base_conf, s path = GetMember(json, "Path"); tlssecure = GetMember(json, "TLSSecure") == "true"; proxy = "vmess, " + hostname + ", " + port + ", username=" + id + ", tls=" + (tlssecure ? "true" : "false"); - if(transproto == "ws") + switch(hash_(transproto)) { + case "tcp"_hash: + break; + case "ws"_hash: proxy += ", ws=true, ws-path=" + path + ", ws-headers=Host:" + host; if(edge.size()) proxy += "|Edge:" + edge; + break; + default: + continue; } if(ext.skip_cert_verify) proxy += ", skip-cert-verify=1"; - else if(transproto == "kcp" || transproto == "h2" || transproto == "quic") - continue; break; case SPEEDTEST_MESSAGE_FOUNDSSR: if(ext.surge_ssr_path.empty() || surge_ver < 2) @@ -1191,24 +1190,6 @@ std::string netchToSS(std::vector &nodes, extra_settings &ext) std::string protocol, protoparam, obfs, obfsparam; std::string proxyStr, allLinks; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -1262,25 +1243,6 @@ std::string netchToSSSub(std::vector &nodes, extra_settings &ext) int port; writer.StartArray(); - - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -1336,24 +1298,6 @@ std::string netchToSSR(std::vector &nodes, extra_settings &ext) std::string protocol, protoparam, obfs, obfsparam; std::string proxyStr, allLinks; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -1397,24 +1341,6 @@ std::string netchToVMess(std::vector &nodes, extra_settings &ext) std::string proxyStr, allLinks; bool tlssecure; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -1451,24 +1377,6 @@ std::string netchToTrojan(std::vector &nodes, extra_settings &ext) std::string server, port, psk, remark; std::string proxyStr, allLinks; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -1529,24 +1437,6 @@ void netchToQuan(std::vector &nodes, INIReader &ini, std::vector nodelist; string_array remarks_list; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - ini.SetCurrentSection("SERVER"); ini.EraseSection(); for(nodeInfo &x : nodes) @@ -1755,24 +1645,6 @@ void netchToQuanX(std::vector &nodes, INIReader &ini, std::vector nodelist; string_array remarks_list; - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - ini.SetCurrentSection("server_local"); ini.EraseSection(); for(nodeInfo &x : nodes) @@ -1835,6 +1707,17 @@ void netchToQuanX(std::vector &nodes, INIReader &ini, std::vector &nodes, INIReader &ini, std::vector &nodes, std::string &base_conf, st ini.SetCurrentSection("Proxy"); ini.EraseSection(); - std::for_each(nodes.begin(), nodes.end(), [ext](nodeInfo &x) - { - x.remarks = nodeRename(x.remarks, x.groupID, ext.rename_array); - if(ext.remove_emoji) - x.remarks = trim(removeEmoji(x.remarks)); - - if(ext.add_emoji) - x.remarks = addEmoji(x.remarks, x.groupID, ext.emoji_array); - }); - - if(ext.sort_flag) - { - std::sort(nodes.begin(), nodes.end(), [](const nodeInfo &a, const nodeInfo &b) - { - return a.remarks < b.remarks; - }); - } - for(nodeInfo &x : nodes) { json.Parse(x.proxyStr.data()); @@ -2386,14 +2215,17 @@ std::string netchToLoon(std::vector &nodes, std::string &base_conf, st proxy = "vmess," + hostname + "," + port + "," + method + ",\"" + id + "\",over-tls:" + (tlssecure ? "true" : "false"); if(tlssecure) proxy += ",tls-name:" + host; - if(transproto == "ws") + switch(hash_(transproto)) { - proxy += ",transport:ws,path:" + path + ",host:" + host; - } - else if(transproto == "kcp" || transproto == "h2" || transproto == "quic") - continue; - else + case "tcp"_hash: proxy += ",transport:tcp"; + break; + case "ws"_hash: + proxy += ",transport:ws,path:" + path + ",host:" + host; + break; + default: + continue; + } if(ext.skip_cert_verify) proxy += ",skip-cert-verify:1"; break; diff --git a/src/subexport.h b/src/subexport.h index a6dec30..82504bb 100644 --- a/src/subexport.h +++ b/src/subexport.h @@ -37,6 +37,8 @@ struct extra_settings void rulesetToClash(YAML::Node &base_rule, std::vector &ruleset_content_array, bool overwrite_original_rules); void rulesetToSurge(INIReader &base_rule, std::vector &ruleset_content_array, int surge_ver, bool overwrite_original_rules, std::string remote_path_prefix); +void preprocessNodes(std::vector &nodes, extra_settings &ext); + std::string netchToClash(std::vector &nodes, std::string &base_conf, std::vector &ruleset_content_array, string_array &extra_proxy_group, bool clashR, extra_settings &ext); void netchToClash(std::vector &nodes, YAML::Node &yamlnode, string_array &extra_proxy_group, bool clashR, extra_settings &ext); std::string netchToSurge(std::vector &nodes, std::string &base_conf, std::vector &ruleset_content_array, string_array &extra_proxy_group, int surge_ver, extra_settings &ext); @@ -53,6 +55,7 @@ void netchToQuanX(std::vector &nodes, INIReader &ini, std::vector &nodes, std::string &base_conf, std::vector &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext); void netchToQuan(std::vector &nodes, INIReader &ini, std::vector &ruleset_content_array, string_array &extra_proxy_group, extra_settings &ext); std::string netchToSSD(std::vector &nodes, std::string &group, std::string &userinfo, extra_settings &ext); + std::string buildGistData(std::string name, std::string content); int uploadGist(std::string name, std::string path, std::string content, bool writeManageURL);