|
1 | | -const Version = '2026-05-06 17:51:02'; |
| 1 | +const Version = '2026-05-08 04:15:13'; |
2 | 2 | /*In our project workflow, we first*/ import //the necessary modules, |
3 | 3 | /*then*/ { connect }//to the central server, |
4 | 4 | /*and all data flows*/ from//this single source. |
@@ -5210,80 +5210,70 @@ async function 解析地址端口(proxyIP, 目标域名 = 'dash.cloudflare.com', |
5210 | 5210 | const parts = str.split(']:'); |
5211 | 5211 | 地址 = parts[0] + ']'; |
5212 | 5212 | 端口 = parseInt(parts[1], 10) || 端口; |
5213 | | - } else if (str.includes(':') && !str.startsWith('[')) { |
| 5213 | + } else if ((str.match(/:/g) || []).length === 1 && !str.startsWith('[')) { |
5214 | 5214 | const colonIndex = str.lastIndexOf(':'); |
5215 | 5215 | 地址 = str.slice(0, colonIndex); |
5216 | 5216 | 端口 = parseInt(str.slice(colonIndex + 1), 10) || 端口; |
5217 | 5217 | } |
5218 | 5218 | return [地址, 端口]; |
5219 | 5219 | } |
5220 | 5220 |
|
| 5221 | + function 解析TXT反代记录(txtData) { |
| 5222 | + return txtData.flatMap(data => { |
| 5223 | + if (data.startsWith('"') && data.endsWith('"')) data = data.slice(1, -1); |
| 5224 | + return data.replace(/\\010/g, ',').replace(/\n/g, ',').split(',').map(s => s.trim()).filter(Boolean); |
| 5225 | + }).map(prefix => 解析地址端口字符串(prefix)); |
| 5226 | + } |
| 5227 | + |
5221 | 5228 | const 反代IP数组 = await 整理成数组(proxyIP); |
5222 | 5229 | let 所有反代数组 = []; |
| 5230 | + const ipv4Regex = /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/; |
| 5231 | + const ipv6Regex = /^\[?(?:[a-fA-F0-9]{0,4}:){1,7}[a-fA-F0-9]{0,4}\]?$/; |
5223 | 5232 |
|
5224 | 5233 | // 遍历数组中的每个IP元素进行处理 |
5225 | 5234 | for (const singleProxyIP of 反代IP数组) { |
5226 | | - if (singleProxyIP.includes('.william')) { |
5227 | | - try { |
5228 | | - let txtRecords = await DoH查询(singleProxyIP, 'TXT'); |
5229 | | - let txtData = txtRecords.filter(r => r.type === 16).map(r => /** @type {string} */(r.data)); |
5230 | | - if (txtData.length === 0) { |
5231 | | - log(`[反代解析] 默认DoH未获取到TXT记录,切换Google DoH重试 ${singleProxyIP}`); |
5232 | | - txtRecords = await DoH查询(singleProxyIP, 'TXT', 'https://dns.google/dns-query'); |
5233 | | - txtData = txtRecords.filter(r => r.type === 16).map(r => /** @type {string} */(r.data)); |
5234 | | - } |
5235 | | - if (txtData.length > 0) { |
5236 | | - let data = txtData[0]; |
5237 | | - if (data.startsWith('"') && data.endsWith('"')) data = data.slice(1, -1); |
5238 | | - const prefixes = data.replace(/\\010/g, ',').replace(/\n/g, ',').split(',').map(s => s.trim()).filter(Boolean); |
5239 | | - 所有反代数组.push(...prefixes.map(prefix => 解析地址端口字符串(prefix))); |
5240 | | - } |
5241 | | - } catch (error) { |
5242 | | - console.error('解析William域名失败:', error); |
5243 | | - } |
5244 | | - } else { |
5245 | | - let [地址, 端口] = 解析地址端口字符串(singleProxyIP); |
| 5235 | + let [地址, 端口] = 解析地址端口字符串(singleProxyIP); |
5246 | 5236 |
|
5247 | | - if (singleProxyIP.includes('.tp')) { |
5248 | | - const tpMatch = singleProxyIP.match(/\.tp(\d+)/); |
5249 | | - if (tpMatch) 端口 = parseInt(tpMatch[1], 10); |
5250 | | - } |
| 5237 | + if (singleProxyIP.includes('.tp')) { |
| 5238 | + const tpMatch = singleProxyIP.match(/\.tp(\d+)/); |
| 5239 | + if (tpMatch) 端口 = parseInt(tpMatch[1], 10); |
| 5240 | + } |
5251 | 5241 |
|
5252 | | - // 判断是否是域名(非IP地址) |
5253 | | - const ipv4Regex = /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/; |
5254 | | - const ipv6Regex = /^\[?([a-fA-F0-9:]+)\]?$/; |
5255 | | - |
5256 | | - if (!ipv4Regex.test(地址) && !ipv6Regex.test(地址)) { |
5257 | | - // 并行查询 A 和 AAAA 记录 |
5258 | | - let [aRecords, aaaaRecords] = await Promise.all([ |
5259 | | - DoH查询(地址, 'A'), |
5260 | | - DoH查询(地址, 'AAAA') |
5261 | | - ]); |
5262 | | - |
5263 | | - let ipv4List = aRecords.filter(r => r.type === 1).map(r => r.data); |
5264 | | - let ipv6List = aaaaRecords.filter(r => r.type === 28).map(r => `[${r.data}]`); |
5265 | | - let ipAddresses = [...ipv4List, ...ipv6List]; |
5266 | | - |
5267 | | - // 默认DoH无结果时,切换Google DoH重试 |
5268 | | - if (ipAddresses.length === 0) { |
5269 | | - log(`[反代解析] 默认DoH未获取到解析结果,切换Google DoH重试 ${地址}`); |
5270 | | - [aRecords, aaaaRecords] = await Promise.all([ |
5271 | | - DoH查询(地址, 'A', 'https://dns.google/dns-query'), |
5272 | | - DoH查询(地址, 'AAAA', 'https://dns.google/dns-query') |
5273 | | - ]); |
5274 | | - ipv4List = aRecords.filter(r => r.type === 1).map(r => r.data); |
5275 | | - ipv6List = aaaaRecords.filter(r => r.type === 28).map(r => `[${r.data}]`); |
5276 | | - ipAddresses = [...ipv4List, ...ipv6List]; |
5277 | | - } |
| 5242 | + // 判断是否是域名(非IP地址) |
| 5243 | + if (ipv4Regex.test(地址) || ipv6Regex.test(地址)) { |
| 5244 | + log(`[反代解析] ${地址} 为IP地址,直接使用`); |
| 5245 | + 所有反代数组.push([地址, 端口]); |
| 5246 | + continue; |
| 5247 | + } |
5278 | 5248 |
|
5279 | | - if (ipAddresses.length > 0) { |
5280 | | - 所有反代数组.push(...ipAddresses.map(ip => [ip, 端口])); |
5281 | | - } else { |
5282 | | - 所有反代数组.push([地址, 端口]); |
5283 | | - } |
5284 | | - } else { |
5285 | | - 所有反代数组.push([地址, 端口]); |
5286 | | - } |
| 5249 | + const [txtRecords, aRecords] = await Promise.all([ |
| 5250 | + DoH查询(地址, 'TXT'), |
| 5251 | + DoH查询(地址, 'A') |
| 5252 | + ]); |
| 5253 | + |
| 5254 | + const txtData = txtRecords.filter(r => r.type === 16).map(r => (r.data)); |
| 5255 | + const txtAddresses = 解析TXT反代记录(txtData); |
| 5256 | + if (txtAddresses.length > 0) { |
| 5257 | + log(`[反代解析] ${地址} 使用TXT记录,共${txtAddresses.length}个结果`); |
| 5258 | + 所有反代数组.push(...txtAddresses); |
| 5259 | + continue; |
| 5260 | + } |
| 5261 | + |
| 5262 | + const ipv4List = aRecords.filter(r => r.type === 1).map(r => r.data); |
| 5263 | + if (ipv4List.length > 0) { |
| 5264 | + log(`[反代解析] ${地址} 未获取到TXT记录,使用A记录,共${ipv4List.length}个结果`); |
| 5265 | + 所有反代数组.push(...ipv4List.map(ip => [ip, 端口])); |
| 5266 | + continue; |
| 5267 | + } |
| 5268 | + |
| 5269 | + const aaaaRecords = await DoH查询(地址, 'AAAA'); |
| 5270 | + const ipv6List = aaaaRecords.filter(r => r.type === 28).map(r => `[${r.data}]`); |
| 5271 | + if (ipv6List.length > 0) { |
| 5272 | + log(`[反代解析] ${地址} 未获取到TXT和A记录,使用AAAA记录,共${ipv6List.length}个结果`); |
| 5273 | + 所有反代数组.push(...ipv6List.map(ip => [ip, 端口])); |
| 5274 | + } else { |
| 5275 | + log(`[反代解析] ${地址} 未获取到TXT、A和AAAA记录,保留原域名`); |
| 5276 | + 所有反代数组.push([地址, 端口]); |
5287 | 5277 | } |
5288 | 5278 | } |
5289 | 5279 | const 排序后数组 = 所有反代数组.sort((a, b) => a[0].localeCompare(b[0])); |
|
0 commit comments