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.
@@ -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*(美国|US|USA|United\s*States)/i,
41
- GB: /[🇬🇧]\s*(英国|UK|GB|United\s*Kingdom)/i,
42
- DE: /[🇩🇪]\s*(德国|DE|Germany)/i,
43
- FR: /[🇫🇷]\s*(法国|FR|France)/i,
44
- JP: /[🇯🇵]\s*(日本|JP|Japan)/i,
45
- KR: /[🇰🇷]\s*(韩国|KR|Korea)/i,
46
- SG: /[🇸🇬]\s*(新加坡|SG|Singapore)/i,
47
- HK: /[🇭🇰]\s*(香港|HK|Hong\s*Kong)/i,
48
- TW: /[🇹🇼]\s*(台湾|TW|Taiwan)/i,
49
- RU: /[🇷🇺]\s*(俄罗斯|RU|Russia)/i,
50
- NL: /[🇳🇱]\s*(荷兰|NL|Netherlands)/i,
51
- IN: /[🇮🇳]\s*(印度|IN|India)/i,
52
- CA: /[🇨🇦]\s*(加拿大|CA|Canada)/i,
53
- AU: /[🇦🇺]\s*(澳大利亚|AU|Australia)/i,
54
- MY: /[🇲🇾]\s*(马来西亚|MY|Malaysia)/i,
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 r = spawnSync(
108
- "tasklist",
109
- ["/FI", "IMAGENAME eq verge-mihomo.exe", "/NH"],
110
- { encoding: "utf-8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] },
111
- );
112
- return r.stdout?.includes("verge-mihomo.exe");
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 r = spawnSync("pgrep", ["-x", "verge-mihomo"], {
115
- encoding: "utf-8",
116
- timeout: 5000,
117
- stdio: ["pipe", "pipe", "pipe"],
118
- });
119
- return r.status === 0 && !!r.stdout.trim();
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(HEALTHY_FILE)) return _emptyList();
371
- const d = JSON.parse(readFileSync(HEALTHY_FILE, "utf-8"));
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
- HEALTHY_FILE,
424
+ _healthyFile,
392
425
  JSON.stringify({ updated: new Date().toISOString(), nodes }, null, 2),
393
426
  "utf-8",
394
427
  );