Skip to content

Commit bbd3901

Browse files
authored
Merge pull request cmliu#876 from cmliu/beta2.0
Beta2.0
2 parents b8d94e4 + b8f423f commit bbd3901

1 file changed

Lines changed: 101 additions & 39 deletions

File tree

_worker.js

Lines changed: 101 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,11 @@ export default {
318318
return new Response(订阅内容, { status: 200, headers: responseHeaders });
319319
}
320320
return new Response('无效的订阅TOKEN', { status: 403 });
321-
} else if (访问路径 === 'locations') return fetch(new Request('https://speed.cloudflare.com/locations', { headers: { 'Referer': 'https://speed.cloudflare.com/' } }));
321+
} else if (访问路径 === 'locations') {//反代locations列表
322+
const cookies = request.headers.get('Cookie') || '';
323+
const authCookie = cookies.split(';').find(c => c.trim().startsWith('auth='))?.split('=')[1];
324+
if (authCookie && authCookie == await MD5MD5(UA + 加密秘钥 + 管理员密码)) return fetch(new Request('https://speed.cloudflare.com/locations', { headers: { 'Referer': 'https://speed.cloudflare.com/' } }));
325+
}
322326
} else if (管理员密码) {// ws代理
323327
await 反代参数获取(request);
324328
return await 处理WS请求(request, userID);
@@ -495,8 +499,26 @@ function 解析魏烈思请求(chunk, token) {
495499
}
496500
async function forwardataTCP(host, portNum, rawData, ws, respHeader, remoteConnWrapper) {
497501
console.log(JSON.stringify({ configJSON: { 目标地址: host, 目标端口: portNum, 反代IP: 反代IP, 代理类型: 启用SOCKS5反代, 全局代理: 启用SOCKS5全局反代, 代理账号: 我的SOCKS5账号 } }));
498-
async function connectDirect(address, port, data) {
499-
const remoteSock = connect({ hostname: address, port: port });
502+
async function connectDirect(address, port, data, 所有反代数组 = null) {
503+
let remoteSock;
504+
if (所有反代数组 && 所有反代数组.length > 0) {
505+
const 打乱后数组 = [...所有反代数组].sort(() => Math.random() - 0.5);
506+
const 最大尝试次数 = Math.min(8, 打乱后数组.length);
507+
for (let i = 0; i < 最大尝试次数; i++) {
508+
const [反代地址, 反代端口] = 打乱后数组[i];
509+
try {
510+
remoteSock = connect({ hostname: 反代地址, port: 反代端口 });
511+
const testWriter = remoteSock.writable.getWriter();
512+
await testWriter.write(data);
513+
testWriter.releaseLock();
514+
return remoteSock;
515+
} catch (err) {
516+
try { remoteSock?.close?.(); } catch (e) { }
517+
continue;
518+
}
519+
}
520+
}
521+
remoteSock = connect({ hostname: address, port: port });
500522
const writer = remoteSock.writable.getWriter();
501523
await writer.write(data);
502524
writer.releaseLock();
@@ -509,10 +531,8 @@ async function forwardataTCP(host, portNum, rawData, ws, respHeader, remoteConnW
509531
} else if (启用SOCKS5反代 === 'http' || 启用SOCKS5反代 === 'https') {
510532
newSocket = await httpConnect(host, portNum, rawData);
511533
} else {
512-
try {
513-
const [反代IP地址, 反代IP端口] = await 解析地址端口(反代IP);
514-
newSocket = await connectDirect(反代IP地址, 反代IP端口, rawData);
515-
} catch { newSocket = await connectDirect(atob('UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg=='), 1, rawData) }
534+
const 所有反代数组 = await 解析地址端口(反代IP);
535+
newSocket = await connectDirect(atob('UFJPWFlJUC50cDEuMDkwMjI3Lnh5eg=='), 1, rawData, 所有反代数组);
516536
}
517537
remoteConnWrapper.socket = newSocket;
518538
newSocket.closed.catch(() => { }).finally(() => closeSocketQuietly(ws));
@@ -1295,42 +1315,84 @@ function sha224(s) {
12951315

12961316
async function 解析地址端口(proxyIP) {
12971317
proxyIP = proxyIP.toLowerCase();
1298-
if (proxyIP.includes('.william')) {
1299-
const williamResult = await (async function 解析William域名(william) {
1300-
try {
1301-
const response = await fetch(`https://1.1.1.1/dns-query?name=${william}&type=TXT`, { headers: { 'Accept': 'application/dns-json' } });
1302-
if (!response.ok) return null;
1303-
const data = await response.json();
1304-
const txtRecords = (data.Answer || []).filter(record => record.type === 16).map(record => record.data);
1305-
if (txtRecords.length === 0) return null;
1306-
let txtData = txtRecords[0];
1307-
if (txtData.startsWith('"') && txtData.endsWith('"')) txtData = txtData.slice(1, -1);
1308-
const prefixes = txtData.replace(/\\010/g, ',').replace(/\n/g, ',').split(',').map(s => s.trim()).filter(Boolean);
1309-
if (prefixes.length === 0) return null;
1310-
return prefixes[Math.floor(Math.random() * prefixes.length)];
1311-
} catch (error) {
1312-
console.error('解析ProxyIP失败:', error);
1313-
return null;
1314-
}
1315-
})(proxyIP);
1316-
proxyIP = williamResult || proxyIP;
1318+
async function DoH查询(域名, 记录类型) {
1319+
try {
1320+
const response = await fetch(`https://1.1.1.1/dns-query?name=${域名}&type=${记录类型}`, {
1321+
headers: { 'Accept': 'application/dns-json' }
1322+
});
1323+
if (!response.ok) return [];
1324+
const data = await response.json();
1325+
return data.Answer || [];
1326+
} catch (error) {
1327+
console.error(`DoH查询失败 (${记录类型}):`, error);
1328+
return [];
1329+
}
13171330
}
1318-
let 地址 = proxyIP, 端口 = 443;
1319-
if (proxyIP.includes('.tp')) {
1320-
const tpMatch = proxyIP.match(/\.tp(\d+)/);
1321-
if (tpMatch) 端口 = parseInt(tpMatch[1], 10);
1331+
1332+
function 解析地址端口字符串(str) {
1333+
let 地址 = str, 端口 = 443;
1334+
if (str.includes(']:')) {
1335+
const parts = str.split(']:');
1336+
地址 = parts[0] + ']';
1337+
端口 = parseInt(parts[1], 10) || 端口;
1338+
} else if (str.includes(':') && !str.startsWith('[')) {
1339+
const colonIndex = str.lastIndexOf(':');
1340+
地址 = str.slice(0, colonIndex);
1341+
端口 = parseInt(str.slice(colonIndex + 1), 10) || 端口;
1342+
}
13221343
return [地址, 端口];
13231344
}
1324-
if (proxyIP.includes(']:')) {
1325-
const parts = proxyIP.split(']:');
1326-
地址 = parts[0] + ']';
1327-
端口 = parseInt(parts[1], 10) || 端口;
1328-
} else if (proxyIP.includes(':') && !proxyIP.startsWith('[')) {
1329-
const colonIndex = proxyIP.lastIndexOf(':');
1330-
地址 = proxyIP.slice(0, colonIndex);
1331-
端口 = parseInt(proxyIP.slice(colonIndex + 1), 10) || 端口;
1345+
1346+
let 所有反代数组 = [];
1347+
1348+
if (proxyIP.includes('.william')) {
1349+
try {
1350+
const txtRecords = await DoH查询(proxyIP, 'TXT');
1351+
const txtData = txtRecords.filter(r => r.type === 16).map(r => r.data);
1352+
if (txtData.length > 0) {
1353+
let data = txtData[0];
1354+
if (data.startsWith('"') && data.endsWith('"')) data = data.slice(1, -1);
1355+
const prefixes = data.replace(/\\010/g, ',').replace(/\n/g, ',').split(',').map(s => s.trim()).filter(Boolean);
1356+
所有反代数组 = prefixes.map(prefix => 解析地址端口字符串(prefix));
1357+
}
1358+
} catch (error) {
1359+
console.error('解析William域名失败:', error);
1360+
}
1361+
} else {
1362+
let [地址, 端口] = 解析地址端口字符串(proxyIP);
1363+
1364+
if (proxyIP.includes('.tp')) {
1365+
const tpMatch = proxyIP.match(/\.tp(\d+)/);
1366+
if (tpMatch) 端口 = parseInt(tpMatch[1], 10);
1367+
}
1368+
1369+
// 判断是否是域名(非IP地址)
1370+
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?)$/;
1371+
const ipv6Regex = /^\[?([a-fA-F0-9:]+)\]?$/;
1372+
1373+
if (!ipv4Regex.test(地址) && !ipv6Regex.test(地址)) {
1374+
// 并行查询 A 和 AAAA 记录
1375+
const [aRecords, aaaaRecords] = await Promise.all([
1376+
DoH查询(地址, 'A'),
1377+
DoH查询(地址, 'AAAA')
1378+
]);
1379+
1380+
const ipv4List = aRecords.filter(r => r.type === 1).map(r => r.data);
1381+
const ipv6List = aaaaRecords.filter(r => r.type === 28).map(r => `[${r.data}]`);
1382+
const ipAddresses = [...ipv4List, ...ipv6List];
1383+
1384+
所有反代数组 = ipAddresses.length > 0
1385+
? ipAddresses.map(ip => [ip, 端口])
1386+
: [[地址, 端口]];
1387+
} else {
1388+
所有反代数组 = [[地址, 端口]];
1389+
}
13321390
}
1333-
return [地址, 端口];
1391+
1392+
return 所有反代数组;
1393+
// low
1394+
const [选中地址, 选中端口] = 所有反代数组[Math.floor(Math.random() * 所有反代数组.length)];
1395+
return [选中地址, 选中端口];
13341396
}
13351397

13361398
async function SOCKS5可用性验证(代理协议 = 'socks5', 代理参数) {

0 commit comments

Comments
 (0)