From d02d4a9de9eecf2ffc101975629af0fd3609fa27 Mon Sep 17 00:00:00 2001 From: q15050182747-ops Date: Fri, 13 Feb 2026 21:57:21 +0800 Subject: [PATCH] Update print statement from 'Hello' to 'Goodbye' --- _worker.js | 1949 +++++++++------------------------------------------- 1 file changed, 307 insertions(+), 1642 deletions(-) diff --git a/_worker.js b/_worker.js index 80145be..c4d7f85 100644 --- a/_worker.js +++ b/_worker.js @@ -1,1697 +1,362 @@ -// Cloudflare Worker - 简化版优选工具 -// 仅保留优选域名、优选IP、GitHub、上报和节点生成功能 -// 修复记录:已修正 VMess 协议下节点名称包含中文导致 Error 1101 的问题 +// Cloudflare Workers 优选工具 +// GitHub: https://github.com/byJoey/yx-auto -// 默认配置 -let customPreferredIPs = []; -let customPreferredDomains = []; -let epd = true; // 启用优选域名 -let epi = true; // 启用优选IP -let egi = true; // 启用GitHub优选 -let ev = true; // 启用VLESS协议 -let et = false; // 启用Trojan协议 -let vm = false; // 启用VMess协议 -let scu = 'https://url.v1.mk/sub'; // 订阅转换地址 -// ECH (Encrypted Client Hello) -let enableECH = false; -let customDNS = 'https://dns.joeyblog.eu.org/joeyblog'; -let customECHDomain = 'cloudflare-ech.com'; +const HTML_CONTENT = ` + + + + + + 优选订阅生成器 + + + +
+

🚀 优选订阅生成器

+
+ 使用说明:填写域名和UUID,选择协议和客户端类型,点击生成订阅链接。 +
+
+
+ + +
+
+ + +
+
+ +
+
VLESS
+
Trojan
+
VMess
+
+
+
+ +
+
默认域名
+
优选IP
+
GitHub优选
+
+
+
+ +
+
移动
+
联通
+
电信
+
+
+
+ +
+
IPv4
+
IPv6
+
+
+
+ + +
+
+ + +
+ +
+ +
+ + + +`; // 默认优选域名列表 -const directDomains = [ - { name: "cloudflare.182682.xyz", domain: "cloudflare.182682.xyz" }, - { domain: "freeyx.cloudflare88.eu.org" }, - { domain: "bestcf.top" }, - { domain: "cdn.2020111.xyz" }, - { domain: "cf.0sm.com" }, - { domain: "cf.090227.xyz" }, - { domain: "cf.zhetengsha.eu.org" }, - { domain: "cfip.1323123.xyz" }, - { domain: "cloudflare-ip.mofashi.ltd" }, - { domain: "cf.877771.xyz" }, - { domain: "xn--b6gac.eu.org" } +const DEFAULT_DOMAINS = [ + 'www.visa.com.sg', + 'www.visa.com.hk', + 'www.visa.com.tw', + 'www.gstatic.com', + 'www.digitalocean.com' ]; -// 默认优选IP来源URL -const defaultIPURL = 'https://raw.githubusercontent.com/qwer-search/bestip/refs/heads/main/kejilandbestip.txt'; - -// UUID验证 -function isValidUUID(str) { - const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; - return uuidRegex.test(str); -} - -// 从环境变量获取配置 -function getConfigValue(key, defaultValue) { - return defaultValue || ''; -} - -// 获取动态IP列表(支持IPv4/IPv6和运营商筛选) -async function fetchDynamicIPs(ipv4Enabled = true, ipv6Enabled = true, ispMobile = true, ispUnicom = true, ispTelecom = true) { - const v4Url = "https://www.wetest.vip/page/cloudflare/address_v4.html"; - const v6Url = "https://www.wetest.vip/page/cloudflare/address_v6.html"; - let results = []; - - try { - const fetchPromises = []; - if (ipv4Enabled) { - fetchPromises.push(fetchAndParseWetest(v4Url)); - } else { - fetchPromises.push(Promise.resolve([])); - } - if (ipv6Enabled) { - fetchPromises.push(fetchAndParseWetest(v6Url)); - } else { - fetchPromises.push(Promise.resolve([])); - } - - const [ipv4List, ipv6List] = await Promise.all(fetchPromises); - results = [...ipv4List, ...ipv6List]; - - // 按运营商筛选 - if (results.length > 0) { - results = results.filter(item => { - const isp = item.isp || ''; - if (isp.includes('移动') && !ispMobile) return false; - if (isp.includes('联通') && !ispUnicom) return false; - if (isp.includes('电信') && !ispTelecom) return false; - return true; - }); - } - - return results.length > 0 ? results : []; - } catch (e) { - return []; - } -} - -// 解析wetest页面 -async function fetchAndParseWetest(url) { +// 从 wetest.vip 获取优选IP +async function fetchOptimalIPs(ipVersion = 'v4', isp = 'all') { try { - const response = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } }); - if (!response.ok) return []; - const html = await response.text(); - const results = []; - const rowRegex = //g; - const cellRegex = /(.+?)<\/td>[\s\S]*?([\d.:a-fA-F]+)<\/td>[\s\S]*?(.+?)<\/td>/; - - let match; - while ((match = rowRegex.exec(html)) !== null) { - const rowHtml = match[0]; - const cellMatch = rowHtml.match(cellRegex); - if (cellMatch && cellMatch[1] && cellMatch[2]) { - const colo = cellMatch[3] ? cellMatch[3].trim().replace(/<.*?>/g, '') : ''; - results.push({ - isp: cellMatch[1].trim().replace(/<.*?>/g, ''), - ip: cellMatch[2].trim(), - colo: colo - }); - } - } - return results; + const url = `https://api.wetest.vip/api/bestcf/${ipVersion}/${isp}`; + const response = await fetch(url); + const data = await response.json(); + return data.ips || []; } catch (error) { + console.error('获取优选IP失败:', error); return []; } } -// 整理成数组 -async function 整理成数组(内容) { - var 替换后的内容 = 内容.replace(/[ "'\r\n]+/g, ',').replace(/,+/g, ','); - if (替换后的内容.charAt(0) == ',') 替换后的内容 = 替换后的内容.slice(1); - if (替换后的内容.charAt(替换后的内容.length - 1) == ',') 替换后的内容 = 替换后的内容.slice(0, 替换后的内容.length - 1); - const 地址数组 = 替换后的内容.split(','); - return 地址数组; -} - -// 请求优选API -async function 请求优选API(urls, 默认端口 = '443', 超时时间 = 3000) { - if (!urls?.length) return []; - const results = new Set(); - await Promise.allSettled(urls.map(async (url) => { - try { - const controller = new AbortController(); - const timeoutId = setTimeout(() => controller.abort(), 超时时间); - const response = await fetch(url, { signal: controller.signal }); - clearTimeout(timeoutId); - let text = ''; - try { - const buffer = await response.arrayBuffer(); - const contentType = (response.headers.get('content-type') || '').toLowerCase(); - const charset = contentType.match(/charset=([^\s;]+)/i)?.[1]?.toLowerCase() || ''; - - // 根据 Content-Type 响应头判断编码优先级 - let decoders = ['utf-8', 'gb2312']; // 默认优先 UTF-8 - if (charset.includes('gb') || charset.includes('gbk') || charset.includes('gb2312')) { - decoders = ['gb2312', 'utf-8']; // 如果明确指定 GB 系编码,优先尝试 GB2312 - } - - // 尝试多种编码解码 - let decodeSuccess = false; - for (const decoder of decoders) { - try { - const decoded = new TextDecoder(decoder).decode(buffer); - // 验证解码结果的有效性 - if (decoded && decoded.length > 0 && !decoded.includes('\ufffd')) { - text = decoded; - decodeSuccess = true; - break; - } else if (decoded && decoded.length > 0) { - // 如果有替换字符 (U+FFFD),说明编码不匹配,继续尝试下一个编码 - continue; - } - } catch (e) { - // 该编码解码失败,尝试下一个 - continue; - } - } - - // 如果所有编码都失败或无效,尝试 response.text() - if (!decodeSuccess) { - text = await response.text(); - } - - // 如果返回的是空或无效数据,返回 - if (!text || text.trim().length === 0) { - return; - } - } catch (e) { - console.error('Failed to decode response:', e); - return; - } - const lines = text.trim().split('\n').map(l => l.trim()).filter(l => l); - const isCSV = lines.length > 1 && lines[0].includes(','); - const IPV6_PATTERN = /^[^\[\]]*:[^\[\]]*:[^\[\]]/; - if (!isCSV) { - lines.forEach(line => { - const hashIndex = line.indexOf('#'); - const [hostPart, remark] = hashIndex > -1 ? [line.substring(0, hashIndex), line.substring(hashIndex)] : [line, '']; - let hasPort = false; - if (hostPart.startsWith('[')) { - hasPort = /\]:(\d+)$/.test(hostPart); - } else { - const colonIndex = hostPart.lastIndexOf(':'); - hasPort = colonIndex > -1 && /^\d+$/.test(hostPart.substring(colonIndex + 1)); - } - const port = new URL(url).searchParams.get('port') || 默认端口; - results.add(hasPort ? line : `${hostPart}:${port}${remark}`); - }); - } else { - const headers = lines[0].split(',').map(h => h.trim()); - const dataLines = lines.slice(1); - if (headers.includes('IP地址') && headers.includes('端口') && headers.includes('数据中心')) { - const ipIdx = headers.indexOf('IP地址'), portIdx = headers.indexOf('端口'); - const remarkIdx = headers.indexOf('国家') > -1 ? headers.indexOf('国家') : - headers.indexOf('城市') > -1 ? headers.indexOf('城市') : headers.indexOf('数据中心'); - const tlsIdx = headers.indexOf('TLS'); - dataLines.forEach(line => { - const cols = line.split(',').map(c => c.trim()); - if (tlsIdx !== -1 && cols[tlsIdx]?.toLowerCase() !== 'true') return; - const wrappedIP = IPV6_PATTERN.test(cols[ipIdx]) ? `[${cols[ipIdx]}]` : cols[ipIdx]; - results.add(`${wrappedIP}:${cols[portIdx]}#${cols[remarkIdx]}`); - }); - } else if (headers.some(h => h.includes('IP')) && headers.some(h => h.includes('延迟')) && headers.some(h => h.includes('下载速度'))) { - const ipIdx = headers.findIndex(h => h.includes('IP')); - const delayIdx = headers.findIndex(h => h.includes('延迟')); - const speedIdx = headers.findIndex(h => h.includes('下载速度')); - const port = new URL(url).searchParams.get('port') || 默认端口; - dataLines.forEach(line => { - const cols = line.split(',').map(c => c.trim()); - const wrappedIP = IPV6_PATTERN.test(cols[ipIdx]) ? `[${cols[ipIdx]}]` : cols[ipIdx]; - results.add(`${wrappedIP}:${port}#CF优选 ${cols[delayIdx]}ms ${cols[speedIdx]}MB/s`); - }); - } - } - } catch (e) { } - })); - return Array.from(results); -} - -// 从GitHub获取优选IP(保留原有功能,同时支持优选API) -async function fetchAndParseNewIPs(piu) { - const url = piu || defaultIPURL; +// 从 GitHub 获取IP列表 +async function fetchGitHubIPs(url) { try { const response = await fetch(url); - if (!response.ok) return []; const text = await response.text(); - const results = []; - const lines = text.trim().replace(/\r/g, "").split('\n'); - const regex = /^([^:]+):(\d+)#(.*)$/; - - for (const line of lines) { - const trimmedLine = line.trim(); - if (!trimmedLine) continue; - const match = trimmedLine.match(regex); - if (match) { - results.push({ - ip: match[1], - port: parseInt(match[2], 10), - name: match[3].trim() || match[1] - }); - } - } - return results; + return text.split('\n').filter(line => line.trim()); } catch (error) { + console.error('从GitHub获取IP失败:', error); return []; } } -// 生成VLESS链接 -function generateLinksFromSource(list, user, workerDomain, disableNonTLS = false, customPath = '/', echConfig = null) { - const CF_HTTP_PORTS = [80, 8080, 8880, 2052, 2082, 2086, 2095]; - const CF_HTTPS_PORTS = [443, 2053, 2083, 2087, 2096, 8443]; - const defaultHttpsPorts = [443]; - const defaultHttpPorts = disableNonTLS ? [] : [80]; - const links = []; - const wsPath = customPath || '/'; - const proto = 'vless'; - - list.forEach(item => { - let nodeNameBase = item.isp ? item.isp.replace(/\s/g, '_') : (item.name || item.domain || item.ip); - if (item.colo && item.colo.trim()) { - nodeNameBase = `${nodeNameBase}-${item.colo.trim()}`; - } - const safeIP = item.ip.includes(':') ? `[${item.ip}]` : item.ip; - - let portsToGenerate = []; - - if (item.port) { - const port = item.port; - if (CF_HTTPS_PORTS.includes(port)) { - portsToGenerate.push({ port: port, tls: true }); - } else if (CF_HTTP_PORTS.includes(port)) { - portsToGenerate.push({ port: port, tls: false }); - } else { - portsToGenerate.push({ port: port, tls: true }); - } - } else { - defaultHttpsPorts.forEach(port => { - portsToGenerate.push({ port: port, tls: true }); - }); - defaultHttpPorts.forEach(port => { - portsToGenerate.push({ port: port, tls: false }); - }); - } - - portsToGenerate.forEach(({ port, tls }) => { - if (tls) { - const wsNodeName = `${nodeNameBase}-${port}-WS-TLS`; - const wsParams = new URLSearchParams({ - encryption: 'none', - security: 'tls', - sni: workerDomain, - fp: 'chrome', - type: 'ws', - host: workerDomain, - path: wsPath - }); - if (echConfig) { - wsParams.set('alpn', 'h3,h2,http/1.1'); - wsParams.set('ech', echConfig); - } - links.push(`${proto}://${user}@${safeIP}:${port}?${wsParams.toString()}#${encodeURIComponent(wsNodeName)}`); - } else { - const wsNodeName = `${nodeNameBase}-${port}-WS`; - const wsParams = new URLSearchParams({ - encryption: 'none', - security: 'none', - type: 'ws', - host: workerDomain, - path: wsPath - }); - links.push(`${proto}://${user}@${safeIP}:${port}?${wsParams.toString()}#${encodeURIComponent(wsNodeName)}`); - } - }); - }); - return links; -} - -// 生成Trojan链接 -async function generateTrojanLinksFromSource(list, user, workerDomain, disableNonTLS = false, customPath = '/', echConfig = null) { - const CF_HTTP_PORTS = [80, 8080, 8880, 2052, 2082, 2086, 2095]; - const CF_HTTPS_PORTS = [443, 2053, 2083, 2087, 2096, 8443]; - const defaultHttpsPorts = [443]; - const defaultHttpPorts = disableNonTLS ? [] : [80]; - const links = []; - const wsPath = customPath || '/'; - const password = user; // Trojan使用UUID作为密码 - - list.forEach(item => { - let nodeNameBase = item.isp ? item.isp.replace(/\s/g, '_') : (item.name || item.domain || item.ip); - if (item.colo && item.colo.trim()) { - nodeNameBase = `${nodeNameBase}-${item.colo.trim()}`; - } - const safeIP = item.ip.includes(':') ? `[${item.ip}]` : item.ip; - - let portsToGenerate = []; - - if (item.port) { - const port = item.port; - if (CF_HTTPS_PORTS.includes(port)) { - portsToGenerate.push({ port: port, tls: true }); - } else if (CF_HTTP_PORTS.includes(port)) { - if (!disableNonTLS) { - portsToGenerate.push({ port: port, tls: false }); - } - } else { - portsToGenerate.push({ port: port, tls: true }); - } - } else { - defaultHttpsPorts.forEach(port => { - portsToGenerate.push({ port: port, tls: true }); - }); - defaultHttpPorts.forEach(port => { - portsToGenerate.push({ port: port, tls: false }); - }); - } - - portsToGenerate.forEach(({ port, tls }) => { - if (tls) { - const wsNodeName = `${nodeNameBase}-${port}-Trojan-WS-TLS`; - const wsParams = new URLSearchParams({ - security: 'tls', - sni: workerDomain, - fp: 'chrome', - type: 'ws', - host: workerDomain, - path: wsPath - }); - if (echConfig) { - wsParams.set('alpn', 'h3,h2,http/1.1'); - wsParams.set('ech', echConfig); - } - links.push(`trojan://${password}@${safeIP}:${port}?${wsParams.toString()}#${encodeURIComponent(wsNodeName)}`); - } else { - const wsNodeName = `${nodeNameBase}-${port}-Trojan-WS`; - const wsParams = new URLSearchParams({ - security: 'none', - type: 'ws', - host: workerDomain, - path: wsPath - }); - links.push(`trojan://${password}@${safeIP}:${port}?${wsParams.toString()}#${encodeURIComponent(wsNodeName)}`); - } - }); - }); - return links; +// 生成节点配置 +function generateNode(protocol, address, port, uuid, domain, index) { + const name = `${protocol.toUpperCase()}-${address}-${index}`; + + if (protocol === 'vless') { + return `vless://${uuid}@${address}:${port}?encryption=none&security=tls&sni=${domain}&type=ws&host=${domain}&path=%2F#${encodeURIComponent(name)}`; + } else if (protocol === 'trojan') { + return `trojan://${uuid}@${address}:${port}?security=tls&sni=${domain}&type=ws&host=${domain}&path=%2F#${encodeURIComponent(name)}`; + } else if (protocol === 'vmess') { + const vmessConfig = { + v: "2", + ps: name, + add: address, + port: port, + id: uuid, + aid: "0", + net: "ws", + type: "none", + host: domain, + path: "/", + tls: "tls", + sni: domain + }; + return 'vmess://' + btoa(JSON.stringify(vmessConfig)); + } } -// 生成VMess链接 (已修复中文名导致1101报错的问题) -function generateVMessLinksFromSource(list, user, workerDomain, disableNonTLS = false, customPath = '/', echConfig = null) { - const CF_HTTP_PORTS = [80, 8080, 8880, 2052, 2082, 2086, 2095]; - const CF_HTTPS_PORTS = [443, 2053, 2083, 2087, 2096, 8443]; - const defaultHttpsPorts = [443]; - const defaultHttpPorts = disableNonTLS ? [] : [80]; - const links = []; - const wsPath = customPath || '/'; - - list.forEach(item => { - let nodeNameBase = item.isp ? item.isp.replace(/\s/g, '_') : (item.name || item.domain || item.ip); - if (item.colo && item.colo.trim()) { - nodeNameBase = `${nodeNameBase}-${item.colo.trim()}`; - } - const safeIP = item.ip.includes(':') ? `[${item.ip}]` : item.ip; - - let portsToGenerate = []; - - if (item.port) { - const port = item.port; - if (CF_HTTPS_PORTS.includes(port)) { - portsToGenerate.push({ port: port, tls: true }); - } else if (CF_HTTP_PORTS.includes(port)) { - if (!disableNonTLS) { - portsToGenerate.push({ port: port, tls: false }); - } - } else { - portsToGenerate.push({ port: port, tls: true }); - } - } else { - defaultHttpsPorts.forEach(port => { - portsToGenerate.push({ port: port, tls: true }); - }); - defaultHttpPorts.forEach(port => { - portsToGenerate.push({ port: port, tls: false }); - }); - } - - portsToGenerate.forEach(({ port, tls }) => { - const vmessConfig = { - v: "2", - ps: tls ? `${nodeNameBase}-${port}-VMess-WS-TLS` : `${nodeNameBase}-${port}-VMess-WS`, - add: safeIP, - port: port.toString(), - id: user, - aid: "0", - scy: "auto", - net: "ws", - type: "none", - host: workerDomain, - path: wsPath, - tls: tls ? "tls" : "none" - }; - if (tls) { - vmessConfig.sni = workerDomain; - vmessConfig.fp = "chrome"; +// 生成 Clash 配置 +function generateClashConfig(nodes, domain) { + const proxies = nodes.map((node, index) => { + const url = new URL(node); + const protocol = url.protocol.replace(':', ''); + const params = new URLSearchParams(url.search); + + return { + name: decodeURIComponent(url.hash.substring(1)), + type: protocol, + server: url.hostname, + port: parseInt(url.port) || 443, + uuid: url.username, + tls: true, + 'skip-cert-verify': false, + network: 'ws', + 'ws-opts': { + path: params.get('path') || '/', + headers: { Host: domain } } - - // 核心修复:处理中文编码,防止 btoa 报错 - const jsonStr = JSON.stringify(vmessConfig); - const vmessBase64 = btoa(encodeURIComponent(jsonStr).replace(/%([0-9A-F]{2})/g, - function toSolidBytes(match, p1) { - return String.fromCharCode('0x' + p1); - })); - - links.push(`vmess://${vmessBase64}`); - }); + }; }); - return links; -} - -// 从GitHub IP生成链接(VLESS) -function generateLinksFromNewIPs(list, user, workerDomain, customPath = '/', echConfig = null) { - const CF_HTTP_PORTS = [80, 8080, 8880, 2052, 2082, 2086, 2095]; - const CF_HTTPS_PORTS = [443, 2053, 2083, 2087, 2096, 8443]; - const links = []; - const wsPath = customPath || '/'; - const proto = 'vless'; - const echSuffix = echConfig ? `&alpn=h3%2Ch2%2Chttp%2F1.1&ech=${encodeURIComponent(echConfig)}` : ''; - list.forEach(item => { - const nodeName = item.name.replace(/\s/g, '_'); - const port = item.port; - - if (CF_HTTPS_PORTS.includes(port)) { - const wsNodeName = `${nodeName}-${port}-WS-TLS`; - const link = `${proto}://${user}@${item.ip}:${port}?encryption=none&security=tls&sni=${workerDomain}&fp=chrome&type=ws&host=${workerDomain}&path=${wsPath}${echSuffix}#${encodeURIComponent(wsNodeName)}`; - links.push(link); - } else if (CF_HTTP_PORTS.includes(port)) { - const wsNodeName = `${nodeName}-${port}-WS`; - const link = `${proto}://${user}@${item.ip}:${port}?encryption=none&security=none&type=ws&host=${workerDomain}&path=${wsPath}#${encodeURIComponent(wsNodeName)}`; - links.push(link); - } else { - const wsNodeName = `${nodeName}-${port}-WS-TLS`; - const link = `${proto}://${user}@${item.ip}:${port}?encryption=none&security=tls&sni=${workerDomain}&fp=chrome&type=ws&host=${workerDomain}&path=${wsPath}${echSuffix}#${encodeURIComponent(wsNodeName)}`; - links.push(link); - } - }); - return links; + return { + proxies: proxies, + 'proxy-groups': [{ + name: '自动选择', + type: 'url-test', + proxies: proxies.map(p => p.name), + url: 'http://www.gstatic.com/generate_204', + interval: 300 + }] + }; } -// 生成订阅内容 -async function handleSubscriptionRequest(request, user, customDomain, piu, ipv4Enabled, ipv6Enabled, ispMobile, ispUnicom, ispTelecom, evEnabled, etEnabled, vmEnabled, disableNonTLS, customPath, echConfig = null) { +// 处理订阅请求 +async function handleSubscription(request, uuid) { const url = new URL(request.url); - const finalLinks = []; - const workerDomain = url.hostname; // workerDomain始终是请求的hostname - const nodeDomain = customDomain || url.hostname; // 用户输入的域名用于生成节点时的host/sni - const target = url.searchParams.get('target') || 'base64'; - const wsPath = customPath || '/'; - - async function addNodesFromList(list) { - // 确保至少有一个协议被启用 - const hasProtocol = evEnabled || etEnabled || vmEnabled; - const useVL = hasProtocol ? evEnabled : true; // 如果没有选择任何协议,默认使用VLESS - - if (useVL) { - finalLinks.push(...generateLinksFromSource(list, user, nodeDomain, disableNonTLS, wsPath, echConfig)); - } - if (etEnabled) { - finalLinks.push(...await generateTrojanLinksFromSource(list, user, nodeDomain, disableNonTLS, wsPath, echConfig)); - } - if (vmEnabled) { - finalLinks.push(...generateVMessLinksFromSource(list, user, nodeDomain, disableNonTLS, wsPath, echConfig)); - } - } - - // 原生地址 - const nativeList = [{ ip: workerDomain, isp: '原生地址' }]; - await addNodesFromList(nativeList); - - // 优选域名 - if (epd) { - const domainList = directDomains.map(d => ({ ip: d.domain, isp: d.name || d.domain })); - await addNodesFromList(domainList); - } - - // 优选IP - if (epi) { - try { - const dynamicIPList = await fetchDynamicIPs(ipv4Enabled, ipv6Enabled, ispMobile, ispUnicom, ispTelecom); - if (dynamicIPList.length > 0) { - await addNodesFromList(dynamicIPList); - } - } catch (error) { - console.error('获取动态IP失败:', error); - } - } - - // GitHub优选 / 优选API - if (egi) { - try { - // 检查是否是优选API URL(以https://开头) - if (piu && piu.toLowerCase().startsWith('https://')) { - // 从优选API获取IP列表 - const 优选API的IP = await 请求优选API([piu]); - if (优选API的IP && 优选API的IP.length > 0) { - // 解析IP字符串格式:IP:端口#备注 - const IP列表 = 优选API的IP.map(原始地址 => { - // 统一正则: 匹配 域名/IPv4/IPv6地址 + 可选端口 + 可选备注 - const regex = /^(\[[\da-fA-F:]+\]|[\d.]+|[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*)(?::(\d+))?(?:#(.+))?$/; - const match = 原始地址.match(regex); - - if (match) { - const 节点地址 = match[1].replace(/[\[\]]/g, ''); // 移除IPv6的方括号 - const 节点端口 = match[2] || 443; - const 节点备注 = match[3] || 节点地址; - return { - ip: 节点地址, - port: parseInt(节点端口), - name: 节点备注 - }; - } - return null; - }).filter(item => item !== null); - - if (IP列表.length > 0) { - const hasProtocol = evEnabled || etEnabled || vmEnabled; - const useVL = hasProtocol ? evEnabled : true; - - if (useVL) { - finalLinks.push(...generateLinksFromNewIPs(IP列表, user, nodeDomain, wsPath, echConfig)); - } - } - } - } else if (piu && piu.includes('\n')) { - // 支持多行文本,包含混合格式(优选API URL + IP列表) - const 完整优选列表 = await 整理成数组(piu); - const 优选API = [], 优选IP = [], 其他节点 = []; - - for (const 元素 of 完整优选列表) { - if (元素.toLowerCase().startsWith('https://')) { - 优选API.push(元素); - } else if (元素.toLowerCase().includes('://')) { - 其他节点.push(元素); - } else { - 优选IP.push(元素); - } - } - - // 从优选API获取IP - if (优选API.length > 0) { - const 优选API的IP = await 请求优选API(优选API); - 优选IP.push(...优选API的IP); - } - - // 解析所有IP并生成节点 - if (优选IP.length > 0) { - const IP列表 = 优选IP.map(原始地址 => { - const regex = /^(\[[\da-fA-F:]+\]|[\d.]+|[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*)(?::(\d+))?(?:#(.+))?$/; - const match = 原始地址.match(regex); - - if (match) { - const 节点地址 = match[1].replace(/[\[\]]/g, ''); - const 节点端口 = match[2] || 443; - const 节点备注 = match[3] || 节点地址; - return { - ip: 节点地址, - port: parseInt(节点端口), - name: 节点备注 - }; - } - return null; - }).filter(item => item !== null); - - if (IP列表.length > 0) { - const hasProtocol = evEnabled || etEnabled || vmEnabled; - const useVL = hasProtocol ? evEnabled : true; - - if (useVL) { - finalLinks.push(...generateLinksFromNewIPs(IP列表, user, nodeDomain, wsPath, echConfig)); - } - } - } - } else { - // 原有的GitHub优选逻辑(单URL) - const newIPList = await fetchAndParseNewIPs(piu); - if (newIPList.length > 0) { - const hasProtocol = evEnabled || etEnabled || vmEnabled; - const useVL = hasProtocol ? evEnabled : true; - - if (useVL) { - finalLinks.push(...generateLinksFromNewIPs(newIPList, user, nodeDomain, wsPath, echConfig)); - } - } - } - } catch (error) { - console.error('获取优选IP失败:', error); - } - } - - if (finalLinks.length === 0) { - const errorRemark = "所有节点获取失败"; - const errorLink = `vless://00000000-0000-0000-0000-000000000000@127.0.0.1:80?encryption=none&security=none&type=ws&host=error.com&path=%2F#${encodeURIComponent(errorRemark)}`; - finalLinks.push(errorLink); - } - - let subscriptionContent; - let contentType = 'text/plain; charset=utf-8'; + const params = url.searchParams; - switch (target.toLowerCase()) { - case 'clash': - case 'clashr': - subscriptionContent = generateClashConfig(finalLinks); - contentType = 'text/yaml; charset=utf-8'; - break; - case 'surge': - case 'surge2': - case 'surge3': - case 'surge4': - subscriptionContent = generateSurgeConfig(finalLinks); - break; - case 'quantumult': - case 'quanx': - subscriptionContent = generateQuantumultConfig(finalLinks); - break; - default: - subscriptionContent = btoa(finalLinks.join('\n')); + // 获取参数 + const domain = params.get('domain'); + if (!domain) { + return new Response('缺少 domain 参数', { status: 400 }); } - return new Response(subscriptionContent, { - headers: { - 'Content-Type': contentType, - 'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0', - }, - }); -} - -// 生成Clash配置(简化版,返回YAML格式) -function generateClashConfig(links) { - let yaml = 'port: 7890\n'; - yaml += 'socks-port: 7891\n'; - yaml += 'allow-lan: false\n'; - yaml += 'mode: rule\n'; - yaml += 'log-level: info\n\n'; - yaml += 'proxies:\n'; + const enableVLESS = params.get('ev') === 'yes'; + const enableTrojan = params.get('et') === 'yes'; + const enableVMess = params.get('mess') === 'yes'; + const enableDefaultDomains = params.get('epd') === 'yes'; + const enableOptimalIP = params.get('epi') === 'yes'; + const enableGitHubIP = params.get('egi') === 'yes'; + const customIPUrl = params.get('piu'); + const target = params.get('target') || 'base64'; - const proxyNames = []; - links.forEach((link, index) => { - const name = decodeURIComponent(link.split('#')[1] || `节点${index + 1}`); - proxyNames.push(name); - const server = link.match(/@([^:]+):(\d+)/)?.[1] || ''; - const port = link.match(/@[^:]+:(\d+)/)?.[1] || '443'; - const uuid = link.match(/vless:\/\/([^@]+)@/)?.[1] || ''; - const tls = link.includes('security=tls'); - const path = link.match(/path=([^&#]+)/)?.[1] || '/'; - const host = link.match(/host=([^&#]+)/)?.[1] || ''; - const sni = link.match(/sni=([^&#]+)/)?.[1] || ''; - const echParam = link.match(/[?&]ech=([^&#]+)/)?.[1]; - const echDomain = echParam ? decodeURIComponent(echParam).split('+')[0] : ''; - - yaml += ` - name: ${name}\n`; - yaml += ` type: vless\n`; - yaml += ` server: ${server}\n`; - yaml += ` port: ${port}\n`; - yaml += ` uuid: ${uuid}\n`; - yaml += ` tls: ${tls}\n`; - yaml += ` network: ws\n`; - yaml += ` ws-opts:\n`; - yaml += ` path: ${path}\n`; - yaml += ` headers:\n`; - yaml += ` Host: ${host}\n`; - if (sni) { - yaml += ` servername: ${sni}\n`; - } - if (echDomain) { - yaml += ` ech-opts:\n`; - yaml += ` enable: true\n`; - yaml += ` query-server-name: ${echDomain}\n`; - } - }); + const enableIPv4 = params.get('ipv4') !== 'no'; + const enableIPv6 = params.get('ipv6') !== 'no'; + const enableMobile = params.get('ispMobile') !== 'no'; + const enableUnicom = params.get('ispUnicom') !== 'no'; + const enableTelecom = params.get('ispTelecom') !== 'no'; - yaml += '\nproxy-groups:\n'; - yaml += ' - name: PROXY\n'; - yaml += ' type: select\n'; - yaml += ` proxies: [${proxyNames.map(n => `'${n}'`).join(', ')}]\n`; - yaml += '\nrules:\n'; - yaml += ' - DOMAIN-SUFFIX,local,DIRECT\n'; - yaml += ' - IP-CIDR,127.0.0.0/8,DIRECT\n'; - yaml += ' - GEOIP,CN,DIRECT\n'; - yaml += ' - MATCH,PROXY\n'; + // 收集所有地址 + let addresses = []; - return yaml; -} - -// 生成Surge配置 -function generateSurgeConfig(links) { - let config = '[Proxy]\n'; - links.forEach(link => { - const name = decodeURIComponent(link.split('#')[1] || '节点'); - config += `${name} = vless, ${link.match(/@([^:]+):(\d+)/)?.[1] || ''}, ${link.match(/@[^:]+:(\d+)/)?.[1] || '443'}, username=${link.match(/vless:\/\/([^@]+)@/)?.[1] || ''}, tls=${link.includes('security=tls')}, ws=true, ws-path=${link.match(/path=([^&#]+)/)?.[1] || '/'}, ws-headers=Host:${link.match(/host=([^&#]+)/)?.[1] || ''}\n`; - }); - config += '\n[Proxy Group]\nPROXY = select, ' + links.map((_, i) => decodeURIComponent(links[i].split('#')[1] || `节点${i + 1}`)).join(', ') + '\n'; - return config; -} - -// 生成Quantumult配置 -function generateQuantumultConfig(links) { - return btoa(links.join('\n')); -} - -// 生成iOS 26风格的主页 -function generateHomePage(scuValue) { - const scu = scuValue || 'https://url.v1.mk/sub'; - return ` - - - - - - - 服务器优选工具 - - - -
-
-

服务器优选工具

-

智能优选 • 一键生成

-
- -
-
- - -
- -
- - -
- -
- - - 自定义WebSocket路径,例如:/v2ray 或 / -
- -
-
-
启用优选域名
-
-
-
- -
-
-
启用优选IP
-
-
-
- -
-
-
启用GitHub优选
-
-
-
- -
- - - 自定义优选IP列表来源URL,留空则使用默认地址 -
- -
- -
-
-
-
VLESS (vl)
-
-
-
-
-
-
Trojan (tj)
-
-
-
-
-
-
VMess (vm)
-
-
-
-
-
- -
- -
- - - - - - - - - - -
- -
- -
- -
- - -
-
- -
- -
- - - -
-
- -
-
-
仅TLS节点
-
启用后只生成带TLS的节点,不生成非TLS节点(如80端口)
-
-
-
- -
-
-
ECH (Encrypted Client Hello)
-
启用后节点链接将携带 ECH 参数,需客户端支持;开启时自动仅TLS
-
-
-
- -
- - -
+ } - - -`; + } + + // 根据目标格式返回 + if (target === 'clash') { + const config = generateClashConfig(nodes, domain); + return new Response(JSON.stringify(config, null, 2), { + headers: { 'Content-Type': 'application/json' } + }); + } else { + // Base64 格式 + const content = nodes.join('\n'); + const base64Content = btoa(unescape(encodeURIComponent(content))); + return new Response(base64Content, { + headers: { 'Content-Type': 'text/plain' } + }); + } } -// 主处理函数 export default { - async fetch(request, env, ctx) { + async fetch(request) { const url = new URL(request.url); - const path = url.pathname; - - // 主页 - if (path === '/' || path === '') { - const scuValue = env?.scu || scu; - return new Response(generateHomePage(scuValue), { - headers: { 'Content-Type': 'text/html; charset=utf-8' } - }); - } - // 测试优选API API: /test-optimize-api?url=xxx&port=443 - if (path === '/test-optimize-api') { - if (request.method === 'OPTIONS') { - return new Response(null, { - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type' - } - }); - } + // 代理 3xui.xlihf.top 到服务器 8080 端口 + if (url.hostname === '3xui.xlihf.top') { + const targetUrl = `http://192.227.232.131:8080${url.pathname}${url.search}`; - const apiUrl = url.searchParams.get('url'); - const port = url.searchParams.get('port') || '443'; - const timeout = parseInt(url.searchParams.get('timeout') || '3000'); - - if (!apiUrl) { - return new Response(JSON.stringify({ - success: false, - error: '缺少url参数' - }), { - status: 400, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - 'Access-Control-Allow-Origin': '*' - } - }); - } + // 创建新的请求头 + const headers = new Headers(request.headers); + headers.set('Host', '3xui.xlihf.top'); + headers.set('X-Forwarded-For', request.headers.get('CF-Connecting-IP') || ''); + headers.set('X-Real-IP', request.headers.get('CF-Connecting-IP') || ''); try { - const results = await 请求优选API([apiUrl], port, timeout); - return new Response(JSON.stringify({ - success: true, - results: results, - total: results.length, - message: `成功获取 ${results.length} 个优选IP` - }, null, 2), { - headers: { - 'Content-Type': 'application/json; charset=utf-8', - 'Access-Control-Allow-Origin': '*' - } + const response = await fetch(targetUrl, { + method: request.method, + headers: headers, + body: request.body, + redirect: 'follow' }); - } catch (error) { - return new Response(JSON.stringify({ - success: false, - error: error.message - }), { - status: 500, - headers: { - 'Content-Type': 'application/json; charset=utf-8', - 'Access-Control-Allow-Origin': '*' - } + + // 返回响应 + return new Response(response.body, { + status: response.status, + statusText: response.statusText, + headers: response.headers }); + } catch (error) { + return new Response('代理错误: ' + error.message, { status: 502 }); } } - // 订阅请求格式: /{UUID或Password}/sub?domain=xxx&epd=yes&epi=yes&egi=yes - const pathMatch = path.match(/^\/([^\/]+)\/sub$/); - if (pathMatch) { - const uuid = pathMatch[1]; - - const domain = url.searchParams.get('domain'); - if (!domain) { - return new Response('缺少域名参数', { status: 400 }); - } - - // 从URL参数获取配置 - epd = url.searchParams.get('epd') !== 'no'; - epi = url.searchParams.get('epi') !== 'no'; - egi = url.searchParams.get('egi') !== 'no'; - const piu = url.searchParams.get('piu') || defaultIPURL; - - // 协议选择 - const evEnabled = url.searchParams.get('ev') === 'yes' || (url.searchParams.get('ev') === null && ev); - const etEnabled = url.searchParams.get('et') === 'yes'; - const vmEnabled = url.searchParams.get('mess') === 'yes'; - - // IPv4/IPv6选择 - const ipv4Enabled = url.searchParams.get('ipv4') !== 'no'; - const ipv6Enabled = url.searchParams.get('ipv6') !== 'no'; - - // 运营商选择 - const ispMobile = url.searchParams.get('ispMobile') !== 'no'; - const ispUnicom = url.searchParams.get('ispUnicom') !== 'no'; - const ispTelecom = url.searchParams.get('ispTelecom') !== 'no'; - - // TLS控制(ECH 开启时强制仅 TLS) - let disableNonTLS = url.searchParams.get('dkby') === 'yes'; - const echParam = url.searchParams.get('ech'); - const echEnabled = echParam === 'yes' || (echParam === null && enableECH); - if (echEnabled) disableNonTLS = true; - const customDNSParam = url.searchParams.get('customDNS') || customDNS; - const customECHDomainParam = url.searchParams.get('customECHDomain') || customECHDomain; - const echConfig = echEnabled ? `${customECHDomainParam}+${customDNSParam}` : null; - - // 自定义路径 - const customPath = url.searchParams.get('path') || '/'; - - return await handleSubscriptionRequest(request, uuid, domain, piu, ipv4Enabled, ipv6Enabled, ispMobile, ispUnicom, ispTelecom, evEnabled, etEnabled, vmEnabled, disableNonTLS, customPath, echConfig); + const path = url.pathname; + + // 首页 + if (path === '/' || path === '') { + return new Response(HTML_CONTENT, { + headers: { 'Content-Type': 'text/html;charset=UTF-8' } + }); + } + + // 订阅路径: /{uuid}/sub + const match = path.match(/^\/([^\/]+)\/sub$/); + if (match) { + const uuid = match[1]; + return handleSubscription(request, uuid); } return new Response('Not Found', { status: 404 });