mirror of
https://github.com/asdlokj1qpi233/subconverter.git
synced 2025-10-28 20:32:42 +00:00
Compare commits
25 Commits
v0.9.8
...
36229fc2ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36229fc2ad | ||
|
|
aa721c5b06 | ||
|
|
60d20e42c8 | ||
|
|
645361a07e | ||
|
|
9947eebbfc | ||
|
|
11bc5c7236 | ||
|
|
4b4d227603 | ||
|
|
383deb54a7 | ||
|
|
766434b771 | ||
|
|
cc9e3b77d4 | ||
|
|
4ae0d1b0bd | ||
|
|
a428c844a2 | ||
|
|
3a0784f1f6 | ||
|
|
4787d821bd | ||
|
|
97192f9e5d | ||
|
|
b0b04a0130 | ||
|
|
4e73f5695e | ||
|
|
dd59d514bd | ||
|
|
57ed33f96c | ||
|
|
eab18a9568 | ||
|
|
c242e631ba | ||
|
|
b649fdc253 | ||
|
|
5759f52ebc | ||
|
|
e4b3ee816d | ||
|
|
ebf6a08449 |
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -7,6 +7,7 @@ body:
|
||||
value: |
|
||||
遇到问题请先尝试使用[Action](https://github.com/tindy2013/subconverter/actions)中的最新版本
|
||||
如果是使用公共转换服务中遇到的问题,请先联系服务的提供者。
|
||||
Please note that if the bug report does not include reproduction steps, configuration files, or relevant URL content, it will not be considered.
|
||||
- type: checkboxes
|
||||
id: version-check
|
||||
attributes:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
PROJECT(subconverter LANGUAGES CXX)
|
||||
SET(BUILD_TARGET_NAME ${PROJECT_NAME})
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/")
|
||||
|
||||
|
||||
@@ -8,8 +8,10 @@ WORKDIR /
|
||||
RUN set -xe && \
|
||||
apk add --no-cache --virtual .build-tools git g++ build-base linux-headers cmake python3 && \
|
||||
apk add --no-cache --virtual .build-deps curl-dev rapidjson-dev pcre2-dev yaml-cpp-dev && \
|
||||
git clone https://github.com/ftk/quickjspp --depth=1 && \
|
||||
git clone --no-checkout https://github.com/ftk/quickjspp.git && \
|
||||
cd quickjspp && \
|
||||
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09 && \
|
||||
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09 && \
|
||||
git submodule update --init && \
|
||||
cmake -DCMAKE_BUILD_TYPE=Release . && \
|
||||
make quickjs -j $THREADS && \
|
||||
|
||||
@@ -16,8 +16,10 @@ cmake -DCMAKE_BUILD_TYPE=Release -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOO
|
||||
make install -j3 > /dev/null
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ftk/quickjspp --depth=1
|
||||
git clone --no-checkout https://github.com/ftk/quickjspp.git
|
||||
cd quickjspp
|
||||
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
cmake -DCMAKE_BUILD_TYPE=Release .
|
||||
make quickjs -j3 > /dev/null
|
||||
install -d /usr/lib/quickjs/
|
||||
|
||||
@@ -18,8 +18,10 @@ make -j6 > /dev/null
|
||||
sudo make install > /dev/null
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ftk/quickjspp --depth=1
|
||||
git clone --no-checkout https://github.com/ftk/quickjspp.git
|
||||
cd quickjspp
|
||||
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
cmake -DCMAKE_BUILD_TYPE=Release .
|
||||
make quickjs -j6 > /dev/null
|
||||
sudo install -d /usr/local/lib/quickjs/
|
||||
|
||||
@@ -13,8 +13,10 @@ cmake -DCMAKE_BUILD_TYPE=Release -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOO
|
||||
make install -j4
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ftk/quickjspp --depth=1
|
||||
git clone --no-checkout https://github.com/ftk/quickjspp.git
|
||||
cd quickjspp
|
||||
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
patch quickjs/quickjs-libc.c -i ../scripts/patches/0001-quickjs-libc-add-realpath-for-Windows.patch
|
||||
cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
|
||||
@@ -16,8 +16,10 @@ cd rapidjson
|
||||
cp -r include/* $PREFIX/include/
|
||||
cd ..
|
||||
|
||||
git clone https://github.com/ftk/quickjspp --depth=1
|
||||
git clone --no-checkout https://github.com/ftk/quickjspp.git
|
||||
cd quickjspp
|
||||
git fetch origin 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
git checkout 0c00c48895919fc02da3f191a2da06addeb07f09
|
||||
cmake -DCMAKE_BUILD_TYPE=Release .
|
||||
make quickjs -j3
|
||||
install -d $PREFIX/lib/quickjs/
|
||||
|
||||
@@ -37,6 +37,15 @@ const string_array clash_ssr_ciphers = {
|
||||
"rc4-md5", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb",
|
||||
"aes-192-cfb", "aes-256-cfb", "chacha20-ietf", "xchacha20", "none"
|
||||
};
|
||||
bool isNumeric(const std::string &str) {
|
||||
for (char c: str) {
|
||||
if (!std::isdigit(static_cast<unsigned char>(c))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
vmessLinkConstruct(const std::string &remarks, const std::string &add, const std::string &port, const std::string &type,
|
||||
@@ -551,6 +560,47 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
singleproxy["congestion-controller"] = x.CongestionControl;
|
||||
}
|
||||
break;
|
||||
case ProxyType::AnyTLS:
|
||||
singleproxy["type"] = "anytls";
|
||||
if (!x.Password.empty()) {
|
||||
singleproxy["password"] = x.Password;
|
||||
}
|
||||
if (!x.Fingerprint.empty()) {
|
||||
singleproxy["client-fingerprint"] = x.Fingerprint;
|
||||
}
|
||||
if (!udp.is_undef()) {
|
||||
singleproxy["udp"] = udp.get();
|
||||
}
|
||||
if (!x.ServerName.empty()) {
|
||||
singleproxy["sni"] = x.SNI;
|
||||
}
|
||||
if (!scv.is_undef())
|
||||
singleproxy["skip-cert-verify"] = scv.get();
|
||||
if (!x.AlpnList.empty()) {
|
||||
for (auto &item: x.AlpnList) {
|
||||
singleproxy["alpn"].push_back(item);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ProxyType::Mieru:
|
||||
singleproxy["type"] = "mieru";
|
||||
if (!x.Password.empty()) {
|
||||
singleproxy["password"] = x.Password;
|
||||
}
|
||||
if (!x.Username.empty()) {
|
||||
singleproxy["username"] = x.Username;
|
||||
}
|
||||
if (!x.Multiplexing.empty()) {
|
||||
singleproxy["multiplexing"] = x.Multiplexing;
|
||||
}
|
||||
if (!x.TransferProtocol.empty()) {
|
||||
singleproxy["transport"] = x.TransferProtocol;
|
||||
}
|
||||
if (!x.Ports.empty()) {
|
||||
singleproxy["port-range"] = x.Ports;
|
||||
singleproxy.remove("port");
|
||||
}
|
||||
break;
|
||||
case ProxyType::VLESS:
|
||||
singleproxy["type"] = "vless";
|
||||
singleproxy["uuid"] = x.UserId;
|
||||
@@ -597,6 +647,9 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
singleproxy["ws-opts"]["headers"]["Host"] = x.Host;
|
||||
if (!x.Edge.empty())
|
||||
singleproxy["ws-opts"]["headers"]["Edge"] = x.Edge;
|
||||
if (!x.V2rayHttpUpgrade.is_undef()) {
|
||||
singleproxy["ws-opts"]["v2ray-http-upgrade"] = x.V2rayHttpUpgrade.get();
|
||||
}
|
||||
} else {
|
||||
singleproxy["ws-path"] = x.Path;
|
||||
if (!x.Host.empty())
|
||||
@@ -637,7 +690,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
// sees in https://dreamacro.github.io/clash/configuration/outbound.html#snell
|
||||
if (udp && x.Type != ProxyType::Snell && x.Type != ProxyType::TUIC)
|
||||
singleproxy["udp"] = true;
|
||||
if(proxy_block)
|
||||
if (proxy_block)
|
||||
singleproxy.SetStyle(YAML::EmitterStyle::Block);
|
||||
else
|
||||
singleproxy.SetStyle(YAML::EmitterStyle::Flow);
|
||||
@@ -646,7 +699,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
nodelist.emplace_back(x);
|
||||
}
|
||||
|
||||
if(proxy_compact)
|
||||
if (proxy_compact)
|
||||
proxies.SetStyle(YAML::EmitterStyle::Flow);
|
||||
|
||||
if (ext.nodelist) {
|
||||
@@ -662,8 +715,7 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
yamlnode["Proxy"] = proxies;
|
||||
|
||||
|
||||
for(const ProxyGroupConfig &x : extra_proxy_group)
|
||||
{
|
||||
for (const ProxyGroupConfig &x: extra_proxy_group) {
|
||||
YAML::Node singlegroup;
|
||||
string_array filtered_nodelist;
|
||||
|
||||
@@ -673,67 +725,63 @@ proxyToClash(std::vector<Proxy> &nodes, YAML::Node &yamlnode, const ProxyGroupCo
|
||||
else
|
||||
singlegroup["type"] = x.TypeStr();
|
||||
|
||||
switch(x.Type)
|
||||
{
|
||||
case ProxyGroupType::Select:
|
||||
case ProxyGroupType::Relay:
|
||||
break;
|
||||
case ProxyGroupType::LoadBalance:
|
||||
singlegroup["strategy"] = x.StrategyStr();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Smart:
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::URLTest:
|
||||
if(!x.Lazy.is_undef())
|
||||
singlegroup["lazy"] = x.Lazy.get();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Fallback:
|
||||
singlegroup["url"] = x.Url;
|
||||
if(x.Interval > 0)
|
||||
singlegroup["interval"] = x.Interval;
|
||||
if(x.Tolerance > 0)
|
||||
singlegroup["tolerance"] = x.Tolerance;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
switch (x.Type) {
|
||||
case ProxyGroupType::Select:
|
||||
case ProxyGroupType::Relay:
|
||||
break;
|
||||
case ProxyGroupType::LoadBalance:
|
||||
singlegroup["strategy"] = x.StrategyStr();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Smart:
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::URLTest:
|
||||
if (!x.Lazy.is_undef())
|
||||
singlegroup["lazy"] = x.Lazy.get();
|
||||
[[fallthrough]];
|
||||
case ProxyGroupType::Fallback:
|
||||
singlegroup["url"] = x.Url;
|
||||
if (x.Interval > 0)
|
||||
singlegroup["interval"] = x.Interval;
|
||||
if (x.Tolerance > 0)
|
||||
singlegroup["tolerance"] = x.Tolerance;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if(!x.DisableUdp.is_undef())
|
||||
if (!x.DisableUdp.is_undef())
|
||||
singlegroup["disable-udp"] = x.DisableUdp.get();
|
||||
|
||||
for(const auto& y : x.Proxies)
|
||||
for (const auto &y: x.Proxies)
|
||||
groupGenerate(y, nodelist, filtered_nodelist, true, ext);
|
||||
|
||||
if(!x.UsingProvider.empty())
|
||||
if (!x.UsingProvider.empty())
|
||||
singlegroup["use"] = x.UsingProvider;
|
||||
else
|
||||
{
|
||||
if(filtered_nodelist.empty())
|
||||
else {
|
||||
if (filtered_nodelist.empty())
|
||||
filtered_nodelist.emplace_back("DIRECT");
|
||||
}
|
||||
if(!filtered_nodelist.empty())
|
||||
if (!filtered_nodelist.empty())
|
||||
singlegroup["proxies"] = filtered_nodelist;
|
||||
if(group_block)
|
||||
if (group_block)
|
||||
singlegroup.SetStyle(YAML::EmitterStyle::Block);
|
||||
else
|
||||
singlegroup.SetStyle(YAML::EmitterStyle::Flow);
|
||||
|
||||
bool replace_flag = false;
|
||||
for(auto && original_group : original_groups)
|
||||
{
|
||||
if(original_group["name"].as<std::string>() == x.Name)
|
||||
{
|
||||
for (auto &&original_group: original_groups) {
|
||||
if (original_group["name"].as<std::string>() == x.Name) {
|
||||
original_group.reset(singlegroup);
|
||||
replace_flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!replace_flag)
|
||||
if (!replace_flag)
|
||||
original_groups.push_back(singlegroup);
|
||||
}
|
||||
if(group_compact)
|
||||
if (group_compact)
|
||||
original_groups.SetStyle(YAML::EmitterStyle::Flow);
|
||||
|
||||
if(ext.clash_new_field_name)
|
||||
if (ext.clash_new_field_name)
|
||||
yamlnode["proxy-groups"] = original_groups;
|
||||
else
|
||||
yamlnode["Proxy Group"] = original_groups;
|
||||
@@ -894,6 +942,7 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
|
||||
std::string proxy, section, real_section;
|
||||
string_array args, headers;
|
||||
std::string search = " Mbps";
|
||||
|
||||
switch (x.Type) {
|
||||
case ProxyType::Shadowsocks:
|
||||
@@ -1022,16 +1071,25 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
case ProxyType::Hysteria2:
|
||||
if (surge_ver < 4)
|
||||
continue;
|
||||
proxy = "hysteria, " + hostname + ", " + port + ", password=" + password;
|
||||
if (x.DownSpeed)
|
||||
proxy += ", download-bandwidth=" + x.DownSpeed;
|
||||
proxy = "hysteria2, " + hostname + ", " + port + ", password=" + password;
|
||||
if (!x.DownMbps.empty()) {
|
||||
if (!isNumeric(x.DownMbps)) {
|
||||
size_t pos = x.DownMbps.find(search);
|
||||
if (pos != std::string::npos) {
|
||||
x.DownMbps.replace(pos, search.length(), "");
|
||||
}
|
||||
}
|
||||
proxy += ", download-bandwidth=" +x.DownMbps;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!x.ServerName.empty())
|
||||
proxy += ",sni=" + x.ServerName;
|
||||
if (!x.Ports.empty())
|
||||
proxy += ",port-hopping=" + x.Ports;
|
||||
break;
|
||||
case ProxyType::WireGuard:
|
||||
if (surge_ver < 4 && surge_ver != -3)
|
||||
@@ -1145,22 +1203,24 @@ std::string proxyToSurge(std::vector<Proxy> &nodes, const std::string &base_conf
|
||||
}
|
||||
|
||||
std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &ext) {
|
||||
/// types: SS=1 SSR=2 VMess=4 Trojan=8
|
||||
/// types: SS=1 SSR=2 VMess=4 Trojan=8,hysteria2=16,vless=32
|
||||
std::string proxyStr, allLinks;
|
||||
bool ss = GETBIT(types, 1), ssr = GETBIT(types, 2), vmess = GETBIT(types, 3), trojan = GETBIT(types, 4);
|
||||
bool ss = GETBIT(types, 1), ssr = GETBIT(types, 2), vmess = GETBIT(types, 3), trojan = GETBIT(types, 4), hysteria2 =
|
||||
GETBIT(types, 5), vless = GETBIT(types, 6);
|
||||
|
||||
for (Proxy &x: nodes) {
|
||||
std::string remark = x.Remark;
|
||||
std::string &hostname = x.Hostname, &sni = x.ServerName, &password = x.Password, &method = x.EncryptMethod, &
|
||||
plugin = x.Plugin, &pluginopts = x.PluginOption, &protocol = x.Protocol, &protoparam = x.
|
||||
ProtocolParam,
|
||||
&obfs = x.OBFS, &obfsparam = x.OBFSParam, &id = x.UserId, &transproto = x.TransferProtocol, &host = x.
|
||||
Host, &
|
||||
path = x.Path, &faketype = x.FakeType;
|
||||
ProtocolParam, &flow = x.Flow, &pbk = x.PublicKey, &sid = x.ShortId, &fp = x.Fingerprint,
|
||||
&packet_encoding = x.PacketEncoding, &fake_type = x.FakeType, &mode = x.GRPCMode,
|
||||
&obfs = x.OBFS, &obfsparam = x.OBFSParam, &obfsPassword = x.OBFSPassword, &id = x.UserId, &transproto =
|
||||
x.TransferProtocol, &host = x.
|
||||
Host, &tls = x.TLSStr, &path = x.Path, &faketype = x.FakeType, &ports = x.Ports;
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
std::vector<string> alpns = x.AlpnList;
|
||||
std::string port = std::to_string(x.Port);
|
||||
std::string aid = std::to_string(x.AlterId);
|
||||
|
||||
switch (x.Type) {
|
||||
case ProxyType::Shadowsocks:
|
||||
if (ss) {
|
||||
@@ -1206,6 +1266,93 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
||||
vmessLinkConstruct(remark, hostname, port, faketype, id, aid, transproto, path, host,
|
||||
tlssecure ? "tls" : ""));
|
||||
break;
|
||||
case ProxyType::Hysteria2:
|
||||
if (!hysteria2)
|
||||
continue;
|
||||
proxyStr = "hysteria2://" + password + "@" + hostname + ":" + port + (ports.empty() ? "" : "," + ports)
|
||||
+ "?insecure=" +
|
||||
(x.AllowInsecure.get() ? "1" : "0");
|
||||
if (!obfsparam.empty()) {
|
||||
proxyStr += "&obfs=" + obfsparam;
|
||||
if (!obfsPassword.empty()) {
|
||||
proxyStr += "&obfs-password=" + obfsparam;
|
||||
}
|
||||
}
|
||||
if (!sni.empty()) {
|
||||
proxyStr += "&sni=" + sni;
|
||||
}
|
||||
proxyStr += "#" + urlEncode(remark);
|
||||
break;
|
||||
case ProxyType::VLESS:
|
||||
if (!vless)
|
||||
continue;
|
||||
// tls = getUrlArg(addition, "security");
|
||||
// net = getUrlArg(addition, "type");
|
||||
// flow = getUrlArg(addition, "flow");
|
||||
// pbk = getUrlArg(addition, "pbk");
|
||||
// sid = getUrlArg(addition, "sid");
|
||||
// fp = getUrlArg(addition, "fp");
|
||||
// std::string packet_encoding = getUrlArg(addition, "packet-encoding");
|
||||
// std::string alpn = getUrlArg(addition, "alpn");
|
||||
proxyStr = "vless://" + (id.empty()
|
||||
? "00000000-0000-0000-0000-000000000000"
|
||||
: id) + "@" + hostname + ":" + port+"?";
|
||||
if (!tls.empty()) {
|
||||
if (!pbk.empty()) {
|
||||
proxyStr += "&security=reality";
|
||||
}else {
|
||||
proxyStr += "&security=" + tls;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flow.empty()) {
|
||||
proxyStr += "&flow=" + flow;
|
||||
}
|
||||
if (!pbk.empty()) {
|
||||
proxyStr += "&pbk=" + pbk;
|
||||
}
|
||||
if (!sid.empty()) {
|
||||
proxyStr += "&sid=" + sid;
|
||||
}
|
||||
if (!fp.empty()) {
|
||||
proxyStr += "&fp=" + fp;
|
||||
}
|
||||
if (!packet_encoding.empty()) {
|
||||
proxyStr += "&packet-encoding=" + packet_encoding;
|
||||
}
|
||||
if (!alpns.empty()) {
|
||||
proxyStr += "&alpn=" + alpns[0];
|
||||
}
|
||||
if (!sni.empty()) {
|
||||
proxyStr += "&sni=" + sni;
|
||||
}
|
||||
if (!transproto.empty()) {
|
||||
proxyStr += "&type=" + transproto;
|
||||
switch (hash_(transproto)) {
|
||||
case "tcp"_hash:
|
||||
case "ws"_hash:
|
||||
case "h2"_hash:
|
||||
proxyStr += "&headerType=" + fake_type;
|
||||
if (!host.empty()) {
|
||||
proxyStr += "&host=" + host;
|
||||
}
|
||||
proxyStr += "&path=" + urlEncode(path.empty() ? "/" : path);
|
||||
break;
|
||||
case "grpc"_hash:
|
||||
proxyStr += "&serviceName=" + path;
|
||||
proxyStr += "&mode=" + mode;
|
||||
break;
|
||||
case "quic"_hash:
|
||||
proxyStr += "&headerType=" + fake_type;
|
||||
proxyStr += "&quicSecurity=" + (host.empty() ? sni : host);
|
||||
proxyStr += "&key=" + path;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
proxyStr += "#" + urlEncode(remark);
|
||||
break;
|
||||
case ProxyType::Trojan:
|
||||
if (!trojan)
|
||||
continue;
|
||||
@@ -1231,8 +1378,7 @@ std::string proxyToSingle(std::vector<Proxy> &nodes, int types, extra_settings &
|
||||
|
||||
if (ext.nodelist)
|
||||
return allLinks;
|
||||
else
|
||||
return base64Encode(allLinks);
|
||||
return base64Encode(allLinks);
|
||||
}
|
||||
|
||||
std::string proxyToSSSub(std::string base_conf, std::vector<Proxy> &nodes, extra_settings &ext) {
|
||||
@@ -2071,13 +2217,13 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
std::string &hostname = x.Hostname, &username = x.Username, &password = x.Password, &method = x.EncryptMethod, &
|
||||
plugin = x.Plugin, &pluginopts = x.PluginOption, &id = x.UserId, &transproto = x.TransferProtocol, &host
|
||||
= x.Host, &path = x.Path, &protocol = x.Protocol, &protoparam = x.ProtocolParam, &obfs = x.OBFS, &
|
||||
obfsparam = x.OBFSParam;
|
||||
obfsparam = x.OBFSParam, flow = x.Flow, pk = x.PublicKey, shortId = x.ShortId, sni = x.ServerName;
|
||||
std::string port = std::to_string(x.Port), aid = std::to_string(x.AlterId);
|
||||
bool &tlssecure = x.TLSSecure;
|
||||
|
||||
tribool scv = ext.skip_cert_verify;
|
||||
scv.define(x.AllowInsecure);
|
||||
|
||||
tribool udp = x.UDP.is_undef() ? ext.udp.is_undef() ? false : ext.udp.get() : x.UDP.get();
|
||||
std::string proxy;
|
||||
|
||||
switch (x.Type) {
|
||||
@@ -2112,6 +2258,24 @@ proxyToLoon(std::vector<Proxy> &nodes, const std::string &base_conf,
|
||||
if (!scv.is_undef())
|
||||
proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false");
|
||||
break;
|
||||
case ProxyType::VLESS:
|
||||
if (flow != "xtls-rprx-vision") {
|
||||
continue;
|
||||
}
|
||||
proxy = "VLESS," + hostname + "," + port + ",\"" + id + "\",flow=" + flow + ",public-key=\"" + pk +
|
||||
"\",short-id=" + shortId + ",udp=" + (udp.get() ? "true" : "false") + ",over-tls=" + (
|
||||
tlssecure ? "true" : "false") + ",sni=" + sni;
|
||||
|
||||
switch (hash_(transproto)) {
|
||||
case "tcp"_hash:
|
||||
proxy += ",transport=tcp";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if (!scv.is_undef())
|
||||
proxy += ",skip-cert-verify=" + std::string(scv.get() ? "true" : "false");
|
||||
break;
|
||||
case ProxyType::ShadowsocksR:
|
||||
proxy = "ShadowsocksR," + hostname + "," + port + "," + method + ",\"" + password + "\",protocol=" +
|
||||
protocol + ",protocol-param=" + protoparam + ",obfs=" + obfs + ",obfs-param=" + obfsparam;
|
||||
@@ -2380,15 +2544,6 @@ vectorToJsonArray(const std::vector<std::string> &array, rapidjson::MemoryPoolAl
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isNumeric(const std::string &str) {
|
||||
for (char c: str) {
|
||||
if (!std::isdigit(static_cast<unsigned char>(c))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json,
|
||||
std::vector<RulesetContent> &ruleset_content_array,
|
||||
@@ -2692,6 +2847,29 @@ proxyToSingBox(std::vector<Proxy> &nodes, rapidjson::Document &json,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ProxyType::AnyTLS: {
|
||||
addSingBoxCommonMembers(proxy, x, "anytls", allocator);
|
||||
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", buildBooleanValue(scv), allocator);
|
||||
}
|
||||
if (!x.SNI.empty())
|
||||
tls.AddMember("server_name", rapidjson::StringRef(x.SNI.c_str()), allocator);
|
||||
if (!x.AlpnList.empty()) {
|
||||
auto alpns = vectorToJsonArray(x.AlpnList, allocator);
|
||||
tls.AddMember("alpn", alpns, allocator);
|
||||
}
|
||||
if (!x.Fingerprint.empty()) {
|
||||
rapidjson::Value utls(rapidjson::kObjectType);
|
||||
utls.AddMember("enabled", true, allocator);
|
||||
utls.AddMember("fingerprint", rapidjson::StringRef(x.Fingerprint.c_str()), allocator);
|
||||
tls.AddMember("utls", utls, allocator);
|
||||
}
|
||||
proxy.AddMember("tls", tls, allocator);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,9 @@ enum class ProxyType
|
||||
VLESS,
|
||||
Hysteria,
|
||||
Hysteria2,
|
||||
TUIC
|
||||
TUIC,
|
||||
AnyTLS,
|
||||
Mieru
|
||||
};
|
||||
|
||||
inline String getProxyTypeName(ProxyType type) {
|
||||
@@ -55,6 +57,8 @@ inline String getProxyTypeName(ProxyType type) {
|
||||
return "Hysteria2";
|
||||
case ProxyType::TUIC:
|
||||
return "Tuic";
|
||||
case ProxyType::AnyTLS:
|
||||
return "AnyTLS";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -83,7 +87,10 @@ struct Proxy {
|
||||
String TransferProtocol;
|
||||
String FakeType;
|
||||
String AuthStr;
|
||||
|
||||
uint16_t IdleSessionCheckInterval=30;
|
||||
uint16_t IdleSessionTimeout=30;
|
||||
uint16_t MinIdleSession=0;
|
||||
String TLSStr;
|
||||
bool TLSSecure = false;
|
||||
|
||||
String Host;
|
||||
@@ -137,6 +144,8 @@ struct Proxy {
|
||||
String UnderlyingProxy;
|
||||
std::vector<String> AlpnList;
|
||||
String PacketEncoding;
|
||||
String Multiplexing;
|
||||
tribool V2rayHttpUpgrade;
|
||||
};
|
||||
|
||||
#define SS_DEFAULT_GROUP "SSProvider"
|
||||
@@ -151,5 +160,6 @@ struct Proxy {
|
||||
#define HYSTERIA_DEFAULT_GROUP "HysteriaProvider"
|
||||
#define HYSTERIA2_DEFAULT_GROUP "Hysteria2Provider"
|
||||
#define TUIC_DEFAULT_GROUP "TuicProvider"
|
||||
|
||||
#define ANYTLS_DEFAULT_GROUP "AnyTLSProvider"
|
||||
#define MIERU_DEFAULT_GROUP "MieruProvider"
|
||||
#endif // PROXY_H_INCLUDED
|
||||
|
||||
@@ -18,29 +18,44 @@ using namespace rapidjson;
|
||||
using namespace rapidjson_ext;
|
||||
using namespace YAML;
|
||||
|
||||
string_array ss_ciphers = {"rc4-md5", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "aes-128-cfb", "aes-192-cfb",
|
||||
"aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "camellia-128-cfb",
|
||||
"camellia-192-cfb", "camellia-256-cfb", "bf-cfb", "chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305", "salsa20", "chacha20", "chacha20-ietf", "2022-blake3-aes-128-gcm",
|
||||
"2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "2022-blake3-chacha12-poly1305",
|
||||
"2022-blake3-chacha8-poly1305"};
|
||||
string_array ssr_ciphers = {"none", "table", "rc4", "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
||||
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
||||
"camellia-192-cfb", "camellia-256-cfb", "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb",
|
||||
"seed-cfb", "salsa20", "chacha20", "chacha20-ietf"};
|
||||
string_array ss_ciphers = {
|
||||
"rc4-md5", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "aes-128-cfb", "aes-192-cfb",
|
||||
"aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "camellia-128-cfb",
|
||||
"camellia-192-cfb", "camellia-256-cfb", "bf-cfb", "chacha20-ietf-poly1305",
|
||||
"xchacha20-ietf-poly1305", "salsa20", "chacha20", "chacha20-ietf", "2022-blake3-aes-128-gcm",
|
||||
"2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "2022-blake3-chacha12-poly1305",
|
||||
"2022-blake3-chacha8-poly1305"
|
||||
};
|
||||
string_array ssr_ciphers = {
|
||||
"none", "table", "rc4", "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
||||
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
||||
"camellia-192-cfb", "camellia-256-cfb", "cast5-cfb", "des-cfb", "idea-cfb", "rc2-cfb",
|
||||
"seed-cfb", "salsa20", "chacha20", "chacha20-ietf"
|
||||
};
|
||||
|
||||
std::map<std::string, std::string> parsedMD5;
|
||||
std::string modSSMD5 = "f7653207090ce3389115e9c88541afe0";
|
||||
|
||||
//remake from speedtestutil
|
||||
std::string removeBrackets(const std::string& input) {
|
||||
std::string result = input;
|
||||
size_t left = result.find('[');
|
||||
size_t right = result.find(']');
|
||||
|
||||
if (left != std::string::npos && right != std::string::npos && right > left) {
|
||||
result.erase(right, 1); // 删除 ']'
|
||||
result.erase(left, 1); // 删除 '['
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
void commonConstruct(Proxy &node, ProxyType type, const std::string &group, const std::string &remarks,
|
||||
const std::string &server, const std::string &port, const tribool &udp, const tribool &tfo,
|
||||
const tribool &scv, const tribool &tls13,const std::string& underlying_proxy) {
|
||||
const tribool &scv, const tribool &tls13, const std::string &underlying_proxy) {
|
||||
node.Type = type;
|
||||
node.Group = group;
|
||||
node.Remark = remarks;
|
||||
node.Hostname = server;
|
||||
node.Hostname = removeBrackets(server);
|
||||
node.Port = to_int(port);
|
||||
node.UDP = udp;
|
||||
node.TCPFastOpen = tfo;
|
||||
@@ -54,8 +69,8 @@ void vmessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
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::vector<std::string> &alpnList, tribool udp, tribool tfo,
|
||||
tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::VMess, group, remarks, add, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
tribool scv, tribool tls13, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::VMess, group, remarks, add, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
|
||||
node.AlterId = to_int(aid);
|
||||
node.EncryptMethod = cipher;
|
||||
@@ -77,8 +92,10 @@ void vmessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
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 tfo, tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::ShadowsocksR, group, remarks, server, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
const std::string &protoparam, tribool udp, tribool tfo, tribool scv,
|
||||
const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::ShadowsocksR, group, remarks, server, port, udp, tfo, scv, tribool(),
|
||||
underlying_proxy);
|
||||
node.Password = password;
|
||||
node.EncryptMethod = method;
|
||||
node.Protocol = protocol;
|
||||
@@ -90,8 +107,8 @@ void ssrConstruct(Proxy &node, const std::string &group, const std::string &rema
|
||||
void ssConstruct(Proxy &node, 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, tribool udp, tribool tfo, tribool scv,
|
||||
tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Shadowsocks, group, remarks, server, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
tribool tls13, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Shadowsocks, group, remarks, server, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.Password = password;
|
||||
node.EncryptMethod = method;
|
||||
node.Plugin = plugin;
|
||||
@@ -100,17 +117,17 @@ void ssConstruct(Proxy &node, const std::string &group, const std::string &remar
|
||||
|
||||
void socksConstruct(Proxy &node, 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 tfo, tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::SOCKS5, group, remarks, server, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
tribool tfo, tribool scv, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::SOCKS5, group, remarks, server, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||
node.Username = username;
|
||||
node.Password = password;
|
||||
}
|
||||
|
||||
void httpConstruct(Proxy &node, 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,const std::string& underlying_proxy) {
|
||||
tribool tfo, tribool scv, tribool tls13, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, tls ? ProxyType::HTTPS : ProxyType::HTTP, group, remarks, server, port, tribool(), tfo, scv,
|
||||
tls13,underlying_proxy);
|
||||
tls13, underlying_proxy);
|
||||
node.Username = username;
|
||||
node.Password = password;
|
||||
node.TLSSecure = tls;
|
||||
@@ -122,8 +139,8 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
|
||||
const std::vector<std::string> &alpnList,
|
||||
bool tlssecure,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
tribool scv, tribool tls13, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Trojan, group, remarks, server, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.Password = password;
|
||||
node.Host = host;
|
||||
node.TLSSecure = tlssecure;
|
||||
@@ -136,8 +153,9 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
|
||||
|
||||
void snellConstruct(Proxy &node, 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, uint16_t version, tribool udp, tribool tfo, tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Snell, group, remarks, server, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
const std::string &host, uint16_t version, tribool udp, tribool tfo, tribool scv,
|
||||
const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Snell, group, remarks, server, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||
node.Password = password;
|
||||
node.OBFS = obfs;
|
||||
node.Host = host;
|
||||
@@ -148,8 +166,10 @@ void wireguardConstruct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &port, const std::string &selfIp, const std::string &selfIpv6,
|
||||
const std::string &privKey, const std::string &pubKey, const std::string &psk,
|
||||
const string_array &dns, const std::string &mtu, const std::string &keepalive,
|
||||
const std::string &testUrl, const std::string &clientId, const tribool &udp,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::WireGuard, group, remarks, server, port, udp, tribool(), tribool(), tribool(),underlying_proxy);
|
||||
const std::string &testUrl, const std::string &clientId, const tribool &udp,
|
||||
const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::WireGuard, group, remarks, server, port, udp, tribool(), tribool(), tribool(),
|
||||
underlying_proxy);
|
||||
node.SelfIP = selfIp;
|
||||
node.SelfIPv6 = selfIpv6;
|
||||
node.PrivateKey = privKey;
|
||||
@@ -169,8 +189,8 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &obfsParam, const std::string &insecure, const std::string &ports,
|
||||
const std::string &sni, tribool udp,
|
||||
tribool tfo, tribool scv,
|
||||
tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
tribool tls13, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Hysteria, group, remarks, add, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.Auth = auth;
|
||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||
node.UpMbps = up;
|
||||
@@ -184,16 +204,50 @@ void hysteriaConstruct(Proxy &node, const std::string &group, const std::string
|
||||
node.ServerName = sni;
|
||||
}
|
||||
|
||||
void anyTlSConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||
const std::string &port, const std::string &password,
|
||||
const std::string &host, const std::vector<String> &AlpnList,
|
||||
const std::string &fingerprint,
|
||||
const std::string &sni, tribool udp,
|
||||
tribool tfo, tribool scv,
|
||||
tribool tls13, const std::string &underlying_proxy, uint16_t idleSessionCheckInterval,
|
||||
uint16_t idleSessionTimeout, uint16_t minIdleSession) {
|
||||
commonConstruct(node, ProxyType::AnyTLS, group, remarks, host, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.Host = trim(host);
|
||||
node.Password = password;
|
||||
node.AlpnList = AlpnList;
|
||||
node.SNI = sni;
|
||||
node.Fingerprint = fingerprint;
|
||||
node.IdleSessionCheckInterval = idleSessionCheckInterval;
|
||||
node.IdleSessionTimeout = idleSessionTimeout;
|
||||
node.MinIdleSession = minIdleSession;
|
||||
}
|
||||
|
||||
void mieruConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||
const std::string &port, const std::string &password,
|
||||
const std::string &host, const std::string &ports,
|
||||
const std::string &username, const std::string &multiplexing,
|
||||
const std::string &transfer_protocol, tribool udp,
|
||||
tribool tfo, tribool scv,
|
||||
tribool tls13, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Mieru, group, remarks, host, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.Host = trim(host);
|
||||
node.Password = password;
|
||||
node.Ports = ports;
|
||||
node.TransferProtocol = transfer_protocol.empty() ? "TCP" : trim(transfer_protocol);
|
||||
node.Username = username;
|
||||
node.Multiplexing = multiplexing.empty() ? "MULTIPLEXING_LOW" : trim(multiplexing);
|
||||
}
|
||||
|
||||
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, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList,const std::string &packet_encoding,
|
||||
const std::vector<std::string> &alpnList, const std::string &packet_encoding,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv, tribool tls13,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13,underlying_proxy);
|
||||
tribool scv, tribool tls13, const std::string &underlying_proxy, tribool v2ray_http_upgrade) {
|
||||
commonConstruct(node, ProxyType::VLESS, group, remarks, add, port, udp, tfo, scv, tls13, underlying_proxy);
|
||||
node.UserId = id.empty() ? "00000000-0000-0000-0000-000000000000" : id;
|
||||
node.AlterId = to_int(aid);
|
||||
node.EncryptMethod = cipher;
|
||||
@@ -208,6 +262,7 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
node.ServerName = sni;
|
||||
node.AlpnList = alpnList;
|
||||
node.PacketEncoding = packet_encoding;
|
||||
node.TLSStr = tls;
|
||||
switch (hash_(net)) {
|
||||
case "grpc"_hash:
|
||||
node.Host = host;
|
||||
@@ -215,12 +270,13 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
node.GRPCServiceName = path.empty() ? "/" : urlEncode(urlDecode(trim(path)));
|
||||
break;
|
||||
case "quic"_hash:
|
||||
node.QUICSecure = host;
|
||||
node.Host = host;
|
||||
node.QUICSecret = path.empty() ? "/" : trim(path);
|
||||
break;
|
||||
default:
|
||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||
node.Path = path.empty() ? "/" : urlDecode(trim(path));
|
||||
node.V2rayHttpUpgrade = v2ray_http_upgrade;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -232,8 +288,8 @@ void hysteria2Construct(Proxy &node, const std::string &group, const std::string
|
||||
const std::string &obfsParam, const std::string &obfsPassword, const std::string &sni,
|
||||
const std::string &publicKey, const std::string &ports,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
tribool scv, const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::Hysteria2, group, remarks, add, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||
node.Password = password;
|
||||
node.Host = (host.empty() && !isIPv4(add) && !isIPv6(add)) ? add.data() : trim(host);
|
||||
node.UpMbps = up;
|
||||
@@ -252,8 +308,9 @@ void tuicConstruct(Proxy &node, const std::string &group, const std::string &rem
|
||||
const std::string &sni, const std::string &uuid, const std::string &udpRelayMode,
|
||||
const std::string &token,
|
||||
tribool udp, tribool tfo,
|
||||
tribool scv, tribool reduceRtt, tribool disableSni, uint16_t request_timeout,const std::string& underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::TUIC, group, remarks, add, port, udp, tfo, scv, tribool(),underlying_proxy);
|
||||
tribool scv, tribool reduceRtt, tribool disableSni, uint16_t request_timeout,
|
||||
const std::string &underlying_proxy) {
|
||||
commonConstruct(node, ProxyType::TUIC, group, remarks, add, port, udp, tfo, scv, tribool(), underlying_proxy);
|
||||
node.Password = password;
|
||||
node.Alpn = alpn;
|
||||
node.ServerName = sni;
|
||||
@@ -326,7 +383,8 @@ void explodeVmess(std::string vmess, Proxy &node) {
|
||||
|
||||
add = trim(add);
|
||||
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, "auto", path, host, "", tls, sni,std::vector<std::string>{});
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, "auto", path, host, "", tls, sni,
|
||||
std::vector<std::string>{});
|
||||
}
|
||||
|
||||
void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
||||
@@ -397,13 +455,12 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
}
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, add + ":" + port, add, port, type, id, aid, net, cipher, path,
|
||||
host, edge, tls, "",std::vector<std::string>{}, udp, tfo, scv);
|
||||
host, edge, tls, "", std::vector<std::string>{}, udp, tfo, scv);
|
||||
nodes.emplace_back(std::move(node));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
} catch (std::exception &e) {
|
||||
//writeLog(0, "VMessConf parser throws an error. Leaving...", LOG_LEVEL_WARNING);
|
||||
//return;
|
||||
//ignore
|
||||
@@ -450,7 +507,7 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
||||
json["vmess"][i]["security"] >> cipher;
|
||||
json["vmess"][i]["sni"] >> sni;
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, ps, add, port, type, id, aid, net, cipher, path, host, "",
|
||||
tls, sni,std::vector<std::string>{}, udp, tfo, scv);
|
||||
tls, sni, std::vector<std::string>{}, udp, tfo, scv);
|
||||
break;
|
||||
case 3: //ss config
|
||||
json["vmess"][i]["id"] >> id;
|
||||
@@ -470,7 +527,8 @@ void explodeVmessConf(std::string content, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
|
||||
void explodeSS(std::string ss, Proxy &node) {
|
||||
std::string ps, password, method, server, port, plugins, plugin, pluginopts, addition, group = SS_DEFAULT_GROUP, secret;
|
||||
std::string ps, password, method, server, port, plugins, plugin, pluginopts, addition, group = SS_DEFAULT_GROUP,
|
||||
secret;
|
||||
//std::vector<std::string> args, secret;
|
||||
ss = replaceAllDistinct(ss.substr(5), "/?", "?");
|
||||
if (strFind(ss, "#")) {
|
||||
@@ -683,7 +741,8 @@ void explodeSSR(std::string ssr, Proxy &node) {
|
||||
|
||||
void explodeSSRConf(std::string content, std::vector<Proxy> &nodes) {
|
||||
Document json;
|
||||
std::string remarks, group, server, port, method, password, protocol, protoparam, obfs, obfsparam, plugin, pluginopts;
|
||||
std::string remarks, group, server, port, method, password, protocol, protoparam, obfs, obfsparam, plugin,
|
||||
pluginopts;
|
||||
auto index = nodes.size();
|
||||
|
||||
json.Parse(content.data());
|
||||
@@ -875,8 +934,8 @@ void explodeTrojan(std::string trojan, Proxy &node) {
|
||||
path = getUrlArg(addition, "wspath");
|
||||
network = "ws";
|
||||
}
|
||||
// support the trojan link format used by v2ryaN and X-ui.
|
||||
// format: trojan://{password}@{server}:{port}?type=ws&security=tls&path={path (urlencoded)}&sni={host}#{name}
|
||||
// support the trojan link format used by v2ryaN and X-ui.
|
||||
// format: trojan://{password}@{server}:{port}?type=ws&security=tls&path={path (urlencoded)}&sni={host}#{name}
|
||||
else if (getUrlArg(addition, "type") == "ws") {
|
||||
path = getUrlArg(addition, "path");
|
||||
if (path.substr(0, 3) == "%2F")
|
||||
@@ -904,6 +963,24 @@ void explodeVless(std::string vless, Proxy &node) {
|
||||
}
|
||||
}
|
||||
|
||||
void explodeMierus(std::string mierus, Proxy &node) {
|
||||
if (strFind(mierus, "mierus://")) {
|
||||
if (regMatch(mierus, "mierus://(.*?)@(.*)")) {
|
||||
explodeStdMieru(mierus.substr(9), node);
|
||||
} else {
|
||||
mierus = urlSafeBase64Decode(mierus.substr(9));
|
||||
explodeStdMieru("mierus://" + mierus, node);
|
||||
}
|
||||
} else if (strFind(mierus, "mieru://")) {
|
||||
if (regMatch(mierus, "mierus://(.*?)@(.*)")) {
|
||||
explodeStdMieru(mierus.substr(8), node);
|
||||
} else {
|
||||
mierus = urlSafeBase64Decode(mierus.substr(8));
|
||||
explodeStdMieru("mierus://" + mierus, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void explodeHysteria(std::string hysteria, Proxy &node) {
|
||||
printf("explodeHysteria\n");
|
||||
hysteria = regReplace(hysteria, "(hysteria|hy)://", "hysteria://");
|
||||
@@ -926,7 +1003,8 @@ void explodeHysteria2(std::string hysteria2, Proxy &node) {
|
||||
|
||||
void explodeQuan(const std::string &quan, Proxy &node) {
|
||||
std::string strTemp, itemName, itemVal;
|
||||
std::string group = V2RAY_DEFAULT_GROUP, ps, add, port, cipher, type = "none", id, aid = "0", net = "tcp", path, host, edge, tls;
|
||||
std::string group = V2RAY_DEFAULT_GROUP, ps, add, port, cipher, type = "none", id, aid = "0", net = "tcp", path,
|
||||
host, edge, tls;
|
||||
string_array configs, vArray, headers;
|
||||
strTemp = regReplace(quan, "(.*?) = (.*)", "$1,$2");
|
||||
configs = split(strTemp, ",");
|
||||
@@ -982,7 +1060,8 @@ void explodeQuan(const std::string &quan, Proxy &node) {
|
||||
if (path.empty())
|
||||
path = "/";
|
||||
|
||||
vmessConstruct(node, group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls, "",std::vector<std::string>{});
|
||||
vmessConstruct(node, group, ps, add, port, type, id, aid, net, cipher, path, host, edge, tls, "",
|
||||
std::vector<std::string>{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,7 +1131,7 @@ void explodeNetch(std::string netch, Proxy &node) {
|
||||
if (group.empty())
|
||||
group = V2RAY_DEFAULT_GROUP;
|
||||
vmessConstruct(node, group, remark, address, port, faketype, id, aid, transprot, method, path, host, edge,
|
||||
tls, sni,std::vector<std::string>{}, udp, tfo, scv);
|
||||
tls, sni, std::vector<std::string>{}, udp, tfo, scv);
|
||||
break;
|
||||
case "Socks5"_hash:
|
||||
username = GetMember(json, "Username");
|
||||
@@ -1099,18 +1178,21 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
for (uint32_t i = 0; i < yamlnode[section].size(); i++) {
|
||||
std::string proxytype, ps, server, port, cipher, group, password = "", ports, tempPassword; //common
|
||||
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
|
||||
std::string fp = "chrome", pbk, sid,packet_encoding; //vless
|
||||
std::string fp = "chrome", pbk, sid, packet_encoding; //vless
|
||||
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
|
||||
std::string protocol, protoparam, obfs, obfsparam; //ssr
|
||||
std::string flow, mode; //trojan
|
||||
std::string user; //socks
|
||||
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
|
||||
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
|
||||
std::string obfsPassword;//hysteria2
|
||||
std::string congestion_control, udp_relay_mode, token;// tuic
|
||||
std::string auth, up, down, obfsParam, insecure, alpn; //hysteria
|
||||
std::string obfsPassword; //hysteria2
|
||||
std::string congestion_control, udp_relay_mode, token; // tuic
|
||||
string_array dns_server;
|
||||
std::vector<String> alpns;
|
||||
String alpn2;
|
||||
std::string fingerprint, multiplexing, transfer_protocol, v2ray_http_upgrade;
|
||||
tribool udp, tfo, scv;
|
||||
bool reduceRtt, disableSni;//tuic
|
||||
bool reduceRtt, disableSni; //tuic
|
||||
std::vector<std::string> alpnList;
|
||||
Proxy node;
|
||||
singleproxy = yamlnode[section][i];
|
||||
@@ -1118,8 +1200,11 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
singleproxy["name"] >>= ps;
|
||||
singleproxy["server"] >>= server;
|
||||
singleproxy["port"] >>= port;
|
||||
singleproxy["port-range"] >>= ports;
|
||||
|
||||
if (port.empty() || port == "0")
|
||||
continue;
|
||||
if (ports.empty())
|
||||
continue;
|
||||
udp = safe_as<std::string>(singleproxy["udp"]);
|
||||
scv = safe_as<std::string>(singleproxy["skip-cert-verify"]);
|
||||
switch (hash_(proxytype)) {
|
||||
@@ -1141,13 +1226,16 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
break;
|
||||
case "ws"_hash:
|
||||
if (singleproxy["ws-opts"].IsDefined()) {
|
||||
path = singleproxy["ws-opts"]["path"].IsDefined() ? safe_as<std::string>(
|
||||
singleproxy["ws-opts"]["path"]) : "/";
|
||||
path = singleproxy["ws-opts"]["path"].IsDefined()
|
||||
? safe_as<std::string>(
|
||||
singleproxy["ws-opts"]["path"])
|
||||
: "/";
|
||||
singleproxy["ws-opts"]["headers"]["Host"] >>= host;
|
||||
singleproxy["ws-opts"]["headers"]["Edge"] >>= edge;
|
||||
} else {
|
||||
path = singleproxy["ws-path"].IsDefined() ? safe_as<std::string>(singleproxy["ws-path"])
|
||||
: "/";
|
||||
path = singleproxy["ws-path"].IsDefined()
|
||||
? safe_as<std::string>(singleproxy["ws-path"])
|
||||
: "/";
|
||||
singleproxy["ws-headers"]["Host"] >>= host;
|
||||
singleproxy["ws-headers"]["Edge"] >>= edge;
|
||||
}
|
||||
@@ -1220,7 +1308,7 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
break;
|
||||
}
|
||||
|
||||
//support for go-shadowsocks2
|
||||
//support for go-shadowsocks2
|
||||
if (cipher == "AEAD_CHACHA20_POLY1305")
|
||||
cipher = "chacha20-ietf-poly1305";
|
||||
else if (strFind(cipher, "AEAD")) {
|
||||
@@ -1310,17 +1398,19 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
singleproxy["ipv6"] >>= ipv6;
|
||||
|
||||
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
||||
dns_server, mtu, "0", "", "", udp,"");
|
||||
dns_server, mtu, "0", "", "", udp, "");
|
||||
break;
|
||||
case "vless"_hash:
|
||||
group = XRAY_DEFAULT_GROUP;
|
||||
|
||||
singleproxy["uuid"] >>= id;
|
||||
singleproxy["alterId"] >>= aid;
|
||||
net = singleproxy["network"].IsDefined() ? safe_as<std::string>(singleproxy["network"]) : "tcp";
|
||||
sni = singleproxy["sni"].IsDefined() ? safe_as<std::string>(singleproxy["sni"]) : safe_as<std::string>(
|
||||
singleproxy["servername"]);
|
||||
sni = singleproxy["sni"].IsDefined()
|
||||
? safe_as<std::string>(singleproxy["sni"])
|
||||
: safe_as<std::string>(
|
||||
singleproxy["servername"]);
|
||||
switch (hash_(net)) {
|
||||
case "tcp"_hash:
|
||||
case "http"_hash:
|
||||
singleproxy["http-opts"]["path"][0] >>= path;
|
||||
singleproxy["http-opts"]["headers"]["Host"][0] >>= host;
|
||||
@@ -1328,16 +1418,23 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
break;
|
||||
case "ws"_hash:
|
||||
if (singleproxy["ws-opts"].IsDefined()) {
|
||||
path = singleproxy["ws-opts"]["path"].IsDefined() ? safe_as<std::string>(
|
||||
singleproxy["ws-opts"]["path"]) : "/";
|
||||
path = singleproxy["ws-opts"]["path"].IsDefined()
|
||||
? safe_as<std::string>(
|
||||
singleproxy["ws-opts"]["path"])
|
||||
: "/";
|
||||
singleproxy["ws-opts"]["headers"]["Host"] >>= host;
|
||||
singleproxy["ws-opts"]["headers"]["Edge"] >>= edge;
|
||||
if (singleproxy["ws-opts"]["v2ray-http-upgrade"].IsDefined()) {
|
||||
v2ray_http_upgrade = safe_as<std::string>(singleproxy["ws-opts"]["v2ray-http-upgrade"]);
|
||||
}
|
||||
} else {
|
||||
path = singleproxy["ws-path"].IsDefined() ? safe_as<std::string>(singleproxy["ws-path"])
|
||||
: "/";
|
||||
path = singleproxy["ws-path"].IsDefined()
|
||||
? safe_as<std::string>(singleproxy["ws-path"])
|
||||
: "/";
|
||||
singleproxy["ws-headers"]["Host"] >>= host;
|
||||
singleproxy["ws-headers"]["Edge"] >>= edge;
|
||||
}
|
||||
|
||||
break;
|
||||
case "h2"_hash:
|
||||
singleproxy["h2-opts"]["path"] >>= path;
|
||||
@@ -1349,12 +1446,15 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
singleproxy["grpc-opts"]["grpc-service-name"] >>= path;
|
||||
edge.clear();
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
tls = safe_as<std::string>(singleproxy["tls"]) == "true" ? "tls" : "";
|
||||
if (singleproxy["reality-opts"].IsDefined()) {
|
||||
host = singleproxy["sni"].IsDefined() ? safe_as<std::string>(singleproxy["sni"])
|
||||
: safe_as<std::string>(singleproxy["servername"]);
|
||||
host = singleproxy["sni"].IsDefined()
|
||||
? safe_as<std::string>(singleproxy["sni"])
|
||||
: safe_as<std::string>(singleproxy["servername"]);
|
||||
printf("host:%s", host.c_str());
|
||||
singleproxy["reality-opts"]["public-key"] >>= pbk;
|
||||
singleproxy["reality-opts"]["short-id"] >>= sid;
|
||||
@@ -1366,7 +1466,8 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
bool vless_udp;
|
||||
singleproxy["udp"] >> vless_udp;
|
||||
vlessConstruct(node, XRAY_DEFAULT_GROUP, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
|
||||
host, "", tls, pbk, sid, fp, sni, alpnList,packet_encoding,udp);
|
||||
host, "", tls, pbk, sid, fp, sni, alpnList, packet_encoding, udp, tribool(), tribool(),
|
||||
tribool(), "", v2ray_http_upgrade);
|
||||
break;
|
||||
case "hysteria"_hash:
|
||||
group = HYSTERIA_DEFAULT_GROUP;
|
||||
@@ -1396,8 +1497,24 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
singleproxy["password"] >>= password;
|
||||
if (password.empty())
|
||||
singleproxy["auth"] >>= password;
|
||||
singleproxy["up"] >>= up;
|
||||
singleproxy["down"] >>= down;
|
||||
if (singleproxy["up"].IsDefined()) {
|
||||
singleproxy["up"] >>= up;
|
||||
if (up.empty()) {
|
||||
try {
|
||||
up = singleproxy["up"].as<std::string>();
|
||||
} catch (const YAML::BadConversion& e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (singleproxy["down"].IsDefined()) {
|
||||
singleproxy["down"] >>= down;
|
||||
if (down.empty()) {
|
||||
try {
|
||||
down = singleproxy["down"].as<std::string>();
|
||||
} catch (const YAML::BadConversion& e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
singleproxy["obfs"] >>= obfsParam;
|
||||
singleproxy["obfs-password"] >>= obfsPassword;
|
||||
singleproxy["sni"] >>= host;
|
||||
@@ -1428,6 +1545,41 @@ void explodeClash(Node yamlnode, std::vector<Proxy> &nodes) {
|
||||
tribool(), scv, reduceRtt, disableSni, request_timeout);
|
||||
|
||||
break;
|
||||
case "anytls"_hash:
|
||||
group = ANYTLS_DEFAULT_GROUP;
|
||||
singleproxy["password"] >>= password;
|
||||
singleproxy["sni"] >>= sni;
|
||||
|
||||
if (!singleproxy["alpn"].IsNull() && singleproxy["alpn"].size() >= 1) {
|
||||
singleproxy["alpn"][0] >>= alpn;
|
||||
alpns.push_back(alpn);
|
||||
if (singleproxy["alpn"].size() >= 2 && !singleproxy["alpn"][1].IsNull()) {
|
||||
singleproxy["alpn"][1] >>= alpn2;
|
||||
alpns.push_back(alpn2);
|
||||
}
|
||||
}
|
||||
singleproxy["client-fingerprint"] >>= fingerprint;
|
||||
anyTlSConstruct(node, ANYTLS_DEFAULT_GROUP, ps, port, password, server, alpns, fingerprint, sni,
|
||||
udp,
|
||||
tribool(), scv, tribool(), "", 30, 30, 0);
|
||||
break;
|
||||
case "mieru"_hash:
|
||||
group = MIERU_DEFAULT_GROUP;
|
||||
singleproxy["password"] >>= password;
|
||||
singleproxy["username"] >>= user;
|
||||
singleproxy["port-range"] >>= ports;
|
||||
if (!singleproxy["multiplexing"].IsNull()) {
|
||||
singleproxy["multiplexing"] >>= multiplexing;
|
||||
}
|
||||
transfer_protocol = "TCP";
|
||||
if (!singleproxy["transport"].IsNull()) {
|
||||
singleproxy["transport"] >>= transfer_protocol;
|
||||
}
|
||||
mieruConstruct(node, MIERU_DEFAULT_GROUP, ps, port, password, server, ports, user, multiplexing,
|
||||
transfer_protocol,
|
||||
udp,
|
||||
tribool(), scv, tribool(), "");
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -1449,7 +1601,8 @@ void explodeStdVMess(std::string vmess, Proxy &node) {
|
||||
remarks = urlDecode(vmess.substr(pos + 1));
|
||||
vmess.erase(pos);
|
||||
}
|
||||
const std::string stdvmess_matcher = R"(^([a-z]+)(?:\+([a-z]+))?:([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})-(\d+)@(.+):(\d+)(?:\/?\?(.*))?$)";
|
||||
const std::string stdvmess_matcher =
|
||||
R"(^([a-z]+)(?:\+([a-z]+))?:([\da-f]{4}(?:[\da-f]{4}-){4}[\da-f]{12})-(\d+)@(.+):(\d+)(?:\/?\?(.*))?$)";
|
||||
if (regGetMatch(vmess, stdvmess_matcher, 8, 0, &net, &tls, &id, &aid, &add, &port, &addition))
|
||||
return;
|
||||
|
||||
@@ -1479,7 +1632,8 @@ void explodeStdVMess(std::string vmess, Proxy &node) {
|
||||
if (!alpn.empty()) {
|
||||
alpnList.push_back(alpn);
|
||||
}
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", path, host, "", tls, "",alpnList);
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", path, host, "", tls, "",
|
||||
alpnList);
|
||||
}
|
||||
|
||||
|
||||
@@ -1520,6 +1674,51 @@ void explodeStdHysteria(std::string hysteria, Proxy &node) {
|
||||
return;
|
||||
}
|
||||
|
||||
void explodeStdMieru(std::string mieru, Proxy &node) {
|
||||
std::string username, password, host, port, ports, profile, protocol, multiplexing, mtu, remarks;
|
||||
std::string addition;
|
||||
tribool udp, tfo, scv, tls13;
|
||||
|
||||
// 去除前缀
|
||||
string_size pos;
|
||||
|
||||
// 提取 remarks
|
||||
pos = mieru.rfind("#");
|
||||
if (pos != mieru.npos) {
|
||||
remarks = urlDecode(mieru.substr(pos + 1));
|
||||
mieru.erase(pos);
|
||||
}
|
||||
|
||||
// 提取参数
|
||||
pos = mieru.rfind("?");
|
||||
if (pos != mieru.npos) {
|
||||
addition = mieru.substr(pos + 1);
|
||||
mieru.erase(pos);
|
||||
}
|
||||
|
||||
// 账号密码@host
|
||||
if (regGetMatch(mieru, R"(^(.*?):(.*?)@(.*)$)", 4, 0, &username, &password, &host))
|
||||
return;
|
||||
|
||||
// 提取端口(port=多个情况)
|
||||
port = getUrlArg(addition, "port");
|
||||
if (port.find('-') != std::string::npos) {
|
||||
ports = port;
|
||||
}
|
||||
// 提取协议(多个 protocol)
|
||||
protocol = getUrlArg(addition, "protocol");
|
||||
|
||||
multiplexing = getUrlArg(addition, "multiplexing");
|
||||
mtu = getUrlArg(addition, "mtu");
|
||||
|
||||
if (remarks.empty())
|
||||
remarks = host;
|
||||
|
||||
mieruConstruct(node, "MieruGroup", remarks, port,
|
||||
password, host, ports, username, multiplexing, protocol,
|
||||
udp, tfo, scv, tls13, "");
|
||||
}
|
||||
|
||||
void explodeStdHysteria2(std::string hysteria2, Proxy &node) {
|
||||
std::string add, port, password, host, insecure, up, down, alpn, obfsParam, obfsPassword, remarks, sni, ports;
|
||||
std::string addition;
|
||||
@@ -1583,7 +1782,8 @@ void explodeStdVless(std::string vless, Proxy &node) {
|
||||
remarks = urlDecode(vless.substr(pos + 1));
|
||||
vless.erase(pos);
|
||||
}
|
||||
const std::string stdvless_matcher = R"(^([\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12})@\[?([\d\-a-zA-Z:.]+)\]?:(\d+)(?:\/?\?(.*))?$)";
|
||||
const std::string stdvless_matcher =
|
||||
R"(^([\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12})@\[?([\d\-a-zA-Z:.]+)\]?:(\d+)(?:\/?\?(.*))?$)";
|
||||
if (regGetMatch(vless, stdvless_matcher, 5, 0, &id, &add, &port, &addition))
|
||||
return;
|
||||
|
||||
@@ -1625,7 +1825,7 @@ void explodeStdVless(std::string vless, Proxy &node) {
|
||||
remarks = add + ":" + port;
|
||||
sni = getUrlArg(addition, "sni");
|
||||
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, "auto", flow, mode, path, host, "",
|
||||
tls, pbk, sid, fp, sni, alpnList,packet_encoding);
|
||||
tls, pbk, sid, fp, sni, alpnList, packet_encoding);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1669,7 +1869,8 @@ void explodeShadowrocket(std::string rocket, Proxy &node) {
|
||||
if (!alpn.empty()) {
|
||||
alpnList.push_back(alpn);
|
||||
}
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "",alpnList);
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "",
|
||||
alpnList);
|
||||
}
|
||||
|
||||
void explodeKitsunebi(std::string kit, Proxy &node) {
|
||||
@@ -1708,7 +1909,8 @@ void explodeKitsunebi(std::string kit, Proxy &node) {
|
||||
if (!alpn.empty()) {
|
||||
alpnList.push_back(alpn);
|
||||
}
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "",alpnList);
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, add, port, type, id, aid, net, cipher, path, host, "", tls, "",
|
||||
alpnList);
|
||||
}
|
||||
|
||||
// peer = (public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, allowed-ips = "0.0.0.0/0, ::/0", endpoint = engage.cloudflareclient.com:2408, client-id = 139/184/125),(public-key = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=, endpoint = engage.cloudflareclient.com:2408)
|
||||
@@ -1854,9 +2056,9 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
||||
ssConstruct(node, SS_DEFAULT_GROUP, remarks, server, port, password, method, plugin, pluginopts, udp,
|
||||
tfo, scv);
|
||||
}
|
||||
//else
|
||||
// continue;
|
||||
break;
|
||||
//else
|
||||
// continue;
|
||||
break;
|
||||
case "ss"_hash: //surge 3 style ss proxy
|
||||
server = trim(configs[1]);
|
||||
port = trim(configs[2]);
|
||||
@@ -1994,7 +2196,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method, path, host,
|
||||
edge, tls, "",std::vector<std::string>{}, udp, tfo, scv, tls13);
|
||||
edge, tls, "", std::vector<std::string>{}, udp, tfo, scv, tls13);
|
||||
break;
|
||||
case "http"_hash: //http proxy
|
||||
server = trim(configs[1]);
|
||||
@@ -2161,7 +2363,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
|
||||
wireguardConstruct(node, WG_DEFAULT_GROUP, remarks, "", "0", ip, ipv6, private_key, "", "", dns_servers,
|
||||
mtu, keepalive, test_url, "", udp,"");
|
||||
mtu, keepalive, test_url, "", udp, "");
|
||||
parsePeers(node, peer);
|
||||
break;
|
||||
default:
|
||||
@@ -2325,7 +2527,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
||||
remarks = server + ":" + port;
|
||||
|
||||
vmessConstruct(node, V2RAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
|
||||
path, host, "", tls, "",std::vector<std::string>{}, udp, tfo, scv, tls13);
|
||||
path, host, "", tls, "", std::vector<std::string>{}, udp, tfo, scv, tls13);
|
||||
break;
|
||||
case "vless"_hash: //quantumult x style vless link
|
||||
server = trim(configs[0].substr(0, configs[0].rfind(":")));
|
||||
@@ -2392,7 +2594,7 @@ bool explodeSurge(std::string surge, std::vector<Proxy> &nodes) {
|
||||
remarks = server + ":" + port;
|
||||
vlessConstruct(node, XRAY_DEFAULT_GROUP, remarks, server, port, "", id, aead, net, method,
|
||||
"chrome", "", path, host, "",
|
||||
tls, "", "", fp, sni, std::vector<std::string>{},"", udp, tfo, scv, tls13);
|
||||
tls, "", "", fp, sni, std::vector<std::string>{}, "", udp, tfo, scv, tls13);
|
||||
break;
|
||||
case "trojan"_hash: //quantumult x style trojan link
|
||||
server = trim(configs[0].substr(0, configs[0].rfind(':')));
|
||||
@@ -2672,16 +2874,17 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
if (outbounds[i].IsObject()) {
|
||||
std::string proxytype, ps, server, port, cipher, group, password, ports, tempPassword; //common
|
||||
std::string type = "none", id, aid = "0", net = "tcp", path, host, edge, tls, sni; //vmess
|
||||
std::string fp = "chrome", pbk, sid,packet_encoding; //vless
|
||||
std::string fp = "chrome", pbk, sid, packet_encoding; //vless
|
||||
std::string plugin, pluginopts, pluginopts_mode, pluginopts_host, pluginopts_mux; //ss
|
||||
std::string protocol, protoparam, obfs, obfsparam; //ssr
|
||||
std::string flow, mode; //trojan
|
||||
std::string user; //socks
|
||||
std::string ip, ipv6, private_key, public_key, mtu; //wireguard
|
||||
std::string auth, up, down, obfsParam, insecure, alpn;//hysteria
|
||||
std::string obfsPassword;//hysteria2
|
||||
std::string auth, up, down, obfsParam, insecure, alpn; //hysteria
|
||||
std::string obfsPassword; //hysteria2
|
||||
string_array dns_server;
|
||||
std::string congestion_control, udp_relay_mode;//quic
|
||||
std::string fingerprint;
|
||||
std::string congestion_control, udp_relay_mode; //quic
|
||||
tribool udp, tfo, scv, rrt, disableSni;
|
||||
rapidjson::Value singboxNode = outbounds[i].GetObject();
|
||||
if (singboxNode.HasMember("type") && singboxNode["type"].IsString()) {
|
||||
@@ -2730,6 +2933,12 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
sid = reality["short_id"].GetString();
|
||||
}
|
||||
}
|
||||
if (tlsObj.HasMember("utls") && tlsObj["utls"].IsObject()) {
|
||||
if (rapidjson::Value reality = tlsObj["utls"].GetObject();
|
||||
reality.HasMember("fingerprint") && reality["fingerprint"].IsString()) {
|
||||
fingerprint = reality["fingerprint"].GetString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tls = "false";
|
||||
}
|
||||
@@ -2744,7 +2953,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
cipher = GetMember(singboxNode, "security");
|
||||
explodeSingboxTransport(singboxNode, net, host, path, edge);
|
||||
vmessConstruct(node, group, ps, server, port, "", id, aid, net, cipher, path, host, edge, tls,
|
||||
sni,alpnList, udp,
|
||||
sni, alpnList, udp,
|
||||
tfo, scv);
|
||||
break;
|
||||
case "shadowsocks"_hash:
|
||||
@@ -2768,7 +2977,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
group = XRAY_DEFAULT_GROUP;
|
||||
id = GetMember(singboxNode, "uuid");
|
||||
flow = GetMember(singboxNode, "flow");
|
||||
packet_encoding = GetMember(singboxNode,"packet_encoding");
|
||||
packet_encoding = GetMember(singboxNode, "packet_encoding");
|
||||
if (singboxNode.HasMember("transport") && singboxNode["transport"].IsObject()) {
|
||||
rapidjson::Value transport = singboxNode["transport"].GetObject();
|
||||
net = GetMember(transport, "type");
|
||||
@@ -2807,7 +3016,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
|
||||
vlessConstruct(node, group, ps, server, port, type, id, aid, net, "auto", flow, mode, path,
|
||||
host, "", tls, pbk, sid, fp, sni, alpnList,packet_encoding,udp);
|
||||
host, "", tls, pbk, sid, fp, sni, alpnList, packet_encoding, udp);
|
||||
break;
|
||||
case "http"_hash:
|
||||
password = GetMember(singboxNode, "password");
|
||||
@@ -2824,7 +3033,7 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
password = GetMember(singboxNode, "pre_shared_key");
|
||||
dns_server = {"8.8.8.8"};
|
||||
wireguardConstruct(node, group, ps, server, port, ip, ipv6, private_key, public_key, password,
|
||||
dns_server, mtu, "0", "", "", udp,"");
|
||||
dns_server, mtu, "0", "", "", udp, "");
|
||||
break;
|
||||
case "socks"_hash:
|
||||
group = SOCKS_DEFAULT_GROUP;
|
||||
@@ -2849,6 +3058,14 @@ void explodeSingbox(rapidjson::Value &outbounds, std::vector<Proxy> &nodes) {
|
||||
obfsParam, insecure, ports, sni,
|
||||
udp, tfo, scv);
|
||||
break;
|
||||
case "anytls"_hash:
|
||||
group = ANYTLS_DEFAULT_GROUP;
|
||||
password = GetMember(singboxNode, "password");
|
||||
anyTlSConstruct(node, ANYTLS_DEFAULT_GROUP, ps, port, password, server, alpnList, fingerprint,
|
||||
sni,
|
||||
udp,
|
||||
tribool(), scv, tribool(), "", 30, 30, 0);
|
||||
break;
|
||||
case "hysteria2"_hash:
|
||||
group = HYSTERIA2_DEFAULT_GROUP;
|
||||
password = GetMember(singboxNode, "password");
|
||||
@@ -2971,6 +3188,8 @@ void explode(const std::string &link, Proxy &node) {
|
||||
explodeTuic(link, node);
|
||||
else if (strFind(link, "hysteria2://") || strFind(link, "hy2://"))
|
||||
explodeHysteria2(link, node);
|
||||
else if (strFind(link, "mierus://") || strFind(link, "mieru://"))
|
||||
explodeMierus(link, node);
|
||||
else if (isLink(link))
|
||||
explodeHTTPSub(link, node);
|
||||
}
|
||||
@@ -2996,8 +3215,7 @@ void explodeSub(std::string sub, std::vector<Proxy> &nodes) {
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
} catch (std::exception &e) {
|
||||
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
|
||||
//ignore
|
||||
throw;
|
||||
@@ -3022,8 +3240,7 @@ void explodeSub(std::string sub, std::vector<Proxy> &nodes) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
} catch (std::exception &e) {
|
||||
writeLog(LOG_TYPE_ERROR, e.what(), LOG_LEVEL_ERROR);
|
||||
//writeLog(0, e.what(), LOG_LEVEL_DEBUG);
|
||||
//ignore
|
||||
|
||||
@@ -42,7 +42,7 @@ void vlessConstruct(Proxy &node, const std::string &group, const std::string &re
|
||||
const std::string &pkd, const std::string &sid, const std::string &fp, const std::string &sni,
|
||||
const std::vector<std::string> &alpnList,const std::string &packet_encoding,
|
||||
tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="",tribool v2ray_http_upgrade=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,
|
||||
@@ -76,7 +76,12 @@ void trojanConstruct(Proxy &node, const std::string &group, const std::string &r
|
||||
const std::vector<std::string> &alpnList,
|
||||
bool tlssecure, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="");
|
||||
|
||||
void anyTlSConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||
const std::string &port, const std::string &password,
|
||||
const std::string &host, const std::vector<String> &AlpnList,
|
||||
const std::string &fingerprint,
|
||||
const std::string &sni, tribool udp = tribool(), tribool tfo = tribool(), tribool scv = tribool(),
|
||||
tribool tls13 = tribool(),const std::string& underlying_proxy="",uint16_t idleSessionCheckInterval=30,uint16_t idleSessionTimeout=30,uint16_t minIdleSession=0);
|
||||
void snellConstruct(Proxy &node, 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, uint16_t version = 0, tribool udp = tribool(), tribool tfo = tribool(),
|
||||
@@ -90,7 +95,13 @@ void tuicConstruct(Proxy &node, const std::string &group, const std::string &rem
|
||||
tribool udp = tribool(), tribool tfo = tribool(),
|
||||
tribool scv = tribool(), tribool reduceRtt = tribool(), tribool disableSni = tribool(),
|
||||
uint16_t request_timeout = 15000,const std::string& underlying_proxy="");
|
||||
|
||||
void mieruConstruct(Proxy &node, const std::string &group, const std::string &remarks,
|
||||
const std::string &port, const std::string &password,
|
||||
const std::string &host, const std::string &ports,
|
||||
const std::string &username,const std::string &multiplexing,
|
||||
const std::string &transfer_protocol, tribool udp,
|
||||
tribool tfo, tribool scv,
|
||||
tribool tls13, const std::string &underlying_proxy);
|
||||
void explodeVmess(std::string vmess, Proxy &node);
|
||||
|
||||
void explodeSSR(std::string ssr, Proxy &node);
|
||||
@@ -100,11 +111,11 @@ void explodeSS(std::string ss, Proxy &node);
|
||||
void explodeTrojan(std::string trojan, Proxy &node);
|
||||
|
||||
void explodeQuan(const std::string &quan, Proxy &node);
|
||||
|
||||
void explodeMierus(std::string mieru, Proxy &node);
|
||||
void explodeStdVMess(std::string vmess, Proxy &node);
|
||||
|
||||
void explodeStdVless(std::string vless, Proxy &node);
|
||||
|
||||
void explodeStdMieru(std::string mieru, Proxy &node);
|
||||
void explodeStdHysteria(std::string hysteria, Proxy &node);
|
||||
|
||||
void explodeStdHysteria2(std::string hysteria2, Proxy &node);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef VERSION_H_INCLUDED
|
||||
#define VERSION_H_INCLUDED
|
||||
|
||||
#define VERSION "v0.9.8"
|
||||
#define VERSION "v0.9.9"
|
||||
|
||||
#endif // VERSION_H_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user