7a62f839f1
- 从各个重命名脚本中移除重复的工具函数实现 - 将 multiplierOf、multiplierValueOf、stripSubscriptionSuffix 等函数统一到 common.js - 使用 utils.multiplierOf、utils.multiplierValueOf 替代本地实现 - 引入 utils.createSequenceCounter 替代手动计数逻辑 - 更新版本号从 20260608-1 到 20260702-1 - 移除重复的正则表达式匹配逻辑 - 标准化序列计数器实现方式 - 优化 yinyun-rename.js 中的信息节点过滤逻辑
123 lines
4.6 KiB
JavaScript
123 lines
4.6 KiB
JavaScript
/**
|
|
* Iris Cloud 专用节点清理脚本
|
|
* - Iris Cloud 名称里 HK 是入口/线路名的一部分,落地以尾部 SG、TYO、HKG 等标识为准
|
|
* - 包含 SG 的节点归新加坡,包含 TYO/JP 的节点归日本,明确 HK/iCable 的节点归香港
|
|
* - 无法识别为 Iris Cloud 节点的名称原样放行,不参与排序和编号
|
|
* - 去掉 SZ/HZ/[Edge] 入口标签,保留倍率,压掉供应商和入口线路特征
|
|
*/
|
|
// 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 landingPrefixOf = name => {
|
|
if (/^(?:US)(?:$|[\s|.-])/i.test(name)) return 'US';
|
|
if (/(?:^|[-\s])SG(?:$|[-\s.])/i.test(name)) return 'SG';
|
|
if (/(?:^|[-\s])TYO(?:$|[-\s])/i.test(name)) return 'JP TYO';
|
|
if (/(?:^|[-\s])JP(?:$|[-\s])/i.test(name)) return 'JP';
|
|
if (/(?:^|[-\s])HK(?:$|[-\s])/i.test(name)) return 'HK';
|
|
if (/iCable/i.test(name)) return 'HK';
|
|
return '';
|
|
};
|
|
|
|
const cleanCoreName = name => {
|
|
const { text } = utils.splitLeadingOrInlineFlag(name);
|
|
return utils.stripSubscriptionSuffix(text, 'Iris Cloud')
|
|
.replace(/^\s*(?:SZ|HZ)\s+\d{1,2}\s+/i, '')
|
|
.replace(/^\s*\[Edge]\s*/i, '')
|
|
.trim();
|
|
};
|
|
|
|
const normalizedItems = proxies.map((proxy, originalIndex) => {
|
|
if (typeof proxy.name !== 'string') {
|
|
return {
|
|
proxy,
|
|
originalIndex,
|
|
regionPrefix: ''
|
|
};
|
|
}
|
|
|
|
const coreName = cleanCoreName(proxy.name);
|
|
const regionPrefix = landingPrefixOf(coreName);
|
|
if (!regionPrefix) {
|
|
return {
|
|
proxy,
|
|
originalIndex,
|
|
regionPrefix: ''
|
|
};
|
|
}
|
|
|
|
const regionCode = regionPrefix.split(/\s+/)[0];
|
|
|
|
return {
|
|
proxy,
|
|
originalIndex,
|
|
regionPrefix,
|
|
regionCode,
|
|
multiplier: utils.multiplierOf(coreName),
|
|
flag: utils.regionCodeToFlag(regionCode)
|
|
};
|
|
});
|
|
|
|
const regionOrder = Object.create(null);
|
|
let regionOrderCount = 0;
|
|
normalizedItems.forEach(item => {
|
|
if (!item.regionPrefix || regionOrder[item.regionPrefix] !== undefined) return;
|
|
regionOrder[item.regionPrefix] = regionOrderCount++;
|
|
});
|
|
|
|
normalizedItems.sort((firstItem, secondItem) => {
|
|
if (!firstItem.regionPrefix || !secondItem.regionPrefix) {
|
|
return firstItem.originalIndex - secondItem.originalIndex;
|
|
}
|
|
|
|
const firstRegionOrder = regionOrder[firstItem.regionPrefix];
|
|
const secondRegionOrder = regionOrder[secondItem.regionPrefix];
|
|
if (firstRegionOrder !== secondRegionOrder) return firstRegionOrder - secondRegionOrder;
|
|
const firstMultiplierValue = utils.multiplierValueOf(firstItem.multiplier);
|
|
const secondMultiplierValue = utils.multiplierValueOf(secondItem.multiplier);
|
|
if (firstMultiplierValue !== secondMultiplierValue) {
|
|
return firstMultiplierValue - secondMultiplierValue;
|
|
}
|
|
return firstItem.originalIndex - secondItem.originalIndex;
|
|
});
|
|
|
|
const nextSequence = utils.createSequenceCounter();
|
|
return normalizedItems.map(item => {
|
|
if (!item.regionPrefix) return item.proxy;
|
|
|
|
item.proxy.name = [
|
|
item.flag,
|
|
item.regionPrefix,
|
|
nextSequence(item.regionPrefix),
|
|
item.multiplier
|
|
].filter(Boolean).join(' ').trim();
|
|
return item.proxy;
|
|
});
|
|
}
|