@subconverter/core 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/dist/index.cjs +792 -486
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -4
- package/dist/index.d.ts +47 -4
- package/dist/index.js +792 -486
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -219,6 +219,16 @@ function createRulesetConfig() {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
// src/types/settings.ts
|
|
222
|
+
function parseClashFlavor(value) {
|
|
223
|
+
const normalized = (value ?? "").trim().toLowerCase();
|
|
224
|
+
if (normalized === "premium" || normalized === "original" || normalized === "classic" || normalized === "clash") {
|
|
225
|
+
return "premium";
|
|
226
|
+
}
|
|
227
|
+
if (normalized === "stash") {
|
|
228
|
+
return "stash";
|
|
229
|
+
}
|
|
230
|
+
return "mihomo";
|
|
231
|
+
}
|
|
222
232
|
var TargetFormat = /* @__PURE__ */ ((TargetFormat2) => {
|
|
223
233
|
TargetFormat2["Clash"] = "clash";
|
|
224
234
|
TargetFormat2["ClashR"] = "clashr";
|
|
@@ -247,6 +257,7 @@ function createExtraSettings() {
|
|
|
247
257
|
authorized: false,
|
|
248
258
|
autoCountry: false,
|
|
249
259
|
clashClassicalRuleset: false,
|
|
260
|
+
clashFlavor: "mihomo",
|
|
250
261
|
clashNewFieldName: true,
|
|
251
262
|
clashProxiesStyle: "flow",
|
|
252
263
|
clashProxyGroupsStyle: "flow",
|
|
@@ -257,6 +268,7 @@ function createExtraSettings() {
|
|
|
257
268
|
enableRuleGenerator: true,
|
|
258
269
|
excludeCountries: [],
|
|
259
270
|
excludeRemarks: [],
|
|
271
|
+
expandRulesets: true,
|
|
260
272
|
filterDeprecated: false,
|
|
261
273
|
includeCountries: [],
|
|
262
274
|
includeRemarks: [],
|
|
@@ -272,6 +284,7 @@ function createExtraSettings() {
|
|
|
272
284
|
sortFlag: false,
|
|
273
285
|
sortScript: "",
|
|
274
286
|
surgeSsrPath: "",
|
|
287
|
+
templateVars: {},
|
|
275
288
|
tfo: void 0,
|
|
276
289
|
tls13: void 0,
|
|
277
290
|
udp: void 0
|
|
@@ -495,7 +508,7 @@ function toBool(value) {
|
|
|
495
508
|
return false;
|
|
496
509
|
}
|
|
497
510
|
const normalized = value.trim().toLowerCase();
|
|
498
|
-
return normalized === "true" || normalized === "1";
|
|
511
|
+
return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on";
|
|
499
512
|
}
|
|
500
513
|
function strFind(haystack, needle) {
|
|
501
514
|
return haystack.includes(needle);
|
|
@@ -644,6 +657,23 @@ function templateVariableNames(content) {
|
|
|
644
657
|
}
|
|
645
658
|
|
|
646
659
|
// src/settings/config.ts
|
|
660
|
+
var RULESET_TYPE_PREFIXES = [
|
|
661
|
+
["surge:", "surge" /* Surge */],
|
|
662
|
+
["quanx:", "quanx" /* QuantumultX */],
|
|
663
|
+
["quantumultx:", "quanx" /* QuantumultX */],
|
|
664
|
+
["clash-domain:", "clash-domain" /* ClashDomain */],
|
|
665
|
+
["clash-ipcidr:", "clash-ipcidr" /* ClashIpCidr */],
|
|
666
|
+
["clash-classic:", "clash-classical" /* ClashClassical */],
|
|
667
|
+
["clash:", "clash-classical" /* ClashClassical */]
|
|
668
|
+
];
|
|
669
|
+
function parseRulesetSource(source) {
|
|
670
|
+
for (const [prefix, type] of RULESET_TYPE_PREFIXES) {
|
|
671
|
+
if (source.toLowerCase().startsWith(prefix)) {
|
|
672
|
+
return { type, url: source.slice(prefix.length) };
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return { url: source };
|
|
676
|
+
}
|
|
647
677
|
var GROUP_TYPE_MAP = {
|
|
648
678
|
fallback: "fallback" /* Fallback */,
|
|
649
679
|
"load-balance": "load-balance" /* LoadBalance */,
|
|
@@ -928,12 +958,16 @@ function createRequestSettings() {
|
|
|
928
958
|
appendType: false,
|
|
929
959
|
autoCountry: false,
|
|
930
960
|
autoExtract: false,
|
|
961
|
+
clashFlavor: "mihomo",
|
|
931
962
|
clashScript: false,
|
|
932
963
|
classicalRuleset: false,
|
|
933
964
|
dedupe: false,
|
|
965
|
+
devId: "",
|
|
934
966
|
emoji: [],
|
|
935
967
|
excludeCountries: [],
|
|
936
968
|
excludeRemarks: [],
|
|
969
|
+
expand: true,
|
|
970
|
+
filename: "",
|
|
937
971
|
filterDeprecated: false,
|
|
938
972
|
group: [],
|
|
939
973
|
includeCountries: [],
|
|
@@ -954,6 +988,7 @@ function createRequestSettings() {
|
|
|
954
988
|
script: "",
|
|
955
989
|
scv: void 0,
|
|
956
990
|
sort: false,
|
|
991
|
+
strict: false,
|
|
957
992
|
target: "auto" /* Auto */,
|
|
958
993
|
tfo: void 0,
|
|
959
994
|
tls13: void 0,
|
|
@@ -982,6 +1017,11 @@ function parseRequestSettings(query) {
|
|
|
982
1017
|
settings.filterDeprecated = boolArg(query, "filter_deprecated");
|
|
983
1018
|
settings.newFieldName = resolveNewFieldName(query);
|
|
984
1019
|
settings.classicalRuleset = boolArg(query, "classical");
|
|
1020
|
+
settings.clashFlavor = parseClashFlavor(firstArg(query, "flavor"));
|
|
1021
|
+
settings.expand = queryBoolFlag(query, "expand") ?? true;
|
|
1022
|
+
settings.strict = boolArg(query, "strict");
|
|
1023
|
+
settings.filename = firstArg(query, "filename");
|
|
1024
|
+
settings.devId = firstArg(query, "dev_id", "dev-id", "device_id", "device-id");
|
|
985
1025
|
settings.insert = getUrlArg(query, "insert") !== "";
|
|
986
1026
|
settings.clashScript = boolArg(query, "clash_script");
|
|
987
1027
|
settings.autoExtract = boolArg(query, "auto_extract");
|
|
@@ -1874,485 +1914,493 @@ function explodeClash(root, nodes) {
|
|
|
1874
1914
|
}
|
|
1875
1915
|
let index = nodes.length;
|
|
1876
1916
|
for (const single of list) {
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
const port = asString(get(single, "port"));
|
|
1881
|
-
let underlyingProxy = asString(get(single, "underlying-proxy"));
|
|
1882
|
-
if (underlyingProxy === "") {
|
|
1883
|
-
underlyingProxy = asString(get(single, "dialer-proxy"));
|
|
1884
|
-
}
|
|
1885
|
-
if (port === "" || port === "0") {
|
|
1886
|
-
continue;
|
|
1887
|
-
}
|
|
1888
|
-
const udp = asTri(get(single, "udp"));
|
|
1889
|
-
const tfo = asTri(get(single, "fast-open"));
|
|
1890
|
-
const scv = asTri(get(single, "skip-cert-verify"));
|
|
1891
|
-
const node = createProxy();
|
|
1892
|
-
let group2 = "";
|
|
1893
|
-
switch (proxyType) {
|
|
1894
|
-
case "vmess": {
|
|
1895
|
-
group2 = DEFAULT_GROUPS.v2ray;
|
|
1896
|
-
const id = asString(get(single, "uuid"));
|
|
1897
|
-
const aid = asString(get(single, "alterId"));
|
|
1898
|
-
const cipher = asString(get(single, "cipher"));
|
|
1899
|
-
const net = get(single, "network") !== void 0 ? asString(get(single, "network")) : "tcp";
|
|
1900
|
-
const sni = asString(get(single, "servername"));
|
|
1901
|
-
let path = "";
|
|
1902
|
-
let host = "";
|
|
1903
|
-
let edge = "";
|
|
1904
|
-
switch (net) {
|
|
1905
|
-
case "http":
|
|
1906
|
-
path = asString(get(get(get(single, "http-opts"), "path"), 0));
|
|
1907
|
-
host = asString(get(get(get(get(single, "http-opts"), "headers"), "Host"), 0));
|
|
1908
|
-
edge = "";
|
|
1909
|
-
break;
|
|
1910
|
-
case "ws":
|
|
1911
|
-
if (get(single, "ws-opts") !== void 0) {
|
|
1912
|
-
const wsOpts = get(single, "ws-opts");
|
|
1913
|
-
path = get(wsOpts, "path") !== void 0 ? asString(get(wsOpts, "path")) : "/";
|
|
1914
|
-
host = asString(get(get(wsOpts, "headers"), "Host"));
|
|
1915
|
-
edge = asString(get(get(wsOpts, "headers"), "Edge"));
|
|
1916
|
-
} else {
|
|
1917
|
-
path = get(single, "ws-path") !== void 0 ? asString(get(single, "ws-path")) : "/";
|
|
1918
|
-
host = asString(get(get(single, "ws-headers"), "Host"));
|
|
1919
|
-
edge = asString(get(get(single, "ws-headers"), "Edge"));
|
|
1920
|
-
}
|
|
1921
|
-
break;
|
|
1922
|
-
case "h2":
|
|
1923
|
-
path = asString(get(get(single, "h2-opts"), "path"));
|
|
1924
|
-
host = asString(get(get(get(single, "h2-opts"), "host"), 0));
|
|
1925
|
-
edge = "";
|
|
1926
|
-
break;
|
|
1927
|
-
case "grpc":
|
|
1928
|
-
host = asString(get(single, "servername"));
|
|
1929
|
-
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
1930
|
-
edge = "";
|
|
1931
|
-
break;
|
|
1932
|
-
default:
|
|
1933
|
-
break;
|
|
1934
|
-
}
|
|
1935
|
-
const tls = asBool(get(single, "tls")) ? "tls" : "";
|
|
1936
|
-
vmessConstruct(node, {
|
|
1937
|
-
add: server,
|
|
1938
|
-
aid,
|
|
1939
|
-
cipher,
|
|
1940
|
-
edge,
|
|
1941
|
-
group: group2,
|
|
1942
|
-
host,
|
|
1943
|
-
id,
|
|
1944
|
-
net,
|
|
1945
|
-
path,
|
|
1946
|
-
port,
|
|
1947
|
-
remark: ps,
|
|
1948
|
-
scv,
|
|
1949
|
-
sni,
|
|
1950
|
-
tfo,
|
|
1951
|
-
tls,
|
|
1952
|
-
type: "",
|
|
1953
|
-
udp,
|
|
1954
|
-
underlyingProxy
|
|
1955
|
-
});
|
|
1956
|
-
break;
|
|
1917
|
+
try {
|
|
1918
|
+
if (parseClashNode(single, nodes, index)) {
|
|
1919
|
+
index += 1;
|
|
1957
1920
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
if (
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
1921
|
+
} catch {
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
function parseClashNode(single, nodes, index) {
|
|
1926
|
+
const proxyType = asString(get(single, "type")).toLowerCase();
|
|
1927
|
+
const ps = asString(get(single, "name"));
|
|
1928
|
+
const server = asString(get(single, "server"));
|
|
1929
|
+
const port = asString(get(single, "port"));
|
|
1930
|
+
let underlyingProxy = asString(get(single, "underlying-proxy"));
|
|
1931
|
+
if (underlyingProxy === "") {
|
|
1932
|
+
underlyingProxy = asString(get(single, "dialer-proxy"));
|
|
1933
|
+
}
|
|
1934
|
+
if (port === "" || port === "0") {
|
|
1935
|
+
return false;
|
|
1936
|
+
}
|
|
1937
|
+
const udp = asTri(get(single, "udp"));
|
|
1938
|
+
const tfo = asTri(get(single, "fast-open"));
|
|
1939
|
+
const scv = asTri(get(single, "skip-cert-verify"));
|
|
1940
|
+
const node = createProxy();
|
|
1941
|
+
let group2 = "";
|
|
1942
|
+
switch (proxyType) {
|
|
1943
|
+
case "vmess": {
|
|
1944
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
1945
|
+
const id = asString(get(single, "uuid"));
|
|
1946
|
+
const aid = asString(get(single, "alterId"));
|
|
1947
|
+
const cipher = asString(get(single, "cipher"));
|
|
1948
|
+
const net = get(single, "network") !== void 0 ? asString(get(single, "network")) : "tcp";
|
|
1949
|
+
const sni = asString(get(single, "servername"));
|
|
1950
|
+
let path = "";
|
|
1951
|
+
let host = "";
|
|
1952
|
+
let edge = "";
|
|
1953
|
+
switch (net) {
|
|
1954
|
+
case "http":
|
|
1955
|
+
path = asString(get(get(get(single, "http-opts"), "path"), 0));
|
|
1956
|
+
host = asString(get(get(get(get(single, "http-opts"), "headers"), "Host"), 0));
|
|
1957
|
+
edge = "";
|
|
1958
|
+
break;
|
|
1959
|
+
case "ws":
|
|
1960
|
+
if (get(single, "ws-opts") !== void 0) {
|
|
1961
|
+
const wsOpts = get(single, "ws-opts");
|
|
1962
|
+
path = get(wsOpts, "path") !== void 0 ? asString(get(wsOpts, "path")) : "/";
|
|
1963
|
+
host = asString(get(get(wsOpts, "headers"), "Host"));
|
|
1964
|
+
edge = asString(get(get(wsOpts, "headers"), "Edge"));
|
|
1965
|
+
} else {
|
|
1966
|
+
path = get(single, "ws-path") !== void 0 ? asString(get(single, "ws-path")) : "/";
|
|
1967
|
+
host = asString(get(get(single, "ws-headers"), "Host"));
|
|
1968
|
+
edge = asString(get(get(single, "ws-headers"), "Edge"));
|
|
2002
1969
|
}
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
remark: ps,
|
|
2017
|
-
scv,
|
|
2018
|
-
server,
|
|
2019
|
-
tfo,
|
|
2020
|
-
udp,
|
|
2021
|
-
underlyingProxy
|
|
2022
|
-
});
|
|
2023
|
-
break;
|
|
2024
|
-
}
|
|
2025
|
-
case "socks5": {
|
|
2026
|
-
group2 = DEFAULT_GROUPS.socks;
|
|
2027
|
-
const user = asString(get(single, "username"));
|
|
2028
|
-
const password = asString(get(single, "password"));
|
|
2029
|
-
socksConstruct(node, {
|
|
2030
|
-
group: group2,
|
|
2031
|
-
password,
|
|
2032
|
-
port,
|
|
2033
|
-
remark: ps,
|
|
2034
|
-
server,
|
|
2035
|
-
underlyingProxy,
|
|
2036
|
-
username: user
|
|
2037
|
-
});
|
|
2038
|
-
break;
|
|
2039
|
-
}
|
|
2040
|
-
case "ssr": {
|
|
2041
|
-
group2 = DEFAULT_GROUPS.ssr;
|
|
2042
|
-
let cipher = asString(get(single, "cipher"));
|
|
2043
|
-
if (cipher === "dummy") {
|
|
2044
|
-
cipher = "none";
|
|
2045
|
-
}
|
|
2046
|
-
const password = asString(get(single, "password"));
|
|
2047
|
-
const protocol = asString(get(single, "protocol"));
|
|
2048
|
-
const obfs = asString(get(single, "obfs"));
|
|
2049
|
-
const protocolParam = get(single, "protocol-param") !== void 0 ? asString(get(single, "protocol-param")) : asString(get(single, "protocolparam"));
|
|
2050
|
-
const obfsParam = get(single, "obfs-param") !== void 0 ? asString(get(single, "obfs-param")) : asString(get(single, "obfsparam"));
|
|
2051
|
-
ssrConstruct(node, {
|
|
2052
|
-
group: group2,
|
|
2053
|
-
method: cipher,
|
|
2054
|
-
obfs,
|
|
2055
|
-
obfsParam,
|
|
2056
|
-
password,
|
|
2057
|
-
port,
|
|
2058
|
-
protocol,
|
|
2059
|
-
protocolParam,
|
|
2060
|
-
remark: ps,
|
|
2061
|
-
scv,
|
|
2062
|
-
server,
|
|
2063
|
-
tfo,
|
|
2064
|
-
udp,
|
|
2065
|
-
underlyingProxy
|
|
2066
|
-
});
|
|
2067
|
-
break;
|
|
2068
|
-
}
|
|
2069
|
-
case "http": {
|
|
2070
|
-
group2 = DEFAULT_GROUPS.http;
|
|
2071
|
-
const user = asString(get(single, "username"));
|
|
2072
|
-
const password = asString(get(single, "password"));
|
|
2073
|
-
const tls = asString(get(single, "tls"));
|
|
2074
|
-
httpConstruct(node, {
|
|
2075
|
-
group: group2,
|
|
2076
|
-
password,
|
|
2077
|
-
port,
|
|
2078
|
-
remark: ps,
|
|
2079
|
-
scv,
|
|
2080
|
-
server,
|
|
2081
|
-
tfo,
|
|
2082
|
-
tls: tls === "true",
|
|
2083
|
-
underlyingProxy,
|
|
2084
|
-
username: user
|
|
2085
|
-
});
|
|
2086
|
-
break;
|
|
1970
|
+
break;
|
|
1971
|
+
case "h2":
|
|
1972
|
+
path = asString(get(get(single, "h2-opts"), "path"));
|
|
1973
|
+
host = asString(get(get(get(single, "h2-opts"), "host"), 0));
|
|
1974
|
+
edge = "";
|
|
1975
|
+
break;
|
|
1976
|
+
case "grpc":
|
|
1977
|
+
host = asString(get(single, "servername"));
|
|
1978
|
+
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
1979
|
+
edge = "";
|
|
1980
|
+
break;
|
|
1981
|
+
default:
|
|
1982
|
+
break;
|
|
2087
1983
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
1984
|
+
const tls = asBool(get(single, "tls")) ? "tls" : "";
|
|
1985
|
+
vmessConstruct(node, {
|
|
1986
|
+
add: server,
|
|
1987
|
+
aid,
|
|
1988
|
+
cipher,
|
|
1989
|
+
edge,
|
|
1990
|
+
group: group2,
|
|
1991
|
+
host,
|
|
1992
|
+
id,
|
|
1993
|
+
net,
|
|
1994
|
+
path,
|
|
1995
|
+
port,
|
|
1996
|
+
remark: ps,
|
|
1997
|
+
scv,
|
|
1998
|
+
sni,
|
|
1999
|
+
tfo,
|
|
2000
|
+
tls,
|
|
2001
|
+
type: "",
|
|
2002
|
+
udp,
|
|
2003
|
+
underlyingProxy
|
|
2004
|
+
});
|
|
2005
|
+
break;
|
|
2006
|
+
}
|
|
2007
|
+
case "ss": {
|
|
2008
|
+
group2 = DEFAULT_GROUPS.ss;
|
|
2009
|
+
let cipher = asString(get(single, "cipher"));
|
|
2010
|
+
const password = asString(get(single, "password"));
|
|
2011
|
+
let plugin = "";
|
|
2012
|
+
let pluginOption = "";
|
|
2013
|
+
let pluginMode = "";
|
|
2014
|
+
let pluginHost = "";
|
|
2015
|
+
let pluginMux = "";
|
|
2016
|
+
let pluginTls = "";
|
|
2017
|
+
let path = "";
|
|
2018
|
+
if (get(single, "plugin") !== void 0) {
|
|
2019
|
+
const pluginName = asString(get(single, "plugin")).toLowerCase();
|
|
2020
|
+
const pluginOpts = get(single, "plugin-opts");
|
|
2021
|
+
if (pluginName === "obfs") {
|
|
2022
|
+
plugin = "obfs-local";
|
|
2023
|
+
pluginMode = asString(get(pluginOpts, "mode"));
|
|
2024
|
+
pluginHost = asString(get(pluginOpts, "host"));
|
|
2025
|
+
} else if (pluginName === "v2ray-plugin") {
|
|
2026
|
+
plugin = "v2ray-plugin";
|
|
2027
|
+
pluginMode = asString(get(pluginOpts, "mode"));
|
|
2028
|
+
pluginHost = asString(get(pluginOpts, "host"));
|
|
2029
|
+
pluginTls = asBool(get(pluginOpts, "tls")) ? "tls;" : "";
|
|
2030
|
+
path = asString(get(pluginOpts, "path"));
|
|
2031
|
+
pluginMux = asBool(get(pluginOpts, "mux")) ? "mux=4;" : "";
|
|
2105
2032
|
}
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
udp,
|
|
2119
|
-
underlyingProxy
|
|
2120
|
-
});
|
|
2121
|
-
break;
|
|
2122
|
-
}
|
|
2123
|
-
case "snell": {
|
|
2124
|
-
group2 = DEFAULT_GROUPS.snell;
|
|
2125
|
-
const password = asString(get(single, "psk"));
|
|
2126
|
-
const obfs = asString(get(get(single, "obfs-opts"), "mode"));
|
|
2127
|
-
const host = asString(get(get(single, "obfs-opts"), "host"));
|
|
2128
|
-
const version = asString(get(single, "version"));
|
|
2129
|
-
snellConstruct(node, {
|
|
2130
|
-
group: group2,
|
|
2131
|
-
host,
|
|
2132
|
-
obfs,
|
|
2133
|
-
password,
|
|
2134
|
-
port,
|
|
2135
|
-
remark: ps,
|
|
2136
|
-
scv,
|
|
2137
|
-
server,
|
|
2138
|
-
tfo,
|
|
2139
|
-
udp,
|
|
2140
|
-
underlyingProxy,
|
|
2141
|
-
version: toInt(version)
|
|
2142
|
-
});
|
|
2143
|
-
break;
|
|
2144
|
-
}
|
|
2145
|
-
case "wireguard": {
|
|
2146
|
-
group2 = DEFAULT_GROUPS.wireguard;
|
|
2147
|
-
const publicKey = asString(get(single, "public-key"));
|
|
2148
|
-
const privateKey = asString(get(single, "private-key"));
|
|
2149
|
-
const dns = get(single, "dns");
|
|
2150
|
-
const dnsServers = Array.isArray(dns) ? dns.map((d) => String(d)) : dns ? [String(dns)] : [];
|
|
2151
|
-
const mtu = asString(get(single, "mtu"));
|
|
2152
|
-
const psk = asString(get(single, "preshared-key"));
|
|
2153
|
-
const ip = asString(get(single, "ip"));
|
|
2154
|
-
const ipv6 = asString(get(single, "ipv6"));
|
|
2155
|
-
wireGuardConstruct(node, {
|
|
2156
|
-
dnsServers,
|
|
2157
|
-
group: group2,
|
|
2158
|
-
keepAlive: "0",
|
|
2159
|
-
mtu,
|
|
2160
|
-
port,
|
|
2161
|
-
preSharedKey: psk,
|
|
2162
|
-
privateKey,
|
|
2163
|
-
publicKey,
|
|
2164
|
-
remark: ps,
|
|
2165
|
-
selfIp: ip,
|
|
2166
|
-
selfIpv6: ipv6,
|
|
2167
|
-
server,
|
|
2168
|
-
testUrl: "",
|
|
2169
|
-
udp,
|
|
2170
|
-
underlyingProxy
|
|
2171
|
-
});
|
|
2172
|
-
break;
|
|
2173
|
-
}
|
|
2174
|
-
case "hysteria": {
|
|
2175
|
-
group2 = DEFAULT_GROUPS.hysteria;
|
|
2176
|
-
const ports = asString(get(single, "ports"));
|
|
2177
|
-
const protocol = asString(get(single, "protocol"));
|
|
2178
|
-
const obfsProtocol = asString(get(single, "obfs-protocol"));
|
|
2179
|
-
const up = asString(get(single, "up"));
|
|
2180
|
-
const upSpeed = asString(get(single, "up-speed"));
|
|
2181
|
-
const down = asString(get(single, "down"));
|
|
2182
|
-
const downSpeed = asString(get(single, "down-speed"));
|
|
2183
|
-
const auth = asString(get(single, "auth"));
|
|
2184
|
-
let authStr = asString(get(single, "auth-str"));
|
|
2185
|
-
if (authStr === "") {
|
|
2186
|
-
authStr = asString(get(single, "auth_str"));
|
|
2033
|
+
} else if (get(single, "obfs") !== void 0) {
|
|
2034
|
+
plugin = "obfs-local";
|
|
2035
|
+
pluginMode = asString(get(single, "obfs"));
|
|
2036
|
+
pluginHost = asString(get(single, "obfs-host"));
|
|
2037
|
+
}
|
|
2038
|
+
if (plugin === "simple-obfs" || plugin === "obfs-local") {
|
|
2039
|
+
pluginOption = `obfs=${pluginMode}`;
|
|
2040
|
+
pluginOption += pluginHost === "" ? "" : `;obfs-host=${pluginHost}`;
|
|
2041
|
+
} else if (plugin === "v2ray-plugin") {
|
|
2042
|
+
pluginOption = `mode=${pluginMode};${pluginTls}${pluginMux}`;
|
|
2043
|
+
if (pluginHost !== "") {
|
|
2044
|
+
pluginOption += `host=${pluginHost};`;
|
|
2187
2045
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
const fingerprint = asString(get(single, "fingerprint"));
|
|
2191
|
-
const alpnValue = get(single, "alpn");
|
|
2192
|
-
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2193
|
-
const ca = asString(get(single, "ca"));
|
|
2194
|
-
const caStr = asString(get(single, "ca-str"));
|
|
2195
|
-
const recvWindowConn = asString(get(single, "recv-window-conn"));
|
|
2196
|
-
const recvWindow = asString(get(single, "recv-window"));
|
|
2197
|
-
let disableMtuDiscovery = asString(get(single, "disable-mtu-discovery"));
|
|
2198
|
-
if (disableMtuDiscovery === "") {
|
|
2199
|
-
disableMtuDiscovery = asString(get(single, "disable_mtu_discovery"));
|
|
2046
|
+
if (path !== "") {
|
|
2047
|
+
pluginOption += `path=${path};`;
|
|
2200
2048
|
}
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
alpn,
|
|
2204
|
-
auth,
|
|
2205
|
-
authStr,
|
|
2206
|
-
ca,
|
|
2207
|
-
caStr,
|
|
2208
|
-
disableMtuDiscovery,
|
|
2209
|
-
down,
|
|
2210
|
-
downSpeed,
|
|
2211
|
-
fingerprint,
|
|
2212
|
-
group: group2,
|
|
2213
|
-
hopInterval,
|
|
2214
|
-
obfs,
|
|
2215
|
-
obfsProtocol,
|
|
2216
|
-
port,
|
|
2217
|
-
ports,
|
|
2218
|
-
protocol,
|
|
2219
|
-
recvWindow,
|
|
2220
|
-
recvWindowConn,
|
|
2221
|
-
remark: ps,
|
|
2222
|
-
scv,
|
|
2223
|
-
server,
|
|
2224
|
-
sni,
|
|
2225
|
-
tfo,
|
|
2226
|
-
underlyingProxy,
|
|
2227
|
-
up,
|
|
2228
|
-
upSpeed
|
|
2229
|
-
});
|
|
2230
|
-
break;
|
|
2231
|
-
}
|
|
2232
|
-
case "hysteria2": {
|
|
2233
|
-
group2 = DEFAULT_GROUPS.hysteria2;
|
|
2234
|
-
const ports = asString(get(single, "ports"));
|
|
2235
|
-
const up = asString(get(single, "up"));
|
|
2236
|
-
const down = asString(get(single, "down"));
|
|
2237
|
-
let password = asString(get(single, "password"));
|
|
2238
|
-
if (password === "") {
|
|
2239
|
-
password = asString(get(single, "auth"));
|
|
2049
|
+
if (pluginMux !== "") {
|
|
2050
|
+
pluginOption += `mux=${pluginMux};`;
|
|
2240
2051
|
}
|
|
2241
|
-
const obfs = asString(get(single, "obfs"));
|
|
2242
|
-
const obfsPassword = asString(get(single, "obfs-password"));
|
|
2243
|
-
const sni = asString(get(single, "sni"));
|
|
2244
|
-
const fingerprint = asString(get(single, "fingerprint"));
|
|
2245
|
-
const alpnValue = get(single, "alpn");
|
|
2246
|
-
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2247
|
-
const ca = asString(get(single, "ca"));
|
|
2248
|
-
const caStr = asString(get(single, "ca-str"));
|
|
2249
|
-
const cwnd = asString(get(single, "cwnd"));
|
|
2250
|
-
const hopInterval = asString(get(single, "hop-interval"));
|
|
2251
|
-
hysteria2Construct(node, {
|
|
2252
|
-
alpn,
|
|
2253
|
-
ca,
|
|
2254
|
-
caStr,
|
|
2255
|
-
cwnd,
|
|
2256
|
-
down,
|
|
2257
|
-
fingerprint,
|
|
2258
|
-
group: group2,
|
|
2259
|
-
hopInterval,
|
|
2260
|
-
obfs,
|
|
2261
|
-
obfsPassword,
|
|
2262
|
-
password,
|
|
2263
|
-
port,
|
|
2264
|
-
ports,
|
|
2265
|
-
remark: ps,
|
|
2266
|
-
scv,
|
|
2267
|
-
server,
|
|
2268
|
-
sni,
|
|
2269
|
-
tfo,
|
|
2270
|
-
underlyingProxy,
|
|
2271
|
-
up
|
|
2272
|
-
});
|
|
2273
|
-
break;
|
|
2274
2052
|
}
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
anyTlsConstruct(node, {
|
|
2280
|
-
group: group2,
|
|
2281
|
-
password,
|
|
2282
|
-
port,
|
|
2283
|
-
remark: ps,
|
|
2284
|
-
scv,
|
|
2285
|
-
server,
|
|
2286
|
-
sni,
|
|
2287
|
-
tfo,
|
|
2288
|
-
udp,
|
|
2289
|
-
underlyingProxy
|
|
2290
|
-
});
|
|
2291
|
-
break;
|
|
2053
|
+
if (cipher === "AEAD_CHACHA20_POLY1305") {
|
|
2054
|
+
cipher = "chacha20-ietf-poly1305";
|
|
2055
|
+
} else if (cipher.includes("AEAD")) {
|
|
2056
|
+
cipher = cipher.replace(/AEAD_/g, "").replace(/_/g, "-").toLowerCase();
|
|
2292
2057
|
}
|
|
2293
|
-
|
|
2294
|
-
group2
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2058
|
+
ssConstruct(node, {
|
|
2059
|
+
group: group2,
|
|
2060
|
+
method: cipher,
|
|
2061
|
+
password,
|
|
2062
|
+
plugin,
|
|
2063
|
+
pluginOption,
|
|
2064
|
+
port,
|
|
2065
|
+
remark: ps,
|
|
2066
|
+
scv,
|
|
2067
|
+
server,
|
|
2068
|
+
tfo,
|
|
2069
|
+
udp,
|
|
2070
|
+
underlyingProxy
|
|
2071
|
+
});
|
|
2072
|
+
break;
|
|
2073
|
+
}
|
|
2074
|
+
case "socks5": {
|
|
2075
|
+
group2 = DEFAULT_GROUPS.socks;
|
|
2076
|
+
const user = asString(get(single, "username"));
|
|
2077
|
+
const password = asString(get(single, "password"));
|
|
2078
|
+
socksConstruct(node, {
|
|
2079
|
+
group: group2,
|
|
2080
|
+
password,
|
|
2081
|
+
port,
|
|
2082
|
+
remark: ps,
|
|
2083
|
+
server,
|
|
2084
|
+
underlyingProxy,
|
|
2085
|
+
username: user
|
|
2086
|
+
});
|
|
2087
|
+
break;
|
|
2088
|
+
}
|
|
2089
|
+
case "ssr": {
|
|
2090
|
+
group2 = DEFAULT_GROUPS.ssr;
|
|
2091
|
+
let cipher = asString(get(single, "cipher"));
|
|
2092
|
+
if (cipher === "dummy") {
|
|
2093
|
+
cipher = "none";
|
|
2094
|
+
}
|
|
2095
|
+
const password = asString(get(single, "password"));
|
|
2096
|
+
const protocol = asString(get(single, "protocol"));
|
|
2097
|
+
const obfs = asString(get(single, "obfs"));
|
|
2098
|
+
const protocolParam = get(single, "protocol-param") !== void 0 ? asString(get(single, "protocol-param")) : asString(get(single, "protocolparam"));
|
|
2099
|
+
const obfsParam = get(single, "obfs-param") !== void 0 ? asString(get(single, "obfs-param")) : asString(get(single, "obfsparam"));
|
|
2100
|
+
ssrConstruct(node, {
|
|
2101
|
+
group: group2,
|
|
2102
|
+
method: cipher,
|
|
2103
|
+
obfs,
|
|
2104
|
+
obfsParam,
|
|
2105
|
+
password,
|
|
2106
|
+
port,
|
|
2107
|
+
protocol,
|
|
2108
|
+
protocolParam,
|
|
2109
|
+
remark: ps,
|
|
2110
|
+
scv,
|
|
2111
|
+
server,
|
|
2112
|
+
tfo,
|
|
2113
|
+
udp,
|
|
2114
|
+
underlyingProxy
|
|
2115
|
+
});
|
|
2116
|
+
break;
|
|
2117
|
+
}
|
|
2118
|
+
case "http": {
|
|
2119
|
+
group2 = DEFAULT_GROUPS.http;
|
|
2120
|
+
const user = asString(get(single, "username"));
|
|
2121
|
+
const password = asString(get(single, "password"));
|
|
2122
|
+
const tls = asString(get(single, "tls"));
|
|
2123
|
+
httpConstruct(node, {
|
|
2124
|
+
group: group2,
|
|
2125
|
+
password,
|
|
2126
|
+
port,
|
|
2127
|
+
remark: ps,
|
|
2128
|
+
scv,
|
|
2129
|
+
server,
|
|
2130
|
+
tfo,
|
|
2131
|
+
tls: tls === "true",
|
|
2132
|
+
underlyingProxy,
|
|
2133
|
+
username: user
|
|
2134
|
+
});
|
|
2135
|
+
break;
|
|
2136
|
+
}
|
|
2137
|
+
case "trojan": {
|
|
2138
|
+
group2 = DEFAULT_GROUPS.trojan;
|
|
2139
|
+
const password = asString(get(single, "password"));
|
|
2140
|
+
const host = asString(get(single, "sni"));
|
|
2141
|
+
let net = asString(get(single, "network"));
|
|
2142
|
+
let path = "";
|
|
2143
|
+
switch (net) {
|
|
2144
|
+
case "grpc":
|
|
2304
2145
|
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
host,
|
|
2314
|
-
network: net,
|
|
2315
|
-
path,
|
|
2316
|
-
port,
|
|
2317
|
-
remark: ps,
|
|
2318
|
-
scv,
|
|
2319
|
-
server,
|
|
2320
|
-
sni: asString(get(single, "servername")),
|
|
2321
|
-
tfo,
|
|
2322
|
-
tls: tls === "true" ? "tls" : "",
|
|
2323
|
-
udp,
|
|
2324
|
-
underlyingProxy,
|
|
2325
|
-
userId
|
|
2326
|
-
});
|
|
2327
|
-
break;
|
|
2328
|
-
}
|
|
2329
|
-
case "tuic": {
|
|
2330
|
-
group2 = DEFAULT_GROUPS.v2ray;
|
|
2331
|
-
const alpnValue = get(single, "alpn");
|
|
2332
|
-
tuicConstruct(node, {
|
|
2333
|
-
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2334
|
-
congestionControl: asString(get(single, "congestion-controller")),
|
|
2335
|
-
group: group2,
|
|
2336
|
-
password: asString(get(single, "password")),
|
|
2337
|
-
port,
|
|
2338
|
-
remark: ps,
|
|
2339
|
-
scv,
|
|
2340
|
-
server,
|
|
2341
|
-
sni: asString(get(single, "sni")),
|
|
2342
|
-
tfo,
|
|
2343
|
-
udp,
|
|
2344
|
-
underlyingProxy,
|
|
2345
|
-
userId: asString(get(single, "uuid"))
|
|
2346
|
-
});
|
|
2347
|
-
break;
|
|
2146
|
+
break;
|
|
2147
|
+
case "ws":
|
|
2148
|
+
path = asString(get(get(single, "ws-opts"), "path"));
|
|
2149
|
+
break;
|
|
2150
|
+
default:
|
|
2151
|
+
net = "tcp";
|
|
2152
|
+
path = "";
|
|
2153
|
+
break;
|
|
2348
2154
|
}
|
|
2349
|
-
|
|
2350
|
-
|
|
2155
|
+
trojanConstruct(node, {
|
|
2156
|
+
group: group2,
|
|
2157
|
+
host,
|
|
2158
|
+
network: net,
|
|
2159
|
+
password,
|
|
2160
|
+
path,
|
|
2161
|
+
port,
|
|
2162
|
+
remark: ps,
|
|
2163
|
+
scv,
|
|
2164
|
+
server,
|
|
2165
|
+
tfo,
|
|
2166
|
+
tlsSecure: true,
|
|
2167
|
+
udp,
|
|
2168
|
+
underlyingProxy
|
|
2169
|
+
});
|
|
2170
|
+
break;
|
|
2351
2171
|
}
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2172
|
+
case "snell": {
|
|
2173
|
+
group2 = DEFAULT_GROUPS.snell;
|
|
2174
|
+
const password = asString(get(single, "psk"));
|
|
2175
|
+
const obfs = asString(get(get(single, "obfs-opts"), "mode"));
|
|
2176
|
+
const host = asString(get(get(single, "obfs-opts"), "host"));
|
|
2177
|
+
const version = asString(get(single, "version"));
|
|
2178
|
+
snellConstruct(node, {
|
|
2179
|
+
group: group2,
|
|
2180
|
+
host,
|
|
2181
|
+
obfs,
|
|
2182
|
+
password,
|
|
2183
|
+
port,
|
|
2184
|
+
remark: ps,
|
|
2185
|
+
scv,
|
|
2186
|
+
server,
|
|
2187
|
+
tfo,
|
|
2188
|
+
udp,
|
|
2189
|
+
underlyingProxy,
|
|
2190
|
+
version: toInt(version)
|
|
2191
|
+
});
|
|
2192
|
+
break;
|
|
2193
|
+
}
|
|
2194
|
+
case "wireguard": {
|
|
2195
|
+
group2 = DEFAULT_GROUPS.wireguard;
|
|
2196
|
+
const publicKey = asString(get(single, "public-key"));
|
|
2197
|
+
const privateKey = asString(get(single, "private-key"));
|
|
2198
|
+
const dns = get(single, "dns");
|
|
2199
|
+
const dnsServers = Array.isArray(dns) ? dns.map((d) => String(d)) : dns ? [String(dns)] : [];
|
|
2200
|
+
const mtu = asString(get(single, "mtu"));
|
|
2201
|
+
const psk = asString(get(single, "preshared-key"));
|
|
2202
|
+
const ip = asString(get(single, "ip"));
|
|
2203
|
+
const ipv6 = asString(get(single, "ipv6"));
|
|
2204
|
+
wireGuardConstruct(node, {
|
|
2205
|
+
dnsServers,
|
|
2206
|
+
group: group2,
|
|
2207
|
+
keepAlive: "0",
|
|
2208
|
+
mtu,
|
|
2209
|
+
port,
|
|
2210
|
+
preSharedKey: psk,
|
|
2211
|
+
privateKey,
|
|
2212
|
+
publicKey,
|
|
2213
|
+
remark: ps,
|
|
2214
|
+
selfIp: ip,
|
|
2215
|
+
selfIpv6: ipv6,
|
|
2216
|
+
server,
|
|
2217
|
+
testUrl: "",
|
|
2218
|
+
udp,
|
|
2219
|
+
underlyingProxy
|
|
2220
|
+
});
|
|
2221
|
+
break;
|
|
2222
|
+
}
|
|
2223
|
+
case "hysteria": {
|
|
2224
|
+
group2 = DEFAULT_GROUPS.hysteria;
|
|
2225
|
+
const ports = asString(get(single, "ports"));
|
|
2226
|
+
const protocol = asString(get(single, "protocol"));
|
|
2227
|
+
const obfsProtocol = asString(get(single, "obfs-protocol"));
|
|
2228
|
+
const up = asString(get(single, "up"));
|
|
2229
|
+
const upSpeed = asString(get(single, "up-speed"));
|
|
2230
|
+
const down = asString(get(single, "down"));
|
|
2231
|
+
const downSpeed = asString(get(single, "down-speed"));
|
|
2232
|
+
const auth = asString(get(single, "auth"));
|
|
2233
|
+
let authStr = asString(get(single, "auth-str"));
|
|
2234
|
+
if (authStr === "") {
|
|
2235
|
+
authStr = asString(get(single, "auth_str"));
|
|
2236
|
+
}
|
|
2237
|
+
const obfs = asString(get(single, "obfs"));
|
|
2238
|
+
const sni = asString(get(single, "sni"));
|
|
2239
|
+
const fingerprint = asString(get(single, "fingerprint"));
|
|
2240
|
+
const alpnValue = get(single, "alpn");
|
|
2241
|
+
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2242
|
+
const ca = asString(get(single, "ca"));
|
|
2243
|
+
const caStr = asString(get(single, "ca-str"));
|
|
2244
|
+
const recvWindowConn = asString(get(single, "recv-window-conn"));
|
|
2245
|
+
const recvWindow = asString(get(single, "recv-window"));
|
|
2246
|
+
let disableMtuDiscovery = asString(get(single, "disable-mtu-discovery"));
|
|
2247
|
+
if (disableMtuDiscovery === "") {
|
|
2248
|
+
disableMtuDiscovery = asString(get(single, "disable_mtu_discovery"));
|
|
2249
|
+
}
|
|
2250
|
+
const hopInterval = asString(get(single, "hop-interval"));
|
|
2251
|
+
hysteriaConstruct(node, {
|
|
2252
|
+
alpn,
|
|
2253
|
+
auth,
|
|
2254
|
+
authStr,
|
|
2255
|
+
ca,
|
|
2256
|
+
caStr,
|
|
2257
|
+
disableMtuDiscovery,
|
|
2258
|
+
down,
|
|
2259
|
+
downSpeed,
|
|
2260
|
+
fingerprint,
|
|
2261
|
+
group: group2,
|
|
2262
|
+
hopInterval,
|
|
2263
|
+
obfs,
|
|
2264
|
+
obfsProtocol,
|
|
2265
|
+
port,
|
|
2266
|
+
ports,
|
|
2267
|
+
protocol,
|
|
2268
|
+
recvWindow,
|
|
2269
|
+
recvWindowConn,
|
|
2270
|
+
remark: ps,
|
|
2271
|
+
scv,
|
|
2272
|
+
server,
|
|
2273
|
+
sni,
|
|
2274
|
+
tfo,
|
|
2275
|
+
underlyingProxy,
|
|
2276
|
+
up,
|
|
2277
|
+
upSpeed
|
|
2278
|
+
});
|
|
2279
|
+
break;
|
|
2280
|
+
}
|
|
2281
|
+
case "hysteria2": {
|
|
2282
|
+
group2 = DEFAULT_GROUPS.hysteria2;
|
|
2283
|
+
const ports = asString(get(single, "ports"));
|
|
2284
|
+
const up = asString(get(single, "up"));
|
|
2285
|
+
const down = asString(get(single, "down"));
|
|
2286
|
+
let password = asString(get(single, "password"));
|
|
2287
|
+
if (password === "") {
|
|
2288
|
+
password = asString(get(single, "auth"));
|
|
2289
|
+
}
|
|
2290
|
+
const obfs = asString(get(single, "obfs"));
|
|
2291
|
+
const obfsPassword = asString(get(single, "obfs-password"));
|
|
2292
|
+
const sni = asString(get(single, "sni"));
|
|
2293
|
+
const fingerprint = asString(get(single, "fingerprint"));
|
|
2294
|
+
const alpnValue = get(single, "alpn");
|
|
2295
|
+
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2296
|
+
const ca = asString(get(single, "ca"));
|
|
2297
|
+
const caStr = asString(get(single, "ca-str"));
|
|
2298
|
+
const cwnd = asString(get(single, "cwnd"));
|
|
2299
|
+
const hopInterval = asString(get(single, "hop-interval"));
|
|
2300
|
+
hysteria2Construct(node, {
|
|
2301
|
+
alpn,
|
|
2302
|
+
ca,
|
|
2303
|
+
caStr,
|
|
2304
|
+
cwnd,
|
|
2305
|
+
down,
|
|
2306
|
+
fingerprint,
|
|
2307
|
+
group: group2,
|
|
2308
|
+
hopInterval,
|
|
2309
|
+
obfs,
|
|
2310
|
+
obfsPassword,
|
|
2311
|
+
password,
|
|
2312
|
+
port,
|
|
2313
|
+
ports,
|
|
2314
|
+
remark: ps,
|
|
2315
|
+
scv,
|
|
2316
|
+
server,
|
|
2317
|
+
sni,
|
|
2318
|
+
tfo,
|
|
2319
|
+
underlyingProxy,
|
|
2320
|
+
up
|
|
2321
|
+
});
|
|
2322
|
+
break;
|
|
2323
|
+
}
|
|
2324
|
+
case "anytls": {
|
|
2325
|
+
group2 = DEFAULT_GROUPS.anytls;
|
|
2326
|
+
const password = asString(get(single, "password"));
|
|
2327
|
+
const sni = asString(get(single, "sni"));
|
|
2328
|
+
anyTlsConstruct(node, {
|
|
2329
|
+
group: group2,
|
|
2330
|
+
password,
|
|
2331
|
+
port,
|
|
2332
|
+
remark: ps,
|
|
2333
|
+
scv,
|
|
2334
|
+
server,
|
|
2335
|
+
sni,
|
|
2336
|
+
tfo,
|
|
2337
|
+
udp,
|
|
2338
|
+
underlyingProxy
|
|
2339
|
+
});
|
|
2340
|
+
break;
|
|
2341
|
+
}
|
|
2342
|
+
case "vless": {
|
|
2343
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2344
|
+
const userId = asString(get(single, "uuid"));
|
|
2345
|
+
const net = asString(get(single, "network"));
|
|
2346
|
+
const tls = asString(get(single, "tls"));
|
|
2347
|
+
let path = "";
|
|
2348
|
+
let host = "";
|
|
2349
|
+
if (net === "ws") {
|
|
2350
|
+
path = asString(get(get(single, "ws-opts"), "path"));
|
|
2351
|
+
host = asString(get(get(get(single, "ws-opts"), "headers"), "Host"));
|
|
2352
|
+
} else if (net === "grpc") {
|
|
2353
|
+
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
2354
|
+
}
|
|
2355
|
+
const alpnValue = get(single, "alpn");
|
|
2356
|
+
vlessConstruct(node, {
|
|
2357
|
+
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2358
|
+
encryption: asString(get(single, "encryption")),
|
|
2359
|
+
fingerprint: asString(get(single, "client-fingerprint")),
|
|
2360
|
+
flow: asString(get(single, "flow")),
|
|
2361
|
+
group: group2,
|
|
2362
|
+
host,
|
|
2363
|
+
network: net,
|
|
2364
|
+
path,
|
|
2365
|
+
port,
|
|
2366
|
+
remark: ps,
|
|
2367
|
+
scv,
|
|
2368
|
+
server,
|
|
2369
|
+
sni: asString(get(single, "servername")),
|
|
2370
|
+
tfo,
|
|
2371
|
+
tls: tls === "true" ? "tls" : "",
|
|
2372
|
+
udp,
|
|
2373
|
+
underlyingProxy,
|
|
2374
|
+
userId
|
|
2375
|
+
});
|
|
2376
|
+
break;
|
|
2377
|
+
}
|
|
2378
|
+
case "tuic": {
|
|
2379
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2380
|
+
const alpnValue = get(single, "alpn");
|
|
2381
|
+
tuicConstruct(node, {
|
|
2382
|
+
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2383
|
+
congestionControl: asString(get(single, "congestion-controller")),
|
|
2384
|
+
group: group2,
|
|
2385
|
+
password: asString(get(single, "password")),
|
|
2386
|
+
port,
|
|
2387
|
+
remark: ps,
|
|
2388
|
+
scv,
|
|
2389
|
+
server,
|
|
2390
|
+
sni: asString(get(single, "sni")),
|
|
2391
|
+
tfo,
|
|
2392
|
+
udp,
|
|
2393
|
+
underlyingProxy,
|
|
2394
|
+
userId: asString(get(single, "uuid"))
|
|
2395
|
+
});
|
|
2396
|
+
break;
|
|
2397
|
+
}
|
|
2398
|
+
default:
|
|
2399
|
+
return false;
|
|
2355
2400
|
}
|
|
2401
|
+
node.id = index;
|
|
2402
|
+
nodes.push(node);
|
|
2403
|
+
return true;
|
|
2356
2404
|
}
|
|
2357
2405
|
function parseRawSections(text) {
|
|
2358
2406
|
const sections = [];
|
|
@@ -3960,7 +4008,10 @@ function explodeSs(ss, node) {
|
|
|
3960
4008
|
const secret = match[1];
|
|
3961
4009
|
server = match[2];
|
|
3962
4010
|
port = match[3];
|
|
3963
|
-
const
|
|
4011
|
+
const raw = urlDecode(secret);
|
|
4012
|
+
const decoded = firstMatch(urlSafeBase64Decode(raw), "(\\S+?):(\\S+)");
|
|
4013
|
+
const plaintext = firstMatch(raw, "(\\S+?):(\\S+)");
|
|
4014
|
+
const secretMatch = decoded && isSsCipher(decoded[1]) ? decoded : plaintext ?? decoded;
|
|
3964
4015
|
if (!secretMatch) {
|
|
3965
4016
|
return;
|
|
3966
4017
|
}
|
|
@@ -4425,6 +4476,157 @@ function explodeAnyTls(link, node) {
|
|
|
4425
4476
|
udp: udp === "" ? void 0 : parseTri(udp)
|
|
4426
4477
|
});
|
|
4427
4478
|
}
|
|
4479
|
+
function explodeSnell(link, node) {
|
|
4480
|
+
let body = link.slice(8);
|
|
4481
|
+
let remark = "";
|
|
4482
|
+
let addition = "";
|
|
4483
|
+
const hashPos = body.lastIndexOf("#");
|
|
4484
|
+
if (hashPos !== -1) {
|
|
4485
|
+
remark = urlDecode(body.slice(hashPos + 1));
|
|
4486
|
+
body = body.slice(0, hashPos);
|
|
4487
|
+
}
|
|
4488
|
+
const qpos = body.lastIndexOf("?");
|
|
4489
|
+
if (qpos !== -1) {
|
|
4490
|
+
addition = body.slice(qpos + 1);
|
|
4491
|
+
body = body.slice(0, qpos);
|
|
4492
|
+
}
|
|
4493
|
+
const match = /^(.*?)@(.*)[:](\d+)$/.exec(body);
|
|
4494
|
+
if (!match) {
|
|
4495
|
+
return;
|
|
4496
|
+
}
|
|
4497
|
+
const password = match[1];
|
|
4498
|
+
const server = match[2];
|
|
4499
|
+
const port = match[3];
|
|
4500
|
+
if (password === "" || port === "" || port === "0") {
|
|
4501
|
+
return;
|
|
4502
|
+
}
|
|
4503
|
+
const obfs = getUrlArg(addition, "obfs");
|
|
4504
|
+
const host = getUrlArg(addition, "host");
|
|
4505
|
+
const version = getUrlArg(addition, "version");
|
|
4506
|
+
const udp = getUrlArg(addition, "udp");
|
|
4507
|
+
const tfo = getUrlArg(addition, "tfo");
|
|
4508
|
+
const scv = getUrlArg(addition, "skip-cert-verify");
|
|
4509
|
+
if (remark === "") {
|
|
4510
|
+
remark = `${server}:${port}`;
|
|
4511
|
+
}
|
|
4512
|
+
snellConstruct(node, {
|
|
4513
|
+
group: DEFAULT_GROUPS.snell,
|
|
4514
|
+
host,
|
|
4515
|
+
obfs: obfs === "" ? "none" : obfs,
|
|
4516
|
+
password,
|
|
4517
|
+
port,
|
|
4518
|
+
remark,
|
|
4519
|
+
scv: scv === "" ? void 0 : parseTri(scv),
|
|
4520
|
+
server,
|
|
4521
|
+
tfo: tfo === "" ? void 0 : parseTri(tfo),
|
|
4522
|
+
udp: udp === "" ? void 0 : parseTri(udp),
|
|
4523
|
+
version: version === "" ? 1 : toInt(version)
|
|
4524
|
+
});
|
|
4525
|
+
}
|
|
4526
|
+
function explodeHysteria(link, node) {
|
|
4527
|
+
let body = link.slice(11);
|
|
4528
|
+
let remark = "";
|
|
4529
|
+
let addition = "";
|
|
4530
|
+
const hashPos = body.lastIndexOf("#");
|
|
4531
|
+
if (hashPos !== -1) {
|
|
4532
|
+
remark = urlDecode(body.slice(hashPos + 1));
|
|
4533
|
+
body = body.slice(0, hashPos);
|
|
4534
|
+
}
|
|
4535
|
+
const qpos = body.lastIndexOf("?");
|
|
4536
|
+
if (qpos !== -1) {
|
|
4537
|
+
addition = body.slice(qpos + 1);
|
|
4538
|
+
body = body.slice(0, qpos);
|
|
4539
|
+
}
|
|
4540
|
+
const match = /^(.*)[:](\d+)$/.exec(body);
|
|
4541
|
+
if (!match) {
|
|
4542
|
+
return;
|
|
4543
|
+
}
|
|
4544
|
+
const server = match[1];
|
|
4545
|
+
const port = match[2];
|
|
4546
|
+
if (server === "" || port === "0") {
|
|
4547
|
+
return;
|
|
4548
|
+
}
|
|
4549
|
+
const auth = getUrlArg(addition, "auth");
|
|
4550
|
+
const protocol = getUrlArg(addition, "protocol");
|
|
4551
|
+
const upSpeed = getUrlArg(addition, "upmbps");
|
|
4552
|
+
const downSpeed = getUrlArg(addition, "downmbps");
|
|
4553
|
+
const alpn = getUrlArg(addition, "alpn");
|
|
4554
|
+
const obfs = getUrlArg(addition, "obfs");
|
|
4555
|
+
const obfsProtocol = getUrlArg(addition, "obfsParam");
|
|
4556
|
+
const sni = getUrlArg(addition, "peer");
|
|
4557
|
+
const insecure = getUrlArg(addition, "insecure");
|
|
4558
|
+
if (remark === "") {
|
|
4559
|
+
remark = `${server}:${port}`;
|
|
4560
|
+
}
|
|
4561
|
+
hysteriaConstruct(node, {
|
|
4562
|
+
alpn,
|
|
4563
|
+
authStr: auth,
|
|
4564
|
+
downSpeed,
|
|
4565
|
+
group: DEFAULT_GROUPS.hysteria,
|
|
4566
|
+
obfs,
|
|
4567
|
+
obfsProtocol,
|
|
4568
|
+
port,
|
|
4569
|
+
protocol: protocol === "" ? "udp" : protocol,
|
|
4570
|
+
remark,
|
|
4571
|
+
scv: insecure === "" ? void 0 : parseTri(insecure),
|
|
4572
|
+
server,
|
|
4573
|
+
sni: sni === "" ? server : sni,
|
|
4574
|
+
upSpeed
|
|
4575
|
+
});
|
|
4576
|
+
}
|
|
4577
|
+
function explodeWireguard(link, node) {
|
|
4578
|
+
const normalized = link.replace(/^(wg|wireguard):\/\//, "wireguard://");
|
|
4579
|
+
let body = normalized.slice(13);
|
|
4580
|
+
let remark = "";
|
|
4581
|
+
let addition = "";
|
|
4582
|
+
const hashPos = body.lastIndexOf("#");
|
|
4583
|
+
if (hashPos !== -1) {
|
|
4584
|
+
remark = urlDecode(body.slice(hashPos + 1));
|
|
4585
|
+
body = body.slice(0, hashPos);
|
|
4586
|
+
}
|
|
4587
|
+
const qpos = body.lastIndexOf("?");
|
|
4588
|
+
if (qpos !== -1) {
|
|
4589
|
+
addition = body.slice(qpos + 1);
|
|
4590
|
+
body = body.slice(0, qpos);
|
|
4591
|
+
}
|
|
4592
|
+
const match = /^(?:(.*)@)?\[?(.*?)]?:(\d+)$/.exec(body);
|
|
4593
|
+
if (!match) {
|
|
4594
|
+
return;
|
|
4595
|
+
}
|
|
4596
|
+
const server = match[2];
|
|
4597
|
+
const port = match[3];
|
|
4598
|
+
if (server === "" || port === "0") {
|
|
4599
|
+
return;
|
|
4600
|
+
}
|
|
4601
|
+
const privateKey = getUrlArg(addition, "privateKey") || getUrlArg(addition, "privatekey");
|
|
4602
|
+
const publicKey = getUrlArg(addition, "publicKey") || getUrlArg(addition, "publickey");
|
|
4603
|
+
if (privateKey === "" || publicKey === "") {
|
|
4604
|
+
return;
|
|
4605
|
+
}
|
|
4606
|
+
const presharedKey = getUrlArg(addition, "presharedKey");
|
|
4607
|
+
const selfIp = getUrlArg(addition, "selfIP");
|
|
4608
|
+
const selfIpv6 = getUrlArg(addition, "selfIPv6");
|
|
4609
|
+
const mtu = getUrlArg(addition, "mtu");
|
|
4610
|
+
const keepAlive = getUrlArg(addition, "keepAlive");
|
|
4611
|
+
const dns = getUrlArg(addition, "dns");
|
|
4612
|
+
if (remark === "") {
|
|
4613
|
+
remark = `${server}:${port}`;
|
|
4614
|
+
}
|
|
4615
|
+
wireGuardConstruct(node, {
|
|
4616
|
+
dnsServers: dns === "" ? ["1.1.1.1"] : dns.split(",").map((s) => s.trim()),
|
|
4617
|
+
group: DEFAULT_GROUPS.wireguard,
|
|
4618
|
+
keepAlive: keepAlive === "" ? 25 : toInt(keepAlive),
|
|
4619
|
+
mtu: mtu === "" ? 1420 : toInt(mtu),
|
|
4620
|
+
port,
|
|
4621
|
+
preSharedKey: presharedKey,
|
|
4622
|
+
privateKey,
|
|
4623
|
+
publicKey,
|
|
4624
|
+
remark,
|
|
4625
|
+
selfIp: selfIp === "" ? "10.0.0.2" : selfIp,
|
|
4626
|
+
selfIpv6,
|
|
4627
|
+
server
|
|
4628
|
+
});
|
|
4629
|
+
}
|
|
4428
4630
|
function explodeVless(link, node) {
|
|
4429
4631
|
let body = link.slice(8);
|
|
4430
4632
|
let remark = "";
|
|
@@ -4548,6 +4750,12 @@ function explode(link, node) {
|
|
|
4548
4750
|
explodeVless(link, node);
|
|
4549
4751
|
} else if (startsWith(link, "tuic://")) {
|
|
4550
4752
|
explodeTuic(link, node);
|
|
4753
|
+
} else if (startsWith(link, "snell://")) {
|
|
4754
|
+
explodeSnell(link, node);
|
|
4755
|
+
} else if (startsWith(link, "hysteria://")) {
|
|
4756
|
+
explodeHysteria(link, node);
|
|
4757
|
+
} else if (startsWith(link, "wg://") || startsWith(link, "wireguard://")) {
|
|
4758
|
+
explodeWireguard(link, node);
|
|
4551
4759
|
} else if (link.includes("hysteria2://") || link.includes("hy2://")) {
|
|
4552
4760
|
explodeHysteria2(link, node);
|
|
4553
4761
|
} else if (startsWith(link, "anytls://")) {
|
|
@@ -5052,6 +5260,10 @@ function toRegex(pattern) {
|
|
|
5052
5260
|
function regFind(value, pattern) {
|
|
5053
5261
|
return toRegex(pattern).test(value);
|
|
5054
5262
|
}
|
|
5263
|
+
var REGEX_BLACKLIST = ["(.*)*"];
|
|
5264
|
+
function isBlacklistedPattern(pattern) {
|
|
5265
|
+
return REGEX_BLACKLIST.includes(pattern);
|
|
5266
|
+
}
|
|
5055
5267
|
function regMatch2(value, pattern) {
|
|
5056
5268
|
const match = toRegex(pattern).exec(value);
|
|
5057
5269
|
return match !== null && match[0] === value;
|
|
@@ -5423,12 +5635,59 @@ function stripBrackets(value) {
|
|
|
5423
5635
|
function toTri(value) {
|
|
5424
5636
|
return value;
|
|
5425
5637
|
}
|
|
5638
|
+
var MIHOMO_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
5639
|
+
"ss" /* Shadowsocks */,
|
|
5640
|
+
"ssr" /* ShadowsocksR */,
|
|
5641
|
+
"vmess" /* VMess */,
|
|
5642
|
+
"trojan" /* Trojan */,
|
|
5643
|
+
"snell" /* Snell */,
|
|
5644
|
+
"http" /* HTTP */,
|
|
5645
|
+
"https" /* HTTPS */,
|
|
5646
|
+
"socks5" /* SOCKS5 */,
|
|
5647
|
+
"wireguard" /* WireGuard */,
|
|
5648
|
+
"hysteria" /* Hysteria */,
|
|
5649
|
+
"hysteria2" /* Hysteria2 */,
|
|
5650
|
+
"vless" /* VLESS */,
|
|
5651
|
+
"anytls" /* AnyTLS */,
|
|
5652
|
+
"tuic" /* TUIC */
|
|
5653
|
+
]);
|
|
5654
|
+
var PREMIUM_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
5655
|
+
"ss" /* Shadowsocks */,
|
|
5656
|
+
"ssr" /* ShadowsocksR */,
|
|
5657
|
+
"vmess" /* VMess */,
|
|
5658
|
+
"trojan" /* Trojan */,
|
|
5659
|
+
"snell" /* Snell */,
|
|
5660
|
+
"http" /* HTTP */,
|
|
5661
|
+
"https" /* HTTPS */,
|
|
5662
|
+
"socks5" /* SOCKS5 */,
|
|
5663
|
+
"wireguard" /* WireGuard */
|
|
5664
|
+
]);
|
|
5665
|
+
var STASH_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
5666
|
+
...PREMIUM_PROTOCOLS,
|
|
5667
|
+
"hysteria" /* Hysteria */,
|
|
5668
|
+
"hysteria2" /* Hysteria2 */,
|
|
5669
|
+
"vless" /* VLESS */,
|
|
5670
|
+
"tuic" /* TUIC */
|
|
5671
|
+
]);
|
|
5672
|
+
function clashCapabilities(flavor) {
|
|
5673
|
+
if (flavor === "premium") {
|
|
5674
|
+
return { clientFingerprint: false, protocols: PREMIUM_PROTOCOLS, reality: false };
|
|
5675
|
+
}
|
|
5676
|
+
if (flavor === "stash") {
|
|
5677
|
+
return { clientFingerprint: false, protocols: STASH_PROTOCOLS, reality: true };
|
|
5678
|
+
}
|
|
5679
|
+
return { clientFingerprint: true, protocols: MIHOMO_PROTOCOLS, reality: true };
|
|
5680
|
+
}
|
|
5426
5681
|
function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
5427
5682
|
const proxy = {
|
|
5428
5683
|
name: remark,
|
|
5429
5684
|
port: x.port,
|
|
5430
5685
|
server: stripBrackets(x.hostname)
|
|
5431
5686
|
};
|
|
5687
|
+
const caps = clashCapabilities(settings.clashFlavor);
|
|
5688
|
+
if (!caps.protocols.has(x.type)) {
|
|
5689
|
+
return void 0;
|
|
5690
|
+
}
|
|
5432
5691
|
switch (x.type) {
|
|
5433
5692
|
case "ss" /* Shadowsocks */: {
|
|
5434
5693
|
if (settings.filterDeprecated && x.encryptMethod === "chacha20") {
|
|
@@ -5678,7 +5937,7 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5678
5937
|
if (skipCertVerify !== void 0) {
|
|
5679
5938
|
proxy["skip-cert-verify"] = skipCertVerify;
|
|
5680
5939
|
}
|
|
5681
|
-
if (x.fingerprint !== "") {
|
|
5940
|
+
if (x.fingerprint !== "" && caps.clientFingerprint) {
|
|
5682
5941
|
proxy.fingerprint = x.fingerprint;
|
|
5683
5942
|
}
|
|
5684
5943
|
if (x.alpn.length > 0) {
|
|
@@ -5733,7 +5992,7 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5733
5992
|
if (skipCertVerify !== void 0) {
|
|
5734
5993
|
proxy["skip-cert-verify"] = skipCertVerify;
|
|
5735
5994
|
}
|
|
5736
|
-
if (x.fingerprint !== "") {
|
|
5995
|
+
if (x.fingerprint !== "" && caps.clientFingerprint) {
|
|
5737
5996
|
proxy.fingerprint = x.fingerprint;
|
|
5738
5997
|
}
|
|
5739
5998
|
if (x.alpn.length > 0) {
|
|
@@ -5772,10 +6031,13 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5772
6031
|
if (x.serverName !== "") {
|
|
5773
6032
|
proxy.servername = x.serverName;
|
|
5774
6033
|
}
|
|
5775
|
-
if (x.fingerprint !== "") {
|
|
6034
|
+
if (x.fingerprint !== "" && caps.clientFingerprint) {
|
|
5776
6035
|
proxy["client-fingerprint"] = x.fingerprint;
|
|
5777
6036
|
}
|
|
5778
6037
|
if (x.publicKey !== "" || x.shortId !== "") {
|
|
6038
|
+
if (!caps.reality) {
|
|
6039
|
+
return void 0;
|
|
6040
|
+
}
|
|
5779
6041
|
const realityOpts = {};
|
|
5780
6042
|
if (x.publicKey !== "") {
|
|
5781
6043
|
realityOpts["public-key"] = x.publicKey;
|
|
@@ -7132,7 +7394,7 @@ function collectRuleLines(content, group2, noResolveOnly) {
|
|
|
7132
7394
|
}
|
|
7133
7395
|
return out;
|
|
7134
7396
|
}
|
|
7135
|
-
function rulesetToClashRules(rulesets) {
|
|
7397
|
+
function rulesetToClashRules(rulesets, classical = false) {
|
|
7136
7398
|
const rules = [];
|
|
7137
7399
|
for (const ruleset of rulesets) {
|
|
7138
7400
|
const content = ruleset.content;
|
|
@@ -7148,7 +7410,10 @@ function rulesetToClashRules(rulesets) {
|
|
|
7148
7410
|
rules.push(transformRuleToCommon(line, group2));
|
|
7149
7411
|
continue;
|
|
7150
7412
|
}
|
|
7151
|
-
const converted = convertRuleset(
|
|
7413
|
+
const converted = convertRuleset(
|
|
7414
|
+
content,
|
|
7415
|
+
classical && /^payload:\r?\n/.test(content) ? "clash-classical" /* ClashClassical */ : ruleset.ruleType
|
|
7416
|
+
);
|
|
7152
7417
|
for (const rawLine of converted.split(/\r?\n/)) {
|
|
7153
7418
|
let line = rawLine.trim();
|
|
7154
7419
|
if (!isRuleLine(line)) {
|
|
@@ -7165,7 +7430,7 @@ function rulesetToClashRules(rulesets) {
|
|
|
7165
7430
|
}
|
|
7166
7431
|
return rules;
|
|
7167
7432
|
}
|
|
7168
|
-
function rulesetToSurgeRules(rulesets, surgeVersion) {
|
|
7433
|
+
function rulesetToSurgeRules(rulesets, surgeVersion, expand = true) {
|
|
7169
7434
|
let section;
|
|
7170
7435
|
let allowed;
|
|
7171
7436
|
let noResolveOnly = false;
|
|
@@ -7203,6 +7468,17 @@ function rulesetToSurgeRules(rulesets, surgeVersion) {
|
|
|
7203
7468
|
continue;
|
|
7204
7469
|
}
|
|
7205
7470
|
const group2 = ruleset.ruleGroup;
|
|
7471
|
+
if (!expand && (surgeVersion > 2 || surgeVersion === -3)) {
|
|
7472
|
+
const { url } = parseRulesetSource(ruleset.rulePath);
|
|
7473
|
+
if (/^https?:\/\//i.test(url.trim()) && !ruleset.content.startsWith("[]")) {
|
|
7474
|
+
let line = `RULE-SET,${url.trim()},${group2}`;
|
|
7475
|
+
if (ruleset.updateInterval > 0) {
|
|
7476
|
+
line += `,update-interval=${ruleset.updateInterval}`;
|
|
7477
|
+
}
|
|
7478
|
+
lines.push(line);
|
|
7479
|
+
continue;
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7206
7482
|
if (ruleset.content.startsWith("[]")) {
|
|
7207
7483
|
let line = ruleset.content.slice(2);
|
|
7208
7484
|
if (line === "MATCH") {
|
|
@@ -7967,9 +8243,24 @@ function buildOutbound(x, settings, remark) {
|
|
|
7967
8243
|
proxy = out;
|
|
7968
8244
|
break;
|
|
7969
8245
|
}
|
|
7970
|
-
// sing-box has no
|
|
8246
|
+
// sing-box has no ShadowsocksR implementation (configs using it fail
|
|
8247
|
+
// at startup), so such nodes are dropped.
|
|
7971
8248
|
case "ssr" /* ShadowsocksR */:
|
|
7972
8249
|
return void 0;
|
|
8250
|
+
case "snell" /* Snell */: {
|
|
8251
|
+
const out = { ...common, psk: x.password, type: "snell" };
|
|
8252
|
+
if (x.snellVersion) {
|
|
8253
|
+
out.version = x.snellVersion;
|
|
8254
|
+
}
|
|
8255
|
+
if (x.obfs !== "" && x.obfs !== "none") {
|
|
8256
|
+
out.obfs_mode = x.obfs;
|
|
8257
|
+
}
|
|
8258
|
+
if (x.host !== "") {
|
|
8259
|
+
out.obfs_host = x.host;
|
|
8260
|
+
}
|
|
8261
|
+
proxy = out;
|
|
8262
|
+
break;
|
|
8263
|
+
}
|
|
7973
8264
|
case "vmess" /* VMess */: {
|
|
7974
8265
|
const out = {
|
|
7975
8266
|
...common,
|
|
@@ -8273,6 +8564,7 @@ function generate(nodes, options) {
|
|
|
8273
8564
|
runPreprocess(nodes, settings);
|
|
8274
8565
|
const groups = resolveGroups(options);
|
|
8275
8566
|
const rulesets = resolveRulesets(options, settings);
|
|
8567
|
+
const baseConf = applyBaseTemplate(options.baseConf ?? "", settings);
|
|
8276
8568
|
switch (options.target) {
|
|
8277
8569
|
case "clash" /* Clash */:
|
|
8278
8570
|
case "clashr" /* ClashR */: {
|
|
@@ -8282,9 +8574,9 @@ function generate(nodes, options) {
|
|
|
8282
8574
|
}
|
|
8283
8575
|
case "surge" /* Surge */: {
|
|
8284
8576
|
const surgeVersion = options.surgeVersion ?? 5;
|
|
8285
|
-
const rules = rulesets ? rulesetToSurgeRules(rulesets, surgeVersion) : void 0;
|
|
8577
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, surgeVersion, settings.expandRulesets) : void 0;
|
|
8286
8578
|
return toSurge(nodes, groups, settings, {
|
|
8287
|
-
baseConf
|
|
8579
|
+
baseConf,
|
|
8288
8580
|
nodeList: settings.nodeList,
|
|
8289
8581
|
rules,
|
|
8290
8582
|
version: surgeVersion
|
|
@@ -8293,7 +8585,7 @@ function generate(nodes, options) {
|
|
|
8293
8585
|
case "quanx" /* QuantumultX */: {
|
|
8294
8586
|
const rules = rulesets ? rulesetToSurgeRules(rulesets, -1) : void 0;
|
|
8295
8587
|
return toQuanX(nodes, groups, settings, {
|
|
8296
|
-
baseConf
|
|
8588
|
+
baseConf,
|
|
8297
8589
|
nodeList: settings.nodeList,
|
|
8298
8590
|
rules
|
|
8299
8591
|
});
|
|
@@ -8301,7 +8593,7 @@ function generate(nodes, options) {
|
|
|
8301
8593
|
case "quan" /* Quantumult */: {
|
|
8302
8594
|
const rules = rulesets ? rulesetToSurgeRules(rulesets, -2) : void 0;
|
|
8303
8595
|
return toQuan(nodes, groups, settings, {
|
|
8304
|
-
baseConf
|
|
8596
|
+
baseConf,
|
|
8305
8597
|
nodeList: settings.nodeList,
|
|
8306
8598
|
rules
|
|
8307
8599
|
});
|
|
@@ -8309,21 +8601,21 @@ function generate(nodes, options) {
|
|
|
8309
8601
|
case "loon" /* Loon */: {
|
|
8310
8602
|
const rules = rulesets ? rulesetToSurgeRules(rulesets, -4) : void 0;
|
|
8311
8603
|
return toLoon(nodes, groups, settings, {
|
|
8312
|
-
baseConf
|
|
8604
|
+
baseConf,
|
|
8313
8605
|
nodeList: settings.nodeList,
|
|
8314
8606
|
rules
|
|
8315
8607
|
});
|
|
8316
8608
|
}
|
|
8317
8609
|
case "singbox" /* SingBox */:
|
|
8318
8610
|
return toSingBox(nodes, groups, settings, {
|
|
8319
|
-
baseConf
|
|
8611
|
+
baseConf,
|
|
8320
8612
|
nodeList: settings.nodeList,
|
|
8321
8613
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
8322
8614
|
rulesets
|
|
8323
8615
|
});
|
|
8324
8616
|
case "mellow" /* Mellow */:
|
|
8325
8617
|
return toMellow(nodes, groups, settings, {
|
|
8326
|
-
baseConf
|
|
8618
|
+
baseConf,
|
|
8327
8619
|
nodeList: settings.nodeList,
|
|
8328
8620
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
8329
8621
|
rulesets
|
|
@@ -8341,11 +8633,11 @@ function generate(nodes, options) {
|
|
|
8341
8633
|
case "ssd" /* SSD */:
|
|
8342
8634
|
return proxyToSsd(nodes, "", "");
|
|
8343
8635
|
case "sssub" /* SSSub */:
|
|
8344
|
-
return proxyToSsSub(nodes,
|
|
8636
|
+
return proxyToSsSub(nodes, baseConf);
|
|
8345
8637
|
case "surfboard" /* Surfboard */: {
|
|
8346
|
-
const rules = rulesets ? rulesetToSurgeRules(rulesets, options.surgeVersion ?? 5) : void 0;
|
|
8638
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, options.surgeVersion ?? 5, settings.expandRulesets) : void 0;
|
|
8347
8639
|
return toSurfboard(nodes, groups, settings, {
|
|
8348
|
-
baseConf
|
|
8640
|
+
baseConf,
|
|
8349
8641
|
nodeList: settings.nodeList,
|
|
8350
8642
|
rules
|
|
8351
8643
|
});
|
|
@@ -8358,6 +8650,12 @@ function generate(nodes, options) {
|
|
|
8358
8650
|
throw new Error(`Unsupported target format: ${options.target}`);
|
|
8359
8651
|
}
|
|
8360
8652
|
}
|
|
8653
|
+
function applyBaseTemplate(baseConf, settings) {
|
|
8654
|
+
if (baseConf === "" || !hasTemplatePlaceholders(baseConf)) {
|
|
8655
|
+
return baseConf;
|
|
8656
|
+
}
|
|
8657
|
+
return renderTemplate(baseConf, settings.templateVars);
|
|
8658
|
+
}
|
|
8361
8659
|
function toSip008(nodes, baseConf = "") {
|
|
8362
8660
|
return proxyToSsSub(nodes, baseConf);
|
|
8363
8661
|
}
|
|
@@ -8387,7 +8685,7 @@ function attachClashRules(doc, settings, rulesets) {
|
|
|
8387
8685
|
return;
|
|
8388
8686
|
}
|
|
8389
8687
|
const field = settings.clashNewFieldName ? "rules" : "Rule";
|
|
8390
|
-
const generated = rulesetToClashRules(rulesets);
|
|
8688
|
+
const generated = rulesetToClashRules(rulesets, settings.clashClassicalRuleset);
|
|
8391
8689
|
if (generated.length === 0) {
|
|
8392
8690
|
return;
|
|
8393
8691
|
}
|
|
@@ -8405,6 +8703,8 @@ export {
|
|
|
8405
8703
|
ProxyGroupType,
|
|
8406
8704
|
ProxyType,
|
|
8407
8705
|
QUANX_RULE_TYPES,
|
|
8706
|
+
REGEX_BLACKLIST,
|
|
8707
|
+
RULESET_TYPE_PREFIXES,
|
|
8408
8708
|
RulesetType,
|
|
8409
8709
|
SING_BOX_RULE_TYPES,
|
|
8410
8710
|
SSR_CIPHERS,
|
|
@@ -8436,12 +8736,14 @@ export {
|
|
|
8436
8736
|
explodeClash,
|
|
8437
8737
|
explodeHttp,
|
|
8438
8738
|
explodeHttpSub,
|
|
8739
|
+
explodeHysteria,
|
|
8439
8740
|
explodeHysteria2,
|
|
8440
8741
|
explodeKitsunebi,
|
|
8441
8742
|
explodeNetch,
|
|
8442
8743
|
explodeNetchConf,
|
|
8443
8744
|
explodeQuan,
|
|
8444
8745
|
explodeShadowrocket,
|
|
8746
|
+
explodeSnell,
|
|
8445
8747
|
explodeSocks,
|
|
8446
8748
|
explodeSs,
|
|
8447
8749
|
explodeSsAndroid,
|
|
@@ -8458,6 +8760,7 @@ export {
|
|
|
8458
8760
|
explodeVless,
|
|
8459
8761
|
explodeVmess,
|
|
8460
8762
|
explodeVmessConf,
|
|
8763
|
+
explodeWireguard,
|
|
8461
8764
|
filterNodes,
|
|
8462
8765
|
filterNodesByCountry,
|
|
8463
8766
|
findSection,
|
|
@@ -8481,6 +8784,7 @@ export {
|
|
|
8481
8784
|
hysteria2Construct,
|
|
8482
8785
|
hysteriaConstruct,
|
|
8483
8786
|
inferUserinfoProviderFromUrl,
|
|
8787
|
+
isBlacklistedPattern,
|
|
8484
8788
|
isBlank,
|
|
8485
8789
|
isFlattenableSsr,
|
|
8486
8790
|
isIp,
|
|
@@ -8498,6 +8802,7 @@ export {
|
|
|
8498
8802
|
normalizeQueryKey,
|
|
8499
8803
|
normalizeUserinfoProvider,
|
|
8500
8804
|
pad2,
|
|
8805
|
+
parseClashFlavor,
|
|
8501
8806
|
parseClashText,
|
|
8502
8807
|
parseConfContent,
|
|
8503
8808
|
parseCustomProxyGroup,
|
|
@@ -8512,6 +8817,7 @@ export {
|
|
|
8512
8817
|
parseRegexMatch,
|
|
8513
8818
|
parseRequestSettings,
|
|
8514
8819
|
parseRulesetConfig,
|
|
8820
|
+
parseRulesetSource,
|
|
8515
8821
|
parseSubscription,
|
|
8516
8822
|
parseSubscriptionUserinfo,
|
|
8517
8823
|
parseTriBool,
|