diff --git "a/\346\230\216\346\226\207\346\272\220\347\240\201.js" "b/\346\230\216\346\226\207\346\272\220\347\240\201.js"
index 19691c05d8..fddffda11b 100644
--- "a/\346\230\216\346\226\207\346\272\220\347\240\201.js"
+++ "b/\346\230\216\346\226\207\346\272\220\347\240\201.js"
@@ -9,12 +9,12 @@ let subConfig = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/
let subProtocol = 'https';
let subEmoji = 'true';
let socks5Address = '';
-let parsedSocks5Address = {};
+let parsedSocks5Address = {};
let enableSocks = false;
-let fakeUserID ;
-let fakeHostName ;
-let noTLS = 'false';
+let fakeUserID;
+let fakeHostName;
+let noTLS = 'false';
const expire = 4102329600;//2099-12-31
let proxyIPs;
let socks5s;
@@ -33,11 +33,11 @@ let DLS = 8;
let remarkIndex = 1;//CSV备注所在列偏移量
let FileName = atob('ZWRnZXR1bm5lbA==');
let BotToken;
-let ChatID;
+let ChatID;
let proxyhosts = [];
let proxyhostsURL = '';
let RproxyIP = 'false';
-let httpsPorts = ["2053","2083","2087","2096","8443"];
+let httpsPorts = ["2053", "2083", "2087", "2096", "8443"];
let 有效时间 = 7;
let 更新时间 = 3;
let userIDLow;
@@ -63,7 +63,7 @@ export default {
}
if (!userID) {
- return new Response('请设置你的UUID变量,或尝试重试部署,检查变量是否生效?', {
+ return new Response('请设置你的UUID变量,或尝试重试部署,检查变量是否生效?', {
status: 404,
headers: {
"Content-Type": "text/plain;charset=utf-8",
@@ -71,7 +71,7 @@ export default {
});
}
const currentDate = new Date();
- currentDate.setHours(0, 0, 0, 0);
+ currentDate.setHours(0, 0, 0, 0);
const timestamp = Math.ceil(currentDate.getTime() / 1000);
const fakeUserIDMD5 = await 双重哈希(`${userID}${timestamp}`);
fakeUserID = [
@@ -81,7 +81,7 @@ export default {
fakeUserIDMD5.slice(16, 20),
fakeUserIDMD5.slice(20)
].join('-');
-
+
fakeHostName = `${fakeUserIDMD5.slice(6, 9)}.${fakeUserIDMD5.slice(13, 19)}`;
proxyIP = env.PROXYIP || env.proxyip || proxyIP;
@@ -121,14 +121,14 @@ export default {
DLS = Number(env.DLS) || DLS;
remarkIndex = Number(env.CSVREMARK) || remarkIndex;
BotToken = env.TGTOKEN || BotToken;
- ChatID = env.TGID || ChatID;
+ ChatID = env.TGID || ChatID;
FileName = env.SUBNAME || FileName;
subEmoji = env.SUBEMOJI || env.EMOJI || subEmoji;
if (subEmoji == '0') subEmoji = 'false';
- if (env.LINK) link = await 整理(env.LINK) ;
+ if (env.LINK) link = await 整理(env.LINK);
sub = env.SUB || sub;
subConverter = env.SUBAPI || subConverter;
- if (subConverter.includes("http://") ){
+ if (subConverter.includes("http://")) {
subConverter = subConverter.split("//")[1];
subProtocol = 'http';
} else {
@@ -172,12 +172,12 @@ export default {
//const timestamp = Math.floor(now / 1000);
const today = new Date(now);
today.setHours(0, 0, 0, 0);
- const UD = Math.floor(((now - today.getTime())/86400000) * 24 * 1099511627776 / 2);
+ const UD = Math.floor(((now - today.getTime()) / 86400000) * 24 * 1099511627776 / 2);
let pagesSum = UD;
let workersSum = UD;
- let total = 24 * 1099511627776 ;
+ let total = 24 * 1099511627776;
- if (userAgent && userAgent.includes('mozilla')){
+ if (userAgent && userAgent.includes('mozilla')) {
return new Response(`
${维列斯Config}
`, {
status: 200,
headers: {
@@ -208,7 +208,7 @@ export default {
if (new RegExp('/socks5=', 'i').test(url.pathname)) socks5Address = url.pathname.split('5=')[1];
else if (new RegExp('/socks://', 'i').test(url.pathname) || new RegExp('/socks5://', 'i').test(url.pathname)) {
socks5Address = url.pathname.split('://')[1].split('#')[0];
- if (socks5Address.includes('@')){
+ if (socks5Address.includes('@')) {
let userPassword = socks5Address.split('@')[0];
const base64Regex = /^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i;
if (base64Regex.test(userPassword) && !userPassword.includes(':')) userPassword = atob(userPassword);
@@ -229,7 +229,7 @@ export default {
enableSocks = false;
}
- if (url.searchParams.has('proxyip')){
+ if (url.searchParams.has('proxyip')) {
proxyIP = url.searchParams.get('proxyip');
enableSocks = false;
} else if (new RegExp('/proxyip=', 'i').test(url.pathname)) {
@@ -360,7 +360,7 @@ async function 维列斯OverWSHandler(request) {
async function handleTCPOutBound(remoteSocket, addressType, addressRemote, portRemote, rawClientData, webSocket, 维列斯ResponseHeader, log,) {
async function useSocks5Pattern(address) {
- if ( go2Socks5s.includes(atob('YWxsIGlu')) || go2Socks5s.includes(atob('Kg==')) ) return true;
+ if (go2Socks5s.includes(atob('YWxsIGlu')) || go2Socks5s.includes(atob('Kg=='))) return true;
return go2Socks5s.some(pattern => {
let regexPattern = pattern.replace(/\*/g, '.*');
let regex = new RegExp(`^${regexPattern}$`, 'i');
@@ -419,7 +419,7 @@ async function handleTCPOutBound(remoteSocket, addressType, addressRemote, portR
}
let useSocks = false;
- if (go2Socks5s.length > 0 && enableSocks ) useSocks = await useSocks5Pattern(addressRemote);
+ if (go2Socks5s.length > 0 && enableSocks) useSocks = await useSocks5Pattern(addressRemote);
// 首次尝试连接远程服务器
let tcpSocket = await connectAndWrite(addressRemote, portRemote, useSocks);
@@ -750,15 +750,15 @@ function base64ToArrayBuffer(base64Str) {
// 这种变体使用 '-' 和 '_' 来代替标准 Base64 中的 '+' 和 '/'
// JavaScript 的 atob 函数不直接支持这种变体,所以我们需要先转换
base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/');
-
+
// 使用 atob 函数解码 Base64 字符串
// atob 将 Base64 编码的 ASCII 字符串转换为原始的二进制字符串
const decode = atob(base64Str);
-
+
// 将二进制字符串转换为 Uint8Array
// 这是通过遍历字符串中的每个字符并获取其 Unicode 编码值(0-255)来完成的
const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0));
-
+
// 返回 Uint8Array 的底层 ArrayBuffer
// 这是实际的二进制数据,可以用于网络传输或其他二进制操作
return { earlyData: arryBuffer.buffer, error: null };
@@ -776,7 +776,7 @@ function base64ToArrayBuffer(base64Str) {
function isValidUUID(uuid) {
// 定义一个正则表达式来匹配 UUID 格式
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
-
+
// 使用正则表达式测试 UUID 字符串
return uuidRegex.test(uuid);
}
@@ -839,7 +839,7 @@ function stringify(arr, offset = 0) {
// 验证生成的 UUID 是否有效
if (!isValidUUID(uuid)) {
// 原:throw TypeError("Stringified UUID is invalid");
- throw TypeError(`生成的 UUID 不符合规范 ${uuid}`);
+ throw TypeError(`生成的 UUID 不符合规范 ${uuid}`);
//uuid = userID;
}
return uuid;
@@ -1108,14 +1108,14 @@ function socks5AddressParser(address) {
*/
function 恢复伪装信息(content, userID, hostName, isBase64) {
if (isBase64) content = atob(content); // 如果内容是Base64编码的,先解码
-
+
// 使用正则表达式全局替换('g'标志)
// 将所有出现的假用户ID和假主机名替换为真实的值
content = content.replace(new RegExp(fakeUserID, 'g'), userID)
- .replace(new RegExp(fakeHostName, 'g'), hostName);
-
+ .replace(new RegExp(fakeHostName, 'g'), hostName);
+
if (isBase64) content = btoa(content); // 如果原内容是Base64编码的,处理完后再次编码
-
+
return content;
}
@@ -1137,7 +1137,7 @@ async function 双重哈希(文本) {
const 第二次哈希 = await crypto.subtle.digest('MD5', 编码器.encode(第一次十六进制.slice(7, 27)));
const 第二次哈希数组 = Array.from(new Uint8Array(第二次哈希));
const 第二次十六进制 = 第二次哈希数组.map(字节 => 字节.toString(16).padStart(2, '0')).join('');
-
+
return 第二次十六进制.toLowerCase();
}
@@ -1184,34 +1184,34 @@ async function 代理URL(代理网址, 目标网址) {
const 啥啥啥_写的这是啥啊 = atob('ZG14bGMzTT0=');
function 配置信息(UUID, 域名地址) {
const 协议类型 = atob(啥啥啥_写的这是啥啊);
-
+
const 别名 = FileName;
let 地址 = 域名地址;
let 端口 = 443;
const 用户ID = UUID;
const 加密方式 = 'none';
-
+
const 传输层协议 = 'ws';
const 伪装域名 = 域名地址;
const 路径 = path;
-
- let 传输层安全 = ['tls',true];
+
+ let 传输层安全 = ['tls', true];
const SNI = 域名地址;
const 指纹 = 'randomized';
- if (域名地址.includes('.workers.dev')){
+ if (域名地址.includes('.workers.dev')) {
地址 = atob('dmlzYS5jbg==');
- 端口 = 80 ;
- 传输层安全 = ['',false];
+ 端口 = 80;
+ 传输层安全 = ['', false];
}
- const 威图瑞 = `${协议类型}://${用户ID}@${地址}:${端口}\u003f\u0065\u006e\u0063\u0072\u0079`+'p'+`${atob('dGlvbj0=') + 加密方式}\u0026\u0073\u0065\u0063\u0075\u0072\u0069\u0074\u0079\u003d${传输层安全[0]}&sni=${SNI}&fp=${指纹}&type=${传输层协议}&host=${伪装域名}&path=${encodeURIComponent(路径)}#${encodeURIComponent(别名)}`;
+ const 威图瑞 = `${协议类型}://${用户ID}@${地址}:${端口}\u003f\u0065\u006e\u0063\u0072\u0079` + 'p' + `${atob('dGlvbj0=') + 加密方式}\u0026\u0073\u0065\u0063\u0075\u0072\u0069\u0074\u0079\u003d${传输层安全[0]}&sni=${SNI}&fp=${指纹}&type=${传输层协议}&host=${伪装域名}&path=${encodeURIComponent(路径)}#${encodeURIComponent(别名)}`;
const 猫猫猫 = `- {name: ${FileName}, server: ${地址}, port: ${端口}, type: ${协议类型}, uuid: ${用户ID}, tls: ${传输层安全[1]}, alpn: [h3], udp: false, sni: ${SNI}, tfo: false, skip-cert-verify: true, servername: ${伪装域名}, client-fingerprint: ${指纹}, network: ${传输层协议}, ws-opts: {path: "${路径}", headers: {${伪装域名}}}}`;
- return [威图瑞,猫猫猫];
+ return [威图瑞, 猫猫猫];
}
-let subParams = ['sub','base64','b64','clash','singbox','sb'];
+let subParams = ['sub', 'base64', 'b64', 'clash', 'singbox', 'sb'];
const cmad = decodeURIComponent(atob('dGVsZWdyYW0lMjAlRTQlQkElQTQlRTYlQjUlODElRTclQkUlQTQlMjAlRTYlOEElODAlRTYlOUMlQUYlRTUlQTQlQTclRTQlQkQlQUMlN0UlRTUlOUMlQTglRTclQkElQkYlRTUlOEYlOTElRTclODklOEMhJTNDYnIlM0UKJTNDYSUyMGhyZWYlM0QlMjdodHRwcyUzQSUyRiUyRnQubWUlMkZDTUxpdXNzc3MlMjclM0VodHRwcyUzQSUyRiUyRnQubWUlMkZDTUxpdXNzc3MlM0MlMkZhJTNFJTNDYnIlM0UKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJTNDYnIlM0UKZ2l0aHViJTIwJUU5JUExJUI5JUU3JTlCJUFFJUU1JTlDJUIwJUU1JTlEJTgwJTIwU3RhciFTdGFyIVN0YXIhISElM0NiciUzRQolM0NhJTIwaHJlZiUzRCUyN2h0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNtbGl1JTJGZWRnZXR1bm5lbCUyNyUzRWh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNtbGl1JTJGZWRnZXR1bm5lbCUzQyUyRmElM0UlM0NiciUzRQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0lM0NiciUzRQolMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjM='));
/**
* @param {string} userID
@@ -1229,7 +1229,7 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
const subs = await 整理(sub);
if (subs.length > 1) sub = subs[0];
} else {
- if (env.KV){
+ if (env.KV) {
await 迁移地址列表(env);
const 优选地址列表 = await env.KV.get('ADD.txt');
if (优选地址列表) {
@@ -1239,7 +1239,7 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
链接地址: new Set(),
优选地址: new Set()
};
-
+
for (const 元素 of 优选地址数组) {
if (元素.startsWith('https://')) {
分类地址.接口地址.add(元素);
@@ -1249,14 +1249,14 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
分类地址.优选地址.add(元素);
}
}
-
+
addressesapi = [...分类地址.接口地址];
link = [...分类地址.链接地址];
addresses = [...分类地址.优选地址];
}
}
-
- if ((addresses.length + addressesapi.length + addressesnotls.length + addressesnotlsapi.length + addressescsv.length) == 0){
+
+ if ((addresses.length + addressesapi.length + addressesnotls.length + addressesnotlsapi.length + addressescsv.length) == 0) {
// 定义 Cloudflare IP 范围的 CIDR 列表
let cfips = [
'103.21.244.0/23',
@@ -1271,7 +1271,7 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
'188.114.96.0/21',
'190.93.240.0/21',
];
-
+
// 生成符合给定 CIDR 范围的随机 IP 地址
function generateRandomIPFromCIDR(cidr) {
const [base, mask] = cidr.split('/');
@@ -1279,13 +1279,13 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
const subnetMask = 32 - parseInt(mask, 10);
const maxHosts = Math.pow(2, subnetMask) - 1;
const randomHost = Math.floor(Math.random() * maxHosts);
-
+
const randomIP = baseIP.map((octet, index) => {
if (index < 2) return octet;
if (index === 2) return (octet & (255 << (subnetMask - 8))) + ((randomHost >> 8) & 255);
return (octet & (255 << subnetMask)) + (randomHost & 255);
});
-
+
return randomIP.join('.');
}
addresses = addresses.concat('127.0.0.1:1234#CFnat');
@@ -1299,30 +1299,30 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
const uuid = (_url.pathname == `/${动态UUID}`) ? 动态UUID : userID;
const userAgent = UA.toLowerCase();
- const Config = 配置信息(userID , hostName);
+ const Config = 配置信息(userID, hostName);
const v2ray = Config[0];
const clash = Config[1];
let proxyhost = "";
- if(hostName.includes(".workers.dev")){
- if ( proxyhostsURL && (!proxyhosts || proxyhosts.length == 0)) {
+ if (hostName.includes(".workers.dev")) {
+ if (proxyhostsURL && (!proxyhosts || proxyhosts.length == 0)) {
try {
- const response = await fetch(proxyhostsURL);
-
+ const response = await fetch(proxyhostsURL);
+
if (!response.ok) {
console.error('获取地址时出错:', response.status, response.statusText);
return; // 如果有错误,直接返回
}
-
+
const text = await response.text();
const lines = text.split('\n');
// 过滤掉空行或只包含空白字符的行
const nonEmptyLines = lines.filter(line => line.trim() !== '');
-
+
proxyhosts = proxyhosts.concat(nonEmptyLines);
} catch (error) {
//console.error('获取地址时出错:', error);
}
- }
+ }
if (proxyhosts.length != 0) proxyhost = proxyhosts[Math.floor(Math.random() * proxyhosts.length)] + "/";
}
@@ -1334,9 +1334,9 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
});
let socks5List = '';
- if (go2Socks5s.length > 0 && enableSocks ) {
+ if (go2Socks5s.length > 0 && enableSocks) {
socks5List = `${decodeURIComponent('SOCKS5%EF%BC%88%E7%99%BD%E5%90%8D%E5%8D%95%EF%BC%89%3A%20')}`;
- if (go2Socks5s.includes(atob('YWxsIGlu'))||go2Socks5s.includes(atob('Kg=='))) socks5List += `${decodeURIComponent('%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F')}
`;
+ if (go2Socks5s.includes(atob('YWxsIGlu')) || go2Socks5s.includes(atob('Kg=='))) socks5List += `${decodeURIComponent('%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F')}
`;
else socks5List += `
${go2Socks5s.join('
')}
`;
}
@@ -1366,23 +1366,20 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
const 动态UUID信息 = (uuid != userID) ? `TOKEN: ${uuid}
UUIDNow: ${userID}
UUIDLow: ${userIDLow}
${userIDTime}TIME(动态UUID有效时间): ${有效时间} 天
UPTIME(动态UUID更新时间): ${更新时间} 时(北京时间)
` : `${userIDTime}`;
const 节点配置页 = `
################################################################
- Subscribe / sub 订阅地址, 支持 Base64、clash-meta、sing-box 订阅格式
+ Subscribe / sub 订阅地址, 点击链接自动 复制订阅链接 并 生成订阅二维码
---------------------------------------------------------------
自适应订阅地址:
- https://${proxyhost}${hostName}/${uuid}
- https://${proxyhost}${hostName}/${uuid}?sub
-
+ https://${proxyhost}${hostName}/${uuid}
+
Base64订阅地址:
- https://${proxyhost}${hostName}/${uuid}?b64
- https://${proxyhost}${hostName}/${uuid}?base64
-
+ https://${proxyhost}${hostName}/${uuid}?b64
+
clash订阅地址:
- https://${proxyhost}${hostName}/${uuid}?clash
-
+ https://${proxyhost}${hostName}/${uuid}?clash
+
singbox订阅地址:
- https://${proxyhost}${hostName}/${uuid}?sb
- https://${proxyhost}${hostName}/${uuid}?singbox
-
+ https://${proxyhost}${hostName}/${uuid}?sb
+
实用订阅技巧∨
1. 如您使用的是 PassWall、SSR+ 等路由插件,推荐使用 Base64订阅地址 进行订阅;
@@ -1399,13 +1396,25 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env
5. 如需指定多个参数则需要使用'&'做间隔,例如:
https://${proxyhost}${hostName}/${uuid}?sub=sub.google.com&proxyip=proxyip.fxxk.dedyn.io
+