mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2026-11-05 11:12:12 +00:00
Fix implementation of v2ray-plugin in Quantumult X subscriptions
Add example for using Clash proxy-provider. Optimize codes.
This commit is contained in:
5 files changed
+142
-25
No files matched your search
@@ -0,0 +1,17 @@
|
|||||||
|
mixed-port: 7890
|
||||||
|
allow-lan: true
|
||||||
|
mode: Rule
|
||||||
|
log-level: info
|
||||||
|
external-controller: 127.0.0.1:9090
|
||||||
|
proxy-providers:
|
||||||
|
HK:
|
||||||
|
type: http
|
||||||
|
path: proxy-providers/HK.yaml
|
||||||
|
url: {{ getLink("/sub?target=clash&list=true&include=HK&url=https%3A%2F%2Fexample.com%2Fsubscription") }}
|
||||||
|
interval: 86400
|
||||||
|
health-check:
|
||||||
|
enable: true
|
||||||
|
url: http://www.gstatic.com/generate_204
|
||||||
|
interval: 300
|
||||||
|
rule-providers: ~
|
||||||
|
rules: ~
|
||||||
+19
-1
@@ -162,7 +162,7 @@ public:
|
|||||||
|
|
||||||
template <typename T> tribool(const T &value) { set(value); }
|
template <typename T> tribool(const T &value) { set(value); }
|
||||||
|
|
||||||
explicit tribool(const tribool &value) { *this = value; }
|
tribool(const tribool &value) { *this = value; }
|
||||||
|
|
||||||
~tribool() = default;
|
~tribool() = default;
|
||||||
|
|
||||||
@@ -194,6 +194,12 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tribool reverse()
|
||||||
|
{
|
||||||
|
_M_VALUE = _M_VALUE == -1 ? -1 : (_M_VALUE == 0 ? 1 : 0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool get(const bool &def_value = false)
|
bool get(const bool &def_value = false)
|
||||||
{
|
{
|
||||||
if(_M_VALUE == -1)
|
if(_M_VALUE == -1)
|
||||||
@@ -201,6 +207,18 @@ public:
|
|||||||
return _M_VALUE;
|
return _M_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_str()
|
||||||
|
{
|
||||||
|
switch(_M_VALUE)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "false";
|
||||||
|
case 1:
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
|
return "undef";
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T> bool set(const T &value)
|
template <typename T> bool set(const T &value)
|
||||||
{
|
{
|
||||||
_M_VALUE = value;
|
_M_VALUE = value;
|
||||||
|
|||||||
+39
-8
@@ -903,7 +903,7 @@ void explodeNetch(std::string netch, bool ss_libev, bool ssr_libev, const std::s
|
|||||||
if(group.empty())
|
if(group.empty())
|
||||||
group = HTTP_DEFAULT_GROUP;
|
group = HTTP_DEFAULT_GROUP;
|
||||||
node.group = group;
|
node.group = group;
|
||||||
node.proxyStr = httpConstruct(group, remark, address, port, username, password, type == "HTTPS", scv);
|
node.proxyStr = httpConstruct(group, remark, address, port, username, password, type == "HTTPS", tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "Trojan"_hash:
|
case "Trojan"_hash:
|
||||||
host = GetMember(json, "Host");
|
host = GetMember(json, "Host");
|
||||||
@@ -1081,7 +1081,7 @@ void explodeClash(Node yamlnode, const std::string &custom_port, std::vector<nod
|
|||||||
singleproxy["tls"] >>= tls;
|
singleproxy["tls"] >>= tls;
|
||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
node.proxyStr = httpConstruct(group, ps, server, port, user, password, tls == "true", scv);
|
node.proxyStr = httpConstruct(group, ps, server, port, user, password, tls == "true", tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "trojan"_hash:
|
case "trojan"_hash:
|
||||||
group = TROJAN_DEFAULT_GROUP;
|
group = TROJAN_DEFAULT_GROUP;
|
||||||
@@ -1242,7 +1242,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
for(auto &x : proxies)
|
for(auto &x : proxies)
|
||||||
{
|
{
|
||||||
std::string remarks, server, port, method, username, password; //common
|
std::string remarks, server, port, method, username, password; //common
|
||||||
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host = "cloudfront.net", mod_url, mod_md5; //ss
|
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, mod_url, mod_md5; //ss
|
||||||
std::string id, net, tls, host, edge, path; //v2
|
std::string id, net, tls, host, edge, path; //v2
|
||||||
std::string protocol, protoparam; //ssr
|
std::string protocol, protoparam; //ssr
|
||||||
std::string itemName, itemVal, config;
|
std::string itemName, itemVal, config;
|
||||||
@@ -1458,7 +1458,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.proxyStr = httpConstruct(node.group, remarks, server, port, username, password, false, scv);
|
node.proxyStr = httpConstruct(node.group, remarks, server, port, username, password, false, tfo, scv);
|
||||||
break;
|
break;
|
||||||
case "trojan"_hash: // surge 4 style trojan proxy
|
case "trojan"_hash: // surge 4 style trojan proxy
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDTROJAN;
|
||||||
@@ -1546,10 +1546,28 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
case "ssr-protocol"_hash: protocol = itemVal; break;
|
case "ssr-protocol"_hash: protocol = itemVal; break;
|
||||||
case "ssr-protocol-param"_hash: protoparam = itemVal; break;
|
case "ssr-protocol-param"_hash: protoparam = itemVal; break;
|
||||||
case "obfs"_hash:
|
case "obfs"_hash:
|
||||||
plugin = "simple-obfs";
|
{
|
||||||
pluginopts_mode = itemVal;
|
switch(hash_(itemVal))
|
||||||
|
{
|
||||||
|
case "http"_hash:
|
||||||
|
case "tls"_hash:
|
||||||
|
plugin = "simple-obfs";
|
||||||
|
pluginopts_mode = itemVal;
|
||||||
|
break;
|
||||||
|
case "wss"_hash:
|
||||||
|
tls = "tls";
|
||||||
|
[[fallthrough]];
|
||||||
|
case "ws"_hash:
|
||||||
|
pluginopts_mode = "websocket";
|
||||||
|
plugin = "v2ray-plugin";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pluginopts_mode = itemVal;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case "obfs-host"_hash: pluginopts_host = itemVal; break;
|
case "obfs-host"_hash: pluginopts_host = itemVal; break;
|
||||||
|
case "obfs-uri"_hash: path = itemVal; break;
|
||||||
case "udp-relay"_hash: udp = itemVal; break;
|
case "udp-relay"_hash: udp = itemVal; break;
|
||||||
case "fast-open"_hash: tfo = itemVal; break;
|
case "fast-open"_hash: tfo = itemVal; break;
|
||||||
case "tls13"_hash: tls13 = itemVal; break;
|
case "tls13"_hash: tls13 = itemVal; break;
|
||||||
@@ -1558,11 +1576,23 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
}
|
}
|
||||||
if(remarks.empty())
|
if(remarks.empty())
|
||||||
remarks = server + ":" + port;
|
remarks = server + ":" + port;
|
||||||
if(plugin.size())
|
switch(hash_(plugin))
|
||||||
{
|
{
|
||||||
|
case "simple-obfs"_hash:
|
||||||
pluginopts = "obfs=" + pluginopts_mode;
|
pluginopts = "obfs=" + pluginopts_mode;
|
||||||
if(pluginopts_host.size())
|
if(pluginopts_host.size())
|
||||||
pluginopts += ";obfs-host=" + pluginopts_host;
|
pluginopts += ";obfs-host=" + pluginopts_host;
|
||||||
|
break;
|
||||||
|
case "v2ray-plugin"_hash:
|
||||||
|
if(pluginopts_host.empty() && !isIPv4(server) && !isIPv6(server))
|
||||||
|
pluginopts_host = server;
|
||||||
|
pluginopts = "mode=" + pluginopts_mode;
|
||||||
|
if(pluginopts_host.size())
|
||||||
|
pluginopts += ";host=" + pluginopts_host;
|
||||||
|
if(path.size())
|
||||||
|
pluginopts += ";path=" + path;
|
||||||
|
pluginopts += ";" + tls;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(protocol.size())
|
if(protocol.size())
|
||||||
@@ -1681,6 +1711,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
case "over-tls"_hash: tls = itemVal; break;
|
case "over-tls"_hash: tls = itemVal; break;
|
||||||
case "tls-verification"_hash: scv = itemVal == "false"; break;
|
case "tls-verification"_hash: scv = itemVal == "false"; break;
|
||||||
case "tls13"_hash: tls13 = itemVal; break;
|
case "tls13"_hash: tls13 = itemVal; break;
|
||||||
|
case "fast-open"_hash: tfo = itemVal; break;
|
||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1697,7 +1728,7 @@ bool explodeSurge(std::string surge, const std::string &custom_port, std::vector
|
|||||||
|
|
||||||
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
node.linkType = SPEEDTEST_MESSAGE_FOUNDHTTP;
|
||||||
node.group = HTTP_DEFAULT_GROUP;
|
node.group = HTTP_DEFAULT_GROUP;
|
||||||
node.proxyStr = httpConstruct(node.group, remarks, server, port, username, password, tls == "true", scv, tls13);
|
node.proxyStr = httpConstruct(node.group, remarks, server, port, username, password, tls == "true", tfo, scv, tls13);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ std::string vmessConstruct(const std::string &group, const std::string &remarks,
|
|||||||
std::string ssrConstruct(const std::string &group, const std::string &remarks, const std::string &remarks_base64, const std::string &server, const std::string &port, const std::string &protocol, const std::string &method, const std::string &obfs, const std::string &password, const std::string &obfsparam, const std::string &protoparam, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string ssrConstruct(const std::string &group, const std::string &remarks, const std::string &remarks_base64, const std::string &server, const std::string &port, const std::string &protocol, const std::string &method, const std::string &obfs, const std::string &password, const std::string &obfsparam, const std::string &protoparam, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string ssConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &method, const std::string &plugin, const std::string &pluginopts, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
std::string ssConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &method, const std::string &plugin, const std::string &pluginopts, bool libev, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
||||||
std::string socksConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string socksConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
||||||
std::string httpConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool scv = tribool(), tribool tls13 = tribool());
|
std::string httpConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
||||||
std::string trojanConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &host, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
std::string trojanConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &host, bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
|
||||||
std::string snellConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const std::string &host, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
|
std::string snellConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &password, const std::string &obfs, const 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 explodeVmess(std::string vmess, const std::string &custom_port, nodeInfo &node);
|
||||||
|
|||||||
+66
-15
@@ -273,7 +273,7 @@ std::string socksConstruct(const std::string &group, const std::string &remarks,
|
|||||||
return sb.GetString();
|
return sb.GetString();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string httpConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool scv, tribool tls13)
|
std::string httpConstruct(const std::string &group, const std::string &remarks, const std::string &server, const std::string &port, const std::string &username, const std::string &password, bool tls, tribool tfo, tribool scv, tribool tls13)
|
||||||
{
|
{
|
||||||
rapidjson::StringBuffer sb;
|
rapidjson::StringBuffer sb;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
|
||||||
@@ -292,6 +292,13 @@ std::string httpConstruct(const std::string &group, const std::string &remarks,
|
|||||||
writer.String(username.data());
|
writer.String(username.data());
|
||||||
writer.Key("Password");
|
writer.Key("Password");
|
||||||
writer.String(password.data());
|
writer.String(password.data());
|
||||||
|
writer.Key("TLSSecure");
|
||||||
|
writer.Bool(tls);
|
||||||
|
if(!tfo.is_undef())
|
||||||
|
{
|
||||||
|
writer.Key("EnableTFO");
|
||||||
|
writer.Bool(tfo);
|
||||||
|
}
|
||||||
if(!scv.is_undef())
|
if(!scv.is_undef())
|
||||||
{
|
{
|
||||||
writer.Key("AllowInsecure");
|
writer.Key("AllowInsecure");
|
||||||
@@ -1540,8 +1547,18 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, const std::string &base_c
|
|||||||
{
|
{
|
||||||
proxy = "custom, " + hostname + ", " + port + ", " + method + ", " + password + ", https://github.com/ConnersHua/SSEncrypt/raw/master/SSEncrypt.module";
|
proxy = "custom, " + hostname + ", " + port + ", " + method + ", " + password + ", https://github.com/ConnersHua/SSEncrypt/raw/master/SSEncrypt.module";
|
||||||
}
|
}
|
||||||
if(plugin.size() && pluginopts.size())
|
if(plugin.size())
|
||||||
proxy += "," + replace_all_distinct(pluginopts, ";", ",");
|
{
|
||||||
|
switch(hash_(plugin))
|
||||||
|
{
|
||||||
|
case "simple-obfs"_hash:
|
||||||
|
if(pluginopts.size())
|
||||||
|
proxy += "," + replace_all_distinct(pluginopts, ";", ",");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDVMESS:
|
case SPEEDTEST_MESSAGE_FOUNDVMESS:
|
||||||
if(surge_ver < 4 && surge_ver != -3)
|
if(surge_ver < 4 && surge_ver != -3)
|
||||||
@@ -1638,10 +1655,10 @@ std::string netchToSurge(std::vector<nodeInfo> &nodes, const std::string &base_c
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tfo)
|
if(!tfo.is_undef())
|
||||||
proxy += ", tfo=true";
|
proxy += ", tfo=" + tfo.get_str();
|
||||||
if(udp)
|
if(!udp.is_undef())
|
||||||
proxy += ", udp-relay=true";
|
proxy += ", udp-relay=" + udp.get_str();
|
||||||
|
|
||||||
if(ext.nodelist)
|
if(ext.nodelist)
|
||||||
output_nodelist += remark + " = " + proxy + "\n";
|
output_nodelist += remark + " = " + proxy + "\n";
|
||||||
@@ -2278,8 +2295,36 @@ void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rule
|
|||||||
plugin = GetMember(json, "Plugin");
|
plugin = GetMember(json, "Plugin");
|
||||||
pluginopts = GetMember(json, "PluginOption");
|
pluginopts = GetMember(json, "PluginOption");
|
||||||
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
|
proxyStr = "shadowsocks = " + hostname + ":" + port + ", method=" + method + ", password=" + password;
|
||||||
if(plugin.size() && pluginopts.size())
|
if(plugin.size())
|
||||||
proxyStr += ", " + replace_all_distinct(pluginopts, ";", ", ");
|
{
|
||||||
|
switch(hash_(plugin))
|
||||||
|
{
|
||||||
|
case "simple-obfs"_hash:
|
||||||
|
if(pluginopts.size())
|
||||||
|
proxyStr += ", " + replace_all_distinct(pluginopts, ";", ", ");
|
||||||
|
break;
|
||||||
|
case "v2ray-plugin"_hash:
|
||||||
|
pluginopts = replace_all_distinct(pluginopts, ";", "&");
|
||||||
|
plugin = getUrlArg(pluginopts, "mode") == "websocket" ? "ws" : "";
|
||||||
|
host = getUrlArg(pluginopts, "host");
|
||||||
|
path = getUrlArg(pluginopts, "path");
|
||||||
|
tlssecure = pluginopts.find("tls") != pluginopts.npos;
|
||||||
|
if(tlssecure && plugin == "ws")
|
||||||
|
{
|
||||||
|
plugin += 's';
|
||||||
|
if(!tls13.is_undef())
|
||||||
|
proxyStr += ", tls13=" + std::string(tls13 ? "true" : "false");
|
||||||
|
}
|
||||||
|
proxyStr += ", obfs=" + plugin;
|
||||||
|
if(host.size())
|
||||||
|
proxyStr += ", obfs-host=" + host;
|
||||||
|
if(path.size())
|
||||||
|
proxyStr += ", obfs-uri=" + path;
|
||||||
|
break;
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDSSR:
|
case SPEEDTEST_MESSAGE_FOUNDSSR:
|
||||||
password = GetMember(json, "Password");
|
password = GetMember(json, "Password");
|
||||||
@@ -2301,7 +2346,11 @@ void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rule
|
|||||||
|
|
||||||
proxyStr = "http = " + hostname + ":" + port + ", username=" + (id.size() ? id : "none") + ", password=" + (password.size() ? password : "none");
|
proxyStr = "http = " + hostname + ":" + port + ", username=" + (id.size() ? id : "none") + ", password=" + (password.size() ? password : "none");
|
||||||
if(tlssecure)
|
if(tlssecure)
|
||||||
|
{
|
||||||
proxyStr += ", over-tls=true";
|
proxyStr += ", over-tls=true";
|
||||||
|
if(!tls13.is_undef())
|
||||||
|
proxyStr += ", tls13=" + std::string(tls13 ? "true" : "false");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SPEEDTEST_MESSAGE_FOUNDTROJAN:
|
case SPEEDTEST_MESSAGE_FOUNDTROJAN:
|
||||||
password = GetMember(json, "Password");
|
password = GetMember(json, "Password");
|
||||||
@@ -2312,17 +2361,19 @@ void netchToQuanX(std::vector<nodeInfo> &nodes, INIReader &ini, std::vector<rule
|
|||||||
if(tlssecure)
|
if(tlssecure)
|
||||||
{
|
{
|
||||||
proxyStr += ", over-tls=true, tls-host=" + host;
|
proxyStr += ", over-tls=true, tls-host=" + host;
|
||||||
|
if(!tls13.is_undef())
|
||||||
|
proxyStr += ", tls13=" + std::string(tls13 ? "true" : "false");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(tfo)
|
if(!tfo.is_undef())
|
||||||
proxyStr += ", fast-open=true";
|
proxyStr += ", fast-open=" + tfo.get_str();
|
||||||
if(udp)
|
if(!udp.is_undef())
|
||||||
proxyStr += ", udp-relay=true";
|
proxyStr += ", udp-relay=" + tfo.get_str();
|
||||||
if(scv && (x.linkType == SPEEDTEST_MESSAGE_FOUNDHTTP || x.linkType == SPEEDTEST_MESSAGE_FOUNDTROJAN))
|
if(!scv.is_undef() && (x.linkType == SPEEDTEST_MESSAGE_FOUNDHTTP || x.linkType == SPEEDTEST_MESSAGE_FOUNDTROJAN))
|
||||||
proxyStr += ", tls-verification=false";
|
proxyStr += ", tls-verification=" + scv.reverse().get_str();
|
||||||
proxyStr += ", tag=" + remark;
|
proxyStr += ", tag=" + remark;
|
||||||
|
|
||||||
ini.Set("{NONAME}", proxyStr);
|
ini.Set("{NONAME}", proxyStr);
|
||||||
|
|||||||
Reference in new issue
Block a user