mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2026-11-03 18:24:58 +00:00
Add Hysteria & Hysteria 2 support (#731)
* feat: add hysteria & hysteria 2 support * Fix build error * Remove deleted rules repository --------- Co-authored-by: Tindy X <49061470+tindy2013@users.noreply.github.com>
This commit is contained in:
1 parent
79a7e888b1
commit
c207bfc1f0
8 files changed
+467
-20
No files matched your search
@@ -116,15 +116,19 @@ 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 std::map<ProxyType, const char *> types = {{ProxyType::Shadowsocks, "SS"},
|
||||
{ProxyType::ShadowsocksR, "SSR"},
|
||||
{ProxyType::VMess, "VMESS"},
|
||||
{ProxyType::Trojan, "TROJAN"},
|
||||
{ProxyType::Snell, "SNELL"},
|
||||
{ProxyType::HTTP, "HTTP"},
|
||||
{ProxyType::HTTPS, "HTTPS"},
|
||||
{ProxyType::SOCKS5, "SOCKS5"},
|
||||
{ProxyType::WireGuard, "WIREGUARD"}};
|
||||
static const std::map<ProxyType, const char *> types = {
|
||||
{ProxyType::Shadowsocks, "SS"},
|
||||
{ProxyType::ShadowsocksR, "SSR"},
|
||||
{ProxyType::VMess, "VMESS"},
|
||||
{ProxyType::Trojan, "TROJAN"},
|
||||
{ProxyType::Snell, "SNELL"},
|
||||
{ProxyType::HTTP, "HTTP"},
|
||||
{ProxyType::HTTPS, "HTTPS"},
|
||||
{ProxyType::SOCKS5, "SOCKS5"},
|
||||
{ProxyType::WireGuard, "WIREGUARD"},
|
||||
{ProxyType::Hysteria, "HYSTERIA"},
|
||||
{ProxyType::Hysteria2, "HYSTERIA2"}
|
||||
};
|
||||
if(startsWith(rule, "!!GROUP="))
|
||||
{
|
||||
regGetMatch(rule, group_regex, 3, 0, &target, &ret_real_rule);
|
||||
@@ -478,6 +482,77 @@ void proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGr
|
||||
if(x.Mtu > 0)
|
||||
singleproxy["mtu"] = x.Mtu;
|
||||
break;
|
||||
case ProxyType::Hysteria:
|
||||
singleproxy["type"] = "hysteria";
|
||||
if (!x.Ports.empty())
|
||||
singleproxy["ports"] = x.Ports;
|
||||
if (!x.Protocol.empty())
|
||||
singleproxy["protocol"] = x.Protocol;
|
||||
if (!x.OBFSParam.empty())
|
||||
singleproxy["obfs-protocol"] = x.OBFSParam;
|
||||
if (!x.Up.empty())
|
||||
singleproxy["up"] = x.Up;
|
||||
if (x.UpSpeed)
|
||||
singleproxy["up-speed"] = x.UpSpeed;
|
||||
if (!x.Down.empty())
|
||||
singleproxy["down"] = x.Down;
|
||||
if (x.DownSpeed)
|
||||
singleproxy["down-speed"] = x.DownSpeed;
|
||||
if (!x.AuthStr.empty())
|
||||
{
|
||||
singleproxy["auth-str"] = x.AuthStr;
|
||||
singleproxy["auth"] = base64Encode(x.AuthStr);
|
||||
}
|
||||
if (!x.OBFS.empty())
|
||||
singleproxy["obfs"] = x.OBFS;
|
||||
if (!x.SNI.empty())
|
||||
singleproxy["sni"] = x.SNI;
|
||||
if (!scv.is_undef())
|
||||
singleproxy["skip-cert-verify"] = scv.get();
|
||||
if (!x.Fingerprint.empty())
|
||||
singleproxy["fingerprint"] = x.Fingerprint;
|
||||
if (!x.Alpn.empty())
|
||||
singleproxy["alpn"] = x.Alpn;
|
||||
if (!x.Ca.empty())
|
||||
singleproxy["ca"] = x.Ca;
|
||||
if (!x.CaStr.empty())
|
||||
singleproxy["ca-str"] = x.CaStr;
|
||||
if (x.RecvWindowConn)
|
||||
singleproxy["recv-window-conn"] = x.RecvWindowConn;
|
||||
if (x.RecvWindow)
|
||||
singleproxy["recv-window"] = x.RecvWindow;
|
||||
if (!x.DisableMtuDiscovery.is_undef())
|
||||
singleproxy["disable-mtu-discovery"] = x.DisableMtuDiscovery.get();
|
||||
if (!x.TCPFastOpen.is_undef())
|
||||
singleproxy["fast-open"] = x.TCPFastOpen.get();
|
||||
if (x.HopInterval)
|
||||
singleproxy["hop-interval"] = x.HopInterval;
|
||||
break;
|
||||
case ProxyType::Hysteria2:
|
||||
singleproxy["type"] = "hysteria2";
|
||||
if (!x.Up.empty())
|
||||
singleproxy["up"] = x.UpSpeed;
|
||||
if (!x.Down.empty())
|
||||
singleproxy["down"] = x.DownSpeed;
|
||||
if (!x.Password.empty())
|
||||
singleproxy["password"] = x.Password;
|
||||
if (!x.OBFS.empty())
|
||||
singleproxy["obfs"] = x.OBFS;
|
||||
if (!x.OBFSParam.empty())
|
||||
singleproxy["obfs-password"] = x.OBFSParam;
|
||||
if (!x.SNI.empty())
|
||||
singleproxy["sni"] = x.SNI;
|
||||
if (!scv.is_undef())
|
||||
singleproxy["skip-cert-verify"] = scv.get();
|
||||
if (!x.Alpn.empty())
|
||||
singleproxy["alpn"] = x.Alpn;
|
||||
if (!x.Ca.empty())
|
||||
singleproxy["ca"] = x.Ca;
|
||||
if (!x.CaStr.empty())
|
||||
singleproxy["ca-str"] = x.CaStr;
|
||||
if (x.CWND)
|
||||
singleproxy["cwnd"] = x.CWND;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -860,6 +935,20 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
ini.set(real_section, "keepalive", std::to_string(x.KeepAlive));
|
||||
ini.set(real_section, "peer", "(" + generatePeer(x) + ")");
|
||||
break;
|
||||
case ProxyType::Hysteria2:
|
||||
if(surge_ver < 4)
|
||||
continue;
|
||||
proxy = "hysteria, " + hostname + ", " + port + ", password=" + password;
|
||||
if(x.DownSpeed)
|
||||
proxy += ", download-bandwidth=" + x.DownSpeed;
|
||||
|
||||
if(!scv.is_undef())
|
||||
proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false");
|
||||
if(!x.Fingerprint.empty())
|
||||
proxy += ",server-cert-fingerprint-sha256=" + x.Fingerprint;
|
||||
if(!x.SNI.empty())
|
||||
proxy += ",sni=" + x.SNI;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -2168,7 +2257,6 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
|
||||
udp.define(x.UDP);
|
||||
tfo.define(x.TCPFastOpen);
|
||||
scv.define(x.AllowInsecure);
|
||||
|
||||
rapidjson::Value proxy(rapidjson::kObjectType);
|
||||
switch (x.Type)
|
||||
{
|
||||
@@ -2255,6 +2343,92 @@ void proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json, std::v
|
||||
proxy.AddMember("mtu", x.Mtu, allocator);
|
||||
break;
|
||||
}
|
||||
case ProxyType::Hysteria:
|
||||
{
|
||||
addSingBoxCommonMembers(proxy, x, "hysteria", allocator);
|
||||
if (!x.Up.empty())
|
||||
proxy.AddMember("up_mbps", x.UpSpeed, allocator);
|
||||
if (!x.Down.empty())
|
||||
proxy.AddMember("down_mbps", x.DownSpeed, allocator);
|
||||
if (!x.OBFS.empty())
|
||||
{
|
||||
proxy.AddMember("obfs", rapidjson::StringRef(x.OBFS.c_str()), allocator);
|
||||
}
|
||||
|
||||
if (!x.AuthStr.empty())
|
||||
{
|
||||
proxy.AddMember("auth_str", rapidjson::StringRef(x.AuthStr.c_str()), allocator);
|
||||
rapidjson::Value auth_str;
|
||||
auth_str.SetString(base64Encode(x.AuthStr).c_str(), allocator);
|
||||
proxy.AddMember("auth", auth_str, allocator);
|
||||
}
|
||||
if (x.RecvWindowConn)
|
||||
proxy.AddMember("recv_window_conn", x.RecvWindowConn, allocator);
|
||||
if (x.RecvWindow)
|
||||
proxy.AddMember("recv_window", x.RecvWindow, allocator);
|
||||
if (!x.DisableMtuDiscovery.is_undef())
|
||||
proxy.AddMember("disable_mtu_discovery", x.DisableMtuDiscovery.get(), allocator);
|
||||
|
||||
rapidjson::Value tls(rapidjson::kObjectType);
|
||||
tls.AddMember("enabled", true, allocator);
|
||||
if (!scv.is_undef())
|
||||
tls.AddMember("insecure", scv.get(), allocator);
|
||||
if (!x.Alpn.empty())
|
||||
{
|
||||
rapidjson::Value alpn(rapidjson::kArrayType);
|
||||
alpn.PushBack(rapidjson::StringRef(x.Alpn[0].c_str()), allocator);
|
||||
tls.AddMember("alpn", alpn, allocator);
|
||||
}
|
||||
if (!x.Ca.empty())
|
||||
{
|
||||
rapidjson::Value ca_str;
|
||||
ca_str.SetString(x.Ca.c_str(), allocator);
|
||||
tls.AddMember("certificate", ca_str, allocator);
|
||||
}
|
||||
if (!x.CaStr.empty())
|
||||
tls.AddMember("certificate", rapidjson::StringRef(x.CaStr.c_str()), allocator);
|
||||
proxy.AddMember("tls", tls, allocator);
|
||||
break;
|
||||
}
|
||||
case ProxyType::Hysteria2:
|
||||
{
|
||||
addSingBoxCommonMembers(proxy, x, "hysteria2", allocator);
|
||||
if (!x.Up.empty())
|
||||
proxy.AddMember("up_mbps", x.UpSpeed, allocator);
|
||||
if (!x.Down.empty())
|
||||
proxy.AddMember("down_mbps", x.DownSpeed, allocator);
|
||||
if (!x.OBFS.empty())
|
||||
{
|
||||
rapidjson::Value obfs(rapidjson::kObjectType);
|
||||
obfs.AddMember("type", rapidjson::StringRef(x.OBFS.c_str()), allocator);
|
||||
if (!x.OBFSParam.empty())
|
||||
obfs.AddMember("password", rapidjson::StringRef(x.OBFSParam.c_str()), allocator);
|
||||
proxy.AddMember("obfs", obfs, allocator);
|
||||
}
|
||||
if (!x.Password.empty())
|
||||
proxy.AddMember("password", rapidjson::StringRef(x.Password.c_str()), allocator);
|
||||
|
||||
rapidjson::Value tls(rapidjson::kObjectType);
|
||||
tls.AddMember("enabled", true, allocator);
|
||||
if (!scv.is_undef())
|
||||
tls.AddMember("insecure", scv.get(), allocator);
|
||||
if (!x.Alpn.empty())
|
||||
{
|
||||
rapidjson::Value alpn(rapidjson::kArrayType);
|
||||
alpn.PushBack(rapidjson::StringRef(x.Alpn[0].c_str()), allocator);
|
||||
tls.AddMember("alpn", alpn, allocator);
|
||||
}
|
||||
if (!x.Ca.empty())
|
||||
{
|
||||
rapidjson::Value ca_str(rapidjson::kStringType);
|
||||
ca_str.SetString(x.Ca.c_str(), allocator);
|
||||
tls.AddMember("certificate", ca_str, allocator);
|
||||
}
|
||||
if (!x.CaStr.empty())
|
||||
tls.AddMember("certificate", rapidjson::StringRef(x.CaStr.c_str()), allocator);
|
||||
proxy.AddMember("tls", tls, allocator);
|
||||
break;
|
||||
}
|
||||
case ProxyType::HTTP:
|
||||
case ProxyType::HTTPS:
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user