Skip to content

Commit

Permalink
feat: support hysteria2 for clash.meta
Browse files Browse the repository at this point in the history
  • Loading branch information
dzhuang committed Dec 6, 2023
1 parent 64a0c99 commit 17538a2
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/generator/config/subexport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ bool applyMatcher(const std::string &rule, std::string &real_rule, const Proxy &
std::string target, ret_real_rule;
static const std::string groupid_regex = R"(^!!(?:GROUPID|INSERT)=([\d\-+!,]+)(?:!!(.*))?$)", group_regex = R"(^!!(?:GROUP)=(.+?)(?:!!(.*))?$)";
static const std::string type_regex = R"(^!!(?:TYPE)=(.+?)(?:!!(.*))?$)", port_regex = R"(^!!(?:PORT)=(.+?)(?:!!(.*))?$)", server_regex = R"(^!!(?:SERVER)=(.+?)(?:!!(.*))?$)";
static const string_array types = {"", "SS", "SSR", "VMESS", "TROJAN", "SNELL", "HTTP", "HTTPS", "SOCKS5","VLESS","HYSTERIA"};
static const string_array types = {"", "SS", "SSR", "VMESS", "TROJAN", "SNELL", "HTTP", "HTTPS", "SOCKS5","VLESS","HYSTERIA","HYSTERIA2"};
if (startsWith(rule, "!!GROUP=")) {
regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule);
real_rule = ret_real_rule;
Expand Down Expand Up @@ -352,6 +352,28 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
if (!x.OBFSParam.empty())
singleproxy["obfs"] = x.OBFSParam;
break;
case ProxyType::Hysteria2:
singleproxy["type"] = "hysteria2";
singleproxy["password"] = x.Password;
if (!x.UpMbps.empty())
singleproxy["up"] = x.UpMbps;
if (!x.DownMbps.empty())
singleproxy["down"] = x.DownMbps;
if (!tfo.is_undef())
singleproxy["fast-open"] = tfo.get();
if (!x.Host.empty())
singleproxy["sni"] = x.Host;
if (!scv.is_undef())
singleproxy["skip-cert-verify"] = scv.get();
if (x.Insecure == "1")
singleproxy["skip-cert-verify"] = true;
if (!x.Alpn.empty())
singleproxy["alpn"].push_back(x.Alpn);
if (!x.OBFSParam.empty())
singleproxy["obfs"] = x.OBFSParam;
if (!x.OBFSPassword.empty())
singleproxy["obfs-password"] = x.OBFSPassword;
break;
case ProxyType::VLESS:
singleproxy["type"] = "vless";
singleproxy["uuid"] = x.UserId;
Expand Down
6 changes: 6 additions & 0 deletions src/parser/config/proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum ProxyType
VMess,
VLESS,
Hysteria,
Hysteria2,
Trojan,
Snell,
HTTP,
Expand All @@ -36,6 +37,8 @@ inline String getProxyTypeName(int type)
return "VLESS";
case ProxyType::Hysteria:
return "Hysteria";
case ProxyType::Hysteria2:
return "Hysteria2";
case ProxyType::Trojan:
return "Trojan";
case ProxyType::Snell:
Expand Down Expand Up @@ -107,13 +110,16 @@ struct Proxy
String PublicKey;
String ShortId;

String OBFSPassword;

};

#define SS_DEFAULT_GROUP "SSProvider"
#define SSR_DEFAULT_GROUP "SSRProvider"
#define V2RAY_DEFAULT_GROUP "V2RayProvider"
#define XRAY_DEFAULT_GROUP "XRayProvider"
#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider"
#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider"
#define SOCKS_DEFAULT_GROUP "SocksProvider"
#define HTTP_DEFAULT_GROUP "HTTPProvider"
#define TROJAN_DEFAULT_GROUP "TrojanProvider"
Expand Down
72 changes: 72 additions & 0 deletions src/parser/subparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
node.FakeType = type;
}

void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure ,tribool udp, tribool tfo, tribool scv, tribool tls13)
{
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tls13);
node.Password = password;
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
node.UpMbps = up;
node.DownMbps = down;
node.Alpn = alpn;
node.OBFSParam = obfsParam;
node.OBFSPassword = obfsPassword;
node.Insecure = insecure;
}

void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pbk, const std::string &sid, const std::string &fp ,tribool udp, tribool tfo, tribool scv, tribool tls13)
{
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13);
Expand Down Expand Up @@ -188,6 +201,16 @@ void explodeHysteria(std::string hysteria, Proxy &node)
}
}

void explodeHysteria2(std::string hysteria2, Proxy &node)
{
printf("explodeHysteria2\n");
if(regMatch(hysteria2, "hysteria2://(.*?)[:](.*)"))
{
explodeStdHysteria2(hysteria2, node);
return;
}
}

void explodeVmess(std::string vmess, Proxy &node)
{
std::string version, ps, add, port, type, id, aid, net, path, host, tls, sni, alpn;
Expand Down Expand Up @@ -1035,6 +1058,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)
std::string flow, mode; //trojan
std::string user; //socks
std::string auth,up,down,obfsParam,insecure;//hysteria
std::string password,up,down,obfsParam,obfsPassword,insecure;//hysteria2
tribool udp, tfo, scv;
Node singleproxy;
uint32_t index = nodes.size();
Expand Down Expand Up @@ -1317,6 +1341,19 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes)

hysteriaConstruct(node, group, ps, server, port, type, auth, host, up, down, alpn, obfsParam, insecure, udp, tfo, scv);
break;
case "hysteria2"_hash:
group = HYSTERIA2_DEFAULT_GROUP;
singleproxy["password"] >> password;
singleproxy["up"] >> up;
singleproxy["down"] >> down;
singleproxy["obfs"] >> obfsParam;
singleproxy["obfs-password"] >> obfsPassword;
singleproxy["sni"] >> host;
singleproxy["alpn"][0] >> alpn;
singleproxy["skip-cert-verify"] >> insecure;

hysteria2Construct(node, group, ps, server, port, password, host, up, down, alpn, obfsParam, obfsPassword, insecure, udp, tfo, scv);
break;
default:
continue;
}
Expand Down Expand Up @@ -1404,6 +1441,39 @@ void explodeStdHysteria(std::string hysteria, Proxy &node)
return;
}

void explodeStdHysteria2(std::string hysteria2, Proxy &node)
{
std::string add, port, type, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks;
std::string addition;
hysteria2 = hysteria2.substr(12);
string_size pos;

pos = hysteria2.rfind("#");
if(pos != hysteria2.npos)
{
remarks = urlDecode(hysteria2.substr(pos + 1));
hysteria2.erase(pos);
}
const std::string stdhysteria2_matcher = R"(^(.*)[:](\d+)[?](.*)$)";
if(regGetMatch(hysteria2, stdhysteria2_matcher, 4, 0, &add, &port, &addition))
return;
type = getUrlArg(addition,"protocol");
password = getUrlArg(addition,"password");
host = getUrlArg(addition,"peer");
insecure = getUrlArg(addition, "insecure");
up = getUrlArg(addition,"upmbps");
down = getUrlArg(addition,"downmbps");
alpn = getUrlArg(addition,"alpn");
obfsParam = getUrlArg(addition,"obfsParam");
obfsPassword = getUrlArg(addition,"obfsPassword");

if(remarks.empty())
remarks = add + ":" + port;

hysteria2Construct(node, HYSTERIA2_DEFAULT_GROUP, remarks, add, port, type, password, host, up, down, alpn, obfsParam, obfsPassword, insecure);
return;
}

void explodeStdVless(std::string vless, Proxy &node)
{
std::string add, port, type, id, aid, net, flow, pbk, sid, fp, mode, path, host, tls, remarks;
Expand Down Expand Up @@ -2335,6 +2405,8 @@ void explode(const std::string &link, Proxy &node)
explodeVless(link, node);
else if(strFind(link, "hysteria://"))
explodeHysteria(link, node);
else if(strFind(link, "hysteria2://"))
explodeHysteria2(link, node);
else if(strFind(link, "ss://"))
explodeSS(link, node);
else if(strFind(link, "socks://") || strFind(link, "https://t.me/socks") || strFind(link, "tg://socks"))
Expand Down
3 changes: 3 additions & 0 deletions src/parser/subparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum class ConfType
};

void hysteriaConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &auth, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &insecure ,tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void hysteria2Construct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &password, const std::string &host, const std::string &up, const std::string &down, const std::string &alpn, const std::string &obfsParam, const std::string &obfsPassword, const std::string &insecure ,tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void vmessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls, const std::string &sni, const std::string &alpn, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void vlessConstruct(Proxy &node, const std::string &group, const std::string &remarks, const std::string &add, const std::string &port, const std::string &type, const std::string &id, const std::string &aid, const std::string &net, const std::string &cipher, const std::string &flow, const std::string &mode, const std::string &path, const std::string &host, const std::string &edge, const std::string &tls,const std::string &pkd, const std::string &sid, const std::string &fp, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(), tribool tls13 = tribool());
void ssrConstruct(Proxy &node, const std::string &group, const std::string &remarks, 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, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool());
Expand All @@ -32,13 +33,15 @@ void snellConstruct(Proxy &node, const std::string &group, const std::string &re
void explodeVmess(std::string vmess, Proxy &node);
void explodeVless(std::string vless, Proxy &node);
void explodeHysteria(std::string hysteria, Proxy &node);
void explodeHysteria2(std::string hysteria2, Proxy &node);
void explodeSSR(std::string ssr, Proxy &node);
void explodeSS(std::string ss, Proxy &node);
void explodeTrojan(std::string trojan, Proxy &node);
void explodeQuan(const std::string &quan, Proxy &node);
void explodeStdVMess(std::string vmess, Proxy &node);
void explodeStdVless(std::string vless, Proxy &node);
void explodeStdHysteria(std::string hysteria, Proxy &node);
void explodeStdHysteria2(std::string hysteria2, Proxy &node);
void explodeShadowrocket(std::string kit, Proxy &node);
void explodeKitsunebi(std::string kit, Proxy &node);
/// Parse a link
Expand Down

0 comments on commit 17538a2

Please sign in to comment.