Skip to content

Commit faa14e5

Browse files
committed
feat: 增强订阅链接处理逻辑,支持备注名并优化IP格式
1 parent 436ea99 commit faa14e5

1 file changed

Lines changed: 74 additions & 13 deletions

File tree

_worker.js

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,19 +1793,45 @@ async function 请求优选API(urls, 默认端口 = '443', 超时时间 = 3000)
17931793
const results = new Set();
17941794
let 订阅链接响应的明文LINK内容 = '', 需要订阅转换订阅URLs = [];
17951795
await Promise.allSettled(urls.map(async (url) => {
1796-
if (url.toLowerCase().startsWith('sub://')) {
1796+
// 检查URL是否包含备注名
1797+
const hashIndex = url.indexOf('#');
1798+
const urlWithoutHash = hashIndex > -1 ? url.substring(0, hashIndex) : url;
1799+
const API备注名 = hashIndex > -1 ? decodeURIComponent(url.substring(hashIndex + 1)) : null;
1800+
1801+
if (urlWithoutHash.toLowerCase().startsWith('sub://')) {
17971802
try {
1798-
const [优选IP, 其他节点LINK] = await 获取优选订阅生成器数据(url);
1799-
for (const ip of 优选IP) results.add(ip);
1800-
if (其他节点LINK) 订阅链接响应的明文LINK内容 += 其他节点LINK;
1803+
const [优选IP, 其他节点LINK] = await 获取优选订阅生成器数据(urlWithoutHash);
1804+
// 处理第一个数组 - 优选IP
1805+
if (API备注名) {
1806+
for (const ip of 优选IP) {
1807+
const 处理后IP = ip.includes('#')
1808+
? `${ip} [${API备注名}]`
1809+
: `${ip}#[${API备注名}]`;
1810+
results.add(处理后IP);
1811+
}
1812+
} else {
1813+
for (const ip of 优选IP) results.add(ip);
1814+
}
1815+
// 处理第二个数组 - 其他节点LINK
1816+
if (其他节点LINK && typeof 其他节点LINK === 'string' && API备注名) {
1817+
const 处理后LINK内容 = 其他节点LINK.replace(/([a-z][a-z0-9+\-.]*:\/\/[^\r\n]*?)(\r?\n|$)/gi, (match, link, lineEnd) => {
1818+
const 完整链接 = link.includes('#')
1819+
? `${link}${encodeURIComponent(` [${API备注名}]`)}`
1820+
: `${link}${encodeURIComponent(`#[${API备注名}]`)}`;
1821+
return `${完整链接}${lineEnd}`;
1822+
});
1823+
订阅链接响应的明文LINK内容 += 处理后LINK内容;
1824+
} else if (其他节点LINK && typeof 其他节点LINK === 'string') {
1825+
订阅链接响应的明文LINK内容 += 其他节点LINK;
1826+
}
18011827
} catch (e) { }
18021828
return;
18031829
}
18041830

18051831
try {
18061832
const controller = new AbortController();
18071833
const timeoutId = setTimeout(() => controller.abort(), 超时时间);
1808-
const response = await fetch(url, { signal: controller.signal });
1834+
const response = await fetch(urlWithoutHash, { signal: controller.signal });
18091835
clearTimeout(timeoutId);
18101836
let text = '';
18111837
try {
@@ -1863,26 +1889,47 @@ async function 请求优选API(urls, 默认端口 = '443', 超时时间 = 3000)
18631889

18641890
const 预处理订阅明文内容 = isValidBase64(text) ? base64Decode(text) : text;
18651891
if (预处理订阅明文内容.split('#')[0].includes('://')) {
1866-
订阅链接响应的明文LINK内容 += 预处理订阅明文内容 + '\n'; // 追加LINK明文内容
1892+
// 处理LINK内容
1893+
if (API备注名) {
1894+
const 处理后LINK内容 = 预处理订阅明文内容.replace(/([a-z][a-z0-9+\-.]*:\/\/[^\r\n]*?)(\r?\n|$)/gi, (match, link, lineEnd) => {
1895+
const 完整链接 = link.includes('#')
1896+
? `${link}${encodeURIComponent(` [${API备注名}]`)}`
1897+
: `${link}${encodeURIComponent(`#[${API备注名}]`)}`;
1898+
return `${完整链接}${lineEnd}`;
1899+
});
1900+
订阅链接响应的明文LINK内容 += 处理后LINK内容 + '\n';
1901+
} else {
1902+
订阅链接响应的明文LINK内容 += 预处理订阅明文内容 + '\n';
1903+
}
18671904
return;
18681905
}
18691906

18701907
const lines = text.trim().split('\n').map(l => l.trim()).filter(l => l);
18711908
const isCSV = lines.length > 1 && lines[0].includes(',');
18721909
const IPV6_PATTERN = /^[^\[\]]*:[^\[\]]*:[^\[\]]/;
1910+
const parsedUrl = new URL(urlWithoutHash);
18731911
if (!isCSV) {
18741912
lines.forEach(line => {
1875-
const hashIndex = line.indexOf('#');
1876-
const [hostPart, remark] = hashIndex > -1 ? [line.substring(0, hashIndex), line.substring(hashIndex)] : [line, ''];
1913+
const lineHashIndex = line.indexOf('#');
1914+
const [hostPart, remark] = lineHashIndex > -1 ? [line.substring(0, lineHashIndex), line.substring(lineHashIndex)] : [line, ''];
18771915
let hasPort = false;
18781916
if (hostPart.startsWith('[')) {
18791917
hasPort = /\]:(\d+)$/.test(hostPart);
18801918
} else {
18811919
const colonIndex = hostPart.lastIndexOf(':');
18821920
hasPort = colonIndex > -1 && /^\d+$/.test(hostPart.substring(colonIndex + 1));
18831921
}
1884-
const port = new URL(url).searchParams.get('port') || 默认端口;
1885-
results.add(hasPort ? line : `${hostPart}:${port}${remark}`);
1922+
const port = parsedUrl.searchParams.get('port') || 默认端口;
1923+
const ipItem = hasPort ? line : `${hostPart}:${port}${remark}`;
1924+
// 处理第一个数组 - 优选IP
1925+
if (API备注名) {
1926+
const 处理后IP = ipItem.includes('#')
1927+
? `${ipItem} [${API备注名}]`
1928+
: `${ipItem}#[${API备注名}]`;
1929+
results.add(处理后IP);
1930+
} else {
1931+
results.add(ipItem);
1932+
}
18861933
});
18871934
} else {
18881935
const headers = lines[0].split(',').map(h => h.trim());
@@ -1896,17 +1943,31 @@ async function 请求优选API(urls, 默认端口 = '443', 超时时间 = 3000)
18961943
const cols = line.split(',').map(c => c.trim());
18971944
if (tlsIdx !== -1 && cols[tlsIdx]?.toLowerCase() !== 'true') return;
18981945
const wrappedIP = IPV6_PATTERN.test(cols[ipIdx]) ? `[${cols[ipIdx]}]` : cols[ipIdx];
1899-
results.add(`${wrappedIP}:${cols[portIdx]}#${cols[remarkIdx]}`);
1946+
const ipItem = `${wrappedIP}:${cols[portIdx]}#${cols[remarkIdx]}`;
1947+
// 处理第一个数组 - 优选IP
1948+
if (API备注名) {
1949+
const 处理后IP = `${ipItem} [${API备注名}]`;
1950+
results.add(处理后IP);
1951+
} else {
1952+
results.add(ipItem);
1953+
}
19001954
});
19011955
} else if (headers.some(h => h.includes('IP')) && headers.some(h => h.includes('延迟')) && headers.some(h => h.includes('下载速度'))) {
19021956
const ipIdx = headers.findIndex(h => h.includes('IP'));
19031957
const delayIdx = headers.findIndex(h => h.includes('延迟'));
19041958
const speedIdx = headers.findIndex(h => h.includes('下载速度'));
1905-
const port = new URL(url).searchParams.get('port') || 默认端口;
1959+
const port = parsedUrl.searchParams.get('port') || 默认端口;
19061960
dataLines.forEach(line => {
19071961
const cols = line.split(',').map(c => c.trim());
19081962
const wrappedIP = IPV6_PATTERN.test(cols[ipIdx]) ? `[${cols[ipIdx]}]` : cols[ipIdx];
1909-
results.add(`${wrappedIP}:${port}#CF优选 ${cols[delayIdx]}ms ${cols[speedIdx]}MB/s`);
1963+
const ipItem = `${wrappedIP}:${port}#CF优选 ${cols[delayIdx]}ms ${cols[speedIdx]}MB/s`;
1964+
// 处理第一个数组 - 优选IP
1965+
if (API备注名) {
1966+
const 处理后IP = `${ipItem} [${API备注名}]`;
1967+
results.add(处理后IP);
1968+
} else {
1969+
results.add(ipItem);
1970+
}
19101971
});
19111972
}
19121973
}

0 commit comments

Comments
 (0)