mirror of
https://github.com/lush2020/edgetunnel.git
synced 2026-03-22 01:22:21 +08:00
40
_worker.js
40
_worker.js
@@ -260,14 +260,14 @@ export default {
|
||||
console.warn(`[订阅内容] 不规范的IP格式已忽略: ${原始地址}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return `${协议类型}://${config_JSON.UUID}@${节点地址}:${节点端口}?security=tls&type=${config_JSON.传输协议}&host=${config_JSON.HOST}&sni=${config_JSON.HOST}&path=${encodeURIComponent((随机路径() + 节点路径).replace('/?', '?')) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(节点备注)}`;
|
||||
const 节点HOST = 随机替换通配符(host);
|
||||
return `${协议类型}://${config_JSON.UUID}@${节点地址}:${节点端口}?security=tls&type=${config_JSON.传输协议}&host=${节点HOST}&sni=${节点HOST}&path=${encodeURIComponent(config_JSON.随机路径 ? 随机路径() + 节点路径 : 节点路径) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(节点备注)}`;
|
||||
}).filter(item => item !== null).join('\n');
|
||||
订阅内容 = btoa(其他节点LINK + 订阅内容);
|
||||
} else { // 优选订阅生成器
|
||||
let 优选订阅生成器HOST = url.searchParams.get('sub') || config_JSON.优选订阅生成.SUB;
|
||||
优选订阅生成器HOST = 优选订阅生成器HOST && !/^https?:\/\//i.test(优选订阅生成器HOST) ? `https://${优选订阅生成器HOST}` : 优选订阅生成器HOST;
|
||||
const 优选订阅生成器URL = `${优选订阅生成器HOST}/sub?host=example.com&${协议类型 === ('v' + 'le' + 'ss') ? 'uuid' : 'pw'}=00000000-0000-4000-0000-000000000000&path=${encodeURIComponent((随机路径() + 节点路径).replace('/?', '?')) + TLS分片参数}&type=${config_JSON.传输协议}`;
|
||||
const 优选订阅生成器URL = `${优选订阅生成器HOST}/sub?host=example.com&${协议类型 === ('v' + 'le' + 'ss') ? 'uuid' : 'pw'}=00000000-0000-4000-8000-000000000000&path=${encodeURIComponent(config_JSON.随机路径 ? 随机路径() + 节点路径 : 节点路径) + TLS分片参数}&type=${config_JSON.传输协议}`;
|
||||
try {
|
||||
const response = await fetch(优选订阅生成器URL, { headers: { 'User-Agent': 'v2rayN/edge' + 'tunnel (https://github.com/cmliu/edge' + 'tunnel)' } });
|
||||
if (response.ok) 订阅内容 = btoa(其他节点LINK + atob(await response.text()));
|
||||
@@ -289,9 +289,9 @@ export default {
|
||||
}
|
||||
}
|
||||
if (订阅类型 === 'mixed') {
|
||||
订阅内容 = atob(订阅内容).replace(/example.com/g, config_JSON.HOST).replace(/00000000-0000-4000-0000-000000000000/g, config_JSON.UUID);
|
||||
订阅内容 = 批量替换域名(atob(订阅内容).replace(/00000000-0000-4000-8000-000000000000/g, config_JSON.UUID), host);
|
||||
if (!ua.includes('mozilla')) 订阅内容 = btoa(订阅内容);
|
||||
} else 订阅内容 = 订阅内容.replace(/example.com/g, config_JSON.HOST).replace(/00000000-0000-4000-0000-000000000000/g, config_JSON.UUID);
|
||||
} else 订阅内容 = 批量替换域名(订阅内容.replace(/00000000-0000-4000-8000-000000000000/g, config_JSON.UUID), host);
|
||||
if (订阅类型 === 'singbox') {
|
||||
订阅内容 = JSON.stringify(JSON.parse(订阅内容), null, 2);
|
||||
responseHeaders["content-type"] = 'application/json; charset=utf-8';
|
||||
@@ -819,12 +819,33 @@ async function MD5MD5(文本) {
|
||||
|
||||
function 随机路径() {
|
||||
const 常用路径目录 = ["#","about","account","acg","act","activity","ad","admin","ads","ajax","album","albums","anime","api","app","apps","archive","archives","article","articles","ask","auth","avatar","bbs","bd","blog","blogs","book","books","bt","buy","cart","category","categories","cb","channel","channels","chat","china","city","class","classify","clip","clips","club","cn","code","collect","collection","comic","comics","community","company","config","contact","content","course","courses","cp","data","detail","details","dh","directory","discount","discuss","dl","dload","doc","docs","document","documents","doujin","download","downloads","drama","edu","en","ep","episode","episodes","event","events","f","faq","favorite","favourites","favs","feedback","file","files","film","films","forum","forums","friend","friends","game","games","gif","go","go.html","go.php","group","groups","help","home","hot","htm","html","image","images","img","index","info","intro","item","items","ja","jp","jump","jump.html","jump.php","jumping","knowledge","lang","lesson","lessons","lib","library","link","links","list","live","lives","login","logout","m","mag","magnet","mall","manhua","map","member","members","message","messages","mobile","movie","movies","music","my","new","news","note","novel","novels","online","order","out","out.html","out.php","outbound","p","page","pages","pay","payment","pdf","photo","photos","pic","pics","picture","pictures","play","player","playlist","post","posts","product","products","program","programs","project","qa","question","rank","ranking","read","readme","redirect","redirect.html","redirect.php","reg","register","res","resource","retrieve","sale","search","season","seasons","section","seller","series","service","services","setting","settings","share","shop","show","shows","site","soft","sort","source","special","star","stars","static","stock","store","stream","streaming","streams","student","study","tag","tags","task","teacher","team","tech","temp","test","thread","tool","tools","topic","topics","torrent","trade","travel","tv","txt","type","u","upload","uploads","url","urls","user","users","v","version","video","videos","view","vip","vod","watch","web","wenku","wiki","work","www","zh","zh-cn","zh-tw","zip"];
|
||||
const 随机数 = Math.floor(Math.random() * 4 + 1);
|
||||
const 随机数 = Math.floor(Math.random() * 3 + 1);
|
||||
const 随机路径 = 常用路径目录.sort(() => 0.5 - Math.random()).slice(0, 随机数).join('/');
|
||||
return `/${随机路径}`;
|
||||
}
|
||||
|
||||
async function 读取config_JSON(env, host, userID, 重置配置 = false) {
|
||||
function 随机替换通配符(h) {
|
||||
if (!h?.includes('*')) return h;
|
||||
const 字符集 = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
return h.replace(/\*/g, () => {
|
||||
let s = '';
|
||||
for (let i = 0; i < Math.floor(Math.random() * 14) + 3; i++)
|
||||
s += 字符集[Math.floor(Math.random() * 36)];
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
function 批量替换域名(内容, host, 每组数量 = 2) {
|
||||
let count = 0, currentRandomHost = null;
|
||||
return 内容.replace(/example\.com/g, () => {
|
||||
if (count % 每组数量 === 0) currentRandomHost = 随机替换通配符(host);
|
||||
count++;
|
||||
return currentRandomHost;
|
||||
});
|
||||
}
|
||||
|
||||
async function 读取config_JSON(env, hostname, userID, 重置配置 = false) {
|
||||
const host = 随机替换通配符(hostname);
|
||||
const 初始化开始时间 = performance.now();
|
||||
const 默认配置JSON = {
|
||||
TIME: new Date().toISOString(),
|
||||
@@ -835,6 +856,7 @@ async function 读取config_JSON(env, host, userID, 重置配置 = false) {
|
||||
跳过证书验证: true,
|
||||
启用0RTT: true,
|
||||
TLS分片: null,
|
||||
随机路径: false,
|
||||
优选订阅生成: {
|
||||
local: true, // true: 基于本地的优选地址 false: 优选订阅生成器
|
||||
本地IP库: {
|
||||
@@ -845,7 +867,7 @@ async function 读取config_JSON(env, host, userID, 重置配置 = false) {
|
||||
SUB: null,
|
||||
SUBNAME: "edge" + "tunnel",
|
||||
SUBUpdateTime: 6, // 订阅更新时间(小时)
|
||||
TOKEN: await MD5MD5(host + userID),
|
||||
TOKEN: await MD5MD5(hostname + userID),
|
||||
},
|
||||
订阅转换配置: {
|
||||
SUBAPI: "https://SUBAPI.cmliussss.net",
|
||||
@@ -898,7 +920,7 @@ async function 读取config_JSON(env, host, userID, 重置配置 = false) {
|
||||
config_JSON.PATH = config_JSON.反代.SOCKS5.启用 ? ('/' + config_JSON.反代.SOCKS5.启用 + (config_JSON.反代.SOCKS5.全局 ? '://' : '=') + config_JSON.反代.SOCKS5.账号) : (config_JSON.反代.PROXYIP === 'auto' ? '/' : `/proxyip=${config_JSON.反代.PROXYIP}`);
|
||||
const TLS分片参数 = config_JSON.TLS分片 == 'Shadowrocket' ? `&fragment=${encodeURIComponent('1,40-60,30-50,tlshello')}` : config_JSON.TLS分片 == 'Happ' ? `&fragment=${encodeURIComponent('3,1,tlshello')}` : '';
|
||||
config_JSON.LINK = `${config_JSON.协议类型}://${userID}@${host}:443?security=tls&type=${config_JSON.传输协议}&host=${host}&sni=${host}&path=${encodeURIComponent(config_JSON.启用0RTT ? config_JSON.PATH + '?ed=2560' : config_JSON.PATH) + TLS分片参数}&encryption=none${config_JSON.跳过证书验证 ? '&allowInsecure=1' : ''}#${encodeURIComponent(config_JSON.优选订阅生成.SUBNAME)}`;
|
||||
config_JSON.优选订阅生成.TOKEN = await MD5MD5(host + userID);
|
||||
config_JSON.优选订阅生成.TOKEN = await MD5MD5(hostname + userID);
|
||||
|
||||
const 初始化TG_JSON = { BotToken: null, ChatID: null };
|
||||
config_JSON.TG = { 启用: config_JSON.TG.启用 ? config_JSON.TG.启用 : false, ...初始化TG_JSON };
|
||||
|
||||
Reference in New Issue
Block a user