From 0ef15bfd3bfc2cc4f72fffb2e71b759cfb72ae0d Mon Sep 17 00:00:00 2001 From: Orion Date: Sat, 9 May 2026 15:36:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=E2=99=BB=EF=B8=8F=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=8A=82=E7=82=B9=E9=87=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=8F=98=E9=87=8F=E5=91=BD=E5=90=8D=E4=B8=8E?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对 sntp-rename.js 进行代码重构,通过更具描述性的变量名(如 featureKeyword, proxyName)提高代码可读性。同时更新项目文档,明确该脚本专用于“守候网络” 节点命名,并对默认规则和使用说明进行了优化。 - 优化变量命名以更清晰地表达业务逻辑 - 更新 README 完善守候网络节点的命名说明 - 格式化代码逻辑以增强可维护性 --- README.md | 4 +-- substore/README.md | 19 ++++++----- substore/sntp-rename.js | 70 +++++++++++++++++++++-------------------- 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 76d8a9f..9050e8c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ script/ | 目录 | 脚本 | 用途 | 运行环境 | | --- | --- | --- | --- | | `homebrew/` | `brew-upgrade-manager.sh` | 自动更新 Homebrew、升级 Formula/Cask、清理缓存 | macOS、Bash、Homebrew | -| `substore/` | `sntp-rename.js` | 在 Sub-Store 代理节点名称中注入线路标签 | Sub-Store 脚本处理器 | +| `substore/` | `sntp-rename.js` | 守候网络节点命名专用,在 Sub-Store 代理节点名称中注入线路标签 | Sub-Store 脚本处理器 | | `telegram/` | `tg-bot.js` | 基于 Cloudflare Workers 的 Telegram 私聊转发与管理后台 | Cloudflare Workers、D1、Telegram Bot | ## 快速开始 @@ -48,7 +48,7 @@ HB_TERMINAL_WIDTH=130 ./brew-upgrade-manager.sh ### Sub-Store 节点标签注入 -把 [substore/sntp-rename.js](substore/sntp-rename.js) 作为 Sub-Store 节点处理脚本使用。默认会识别 `GTM`、`S1`、`S2`、`S3`、`S4`、`BGP`、`Anytls` 等关键词,并把标签插入到节点名末尾或 `- SNTP` 后缀之前。 +把 [substore/sntp-rename.js](substore/sntp-rename.js) 作为守候网络节点命名专用的 Sub-Store 节点处理脚本使用。默认会识别 `GTM`、`S1`、`S2`、`S3`、`S4`、`BGP`、`Anytls` 等关键词,并把标签插入到节点名末尾或 `- SNTP` 后缀之前。 详细规则见 [substore/README.md](substore/README.md)。 diff --git a/substore/README.md b/substore/README.md index 9cff06c..7b495b9 100644 --- a/substore/README.md +++ b/substore/README.md @@ -1,8 +1,8 @@ -# Sub-Store SNTP Rename +# 守候网络节点命名脚本 -`sntp-rename.js` 是一个 Sub-Store 节点处理脚本,用于根据节点名中的关键词自动注入线路属性标签,并专用于守候网络的节点。 +`sntp-rename.js` 是一个专用于守候网络节点命名的 Sub-Store 处理脚本。它会根据节点名称中的线路关键词,自动注入统一的线路标签,让节点列表更容易筛选、分组和识别。 -## 作用 +## 功能 脚本会遍历传入的 `proxies` 数组,检查每个代理节点的 `name` 字段。命中关键词后,会把对应标签追加到节点名中: @@ -10,6 +10,8 @@ - 如果节点名没有该后缀,标签会追加到名称末尾。 - 如果已经包含同样标签,不会重复注入。 +脚本只处理节点名称,不会修改协议、地址、端口或其他连接参数。 + ## 默认规则 | 命中关键词 | 注入标签 | @@ -20,7 +22,7 @@ | `S2` | `[广电]` | | `S3` | `[广移]` | | `S4` | `[广联]` | -| `BGP` | `[cn2\|5x]` | +| `BGP` | `[cn2]` | | `Anytls` | `[直连]` | ## 示例 @@ -31,6 +33,7 @@ 香港 GTM 0.5x - SNTP 01 广州 S1 - SNTP 02 日本 BGP 01 +深圳 Anytls - SNTP 03 普通节点 01 ``` @@ -39,7 +42,8 @@ ```text 香港 GTM 0.5x [三网] - SNTP 01 广州 S1 [广移] - SNTP 02 -日本 BGP 01 [cn2|5x] +日本 BGP 01 [cn2] +深圳 Anytls [直连] - SNTP 03 普通节点 01 ``` @@ -61,7 +65,7 @@ function operator(proxies) { ## 修改规则 -只需要编辑脚本顶部的 `featureMap`: +只需要编辑脚本顶部的 `featureMap`。左侧是节点名称中要识别的关键词,右侧是要注入的标签内容: ```javascript const featureMap = { @@ -71,7 +75,7 @@ const featureMap = { "S2": "广电", "S3": "广移", "S4": "广联", - "BGP": "cn2|5x", + "BGP": "cn2", "Anytls": "直连" }; ``` @@ -91,6 +95,5 @@ const featureMap = { ## 注意事项 -- 该脚本只修改节点名称,不修改节点协议、地址、端口或其他连接参数。 - 如果节点命中多个关键词,只会按当前正则排序匹配第一个。 - 如需支持更多后缀位置,可修改脚本中的 `suffixRegex`。 \ No newline at end of file diff --git a/substore/sntp-rename.js b/substore/sntp-rename.js index 154b79c..fd23300 100644 --- a/substore/sntp-rename.js +++ b/substore/sntp-rename.js @@ -24,66 +24,68 @@ function operator(proxies) { // 1. 初始化预处理:生成稳定的查找字典 (全大写+去空格) // 目的:无论节点名叫 "gtm 0.5x" 还是 "GTM0.5X",都能稳定映射 - const normalizedMap = {}; - const originalKeys = Object.keys(featureMap); - const normalizeKey = key => key.toUpperCase().replace(/\s+/g, ''); - const escapeRegex = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - for (const key of originalKeys) { - normalizedMap[normalizeKey(key)] = featureMap[key]; + const normalizedFeatureMap = {}; + const featureKeywords = Object.keys(featureMap); + const normalizeFeatureKeyword = keyword => keyword.toUpperCase().replace(/\s+/g, ''); + const escapeRegexKeyword = keyword => keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + for (const featureKeyword of featureKeywords) { + normalizedFeatureMap[normalizeFeatureKeyword(featureKeyword)] = featureMap[featureKeyword]; } // 2. 动态构建复合正则表达式 (核心引擎) // 按字符串长度降序排序,彻底解决 "短路匹配" (Short-Circuit) 问题 - const sortedKeys = [...originalKeys].sort((a, b) => b.length - a.length); + const sortedFeatureKeywords = [...featureKeywords].sort( + (firstFeatureKeyword, secondFeatureKeyword) => secondFeatureKeyword.length - firstFeatureKeyword.length + ); - const regexParts = sortedKeys.map(key => { + const featureRegexParts = sortedFeatureKeywords.map(featureKeyword => { // 自动转义正则特殊字符 (防注入报错) - const escapedKey = key.trim().split(/\s+/).filter(Boolean).map(escapeRegex).join('\\s*'); + const escapedKeywordPattern = featureKeyword.trim().split(/\s+/).filter(Boolean).map(escapeRegexKeyword).join('\\s*'); // 智能边界处理:如果关键词首尾都是字母或数字,就追加 \b 边界 // 这样能防止配置的 "S1" 错误匹配到 "US1" 或 "TLS1.3" - const trimmedKey = key.trim(); - if (/^[A-Za-z0-9]/.test(trimmedKey) && /[A-Za-z0-9]$/.test(trimmedKey)) { - return `\\b${escapedKey}\\b`; + const trimmedFeatureKeyword = featureKeyword.trim(); + if (/^[A-Za-z0-9]/.test(trimmedFeatureKeyword) && /[A-Za-z0-9]$/.test(trimmedFeatureKeyword)) { + return `\\b${escapedKeywordPattern}\\b`; } - return escapedKey; + return escapedKeywordPattern; }); // 动态拼接出类似: /(GTM\s*0\.5x|\bAnytls\b|\bBGP\b|...)/i - const featureRegex = new RegExp(`(${regexParts.join('|')})`, 'i'); + const featureRegex = new RegExp(`(${featureRegexParts.join('|')})`, 'i'); // 缓存后缀匹配正则,避免循环内重复创建 const suffixRegex = /(\s*-\s*SNTP.*)$/i; // 3. 执行节点遍历与注入 - return proxies.map(p => { - const name = p.name; - if (typeof name !== 'string') return p; + return proxies.map(proxy => { + const proxyName = proxy.name; + if (typeof proxyName !== 'string') return proxy; - // A. 单次复合正则扫描提取 - const match = name.match(featureRegex); - if (!match) return p; // 未命中配置库,直接放行 + // 单次复合正则扫描提取 + const featureMatch = proxyName.match(featureRegex); + if (!featureMatch) return proxy; // 未命中配置库,直接放行 - // B. 清洗提取到的特征词,并去 O(1) 字典中取值 - const mapKey = normalizeKey(match[1]); - const injectPayload = normalizedMap[mapKey]; + // 清洗提取到的特征词,并去 O(1) 字典中取值 + const normalizedMatchedKeyword = normalizeFeatureKeyword(featureMatch[1]); + const injectedFeatureLabel = normalizedFeatureMap[normalizedMatchedKeyword]; - if (!injectPayload) return p; // 兜底安全校验 + if (!injectedFeatureLabel) return proxy; // 兜底安全校验 - // C. 格式化组装与幂等校验 (防重复注入 Bug) - const formatStr = ` [${injectPayload}]`; - if (name.includes(formatStr)) { - return p; + // 格式化组装与幂等校验 (防重复注入 Bug) + const formattedFeatureLabel = ` [${injectedFeatureLabel}]`; + if (proxyName.includes(formattedFeatureLabel)) { + return proxy; } - // D. 实施中缀注入 (Infix Injection) - if (suffixRegex.test(name)) { - p.name = name.replace(suffixRegex, `${formatStr}$1`); + // 实施中缀注入 (Infix Injection) + if (suffixRegex.test(proxyName)) { + proxy.name = proxyName.replace(suffixRegex, `${formattedFeatureLabel}$1`); } else { // 纯净节点无后缀时,直接挂载在末尾 - p.name = name + formatStr; + proxy.name = proxyName + formattedFeatureLabel; } - return p; + return proxy; }); -} \ No newline at end of file +}