/** * Sub-Store 整合订阅后缀脚本 * - 保留节点原名,只追加当前订阅的 `_subName` * - 重复执行不会叠加相同的订阅后缀 * - 同名节点追加两位编号,避免节点名重复 */ // 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 stripSubscriptionSuffix = utils.stripSubscriptionSuffix || ((name, subName) => { const cleanSubName = String(subName || '').trim(); if (!cleanSubName) return String(name); const escapeRegex = utils.escapeRegex || (value => String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&')); return String(name) .replace(new RegExp(`\\s+-\\s*${escapeRegex(cleanSubName)}(?:\\s+\\d{2})?\\s*$`, 'i'), '') .trim(); }); const nameCounts = Object.create(null); const currentCounts = Object.create(null); const baseNames = new Array(proxies.length); const coreNames = new Array(proxies.length); const subNames = new Array(proxies.length); proxies.forEach((proxy, proxyIndex) => { // 非对象或非字符串名称不参与处理,避免改动无效节点数据。 if (!proxy || typeof proxy !== 'object' || typeof proxy.name !== 'string') { baseNames[proxyIndex] = null; return; } const proxyName = proxy.name; const subName = proxy && typeof proxy._subName === 'string' ? proxy._subName.trim() : ''; // 没有订阅名时完全保留原字符串;公共工具的兼容实现会顺手 trim。 const coreName = subName ? stripSubscriptionSuffix(proxyName, subName) : proxyName; const baseName = subName ? (coreName ? `${coreName} - ${subName}` : subName) : coreName; baseNames[proxyIndex] = baseName; coreNames[proxyIndex] = coreName; subNames[proxyIndex] = subName; nameCounts[baseName] = (nameCounts[baseName] || 0) + 1; }); return proxies.map((proxy, proxyIndex) => { const baseName = baseNames[proxyIndex]; if (baseName === null || !proxy || typeof proxy !== 'object') return proxy; if (nameCounts[baseName] > 1) { currentCounts[baseName] = (currentCounts[baseName] || 0) + 1; const duplicateNumber = String(currentCounts[baseName]).padStart(2, '0'); proxy.name = subNames[proxyIndex] ? `${coreNames[proxyIndex]} ${duplicateNumber} - ${subNames[proxyIndex]}` : `${baseName} ${duplicateNumber}`; } else { proxy.name = baseName; } return proxy; }); }