Skip to content

Commit ce7ef9f

Browse files
authored
Merge pull request #961 from cmliu/beta2.0
Beta2.0
2 parents ec259e2 + bc390f7 commit ce7ef9f

1 file changed

Lines changed: 114 additions & 43 deletions

File tree

_worker.js

Lines changed: 114 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import //crypto from "node:crypto";
2-
/*How can we utilize the*/ { connect }
3-
/*function*/ from /*the*/ "cloudflare:sockets";//​ library in this Worker?
1+
/*In our project workflow, we first*/ import //the necessary modules,
2+
/*then*/ { connect }//to the central server,
3+
/*and all data flows*/ from//this single source.
4+
'cloudflare\u003asockets';
45
let config_JSON, 反代IP = '', 启用SOCKS5反代 = null, 启用SOCKS5全局反代 = false, 我的SOCKS5账号 = '', parsedSocks5Address = {};
56
let 缓存反代IP, 缓存反代解析数组, 缓存反代数组索引 = 0, 启用反代兜底 = true;
67
let SOCKS5白名单 = ['*tapecontent.net', '*cloudatacdn.com', '*loadshare.org', '*cdn-centaurus.com', 'scholar.google.com'];
@@ -1358,9 +1359,8 @@ async function getECH(host) {
13581359

13591360
async function 读取config_JSON(env, hostname, userID, 重置配置 = false) {
13601361
//const host = 随机替换通配符(hostname);
1361-
const host = hostname, CM_DoH = "https://doh.cmliussss.net/CMLiussss";
1362-
const 初始化开始时间 = performance.now();
1363-
const 默认配置JSON = {
1362+
const _p = atob("UFJPWFlJUA==");
1363+
const host = hostname, CM_DoH = "https://doh.cmliussss.net/CMLiussss", 占位符 = '{{IP:PORT}}', 初始化开始时间 = performance.now(), 默认配置JSON = {
13641364
TIME: new Date().toISOString(),
13651365
HOST: host,
13661366
HOSTS: [hostname],
@@ -1396,13 +1396,24 @@ async function 读取config_JSON(env, hostname, userID, 重置配置 = false) {
13961396
SUBEMOJI: false,
13971397
},
13981398
反代: {
1399-
PROXYIP: "auto",
1399+
[_p]: "auto",
14001400
SOCKS5: {
14011401
启用: 启用SOCKS5反代,
14021402
全局: 启用SOCKS5全局反代,
14031403
账号: 我的SOCKS5账号,
14041404
白名单: SOCKS5白名单,
14051405
},
1406+
路径模板: {
1407+
[_p]: "proxyip=" + 占位符,
1408+
SOCKS5: {
1409+
全局: "socks5://" + 占位符,
1410+
标准: "socks5=" + 占位符
1411+
},
1412+
HTTP: {
1413+
全局: "http://" + 占位符,
1414+
标准: "http=" + 占位符
1415+
},
1416+
},
14061417
},
14071418
TG: {
14081419
启用: false,
@@ -1448,15 +1459,39 @@ async function 读取config_JSON(env, hostname, userID, 重置配置 = false) {
14481459
if (env.PATH) config_JSON.PATH = env.PATH.startsWith('/') ? env.PATH : '/' + env.PATH;
14491460
else if (!config_JSON.PATH) config_JSON.PATH = '/';
14501461

1451-
const { SOCKS5: 袜子五, PROXYIP: 反代挨批 } = config_JSON.反代;
1452-
const 路径反代参数 = 袜子五.启用
1453-
? `${袜子五.启用}${袜子五.全局 ? '://' : '='}${袜子五.账号}`
1454-
: 反代挨批 !== 'auto' ? `proxyip=${反代挨批}` : '';
1462+
if (!config_JSON.反代.路径模板?.[_p]) {
1463+
config_JSON.反代.路径模板 = {
1464+
[_p]: "proxyip=" + 占位符,
1465+
SOCKS5: {
1466+
全局: "socks5://" + 占位符,
1467+
标准: "socks5=" + 占位符
1468+
},
1469+
HTTP: {
1470+
全局: "http://" + 占位符,
1471+
标准: "http=" + 占位符
1472+
},
1473+
};
1474+
}
1475+
1476+
const 代理配置 = config_JSON.反代.路径模板[config_JSON.反代.SOCKS5.启用?.toUpperCase()];
1477+
1478+
let 路径反代参数 = '';
1479+
if (代理配置 && config_JSON.反代.SOCKS5.账号) 路径反代参数 = (config_JSON.反代.SOCKS5.全局 ? 代理配置.全局 : 代理配置.标准).replace(占位符, config_JSON.反代.SOCKS5.账号);
1480+
else if (config_JSON.反代[_p] !== 'auto') 路径反代参数 = config_JSON.反代.路径模板[_p].replace(占位符, config_JSON.反代[_p]);
1481+
1482+
let 反代查询参数 = '';
1483+
if (路径反代参数.includes('?')) {
1484+
const [反代路径部分, 反代查询部分] = 路径反代参数.split('?');
1485+
路径反代参数 = 反代路径部分;
1486+
反代查询参数 = 反代查询部分;
1487+
}
1488+
14551489
config_JSON.PATH = config_JSON.PATH.replace(路径反代参数, '').replace('//', '/');
14561490
const normalizedPath = config_JSON.PATH === '/' ? '' : config_JSON.PATH.replace(/\/+(?=\?|$)/, '').replace(/\/+$/, '');
14571491
const [路径部分, ...查询数组] = normalizedPath.split('?');
14581492
const 查询部分 = 查询数组.length ? '?' + 查询数组.join('?') : '';
1459-
config_JSON.完整节点路径 = (路径部分 || '/') + (路径部分 && 路径反代参数 ? '/' : '') + 路径反代参数 + 查询部分 + (config_JSON.启用0RTT ? (查询部分 ? '&' : '?') + 'ed=2560' : '');
1493+
const 最终查询部分 = 反代查询参数 ? (查询部分 ? 查询部分 + '&' + 反代查询参数 : '?' + 反代查询参数) : 查询部分;
1494+
config_JSON.完整节点路径 = (路径部分 || '/') + (路径部分 && 路径反代参数 ? '/' : '') + 路径反代参数 + 最终查询部分 + (config_JSON.启用0RTT ? (最终查询部分 ? '&' : '?') + 'ed=2560' : '');
14601495

14611496
if (!config_JSON.TLS分片 && config_JSON.TLS分片 !== null) config_JSON.TLS分片 = null;
14621497
const TLS分片参数 = config_JSON.TLS分片 == 'Shadowrocket' ? `&fragment=${encodeURIComponent('1,40-60,30-50,tlshello')}` : config_JSON.TLS分片 == 'Happ' ? `&fragment=${encodeURIComponent('3,1,tlshello')}` : '';
@@ -1703,50 +1738,86 @@ async function 反代参数获取(request) {
17031738
我的SOCKS5账号 = searchParams.get('socks5') || searchParams.get('http') || null;
17041739
启用SOCKS5全局反代 = searchParams.has('globalproxy') || false;
17051740

1706-
// 统一处理反代IP参数 (优先级最高,使用正则一次匹配)
1707-
const proxyMatch = pathLower.match(/\/(proxyip[.=]|pyip=|ip=)([^/?]+)/);
1741+
// 辅助函数:解析代理协议URL (socks5://... 或 http://...)
1742+
const 解析代理URL = (proxyUrl, 默认全局 = true) => {
1743+
const protocolMatch = proxyUrl.match(/^(socks5|http):\/\/(.+)$/i);
1744+
if (!protocolMatch) return false;
1745+
启用SOCKS5反代 = protocolMatch[1].toLowerCase();
1746+
我的SOCKS5账号 = protocolMatch[2].split('/')[0];
1747+
启用SOCKS5全局反代 = 默认全局 || 启用SOCKS5全局反代;
1748+
return true;
1749+
};
1750+
1751+
// 辅助函数:从路径值中提取干净的地址(移除后续路径段)
1752+
const 提取路径值 = (rawValue) => {
1753+
if (rawValue.includes('://')) {
1754+
// 协议URL:保留 protocol://user:pass@host:port,移除后续路径
1755+
const protocolPart = rawValue.split('://');
1756+
if (protocolPart.length === 2) {
1757+
const [protocol, afterProtocol] = protocolPart;
1758+
const firstSlashIndex = afterProtocol.indexOf('/');
1759+
if (firstSlashIndex > 0) {
1760+
return protocol + '://' + afterProtocol.substring(0, firstSlashIndex);
1761+
}
1762+
}
1763+
} else {
1764+
// 普通IP:PORT:只保留到第一个 /
1765+
const firstSlashIndex = rawValue.indexOf('/');
1766+
if (firstSlashIndex > 0) {
1767+
return rawValue.substring(0, firstSlashIndex);
1768+
}
1769+
}
1770+
return rawValue;
1771+
};
1772+
1773+
// ==================== 第一步:处理 query 参数 ====================
1774+
// 优先级最高:?proxyip=, ?socks5=, ?http=
1775+
let socksMatch, proxyMatch;
17081776
if (searchParams.has('proxyip')) {
17091777
const 路参IP = searchParams.get('proxyip');
1710-
反代IP = 路参IP.includes(',') ? 路参IP.split(',')[Math.floor(Math.random() * 路参IP.split(',').length)] : 路参IP;
1711-
启用反代兜底 = false;
1712-
return;
1713-
} else if (proxyMatch) {
1714-
const 路参IP = proxyMatch[1] === 'proxyip.' ? `proxyip.${proxyMatch[2]}` : proxyMatch[2];
1715-
反代IP = 路参IP.includes(',') ? 路参IP.split(',')[Math.floor(Math.random() * 路参IP.split(',').length)] : 路参IP;
1716-
启用反代兜底 = false;
1717-
return;
1778+
// proxyip 值以 socks5:// 或 http:// 开头,视为对应协议处理
1779+
if (解析代理URL(路参IP)) { /* 继续到下方统一解析 */ }
1780+
else {
1781+
// 否则作为 IP 反代
1782+
反代IP = 路参IP.includes(',') ? 路参IP.split(',')[Math.floor(Math.random() * 路参IP.split(',').length)] : 路参IP;
1783+
启用反代兜底 = false;
1784+
return;
1785+
}
17181786
}
1787+
// query 中的 ?socks5= 和 ?http= 已在初始化时由 searchParams.get 处理
17191788

1720-
// 处理SOCKS5/HTTP代理参数
1721-
let socksMatch;
1722-
if ((socksMatch = pathname.match(/\/(socks5?|http):\/?\/?([^/?#]+)/i))) {
1723-
// 格式: /socks5://... 或 /http://...
1789+
// ==================== 第二步:处理路径中的 SOCKS5/HTTP 协议关键词 ====================
1790+
// 匹配:/socks5://..., /socks://.., /http://...
1791+
else if ((socksMatch = pathname.match(/\/(socks5?|http):\/?\/?([^/?#\s]+)/i))) {
17241792
启用SOCKS5反代 = socksMatch[1].toLowerCase() === 'http' ? 'http' : 'socks5';
1725-
我的SOCKS5账号 = socksMatch[2];
1793+
我的SOCKS5账号 = socksMatch[2].split('/')[0];
17261794
启用SOCKS5全局反代 = true;
1727-
1728-
// 处理Base64编码的用户名密码
1729-
if (我的SOCKS5账号.includes('@')) {
1730-
const atIndex = 我的SOCKS5账号.lastIndexOf('@');
1731-
let userPassword = 我的SOCKS5账号.substring(0, atIndex).replaceAll('%3D', '=');
1732-
if (/^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i.test(userPassword) && !userPassword.includes(':')) {
1733-
userPassword = atob(userPassword);
1734-
}
1735-
我的SOCKS5账号 = `${userPassword}@${我的SOCKS5账号.substring(atIndex + 1)}`;
1736-
}
1737-
} else if ((socksMatch = pathname.match(/\/(g?s5|socks5|g?http)=([^/?#]+)/i))) {
1738-
// 格式: /socks5=... 或 /s5=... 或 /gs5=... 或 /http=... 或 /ghttp=...
1795+
}
1796+
// 匹配:/socks5=..., /s5=..., /gs5=..., /http=..., /ghttp=...
1797+
else if ((socksMatch = pathname.match(/\/(g?s5|socks5|g?http)=([^/?#\s]+)/i))) {
17391798
const type = socksMatch[1].toLowerCase();
1740-
我的SOCKS5账号 = socksMatch[2];
1799+
我的SOCKS5账号 = socksMatch[2].split('/')[0];
17411800
启用SOCKS5反代 = type.includes('http') ? 'http' : 'socks5';
1742-
启用SOCKS5全局反代 = type.startsWith('g') || 启用SOCKS5全局反代; // gs5 或 ghttp 开头启用全局
1801+
启用SOCKS5全局反代 = type.startsWith('g') || 启用SOCKS5全局反代;
1802+
}
1803+
1804+
// ==================== 第三步:处理路径中的 proxyip/pyip/ip ====================
1805+
else if ((proxyMatch = pathLower.match(/\/(proxyip[.=]|pyip=|ip=)([^?#\s]+)/))) {
1806+
let 路参IP = 提取路径值(proxyMatch[2]);
1807+
// proxyip 值以 socks5:// 或 http:// 开头,视为对应协议处理
1808+
if (!解析代理URL(路参IP)) {
1809+
// 否则作为 IP 反代
1810+
反代IP = 路参IP.includes(',') ? 路参IP.split(',')[Math.floor(Math.random() * 路参IP.split(',').length)] : 路参IP;
1811+
启用反代兜底 = false;
1812+
return;
1813+
}
17431814
}
17441815

1745-
// 解析SOCKS5地址
1816+
// 统一解析SOCKS5地址
17461817
if (我的SOCKS5账号) {
17471818
try {
17481819
parsedSocks5Address = await 获取SOCKS5账号(我的SOCKS5账号);
1749-
启用SOCKS5反代 = searchParams.get('http') ? 'http' : 启用SOCKS5反代;
1820+
启用SOCKS5反代 = searchParams.get('http') ? 'http' : (启用SOCKS5反代 || 'socks5');
17501821
} catch (err) {
17511822
console.error('解析SOCKS5地址失败:', err.message);
17521823
启用SOCKS5反代 = null;

0 commit comments

Comments
 (0)