@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.cjs
CHANGED
|
@@ -25,6 +25,8 @@ __export(index_exports, {
|
|
|
25
25
|
ProxyGroupType: () => ProxyGroupType,
|
|
26
26
|
ProxyType: () => ProxyType,
|
|
27
27
|
QUANX_RULE_TYPES: () => QUANX_RULE_TYPES,
|
|
28
|
+
REGEX_BLACKLIST: () => REGEX_BLACKLIST,
|
|
29
|
+
RULESET_TYPE_PREFIXES: () => RULESET_TYPE_PREFIXES,
|
|
28
30
|
RulesetType: () => RulesetType,
|
|
29
31
|
SING_BOX_RULE_TYPES: () => SING_BOX_RULE_TYPES,
|
|
30
32
|
SSR_CIPHERS: () => SSR_CIPHERS,
|
|
@@ -56,12 +58,14 @@ __export(index_exports, {
|
|
|
56
58
|
explodeClash: () => explodeClash,
|
|
57
59
|
explodeHttp: () => explodeHttp,
|
|
58
60
|
explodeHttpSub: () => explodeHttpSub,
|
|
61
|
+
explodeHysteria: () => explodeHysteria,
|
|
59
62
|
explodeHysteria2: () => explodeHysteria2,
|
|
60
63
|
explodeKitsunebi: () => explodeKitsunebi,
|
|
61
64
|
explodeNetch: () => explodeNetch,
|
|
62
65
|
explodeNetchConf: () => explodeNetchConf,
|
|
63
66
|
explodeQuan: () => explodeQuan,
|
|
64
67
|
explodeShadowrocket: () => explodeShadowrocket,
|
|
68
|
+
explodeSnell: () => explodeSnell,
|
|
65
69
|
explodeSocks: () => explodeSocks,
|
|
66
70
|
explodeSs: () => explodeSs,
|
|
67
71
|
explodeSsAndroid: () => explodeSsAndroid,
|
|
@@ -78,6 +82,7 @@ __export(index_exports, {
|
|
|
78
82
|
explodeVless: () => explodeVless,
|
|
79
83
|
explodeVmess: () => explodeVmess,
|
|
80
84
|
explodeVmessConf: () => explodeVmessConf,
|
|
85
|
+
explodeWireguard: () => explodeWireguard,
|
|
81
86
|
filterNodes: () => filterNodes,
|
|
82
87
|
filterNodesByCountry: () => filterNodesByCountry,
|
|
83
88
|
findSection: () => findSection,
|
|
@@ -101,6 +106,7 @@ __export(index_exports, {
|
|
|
101
106
|
hysteria2Construct: () => hysteria2Construct,
|
|
102
107
|
hysteriaConstruct: () => hysteriaConstruct,
|
|
103
108
|
inferUserinfoProviderFromUrl: () => inferUserinfoProviderFromUrl,
|
|
109
|
+
isBlacklistedPattern: () => isBlacklistedPattern,
|
|
104
110
|
isBlank: () => isBlank,
|
|
105
111
|
isFlattenableSsr: () => isFlattenableSsr,
|
|
106
112
|
isIp: () => isIp,
|
|
@@ -118,6 +124,7 @@ __export(index_exports, {
|
|
|
118
124
|
normalizeQueryKey: () => normalizeQueryKey,
|
|
119
125
|
normalizeUserinfoProvider: () => normalizeUserinfoProvider,
|
|
120
126
|
pad2: () => pad2,
|
|
127
|
+
parseClashFlavor: () => parseClashFlavor,
|
|
121
128
|
parseClashText: () => parseClashText,
|
|
122
129
|
parseConfContent: () => parseConfContent,
|
|
123
130
|
parseCustomProxyGroup: () => parseCustomProxyGroup,
|
|
@@ -132,6 +139,7 @@ __export(index_exports, {
|
|
|
132
139
|
parseRegexMatch: () => parseRegexMatch,
|
|
133
140
|
parseRequestSettings: () => parseRequestSettings,
|
|
134
141
|
parseRulesetConfig: () => parseRulesetConfig,
|
|
142
|
+
parseRulesetSource: () => parseRulesetSource,
|
|
135
143
|
parseSubscription: () => parseSubscription,
|
|
136
144
|
parseSubscriptionUserinfo: () => parseSubscriptionUserinfo,
|
|
137
145
|
parseTriBool: () => parseTriBool,
|
|
@@ -420,6 +428,16 @@ function createRulesetConfig() {
|
|
|
420
428
|
}
|
|
421
429
|
|
|
422
430
|
// src/types/settings.ts
|
|
431
|
+
function parseClashFlavor(value) {
|
|
432
|
+
const normalized = (value ?? "").trim().toLowerCase();
|
|
433
|
+
if (normalized === "premium" || normalized === "original" || normalized === "classic" || normalized === "clash") {
|
|
434
|
+
return "premium";
|
|
435
|
+
}
|
|
436
|
+
if (normalized === "stash") {
|
|
437
|
+
return "stash";
|
|
438
|
+
}
|
|
439
|
+
return "mihomo";
|
|
440
|
+
}
|
|
423
441
|
var TargetFormat = /* @__PURE__ */ ((TargetFormat2) => {
|
|
424
442
|
TargetFormat2["Clash"] = "clash";
|
|
425
443
|
TargetFormat2["ClashR"] = "clashr";
|
|
@@ -448,6 +466,7 @@ function createExtraSettings() {
|
|
|
448
466
|
authorized: false,
|
|
449
467
|
autoCountry: false,
|
|
450
468
|
clashClassicalRuleset: false,
|
|
469
|
+
clashFlavor: "mihomo",
|
|
451
470
|
clashNewFieldName: true,
|
|
452
471
|
clashProxiesStyle: "flow",
|
|
453
472
|
clashProxyGroupsStyle: "flow",
|
|
@@ -458,6 +477,7 @@ function createExtraSettings() {
|
|
|
458
477
|
enableRuleGenerator: true,
|
|
459
478
|
excludeCountries: [],
|
|
460
479
|
excludeRemarks: [],
|
|
480
|
+
expandRulesets: true,
|
|
461
481
|
filterDeprecated: false,
|
|
462
482
|
includeCountries: [],
|
|
463
483
|
includeRemarks: [],
|
|
@@ -473,6 +493,7 @@ function createExtraSettings() {
|
|
|
473
493
|
sortFlag: false,
|
|
474
494
|
sortScript: "",
|
|
475
495
|
surgeSsrPath: "",
|
|
496
|
+
templateVars: {},
|
|
476
497
|
tfo: void 0,
|
|
477
498
|
tls13: void 0,
|
|
478
499
|
udp: void 0
|
|
@@ -696,7 +717,7 @@ function toBool(value) {
|
|
|
696
717
|
return false;
|
|
697
718
|
}
|
|
698
719
|
const normalized = value.trim().toLowerCase();
|
|
699
|
-
return normalized === "true" || normalized === "1";
|
|
720
|
+
return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on";
|
|
700
721
|
}
|
|
701
722
|
function strFind(haystack, needle) {
|
|
702
723
|
return haystack.includes(needle);
|
|
@@ -845,6 +866,23 @@ function templateVariableNames(content) {
|
|
|
845
866
|
}
|
|
846
867
|
|
|
847
868
|
// src/settings/config.ts
|
|
869
|
+
var RULESET_TYPE_PREFIXES = [
|
|
870
|
+
["surge:", "surge" /* Surge */],
|
|
871
|
+
["quanx:", "quanx" /* QuantumultX */],
|
|
872
|
+
["quantumultx:", "quanx" /* QuantumultX */],
|
|
873
|
+
["clash-domain:", "clash-domain" /* ClashDomain */],
|
|
874
|
+
["clash-ipcidr:", "clash-ipcidr" /* ClashIpCidr */],
|
|
875
|
+
["clash-classic:", "clash-classical" /* ClashClassical */],
|
|
876
|
+
["clash:", "clash-classical" /* ClashClassical */]
|
|
877
|
+
];
|
|
878
|
+
function parseRulesetSource(source) {
|
|
879
|
+
for (const [prefix, type] of RULESET_TYPE_PREFIXES) {
|
|
880
|
+
if (source.toLowerCase().startsWith(prefix)) {
|
|
881
|
+
return { type, url: source.slice(prefix.length) };
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
return { url: source };
|
|
885
|
+
}
|
|
848
886
|
var GROUP_TYPE_MAP = {
|
|
849
887
|
fallback: "fallback" /* Fallback */,
|
|
850
888
|
"load-balance": "load-balance" /* LoadBalance */,
|
|
@@ -1129,12 +1167,16 @@ function createRequestSettings() {
|
|
|
1129
1167
|
appendType: false,
|
|
1130
1168
|
autoCountry: false,
|
|
1131
1169
|
autoExtract: false,
|
|
1170
|
+
clashFlavor: "mihomo",
|
|
1132
1171
|
clashScript: false,
|
|
1133
1172
|
classicalRuleset: false,
|
|
1134
1173
|
dedupe: false,
|
|
1174
|
+
devId: "",
|
|
1135
1175
|
emoji: [],
|
|
1136
1176
|
excludeCountries: [],
|
|
1137
1177
|
excludeRemarks: [],
|
|
1178
|
+
expand: true,
|
|
1179
|
+
filename: "",
|
|
1138
1180
|
filterDeprecated: false,
|
|
1139
1181
|
group: [],
|
|
1140
1182
|
includeCountries: [],
|
|
@@ -1155,6 +1197,7 @@ function createRequestSettings() {
|
|
|
1155
1197
|
script: "",
|
|
1156
1198
|
scv: void 0,
|
|
1157
1199
|
sort: false,
|
|
1200
|
+
strict: false,
|
|
1158
1201
|
target: "auto" /* Auto */,
|
|
1159
1202
|
tfo: void 0,
|
|
1160
1203
|
tls13: void 0,
|
|
@@ -1183,6 +1226,11 @@ function parseRequestSettings(query) {
|
|
|
1183
1226
|
settings.filterDeprecated = boolArg(query, "filter_deprecated");
|
|
1184
1227
|
settings.newFieldName = resolveNewFieldName(query);
|
|
1185
1228
|
settings.classicalRuleset = boolArg(query, "classical");
|
|
1229
|
+
settings.clashFlavor = parseClashFlavor(firstArg(query, "flavor"));
|
|
1230
|
+
settings.expand = queryBoolFlag(query, "expand") ?? true;
|
|
1231
|
+
settings.strict = boolArg(query, "strict");
|
|
1232
|
+
settings.filename = firstArg(query, "filename");
|
|
1233
|
+
settings.devId = firstArg(query, "dev_id", "dev-id", "device_id", "device-id");
|
|
1186
1234
|
settings.insert = getUrlArg(query, "insert") !== "";
|
|
1187
1235
|
settings.clashScript = boolArg(query, "clash_script");
|
|
1188
1236
|
settings.autoExtract = boolArg(query, "auto_extract");
|
|
@@ -2075,485 +2123,493 @@ function explodeClash(root, nodes) {
|
|
|
2075
2123
|
}
|
|
2076
2124
|
let index = nodes.length;
|
|
2077
2125
|
for (const single of list) {
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
const port = asString(get(single, "port"));
|
|
2082
|
-
let underlyingProxy = asString(get(single, "underlying-proxy"));
|
|
2083
|
-
if (underlyingProxy === "") {
|
|
2084
|
-
underlyingProxy = asString(get(single, "dialer-proxy"));
|
|
2085
|
-
}
|
|
2086
|
-
if (port === "" || port === "0") {
|
|
2087
|
-
continue;
|
|
2088
|
-
}
|
|
2089
|
-
const udp = asTri(get(single, "udp"));
|
|
2090
|
-
const tfo = asTri(get(single, "fast-open"));
|
|
2091
|
-
const scv = asTri(get(single, "skip-cert-verify"));
|
|
2092
|
-
const node = createProxy();
|
|
2093
|
-
let group2 = "";
|
|
2094
|
-
switch (proxyType) {
|
|
2095
|
-
case "vmess": {
|
|
2096
|
-
group2 = DEFAULT_GROUPS.v2ray;
|
|
2097
|
-
const id = asString(get(single, "uuid"));
|
|
2098
|
-
const aid = asString(get(single, "alterId"));
|
|
2099
|
-
const cipher = asString(get(single, "cipher"));
|
|
2100
|
-
const net = get(single, "network") !== void 0 ? asString(get(single, "network")) : "tcp";
|
|
2101
|
-
const sni = asString(get(single, "servername"));
|
|
2102
|
-
let path = "";
|
|
2103
|
-
let host = "";
|
|
2104
|
-
let edge = "";
|
|
2105
|
-
switch (net) {
|
|
2106
|
-
case "http":
|
|
2107
|
-
path = asString(get(get(get(single, "http-opts"), "path"), 0));
|
|
2108
|
-
host = asString(get(get(get(get(single, "http-opts"), "headers"), "Host"), 0));
|
|
2109
|
-
edge = "";
|
|
2110
|
-
break;
|
|
2111
|
-
case "ws":
|
|
2112
|
-
if (get(single, "ws-opts") !== void 0) {
|
|
2113
|
-
const wsOpts = get(single, "ws-opts");
|
|
2114
|
-
path = get(wsOpts, "path") !== void 0 ? asString(get(wsOpts, "path")) : "/";
|
|
2115
|
-
host = asString(get(get(wsOpts, "headers"), "Host"));
|
|
2116
|
-
edge = asString(get(get(wsOpts, "headers"), "Edge"));
|
|
2117
|
-
} else {
|
|
2118
|
-
path = get(single, "ws-path") !== void 0 ? asString(get(single, "ws-path")) : "/";
|
|
2119
|
-
host = asString(get(get(single, "ws-headers"), "Host"));
|
|
2120
|
-
edge = asString(get(get(single, "ws-headers"), "Edge"));
|
|
2121
|
-
}
|
|
2122
|
-
break;
|
|
2123
|
-
case "h2":
|
|
2124
|
-
path = asString(get(get(single, "h2-opts"), "path"));
|
|
2125
|
-
host = asString(get(get(get(single, "h2-opts"), "host"), 0));
|
|
2126
|
-
edge = "";
|
|
2127
|
-
break;
|
|
2128
|
-
case "grpc":
|
|
2129
|
-
host = asString(get(single, "servername"));
|
|
2130
|
-
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
2131
|
-
edge = "";
|
|
2132
|
-
break;
|
|
2133
|
-
default:
|
|
2134
|
-
break;
|
|
2135
|
-
}
|
|
2136
|
-
const tls = asBool(get(single, "tls")) ? "tls" : "";
|
|
2137
|
-
vmessConstruct(node, {
|
|
2138
|
-
add: server,
|
|
2139
|
-
aid,
|
|
2140
|
-
cipher,
|
|
2141
|
-
edge,
|
|
2142
|
-
group: group2,
|
|
2143
|
-
host,
|
|
2144
|
-
id,
|
|
2145
|
-
net,
|
|
2146
|
-
path,
|
|
2147
|
-
port,
|
|
2148
|
-
remark: ps,
|
|
2149
|
-
scv,
|
|
2150
|
-
sni,
|
|
2151
|
-
tfo,
|
|
2152
|
-
tls,
|
|
2153
|
-
type: "",
|
|
2154
|
-
udp,
|
|
2155
|
-
underlyingProxy
|
|
2156
|
-
});
|
|
2157
|
-
break;
|
|
2126
|
+
try {
|
|
2127
|
+
if (parseClashNode(single, nodes, index)) {
|
|
2128
|
+
index += 1;
|
|
2158
2129
|
}
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
if (
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2130
|
+
} catch {
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
function parseClashNode(single, nodes, index) {
|
|
2135
|
+
const proxyType = asString(get(single, "type")).toLowerCase();
|
|
2136
|
+
const ps = asString(get(single, "name"));
|
|
2137
|
+
const server = asString(get(single, "server"));
|
|
2138
|
+
const port = asString(get(single, "port"));
|
|
2139
|
+
let underlyingProxy = asString(get(single, "underlying-proxy"));
|
|
2140
|
+
if (underlyingProxy === "") {
|
|
2141
|
+
underlyingProxy = asString(get(single, "dialer-proxy"));
|
|
2142
|
+
}
|
|
2143
|
+
if (port === "" || port === "0") {
|
|
2144
|
+
return false;
|
|
2145
|
+
}
|
|
2146
|
+
const udp = asTri(get(single, "udp"));
|
|
2147
|
+
const tfo = asTri(get(single, "fast-open"));
|
|
2148
|
+
const scv = asTri(get(single, "skip-cert-verify"));
|
|
2149
|
+
const node = createProxy();
|
|
2150
|
+
let group2 = "";
|
|
2151
|
+
switch (proxyType) {
|
|
2152
|
+
case "vmess": {
|
|
2153
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2154
|
+
const id = asString(get(single, "uuid"));
|
|
2155
|
+
const aid = asString(get(single, "alterId"));
|
|
2156
|
+
const cipher = asString(get(single, "cipher"));
|
|
2157
|
+
const net = get(single, "network") !== void 0 ? asString(get(single, "network")) : "tcp";
|
|
2158
|
+
const sni = asString(get(single, "servername"));
|
|
2159
|
+
let path = "";
|
|
2160
|
+
let host = "";
|
|
2161
|
+
let edge = "";
|
|
2162
|
+
switch (net) {
|
|
2163
|
+
case "http":
|
|
2164
|
+
path = asString(get(get(get(single, "http-opts"), "path"), 0));
|
|
2165
|
+
host = asString(get(get(get(get(single, "http-opts"), "headers"), "Host"), 0));
|
|
2166
|
+
edge = "";
|
|
2167
|
+
break;
|
|
2168
|
+
case "ws":
|
|
2169
|
+
if (get(single, "ws-opts") !== void 0) {
|
|
2170
|
+
const wsOpts = get(single, "ws-opts");
|
|
2171
|
+
path = get(wsOpts, "path") !== void 0 ? asString(get(wsOpts, "path")) : "/";
|
|
2172
|
+
host = asString(get(get(wsOpts, "headers"), "Host"));
|
|
2173
|
+
edge = asString(get(get(wsOpts, "headers"), "Edge"));
|
|
2174
|
+
} else {
|
|
2175
|
+
path = get(single, "ws-path") !== void 0 ? asString(get(single, "ws-path")) : "/";
|
|
2176
|
+
host = asString(get(get(single, "ws-headers"), "Host"));
|
|
2177
|
+
edge = asString(get(get(single, "ws-headers"), "Edge"));
|
|
2203
2178
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
remark: ps,
|
|
2218
|
-
scv,
|
|
2219
|
-
server,
|
|
2220
|
-
tfo,
|
|
2221
|
-
udp,
|
|
2222
|
-
underlyingProxy
|
|
2223
|
-
});
|
|
2224
|
-
break;
|
|
2225
|
-
}
|
|
2226
|
-
case "socks5": {
|
|
2227
|
-
group2 = DEFAULT_GROUPS.socks;
|
|
2228
|
-
const user = asString(get(single, "username"));
|
|
2229
|
-
const password = asString(get(single, "password"));
|
|
2230
|
-
socksConstruct(node, {
|
|
2231
|
-
group: group2,
|
|
2232
|
-
password,
|
|
2233
|
-
port,
|
|
2234
|
-
remark: ps,
|
|
2235
|
-
server,
|
|
2236
|
-
underlyingProxy,
|
|
2237
|
-
username: user
|
|
2238
|
-
});
|
|
2239
|
-
break;
|
|
2240
|
-
}
|
|
2241
|
-
case "ssr": {
|
|
2242
|
-
group2 = DEFAULT_GROUPS.ssr;
|
|
2243
|
-
let cipher = asString(get(single, "cipher"));
|
|
2244
|
-
if (cipher === "dummy") {
|
|
2245
|
-
cipher = "none";
|
|
2246
|
-
}
|
|
2247
|
-
const password = asString(get(single, "password"));
|
|
2248
|
-
const protocol = asString(get(single, "protocol"));
|
|
2249
|
-
const obfs = asString(get(single, "obfs"));
|
|
2250
|
-
const protocolParam = get(single, "protocol-param") !== void 0 ? asString(get(single, "protocol-param")) : asString(get(single, "protocolparam"));
|
|
2251
|
-
const obfsParam = get(single, "obfs-param") !== void 0 ? asString(get(single, "obfs-param")) : asString(get(single, "obfsparam"));
|
|
2252
|
-
ssrConstruct(node, {
|
|
2253
|
-
group: group2,
|
|
2254
|
-
method: cipher,
|
|
2255
|
-
obfs,
|
|
2256
|
-
obfsParam,
|
|
2257
|
-
password,
|
|
2258
|
-
port,
|
|
2259
|
-
protocol,
|
|
2260
|
-
protocolParam,
|
|
2261
|
-
remark: ps,
|
|
2262
|
-
scv,
|
|
2263
|
-
server,
|
|
2264
|
-
tfo,
|
|
2265
|
-
udp,
|
|
2266
|
-
underlyingProxy
|
|
2267
|
-
});
|
|
2268
|
-
break;
|
|
2269
|
-
}
|
|
2270
|
-
case "http": {
|
|
2271
|
-
group2 = DEFAULT_GROUPS.http;
|
|
2272
|
-
const user = asString(get(single, "username"));
|
|
2273
|
-
const password = asString(get(single, "password"));
|
|
2274
|
-
const tls = asString(get(single, "tls"));
|
|
2275
|
-
httpConstruct(node, {
|
|
2276
|
-
group: group2,
|
|
2277
|
-
password,
|
|
2278
|
-
port,
|
|
2279
|
-
remark: ps,
|
|
2280
|
-
scv,
|
|
2281
|
-
server,
|
|
2282
|
-
tfo,
|
|
2283
|
-
tls: tls === "true",
|
|
2284
|
-
underlyingProxy,
|
|
2285
|
-
username: user
|
|
2286
|
-
});
|
|
2287
|
-
break;
|
|
2179
|
+
break;
|
|
2180
|
+
case "h2":
|
|
2181
|
+
path = asString(get(get(single, "h2-opts"), "path"));
|
|
2182
|
+
host = asString(get(get(get(single, "h2-opts"), "host"), 0));
|
|
2183
|
+
edge = "";
|
|
2184
|
+
break;
|
|
2185
|
+
case "grpc":
|
|
2186
|
+
host = asString(get(single, "servername"));
|
|
2187
|
+
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
2188
|
+
edge = "";
|
|
2189
|
+
break;
|
|
2190
|
+
default:
|
|
2191
|
+
break;
|
|
2288
2192
|
}
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2193
|
+
const tls = asBool(get(single, "tls")) ? "tls" : "";
|
|
2194
|
+
vmessConstruct(node, {
|
|
2195
|
+
add: server,
|
|
2196
|
+
aid,
|
|
2197
|
+
cipher,
|
|
2198
|
+
edge,
|
|
2199
|
+
group: group2,
|
|
2200
|
+
host,
|
|
2201
|
+
id,
|
|
2202
|
+
net,
|
|
2203
|
+
path,
|
|
2204
|
+
port,
|
|
2205
|
+
remark: ps,
|
|
2206
|
+
scv,
|
|
2207
|
+
sni,
|
|
2208
|
+
tfo,
|
|
2209
|
+
tls,
|
|
2210
|
+
type: "",
|
|
2211
|
+
udp,
|
|
2212
|
+
underlyingProxy
|
|
2213
|
+
});
|
|
2214
|
+
break;
|
|
2215
|
+
}
|
|
2216
|
+
case "ss": {
|
|
2217
|
+
group2 = DEFAULT_GROUPS.ss;
|
|
2218
|
+
let cipher = asString(get(single, "cipher"));
|
|
2219
|
+
const password = asString(get(single, "password"));
|
|
2220
|
+
let plugin = "";
|
|
2221
|
+
let pluginOption = "";
|
|
2222
|
+
let pluginMode = "";
|
|
2223
|
+
let pluginHost = "";
|
|
2224
|
+
let pluginMux = "";
|
|
2225
|
+
let pluginTls = "";
|
|
2226
|
+
let path = "";
|
|
2227
|
+
if (get(single, "plugin") !== void 0) {
|
|
2228
|
+
const pluginName = asString(get(single, "plugin")).toLowerCase();
|
|
2229
|
+
const pluginOpts = get(single, "plugin-opts");
|
|
2230
|
+
if (pluginName === "obfs") {
|
|
2231
|
+
plugin = "obfs-local";
|
|
2232
|
+
pluginMode = asString(get(pluginOpts, "mode"));
|
|
2233
|
+
pluginHost = asString(get(pluginOpts, "host"));
|
|
2234
|
+
} else if (pluginName === "v2ray-plugin") {
|
|
2235
|
+
plugin = "v2ray-plugin";
|
|
2236
|
+
pluginMode = asString(get(pluginOpts, "mode"));
|
|
2237
|
+
pluginHost = asString(get(pluginOpts, "host"));
|
|
2238
|
+
pluginTls = asBool(get(pluginOpts, "tls")) ? "tls;" : "";
|
|
2239
|
+
path = asString(get(pluginOpts, "path"));
|
|
2240
|
+
pluginMux = asBool(get(pluginOpts, "mux")) ? "mux=4;" : "";
|
|
2306
2241
|
}
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
udp,
|
|
2320
|
-
underlyingProxy
|
|
2321
|
-
});
|
|
2322
|
-
break;
|
|
2323
|
-
}
|
|
2324
|
-
case "snell": {
|
|
2325
|
-
group2 = DEFAULT_GROUPS.snell;
|
|
2326
|
-
const password = asString(get(single, "psk"));
|
|
2327
|
-
const obfs = asString(get(get(single, "obfs-opts"), "mode"));
|
|
2328
|
-
const host = asString(get(get(single, "obfs-opts"), "host"));
|
|
2329
|
-
const version = asString(get(single, "version"));
|
|
2330
|
-
snellConstruct(node, {
|
|
2331
|
-
group: group2,
|
|
2332
|
-
host,
|
|
2333
|
-
obfs,
|
|
2334
|
-
password,
|
|
2335
|
-
port,
|
|
2336
|
-
remark: ps,
|
|
2337
|
-
scv,
|
|
2338
|
-
server,
|
|
2339
|
-
tfo,
|
|
2340
|
-
udp,
|
|
2341
|
-
underlyingProxy,
|
|
2342
|
-
version: toInt(version)
|
|
2343
|
-
});
|
|
2344
|
-
break;
|
|
2345
|
-
}
|
|
2346
|
-
case "wireguard": {
|
|
2347
|
-
group2 = DEFAULT_GROUPS.wireguard;
|
|
2348
|
-
const publicKey = asString(get(single, "public-key"));
|
|
2349
|
-
const privateKey = asString(get(single, "private-key"));
|
|
2350
|
-
const dns = get(single, "dns");
|
|
2351
|
-
const dnsServers = Array.isArray(dns) ? dns.map((d) => String(d)) : dns ? [String(dns)] : [];
|
|
2352
|
-
const mtu = asString(get(single, "mtu"));
|
|
2353
|
-
const psk = asString(get(single, "preshared-key"));
|
|
2354
|
-
const ip = asString(get(single, "ip"));
|
|
2355
|
-
const ipv6 = asString(get(single, "ipv6"));
|
|
2356
|
-
wireGuardConstruct(node, {
|
|
2357
|
-
dnsServers,
|
|
2358
|
-
group: group2,
|
|
2359
|
-
keepAlive: "0",
|
|
2360
|
-
mtu,
|
|
2361
|
-
port,
|
|
2362
|
-
preSharedKey: psk,
|
|
2363
|
-
privateKey,
|
|
2364
|
-
publicKey,
|
|
2365
|
-
remark: ps,
|
|
2366
|
-
selfIp: ip,
|
|
2367
|
-
selfIpv6: ipv6,
|
|
2368
|
-
server,
|
|
2369
|
-
testUrl: "",
|
|
2370
|
-
udp,
|
|
2371
|
-
underlyingProxy
|
|
2372
|
-
});
|
|
2373
|
-
break;
|
|
2374
|
-
}
|
|
2375
|
-
case "hysteria": {
|
|
2376
|
-
group2 = DEFAULT_GROUPS.hysteria;
|
|
2377
|
-
const ports = asString(get(single, "ports"));
|
|
2378
|
-
const protocol = asString(get(single, "protocol"));
|
|
2379
|
-
const obfsProtocol = asString(get(single, "obfs-protocol"));
|
|
2380
|
-
const up = asString(get(single, "up"));
|
|
2381
|
-
const upSpeed = asString(get(single, "up-speed"));
|
|
2382
|
-
const down = asString(get(single, "down"));
|
|
2383
|
-
const downSpeed = asString(get(single, "down-speed"));
|
|
2384
|
-
const auth = asString(get(single, "auth"));
|
|
2385
|
-
let authStr = asString(get(single, "auth-str"));
|
|
2386
|
-
if (authStr === "") {
|
|
2387
|
-
authStr = asString(get(single, "auth_str"));
|
|
2242
|
+
} else if (get(single, "obfs") !== void 0) {
|
|
2243
|
+
plugin = "obfs-local";
|
|
2244
|
+
pluginMode = asString(get(single, "obfs"));
|
|
2245
|
+
pluginHost = asString(get(single, "obfs-host"));
|
|
2246
|
+
}
|
|
2247
|
+
if (plugin === "simple-obfs" || plugin === "obfs-local") {
|
|
2248
|
+
pluginOption = `obfs=${pluginMode}`;
|
|
2249
|
+
pluginOption += pluginHost === "" ? "" : `;obfs-host=${pluginHost}`;
|
|
2250
|
+
} else if (plugin === "v2ray-plugin") {
|
|
2251
|
+
pluginOption = `mode=${pluginMode};${pluginTls}${pluginMux}`;
|
|
2252
|
+
if (pluginHost !== "") {
|
|
2253
|
+
pluginOption += `host=${pluginHost};`;
|
|
2388
2254
|
}
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
const fingerprint = asString(get(single, "fingerprint"));
|
|
2392
|
-
const alpnValue = get(single, "alpn");
|
|
2393
|
-
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2394
|
-
const ca = asString(get(single, "ca"));
|
|
2395
|
-
const caStr = asString(get(single, "ca-str"));
|
|
2396
|
-
const recvWindowConn = asString(get(single, "recv-window-conn"));
|
|
2397
|
-
const recvWindow = asString(get(single, "recv-window"));
|
|
2398
|
-
let disableMtuDiscovery = asString(get(single, "disable-mtu-discovery"));
|
|
2399
|
-
if (disableMtuDiscovery === "") {
|
|
2400
|
-
disableMtuDiscovery = asString(get(single, "disable_mtu_discovery"));
|
|
2255
|
+
if (path !== "") {
|
|
2256
|
+
pluginOption += `path=${path};`;
|
|
2401
2257
|
}
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
alpn,
|
|
2405
|
-
auth,
|
|
2406
|
-
authStr,
|
|
2407
|
-
ca,
|
|
2408
|
-
caStr,
|
|
2409
|
-
disableMtuDiscovery,
|
|
2410
|
-
down,
|
|
2411
|
-
downSpeed,
|
|
2412
|
-
fingerprint,
|
|
2413
|
-
group: group2,
|
|
2414
|
-
hopInterval,
|
|
2415
|
-
obfs,
|
|
2416
|
-
obfsProtocol,
|
|
2417
|
-
port,
|
|
2418
|
-
ports,
|
|
2419
|
-
protocol,
|
|
2420
|
-
recvWindow,
|
|
2421
|
-
recvWindowConn,
|
|
2422
|
-
remark: ps,
|
|
2423
|
-
scv,
|
|
2424
|
-
server,
|
|
2425
|
-
sni,
|
|
2426
|
-
tfo,
|
|
2427
|
-
underlyingProxy,
|
|
2428
|
-
up,
|
|
2429
|
-
upSpeed
|
|
2430
|
-
});
|
|
2431
|
-
break;
|
|
2432
|
-
}
|
|
2433
|
-
case "hysteria2": {
|
|
2434
|
-
group2 = DEFAULT_GROUPS.hysteria2;
|
|
2435
|
-
const ports = asString(get(single, "ports"));
|
|
2436
|
-
const up = asString(get(single, "up"));
|
|
2437
|
-
const down = asString(get(single, "down"));
|
|
2438
|
-
let password = asString(get(single, "password"));
|
|
2439
|
-
if (password === "") {
|
|
2440
|
-
password = asString(get(single, "auth"));
|
|
2258
|
+
if (pluginMux !== "") {
|
|
2259
|
+
pluginOption += `mux=${pluginMux};`;
|
|
2441
2260
|
}
|
|
2442
|
-
const obfs = asString(get(single, "obfs"));
|
|
2443
|
-
const obfsPassword = asString(get(single, "obfs-password"));
|
|
2444
|
-
const sni = asString(get(single, "sni"));
|
|
2445
|
-
const fingerprint = asString(get(single, "fingerprint"));
|
|
2446
|
-
const alpnValue = get(single, "alpn");
|
|
2447
|
-
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2448
|
-
const ca = asString(get(single, "ca"));
|
|
2449
|
-
const caStr = asString(get(single, "ca-str"));
|
|
2450
|
-
const cwnd = asString(get(single, "cwnd"));
|
|
2451
|
-
const hopInterval = asString(get(single, "hop-interval"));
|
|
2452
|
-
hysteria2Construct(node, {
|
|
2453
|
-
alpn,
|
|
2454
|
-
ca,
|
|
2455
|
-
caStr,
|
|
2456
|
-
cwnd,
|
|
2457
|
-
down,
|
|
2458
|
-
fingerprint,
|
|
2459
|
-
group: group2,
|
|
2460
|
-
hopInterval,
|
|
2461
|
-
obfs,
|
|
2462
|
-
obfsPassword,
|
|
2463
|
-
password,
|
|
2464
|
-
port,
|
|
2465
|
-
ports,
|
|
2466
|
-
remark: ps,
|
|
2467
|
-
scv,
|
|
2468
|
-
server,
|
|
2469
|
-
sni,
|
|
2470
|
-
tfo,
|
|
2471
|
-
underlyingProxy,
|
|
2472
|
-
up
|
|
2473
|
-
});
|
|
2474
|
-
break;
|
|
2475
2261
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
anyTlsConstruct(node, {
|
|
2481
|
-
group: group2,
|
|
2482
|
-
password,
|
|
2483
|
-
port,
|
|
2484
|
-
remark: ps,
|
|
2485
|
-
scv,
|
|
2486
|
-
server,
|
|
2487
|
-
sni,
|
|
2488
|
-
tfo,
|
|
2489
|
-
udp,
|
|
2490
|
-
underlyingProxy
|
|
2491
|
-
});
|
|
2492
|
-
break;
|
|
2262
|
+
if (cipher === "AEAD_CHACHA20_POLY1305") {
|
|
2263
|
+
cipher = "chacha20-ietf-poly1305";
|
|
2264
|
+
} else if (cipher.includes("AEAD")) {
|
|
2265
|
+
cipher = cipher.replace(/AEAD_/g, "").replace(/_/g, "-").toLowerCase();
|
|
2493
2266
|
}
|
|
2494
|
-
|
|
2495
|
-
group2
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2267
|
+
ssConstruct(node, {
|
|
2268
|
+
group: group2,
|
|
2269
|
+
method: cipher,
|
|
2270
|
+
password,
|
|
2271
|
+
plugin,
|
|
2272
|
+
pluginOption,
|
|
2273
|
+
port,
|
|
2274
|
+
remark: ps,
|
|
2275
|
+
scv,
|
|
2276
|
+
server,
|
|
2277
|
+
tfo,
|
|
2278
|
+
udp,
|
|
2279
|
+
underlyingProxy
|
|
2280
|
+
});
|
|
2281
|
+
break;
|
|
2282
|
+
}
|
|
2283
|
+
case "socks5": {
|
|
2284
|
+
group2 = DEFAULT_GROUPS.socks;
|
|
2285
|
+
const user = asString(get(single, "username"));
|
|
2286
|
+
const password = asString(get(single, "password"));
|
|
2287
|
+
socksConstruct(node, {
|
|
2288
|
+
group: group2,
|
|
2289
|
+
password,
|
|
2290
|
+
port,
|
|
2291
|
+
remark: ps,
|
|
2292
|
+
server,
|
|
2293
|
+
underlyingProxy,
|
|
2294
|
+
username: user
|
|
2295
|
+
});
|
|
2296
|
+
break;
|
|
2297
|
+
}
|
|
2298
|
+
case "ssr": {
|
|
2299
|
+
group2 = DEFAULT_GROUPS.ssr;
|
|
2300
|
+
let cipher = asString(get(single, "cipher"));
|
|
2301
|
+
if (cipher === "dummy") {
|
|
2302
|
+
cipher = "none";
|
|
2303
|
+
}
|
|
2304
|
+
const password = asString(get(single, "password"));
|
|
2305
|
+
const protocol = asString(get(single, "protocol"));
|
|
2306
|
+
const obfs = asString(get(single, "obfs"));
|
|
2307
|
+
const protocolParam = get(single, "protocol-param") !== void 0 ? asString(get(single, "protocol-param")) : asString(get(single, "protocolparam"));
|
|
2308
|
+
const obfsParam = get(single, "obfs-param") !== void 0 ? asString(get(single, "obfs-param")) : asString(get(single, "obfsparam"));
|
|
2309
|
+
ssrConstruct(node, {
|
|
2310
|
+
group: group2,
|
|
2311
|
+
method: cipher,
|
|
2312
|
+
obfs,
|
|
2313
|
+
obfsParam,
|
|
2314
|
+
password,
|
|
2315
|
+
port,
|
|
2316
|
+
protocol,
|
|
2317
|
+
protocolParam,
|
|
2318
|
+
remark: ps,
|
|
2319
|
+
scv,
|
|
2320
|
+
server,
|
|
2321
|
+
tfo,
|
|
2322
|
+
udp,
|
|
2323
|
+
underlyingProxy
|
|
2324
|
+
});
|
|
2325
|
+
break;
|
|
2326
|
+
}
|
|
2327
|
+
case "http": {
|
|
2328
|
+
group2 = DEFAULT_GROUPS.http;
|
|
2329
|
+
const user = asString(get(single, "username"));
|
|
2330
|
+
const password = asString(get(single, "password"));
|
|
2331
|
+
const tls = asString(get(single, "tls"));
|
|
2332
|
+
httpConstruct(node, {
|
|
2333
|
+
group: group2,
|
|
2334
|
+
password,
|
|
2335
|
+
port,
|
|
2336
|
+
remark: ps,
|
|
2337
|
+
scv,
|
|
2338
|
+
server,
|
|
2339
|
+
tfo,
|
|
2340
|
+
tls: tls === "true",
|
|
2341
|
+
underlyingProxy,
|
|
2342
|
+
username: user
|
|
2343
|
+
});
|
|
2344
|
+
break;
|
|
2345
|
+
}
|
|
2346
|
+
case "trojan": {
|
|
2347
|
+
group2 = DEFAULT_GROUPS.trojan;
|
|
2348
|
+
const password = asString(get(single, "password"));
|
|
2349
|
+
const host = asString(get(single, "sni"));
|
|
2350
|
+
let net = asString(get(single, "network"));
|
|
2351
|
+
let path = "";
|
|
2352
|
+
switch (net) {
|
|
2353
|
+
case "grpc":
|
|
2505
2354
|
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
host,
|
|
2515
|
-
network: net,
|
|
2516
|
-
path,
|
|
2517
|
-
port,
|
|
2518
|
-
remark: ps,
|
|
2519
|
-
scv,
|
|
2520
|
-
server,
|
|
2521
|
-
sni: asString(get(single, "servername")),
|
|
2522
|
-
tfo,
|
|
2523
|
-
tls: tls === "true" ? "tls" : "",
|
|
2524
|
-
udp,
|
|
2525
|
-
underlyingProxy,
|
|
2526
|
-
userId
|
|
2527
|
-
});
|
|
2528
|
-
break;
|
|
2529
|
-
}
|
|
2530
|
-
case "tuic": {
|
|
2531
|
-
group2 = DEFAULT_GROUPS.v2ray;
|
|
2532
|
-
const alpnValue = get(single, "alpn");
|
|
2533
|
-
tuicConstruct(node, {
|
|
2534
|
-
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2535
|
-
congestionControl: asString(get(single, "congestion-controller")),
|
|
2536
|
-
group: group2,
|
|
2537
|
-
password: asString(get(single, "password")),
|
|
2538
|
-
port,
|
|
2539
|
-
remark: ps,
|
|
2540
|
-
scv,
|
|
2541
|
-
server,
|
|
2542
|
-
sni: asString(get(single, "sni")),
|
|
2543
|
-
tfo,
|
|
2544
|
-
udp,
|
|
2545
|
-
underlyingProxy,
|
|
2546
|
-
userId: asString(get(single, "uuid"))
|
|
2547
|
-
});
|
|
2548
|
-
break;
|
|
2355
|
+
break;
|
|
2356
|
+
case "ws":
|
|
2357
|
+
path = asString(get(get(single, "ws-opts"), "path"));
|
|
2358
|
+
break;
|
|
2359
|
+
default:
|
|
2360
|
+
net = "tcp";
|
|
2361
|
+
path = "";
|
|
2362
|
+
break;
|
|
2549
2363
|
}
|
|
2550
|
-
|
|
2551
|
-
|
|
2364
|
+
trojanConstruct(node, {
|
|
2365
|
+
group: group2,
|
|
2366
|
+
host,
|
|
2367
|
+
network: net,
|
|
2368
|
+
password,
|
|
2369
|
+
path,
|
|
2370
|
+
port,
|
|
2371
|
+
remark: ps,
|
|
2372
|
+
scv,
|
|
2373
|
+
server,
|
|
2374
|
+
tfo,
|
|
2375
|
+
tlsSecure: true,
|
|
2376
|
+
udp,
|
|
2377
|
+
underlyingProxy
|
|
2378
|
+
});
|
|
2379
|
+
break;
|
|
2552
2380
|
}
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2381
|
+
case "snell": {
|
|
2382
|
+
group2 = DEFAULT_GROUPS.snell;
|
|
2383
|
+
const password = asString(get(single, "psk"));
|
|
2384
|
+
const obfs = asString(get(get(single, "obfs-opts"), "mode"));
|
|
2385
|
+
const host = asString(get(get(single, "obfs-opts"), "host"));
|
|
2386
|
+
const version = asString(get(single, "version"));
|
|
2387
|
+
snellConstruct(node, {
|
|
2388
|
+
group: group2,
|
|
2389
|
+
host,
|
|
2390
|
+
obfs,
|
|
2391
|
+
password,
|
|
2392
|
+
port,
|
|
2393
|
+
remark: ps,
|
|
2394
|
+
scv,
|
|
2395
|
+
server,
|
|
2396
|
+
tfo,
|
|
2397
|
+
udp,
|
|
2398
|
+
underlyingProxy,
|
|
2399
|
+
version: toInt(version)
|
|
2400
|
+
});
|
|
2401
|
+
break;
|
|
2402
|
+
}
|
|
2403
|
+
case "wireguard": {
|
|
2404
|
+
group2 = DEFAULT_GROUPS.wireguard;
|
|
2405
|
+
const publicKey = asString(get(single, "public-key"));
|
|
2406
|
+
const privateKey = asString(get(single, "private-key"));
|
|
2407
|
+
const dns = get(single, "dns");
|
|
2408
|
+
const dnsServers = Array.isArray(dns) ? dns.map((d) => String(d)) : dns ? [String(dns)] : [];
|
|
2409
|
+
const mtu = asString(get(single, "mtu"));
|
|
2410
|
+
const psk = asString(get(single, "preshared-key"));
|
|
2411
|
+
const ip = asString(get(single, "ip"));
|
|
2412
|
+
const ipv6 = asString(get(single, "ipv6"));
|
|
2413
|
+
wireGuardConstruct(node, {
|
|
2414
|
+
dnsServers,
|
|
2415
|
+
group: group2,
|
|
2416
|
+
keepAlive: "0",
|
|
2417
|
+
mtu,
|
|
2418
|
+
port,
|
|
2419
|
+
preSharedKey: psk,
|
|
2420
|
+
privateKey,
|
|
2421
|
+
publicKey,
|
|
2422
|
+
remark: ps,
|
|
2423
|
+
selfIp: ip,
|
|
2424
|
+
selfIpv6: ipv6,
|
|
2425
|
+
server,
|
|
2426
|
+
testUrl: "",
|
|
2427
|
+
udp,
|
|
2428
|
+
underlyingProxy
|
|
2429
|
+
});
|
|
2430
|
+
break;
|
|
2431
|
+
}
|
|
2432
|
+
case "hysteria": {
|
|
2433
|
+
group2 = DEFAULT_GROUPS.hysteria;
|
|
2434
|
+
const ports = asString(get(single, "ports"));
|
|
2435
|
+
const protocol = asString(get(single, "protocol"));
|
|
2436
|
+
const obfsProtocol = asString(get(single, "obfs-protocol"));
|
|
2437
|
+
const up = asString(get(single, "up"));
|
|
2438
|
+
const upSpeed = asString(get(single, "up-speed"));
|
|
2439
|
+
const down = asString(get(single, "down"));
|
|
2440
|
+
const downSpeed = asString(get(single, "down-speed"));
|
|
2441
|
+
const auth = asString(get(single, "auth"));
|
|
2442
|
+
let authStr = asString(get(single, "auth-str"));
|
|
2443
|
+
if (authStr === "") {
|
|
2444
|
+
authStr = asString(get(single, "auth_str"));
|
|
2445
|
+
}
|
|
2446
|
+
const obfs = asString(get(single, "obfs"));
|
|
2447
|
+
const sni = asString(get(single, "sni"));
|
|
2448
|
+
const fingerprint = asString(get(single, "fingerprint"));
|
|
2449
|
+
const alpnValue = get(single, "alpn");
|
|
2450
|
+
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2451
|
+
const ca = asString(get(single, "ca"));
|
|
2452
|
+
const caStr = asString(get(single, "ca-str"));
|
|
2453
|
+
const recvWindowConn = asString(get(single, "recv-window-conn"));
|
|
2454
|
+
const recvWindow = asString(get(single, "recv-window"));
|
|
2455
|
+
let disableMtuDiscovery = asString(get(single, "disable-mtu-discovery"));
|
|
2456
|
+
if (disableMtuDiscovery === "") {
|
|
2457
|
+
disableMtuDiscovery = asString(get(single, "disable_mtu_discovery"));
|
|
2458
|
+
}
|
|
2459
|
+
const hopInterval = asString(get(single, "hop-interval"));
|
|
2460
|
+
hysteriaConstruct(node, {
|
|
2461
|
+
alpn,
|
|
2462
|
+
auth,
|
|
2463
|
+
authStr,
|
|
2464
|
+
ca,
|
|
2465
|
+
caStr,
|
|
2466
|
+
disableMtuDiscovery,
|
|
2467
|
+
down,
|
|
2468
|
+
downSpeed,
|
|
2469
|
+
fingerprint,
|
|
2470
|
+
group: group2,
|
|
2471
|
+
hopInterval,
|
|
2472
|
+
obfs,
|
|
2473
|
+
obfsProtocol,
|
|
2474
|
+
port,
|
|
2475
|
+
ports,
|
|
2476
|
+
protocol,
|
|
2477
|
+
recvWindow,
|
|
2478
|
+
recvWindowConn,
|
|
2479
|
+
remark: ps,
|
|
2480
|
+
scv,
|
|
2481
|
+
server,
|
|
2482
|
+
sni,
|
|
2483
|
+
tfo,
|
|
2484
|
+
underlyingProxy,
|
|
2485
|
+
up,
|
|
2486
|
+
upSpeed
|
|
2487
|
+
});
|
|
2488
|
+
break;
|
|
2489
|
+
}
|
|
2490
|
+
case "hysteria2": {
|
|
2491
|
+
group2 = DEFAULT_GROUPS.hysteria2;
|
|
2492
|
+
const ports = asString(get(single, "ports"));
|
|
2493
|
+
const up = asString(get(single, "up"));
|
|
2494
|
+
const down = asString(get(single, "down"));
|
|
2495
|
+
let password = asString(get(single, "password"));
|
|
2496
|
+
if (password === "") {
|
|
2497
|
+
password = asString(get(single, "auth"));
|
|
2498
|
+
}
|
|
2499
|
+
const obfs = asString(get(single, "obfs"));
|
|
2500
|
+
const obfsPassword = asString(get(single, "obfs-password"));
|
|
2501
|
+
const sni = asString(get(single, "sni"));
|
|
2502
|
+
const fingerprint = asString(get(single, "fingerprint"));
|
|
2503
|
+
const alpnValue = get(single, "alpn");
|
|
2504
|
+
const alpn = Array.isArray(alpnValue) ? asString(alpnValue[0]) : asString(alpnValue);
|
|
2505
|
+
const ca = asString(get(single, "ca"));
|
|
2506
|
+
const caStr = asString(get(single, "ca-str"));
|
|
2507
|
+
const cwnd = asString(get(single, "cwnd"));
|
|
2508
|
+
const hopInterval = asString(get(single, "hop-interval"));
|
|
2509
|
+
hysteria2Construct(node, {
|
|
2510
|
+
alpn,
|
|
2511
|
+
ca,
|
|
2512
|
+
caStr,
|
|
2513
|
+
cwnd,
|
|
2514
|
+
down,
|
|
2515
|
+
fingerprint,
|
|
2516
|
+
group: group2,
|
|
2517
|
+
hopInterval,
|
|
2518
|
+
obfs,
|
|
2519
|
+
obfsPassword,
|
|
2520
|
+
password,
|
|
2521
|
+
port,
|
|
2522
|
+
ports,
|
|
2523
|
+
remark: ps,
|
|
2524
|
+
scv,
|
|
2525
|
+
server,
|
|
2526
|
+
sni,
|
|
2527
|
+
tfo,
|
|
2528
|
+
underlyingProxy,
|
|
2529
|
+
up
|
|
2530
|
+
});
|
|
2531
|
+
break;
|
|
2532
|
+
}
|
|
2533
|
+
case "anytls": {
|
|
2534
|
+
group2 = DEFAULT_GROUPS.anytls;
|
|
2535
|
+
const password = asString(get(single, "password"));
|
|
2536
|
+
const sni = asString(get(single, "sni"));
|
|
2537
|
+
anyTlsConstruct(node, {
|
|
2538
|
+
group: group2,
|
|
2539
|
+
password,
|
|
2540
|
+
port,
|
|
2541
|
+
remark: ps,
|
|
2542
|
+
scv,
|
|
2543
|
+
server,
|
|
2544
|
+
sni,
|
|
2545
|
+
tfo,
|
|
2546
|
+
udp,
|
|
2547
|
+
underlyingProxy
|
|
2548
|
+
});
|
|
2549
|
+
break;
|
|
2550
|
+
}
|
|
2551
|
+
case "vless": {
|
|
2552
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2553
|
+
const userId = asString(get(single, "uuid"));
|
|
2554
|
+
const net = asString(get(single, "network"));
|
|
2555
|
+
const tls = asString(get(single, "tls"));
|
|
2556
|
+
let path = "";
|
|
2557
|
+
let host = "";
|
|
2558
|
+
if (net === "ws") {
|
|
2559
|
+
path = asString(get(get(single, "ws-opts"), "path"));
|
|
2560
|
+
host = asString(get(get(get(single, "ws-opts"), "headers"), "Host"));
|
|
2561
|
+
} else if (net === "grpc") {
|
|
2562
|
+
path = asString(get(get(single, "grpc-opts"), "grpc-service-name"));
|
|
2563
|
+
}
|
|
2564
|
+
const alpnValue = get(single, "alpn");
|
|
2565
|
+
vlessConstruct(node, {
|
|
2566
|
+
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2567
|
+
encryption: asString(get(single, "encryption")),
|
|
2568
|
+
fingerprint: asString(get(single, "client-fingerprint")),
|
|
2569
|
+
flow: asString(get(single, "flow")),
|
|
2570
|
+
group: group2,
|
|
2571
|
+
host,
|
|
2572
|
+
network: net,
|
|
2573
|
+
path,
|
|
2574
|
+
port,
|
|
2575
|
+
remark: ps,
|
|
2576
|
+
scv,
|
|
2577
|
+
server,
|
|
2578
|
+
sni: asString(get(single, "servername")),
|
|
2579
|
+
tfo,
|
|
2580
|
+
tls: tls === "true" ? "tls" : "",
|
|
2581
|
+
udp,
|
|
2582
|
+
underlyingProxy,
|
|
2583
|
+
userId
|
|
2584
|
+
});
|
|
2585
|
+
break;
|
|
2586
|
+
}
|
|
2587
|
+
case "tuic": {
|
|
2588
|
+
group2 = DEFAULT_GROUPS.v2ray;
|
|
2589
|
+
const alpnValue = get(single, "alpn");
|
|
2590
|
+
tuicConstruct(node, {
|
|
2591
|
+
alpn: Array.isArray(alpnValue) ? alpnValue.map((a) => String(a)) : void 0,
|
|
2592
|
+
congestionControl: asString(get(single, "congestion-controller")),
|
|
2593
|
+
group: group2,
|
|
2594
|
+
password: asString(get(single, "password")),
|
|
2595
|
+
port,
|
|
2596
|
+
remark: ps,
|
|
2597
|
+
scv,
|
|
2598
|
+
server,
|
|
2599
|
+
sni: asString(get(single, "sni")),
|
|
2600
|
+
tfo,
|
|
2601
|
+
udp,
|
|
2602
|
+
underlyingProxy,
|
|
2603
|
+
userId: asString(get(single, "uuid"))
|
|
2604
|
+
});
|
|
2605
|
+
break;
|
|
2606
|
+
}
|
|
2607
|
+
default:
|
|
2608
|
+
return false;
|
|
2556
2609
|
}
|
|
2610
|
+
node.id = index;
|
|
2611
|
+
nodes.push(node);
|
|
2612
|
+
return true;
|
|
2557
2613
|
}
|
|
2558
2614
|
function parseRawSections(text) {
|
|
2559
2615
|
const sections = [];
|
|
@@ -4161,7 +4217,10 @@ function explodeSs(ss, node) {
|
|
|
4161
4217
|
const secret = match[1];
|
|
4162
4218
|
server = match[2];
|
|
4163
4219
|
port = match[3];
|
|
4164
|
-
const
|
|
4220
|
+
const raw = urlDecode(secret);
|
|
4221
|
+
const decoded = firstMatch(urlSafeBase64Decode(raw), "(\\S+?):(\\S+)");
|
|
4222
|
+
const plaintext = firstMatch(raw, "(\\S+?):(\\S+)");
|
|
4223
|
+
const secretMatch = decoded && isSsCipher(decoded[1]) ? decoded : plaintext ?? decoded;
|
|
4165
4224
|
if (!secretMatch) {
|
|
4166
4225
|
return;
|
|
4167
4226
|
}
|
|
@@ -4626,6 +4685,157 @@ function explodeAnyTls(link, node) {
|
|
|
4626
4685
|
udp: udp === "" ? void 0 : parseTri(udp)
|
|
4627
4686
|
});
|
|
4628
4687
|
}
|
|
4688
|
+
function explodeSnell(link, node) {
|
|
4689
|
+
let body = link.slice(8);
|
|
4690
|
+
let remark = "";
|
|
4691
|
+
let addition = "";
|
|
4692
|
+
const hashPos = body.lastIndexOf("#");
|
|
4693
|
+
if (hashPos !== -1) {
|
|
4694
|
+
remark = urlDecode(body.slice(hashPos + 1));
|
|
4695
|
+
body = body.slice(0, hashPos);
|
|
4696
|
+
}
|
|
4697
|
+
const qpos = body.lastIndexOf("?");
|
|
4698
|
+
if (qpos !== -1) {
|
|
4699
|
+
addition = body.slice(qpos + 1);
|
|
4700
|
+
body = body.slice(0, qpos);
|
|
4701
|
+
}
|
|
4702
|
+
const match = /^(.*?)@(.*)[:](\d+)$/.exec(body);
|
|
4703
|
+
if (!match) {
|
|
4704
|
+
return;
|
|
4705
|
+
}
|
|
4706
|
+
const password = match[1];
|
|
4707
|
+
const server = match[2];
|
|
4708
|
+
const port = match[3];
|
|
4709
|
+
if (password === "" || port === "" || port === "0") {
|
|
4710
|
+
return;
|
|
4711
|
+
}
|
|
4712
|
+
const obfs = getUrlArg(addition, "obfs");
|
|
4713
|
+
const host = getUrlArg(addition, "host");
|
|
4714
|
+
const version = getUrlArg(addition, "version");
|
|
4715
|
+
const udp = getUrlArg(addition, "udp");
|
|
4716
|
+
const tfo = getUrlArg(addition, "tfo");
|
|
4717
|
+
const scv = getUrlArg(addition, "skip-cert-verify");
|
|
4718
|
+
if (remark === "") {
|
|
4719
|
+
remark = `${server}:${port}`;
|
|
4720
|
+
}
|
|
4721
|
+
snellConstruct(node, {
|
|
4722
|
+
group: DEFAULT_GROUPS.snell,
|
|
4723
|
+
host,
|
|
4724
|
+
obfs: obfs === "" ? "none" : obfs,
|
|
4725
|
+
password,
|
|
4726
|
+
port,
|
|
4727
|
+
remark,
|
|
4728
|
+
scv: scv === "" ? void 0 : parseTri(scv),
|
|
4729
|
+
server,
|
|
4730
|
+
tfo: tfo === "" ? void 0 : parseTri(tfo),
|
|
4731
|
+
udp: udp === "" ? void 0 : parseTri(udp),
|
|
4732
|
+
version: version === "" ? 1 : toInt(version)
|
|
4733
|
+
});
|
|
4734
|
+
}
|
|
4735
|
+
function explodeHysteria(link, node) {
|
|
4736
|
+
let body = link.slice(11);
|
|
4737
|
+
let remark = "";
|
|
4738
|
+
let addition = "";
|
|
4739
|
+
const hashPos = body.lastIndexOf("#");
|
|
4740
|
+
if (hashPos !== -1) {
|
|
4741
|
+
remark = urlDecode(body.slice(hashPos + 1));
|
|
4742
|
+
body = body.slice(0, hashPos);
|
|
4743
|
+
}
|
|
4744
|
+
const qpos = body.lastIndexOf("?");
|
|
4745
|
+
if (qpos !== -1) {
|
|
4746
|
+
addition = body.slice(qpos + 1);
|
|
4747
|
+
body = body.slice(0, qpos);
|
|
4748
|
+
}
|
|
4749
|
+
const match = /^(.*)[:](\d+)$/.exec(body);
|
|
4750
|
+
if (!match) {
|
|
4751
|
+
return;
|
|
4752
|
+
}
|
|
4753
|
+
const server = match[1];
|
|
4754
|
+
const port = match[2];
|
|
4755
|
+
if (server === "" || port === "0") {
|
|
4756
|
+
return;
|
|
4757
|
+
}
|
|
4758
|
+
const auth = getUrlArg(addition, "auth");
|
|
4759
|
+
const protocol = getUrlArg(addition, "protocol");
|
|
4760
|
+
const upSpeed = getUrlArg(addition, "upmbps");
|
|
4761
|
+
const downSpeed = getUrlArg(addition, "downmbps");
|
|
4762
|
+
const alpn = getUrlArg(addition, "alpn");
|
|
4763
|
+
const obfs = getUrlArg(addition, "obfs");
|
|
4764
|
+
const obfsProtocol = getUrlArg(addition, "obfsParam");
|
|
4765
|
+
const sni = getUrlArg(addition, "peer");
|
|
4766
|
+
const insecure = getUrlArg(addition, "insecure");
|
|
4767
|
+
if (remark === "") {
|
|
4768
|
+
remark = `${server}:${port}`;
|
|
4769
|
+
}
|
|
4770
|
+
hysteriaConstruct(node, {
|
|
4771
|
+
alpn,
|
|
4772
|
+
authStr: auth,
|
|
4773
|
+
downSpeed,
|
|
4774
|
+
group: DEFAULT_GROUPS.hysteria,
|
|
4775
|
+
obfs,
|
|
4776
|
+
obfsProtocol,
|
|
4777
|
+
port,
|
|
4778
|
+
protocol: protocol === "" ? "udp" : protocol,
|
|
4779
|
+
remark,
|
|
4780
|
+
scv: insecure === "" ? void 0 : parseTri(insecure),
|
|
4781
|
+
server,
|
|
4782
|
+
sni: sni === "" ? server : sni,
|
|
4783
|
+
upSpeed
|
|
4784
|
+
});
|
|
4785
|
+
}
|
|
4786
|
+
function explodeWireguard(link, node) {
|
|
4787
|
+
const normalized = link.replace(/^(wg|wireguard):\/\//, "wireguard://");
|
|
4788
|
+
let body = normalized.slice(13);
|
|
4789
|
+
let remark = "";
|
|
4790
|
+
let addition = "";
|
|
4791
|
+
const hashPos = body.lastIndexOf("#");
|
|
4792
|
+
if (hashPos !== -1) {
|
|
4793
|
+
remark = urlDecode(body.slice(hashPos + 1));
|
|
4794
|
+
body = body.slice(0, hashPos);
|
|
4795
|
+
}
|
|
4796
|
+
const qpos = body.lastIndexOf("?");
|
|
4797
|
+
if (qpos !== -1) {
|
|
4798
|
+
addition = body.slice(qpos + 1);
|
|
4799
|
+
body = body.slice(0, qpos);
|
|
4800
|
+
}
|
|
4801
|
+
const match = /^(?:(.*)@)?\[?(.*?)]?:(\d+)$/.exec(body);
|
|
4802
|
+
if (!match) {
|
|
4803
|
+
return;
|
|
4804
|
+
}
|
|
4805
|
+
const server = match[2];
|
|
4806
|
+
const port = match[3];
|
|
4807
|
+
if (server === "" || port === "0") {
|
|
4808
|
+
return;
|
|
4809
|
+
}
|
|
4810
|
+
const privateKey = getUrlArg(addition, "privateKey") || getUrlArg(addition, "privatekey");
|
|
4811
|
+
const publicKey = getUrlArg(addition, "publicKey") || getUrlArg(addition, "publickey");
|
|
4812
|
+
if (privateKey === "" || publicKey === "") {
|
|
4813
|
+
return;
|
|
4814
|
+
}
|
|
4815
|
+
const presharedKey = getUrlArg(addition, "presharedKey");
|
|
4816
|
+
const selfIp = getUrlArg(addition, "selfIP");
|
|
4817
|
+
const selfIpv6 = getUrlArg(addition, "selfIPv6");
|
|
4818
|
+
const mtu = getUrlArg(addition, "mtu");
|
|
4819
|
+
const keepAlive = getUrlArg(addition, "keepAlive");
|
|
4820
|
+
const dns = getUrlArg(addition, "dns");
|
|
4821
|
+
if (remark === "") {
|
|
4822
|
+
remark = `${server}:${port}`;
|
|
4823
|
+
}
|
|
4824
|
+
wireGuardConstruct(node, {
|
|
4825
|
+
dnsServers: dns === "" ? ["1.1.1.1"] : dns.split(",").map((s) => s.trim()),
|
|
4826
|
+
group: DEFAULT_GROUPS.wireguard,
|
|
4827
|
+
keepAlive: keepAlive === "" ? 25 : toInt(keepAlive),
|
|
4828
|
+
mtu: mtu === "" ? 1420 : toInt(mtu),
|
|
4829
|
+
port,
|
|
4830
|
+
preSharedKey: presharedKey,
|
|
4831
|
+
privateKey,
|
|
4832
|
+
publicKey,
|
|
4833
|
+
remark,
|
|
4834
|
+
selfIp: selfIp === "" ? "10.0.0.2" : selfIp,
|
|
4835
|
+
selfIpv6,
|
|
4836
|
+
server
|
|
4837
|
+
});
|
|
4838
|
+
}
|
|
4629
4839
|
function explodeVless(link, node) {
|
|
4630
4840
|
let body = link.slice(8);
|
|
4631
4841
|
let remark = "";
|
|
@@ -4749,6 +4959,12 @@ function explode(link, node) {
|
|
|
4749
4959
|
explodeVless(link, node);
|
|
4750
4960
|
} else if (startsWith(link, "tuic://")) {
|
|
4751
4961
|
explodeTuic(link, node);
|
|
4962
|
+
} else if (startsWith(link, "snell://")) {
|
|
4963
|
+
explodeSnell(link, node);
|
|
4964
|
+
} else if (startsWith(link, "hysteria://")) {
|
|
4965
|
+
explodeHysteria(link, node);
|
|
4966
|
+
} else if (startsWith(link, "wg://") || startsWith(link, "wireguard://")) {
|
|
4967
|
+
explodeWireguard(link, node);
|
|
4752
4968
|
} else if (link.includes("hysteria2://") || link.includes("hy2://")) {
|
|
4753
4969
|
explodeHysteria2(link, node);
|
|
4754
4970
|
} else if (startsWith(link, "anytls://")) {
|
|
@@ -5253,6 +5469,10 @@ function toRegex(pattern) {
|
|
|
5253
5469
|
function regFind(value, pattern) {
|
|
5254
5470
|
return toRegex(pattern).test(value);
|
|
5255
5471
|
}
|
|
5472
|
+
var REGEX_BLACKLIST = ["(.*)*"];
|
|
5473
|
+
function isBlacklistedPattern(pattern) {
|
|
5474
|
+
return REGEX_BLACKLIST.includes(pattern);
|
|
5475
|
+
}
|
|
5256
5476
|
function regMatch2(value, pattern) {
|
|
5257
5477
|
const match = toRegex(pattern).exec(value);
|
|
5258
5478
|
return match !== null && match[0] === value;
|
|
@@ -5624,12 +5844,59 @@ function stripBrackets(value) {
|
|
|
5624
5844
|
function toTri(value) {
|
|
5625
5845
|
return value;
|
|
5626
5846
|
}
|
|
5847
|
+
var MIHOMO_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
5848
|
+
"ss" /* Shadowsocks */,
|
|
5849
|
+
"ssr" /* ShadowsocksR */,
|
|
5850
|
+
"vmess" /* VMess */,
|
|
5851
|
+
"trojan" /* Trojan */,
|
|
5852
|
+
"snell" /* Snell */,
|
|
5853
|
+
"http" /* HTTP */,
|
|
5854
|
+
"https" /* HTTPS */,
|
|
5855
|
+
"socks5" /* SOCKS5 */,
|
|
5856
|
+
"wireguard" /* WireGuard */,
|
|
5857
|
+
"hysteria" /* Hysteria */,
|
|
5858
|
+
"hysteria2" /* Hysteria2 */,
|
|
5859
|
+
"vless" /* VLESS */,
|
|
5860
|
+
"anytls" /* AnyTLS */,
|
|
5861
|
+
"tuic" /* TUIC */
|
|
5862
|
+
]);
|
|
5863
|
+
var PREMIUM_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
5864
|
+
"ss" /* Shadowsocks */,
|
|
5865
|
+
"ssr" /* ShadowsocksR */,
|
|
5866
|
+
"vmess" /* VMess */,
|
|
5867
|
+
"trojan" /* Trojan */,
|
|
5868
|
+
"snell" /* Snell */,
|
|
5869
|
+
"http" /* HTTP */,
|
|
5870
|
+
"https" /* HTTPS */,
|
|
5871
|
+
"socks5" /* SOCKS5 */,
|
|
5872
|
+
"wireguard" /* WireGuard */
|
|
5873
|
+
]);
|
|
5874
|
+
var STASH_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
5875
|
+
...PREMIUM_PROTOCOLS,
|
|
5876
|
+
"hysteria" /* Hysteria */,
|
|
5877
|
+
"hysteria2" /* Hysteria2 */,
|
|
5878
|
+
"vless" /* VLESS */,
|
|
5879
|
+
"tuic" /* TUIC */
|
|
5880
|
+
]);
|
|
5881
|
+
function clashCapabilities(flavor) {
|
|
5882
|
+
if (flavor === "premium") {
|
|
5883
|
+
return { clientFingerprint: false, protocols: PREMIUM_PROTOCOLS, reality: false };
|
|
5884
|
+
}
|
|
5885
|
+
if (flavor === "stash") {
|
|
5886
|
+
return { clientFingerprint: false, protocols: STASH_PROTOCOLS, reality: true };
|
|
5887
|
+
}
|
|
5888
|
+
return { clientFingerprint: true, protocols: MIHOMO_PROTOCOLS, reality: true };
|
|
5889
|
+
}
|
|
5627
5890
|
function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
5628
5891
|
const proxy = {
|
|
5629
5892
|
name: remark,
|
|
5630
5893
|
port: x.port,
|
|
5631
5894
|
server: stripBrackets(x.hostname)
|
|
5632
5895
|
};
|
|
5896
|
+
const caps = clashCapabilities(settings.clashFlavor);
|
|
5897
|
+
if (!caps.protocols.has(x.type)) {
|
|
5898
|
+
return void 0;
|
|
5899
|
+
}
|
|
5633
5900
|
switch (x.type) {
|
|
5634
5901
|
case "ss" /* Shadowsocks */: {
|
|
5635
5902
|
if (settings.filterDeprecated && x.encryptMethod === "chacha20") {
|
|
@@ -5879,7 +6146,7 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5879
6146
|
if (skipCertVerify !== void 0) {
|
|
5880
6147
|
proxy["skip-cert-verify"] = skipCertVerify;
|
|
5881
6148
|
}
|
|
5882
|
-
if (x.fingerprint !== "") {
|
|
6149
|
+
if (x.fingerprint !== "" && caps.clientFingerprint) {
|
|
5883
6150
|
proxy.fingerprint = x.fingerprint;
|
|
5884
6151
|
}
|
|
5885
6152
|
if (x.alpn.length > 0) {
|
|
@@ -5934,7 +6201,7 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5934
6201
|
if (skipCertVerify !== void 0) {
|
|
5935
6202
|
proxy["skip-cert-verify"] = skipCertVerify;
|
|
5936
6203
|
}
|
|
5937
|
-
if (x.fingerprint !== "") {
|
|
6204
|
+
if (x.fingerprint !== "" && caps.clientFingerprint) {
|
|
5938
6205
|
proxy.fingerprint = x.fingerprint;
|
|
5939
6206
|
}
|
|
5940
6207
|
if (x.alpn.length > 0) {
|
|
@@ -5973,10 +6240,13 @@ function buildClashProxy(x, settings, clashR, remark, skipCertVerify, tfo) {
|
|
|
5973
6240
|
if (x.serverName !== "") {
|
|
5974
6241
|
proxy.servername = x.serverName;
|
|
5975
6242
|
}
|
|
5976
|
-
if (x.fingerprint !== "") {
|
|
6243
|
+
if (x.fingerprint !== "" && caps.clientFingerprint) {
|
|
5977
6244
|
proxy["client-fingerprint"] = x.fingerprint;
|
|
5978
6245
|
}
|
|
5979
6246
|
if (x.publicKey !== "" || x.shortId !== "") {
|
|
6247
|
+
if (!caps.reality) {
|
|
6248
|
+
return void 0;
|
|
6249
|
+
}
|
|
5980
6250
|
const realityOpts = {};
|
|
5981
6251
|
if (x.publicKey !== "") {
|
|
5982
6252
|
realityOpts["public-key"] = x.publicKey;
|
|
@@ -7333,7 +7603,7 @@ function collectRuleLines(content, group2, noResolveOnly) {
|
|
|
7333
7603
|
}
|
|
7334
7604
|
return out;
|
|
7335
7605
|
}
|
|
7336
|
-
function rulesetToClashRules(rulesets) {
|
|
7606
|
+
function rulesetToClashRules(rulesets, classical = false) {
|
|
7337
7607
|
const rules = [];
|
|
7338
7608
|
for (const ruleset of rulesets) {
|
|
7339
7609
|
const content = ruleset.content;
|
|
@@ -7349,7 +7619,10 @@ function rulesetToClashRules(rulesets) {
|
|
|
7349
7619
|
rules.push(transformRuleToCommon(line, group2));
|
|
7350
7620
|
continue;
|
|
7351
7621
|
}
|
|
7352
|
-
const converted = convertRuleset(
|
|
7622
|
+
const converted = convertRuleset(
|
|
7623
|
+
content,
|
|
7624
|
+
classical && /^payload:\r?\n/.test(content) ? "clash-classical" /* ClashClassical */ : ruleset.ruleType
|
|
7625
|
+
);
|
|
7353
7626
|
for (const rawLine of converted.split(/\r?\n/)) {
|
|
7354
7627
|
let line = rawLine.trim();
|
|
7355
7628
|
if (!isRuleLine(line)) {
|
|
@@ -7366,7 +7639,7 @@ function rulesetToClashRules(rulesets) {
|
|
|
7366
7639
|
}
|
|
7367
7640
|
return rules;
|
|
7368
7641
|
}
|
|
7369
|
-
function rulesetToSurgeRules(rulesets, surgeVersion) {
|
|
7642
|
+
function rulesetToSurgeRules(rulesets, surgeVersion, expand = true) {
|
|
7370
7643
|
let section;
|
|
7371
7644
|
let allowed;
|
|
7372
7645
|
let noResolveOnly = false;
|
|
@@ -7404,6 +7677,17 @@ function rulesetToSurgeRules(rulesets, surgeVersion) {
|
|
|
7404
7677
|
continue;
|
|
7405
7678
|
}
|
|
7406
7679
|
const group2 = ruleset.ruleGroup;
|
|
7680
|
+
if (!expand && (surgeVersion > 2 || surgeVersion === -3)) {
|
|
7681
|
+
const { url } = parseRulesetSource(ruleset.rulePath);
|
|
7682
|
+
if (/^https?:\/\//i.test(url.trim()) && !ruleset.content.startsWith("[]")) {
|
|
7683
|
+
let line = `RULE-SET,${url.trim()},${group2}`;
|
|
7684
|
+
if (ruleset.updateInterval > 0) {
|
|
7685
|
+
line += `,update-interval=${ruleset.updateInterval}`;
|
|
7686
|
+
}
|
|
7687
|
+
lines.push(line);
|
|
7688
|
+
continue;
|
|
7689
|
+
}
|
|
7690
|
+
}
|
|
7407
7691
|
if (ruleset.content.startsWith("[]")) {
|
|
7408
7692
|
let line = ruleset.content.slice(2);
|
|
7409
7693
|
if (line === "MATCH") {
|
|
@@ -8168,9 +8452,24 @@ function buildOutbound(x, settings, remark) {
|
|
|
8168
8452
|
proxy = out;
|
|
8169
8453
|
break;
|
|
8170
8454
|
}
|
|
8171
|
-
// sing-box has no
|
|
8455
|
+
// sing-box has no ShadowsocksR implementation (configs using it fail
|
|
8456
|
+
// at startup), so such nodes are dropped.
|
|
8172
8457
|
case "ssr" /* ShadowsocksR */:
|
|
8173
8458
|
return void 0;
|
|
8459
|
+
case "snell" /* Snell */: {
|
|
8460
|
+
const out = { ...common, psk: x.password, type: "snell" };
|
|
8461
|
+
if (x.snellVersion) {
|
|
8462
|
+
out.version = x.snellVersion;
|
|
8463
|
+
}
|
|
8464
|
+
if (x.obfs !== "" && x.obfs !== "none") {
|
|
8465
|
+
out.obfs_mode = x.obfs;
|
|
8466
|
+
}
|
|
8467
|
+
if (x.host !== "") {
|
|
8468
|
+
out.obfs_host = x.host;
|
|
8469
|
+
}
|
|
8470
|
+
proxy = out;
|
|
8471
|
+
break;
|
|
8472
|
+
}
|
|
8174
8473
|
case "vmess" /* VMess */: {
|
|
8175
8474
|
const out = {
|
|
8176
8475
|
...common,
|
|
@@ -8474,6 +8773,7 @@ function generate(nodes, options) {
|
|
|
8474
8773
|
runPreprocess(nodes, settings);
|
|
8475
8774
|
const groups = resolveGroups(options);
|
|
8476
8775
|
const rulesets = resolveRulesets(options, settings);
|
|
8776
|
+
const baseConf = applyBaseTemplate(options.baseConf ?? "", settings);
|
|
8477
8777
|
switch (options.target) {
|
|
8478
8778
|
case "clash" /* Clash */:
|
|
8479
8779
|
case "clashr" /* ClashR */: {
|
|
@@ -8483,9 +8783,9 @@ function generate(nodes, options) {
|
|
|
8483
8783
|
}
|
|
8484
8784
|
case "surge" /* Surge */: {
|
|
8485
8785
|
const surgeVersion = options.surgeVersion ?? 5;
|
|
8486
|
-
const rules = rulesets ? rulesetToSurgeRules(rulesets, surgeVersion) : void 0;
|
|
8786
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, surgeVersion, settings.expandRulesets) : void 0;
|
|
8487
8787
|
return toSurge(nodes, groups, settings, {
|
|
8488
|
-
baseConf
|
|
8788
|
+
baseConf,
|
|
8489
8789
|
nodeList: settings.nodeList,
|
|
8490
8790
|
rules,
|
|
8491
8791
|
version: surgeVersion
|
|
@@ -8494,7 +8794,7 @@ function generate(nodes, options) {
|
|
|
8494
8794
|
case "quanx" /* QuantumultX */: {
|
|
8495
8795
|
const rules = rulesets ? rulesetToSurgeRules(rulesets, -1) : void 0;
|
|
8496
8796
|
return toQuanX(nodes, groups, settings, {
|
|
8497
|
-
baseConf
|
|
8797
|
+
baseConf,
|
|
8498
8798
|
nodeList: settings.nodeList,
|
|
8499
8799
|
rules
|
|
8500
8800
|
});
|
|
@@ -8502,7 +8802,7 @@ function generate(nodes, options) {
|
|
|
8502
8802
|
case "quan" /* Quantumult */: {
|
|
8503
8803
|
const rules = rulesets ? rulesetToSurgeRules(rulesets, -2) : void 0;
|
|
8504
8804
|
return toQuan(nodes, groups, settings, {
|
|
8505
|
-
baseConf
|
|
8805
|
+
baseConf,
|
|
8506
8806
|
nodeList: settings.nodeList,
|
|
8507
8807
|
rules
|
|
8508
8808
|
});
|
|
@@ -8510,21 +8810,21 @@ function generate(nodes, options) {
|
|
|
8510
8810
|
case "loon" /* Loon */: {
|
|
8511
8811
|
const rules = rulesets ? rulesetToSurgeRules(rulesets, -4) : void 0;
|
|
8512
8812
|
return toLoon(nodes, groups, settings, {
|
|
8513
|
-
baseConf
|
|
8813
|
+
baseConf,
|
|
8514
8814
|
nodeList: settings.nodeList,
|
|
8515
8815
|
rules
|
|
8516
8816
|
});
|
|
8517
8817
|
}
|
|
8518
8818
|
case "singbox" /* SingBox */:
|
|
8519
8819
|
return toSingBox(nodes, groups, settings, {
|
|
8520
|
-
baseConf
|
|
8820
|
+
baseConf,
|
|
8521
8821
|
nodeList: settings.nodeList,
|
|
8522
8822
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
8523
8823
|
rulesets
|
|
8524
8824
|
});
|
|
8525
8825
|
case "mellow" /* Mellow */:
|
|
8526
8826
|
return toMellow(nodes, groups, settings, {
|
|
8527
|
-
baseConf
|
|
8827
|
+
baseConf,
|
|
8528
8828
|
nodeList: settings.nodeList,
|
|
8529
8829
|
overwriteOriginalRules: settings.overwriteOriginalRules,
|
|
8530
8830
|
rulesets
|
|
@@ -8542,11 +8842,11 @@ function generate(nodes, options) {
|
|
|
8542
8842
|
case "ssd" /* SSD */:
|
|
8543
8843
|
return proxyToSsd(nodes, "", "");
|
|
8544
8844
|
case "sssub" /* SSSub */:
|
|
8545
|
-
return proxyToSsSub(nodes,
|
|
8845
|
+
return proxyToSsSub(nodes, baseConf);
|
|
8546
8846
|
case "surfboard" /* Surfboard */: {
|
|
8547
|
-
const rules = rulesets ? rulesetToSurgeRules(rulesets, options.surgeVersion ?? 5) : void 0;
|
|
8847
|
+
const rules = rulesets ? rulesetToSurgeRules(rulesets, options.surgeVersion ?? 5, settings.expandRulesets) : void 0;
|
|
8548
8848
|
return toSurfboard(nodes, groups, settings, {
|
|
8549
|
-
baseConf
|
|
8849
|
+
baseConf,
|
|
8550
8850
|
nodeList: settings.nodeList,
|
|
8551
8851
|
rules
|
|
8552
8852
|
});
|
|
@@ -8559,6 +8859,12 @@ function generate(nodes, options) {
|
|
|
8559
8859
|
throw new Error(`Unsupported target format: ${options.target}`);
|
|
8560
8860
|
}
|
|
8561
8861
|
}
|
|
8862
|
+
function applyBaseTemplate(baseConf, settings) {
|
|
8863
|
+
if (baseConf === "" || !hasTemplatePlaceholders(baseConf)) {
|
|
8864
|
+
return baseConf;
|
|
8865
|
+
}
|
|
8866
|
+
return renderTemplate(baseConf, settings.templateVars);
|
|
8867
|
+
}
|
|
8562
8868
|
function toSip008(nodes, baseConf = "") {
|
|
8563
8869
|
return proxyToSsSub(nodes, baseConf);
|
|
8564
8870
|
}
|
|
@@ -8588,7 +8894,7 @@ function attachClashRules(doc, settings, rulesets) {
|
|
|
8588
8894
|
return;
|
|
8589
8895
|
}
|
|
8590
8896
|
const field = settings.clashNewFieldName ? "rules" : "Rule";
|
|
8591
|
-
const generated = rulesetToClashRules(rulesets);
|
|
8897
|
+
const generated = rulesetToClashRules(rulesets, settings.clashClassicalRuleset);
|
|
8592
8898
|
if (generated.length === 0) {
|
|
8593
8899
|
return;
|
|
8594
8900
|
}
|