From 07ef71bf4afc82056702e5bfb4fdcb8eaa79eb77 Mon Sep 17 00:00:00 2001 From: Orion Date: Wed, 3 Jun 2026 10:12:11 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(substore):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20peiqian=20=E5=92=8C=20yuetong=20=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E8=84=9A=E6=9C=AC=E5=B9=B6=E4=BC=98=E5=8C=96=E7=8E=B0?= =?UTF-8?q?=E6=9C=89=E8=84=9A=E6=9C=AC=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- substore/alphaair-rename.js | 11 ++++++++--- substore/peiqian-rename.js | 34 ++++++++++++++++++++++++++++++++++ substore/rename.js | 15 ++++++++++----- substore/sntp-rename.js | 6 +++++- substore/yuetong-rename.js | 21 +++++++++++++++++++++ 5 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 substore/peiqian-rename.js create mode 100644 substore/yuetong-rename.js diff --git a/substore/alphaair-rename.js b/substore/alphaair-rename.js index d6f7c38..5f76ef6 100644 --- a/substore/alphaair-rename.js +++ b/substore/alphaair-rename.js @@ -5,6 +5,7 @@ * - 按地区内“普通 -> 倍率 -> 高级”排序并连续编号 * - 不追加订阅后缀,整合订阅最后仍交给 rename.js 处理 */ +// noinspection JSUnusedGlobalSymbols function operator(proxies) { const regionAliases = [ ['美国夏威夷', 'US HNL'], @@ -97,7 +98,7 @@ function operator(proxies) { const providerOf = name => { if (/SkyStroll/i.test(name)) return 'SkyStroll'; if (/isif/i.test(name)) return 'ISIF'; - if (/(?:搬瓦工|Bandwagon|BWH|BWG)/i.test(name)) return 'BWH'; + if (/搬瓦工|Bandwagon|BWH|BWG/i.test(name)) return 'BWH'; return ''; }; @@ -109,7 +110,7 @@ function operator(proxies) { const aliasRegionPrefixOf = name => { const cleanNameLower = name.toLowerCase(); - for (const [alias, replacement, aliasLower] of sortedRegionAliases) { + for (const [, replacement, aliasLower] of sortedRegionAliases) { if (cleanNameLower.includes(aliasLower)) return replacement; } @@ -123,7 +124,7 @@ function operator(proxies) { }; const regionPrefixOf = (name, flagRegionCode) => { - if (/(?:Hinet|Seednet)/i.test(name)) return 'TW'; + if (/Hinet|Seednet/i.test(name)) return 'TW'; return aliasRegionPrefixOf(name) || leadingRegionPrefixOf(name) || @@ -168,6 +169,10 @@ function operator(proxies) { }); normalizedItems.sort((firstItem, secondItem) => { + if (!firstItem.countryCode || !secondItem.countryCode) { + return firstItem.originalIndex - secondItem.originalIndex; + } + const firstOrder = countryOrder[firstItem.countryCode]; const secondOrder = countryOrder[secondItem.countryCode]; if (firstOrder !== secondOrder) return firstOrder - secondOrder; diff --git a/substore/peiqian-rename.js b/substore/peiqian-rename.js new file mode 100644 index 0000000..13eed79 --- /dev/null +++ b/substore/peiqian-rename.js @@ -0,0 +1,34 @@ +/** + * PeiQian 专用节点清理脚本 + * 负责清理推荐、用途、hy2、倍率等 PeiQian 节点文案。 + */ +// noinspection JSUnusedGlobalSymbols +function operator(proxies) { + return proxies.map(proxy => { + if (typeof proxy.name !== 'string') { + return proxy; + } + + proxy.name = proxy.name + .replace(/^AWS\s*新加坡\s*/i, '新加坡 AWS ') + .replace(/\s*\|\s*合适下载使用\s*-\s*(\d+(?:\.\d+)?)倍/gi, ' $1x') + .replace(/\s*\|\s*合适下载使用/gi, '') + .replace(/\s*\|\s*避免晚高峰使用/gi, '') + .replace(/\s*\|\s*电信联通移动推荐\s*-\s*hy2/gi, ' [三网 HY2]') + .replace(/\s*\|\s*电信联通移动推荐/gi, ' [三网]') + .replace(/\s*\|\s*电信联通推荐\s*-\s*hy2/gi, ' [电联 HY2]') + .replace(/\s*\|\s*电信联通推荐/gi, ' [电联]') + .replace(/\s*\|\s*移动联通推荐\s*-\s*hy2/gi, ' [移联 HY2]') + .replace(/\s*\|\s*移动联通推荐/gi, ' [移联]') + .replace(/\s*\|\s*高速专线(?:推荐)?\s*-\s*hy2/gi, ' [HY2]') + .replace(/\s*\|\s*高速专线推荐/gi, ' [专线]') + .replace(/\s*\|\s*三网推荐/gi, ' [三网]') + .replace(/-\s*(\d+(?:\.\d+)?)倍/gi, ' $1x') + .replace(/(\d+(?:\.\d+)?)倍/gi, '$1x') + .replace(/\s+\[/g, ' [') + .replace(/\s{2,}/g, ' ') + .trim(); + + return proxy; + }); +} diff --git a/substore/rename.js b/substore/rename.js index 11bcd57..09ccda9 100644 --- a/substore/rename.js +++ b/substore/rename.js @@ -4,6 +4,7 @@ * - 清理常见冗余线路描述,例如 DIP 地区说明、IEPL 专线 * - 基于归一化后的完整名称做精准去重 */ +// noinspection JSUnusedGlobalSymbols function operator(proxies) { const globalCount = Object.create(null); const currentCount = Object.create(null); @@ -552,7 +553,10 @@ function operator(proxies) { ); Object.values(flagCodeOverrides).forEach(code => knownRegionCodes.add(code)); - const escapeRegex = value => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regexSpecialChars = new Set(['.', '*', '+', '?', '^', '$', '{', '}', '(', ')', '|', '[', ']', '\\']); + const escapeRegex = value => [...value] + .map(char => regexSpecialChars.has(char) ? `\\${char}` : char) + .join(''); const leadingFlagRegex = /^([\u{1F1E6}-\u{1F1FF}]{2}|🏴‍☠️)\s*/u; const inlineFlagRegex = /^(.{1,24}?)([\u{1F1E6}-\u{1F1FF}]{2}|🏴‍☠️)\s*(.*)$/u; @@ -692,15 +696,16 @@ function operator(proxies) { } core = core - .replace(/\[DIP[^\]]*\]/gi, '[DIP]'); + .replace(/\[DIP.*?]/gi, '[DIP]'); core = normalizeBilingualName(core); core = normalizeLeadingRegion(core); if (/^Pro-\s*/i.test(core)) { - core = core.replace(/^(Pro-\s*)(.+)$/i, (fullMatch, proPrefix, restName) => { - return `${proPrefix}${normalizeLeadingRegion(restName)}`; - }); + const proMatch = core.match(/^(Pro-\s*)(.+)$/i); + if (proMatch) { + core = `${proMatch[1]}${normalizeLeadingRegion(proMatch[2])}`; + } } core = core diff --git a/substore/sntp-rename.js b/substore/sntp-rename.js index 253effb..ea05690 100644 --- a/substore/sntp-rename.js +++ b/substore/sntp-rename.js @@ -3,6 +3,7 @@ * 核心架构:动态按长度排序编译正则 + 智能边界识别 + O(1) 映射提取 * 维护说明:仅需修改 featureMap 字典即可,底部逻辑永远无需改动。 */ +// noinspection JSUnusedGlobalSymbols function operator(proxies) { // ================= 唯一配置区 ================= // 在这里新增或修改关键词。格式:"节点关键词": "想要注入的标签" @@ -29,7 +30,10 @@ function operator(proxies) { const normalizedFeatureMap = {}; const featureKeywords = Object.keys(featureMap); const normalizeFeatureKeyword = keyword => keyword.toUpperCase().replace(/\s+/g, ''); - const escapeRegexKeyword = keyword => keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regexSpecialChars = new Set(['.', '*', '+', '?', '^', '$', '{', '}', '(', ')', '|', '[', ']', '\\']); + const escapeRegexKeyword = keyword => [...keyword] + .map(char => regexSpecialChars.has(char) ? `\\${char}` : char) + .join(''); for (const featureKeyword of featureKeywords) { normalizedFeatureMap[normalizeFeatureKeyword(featureKeyword)] = featureMap[featureKeyword]; } diff --git a/substore/yuetong-rename.js b/substore/yuetong-rename.js new file mode 100644 index 0000000..97ceb4f --- /dev/null +++ b/substore/yuetong-rename.js @@ -0,0 +1,21 @@ +/** + * YueTong 专用节点清理脚本 + * 负责去掉“悦·”品牌前缀、钻石等装饰,以及压短 AI 解锁文案。 + */ +// noinspection JSUnusedGlobalSymbols +function operator(proxies) { + return proxies.map(proxy => { + if (typeof proxy.name !== 'string') { + return proxy; + } + + proxy.name = proxy.name + .replace(/悦[·・]\s*/g, '') + .replace(/AI解锁/g, 'AI') + .replace(/💎/gu, '') + .replace(/\s{2,}/g, ' ') + .trim(); + + return proxy; + }); +}