7a62f839f1
- 从各个重命名脚本中移除重复的工具函数实现 - 将 multiplierOf、multiplierValueOf、stripSubscriptionSuffix 等函数统一到 common.js - 使用 utils.multiplierOf、utils.multiplierValueOf 替代本地实现 - 引入 utils.createSequenceCounter 替代手动计数逻辑 - 更新版本号从 20260608-1 到 20260702-1 - 移除重复的正则表达式匹配逻辑 - 标准化序列计数器实现方式 - 优化 yinyun-rename.js 中的信息节点过滤逻辑
152 lines
5.0 KiB
JavaScript
152 lines
5.0 KiB
JavaScript
/**
|
|
* YueTong 专用节点清理脚本
|
|
* 负责去掉“悦·”品牌前缀、钻石、专属/家宽等线路标识,以及压短 AI 解锁文案。
|
|
* 按地区稳定归并后重新连续编号,避免专属/普通节点撞号。
|
|
*/
|
|
// noinspection JSUnusedGlobalSymbols
|
|
const COMMON_SCRIPT_VERSION = '20260702-1';
|
|
const COMMON_SCRIPT_URL = `https://git.orionc.me/orion/script/raw/branch/main/substore/common.js?v=${COMMON_SCRIPT_VERSION}`;
|
|
const hasCurrentRenameUtils = utils => Boolean(
|
|
utils && utils.version === COMMON_SCRIPT_VERSION
|
|
);
|
|
|
|
async function loadRenameUtils() {
|
|
if (typeof globalThis !== 'undefined' && hasCurrentRenameUtils(globalThis.SubStoreRenameUtils)) {
|
|
return globalThis.SubStoreRenameUtils;
|
|
}
|
|
|
|
const cache = typeof scriptResourceCache !== 'undefined' ? scriptResourceCache : null;
|
|
let script = cache && cache.get(COMMON_SCRIPT_URL);
|
|
if (!script) {
|
|
const response = await $substore.http.get({ url: COMMON_SCRIPT_URL });
|
|
script = response && (response.body || response.data || response);
|
|
if (cache) cache.set(COMMON_SCRIPT_URL, script);
|
|
}
|
|
|
|
new Function(String(script))();
|
|
if (!hasCurrentRenameUtils(globalThis.SubStoreRenameUtils)) {
|
|
throw new Error('Loaded common.js is missing current rename utilities');
|
|
}
|
|
return globalThis.SubStoreRenameUtils;
|
|
}
|
|
|
|
async function operator(proxies) {
|
|
const utils = await loadRenameUtils();
|
|
const regionAliases = [
|
|
['Hong Kong', 'HK'],
|
|
['香港', 'HK'],
|
|
['HK', 'HK'],
|
|
['Japan', 'JP'],
|
|
['日本', 'JP'],
|
|
['JP', 'JP'],
|
|
['Singapore', 'SG'],
|
|
['新加坡', 'SG'],
|
|
['狮城', 'SG'],
|
|
['SG', 'SG'],
|
|
['Taiwan', 'TW'],
|
|
['台湾', 'TW'],
|
|
['台灣', 'TW'],
|
|
['TW', 'TW'],
|
|
['United States', 'US'],
|
|
['America', 'US'],
|
|
['USA', 'US'],
|
|
['美国', 'US'],
|
|
['美國', 'US'],
|
|
['美西', 'US'],
|
|
['美东', 'US'],
|
|
['美東', 'US'],
|
|
['US', 'US'],
|
|
['Korea', 'KR'],
|
|
['韩国', 'KR'],
|
|
['韓國', 'KR'],
|
|
['KR', 'KR'],
|
|
['United Kingdom', 'UK'],
|
|
['Britain', 'UK'],
|
|
['英国', 'UK'],
|
|
['英國', 'UK'],
|
|
['UK', 'UK'],
|
|
['Germany', 'DE'],
|
|
['德国', 'DE'],
|
|
['德國', 'DE'],
|
|
['DE', 'DE'],
|
|
['Netherlands', 'NL'],
|
|
['荷兰', 'NL'],
|
|
['荷蘭', 'NL'],
|
|
['NL', 'NL']
|
|
];
|
|
const { regionCodeOf } = utils.createRegionResolver(regionAliases);
|
|
|
|
const withFreshRegionSequence = (name, sequenceNumber) => {
|
|
const { flag, text } = utils.splitLeadingFlag(name);
|
|
const sequenceText = String(sequenceNumber);
|
|
let core = text.trim();
|
|
let feature = '';
|
|
|
|
core = core.replace(/\s*AI\s*\d+(?!\d)(?!\s*(?:[xX倍]|\.\d))/, () => {
|
|
feature = 'AI';
|
|
return '';
|
|
});
|
|
if (!feature) {
|
|
core = core.replace(/\s+AI\b|AI$/, () => {
|
|
feature = 'AI';
|
|
return '';
|
|
});
|
|
}
|
|
|
|
core = core
|
|
.replace(/\s*\d+(?!\d)(?!\s*(?:[xX倍]|\.\d))(?=\s|$)/, '')
|
|
.replace(/\s{2,}/g, ' ');
|
|
|
|
return utils.normalizeWhitespace(`${flag}${core}${sequenceText}${feature ? ` ${feature}` : ''}`);
|
|
};
|
|
|
|
const normalizedItems = proxies.map((proxy, originalIndex) => {
|
|
if (typeof proxy.name !== 'string') {
|
|
return {
|
|
proxy,
|
|
originalIndex,
|
|
regionCode: ''
|
|
};
|
|
}
|
|
|
|
proxy.name = proxy.name
|
|
.replace(/悦[·・]\s*/g, '')
|
|
.replace(/AI解锁/g, 'AI')
|
|
.replace(/\s*(?:专属|家宽|高速|专线)(?:\s*(\d+)(?!\s*(?:[xX倍]|\.\d)))?/g, '$1')
|
|
.replace(/💎/gu, '')
|
|
.replace(/([\u4e00-\u9fff])AI\b/g, '$1 AI')
|
|
.replace(/\s{2,}/g, ' ');
|
|
proxy.name = utils.normalizeWhitespace(proxy.name);
|
|
|
|
return {
|
|
proxy,
|
|
originalIndex,
|
|
regionCode: regionCodeOf(proxy.name)
|
|
};
|
|
});
|
|
|
|
const regionOrder = Object.create(null);
|
|
const groupOrder = normalizedItems.map(item => {
|
|
if (!item.regionCode) return item.originalIndex;
|
|
if (regionOrder[item.regionCode] === undefined) {
|
|
regionOrder[item.regionCode] = item.originalIndex;
|
|
}
|
|
return regionOrder[item.regionCode];
|
|
});
|
|
|
|
normalizedItems.sort((firstItem, secondItem) => {
|
|
const firstGroupOrder = groupOrder[firstItem.originalIndex];
|
|
const secondGroupOrder = groupOrder[secondItem.originalIndex];
|
|
if (firstGroupOrder !== secondGroupOrder) return firstGroupOrder - secondGroupOrder;
|
|
return firstItem.originalIndex - secondItem.originalIndex;
|
|
});
|
|
|
|
const nextSequence = utils.createSequenceCounter();
|
|
return normalizedItems.map(item => {
|
|
if (!item.regionCode) return item.proxy;
|
|
|
|
item.proxy.name = withFreshRegionSequence(item.proxy.name, nextSequence(item.regionCode));
|
|
return item.proxy;
|
|
});
|
|
}
|