tt-help-cli-ycl 1.4.114 → 1.4.117
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/package.json +1 -1
- package/scripts/precheck-monitor.sh +37 -0
- package/scripts/test-clash-discover.mjs +126 -0
- package/scripts/test-clash-multichannel.mjs +120 -0
- package/src/clash/api.js +29 -3
- package/src/clash/benchmark/lib/clash-api.js +3 -232
- package/src/clash/checker.js +63 -30
- package/src/clash/daemon.js +285 -108
- package/src/clash/discover.js +451 -0
- package/src/clash/ipc.js +65 -20
- package/src/cli/attach.js +57 -10
- package/src/cli/clash-daemon.js +10 -1
- package/src/cli/precheck.js +42 -14
- package/src/cli/refresh-mini.js +36 -24
- package/src/lib/args.js +17 -0
- package/src/lib/constants.js +6 -1
- package/src/watch/public/app.js +58 -17
- package/src/watch/watchdog-server.js +14 -4
- package/src/watchdog/agent.js +16 -6
- package/src/watchdog/reporter.js +32 -1
- package/src/webserver/server.mjs +40 -7
package/src/clash/checker.js
CHANGED
|
@@ -22,6 +22,8 @@ import * as api from "./api.js";
|
|
|
22
22
|
|
|
23
23
|
const IS_WIN = process.platform === "win32";
|
|
24
24
|
const HEALTHY_FILE = join(tmpdir(), "clash-healthy-nodes.json");
|
|
25
|
+
// 多控制端场景下按代理端口分文件(0/默认 = 单客户端旧文件);由 applyDiscovered 切换
|
|
26
|
+
let _healthyFile = HEALTHY_FILE;
|
|
25
27
|
|
|
26
28
|
export const CONFIG = {
|
|
27
29
|
testUrl: "https://www.tiktok.com/explore",
|
|
@@ -36,22 +38,27 @@ export const CONFIG = {
|
|
|
36
38
|
const CURL_UA =
|
|
37
39
|
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36";
|
|
38
40
|
|
|
41
|
+
// 支持的 mihomo 系客户端进程名(FR-8 存活判定扩展)
|
|
42
|
+
const CLASH_PROCESS_NAMES = ["verge-mihomo", "69cloud-core"];
|
|
43
|
+
|
|
44
|
+
// 国家匹配:emoji 国旗可选(Clash Verge 节点名带国旗,69cloud 节点名纯中文/英文不带),
|
|
45
|
+
// 拉丁代码用词边界防误匹配(如 \bUS\b 不匹配 PLUS)
|
|
39
46
|
const COUNTRY_PATTERNS = {
|
|
40
|
-
US: /[🇺🇸]\s*(美国|
|
|
41
|
-
GB: /[🇬🇧]\s*(英国|UK|
|
|
42
|
-
DE: /[🇩🇪]\s*(德国|
|
|
43
|
-
FR: /[🇫🇷]\s*(法国|
|
|
44
|
-
JP: /[🇯🇵]\s*(日本|
|
|
45
|
-
KR: /[🇰🇷]\s*(韩国|
|
|
46
|
-
SG: /[🇸🇬]\s*(新加坡|
|
|
47
|
-
HK: /[🇭🇰]\s*(香港|
|
|
48
|
-
TW: /[🇹🇼]\s*(台湾|
|
|
49
|
-
RU: /[🇷🇺]\s*(俄罗斯|
|
|
50
|
-
NL: /[🇳🇱]\s*(荷兰|
|
|
51
|
-
IN: /[🇮🇳]\s*(印度|
|
|
52
|
-
CA: /[🇨🇦]\s*(加拿大|
|
|
53
|
-
AU: /[🇦🇺]\s*(澳大利亚|
|
|
54
|
-
MY: /[🇲🇾]\s*(马来西亚|
|
|
47
|
+
US: /(?:[🇺🇸]\s*)?(美国|USA|United\s*States|\bUS\b)/i,
|
|
48
|
+
GB: /(?:[🇬🇧]\s*)?(英国|UK|United\s*Kingdom|\bGB\b)/i,
|
|
49
|
+
DE: /(?:[🇩🇪]\s*)?(德国|Germany|\bDE\b)/i,
|
|
50
|
+
FR: /(?:[🇫🇷]\s*)?(法国|France|\bFR\b)/i,
|
|
51
|
+
JP: /(?:[🇯🇵]\s*)?(日本|Japan|\bJP\b)/i,
|
|
52
|
+
KR: /(?:[🇰🇷]\s*)?(韩国|Korea|\bKR\b)/i,
|
|
53
|
+
SG: /(?:[🇸🇬]\s*)?(新加坡|Singapore|\bSG\b)/i,
|
|
54
|
+
HK: /(?:[🇭🇰]\s*)?(香港|Hong\s*Kong|\bHK\b)/i,
|
|
55
|
+
TW: /(?:[🇹🇼]\s*)?(台湾|Taiwan|\bTW\b)/i,
|
|
56
|
+
RU: /(?:[🇷🇺]\s*)?(俄罗斯|Russia|\bRU\b)/i,
|
|
57
|
+
NL: /(?:[🇳🇱]\s*)?(荷兰|Netherlands|\bNL\b)/i,
|
|
58
|
+
IN: /(?:[🇮🇳]\s*)?(印度|India|\bIN\b)/i,
|
|
59
|
+
CA: /(?:[🇨🇦]\s*)?(加拿大|Canada|\bCA\b)/i,
|
|
60
|
+
AU: /(?:[🇦🇺]\s*)?(澳大利亚|Australia|\bAU\b)/i,
|
|
61
|
+
MY: /(?:[🇲🇾]\s*)?(马来西亚|Malaysia|\bMY\b)/i,
|
|
55
62
|
};
|
|
56
63
|
|
|
57
64
|
let _proxyResolved = false;
|
|
@@ -73,6 +80,26 @@ export function resetProxyUrlCache() {
|
|
|
73
80
|
_proxyResolved = false;
|
|
74
81
|
}
|
|
75
82
|
|
|
83
|
+
/**
|
|
84
|
+
* 应用自动发现结果(discover.js)
|
|
85
|
+
* 控制端口写入 CONFIG.apiPort;代理端口直接采用发现到的 mixed-port,
|
|
86
|
+
* 避免 resolveProxyUrl() 再对旧端口发起探测。
|
|
87
|
+
* 多控制端场景:proxyPort 用于切换对应控制端的健康节点列表文件。
|
|
88
|
+
* @param {{port?:number, proxyUrl?:string, proxyPort?:number}} disc
|
|
89
|
+
*/
|
|
90
|
+
export function applyDiscovered(disc = {}) {
|
|
91
|
+
if (disc.port) CONFIG.apiPort = disc.port;
|
|
92
|
+
if (disc.proxyUrl) {
|
|
93
|
+
CONFIG.proxyUrl = disc.proxyUrl;
|
|
94
|
+
_proxyResolved = true;
|
|
95
|
+
}
|
|
96
|
+
if (disc.proxyPort) {
|
|
97
|
+
_healthyFile = join(tmpdir(), `clash-healthy-nodes-${disc.proxyPort}.json`);
|
|
98
|
+
} else {
|
|
99
|
+
_healthyFile = HEALTHY_FILE;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
76
103
|
// ══════════════════════════════════════════════
|
|
77
104
|
// 2. 进程 / API 可达性检测
|
|
78
105
|
// ══════════════════════════════════════════════
|
|
@@ -104,19 +131,25 @@ export function checkClashAliveWithReason() {
|
|
|
104
131
|
function _detectProcess() {
|
|
105
132
|
try {
|
|
106
133
|
if (IS_WIN) {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
for (const name of CLASH_PROCESS_NAMES) {
|
|
135
|
+
const r = spawnSync(
|
|
136
|
+
"tasklist",
|
|
137
|
+
["/FI", `IMAGENAME eq ${name}.exe`, "/NH"],
|
|
138
|
+
{ encoding: "utf-8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] },
|
|
139
|
+
);
|
|
140
|
+
if (r.stdout?.includes(`${name}.exe`)) return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
113
143
|
}
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
for (const name of CLASH_PROCESS_NAMES) {
|
|
145
|
+
const r = spawnSync("pgrep", ["-x", name], {
|
|
146
|
+
encoding: "utf-8",
|
|
147
|
+
timeout: 5000,
|
|
148
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
149
|
+
});
|
|
150
|
+
if (r.status === 0 && r.stdout.trim()) return true;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
120
153
|
} catch {
|
|
121
154
|
return false;
|
|
122
155
|
}
|
|
@@ -367,8 +400,8 @@ export async function runDelayProbe({
|
|
|
367
400
|
*/
|
|
368
401
|
export function loadHealthyList(country = null) {
|
|
369
402
|
try {
|
|
370
|
-
if (!existsSync(
|
|
371
|
-
const d = JSON.parse(readFileSync(
|
|
403
|
+
if (!existsSync(_healthyFile)) return _emptyList();
|
|
404
|
+
const d = JSON.parse(readFileSync(_healthyFile, "utf-8"));
|
|
372
405
|
const allNodes = Array.isArray(d.nodes) ? d.nodes : [];
|
|
373
406
|
const filter = country || CONFIG.nodeCountryFilter;
|
|
374
407
|
const { filtered, excluded } = filterNodesByCountry(allNodes, filter);
|
|
@@ -388,7 +421,7 @@ export function loadHealthyList(country = null) {
|
|
|
388
421
|
export function saveHealthyList(nodes) {
|
|
389
422
|
try {
|
|
390
423
|
writeFileSync(
|
|
391
|
-
|
|
424
|
+
_healthyFile,
|
|
392
425
|
JSON.stringify({ updated: new Date().toISOString(), nodes }, null, 2),
|
|
393
426
|
"utf-8",
|
|
394
427
|
);
|