diff --git a/明文源码.js b/明文源码.js index bfa70b4..15d6413 100644 --- a/明文源码.js +++ b/明文源码.js @@ -168,8 +168,9 @@ export default { const fakeConfig = await 生成配置信息(userID, request.headers.get('Host'), sub, 'CF-Workers-SUB', RproxyIP, url, fakeUserID, fakeHostName, env); return new Response(`${fakeConfig}`, { status: 200 }); } else if (url.pathname == `/${动态UUID}/edit` || 路径 == `/${userID}/edit`) { - const html = await KV(request, env); - return html; + return await KV(request, env); + } else if (url.pathname == `/${动态UUID}/bestip` || 路径 == `/${userID}/bestip`) { + return await bestIP(request, env); } else if (url.pathname == `/${动态UUID}` || 路径 == `/${userID}`) { await sendMessage(`#获取订阅 ${FileName}`, request.headers.get('CF-Connecting-IP'), `UA: ${UA}\n域名: ${url.hostname}\n入口: ${url.pathname + url.search}`); const 维列斯Config = await 生成配置信息(userID, request.headers.get('Host'), sub, UA, RproxyIP, url, fakeUserID, fakeHostName, env); @@ -1506,7 +1507,7 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, fak else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP
  ${proxyIPs.join('
  ')}
`; else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!
`; let 判断是否绑定KV空间 = ''; - if (env.KV) 判断是否绑定KV空间 = ` 编辑优选列表`; + if (env.KV) 判断是否绑定KV空间 = ` [编辑优选列表] [在线优选IP]`; 订阅器 += `
您的订阅内容由 内置 addresses/ADD* 参数变量提供${判断是否绑定KV空间}
`; if (addresses.length > 0) 订阅器 += `ADD(TLS优选域名&IP):
  ${addresses.join('
  ')}
`; if (addressesnotls.length > 0) 订阅器 += `ADDNOTLS(noTLS优选域名&IP):
  ${addressesnotls.join('
  ')}
`; @@ -2543,3 +2544,833 @@ async function resolveToIPv6(target) { return `解析失败: ${error.message}`; } } + +async function bestIP(request, env, txt = 'ADD.txt') { + const country = request.cf?.country || 'CN'; + const url = new URL(request.url); + + async function GetCFIPs() { + try { + // 首先尝试第一个URL + let response = await fetch('https://raw.githubusercontent.com/ipverse/asn-ip/master/as/13335/ipv4-aggregated.txt'); + if (!response.ok) { + // 如果失败,尝试第二个URL + response = await fetch('https://www.cloudflare.com/ips-v4/'); + } + + const text = response.ok ? await response.text() : `173.245.48.0/20 +103.21.244.0/22 +103.22.200.0/22 +103.31.4.0/22 +141.101.64.0/18 +108.162.192.0/18 +190.93.240.0/20 +188.114.96.0/20 +197.234.240.0/22 +198.41.128.0/17 +162.158.0.0/15 +104.16.0.0/13 +104.24.0.0/14 +172.64.0.0/13 +131.0.72.0/22`; + const cidrs = text.split('\n').filter(line => line.trim() && !line.startsWith('#')); + + const ips = new Set(); // 使用Set去重 + const targetCount = 1000; + let round = 1; + + // 不断轮次生成IP直到达到目标数量 + while (ips.size < targetCount) { + console.log(`第${round}轮生成IP,当前已有${ips.size}个`); + + // 每轮为每个CIDR生成指定数量的IP + for (const cidr of cidrs) { + if (ips.size >= targetCount) break; + + const cidrIPs = generateIPsFromCIDR(cidr.trim(), round); + cidrIPs.forEach(ip => ips.add(ip)); + + console.log(`CIDR ${cidr} 第${round}轮生成${cidrIPs.length}个IP,总计${ips.size}个`); + } + + round++; + + // 防止无限循环 + if (round > 100) { + console.warn('达到最大轮次限制,停止生成'); + break; + } + } + + console.log(`最终生成${ips.size}个不重复IP`); + return Array.from(ips).slice(0, targetCount); + } catch (error) { + console.error('获取CF IPs失败:', error); + return []; + } + } + + function generateIPsFromCIDR(cidr, count = 1) { + const [network, prefixLength] = cidr.split('/'); + const prefix = parseInt(prefixLength); + + // 将IP地址转换为32位整数 + const ipToInt = (ip) => { + return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet), 0) >>> 0; + }; + + // 将32位整数转换为IP地址 + const intToIP = (int) => { + return [ + (int >>> 24) & 255, + (int >>> 16) & 255, + (int >>> 8) & 255, + int & 255 + ].join('.'); + }; + + const networkInt = ipToInt(network); + const hostBits = 32 - prefix; + const numHosts = Math.pow(2, hostBits); + + // 限制生成数量不超过该CIDR的可用主机数 + const maxHosts = numHosts - 2; // -2 排除网络地址和广播地址 + const actualCount = Math.min(count, maxHosts); + const ips = new Set(); + + // 如果可用主机数太少,直接返回空数组 + if (maxHosts <= 0) { + return []; + } + + // 生成指定数量的随机IP + let attempts = 0; + const maxAttempts = actualCount * 10; // 防止无限循环 + + while (ips.size < actualCount && attempts < maxAttempts) { + const randomOffset = Math.floor(Math.random() * maxHosts) + 1; // +1 避免网络地址 + const randomIP = intToIP(networkInt + randomOffset); + ips.add(randomIP); + attempts++; + } + + return Array.from(ips); + } + + // POST请求处理 + if (request.method === "POST") { + if (!env.KV) return new Response("未绑定KV空间", { status: 400 }); + + try { + const contentType = request.headers.get('Content-Type'); + + // 处理JSON格式的保存/追加请求 + if (contentType && contentType.includes('application/json')) { + const data = await request.json(); + const action = url.searchParams.get('action') || 'save'; + + if (!data.ips || !Array.isArray(data.ips)) { + return new Response(JSON.stringify({ error: 'Invalid IP list' }), { + status: 400, + headers: { 'Content-Type': 'application/json' } + }); + } + + if (action === 'append') { + // 追加模式 + const existingContent = await env.KV.get(txt) || ''; + const newContent = data.ips.join('\n'); + + // 合并内容并去重 + const existingLines = existingContent ? + existingContent.split('\n').map(line => line.trim()).filter(line => line) : + []; + const newLines = newContent.split('\n').map(line => line.trim()).filter(line => line); + + // 使用Set进行去重 + const allLines = [...existingLines, ...newLines]; + const uniqueLines = [...new Set(allLines)]; + const combinedContent = uniqueLines.join('\n'); + + // 检查合并后的内容大小 + if (combinedContent.length > 24 * 1024 * 1024) { + return new Response(JSON.stringify({ + error: `追加失败:合并后内容过大(${(combinedContent.length / 1024 / 1024).toFixed(2)}MB),超过KV存储限制(24MB)` + }), { + status: 400, + headers: { 'Content-Type': 'application/json' } + }); + } + + await env.KV.put(txt, combinedContent); + + const addedCount = uniqueLines.length - existingLines.length; + const duplicateCount = newLines.length - addedCount; + + let message = `成功追加 ${addedCount} 个新的优选IP(原有 ${existingLines.length} 个,现共 ${uniqueLines.length} 个)`; + if (duplicateCount > 0) { + message += `,已去重 ${duplicateCount} 个重复项`; + } + + return new Response(JSON.stringify({ + success: true, + message: message + }), { + headers: { 'Content-Type': 'application/json' } + }); + } else { + // 保存模式(覆盖) + const content = data.ips.join('\n'); + + // 检查内容大小 + if (content.length > 24 * 1024 * 1024) { + return new Response(JSON.stringify({ + error: '内容过大,超过KV存储限制(24MB)' + }), { + status: 400, + headers: { 'Content-Type': 'application/json' } + }); + } + + await env.KV.put(txt, content); + + return new Response(JSON.stringify({ + success: true, + message: `成功保存 ${data.ips.length} 个优选IP` + }), { + headers: { 'Content-Type': 'application/json' } + }); + } + } else { + // 处理普通文本格式的保存请求(兼容原有功能) + const content = await request.text(); + await env.KV.put(txt, content); + return new Response("保存成功"); + } + + } catch (error) { + console.error('处理POST请求时发生错误:', error); + return new Response(JSON.stringify({ + error: '操作失败: ' + error.message + }), { + status: 500, + headers: { 'Content-Type': 'application/json' } + }); + } + } + + // GET请求部分 + let content = ''; + let hasKV = !!env.KV; + + if (hasKV) { + try { + content = await env.KV.get(txt) || ''; + } catch (error) { + console.error('读取KV时发生错误:', error); + content = '读取数据时发生错误: ' + error.message; + } + } + + const cfIPs = await GetCFIPs(); + + // 判断是否为中国用户 + const isChina = country === 'CN'; + const countryDisplayClass = isChina ? '' : 'proxy-warning'; + const countryDisplayText = isChina ? country : `${country} ⚠️`; + + const html = ` + + + + Cloudflare IP优选 + + + +

在线优选IP

+ +
+

统计信息

+

您的国家:${countryDisplayText}

+

获取到的IP总数:${cfIPs.length} 个

+

测试进度:未开始

+
+
+
+
+ + ${!isChina ? ` +
+

🚨 代理检测警告

+

检测到您当前很可能处于代理/VPN环境中!

+

在代理状态下进行的IP优选测试结果将不准确,可能导致:

+ +

建议操作:请关闭所有代理软件(VPN、科学上网工具等),确保处于直连网络环境后重新访问本页面。

+
+ ` : ''} + +
+
+ + +
+
+ + + + +
+
+ ⚠️ 重要提醒:"覆盖保存优选IP"会完全覆盖当前 addresses/ADD 优选内容,请慎重考虑!建议优先使用"追加保存优选IP"功能。 +
+
+
+ +

IP列表

+
+ ${cfIPs.map(ip => `
${ip}
`).join('')} +
+ + + + + + `; + + return new Response(html, { + headers: { + 'Content-Type': 'text/html; charset=UTF-8', + }, + }); +} \ No newline at end of file