refactor(core): ♻️ 重构节点重命名脚本变量命名与文档
对 sntp-rename.js 进行代码重构,通过更具描述性的变量名(如 featureKeyword, proxyName)提高代码可读性。同时更新项目文档,明确该脚本专用于“守候网络” 节点命名,并对默认规则和使用说明进行了优化。 - 优化变量命名以更清晰地表达业务逻辑 - 更新 README 完善守候网络节点的命名说明 - 格式化代码逻辑以增强可维护性
This commit is contained in:
@@ -24,7 +24,7 @@ script/
|
|||||||
| 目录 | 脚本 | 用途 | 运行环境 |
|
| 目录 | 脚本 | 用途 | 运行环境 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `homebrew/` | `brew-upgrade-manager.sh` | 自动更新 Homebrew、升级 Formula/Cask、清理缓存 | macOS、Bash、Homebrew |
|
| `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 |
|
| `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 节点标签注入
|
### 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)。
|
详细规则见 [substore/README.md](substore/README.md)。
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Sub-Store SNTP Rename
|
# 守候网络节点命名脚本
|
||||||
|
|
||||||
`sntp-rename.js` 是一个 Sub-Store 节点处理脚本,用于根据节点名中的关键词自动注入线路属性标签,并专用于守候网络的节点。
|
`sntp-rename.js` 是一个专用于守候网络节点命名的 Sub-Store 处理脚本。它会根据节点名称中的线路关键词,自动注入统一的线路标签,让节点列表更容易筛选、分组和识别。
|
||||||
|
|
||||||
## 作用
|
## 功能
|
||||||
|
|
||||||
脚本会遍历传入的 `proxies` 数组,检查每个代理节点的 `name` 字段。命中关键词后,会把对应标签追加到节点名中:
|
脚本会遍历传入的 `proxies` 数组,检查每个代理节点的 `name` 字段。命中关键词后,会把对应标签追加到节点名中:
|
||||||
|
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
- 如果节点名没有该后缀,标签会追加到名称末尾。
|
- 如果节点名没有该后缀,标签会追加到名称末尾。
|
||||||
- 如果已经包含同样标签,不会重复注入。
|
- 如果已经包含同样标签,不会重复注入。
|
||||||
|
|
||||||
|
脚本只处理节点名称,不会修改协议、地址、端口或其他连接参数。
|
||||||
|
|
||||||
## 默认规则
|
## 默认规则
|
||||||
|
|
||||||
| 命中关键词 | 注入标签 |
|
| 命中关键词 | 注入标签 |
|
||||||
@@ -20,7 +22,7 @@
|
|||||||
| `S2` | `[广电]` |
|
| `S2` | `[广电]` |
|
||||||
| `S3` | `[广移]` |
|
| `S3` | `[广移]` |
|
||||||
| `S4` | `[广联]` |
|
| `S4` | `[广联]` |
|
||||||
| `BGP` | `[cn2\|5x]` |
|
| `BGP` | `[cn2]` |
|
||||||
| `Anytls` | `[直连]` |
|
| `Anytls` | `[直连]` |
|
||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
@@ -31,6 +33,7 @@
|
|||||||
香港 GTM 0.5x - SNTP 01
|
香港 GTM 0.5x - SNTP 01
|
||||||
广州 S1 - SNTP 02
|
广州 S1 - SNTP 02
|
||||||
日本 BGP 01
|
日本 BGP 01
|
||||||
|
深圳 Anytls - SNTP 03
|
||||||
普通节点 01
|
普通节点 01
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -39,7 +42,8 @@
|
|||||||
```text
|
```text
|
||||||
香港 GTM 0.5x [三网] - SNTP 01
|
香港 GTM 0.5x [三网] - SNTP 01
|
||||||
广州 S1 [广移] - SNTP 02
|
广州 S1 [广移] - SNTP 02
|
||||||
日本 BGP 01 [cn2|5x]
|
日本 BGP 01 [cn2]
|
||||||
|
深圳 Anytls [直连] - SNTP 03
|
||||||
普通节点 01
|
普通节点 01
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ function operator(proxies) {
|
|||||||
|
|
||||||
## 修改规则
|
## 修改规则
|
||||||
|
|
||||||
只需要编辑脚本顶部的 `featureMap`:
|
只需要编辑脚本顶部的 `featureMap`。左侧是节点名称中要识别的关键词,右侧是要注入的标签内容:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const featureMap = {
|
const featureMap = {
|
||||||
@@ -71,7 +75,7 @@ const featureMap = {
|
|||||||
"S2": "广电",
|
"S2": "广电",
|
||||||
"S3": "广移",
|
"S3": "广移",
|
||||||
"S4": "广联",
|
"S4": "广联",
|
||||||
"BGP": "cn2|5x",
|
"BGP": "cn2",
|
||||||
"Anytls": "直连"
|
"Anytls": "直连"
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
@@ -91,6 +95,5 @@ const featureMap = {
|
|||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
- 该脚本只修改节点名称,不修改节点协议、地址、端口或其他连接参数。
|
|
||||||
- 如果节点命中多个关键词,只会按当前正则排序匹配第一个。
|
- 如果节点命中多个关键词,只会按当前正则排序匹配第一个。
|
||||||
- 如需支持更多后缀位置,可修改脚本中的 `suffixRegex`。
|
- 如需支持更多后缀位置,可修改脚本中的 `suffixRegex`。
|
||||||
@@ -24,66 +24,68 @@ function operator(proxies) {
|
|||||||
|
|
||||||
// 1. 初始化预处理:生成稳定的查找字典 (全大写+去空格)
|
// 1. 初始化预处理:生成稳定的查找字典 (全大写+去空格)
|
||||||
// 目的:无论节点名叫 "gtm 0.5x" 还是 "GTM0.5X",都能稳定映射
|
// 目的:无论节点名叫 "gtm 0.5x" 还是 "GTM0.5X",都能稳定映射
|
||||||
const normalizedMap = {};
|
const normalizedFeatureMap = {};
|
||||||
const originalKeys = Object.keys(featureMap);
|
const featureKeywords = Object.keys(featureMap);
|
||||||
const normalizeKey = key => key.toUpperCase().replace(/\s+/g, '');
|
const normalizeFeatureKeyword = keyword => keyword.toUpperCase().replace(/\s+/g, '');
|
||||||
const escapeRegex = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
const escapeRegexKeyword = keyword => keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
for (const key of originalKeys) {
|
for (const featureKeyword of featureKeywords) {
|
||||||
normalizedMap[normalizeKey(key)] = featureMap[key];
|
normalizedFeatureMap[normalizeFeatureKeyword(featureKeyword)] = featureMap[featureKeyword];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 动态构建复合正则表达式 (核心引擎)
|
// 2. 动态构建复合正则表达式 (核心引擎)
|
||||||
// 按字符串长度降序排序,彻底解决 "短路匹配" (Short-Circuit) 问题
|
// 按字符串长度降序排序,彻底解决 "短路匹配" (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 边界
|
// 智能边界处理:如果关键词首尾都是字母或数字,就追加 \b 边界
|
||||||
// 这样能防止配置的 "S1" 错误匹配到 "US1" 或 "TLS1.3"
|
// 这样能防止配置的 "S1" 错误匹配到 "US1" 或 "TLS1.3"
|
||||||
const trimmedKey = key.trim();
|
const trimmedFeatureKeyword = featureKeyword.trim();
|
||||||
if (/^[A-Za-z0-9]/.test(trimmedKey) && /[A-Za-z0-9]$/.test(trimmedKey)) {
|
if (/^[A-Za-z0-9]/.test(trimmedFeatureKeyword) && /[A-Za-z0-9]$/.test(trimmedFeatureKeyword)) {
|
||||||
return `\\b${escapedKey}\\b`;
|
return `\\b${escapedKeywordPattern}\\b`;
|
||||||
}
|
}
|
||||||
return escapedKey;
|
return escapedKeywordPattern;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 动态拼接出类似: /(GTM\s*0\.5x|\bAnytls\b|\bBGP\b|...)/i
|
// 动态拼接出类似: /(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;
|
const suffixRegex = /(\s*-\s*SNTP.*)$/i;
|
||||||
|
|
||||||
// 3. 执行节点遍历与注入
|
// 3. 执行节点遍历与注入
|
||||||
return proxies.map(p => {
|
return proxies.map(proxy => {
|
||||||
const name = p.name;
|
const proxyName = proxy.name;
|
||||||
if (typeof name !== 'string') return p;
|
if (typeof proxyName !== 'string') return proxy;
|
||||||
|
|
||||||
// A. 单次复合正则扫描提取
|
// 单次复合正则扫描提取
|
||||||
const match = name.match(featureRegex);
|
const featureMatch = proxyName.match(featureRegex);
|
||||||
if (!match) return p; // 未命中配置库,直接放行
|
if (!featureMatch) return proxy; // 未命中配置库,直接放行
|
||||||
|
|
||||||
// B. 清洗提取到的特征词,并去 O(1) 字典中取值
|
// 清洗提取到的特征词,并去 O(1) 字典中取值
|
||||||
const mapKey = normalizeKey(match[1]);
|
const normalizedMatchedKeyword = normalizeFeatureKeyword(featureMatch[1]);
|
||||||
const injectPayload = normalizedMap[mapKey];
|
const injectedFeatureLabel = normalizedFeatureMap[normalizedMatchedKeyword];
|
||||||
|
|
||||||
if (!injectPayload) return p; // 兜底安全校验
|
if (!injectedFeatureLabel) return proxy; // 兜底安全校验
|
||||||
|
|
||||||
// C. 格式化组装与幂等校验 (防重复注入 Bug)
|
// 格式化组装与幂等校验 (防重复注入 Bug)
|
||||||
const formatStr = ` [${injectPayload}]`;
|
const formattedFeatureLabel = ` [${injectedFeatureLabel}]`;
|
||||||
if (name.includes(formatStr)) {
|
if (proxyName.includes(formattedFeatureLabel)) {
|
||||||
return p;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// D. 实施中缀注入 (Infix Injection)
|
// 实施中缀注入 (Infix Injection)
|
||||||
if (suffixRegex.test(name)) {
|
if (suffixRegex.test(proxyName)) {
|
||||||
p.name = name.replace(suffixRegex, `${formatStr}$1`);
|
proxy.name = proxyName.replace(suffixRegex, `${formattedFeatureLabel}$1`);
|
||||||
} else {
|
} else {
|
||||||
// 纯净节点无后缀时,直接挂载在末尾
|
// 纯净节点无后缀时,直接挂载在末尾
|
||||||
p.name = name + formatStr;
|
proxy.name = proxyName + formattedFeatureLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return proxy;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user