diff --git a/README.md b/README.md
index 50a6f131..9fbca71a 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,10 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ
- 另外,您也可以选择自行部署 [WorkerVless2sub 订阅生成服务](https://github.com/cmliu/WorkerVless2sub),这样既可以利用订阅生成器的便利。
## Workers 部署方法 [视频教程](https://www.youtube.com/watch?v=MBlAqYajVSY&t=169s)
+
+
+「 Workers 部署文字教程 」
+
1. 部署 CF Worker:
- 在 CF Worker 控制台中创建一个新的 Worker。
- 将 [worker.js](https://github.com/cmliu/epeius/blob/main/_worker.js) 的内容粘贴到 Worker 编辑器中。
@@ -56,21 +60,28 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ
3. 访问订阅内容:
- 访问 `https://[YOUR-WORKERS-URL]/[PASSWORD]` 即可获取订阅内容。
- - 例如 `https://vless.google.workers.dev/auto` 就是你的通用自适应订阅地址。
- - 例如 `https://vless.google.workers.dev/auto?sub` Base64订阅格式,适用PassWall,SSR+等。
- - 例如 `https://vless.google.workers.dev/auto?clash` Clash订阅格式,适用OpenClash等。
- - 例如 `https://vless.google.workers.dev/auto?sb` singbox订阅格式,适用singbox等。
+ - 例如 `https://trojan.google.workers.dev/auto` 就是你的通用自适应订阅地址。
+ - 例如 `https://trojan.google.workers.dev/auto?sub` Base64订阅格式,适用PassWall,SSR+等。
+ - 例如 `https://trojan.google.workers.dev/auto?clash` Clash订阅格式,适用OpenClash等。
+ - 例如 `https://trojan.google.workers.dev/auto?sb` singbox订阅格式,适用singbox等。
4. 给 workers绑定 自定义域:
- 在 workers控制台的 `触发器`选项卡,下方点击 `添加自定义域`。
- - 填入你已转入 CF 域名解析服务的次级域名,例如:`vless.google.com`后 点击`添加自定义域`,等待证书生效即可。
+ - 填入你已转入 CF 域名解析服务的次级域名,例如:`trojan.google.com`后 点击`添加自定义域`,等待证书生效即可。
+
+
## Pages 上传 部署方法
+
+
+「 Pages 上传文件部署文字教程 」
+
1. 部署 CF Pages:
- 下载 [main.zip](https://github.com/cmliu/epeius/archive/refs/heads/main.zip) 文件,并点上 Star !!!
- 在 CF Pages 控制台中选择 `上传资产`后,为你的项目取名后点击 `创建项目`,然后上传你下载好的 [main.zip](https://github.com/cmliu/epeius/archive/refs/heads/main.zip) 文件后点击 `部署站点`。
- 部署完成后点击 `继续处理站点` 后,选择 `设置` > `环境变量` > **制作**为生产环境定义变量 > `添加变量`。
变量名称填写**PASSWORD**,值则为你的密码,后点击 `保存`即可。
+ - **重中之重! `设置` > `运行时` > `兼容性标志` > `nodejs_compat`**,后点击 `保存`即可。
- 返回 `部署` 选项卡,在右下角点击 `创建新部署` 后,重新上传 [main.zip](https://github.com/cmliu/epeius/archive/refs/heads/main.zip) 文件后点击 `保存并部署` 即可。
2. 添加优选线路:
@@ -101,12 +112,19 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ
您分配到的域名是 `fuck.cloudns.biz`,则添加自定义域填入 `lizi.fuck.cloudns.biz`即可;
- 按照 CF 的要求将返回你的域名DNS服务商,添加 该自定义域 `lizi`的 CNAME记录 `epeius.pages.dev` 后,点击 `激活域`即可。
+
+
## Pages GitHub 部署方法 [视频教程](https://www.youtube.com/watch?v=0Cd8uTNJj1Q&t=96s)
+
+
+「 Pages GitHub 部署文字教程 」
+
1. 部署 CF Pages:
- 在 Github 上先 Fork 本项目,并点上 Star !!!
- 在 CF Pages 控制台中选择 `连接到 Git`后,选中 `epeius`项目后点击 `开始设置`。
- 在 `设置构建和部署`页面下方,选择 `环境变量(高级)`后并 `添加变量`,
变量名称填写**PASSWORD**,值则为你的密码,后点击 `保存并部署`即可。
+ - **重中之重! `设置` > `运行时` > `兼容性标志` > `nodejs_compat`**,后点击 `保存`即可。
2. 添加优选线路:
- 添加变量 `ADD` 本地静态的优选线路,若不带端口号 TLS默认端口为443,#号后为备注别名,例如:
@@ -136,6 +154,8 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ
您分配到的域名是 `fuck.cloudns.biz`,则添加自定义域填入 `lizi.fuck.cloudns.biz`即可;
- 按照 CF 的要求将返回你的域名DNS服务商,添加 该自定义域 `lizi`的 CNAME记录 `epeius.pages.dev` 后,点击 `激活域`即可。
+
+
## 变量说明
| 变量名 | 示例 | 备注 |
|--------|---------|-----|
@@ -156,16 +176,12 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ
| RPROXYIP | `false` | 设为 true 即可强制获取订阅器分配的ProxyIP(需订阅器支持)|
| URL302 | `https://t.me/CMLiussss` | 主页302跳转(支持多url, url之间使用`,`或`换行`作间隔, 小白别用) |
| URL | `https://blog.cmliussss.com` | 主页反代伪装(支持多url, url之间使用`,`或`换行`作间隔, 乱设容易触发反诈) |
-| CFEMAIL | `admin@gmail.com` | CF账户邮箱(与`CFKEY`都填上后, 订阅信息将显示请求使用量, 小白别用) |
-| CFKEY | `c6a944b5c956b6c18c2352880952bced8b85e` | CF账户Global API Key(与`CFEMAIL`都填上后, 订阅信息将显示请求使用量, 小白别用) |
| CFPORTS | `2053`,`2096`,`8443` | CF账户标准端口列表 |
**注意: 填入`SOCKS5`后将不再启用`PROXYIP`!请二选一使用!!!**
**注意: 填入`SUB`后将不再启用`ADD*`类变量生成的订阅内容!请二选一使用!!!**
-**注意: 同时填入`CFEMAIL`和`CFKEY`才会启用显示请求使用量,但是不推荐使用!没必要给一个Worker项目这么高的权限!后果自负!!!**
-
## 实用小技巧
**该项目部署的订阅可通过添加`sub`键值快速更换优选订阅生成器!**
diff --git a/_worker.js b/_worker.js
index d582d7ab..a48793f2 100644
--- a/_worker.js
+++ b/_worker.js
@@ -1,5 +1,6 @@
// _worker.src.js
import { connect } from "cloudflare:sockets";
+
let password = '';
let proxyIP = '';
// The user name and password do not contain special characters
@@ -50,7 +51,1250 @@ if (!isValidSHA224(sha224Password)) {
throw new Error('sha224Password is not valid');
}
*/
-const _0x2751a8=_0x1cb6;function _0x8aa5(){const _0x31c850=['/sub?target=singbox&url=','invalid\x20header\x20format\x20(missing\x20CR\x20LF)','ADDCSV(IPTest测速csv文件\x20限速\x20','block','match',';\x20filename*=utf-8\x27\x27','PROXYIP','?singbox\x0a\x0a','\x0aASN:\x20','join','filter','readable','Error\x20fetching\x20content:\x20','MD5','获取地址时出错:','split','sent\x20socks\x20request','pipeTo','CSV文件缺少必需的字段','&parse_mode=HTML&text=','text/html,application/xhtml+xml,application/xml;','function','webSocketServer\x20error','\x20配置信息\x0a---------------------------------------------------------------\x0aHOST:\x20','floor','&insert=false&config=','SUBCONFIG','/?ed=2560','请设置你的PASSWORD变量,或尝试重试部署,检查变量是否生效?','then','&emoji=true&list=false&xudp=false&udp=false&tfo=false&expand=true&scv=true&fdn=false','获取CSV地址时出错:','start','SHA224','slice','webSocket\x20connection\x20is\x20not\x20open','sni=','188.114.96.0/21','surge','set','connected\x20to\x20','digest','entries','?security=tls&sni=','\x0a---------------------------------------------------------------\x0a################################################################\x0a','oKeyPad','','prototype','#!MANAGED-CONFIG\x20','releaseLock','sub','SUBNAME','SOCKS5%EF%BC%88%E7%99%BD%E5%90%8D%E5%8D%95%EF%BC%89%3A%20','\x0a\x20\x20','Q0YtV29ya2Vycy1lcGVpdXMvY21saXU=','reverse','104.24.0.0/14','values','/sub?target=clash&url=','\x0a---------------------------------------------------------------\x0a################################################################\x0aclash-meta\x0a---------------------------------------------------------------\x0a','https://api.telegram.org/bot','some','readableWebSocketStream\x20pipeTo\x20error','\x0a入口:\x20','http://ip-api.com/json/','setUint32','true','remoteSocketToWS\x20error:','hmac',',\x20sni:\x20','TGID','141.101.64.0/19','RPROXYIP','Kg==','443','Host','Mozilla/5.0\x20Chrome/90.0.4430.72','&proxyip=','trim','send',',\x20port:\x20','readyState','replace','exports','Buffer','ceil','56018HQUxvM','URL302','pop','country','http://','padStart','dHJvamFu','read','&allowInsecure=1&type=','X-New-URL','YWxsIGlu','please\x20provide\x20username/password','SUBAPI','/sendMessage?chat_id=','is224','\x0a################################################################\x0aSubscribe\x20/\x20sub\x20订阅地址,\x20支持\x20Base64、clash-meta、sing-box\x20订阅格式\x0a---------------------------------------------------------------\x0a快速自适应订阅地址:\x0ahttps://','object','%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F','hex','buffer','dGVsZWdyYW0g5Lqk5rWB576kIOaKgOacr+Wkp+S9rH7lnKjnur/lj5HniYwhCmh0dHBzOi8vdC5tZS9DTUxpdXNzc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmdpdGh1YiDpobnnm67lnLDlnYAgU3RhciFTdGFyIVN0YXIhISEKaHR0cHM6Ly9naXRodWIuY29tL2NtbGl1L2VwZWl1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw==','upload=','\x22,\x20tfo=false,\x20udp-relay=false','104.16.0.0/13','SUB','arrayBuffer',',\x20ws-opts:\x20{path:\x20\x22',',\x20type:\x20','from','hashed','now','log','.workers.dev','Upgrade','addEventListener','Error\x20fetching\x20content:','hash','CF-Connecting-IP','190.93.240.0/21','status','JS_SHA256_NO_BUFFER_FROM','?lang=zh-CN','encode','invild\x20\x20addressType\x20is\x20','5HTXCFY','SOCKS5','string','User-Agent','text','JmVwZWl1cz1jbWxpdSZwcm94eWlwPQ==','write','crypto','proxyip=true','data','createHash',';\x20download=','CFCDN(访问方式):\x20Socks5\x0a\x20\x20','unsupported\x20command,\x20only\x20TCP\x20(CONNECT)\x20is\x20allowed','inner','retry\x20tcpSocket\x20closed\x20error','\x0a域名:\x20','safeCloseWebSocket\x20error','signal','-\x20{name:\x20','toLowerCase','\x0aSUBAPI(订阅转换后端):\x20','2096','fulfilled','flatMap','test','indexOf','undefined','UA:\x20','utf8','://','\x0aIP:\x20','getUint16','error','abort','finalize','\x22,\x20headers:\x20{Host:\x20','invalid\x20data','\x0a城市:\x20','toUpperCase','concat','includes','\x20已启用临时域名中转服务,请尽快绑定自定义域!','proxyip.','false','create','3905760HKUqlF','retry','proxyip','substring','TGTOKEN','?sub\x0a\x0aBase64订阅地址:\x0ahttps://','text/plain;charset=utf-8','getWriter','call','.xyz','find','}}}','remoteSocket.readable\x20is\x20closed,\x20hasIncomingData:\x20','fail\x20to\x20auth\x20socks\x20server','JS_SHA256_NO_ARRAY_BUFFER','node','https','\x0a国家:\x20','searchParams','CFPORTS','amd','Invalid\x20SOCKS\x20address\x20format','http','Surge订阅地址:\x0ahttps://','chromeBugWorkAround','value','\x0a---------------------------------------------------------------\x0a################################################################\x0av2ray\x0a---------------------------------------------------------------\x0a','stringify','socks\x20server\x20version\x20error:\x20','random','finalized','statusText','\x0aPASSWORD:\x20','CFCDN(访问方式):\x20无法访问,\x20需要您设置\x20proxyIP/PROXYIP\x20!!!\x0a','subconverter','ADDCSV','2083',';\x20total=','json','21SHFmWO','getTime','fail\x20to\x20open\x20socks\x20connection','first','bytes','gzip,\x20deflate,\x20br','UFJPWFlJUC50cDEuZnh4ay5kZWR5bi5pbw==','\x0aUA:\x20','decode','hBytes','不用怀疑!你PASSWORD就是错的!!!','\x20expected:\x205','attachment;\x20filename=','sharedMemory','byteLength','getReader','hostname','1302236LeEyTt','search','b64','ADD','.tp','&path=',';\x20expire=','#CF随机节点','103.21.244.0/23','URL','CF-Workers-SUB','127.0.0.1:1234#CFnat','?base64\x0a\x0aclash订阅地址:\x0ahttps://','setHours','?b64\x0ahttps://','map','\x0ahttps://','416260VDJKlU','invalid\x20SOCKS5\x20request\x20data','?surge','push','application/json','charCodeAt','array','CFCDN(访问方式):\x20ProxyIP\x0a\x20\x20','allSettled','redirect','/sub?target=surge&ver=4&url=','?sb\x0ahttps://',',\x20alpn:\x20[h3],\x20skip-cert-verify:\x20true,\x20network:\x20','blocks','remoteSocket.readable\x20abort','isArray','finally','3048208jSwZFD','\x0a组织:\x20','charAt','https://','/proxyip=','isView','JS_SHA256_NO_COMMON_JS','has','2087','headers','9pFjmfU','catch','invalid\x20password','/sub?host=','reject','&host=','protocol','org','address\x20is\x20empty,\x20addressType\x20is\x20','lastByteIndex','sent\x20socks\x20greeting','readableWebSocketStream\x20is\x20aborted','8443','sha256','message','ADDAPI(TLS优选域名&IP\x20的\x20API):\x20\x0a\x20\x20','get','input\x20is\x20invalid\x20type','socks\x20server\x20needs\x20auth','/socks5=','length','172.64.0.0/14','workers.dev','ADDAPI','singbox','sha224','[object\x20Array]','toString','363342cTTrNx','648234oNALcq','SHA224PASS','city','GO2SOCKS5','\x0aSUBCONFIG(订阅转换配置文件):\x20','subtle','#获取订阅\x20','PASSWORD','close','\x0aSHA224:\x20','update','clash','pathname','getUint8','writable','constructor','enqueue'];_0x8aa5=function(){return _0x31c850;};return _0x8aa5();}(function(_0x5a8299,_0xe4568b){const _0x44f32a=_0x1cb6,_0x4c3ff7=_0x5a8299();while(!![]){try{const _0x499d01=-parseInt(_0x44f32a(0x116))/0x1+parseInt(_0x44f32a(0x1b5))/0x2+parseInt(_0x44f32a(0x14d))/0x3+-parseInt(_0x44f32a(0x105))/0x4*(-parseInt(_0x44f32a(0x1e1))/0x5)+-parseInt(_0x44f32a(0x14e))/0x6*(-parseInt(_0x44f32a(0xf4))/0x7)+-parseInt(_0x44f32a(0x127))/0x8*(-parseInt(_0x44f32a(0x131))/0x9)+-parseInt(_0x44f32a(0xcd))/0xa;if(_0x499d01===_0xe4568b)break;else _0x4c3ff7['push'](_0x4c3ff7['shift']());}catch(_0x4d79f2){_0x4c3ff7['push'](_0x4c3ff7['shift']());}}}(_0x8aa5,0x5b0fd));export default{async 'fetch'(_0x1e6aae,_0x29ffb8,_0x92cacc){const _0x144f4f=_0x1cb6;try{const _0x4fa536=_0x1e6aae[_0x144f4f(0x130)]['get'](_0x144f4f(0x1e4))||'null',_0x2c0489=_0x4fa536[_0x144f4f(0xb3)]();password=_0x29ffb8[_0x144f4f(0x155)]||password;if(!password)return new Response(_0x144f4f(0x17b),{'status':0x194,'headers':{'Content-Type':_0x144f4f(0xd3)}});sha224Password=_0x29ffb8[_0x144f4f(0x180)]||_0x29ffb8[_0x144f4f(0x14f)]||sha256[_0x144f4f(0x14a)](password);const _0x4dcdb0=new Date();_0x4dcdb0['setHours'](0x0,0x0,0x0,0x0);const _0x1ffe14=Math[_0x144f4f(0x1b4)](_0x4dcdb0[_0x144f4f(0xf5)]()/0x3e8),_0xf232cd=await MD5MD5(''+password+_0x1ffe14);fakeUserID=_0xf232cd['slice'](0x0,0x8)+'-'+_0xf232cd[_0x144f4f(0x181)](0x8,0xc)+'-'+_0xf232cd[_0x144f4f(0x181)](0xc,0x10)+'-'+_0xf232cd[_0x144f4f(0x181)](0x10,0x14)+'-'+_0xf232cd[_0x144f4f(0x181)](0x14),fakeHostName=_0xf232cd[_0x144f4f(0x181)](0x6,0x9)+'.'+_0xf232cd[_0x144f4f(0x181)](0xd,0x13),proxyIP=_0x29ffb8[_0x144f4f(0x165)]||proxyIP,proxyIPs=await ADD(proxyIP),proxyIP=proxyIPs[Math[_0x144f4f(0x177)](Math[_0x144f4f(0xea)]()*proxyIPs[_0x144f4f(0x145)])],socks5Address=_0x29ffb8[_0x144f4f(0x1e2)]||socks5Address,socks5s=await ADD(socks5Address),socks5Address=socks5s[Math[_0x144f4f(0x177)](Math[_0x144f4f(0xea)]()*socks5s[_0x144f4f(0x145)])],socks5Address=socks5Address[_0x144f4f(0x16e)]('//')[0x1]||socks5Address;if(_0x29ffb8[_0x144f4f(0xe0)])httpsPorts=await ADD(_0x29ffb8['CFPORTS']);sub=_0x29ffb8[_0x144f4f(0x1cd)]||sub,subconverter=_0x29ffb8[_0x144f4f(0x1c1)]||subconverter;subconverter['includes'](_0x144f4f(0x1b9))?(subconverter=subconverter[_0x144f4f(0x16e)]('//')[0x1],subProtocol=_0x144f4f(0xe3)):subconverter=subconverter[_0x144f4f(0x16e)]('//')[0x1]||subconverter;subconfig=_0x29ffb8[_0x144f4f(0x179)]||subconfig;if(socks5Address)try{parsedSocks5Address=socks5AddressParser(socks5Address),RproxyIP=_0x29ffb8[_0x144f4f(0x1a7)]||'false',enableSocks=!![];}catch(_0x55ad8b){let _0x1fb7bc=_0x55ad8b;console[_0x144f4f(0x1d4)](_0x1fb7bc[_0x144f4f(0x14c)]()),RproxyIP=_0x29ffb8['RPROXYIP']||!proxyIP?_0x144f4f(0x1a1):_0x144f4f(0xcb),enableSocks=![];}else RproxyIP=_0x29ffb8['RPROXYIP']||!proxyIP?_0x144f4f(0x1a1):_0x144f4f(0xcb);if(_0x29ffb8[_0x144f4f(0x108)])addresses=await ADD(_0x29ffb8[_0x144f4f(0x108)]);if(_0x29ffb8[_0x144f4f(0x148)])addressesapi=await ADD(_0x29ffb8[_0x144f4f(0x148)]);if(_0x29ffb8[_0x144f4f(0xf0)])addressescsv=await ADD(_0x29ffb8[_0x144f4f(0xf0)]);DLS=_0x29ffb8['DLS']||DLS,BotToken=_0x29ffb8[_0x144f4f(0xd1)]||BotToken,ChatID=_0x29ffb8[_0x144f4f(0x1a5)]||ChatID;if(_0x29ffb8[_0x144f4f(0x151)])go2Socks5s=await ADD(_0x29ffb8[_0x144f4f(0x151)]);const _0x5b9c94=_0x1e6aae[_0x144f4f(0x130)][_0x144f4f(0x141)](_0x144f4f(0x1d6)),_0x7b9ba=new URL(_0x1e6aae['url']);if(_0x7b9ba[_0x144f4f(0xdf)]['has'](_0x144f4f(0x191))&&_0x7b9ba[_0x144f4f(0xdf)]['get'](_0x144f4f(0x191))!=='')sub=_0x7b9ba[_0x144f4f(0xdf)]['get'](_0x144f4f(0x191));FileName=_0x29ffb8[_0x144f4f(0x192)]||FileName;if(!_0x5b9c94||_0x5b9c94!=='websocket')switch(_0x7b9ba[_0x144f4f(0x15a)]){case'/':if(_0x29ffb8[_0x144f4f(0x1b6)])return Response[_0x144f4f(0x11f)](_0x29ffb8[_0x144f4f(0x1b6)],0x12e);else{if(_0x29ffb8['URL'])return await proxyURL(_0x29ffb8[_0x144f4f(0x10e)],_0x7b9ba);else return new Response(JSON[_0x144f4f(0xe8)](_0x1e6aae['cf'],null,0x4),{'status':0xc8,'headers':{'content-type':_0x144f4f(0x11a)}});}case'/'+fakeUserID:const _0x50615a=await getTrojanConfig(password,_0x1e6aae[_0x144f4f(0x130)]['get'](_0x144f4f(0x1aa)),sub,_0x144f4f(0x10f),RproxyIP,_0x7b9ba);return new Response(''+_0x50615a,{'status':0xc8});case'/'+password:await sendMessage(_0x144f4f(0x154)+FileName,_0x1e6aae['headers']['get'](_0x144f4f(0x1da)),_0x144f4f(0xbb)+_0x4fa536+_0x144f4f(0xaf)+_0x7b9ba[_0x144f4f(0x104)]+_0x144f4f(0x19e)+(_0x7b9ba['pathname']+_0x7b9ba[_0x144f4f(0x106)])+_0x144f4f(0x18d));const _0x2caefd=await getTrojanConfig(password,_0x1e6aae[_0x144f4f(0x130)][_0x144f4f(0x141)]('Host'),sub,_0x4fa536,RproxyIP,_0x7b9ba),_0x1699bc=Date[_0x144f4f(0x1d3)](),_0x2c710b=new Date(_0x1699bc);_0x2c710b[_0x144f4f(0x112)](0x0,0x0,0x0,0x0);const _0x3a4d64=Math[_0x144f4f(0x177)]((_0x1699bc-_0x2c710b['getTime']())/0x5265c00*0x18*0x10000000000/0x2);let _0x417ddc=_0x3a4d64,_0x4f1ea1=_0x3a4d64,_0x1dc1a4=0x18*0x10000000000;return _0x2c0489&&(_0x2c0489[_0x144f4f(0xc8)]('mozilla')||_0x2c0489[_0x144f4f(0xc8)](_0x144f4f(0xef)))?new Response(''+_0x2caefd,{'status':0xc8,'headers':{'Content-Type':'text/plain;charset=utf-8','Profile-Update-Interval':'6','Subscription-Userinfo':_0x144f4f(0x1ca)+_0x417ddc+_0x144f4f(0xaa)+_0x4f1ea1+';\x20total='+_0x1dc1a4+_0x144f4f(0x10b)+expire}}):new Response(''+_0x2caefd,{'status':0xc8,'headers':{'Content-Disposition':_0x144f4f(0x100)+FileName+_0x144f4f(0x164)+encodeURIComponent(FileName),'Content-Type':_0x144f4f(0xd3),'Profile-Update-Interval':'6','Subscription-Userinfo':'upload='+_0x417ddc+_0x144f4f(0xaa)+_0x4f1ea1+_0x144f4f(0xf2)+_0x1dc1a4+_0x144f4f(0x10b)+expire}});default:if(_0x29ffb8[_0x144f4f(0x1b6)])return Response[_0x144f4f(0x11f)](_0x29ffb8[_0x144f4f(0x1b6)],0x12e);else{if(_0x29ffb8[_0x144f4f(0x10e)])return await proxyURL(_0x29ffb8['URL'],_0x7b9ba);else return new Response(_0x144f4f(0xfe),{'status':0x194});}}else{proxyIP=_0x7b9ba[_0x144f4f(0xdf)]['get'](_0x144f4f(0xcf))||proxyIP;if(new RegExp('/proxyip=','i')['test'](_0x7b9ba[_0x144f4f(0x15a)]))proxyIP=_0x7b9ba[_0x144f4f(0x15a)]['toLowerCase']()[_0x144f4f(0x16e)](_0x144f4f(0x12b))[0x1];else{if(new RegExp('/proxyip.','i')[_0x144f4f(0xb8)](_0x7b9ba[_0x144f4f(0x15a)]))proxyIP=_0x144f4f(0xca)+_0x7b9ba[_0x144f4f(0x15a)][_0x144f4f(0xb3)]()[_0x144f4f(0x16e)]('/proxyip.')[0x1];}socks5Address=_0x7b9ba['searchParams']['get']('socks5')||socks5Address;if(new RegExp(_0x144f4f(0x144),'i')[_0x144f4f(0xb8)](_0x7b9ba[_0x144f4f(0x15a)]))socks5Address=_0x7b9ba[_0x144f4f(0x15a)]['split']('5=')[0x1];else{if(new RegExp('/socks://','i')[_0x144f4f(0xb8)](_0x7b9ba['pathname'])||new RegExp('/socks5://','i')[_0x144f4f(0xb8)](_0x7b9ba[_0x144f4f(0x15a)])){socks5Address=_0x7b9ba[_0x144f4f(0x15a)][_0x144f4f(0x16e)](_0x144f4f(0xbd))[0x1][_0x144f4f(0x16e)]('#')[0x0];if(socks5Address[_0x144f4f(0xc8)]('@')){let _0x2fd4b1=socks5Address[_0x144f4f(0x16e)]('@')[0x0];const _0x3565ef=/^(?:[A-Z0-9+/]{4})*(?:[A-Z0-9+/]{2}==|[A-Z0-9+/]{3}=)?$/i;if(_0x3565ef['test'](_0x2fd4b1)&&!_0x2fd4b1['includes'](':'))_0x2fd4b1=atob(_0x2fd4b1);socks5Address=_0x2fd4b1+'@'+socks5Address[_0x144f4f(0x16e)]('@')[0x1];}}}if(socks5Address)try{parsedSocks5Address=socks5AddressParser(socks5Address),enableSocks=!![];}catch(_0x301b4b){let _0x466bb8=_0x301b4b;console[_0x144f4f(0x1d4)](_0x466bb8['toString']()),enableSocks=![];}else enableSocks=![];return await trojanOverWSHandler(_0x1e6aae);}}catch(_0xf14a59){let _0x53b63f=_0xf14a59;return new Response(_0x53b63f[_0x144f4f(0x14c)]());}}};async function trojanOverWSHandler(_0x593603){const _0x251b28=_0x1cb6,_0x287c3f=new WebSocketPair(),[_0x57f6ad,_0xb8790f]=Object[_0x251b28(0x198)](_0x287c3f);_0xb8790f['accept']();let _0x1bd4e2='',_0x25176d='';const _0x4ac4ba=(_0x19b387,_0x1ecc06)=>{const _0x119828=_0x251b28;console[_0x119828(0x1d4)]('['+_0x1bd4e2+':'+_0x25176d+']\x20'+_0x19b387,_0x1ecc06||'');},_0x184bcc=_0x593603[_0x251b28(0x130)][_0x251b28(0x141)]('sec-websocket-protocol')||'',_0x1da8a4=makeReadableWebSocketStream(_0xb8790f,_0x184bcc,_0x4ac4ba);let _0x29cf3a={'value':null},_0x15f1dc=null;return _0x1da8a4[_0x251b28(0x170)](new WritableStream({async 'write'(_0x726e7f,_0x13007e){const _0xb8dadb=_0x251b28;if(_0x15f1dc)return _0x15f1dc(_0x726e7f);if(_0x29cf3a['value']){const _0x530106=_0x29cf3a[_0xb8dadb(0xe6)][_0xb8dadb(0x15c)][_0xb8dadb(0xd4)]();await _0x530106[_0xb8dadb(0x1e7)](_0x726e7f),_0x530106[_0xb8dadb(0x190)]();return;}const {hasError:_0x1294ca,message:_0x58b586,portRemote:portRemote=0x1bb,addressRemote:addressRemote='',rawClientData:_0x8f215f,addressType:_0x1bfa0d}=await parseTrojanHeader(_0x726e7f);_0x1bd4e2=addressRemote,_0x25176d=portRemote+'--'+Math['random']()+'\x20tcp';if(_0x1294ca){throw new Error(_0x58b586);return;}handleTCPOutBound(_0x29cf3a,addressRemote,portRemote,_0x8f215f,_0xb8790f,_0x4ac4ba,_0x1bfa0d);},'close'(){_0x4ac4ba('readableWebSocketStream\x20is\x20closed');},'abort'(_0x5c6a0e){const _0x216f14=_0x251b28;_0x4ac4ba(_0x216f14(0x13c),JSON['stringify'](_0x5c6a0e));}}))['catch'](_0x1ce8d3=>{const _0x1e1eb0=_0x251b28;_0x4ac4ba(_0x1e1eb0(0x19d),_0x1ce8d3);}),new Response(null,{'status':0x65,'webSocket':_0x57f6ad});}async function parseTrojanHeader(_0x2ea652){const _0x43c8c4=_0x1cb6;if(_0x2ea652[_0x43c8c4(0x102)]<0x38)return{'hasError':!![],'message':_0x43c8c4(0xc4)};let _0x944970=0x38;if(new Uint8Array(_0x2ea652['slice'](0x38,0x39))[0x0]!==0xd||new Uint8Array(_0x2ea652[_0x43c8c4(0x181)](0x39,0x3a))[0x0]!==0xa)return{'hasError':!![],'message':_0x43c8c4(0x160)};const _0x24be83=new TextDecoder()['decode'](_0x2ea652['slice'](0x0,_0x944970));if(_0x24be83!==sha224Password)return{'hasError':!![],'message':_0x43c8c4(0x133)};const _0x56e045=_0x2ea652['slice'](_0x944970+0x2);if(_0x56e045[_0x43c8c4(0x102)]<0x6)return{'hasError':!![],'message':_0x43c8c4(0x117)};const _0x5e5aba=new DataView(_0x56e045),_0x893ff1=_0x5e5aba[_0x43c8c4(0x15b)](0x0);if(_0x893ff1!==0x1)return{'hasError':!![],'message':_0x43c8c4(0xac)};const _0x4490e9=_0x5e5aba['getUint8'](0x1);let _0x576c4a=0x0,_0x1138ea=0x2,_0x34f400='';switch(_0x4490e9){case 0x1:_0x576c4a=0x4,_0x34f400=new Uint8Array(_0x56e045['slice'](_0x1138ea,_0x1138ea+_0x576c4a))[_0x43c8c4(0x168)]('.');break;case 0x3:_0x576c4a=new Uint8Array(_0x56e045['slice'](_0x1138ea,_0x1138ea+0x1))[0x0],_0x1138ea+=0x1,_0x34f400=new TextDecoder()[_0x43c8c4(0xfc)](_0x56e045[_0x43c8c4(0x181)](_0x1138ea,_0x1138ea+_0x576c4a));break;case 0x4:_0x576c4a=0x10;const _0x5a9421=new DataView(_0x56e045['slice'](_0x1138ea,_0x1138ea+_0x576c4a)),_0x510f32=[];for(let _0xbb47ab=0x0;_0xbb47ab<0x8;_0xbb47ab++){_0x510f32['push'](_0x5a9421[_0x43c8c4(0xbf)](_0xbb47ab*0x2)[_0x43c8c4(0x14c)](0x10));}_0x34f400=_0x510f32[_0x43c8c4(0x168)](':');break;default:return{'hasError':!![],'message':'invalid\x20addressType\x20is\x20'+_0x4490e9};}if(!_0x34f400)return{'hasError':!![],'message':_0x43c8c4(0x139)+_0x4490e9};const _0xee385e=_0x1138ea+_0x576c4a,_0x52fb4d=_0x56e045[_0x43c8c4(0x181)](_0xee385e,_0xee385e+0x2),_0x2cc2bc=new DataView(_0x52fb4d)[_0x43c8c4(0xbf)](0x0);return{'hasError':![],'addressRemote':_0x34f400,'portRemote':_0x2cc2bc,'rawClientData':_0x56e045[_0x43c8c4(0x181)](_0xee385e+0x4),'addressType':_0x4490e9};}async function handleTCPOutBound(_0xfdbdd4,_0x36e877,_0x2c5318,_0x2cec60,_0x5ea68b,_0x29079f,_0x3f1af8){const _0x179eab=_0x1cb6;async function _0x1d10ae(_0x5d9674){const _0x2d38f5=_0x1cb6;if(go2Socks5s['includes'](atob(_0x2d38f5(0x1bf)))||go2Socks5s[_0x2d38f5(0xc8)](atob(_0x2d38f5(0x1a8))))return!![];return go2Socks5s[_0x2d38f5(0x19c)](_0x93e999=>{const _0x51d2f8=_0x2d38f5;let _0xcc7ac2=_0x93e999[_0x51d2f8(0x1b1)](/\*/g,'.*'),_0x253839=new RegExp('^'+_0xcc7ac2+'$','i');return _0x253839['test'](_0x5d9674);});}async function _0x38c36f(_0x384e4e,_0x1350aa,_0x1e36e6=![]){const _0x3b18c5=_0x1cb6;_0x29079f(_0x3b18c5(0x187)+_0x384e4e+':'+_0x1350aa);const _0x5da1b4=_0x1e36e6?await socks5Connect(_0x3f1af8,_0x384e4e,_0x1350aa,_0x29079f):connect({'hostname':_0x384e4e,'port':_0x1350aa});_0xfdbdd4[_0x3b18c5(0xe6)]=_0x5da1b4;const _0x24bcc8=_0x5da1b4[_0x3b18c5(0x15c)][_0x3b18c5(0xd4)]();return await _0x24bcc8['write'](_0x2cec60),_0x24bcc8[_0x3b18c5(0x190)](),_0x5da1b4;}async function _0x45bb2f(){const _0x5c043c=_0x1cb6;if(enableSocks)_0x3f4e13=await _0x38c36f(_0x36e877,_0x2c5318,!![]);else{if(!proxyIP||proxyIP=='')proxyIP=atob(_0x5c043c(0xfa));else{if(proxyIP['includes'](']:'))_0x2c5318=proxyIP['split'](']:')[0x1]||_0x2c5318,proxyIP=proxyIP[_0x5c043c(0x16e)](']:')[0x0]||proxyIP;else proxyIP[_0x5c043c(0x16e)](':')[_0x5c043c(0x145)]===0x2&&(_0x2c5318=proxyIP[_0x5c043c(0x16e)](':')[0x1]||_0x2c5318,proxyIP=proxyIP[_0x5c043c(0x16e)](':')[0x0]||proxyIP);}if(proxyIP['includes']('.tp'))_0x2c5318=proxyIP[_0x5c043c(0x16e)](_0x5c043c(0x109))[0x1]['split']('.')[0x0]||_0x2c5318;_0x3f4e13=await _0x38c36f(proxyIP||_0x36e877,_0x2c5318);}_0x3f4e13['closed'][_0x5c043c(0x132)](_0x4f5b7e=>{const _0x1717ed=_0x5c043c;console[_0x1717ed(0x1d4)](_0x1717ed(0xae),_0x4f5b7e);})[_0x5c043c(0x126)](()=>{safeCloseWebSocket(_0x5ea68b);}),remoteSocketToWS(_0x3f4e13,_0x5ea68b,null,_0x29079f);}let _0x282270=![];if(go2Socks5s[_0x179eab(0x145)]>0x0&&enableSocks)_0x282270=await _0x1d10ae(_0x36e877);let _0x3f4e13=await _0x38c36f(_0x36e877,_0x2c5318,_0x282270);remoteSocketToWS(_0x3f4e13,_0x5ea68b,_0x45bb2f,_0x29079f);}function makeReadableWebSocketStream(_0x213066,_0x4fd1a2,_0x151a93){let _0x491d1b=![];const _0x3271fa=new ReadableStream({'start'(_0x52ad32){const _0x2082e3=_0x1cb6;_0x213066[_0x2082e3(0x1d7)](_0x2082e3(0x13f),_0x92d954=>{const _0x352d66=_0x2082e3;if(_0x491d1b)return;const _0x78e10=_0x92d954[_0x352d66(0xa8)];_0x52ad32[_0x352d66(0x15e)](_0x78e10);}),_0x213066[_0x2082e3(0x1d7)](_0x2082e3(0x156),()=>{const _0x28776b=_0x2082e3;safeCloseWebSocket(_0x213066);if(_0x491d1b)return;_0x52ad32[_0x28776b(0x156)]();}),_0x213066['addEventListener'](_0x2082e3(0xc0),_0x218142=>{const _0x3922e7=_0x2082e3;_0x151a93(_0x3922e7(0x175)),_0x52ad32[_0x3922e7(0xc0)](_0x218142);});const {earlyData:_0x528039,error:_0x2fb6f6}=base64ToArrayBuffer(_0x4fd1a2);if(_0x2fb6f6)_0x52ad32[_0x2082e3(0xc0)](_0x2fb6f6);else _0x528039&&_0x52ad32['enqueue'](_0x528039);},'pull'(_0x452aeb){},'cancel'(_0x146fb0){if(_0x491d1b)return;_0x151a93('readableStream\x20was\x20canceled,\x20due\x20to\x20'+_0x146fb0),_0x491d1b=!![],safeCloseWebSocket(_0x213066);}});return _0x3271fa;}async function remoteSocketToWS(_0x21ff25,_0x5a4958,_0x4c7f5a,_0x35c72b){const _0x2f3780=_0x1cb6;let _0x14f9f8=![];await _0x21ff25[_0x2f3780(0x16a)][_0x2f3780(0x170)](new WritableStream({'start'(){},async 'write'(_0x1d47bd,_0x3b3ac5){const _0x45076d=_0x2f3780;_0x14f9f8=!![],_0x5a4958[_0x45076d(0x1b0)]!==WS_READY_STATE_OPEN&&_0x3b3ac5[_0x45076d(0xc0)](_0x45076d(0x182)),_0x5a4958[_0x45076d(0x1ae)](_0x1d47bd);},'close'(){const _0x550086=_0x2f3780;_0x35c72b(_0x550086(0xd9)+_0x14f9f8);},'abort'(_0x591272){const _0x5a5e27=_0x2f3780;console[_0x5a5e27(0xc0)](_0x5a5e27(0x124),_0x591272);}}))['catch'](_0x16e75a=>{const _0x564a4d=_0x2f3780;console['error'](_0x564a4d(0x1a2),_0x16e75a['stack']||_0x16e75a),safeCloseWebSocket(_0x5a4958);}),_0x14f9f8===![]&&_0x4c7f5a&&(_0x35c72b(_0x2f3780(0xce)),_0x4c7f5a());}function base64ToArrayBuffer(_0x4c6818){const _0x5219ff=_0x1cb6;if(!_0x4c6818)return{'error':null};try{_0x4c6818=_0x4c6818[_0x5219ff(0x1b1)](/-/g,'+')[_0x5219ff(0x1b1)](/_/g,'/');const _0x4cc6e3=atob(_0x4c6818),_0x329a3b=Uint8Array[_0x5219ff(0x1d1)](_0x4cc6e3,_0x4d75b3=>_0x4d75b3[_0x5219ff(0x11b)](0x0));return{'earlyData':_0x329a3b[_0x5219ff(0x1c8)],'error':null};}catch(_0x2f528a){return{'error':_0x2f528a};}}let WS_READY_STATE_OPEN=0x1,WS_READY_STATE_CLOSING=0x2;function safeCloseWebSocket(_0x41fdb1){const _0x1ced68=_0x1cb6;try{(_0x41fdb1[_0x1ced68(0x1b0)]===WS_READY_STATE_OPEN||_0x41fdb1[_0x1ced68(0x1b0)]===WS_READY_STATE_CLOSING)&&_0x41fdb1[_0x1ced68(0x156)]();}catch(_0x387541){console['error'](_0x1ced68(0xb0),_0x387541);}}function revertFakeInfo(_0x1db085,_0x1ef8e4,_0x18055f,_0x1f5888){const _0x370cc7=_0x1cb6;if(_0x1f5888)_0x1db085=atob(_0x1db085);_0x1db085=_0x1db085[_0x370cc7(0x1b1)](new RegExp(fakeUserID,'g'),_0x1ef8e4)[_0x370cc7(0x1b1)](new RegExp(fakeHostName,'g'),_0x18055f);if(_0x1f5888)_0x1db085=btoa(_0x1db085);return _0x1db085;}async function MD5MD5(_0x1a0ade){const _0x558354=_0x1cb6,_0x442e25=new TextEncoder(),_0x155160=await crypto['subtle'][_0x558354(0x188)]('MD5',_0x442e25[_0x558354(0x1df)](_0x1a0ade)),_0xaad89b=Array['from'](new Uint8Array(_0x155160)),_0x51b839=_0xaad89b[_0x558354(0x114)](_0x2fbf02=>_0x2fbf02[_0x558354(0x14c)](0x10)[_0x558354(0x1ba)](0x2,'0'))['join'](''),_0x4617eb=await crypto[_0x558354(0x153)]['digest'](_0x558354(0x16c),_0x442e25[_0x558354(0x1df)](_0x51b839['slice'](0x7,0x1b))),_0x191cad=Array[_0x558354(0x1d1)](new Uint8Array(_0x4617eb)),_0x2f25a0=_0x191cad['map'](_0x5aba67=>_0x5aba67[_0x558354(0x14c)](0x10)['padStart'](0x2,'0'))['join']('');return _0x2f25a0[_0x558354(0xb3)]();}async function ADD(_0xd804e3){const _0x5ab341=_0x1cb6;var _0x3e52dc=_0xd804e3[_0x5ab341(0x1b1)](/[ |"'\r\n]+/g,',')[_0x5ab341(0x1b1)](/,+/g,',');if(_0x3e52dc[_0x5ab341(0x129)](0x0)==',')_0x3e52dc=_0x3e52dc['slice'](0x1);if(_0x3e52dc[_0x5ab341(0x129)](_0x3e52dc[_0x5ab341(0x145)]-0x1)==',')_0x3e52dc=_0x3e52dc[_0x5ab341(0x181)](0x0,_0x3e52dc[_0x5ab341(0x145)]-0x1);const _0x1fad69=_0x3e52dc[_0x5ab341(0x16e)](',');return _0x1fad69;}async function proxyURL(_0x3e1229,_0x4e3c2f){const _0x2afa92=_0x1cb6,_0x248227=await ADD(_0x3e1229),_0x2b7508=_0x248227[Math['floor'](Math[_0x2afa92(0xea)]()*_0x248227[_0x2afa92(0x145)])];let _0x81a996=new URL(_0x2b7508);console[_0x2afa92(0x1d4)](_0x81a996);let _0x51d8ea=_0x81a996[_0x2afa92(0x137)][_0x2afa92(0x181)](0x0,-0x1)||_0x2afa92(0xdd),_0x3bfc52=_0x81a996[_0x2afa92(0x104)],_0x225356=_0x81a996[_0x2afa92(0x15a)],_0x33d6d7=_0x81a996[_0x2afa92(0x106)];_0x225356['charAt'](_0x225356['length']-0x1)=='/'&&(_0x225356=_0x225356[_0x2afa92(0x181)](0x0,-0x1));_0x225356+=_0x4e3c2f[_0x2afa92(0x15a)];let _0x3a7bac=_0x51d8ea+_0x2afa92(0xbd)+_0x3bfc52+_0x225356+_0x33d6d7,_0x35e050=await fetch(_0x3a7bac),_0x380127=new Response(_0x35e050['body'],{'status':_0x35e050['status'],'statusText':_0x35e050['statusText'],'headers':_0x35e050[_0x2afa92(0x130)]});return _0x380127['headers'][_0x2afa92(0x186)](_0x2afa92(0x1be),_0x3a7bac),_0x380127;}function 配置信息(_0x2a1aba,_0x1dbc00){const _0x3c2f0c=_0x1cb6,_0x3eacbb=_0x3c2f0c(0x1bb),_0x4b23dc=atob(_0x3eacbb),_0x34d1da=FileName;let _0x38ab52=_0x1dbc00,_0x4120e1=0x1bb;const _0x4ac0c2='ws',_0x3de99d=_0x1dbc00,_0x2a6efc=_0x3c2f0c(0x17a);let _0xedfe59=['tls',!![]];const _0x3f85a0=_0x1dbc00,_0x30c885='randomized',_0x121f31=_0x4b23dc+'://'+encodeURIComponent(_0x2a1aba)+'@'+_0x38ab52+':'+_0x4120e1+'?security='+_0xedfe59[0x0]+'&sni='+_0x3f85a0+'&alpn=h3&fp='+_0x30c885+_0x3c2f0c(0x1bd)+_0x4ac0c2+_0x3c2f0c(0x136)+_0x3de99d+_0x3c2f0c(0x10a)+encodeURIComponent(_0x2a6efc)+'#'+encodeURIComponent(_0x34d1da),_0x57c851=_0x3c2f0c(0xb2)+_0x34d1da+',\x20server:\x20'+_0x38ab52+_0x3c2f0c(0x1af)+_0x4120e1+',\x20udp:\x20false,\x20client-fingerprint:\x20'+_0x30c885+_0x3c2f0c(0x1d0)+_0x4b23dc+',\x20password:\x20'+_0x2a1aba+_0x3c2f0c(0x1a4)+_0x3f85a0+_0x3c2f0c(0x122)+_0x4ac0c2+_0x3c2f0c(0x1cf)+_0x2a6efc+_0x3c2f0c(0xc3)+_0x3de99d+_0x3c2f0c(0xd8);return[_0x121f31,_0x57c851];}let subParams=[_0x2751a8(0x191),'base64',_0x2751a8(0x107),'clash','singbox','sb',_0x2751a8(0x185)];async function getTrojanConfig(_0x173b9c,_0xd9010c,_0x503414,_0x433edd,_0x5ad680,_0x975a51){const _0x6bc588=_0x2751a8;if(_0x503414){const _0x5da55b=_0x503414[_0x6bc588(0x163)](/^(?:https?:\/\/)?([^\/]+)/);_0x5da55b&&(_0x503414=_0x5da55b[0x1]);}else{if(addresses[_0x6bc588(0x145)]+addressesapi[_0x6bc588(0x145)]+addressescsv[_0x6bc588(0x145)]==0x0){let _0x149c40=[_0x6bc588(0x10d),_0x6bc588(0x1cc),_0x6bc588(0x197),_0x6bc588(0x146),_0x6bc588(0x10d),'104.16.0.0/14','104.24.0.0/15',_0x6bc588(0x1a6),'172.64.0.0/14',_0x6bc588(0x184),_0x6bc588(0x1db)];function _0x11801f(_0x543ea8){const _0x56d96e=_0x6bc588,[_0x2643e1,_0x1f332a]=_0x543ea8[_0x56d96e(0x16e)]('/'),_0x2f03e9=_0x2643e1[_0x56d96e(0x16e)]('.')['map'](Number),_0x51899a=0x20-parseInt(_0x1f332a,0xa),_0x2c4472=Math['pow'](0x2,_0x51899a)-0x1,_0x191cb4=Math['floor'](Math[_0x56d96e(0xea)]()*_0x2c4472),_0xe9dfe2=_0x2f03e9['map']((_0x4d5501,_0x4e56a1)=>{if(_0x4e56a1<0x2)return _0x4d5501;if(_0x4e56a1===0x2)return(_0x4d5501&0xff<<_0x51899a-0x8)+(_0x191cb4>>0x8&0xff);return(_0x4d5501&0xff<<_0x51899a)+(_0x191cb4&0xff);});return _0xe9dfe2['join']('.');}addresses=addresses[_0x6bc588(0xc7)](_0x6bc588(0x110)),addresses=addresses[_0x6bc588(0xc7)](_0x149c40[_0x6bc588(0x114)](_0x28a0f5=>_0x11801f(_0x28a0f5)+_0x6bc588(0x10c)));}}const _0x41eaec=_0x433edd['toLowerCase'](),_0x2f9f46=配置信息(_0x173b9c,_0xd9010c),_0x1b2b80=_0x2f9f46[0x0],_0x4e64c7=_0x2f9f46[0x1];let _0x5960a0='';if(_0xd9010c[_0x6bc588(0xc8)](_0x6bc588(0x1d5))){if(proxyhostsURL&&(!proxyhosts||proxyhosts['length']==0x0))try{const _0x515645=await fetch(proxyhostsURL);if(!_0x515645['ok']){console[_0x6bc588(0xc0)]('获取地址时出错:',_0x515645['status'],_0x515645[_0x6bc588(0xec)]);return;}const _0x49b75f=await _0x515645[_0x6bc588(0x1e5)](),_0x463519=_0x49b75f[_0x6bc588(0x16e)]('\x0a'),_0x5d4518=_0x463519['filter'](_0x15bbfa=>_0x15bbfa[_0x6bc588(0x1ad)]()!=='');proxyhosts=proxyhosts['concat'](_0x5d4518);}catch(_0xe2fc09){}if(proxyhosts['length']!=0x0)_0x5960a0=proxyhosts[Math['floor'](Math['random']()*proxyhosts['length'])]+'/';}if(_0x41eaec[_0x6bc588(0xc8)]('mozilla')&&!subParams['some'](_0x23e8ce=>_0x975a51[_0x6bc588(0xdf)][_0x6bc588(0x12e)](_0x23e8ce))){let _0x50ab69=_0x6bc588(0xe4)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x118);if(_0xd9010c[_0x6bc588(0xc8)](_0x6bc588(0x1d5)))_0x50ab69='Surge订阅必须绑定自定义域';const _0x4f6fba=socks5s['map'](_0xfdca5=>{const _0x3a8450=_0x6bc588;if(_0xfdca5['includes']('@'))return _0xfdca5[_0x3a8450(0x16e)]('@')[0x1];else{if(_0xfdca5[_0x3a8450(0xc8)]('//'))return _0xfdca5[_0x3a8450(0x16e)]('//')[0x1];else return _0xfdca5;}});let _0x183623='';if(go2Socks5s[_0x6bc588(0x145)]>0x0&&enableSocks){_0x183623=''+decodeURIComponent(_0x6bc588(0x193));if(go2Socks5s[_0x6bc588(0xc8)](atob('YWxsIGlu'))||go2Socks5s[_0x6bc588(0xc8)](atob('Kg==')))_0x183623+=decodeURIComponent(_0x6bc588(0x1c6))+'\x0a';else _0x183623+=_0x6bc588(0x194)+go2Socks5s[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a';}let _0x3cb5e8='';if(!_0x503414||_0x503414==''){if(enableSocks)_0x3cb5e8+='CFCDN(访问方式):\x20Socks5\x0a\x20\x20'+_0x4f6fba[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a'+_0x183623;else{if(proxyIP&&proxyIP!='')_0x3cb5e8+=_0x6bc588(0x11d)+proxyIPs[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a';else _0x3cb5e8+=_0x6bc588(0xee);}_0x3cb5e8+='\x0a您的订阅内容由\x20内置\x20addresses/ADD*\x20参数变量提供\x0a';if(addresses[_0x6bc588(0x145)]>0x0)_0x3cb5e8+='ADD(TLS优选域名&IP):\x20\x0a\x20\x20'+addresses[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a';if(addressesapi[_0x6bc588(0x145)]>0x0)_0x3cb5e8+=_0x6bc588(0x140)+addressesapi[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a';if(addressescsv[_0x6bc588(0x145)]>0x0)_0x3cb5e8+=_0x6bc588(0x161)+DLS+'\x20):\x20\x0a\x20\x20'+addressescsv[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a';}else{if(enableSocks)_0x3cb5e8+=_0x6bc588(0xab)+_0x4f6fba[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a'+_0x183623;else{if(proxyIP&&proxyIP!='')_0x3cb5e8+=_0x6bc588(0x11d)+proxyIPs[_0x6bc588(0x168)](_0x6bc588(0x194))+'\x0a';else{if(_0x5ad680=='true')_0x3cb5e8+='CFCDN(访问方式):\x20自动获取ProxyIP\x0a';else _0x3cb5e8+=_0x6bc588(0xee);}}_0x3cb5e8+='\x0aSUB(优选订阅生成器):\x20'+_0x503414;}return _0x6bc588(0x1c4)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x115)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0xd2)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x113)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x111)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+'?clash\x0a\x0asingbox订阅地址:\x0ahttps://'+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x121)+_0x5960a0+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x166)+_0x50ab69+_0x6bc588(0x18b)+FileName+_0x6bc588(0x176)+_0xd9010c+_0x6bc588(0xed)+_0x173b9c+_0x6bc588(0x157)+sha224Password+'\x0aFAKEPASS:\x20'+fakeUserID+_0x6bc588(0xfb)+_0x433edd+'\x0a\x0a'+_0x3cb5e8+_0x6bc588(0xb4)+subProtocol+_0x6bc588(0xbd)+subconverter+_0x6bc588(0x152)+subconfig+_0x6bc588(0xe7)+_0x1b2b80+_0x6bc588(0x19a)+_0x4e64c7+_0x6bc588(0x18b)+atob(_0x6bc588(0x1c9))+'\x0a';}else{if(typeof fetch!=_0x6bc588(0x174))return'Error:\x20fetch\x20is\x20not\x20available\x20in\x20this\x20environment.';_0xd9010c[_0x6bc588(0xc8)]('.workers.dev')?fakeHostName=fakeHostName+_0x6bc588(0x1d5):fakeHostName=fakeHostName+_0x6bc588(0xd6);let _0x211237=_0x6bc588(0x12a)+_0x503414+_0x6bc588(0x134)+fakeHostName+'&pw='+fakeUserID+'&password='+(fakeUserID+atob(_0x6bc588(0x1e6))+_0x5ad680),_0x4167ef=!![],_0x1502b8=[],_0x4af72f=[];if(!_0x503414||_0x503414==''){if(_0xd9010c[_0x6bc588(0xc8)](_0x6bc588(0x147))){if(proxyhostsURL&&(!proxyhosts||proxyhosts[_0x6bc588(0x145)]==0x0))try{const _0x453ae7=await fetch(proxyhostsURL);if(!_0x453ae7['ok']){console[_0x6bc588(0xc0)](_0x6bc588(0x16d),_0x453ae7[_0x6bc588(0x1dc)],_0x453ae7[_0x6bc588(0xec)]);return;}const _0x5362c1=await _0x453ae7['text'](),_0x297372=_0x5362c1['split']('\x0a'),_0x3e59b1=_0x297372[_0x6bc588(0x169)](_0x43e6d9=>_0x43e6d9[_0x6bc588(0x1ad)]()!=='');proxyhosts=proxyhosts[_0x6bc588(0xc7)](_0x3e59b1);}catch(_0x1d2784){console[_0x6bc588(0xc0)](_0x6bc588(0x16d),_0x1d2784);}proxyhosts=[...new Set(proxyhosts)];}_0x1502b8=await getAddressesapi(addressesapi),_0x4af72f=await getAddressescsv('TRUE'),_0x211237=_0x6bc588(0x12a)+_0xd9010c+'/'+fakeUserID;}if(!_0x41eaec[_0x6bc588(0xc8)](_0x6bc588(0x10f)[_0x6bc588(0xb3)]())){if(_0x41eaec[_0x6bc588(0xc8)]('clash')&&!_0x41eaec[_0x6bc588(0xc8)]('nekobox')||_0x975a51['searchParams'][_0x6bc588(0x12e)](_0x6bc588(0x159)))_0x211237=subProtocol+_0x6bc588(0xbd)+subconverter+_0x6bc588(0x199)+encodeURIComponent(_0x211237)+_0x6bc588(0x178)+encodeURIComponent(subconfig)+'&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true',_0x4167ef=![];else{if(_0x41eaec[_0x6bc588(0xc8)]('sing-box')||_0x41eaec[_0x6bc588(0xc8)](_0x6bc588(0x149))||_0x975a51[_0x6bc588(0xdf)][_0x6bc588(0x12e)](_0x6bc588(0x149))||_0x975a51[_0x6bc588(0xdf)][_0x6bc588(0x12e)]('sb'))_0x211237=subProtocol+_0x6bc588(0xbd)+subconverter+_0x6bc588(0x15f)+encodeURIComponent(_0x211237)+'&insert=false&config='+encodeURIComponent(subconfig)+'&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true',_0x4167ef=![];else(_0x41eaec[_0x6bc588(0xc8)](_0x6bc588(0x185))||_0x975a51['searchParams'][_0x6bc588(0x12e)]('surge'))&&(_0x211237=subProtocol+_0x6bc588(0xbd)+subconverter+_0x6bc588(0x120)+encodeURIComponent(_0x211237)+_0x6bc588(0x178)+encodeURIComponent(subconfig)+_0x6bc588(0x17d),_0x4167ef=![]);}}try{let _0x3c23e9;if((!_0x503414||_0x503414=='')&&_0x4167ef==!![])_0x3c23e9=await subAddresses(fakeHostName,fakeUserID,_0x41eaec,_0x1502b8,_0x4af72f);else{const _0x828f91=await fetch(_0x211237,{'headers':{'User-Agent':atob(_0x6bc588(0x195))}});_0x3c23e9=await _0x828f91[_0x6bc588(0x1e5)]();}if(_0x975a51[_0x6bc588(0x15a)]=='/'+fakeUserID)return _0x3c23e9;_0x3c23e9=revertFakeInfo(_0x3c23e9,_0x173b9c,_0xd9010c,_0x4167ef);if(_0x41eaec['includes'](_0x6bc588(0x185))||_0x975a51[_0x6bc588(0xdf)][_0x6bc588(0x12e)](_0x6bc588(0x185)))_0x3c23e9=surge(_0x3c23e9,'https://'+_0xd9010c+'/'+_0x173b9c+_0x6bc588(0x118));return _0x3c23e9;}catch(_0x3f6396){return console[_0x6bc588(0xc0)](_0x6bc588(0x1d8),_0x3f6396),_0x6bc588(0x16b)+_0x3f6396[_0x6bc588(0x13f)];}}}async function sendMessage(_0x4646fa,_0x43900a,_0x4a2402=''){const _0x3fcfa2=_0x2751a8;if(BotToken!==''&&ChatID!==''){let _0x3aae5c='';const _0x208b4d=await fetch(_0x3fcfa2(0x19f)+_0x43900a+_0x3fcfa2(0x1de));if(_0x208b4d[_0x3fcfa2(0x1dc)]==0xc8){const _0x3d175f=await _0x208b4d[_0x3fcfa2(0xf3)]();_0x3aae5c=_0x4646fa+_0x3fcfa2(0xbe)+_0x43900a+_0x3fcfa2(0xde)+_0x3d175f[_0x3fcfa2(0x1b8)]+_0x3fcfa2(0xc5)+_0x3d175f[_0x3fcfa2(0x150)]+_0x3fcfa2(0x128)+_0x3d175f[_0x3fcfa2(0x138)]+_0x3fcfa2(0x167)+_0x3d175f['as']+'\x0a'+_0x4a2402;}else _0x3aae5c=_0x4646fa+_0x3fcfa2(0xbe)+_0x43900a+'\x0a'+_0x4a2402;let _0x309519=_0x3fcfa2(0x19b)+BotToken+_0x3fcfa2(0x1c2)+ChatID+_0x3fcfa2(0x172)+encodeURIComponent(_0x3aae5c);return fetch(_0x309519,{'method':_0x3fcfa2(0x141),'headers':{'Accept':_0x3fcfa2(0x173),'Accept-Encoding':_0x3fcfa2(0xf9),'User-Agent':_0x3fcfa2(0x1ab)}});}}let proxyIPPool=[];function _0x1cb6(_0xbf6bcd,_0x16c791){const _0x8aa515=_0x8aa5();return _0x1cb6=function(_0x1cb68b,_0x30e832){_0x1cb68b=_0x1cb68b-0xa7;let _0x89ce17=_0x8aa515[_0x1cb68b];return _0x89ce17;},_0x1cb6(_0xbf6bcd,_0x16c791);}function subAddresses(_0xfe2009,_0x276726,_0x3b8e7e,_0x8e1ce,_0x22fb51){const _0x4a9c03=_0x2751a8;addresses=addresses[_0x4a9c03(0xc7)](_0x8e1ce),addresses=addresses[_0x4a9c03(0xc7)](_0x22fb51);const _0x2a16d1=[...new Set(addresses)],_0x505341=_0x2a16d1[_0x4a9c03(0x114)](_0x2027ea=>{const _0xfa4f41=_0x4a9c03;let _0x5e66d2='-1',_0x2f77ef=_0x2027ea;const _0x58b19a=_0x2f77ef[_0xfa4f41(0x163)](regex);if(!_0x58b19a){if(_0x2027ea[_0xfa4f41(0xc8)](':')&&_0x2027ea[_0xfa4f41(0xc8)]('#')){const _0x482b71=_0x2027ea['split'](':');_0x2027ea=_0x482b71[0x0];const _0x5a8839=_0x482b71[0x1][_0xfa4f41(0x16e)]('#');_0x5e66d2=_0x5a8839[0x0],_0x2f77ef=_0x5a8839[0x1];}else{if(_0x2027ea[_0xfa4f41(0xc8)](':')){const _0x55137d=_0x2027ea[_0xfa4f41(0x16e)](':');_0x2027ea=_0x55137d[0x0],_0x5e66d2=_0x55137d[0x1];}else{if(_0x2027ea[_0xfa4f41(0xc8)]('#')){const _0x5a364a=_0x2027ea['split']('#');_0x2027ea=_0x5a364a[0x0],_0x2f77ef=_0x5a364a[0x1];}}}_0x2f77ef['includes'](':')&&(_0x2f77ef=_0x2f77ef[_0xfa4f41(0x16e)](':')[0x0]);}else _0x2027ea=_0x58b19a[0x1],_0x5e66d2=_0x58b19a[0x2]||_0x5e66d2,_0x2f77ef=_0x58b19a[0x3]||_0x2027ea;const _0x56cf4a=['2053',_0xfa4f41(0xf1),_0xfa4f41(0x12f),_0xfa4f41(0xb5),_0xfa4f41(0x13d)];if(!isValidIPv4(_0x2027ea)&&_0x5e66d2=='-1')for(let _0x345abe of _0x56cf4a){if(_0x2027ea[_0xfa4f41(0xc8)](_0x345abe)){_0x5e66d2=_0x345abe;break;}}if(_0x5e66d2=='-1')_0x5e66d2=_0xfa4f41(0x1a9);let _0x4c9908=_0xfe2009,_0x6e5060=_0xfa4f41(0x17a),_0x2dd8a4='';proxyhosts[_0xfa4f41(0x145)]>0x0&&_0x4c9908['includes'](_0xfa4f41(0x1d5))&&(_0x6e5060='/'+_0x4c9908+_0x6e5060,_0x4c9908=proxyhosts[Math[_0xfa4f41(0x177)](Math[_0xfa4f41(0xea)]()*proxyhosts[_0xfa4f41(0x145)])],_0x2dd8a4=_0xfa4f41(0xc9));const _0x114cec=proxyIPPool[_0xfa4f41(0xd7)](_0x1336fd=>_0x1336fd['includes'](_0x2027ea));if(_0x114cec)_0x6e5060+=_0xfa4f41(0x1ac)+_0x114cec;let _0x4a38d9=_0x276726;if(!_0x3b8e7e[_0xfa4f41(0xc8)]('subconverter'))_0x4a38d9=encodeURIComponent(_0x276726);const _0xa3120a=_0xfa4f41(0x1bb),_0x4f0d32=atob(_0xa3120a),_0x8134c1=_0x4f0d32+_0xfa4f41(0xbd)+_0x4a38d9+'@'+_0x2027ea+':'+_0x5e66d2+_0xfa4f41(0x18a)+_0x4c9908+'&fp=randomized&type=ws&host='+_0x4c9908+'&path='+encodeURIComponent(_0x6e5060)+'#'+encodeURIComponent(_0x2f77ef+_0x2dd8a4);return _0x8134c1;})[_0x4a9c03(0x168)]('\x0a'),_0x1955b3=btoa(_0x505341);return _0x1955b3;}async function getAddressesapi(_0x1a1d5b){const _0x167974=_0x2751a8;if(!_0x1a1d5b||_0x1a1d5b['length']===0x0)return[];let _0x2df269='';const _0x28e306=new AbortController(),_0x158650=setTimeout(()=>{const _0x5a82a4=_0x1cb6;_0x28e306[_0x5a82a4(0xc1)]();},0x7d0);try{const _0x4e2ff3=await Promise[_0x167974(0x11e)](_0x1a1d5b[_0x167974(0x114)](_0x5cca03=>fetch(_0x5cca03,{'method':'get','headers':{'Accept':'text/html,application/xhtml+xml,application/xml;','User-Agent':atob('Q0YtV29ya2Vycy1lcGVpdXMvY21saXU=')},'signal':_0x28e306[_0x167974(0xb1)]})[_0x167974(0x17c)](_0x4ce0e4=>_0x4ce0e4['ok']?_0x4ce0e4[_0x167974(0x1e5)]():Promise[_0x167974(0x135)]())));for(const [_0x6f0d6,_0x516702]of _0x4e2ff3[_0x167974(0x189)]()){if(_0x516702[_0x167974(0x1dc)]===_0x167974(0xb6)){const _0x491832=await _0x516702[_0x167974(0xe6)];_0x1a1d5b[_0x6f0d6][_0x167974(0xc8)](_0x167974(0xa7))&&(proxyIPPool=proxyIPPool[_0x167974(0xc7)]((await ADD(_0x491832))[_0x167974(0x114)](_0x55784a=>{const _0x256d84=_0x167974,_0x5b3d81=_0x55784a[_0x256d84(0x16e)]('#')[0x0]||_0x55784a;if(_0x5b3d81['includes'](':')){const _0xbb497b=_0x5b3d81[_0x256d84(0x16e)](':')[0x1];if(!httpsPorts[_0x256d84(0xc8)](_0xbb497b))return _0x5b3d81;}else return _0x5b3d81+':443';return null;})[_0x167974(0x169)](Boolean))),_0x2df269+=_0x491832+'\x0a';}}}catch(_0x321ef2){console[_0x167974(0xc0)](_0x321ef2);}finally{clearTimeout(_0x158650);}const _0x518c07=await ADD(_0x2df269);return _0x518c07;}async function getAddressescsv(_0x4ff414){const _0x4450d0=_0x2751a8;if(!addressescsv||addressescsv[_0x4450d0(0x145)]===0x0)return[];let _0x5d98d2=[];for(const _0x5045e7 of addressescsv){try{const _0x79e9d3=await fetch(_0x5045e7);if(!_0x79e9d3['ok']){console[_0x4450d0(0xc0)](_0x4450d0(0x17e),_0x79e9d3['status'],_0x79e9d3[_0x4450d0(0xec)]);continue;}const _0x12496c=await _0x79e9d3[_0x4450d0(0x1e5)]();let _0x3632ce;_0x12496c[_0x4450d0(0xc8)]('\x0d\x0a')?_0x3632ce=_0x12496c[_0x4450d0(0x16e)]('\x0d\x0a'):_0x3632ce=_0x12496c[_0x4450d0(0x16e)]('\x0a');const _0x3eee1f=_0x3632ce[0x0][_0x4450d0(0x16e)](','),_0x591b6e=_0x3eee1f[_0x4450d0(0xb9)]('TLS'),_0x4ce362=0x0,_0x12b806=0x1,_0x413abc=_0x591b6e+0x1;if(_0x591b6e===-0x1){console[_0x4450d0(0xc0)](_0x4450d0(0x171));continue;}for(let _0x42a2fc=0x1;_0x42a2fc<_0x3632ce[_0x4450d0(0x145)];_0x42a2fc++){const _0x3f2405=_0x3632ce[_0x42a2fc]['split'](','),_0x36faae=_0x3f2405[_0x4450d0(0x145)]-0x1;if(_0x3f2405[_0x591b6e][_0x4450d0(0xc6)]()===_0x4ff414&&parseFloat(_0x3f2405[_0x36faae])>DLS){const _0x1d97b4=_0x3f2405[_0x4ce362],_0x4456a7=_0x3f2405[_0x12b806],_0x3493a1=_0x3f2405[_0x413abc],_0xefa3ec=_0x1d97b4+':'+_0x4456a7+'#'+_0x3493a1;_0x5d98d2[_0x4450d0(0x119)](_0xefa3ec),_0x5045e7[_0x4450d0(0xc8)]('proxyip=true')&&_0x3f2405[_0x591b6e][_0x4450d0(0xc6)]()==_0x4450d0(0x1a1)&&!httpsPorts['includes'](_0x4456a7)&&proxyIPPool[_0x4450d0(0x119)](_0x1d97b4+':'+_0x4456a7);}}}catch(_0xf6a7e0){console[_0x4450d0(0xc0)]('获取CSV地址时出错:',_0xf6a7e0);continue;}}return _0x5d98d2;}function surge(_0x534811,_0x250ad0){const _0x15be0c=_0x2751a8;let _0x44ea21;_0x534811['includes']('\x0d\x0a')?_0x44ea21=_0x534811[_0x15be0c(0x16e)]('\x0d\x0a'):_0x44ea21=_0x534811[_0x15be0c(0x16e)]('\x0a');let _0x22ad11='';for(let _0xf2e304 of _0x44ea21){if(_0xf2e304[_0x15be0c(0xc8)]('=\x20trojan,')){const _0x40aae8=_0xf2e304[_0x15be0c(0x16e)](_0x15be0c(0x183))[0x1]['split'](',')[0x0],_0x49d14e='skip-cert-verify=true,\x20tfo=false,\x20udp-relay=false',_0x1e4b13='skip-cert-verify=true,\x20ws=true,\x20ws-path=/?ed=2560,\x20ws-headers=Host:\x22'+_0x40aae8+_0x15be0c(0x1cb);_0x22ad11+=_0xf2e304[_0x15be0c(0x1b1)](new RegExp(_0x49d14e,'g'),_0x1e4b13)[_0x15be0c(0x1b1)]('[','')[_0x15be0c(0x1b1)](']','')+'\x0a';}else _0x22ad11+=_0xf2e304+'\x0a';}return _0x22ad11=_0x15be0c(0x18f)+_0x250ad0+'\x20interval=86400\x20strict=false'+_0x22ad11[_0x15be0c(0xd0)](_0x22ad11[_0x15be0c(0xb9)]('\x0a')),_0x22ad11;}/**
+export default {
+ async fetch(request, env, ctx) {
+ try {
+ const UA = request.headers.get('User-Agent') || 'null';
+ const userAgent = UA.toLowerCase();
+ password = env.PASSWORD || password;
+ if (!password) {
+ return new Response('请设置你的PASSWORD变量,或尝试重试部署,检查变量是否生效?', {
+ status: 404,
+ headers: {
+ "Content-Type": "text/plain;charset=utf-8",
+ }
+ });
+ }
+ sha224Password = env.SHA224 || env.SHA224PASS || sha224(password);
+ //console.log(sha224Password);
+
+ const currentDate = new Date();
+ currentDate.setHours(0, 0, 0, 0); // 设置时间为当天
+ const timestamp = Math.ceil(currentDate.getTime() / 1000);
+ const fakeUserIDMD5 = await MD5MD5(`${password}${timestamp}`);
+ fakeUserID = fakeUserIDMD5.slice(0, 8) + "-" + fakeUserIDMD5.slice(8, 12) + "-" + fakeUserIDMD5.slice(12, 16) + "-" + fakeUserIDMD5.slice(16, 20) + "-" + fakeUserIDMD5.slice(20);
+ fakeHostName = fakeUserIDMD5.slice(6, 9) + "." + fakeUserIDMD5.slice(13, 19);
+ //console.log(fakeUserID); // 打印fakeID
+
+ proxyIP = env.PROXYIP || proxyIP;
+ proxyIPs = await ADD(proxyIP);
+ proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)];
+ socks5Address = env.SOCKS5 || socks5Address;
+ socks5s = await ADD(socks5Address);
+ socks5Address = socks5s[Math.floor(Math.random() * socks5s.length)];
+ socks5Address = socks5Address.split('//')[1] || socks5Address;
+ if (env.CFPORTS) httpsPorts = await ADD(env.CFPORTS);
+ sub = env.SUB || sub;
+ subconverter = env.SUBAPI || subconverter;
+ if( subconverter.includes("http://") ){
+ subconverter = subconverter.split("//")[1];
+ subProtocol = 'http';
+ } else {
+ subconverter = subconverter.split("//")[1] || subconverter;
+ }
+ subconfig = env.SUBCONFIG || subconfig;
+ if (socks5Address) {
+ try {
+ parsedSocks5Address = socks5AddressParser(socks5Address);
+ RproxyIP = env.RPROXYIP || 'false';
+ enableSocks = true;
+ } catch (err) {
+ /** @type {Error} */
+ let e = err;
+ console.log(e.toString());
+ RproxyIP = env.RPROXYIP || !proxyIP ? 'true' : 'false';
+ enableSocks = false;
+ }
+ } else {
+ RproxyIP = env.RPROXYIP || !proxyIP ? 'true' : 'false';
+ }
+ if (env.ADD) addresses = await ADD(env.ADD);
+ if (env.ADDAPI) addressesapi = await ADD(env.ADDAPI);
+ if (env.ADDCSV) addressescsv = await ADD(env.ADDCSV);
+ DLS = env.DLS || DLS;
+ BotToken = env.TGTOKEN || BotToken;
+ ChatID = env.TGID || ChatID;
+ if(env.GO2SOCKS5) go2Socks5s = await ADD(env.GO2SOCKS5);
+ const upgradeHeader = request.headers.get("Upgrade");
+ const url = new URL(request.url);
+ if (url.searchParams.has('sub') && url.searchParams.get('sub') !== '') sub = url.searchParams.get('sub');
+ FileName = env.SUBNAME || FileName;
+ if (!upgradeHeader || upgradeHeader !== "websocket") {
+ //const url = new URL(request.url);
+ switch (url.pathname) {
+ case '/':
+ if (env.URL302) return Response.redirect(env.URL302, 302);
+ else if (env.URL) return await proxyURL(env.URL, url);
+ else return new Response(JSON.stringify(request.cf, null, 4), {
+ status: 200,
+ headers: {
+ 'content-type': 'application/json',
+ },
+ });
+ case `/${fakeUserID}`:
+ const fakeConfig = await getTrojanConfig(password, request.headers.get('Host'), sub, 'CF-Workers-SUB', RproxyIP, url);
+ return new Response(`${fakeConfig}`, { status: 200 });
+ case `/${password}`:
+ await sendMessage(`#获取订阅 ${FileName}`, request.headers.get('CF-Connecting-IP'), `UA: ${UA}\n域名: ${url.hostname}\n入口: ${url.pathname + url.search}`);
+ const trojanConfig = await getTrojanConfig(password, request.headers.get('Host'), sub, UA, RproxyIP, url);
+ const now = Date.now();
+ //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);
+ let pagesSum = UD;
+ let workersSum = UD;
+ let total = 24 * 1099511627776 ;
+
+ if (userAgent && (userAgent.includes('mozilla') || userAgent.includes('subconverter'))){
+ return new Response(`${trojanConfig}`, {
+ status: 200,
+ headers: {
+ "Content-Type": "text/plain;charset=utf-8",
+ "Profile-Update-Interval": "6",
+ "Subscription-Userinfo": `upload=${pagesSum}; download=${workersSum}; total=${total}; expire=${expire}`,
+ }
+ });
+ } else {
+ return new Response(`${trojanConfig}`, {
+ status: 200,
+ headers: {
+ "Content-Disposition": `attachment; filename=${FileName}; filename*=utf-8''${encodeURIComponent(FileName)}`,
+ "Content-Type": "text/plain;charset=utf-8",
+ "Profile-Update-Interval": "6",
+ "Subscription-Userinfo": `upload=${pagesSum}; download=${workersSum}; total=${total}; expire=${expire}`,
+ }
+ });
+ }
+ default:
+ if (env.URL302) return Response.redirect(env.URL302, 302);
+ else if (env.URL) return await proxyURL(env.URL, url);
+ else return new Response('不用怀疑!你PASSWORD就是错的!!!', { status: 404 });
+ }
+ } else {
+ proxyIP = url.searchParams.get('proxyip') || proxyIP;
+ if (new RegExp('/proxyip=', 'i').test(url.pathname)) proxyIP = url.pathname.toLowerCase().split('/proxyip=')[1];
+ else if (new RegExp('/proxyip.', 'i').test(url.pathname)) proxyIP = `proxyip.${url.pathname.toLowerCase().split("/proxyip.")[1]}`;
+
+ socks5Address = url.searchParams.get('socks5') || socks5Address;
+ 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('@')){
+ 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);
+ socks5Address = `${userPassword}@${socks5Address.split('@')[1]}`;
+ }
+ }
+ if (socks5Address) {
+ try {
+ parsedSocks5Address = socks5AddressParser(socks5Address);
+ enableSocks = true;
+ } catch (err) {
+ /** @type {Error} */
+ let e = err;
+ console.log(e.toString());
+ enableSocks = false;
+ }
+ } else {
+ enableSocks = false;
+ }
+ return await trojanOverWSHandler(request);
+ }
+ } catch (err) {
+ let e = err;
+ return new Response(e.toString());
+ }
+ }
+};
+
+async function trojanOverWSHandler(request) {
+ const webSocketPair = new WebSocketPair();
+ const [client, webSocket] = Object.values(webSocketPair);
+ webSocket.accept();
+ let address = "";
+ let portWithRandomLog = "";
+ const log = (info, event) => {
+ console.log(`[${address}:${portWithRandomLog}] ${info}`, event || "");
+ };
+ const earlyDataHeader = request.headers.get("sec-websocket-protocol") || "";
+ const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log);
+ let remoteSocketWapper = {
+ value: null
+ };
+ let udpStreamWrite = null;
+ readableWebSocketStream.pipeTo(new WritableStream({
+ async write(chunk, controller) {
+ if (udpStreamWrite) {
+ return udpStreamWrite(chunk);
+ }
+ if (remoteSocketWapper.value) {
+ const writer = remoteSocketWapper.value.writable.getWriter();
+ await writer.write(chunk);
+ writer.releaseLock();
+ return;
+ }
+ const {
+ hasError,
+ message,
+ portRemote = 443,
+ addressRemote = "",
+ rawClientData,
+ addressType
+ } = await parseTrojanHeader(chunk);
+ address = addressRemote;
+ portWithRandomLog = `${portRemote}--${Math.random()} tcp`;
+ if (hasError) {
+ throw new Error(message);
+ return;
+ }
+ handleTCPOutBound(remoteSocketWapper, addressRemote, portRemote, rawClientData, webSocket, log, addressType);
+ },
+ close() {
+ log(`readableWebSocketStream is closed`);
+ },
+ abort(reason) {
+ log(`readableWebSocketStream is aborted`, JSON.stringify(reason));
+ }
+ })).catch((err) => {
+ log("readableWebSocketStream pipeTo error", err);
+ });
+ return new Response(null, {
+ status: 101,
+ // @ts-ignore
+ webSocket: client
+ });
+}
+
+async function parseTrojanHeader(buffer) {
+ if (buffer.byteLength < 56) {
+ return {
+ hasError: true,
+ message: "invalid data"
+ };
+ }
+ let crLfIndex = 56;
+ if (new Uint8Array(buffer.slice(56, 57))[0] !== 0x0d || new Uint8Array(buffer.slice(57, 58))[0] !== 0x0a) {
+ return {
+ hasError: true,
+ message: "invalid header format (missing CR LF)"
+ };
+ }
+ const password = new TextDecoder().decode(buffer.slice(0, crLfIndex));
+ if (password !== sha224Password) {
+ return {
+ hasError: true,
+ message: "invalid password"
+ };
+ }
+
+ const socks5DataBuffer = buffer.slice(crLfIndex + 2);
+ if (socks5DataBuffer.byteLength < 6) {
+ return {
+ hasError: true,
+ message: "invalid SOCKS5 request data"
+ };
+ }
+
+ const view = new DataView(socks5DataBuffer);
+ const cmd = view.getUint8(0);
+ if (cmd !== 1) {
+ return {
+ hasError: true,
+ message: "unsupported command, only TCP (CONNECT) is allowed"
+ };
+ }
+
+ const atype = view.getUint8(1);
+ // 0x01: IPv4 address
+ // 0x03: Domain name
+ // 0x04: IPv6 address
+ let addressLength = 0;
+ let addressIndex = 2;
+ let address = "";
+ switch (atype) {
+ case 1:
+ addressLength = 4;
+ address = new Uint8Array(
+ socks5DataBuffer.slice(addressIndex, addressIndex + addressLength)
+ ).join(".");
+ break;
+ case 3:
+ addressLength = new Uint8Array(
+ socks5DataBuffer.slice(addressIndex, addressIndex + 1)
+ )[0];
+ addressIndex += 1;
+ address = new TextDecoder().decode(
+ socks5DataBuffer.slice(addressIndex, addressIndex + addressLength)
+ );
+ break;
+ case 4:
+ addressLength = 16;
+ const dataView = new DataView(socks5DataBuffer.slice(addressIndex, addressIndex + addressLength));
+ const ipv6 = [];
+ for (let i = 0; i < 8; i++) {
+ ipv6.push(dataView.getUint16(i * 2).toString(16));
+ }
+ address = ipv6.join(":");
+ break;
+ default:
+ return {
+ hasError: true,
+ message: `invalid addressType is ${atype}`
+ };
+ }
+
+ if (!address) {
+ return {
+ hasError: true,
+ message: `address is empty, addressType is ${atype}`
+ };
+ }
+
+ const portIndex = addressIndex + addressLength;
+ const portBuffer = socks5DataBuffer.slice(portIndex, portIndex + 2);
+ const portRemote = new DataView(portBuffer).getUint16(0);
+ return {
+ hasError: false,
+ addressRemote: address,
+ portRemote,
+ rawClientData: socks5DataBuffer.slice(portIndex + 4),
+ addressType: atype
+ };
+}
+
+async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawClientData, webSocket, log, addressType) {
+ async function useSocks5Pattern(address) {
+ 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');
+ return regex.test(address);
+ });
+ }
+ async function connectAndWrite(address, port, socks = false) {
+ log(`connected to ${address}:${port}`);
+ //if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(address)) address = `${atob('d3d3Lg==')}${address}${atob('LmlwLjA5MDIyNy54eXo=')}`;
+ const tcpSocket = socks ? await socks5Connect(addressType, address, port, log)
+ : connect({
+ hostname: address,
+ port
+ });
+ remoteSocket.value = tcpSocket;
+ //log(`connected to ${address}:${port}`);
+ const writer = tcpSocket.writable.getWriter();
+ await writer.write(rawClientData);
+ writer.releaseLock();
+ return tcpSocket;
+ }
+ async function retry() {
+ if (enableSocks) {
+ tcpSocket = await connectAndWrite(addressRemote, portRemote, true);
+ } else {
+ if (!proxyIP || proxyIP == '') {
+ proxyIP = atob('UFJPWFlJUC50cDEuZnh4ay5kZWR5bi5pbw==');
+ } else if (proxyIP.includes(']:')) {
+ portRemote = proxyIP.split(']:')[1] || portRemote;
+ proxyIP = proxyIP.split(']:')[0] || proxyIP;
+ } else if (proxyIP.split(':').length === 2) {
+ portRemote = proxyIP.split(':')[1] || portRemote;
+ proxyIP = proxyIP.split(':')[0] || proxyIP;
+ }
+ if (proxyIP.includes('.tp')) portRemote = proxyIP.split('.tp')[1].split('.')[0] || portRemote;
+ tcpSocket = await connectAndWrite(proxyIP || addressRemote, portRemote);
+ }
+ tcpSocket.closed.catch((error) => {
+ console.log("retry tcpSocket closed error", error);
+ }).finally(() => {
+ safeCloseWebSocket(webSocket);
+ });
+ remoteSocketToWS(tcpSocket, webSocket, null, log);
+ }
+ let useSocks = false;
+ if( go2Socks5s.length > 0 && enableSocks ) useSocks = await useSocks5Pattern(addressRemote);
+ let tcpSocket = await connectAndWrite(addressRemote, portRemote, useSocks);
+ remoteSocketToWS(tcpSocket, webSocket, retry, log);
+}
+
+function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) {
+ let readableStreamCancel = false;
+ const stream = new ReadableStream({
+ start(controller) {
+ webSocketServer.addEventListener("message", (event) => {
+ if (readableStreamCancel) {
+ return;
+ }
+ const message = event.data;
+ controller.enqueue(message);
+ });
+ webSocketServer.addEventListener("close", () => {
+ safeCloseWebSocket(webSocketServer);
+ if (readableStreamCancel) {
+ return;
+ }
+ controller.close();
+ });
+ webSocketServer.addEventListener("error", (err) => {
+ log("webSocketServer error");
+ controller.error(err);
+ });
+ const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader);
+ if (error) {
+ controller.error(error);
+ } else if (earlyData) {
+ controller.enqueue(earlyData);
+ }
+ },
+ pull(controller) {},
+ cancel(reason) {
+ if (readableStreamCancel) {
+ return;
+ }
+ log(`readableStream was canceled, due to ${reason}`);
+ readableStreamCancel = true;
+ safeCloseWebSocket(webSocketServer);
+ }
+ });
+ return stream;
+}
+
+async function remoteSocketToWS(remoteSocket, webSocket, retry, log) {
+ let hasIncomingData = false;
+ await remoteSocket.readable.pipeTo(
+ new WritableStream({
+ start() {},
+ /**
+ *
+ * @param {Uint8Array} chunk
+ * @param {*} controller
+ */
+ async write(chunk, controller) {
+ hasIncomingData = true;
+ if (webSocket.readyState !== WS_READY_STATE_OPEN) {
+ controller.error(
+ "webSocket connection is not open"
+ );
+ }
+ webSocket.send(chunk);
+ },
+ close() {
+ log(`remoteSocket.readable is closed, hasIncomingData: ${hasIncomingData}`);
+ },
+ abort(reason) {
+ console.error("remoteSocket.readable abort", reason);
+ }
+ })
+ ).catch((error) => {
+ console.error(
+ `remoteSocketToWS error:`,
+ error.stack || error
+ );
+ safeCloseWebSocket(webSocket);
+ });
+ if (hasIncomingData === false && retry) {
+ log(`retry`);
+ retry();
+ }
+}
+/*
+function isValidSHA224(hash) {
+ const sha224Regex = /^[0-9a-f]{56}$/i;
+ return sha224Regex.test(hash);
+}
+*/
+function base64ToArrayBuffer(base64Str) {
+ if (!base64Str) {
+ return { error: null };
+ }
+ try {
+ base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
+ const decode = atob(base64Str);
+ const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0));
+ return { earlyData: arryBuffer.buffer, error: null };
+ } catch (error) {
+ return { error };
+ }
+}
+
+let WS_READY_STATE_OPEN = 1;
+let WS_READY_STATE_CLOSING = 2;
+
+function safeCloseWebSocket(socket) {
+ try {
+ if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) {
+ socket.close();
+ }
+ } catch (error) {
+ console.error("safeCloseWebSocket error", error);
+ }
+}
+
+/*
+export {
+ worker_default as
+ default
+};
+//# sourceMappingURL=worker.js.map
+*/
+
+function revertFakeInfo(content, userID, hostName, isBase64) {
+ if (isBase64) content = atob(content);//Base64解码
+ content = content.replace(new RegExp(fakeUserID, 'g'), userID).replace(new RegExp(fakeHostName, 'g'), hostName);
+ //console.log(content);
+ if (isBase64) content = btoa(content);//Base64编码
+
+ return content;
+}
+
+async function MD5MD5(text) {
+ const encoder = new TextEncoder();
+
+ const firstPass = await crypto.subtle.digest('MD5', encoder.encode(text));
+ const firstPassArray = Array.from(new Uint8Array(firstPass));
+ const firstHex = firstPassArray.map(b => b.toString(16).padStart(2, '0')).join('');
+
+ const secondPass = await crypto.subtle.digest('MD5', encoder.encode(firstHex.slice(7, 27)));
+ const secondPassArray = Array.from(new Uint8Array(secondPass));
+ const secondHex = secondPassArray.map(b => b.toString(16).padStart(2, '0')).join('');
+
+ return secondHex.toLowerCase();
+}
+
+async function ADD(内容) {
+ // 将制表符、双引号、单引号和换行符都替换为逗号
+ // 然后将连续的多个逗号替换为单个逗号
+ var 替换后的内容 = 内容.replace(/[ |"'\r\n]+/g, ',').replace(/,+/g, ',');
+
+ // 删除开头和结尾的逗号(如果有的话)
+ if (替换后的内容.charAt(0) == ',') 替换后的内容 = 替换后的内容.slice(1);
+ if (替换后的内容.charAt(替换后的内容.length - 1) == ',') 替换后的内容 = 替换后的内容.slice(0, 替换后的内容.length - 1);
+
+ // 使用逗号分割字符串,得到地址数组
+ const 地址数组 = 替换后的内容.split(',');
+
+ return 地址数组;
+}
+
+async function proxyURL(proxyURL, url) {
+ const URLs = await ADD(proxyURL);
+ const fullURL = URLs[Math.floor(Math.random() * URLs.length)];
+ // 解析目标 URL
+ let parsedURL = new URL(fullURL);
+ console.log(parsedURL);
+ // 提取并可能修改 URL 组件
+ let URLProtocol = parsedURL.protocol.slice(0, -1) || 'https';
+ let URLHostname = parsedURL.hostname;
+ let URLPathname = parsedURL.pathname;
+ let URLSearch = parsedURL.search;
+ // 处理 pathname
+ if (URLPathname.charAt(URLPathname.length - 1) == '/') {
+ URLPathname = URLPathname.slice(0, -1);
+ }
+ URLPathname += url.pathname;
+ // 构建新的 URL
+ let newURL = `${URLProtocol}://${URLHostname}${URLPathname}${URLSearch}`;
+ // 反向代理请求
+ let response = await fetch(newURL);
+ // 创建新的响应
+ let newResponse = new Response(response.body, {
+ status: response.status,
+ statusText: response.statusText,
+ headers: response.headers
+ });
+ // 添加自定义头部,包含 URL 信息
+ //newResponse.headers.set('X-Proxied-By', 'Cloudflare Worker');
+ //newResponse.headers.set('X-Original-URL', fullURL);
+ newResponse.headers.set('X-New-URL', newURL);
+ return newResponse;
+}
+
+function 配置信息(密码, 域名地址) {
+ const 啥啥啥_写的这是啥啊 = 'dHJvamFu';
+ const 协议类型 = atob(啥啥啥_写的这是啥啊);
+
+ const 别名 = FileName;
+ let 地址 = 域名地址;
+ let 端口 = 443;
+
+ const 传输层协议 = 'ws';
+ const 伪装域名 = 域名地址;
+ const 路径 = '/?ed=2560';
+
+ let 传输层安全 = ['tls',true];
+ const SNI = 域名地址;
+ const 指纹 = 'randomized';
+
+ const v2ray = `${协议类型}://${encodeURIComponent(密码)}@${地址}:${端口}?security=${传输层安全[0]}&sni=${SNI}&alpn=h3&fp=${指纹}&allowInsecure=1&type=${传输层协议}&host=${伪装域名}&path=${encodeURIComponent(路径)}#${encodeURIComponent(别名)}`
+ const clash = `- {name: ${别名}, server: ${地址}, port: ${端口}, udp: false, client-fingerprint: ${指纹}, type: ${协议类型}, password: ${密码}, sni: ${SNI}, alpn: [h3], skip-cert-verify: true, network: ${传输层协议}, ws-opts: {path: "${路径}", headers: {Host: ${伪装域名}}}}`;
+
+ return [v2ray,clash];
+}
+
+let subParams = ['sub','base64','b64','clash','singbox','sb','surge'];
+async function getTrojanConfig(password, hostName, sub, UA, RproxyIP, _url) {
+ if (sub) {
+ const match = sub.match(/^(?:https?:\/\/)?([^\/]+)/);
+ if (match) {
+ sub = match[1];
+ }
+ } else if ((addresses.length + addressesapi.length + addressescsv.length) == 0){
+ // 定义 Cloudflare IP 范围的 CIDR 列表
+ let cfips = [
+ '103.21.244.0/23',
+ '104.16.0.0/13',
+ '104.24.0.0/14',
+ '172.64.0.0/14',
+ '103.21.244.0/23',
+ '104.16.0.0/14',
+ '104.24.0.0/15',
+ '141.101.64.0/19',
+ '172.64.0.0/14',
+ '188.114.96.0/21',
+ '190.93.240.0/21',
+ ];
+
+ // 生成符合给定 CIDR 范围的随机 IP 地址
+ function generateRandomIPFromCIDR(cidr) {
+ const [base, mask] = cidr.split('/');
+ const baseIP = base.split('.').map(Number);
+ 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');
+ addresses = addresses.concat(cfips.map(cidr => generateRandomIPFromCIDR(cidr) + '#CF随机节点'));
+ }
+ const userAgent = UA.toLowerCase();
+ const Config = 配置信息(password , hostName);
+ const v2ray = Config[0];
+ const clash = Config[1];
+ let proxyhost = "";
+ if(hostName.includes(".workers.dev")){
+ if ( proxyhostsURL && (!proxyhosts || proxyhosts.length == 0)) {
+ try {
+ 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)] + "/";
+ }
+
+ if ( userAgent.includes('mozilla') && !subParams.some(_searchParams => _url.searchParams.has(_searchParams))) {
+ let surge = `Surge订阅地址:\nhttps://${proxyhost}${hostName}/${password}?surge`;
+ if (hostName.includes(".workers.dev")) surge = "Surge订阅必须绑定自定义域";
+ const newSocks5s = socks5s.map(socks5Address => {
+ if (socks5Address.includes('@')) return socks5Address.split('@')[1];
+ else if (socks5Address.includes('//')) return socks5Address.split('//')[1];
+ else return socks5Address;
+ });
+
+ let socks5List = '';
+ 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')}\n`;
+ else socks5List += `\n ${go2Socks5s.join('\n ')}\n`;
+ }
+
+ let 订阅器 = '';
+ if (sub) {
+ if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5\n ${newSocks5s.join('\n ')}\n${socks5List}`;
+ else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP\n ${proxyIPs.join('\n ')}\n`;
+ else if (RproxyIP == 'true') 订阅器 += `CFCDN(访问方式): 自动获取ProxyIP\n`;
+ else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!\n`
+ 订阅器 += `\nSUB(优选订阅生成器): ${sub}`;
+ } else {
+ if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5\n ${newSocks5s.join('\n ')}\n${socks5List}`;
+ else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP\n ${proxyIPs.join('\n ')}\n`;
+ else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!\n`;
+ 订阅器 += `\n您的订阅内容由 内置 addresses/ADD* 参数变量提供\n`;
+ if (addresses.length > 0) 订阅器 += `ADD(TLS优选域名&IP): \n ${addresses.join('\n ')}\n`;
+ if (addressesapi.length > 0) 订阅器 += `ADDAPI(TLS优选域名&IP 的 API): \n ${addressesapi.join('\n ')}\n`;
+ if (addressescsv.length > 0) 订阅器 += `ADDCSV(IPTest测速csv文件 限速 ${DLS} ): \n ${addressescsv.join('\n ')}\n`;
+ }
+
+ return `
+################################################################
+Subscribe / sub 订阅地址, 支持 Base64、clash-meta、sing-box 订阅格式
+---------------------------------------------------------------
+快速自适应订阅地址:
+https://${proxyhost}${hostName}/${password}
+https://${proxyhost}${hostName}/${password}?sub
+
+Base64订阅地址:
+https://${proxyhost}${hostName}/${password}?b64
+https://${proxyhost}${hostName}/${password}?base64
+
+clash订阅地址:
+https://${proxyhost}${hostName}/${password}?clash
+
+singbox订阅地址:
+https://${proxyhost}${hostName}/${password}?sb
+https://${proxyhost}${hostName}/${password}?singbox
+
+${surge}
+---------------------------------------------------------------
+################################################################
+${FileName} 配置信息
+---------------------------------------------------------------
+HOST: ${hostName}
+PASSWORD: ${password}
+SHA224: ${sha224Password}
+FAKEPASS: ${fakeUserID}
+UA: ${UA}
+
+${订阅器}
+SUBAPI(订阅转换后端): ${subProtocol}://${subconverter}
+SUBCONFIG(订阅转换配置文件): ${subconfig}
+---------------------------------------------------------------
+################################################################
+v2ray
+---------------------------------------------------------------
+${v2ray}
+---------------------------------------------------------------
+################################################################
+clash-meta
+---------------------------------------------------------------
+${clash}
+---------------------------------------------------------------
+################################################################
+${atob(`dGVsZWdyYW0g5Lqk5rWB576kIOaKgOacr+Wkp+S9rH7lnKjnur/lj5HniYwhCmh0dHBzOi8vdC5tZS9DTUxpdXNzc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmdpdGh1YiDpobnnm67lnLDlnYAgU3RhciFTdGFyIVN0YXIhISEKaHR0cHM6Ly9naXRodWIuY29tL2NtbGl1L2VwZWl1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw==`)}
+`;
+ } else {
+ if (typeof fetch != 'function') {
+ return 'Error: fetch is not available in this environment.';
+ }
+ // 如果是使用默认域名,则改成一个workers的域名,订阅器会加上代理
+ if (hostName.includes(".workers.dev")){
+ fakeHostName = `${fakeHostName}.workers.dev`;
+ } else {
+ fakeHostName = `${fakeHostName}.xyz`
+ }
+
+ let url = `https://${sub}/sub?host=${fakeHostName}&pw=${fakeUserID}&password=${fakeUserID + atob('JmVwZWl1cz1jbWxpdSZwcm94eWlwPQ==') + RproxyIP}`;
+ let isBase64 = true;
+ let newAddressesapi = [];
+ let newAddressescsv = [];
+
+ if (!sub || sub == "") {
+ if(hostName.includes('workers.dev')) {
+ if (proxyhostsURL && (!proxyhosts || proxyhosts.length == 0)) {
+ try {
+ 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);
+ }
+ }
+ // 使用Set对象去重
+ proxyhosts = [...new Set(proxyhosts)];
+ }
+
+ newAddressesapi = await getAddressesapi(addressesapi);
+ newAddressescsv = await getAddressescsv('TRUE');
+ url = `https://${hostName}/${fakeUserID}`;
+ }
+
+ if (!userAgent.includes(('CF-Workers-SUB').toLowerCase())){
+ if ((userAgent.includes('clash') && !userAgent.includes('nekobox')) || ( _url.searchParams.has('clash'))) {
+ url = `${subProtocol}://${subconverter}/sub?target=clash&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`;
+ isBase64 = false;
+ } else if (userAgent.includes('sing-box') || userAgent.includes('singbox') || _url.searchParams.has('singbox') || _url.searchParams.has('sb')) {
+ url = `${subProtocol}://${subconverter}/sub?target=singbox&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`;
+ isBase64 = false;
+ } else if (userAgent.includes('surge') || _url.searchParams.has('surge')) {
+ url = `${subProtocol}://${subconverter}/sub?target=surge&ver=4&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&xudp=false&udp=false&tfo=false&expand=true&scv=true&fdn=false`;
+ isBase64 = false;
+ }
+ }
+
+ try {
+ let content;
+ if ((!sub || sub == "") && isBase64 == true) {
+ content = await subAddresses(fakeHostName,fakeUserID,userAgent,newAddressesapi,newAddressescsv);
+ } else {
+ const response = await fetch(url ,{
+ headers: {
+ 'User-Agent': atob('Q0YtV29ya2Vycy1lcGVpdXMvY21saXU='),
+ }});
+ content = await response.text();
+ }
+
+ if (_url.pathname == `/${fakeUserID}`) return content;
+
+ content = revertFakeInfo(content, password, hostName, isBase64);
+ if (userAgent.includes('surge') || _url.searchParams.has('surge')) content = surge(content, `https://${hostName}/${password}?surge`);
+ return content;
+ } catch (error) {
+ console.error('Error fetching content:', error);
+ return `Error fetching content: ${error.message}`;
+ }
+ }
+}
+
+async function sendMessage(type, ip, add_data = "") {
+ if ( BotToken !== '' && ChatID !== ''){
+ let msg = "";
+ const response = await fetch(`http://ip-api.com/json/${ip}?lang=zh-CN`);
+ if (response.status == 200) {
+ const ipInfo = await response.json();
+ msg = `${type}\nIP: ${ip}\n国家: ${ipInfo.country}\n城市: ${ipInfo.city}\n组织: ${ipInfo.org}\nASN: ${ipInfo.as}\n${add_data}`;
+ } else {
+ msg = `${type}\nIP: ${ip}\n${add_data}`;
+ }
+
+ let url = "https://api.telegram.org/bot"+ BotToken +"/sendMessage?chat_id=" + ChatID + "&parse_mode=HTML&text=" + encodeURIComponent(msg);
+ return fetch(url, {
+ method: 'get',
+ headers: {
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;',
+ 'Accept-Encoding': 'gzip, deflate, br',
+ 'User-Agent': 'Mozilla/5.0 Chrome/90.0.4430.72'
+ }
+ });
+ }
+}
+
+/**
+ *
+ * @param {number} addressType
+ * @param {string} addressRemote
+ * @param {number} portRemote
+ * @param {function} log The logging function.
+ */
+async function socks5Connect(addressType, addressRemote, portRemote, log) {
+ const { username, password, hostname, port } = parsedSocks5Address;
+ // Connect to the SOCKS server
+ const socket = connect({
+ hostname,
+ port,
+ });
+
+ // Request head format (Worker -> Socks Server):
+ // +----+----------+----------+
+ // |VER | NMETHODS | METHODS |
+ // +----+----------+----------+
+ // | 1 | 1 | 1 to 255 |
+ // +----+----------+----------+
+
+ // https://en.wikipedia.org/wiki/SOCKS#SOCKS5
+ // For METHODS:
+ // 0x00 NO AUTHENTICATION REQUIRED
+ // 0x02 USERNAME/PASSWORD https://datatracker.ietf.org/doc/html/rfc1929
+ const socksGreeting = new Uint8Array([5, 2, 0, 2]);
+
+ const writer = socket.writable.getWriter();
+
+ await writer.write(socksGreeting);
+ log('sent socks greeting');
+
+ const reader = socket.readable.getReader();
+ const encoder = new TextEncoder();
+ let res = (await reader.read()).value;
+ // Response format (Socks Server -> Worker):
+ // +----+--------+
+ // |VER | METHOD |
+ // +----+--------+
+ // | 1 | 1 |
+ // +----+--------+
+ if (res[0] !== 0x05) {
+ log(`socks server version error: ${res[0]} expected: 5`);
+ return;
+ }
+ if (res[1] === 0xff) {
+ log("no acceptable methods");
+ return;
+ }
+
+ // if return 0x0502
+ if (res[1] === 0x02) {
+ log("socks server needs auth");
+ if (!username || !password) {
+ log("please provide username/password");
+ return;
+ }
+ // +----+------+----------+------+----------+
+ // |VER | ULEN | UNAME | PLEN | PASSWD |
+ // +----+------+----------+------+----------+
+ // | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
+ // +----+------+----------+------+----------+
+ const authRequest = new Uint8Array([
+ 1,
+ username.length,
+ ...encoder.encode(username),
+ password.length,
+ ...encoder.encode(password)
+ ]);
+ await writer.write(authRequest);
+ res = (await reader.read()).value;
+ // expected 0x0100
+ if (res[0] !== 0x01 || res[1] !== 0x00) {
+ log("fail to auth socks server");
+ return;
+ }
+ }
+
+ // Request data format (Worker -> Socks Server):
+ // +----+-----+-------+------+----------+----------+
+ // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+ // +----+-----+-------+------+----------+----------+
+ // | 1 | 1 | X'00' | 1 | Variable | 2 |
+ // +----+-----+-------+------+----------+----------+
+ // ATYP: address type of following address
+ // 0x01: IPv4 address
+ // 0x03: Domain name
+ // 0x04: IPv6 address
+ // DST.ADDR: desired destination address
+ // DST.PORT: desired destination port in network octet order
+
+ // addressType
+ // 0x01: IPv4 address
+ // 0x03: Domain name
+ // 0x04: IPv6 address
+ // 1--> ipv4 addressLength =4
+ // 2--> domain name
+ // 3--> ipv6 addressLength =16
+ let DSTADDR; // DSTADDR = ATYP + DST.ADDR
+ switch (addressType) {
+ case 1:
+ DSTADDR = new Uint8Array(
+ [1, ...addressRemote.split('.').map(Number)]
+ );
+ break;
+ case 3:
+ DSTADDR = new Uint8Array(
+ [3, addressRemote.length, ...encoder.encode(addressRemote)]
+ );
+ break;
+ case 4:
+ DSTADDR = new Uint8Array(
+ [4, ...addressRemote.split(':').flatMap(x => [parseInt(x.slice(0, 2), 16), parseInt(x.slice(2), 16)])]
+ );
+ break;
+ default:
+ log(`invild addressType is ${addressType}`);
+ return;
+ }
+ const socksRequest = new Uint8Array([5, 1, 0, ...DSTADDR, portRemote >> 8, portRemote & 0xff]);
+ await writer.write(socksRequest);
+ log('sent socks request');
+
+ res = (await reader.read()).value;
+ // Response format (Socks Server -> Worker):
+ // +----+-----+-------+------+----------+----------+
+ // |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+ // +----+-----+-------+------+----------+----------+
+ // | 1 | 1 | X'00' | 1 | Variable | 2 |
+ // +----+-----+-------+------+----------+----------+
+ if (res[1] === 0x00) {
+ log("socks connection opened");
+ } else {
+ log("fail to open socks connection");
+ return;
+ }
+ writer.releaseLock();
+ reader.releaseLock();
+ return socket;
+}
+
+/**
+ *
+ * @param {string} address
+ */
+function socks5AddressParser(address) {
+ let [latter, former] = address.split("@").reverse();
+ let username, password, hostname, port;
+ if (former) {
+ const formers = former.split(":");
+ if (formers.length !== 2) {
+ throw new Error('Invalid SOCKS address format');
+ }
+ [username, password] = formers;
+ }
+ const latters = latter.split(":");
+ port = Number(latters.pop());
+ if (isNaN(port)) {
+ throw new Error('Invalid SOCKS address format');
+ }
+ hostname = latters.join(":");
+ const regex = /^\[.*\]$/;
+ if (hostname.includes(":") && !regex.test(hostname)) {
+ throw new Error('Invalid SOCKS address format');
+ }
+ //if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(hostname)) hostname = `${atob('d3d3Lg==')}${hostname}${atob('LmlwLjA5MDIyNy54eXo=')}`;
+ return {
+ username,
+ password,
+ hostname,
+ port,
+ }
+}
+
+function isValidIPv4(address) {
+ const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
+ return ipv4Regex.test(address);
+}
+
+let proxyIPPool = [];
+function subAddresses(host,pw,userAgent,newAddressesapi,newAddressescsv) {
+ addresses = addresses.concat(newAddressesapi);
+ addresses = addresses.concat(newAddressescsv);
+ // 使用Set对象去重
+ const uniqueAddresses = [...new Set(addresses)];
+
+ const responseBody = uniqueAddresses.map(address => {
+ let port = "-1";
+ let addressid = address;
+
+ const match = addressid.match(regex);
+ if (!match) {
+ if (address.includes(':') && address.includes('#')) {
+ const parts = address.split(':');
+ address = parts[0];
+ const subParts = parts[1].split('#');
+ port = subParts[0];
+ addressid = subParts[1];
+ } else if (address.includes(':')) {
+ const parts = address.split(':');
+ address = parts[0];
+ port = parts[1];
+ } else if (address.includes('#')) {
+ const parts = address.split('#');
+ address = parts[0];
+ addressid = parts[1];
+ }
+
+ if (addressid.includes(':')) {
+ addressid = addressid.split(':')[0];
+ }
+ } else {
+ address = match[1];
+ port = match[2] || port;
+ addressid = match[3] || address;
+ }
+
+ const httpsPorts = ["2053","2083","2087","2096","8443"];
+ if (!isValidIPv4(address) && port == "-1") {
+ for (let httpsPort of httpsPorts) {
+ if (address.includes(httpsPort)) {
+ port = httpsPort;
+ break;
+ }
+ }
+ }
+ if (port == "-1") port = "443";
+
+ let 伪装域名 = host ;
+ let 最终路径 = '/?ed=2560' ;
+ let 节点备注 = '';
+
+ if(proxyhosts.length > 0 && (伪装域名.includes('.workers.dev'))) {
+ 最终路径 = `/${伪装域名}${最终路径}`;
+ 伪装域名 = proxyhosts[Math.floor(Math.random() * proxyhosts.length)];
+ 节点备注 = ` 已启用临时域名中转服务,请尽快绑定自定义域!`;
+ }
+ const matchingProxyIP = proxyIPPool.find(proxyIP => proxyIP.includes(address));
+ if (matchingProxyIP) 最终路径 += `&proxyip=${matchingProxyIP}`;
+ let 密码 = pw;
+ if (!userAgent.includes('subconverter')) 密码 = encodeURIComponent(pw);
+
+ const 啥啥啥_写的这是啥啊 = 'dHJvamFu';
+ const 协议类型 = atob(啥啥啥_写的这是啥啊);
+ const trojanLink = `${协议类型}://${密码}@${address}:${port}?security=tls&sni=${伪装域名}&fp=randomized&type=ws&host=${伪装域名}&path=${encodeURIComponent(最终路径)}#${encodeURIComponent(addressid + 节点备注)}`;
+
+ return trojanLink;
+ }).join('\n');
+
+ const base64Response = btoa(responseBody); // 重新进行 Base64 编码
+
+ return base64Response;
+}
+
+async function getAddressesapi(api) {
+ if (!api || api.length === 0) return [];
+
+ let newapi = "";
+
+ // 创建一个AbortController对象,用于控制fetch请求的取消
+ const controller = new AbortController();
+
+ const timeout = setTimeout(() => {
+ controller.abort(); // 取消所有请求
+ }, 2000); // 2秒后触发
+
+ try {
+ // 使用Promise.allSettled等待所有API请求完成,无论成功或失败
+ // 对api数组进行遍历,对每个API地址发起fetch请求
+ const responses = await Promise.allSettled(api.map(apiUrl => fetch(apiUrl, {
+ method: 'get',
+ headers: {
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;',
+ 'User-Agent': atob('Q0YtV29ya2Vycy1lcGVpdXMvY21saXU=')
+ },
+ signal: controller.signal // 将AbortController的信号量添加到fetch请求中,以便于需要时可以取消请求
+ }).then(response => response.ok ? response.text() : Promise.reject())));
+
+ // 遍历所有响应
+ for (const [index, response] of responses.entries()) {
+ // 检查响应状态是否为'fulfilled',即请求成功完成
+ if (response.status === 'fulfilled') {
+ // 获取响应的内容
+ const content = await response.value;
+
+ // 验证当前apiUrl是否带有'proxyip=true'
+ if (api[index].includes('proxyip=true')) {
+ // 如果URL带有'proxyip=true',则将内容添加到proxyIPPool
+ proxyIPPool = proxyIPPool.concat((await ADD(content)).map(item => {
+ const baseItem = item.split('#')[0] || item;
+ if (baseItem.includes(':')) {
+ const port = baseItem.split(':')[1];
+ if (!httpsPorts.includes(port)) {
+ return baseItem;
+ }
+ } else {
+ return `${baseItem}:443`;
+ }
+ return null; // 不符合条件时返回 null
+ }).filter(Boolean)); // 过滤掉 null 值
+ }
+ // 将内容添加到newapi中
+ newapi += content + '\n';
+ }
+ }
+ } catch (error) {
+ console.error(error);
+ } finally {
+ // 无论成功或失败,最后都清除设置的超时定时器
+ clearTimeout(timeout);
+ }
+
+ const newAddressesapi = await ADD(newapi);
+
+ // 返回处理后的结果
+ return newAddressesapi;
+}
+
+async function getAddressescsv(tls) {
+ if (!addressescsv || addressescsv.length === 0) {
+ return [];
+ }
+
+ let newAddressescsv = [];
+
+ for (const csvUrl of addressescsv) {
+ try {
+ const response = await fetch(csvUrl);
+
+ if (!response.ok) {
+ console.error('获取CSV地址时出错:', response.status, response.statusText);
+ continue;
+ }
+
+ const text = await response.text();// 使用正确的字符编码解析文本内容
+ let lines;
+ if (text.includes('\r\n')){
+ lines = text.split('\r\n');
+ } else {
+ lines = text.split('\n');
+ }
+
+ // 检查CSV头部是否包含必需字段
+ const header = lines[0].split(',');
+ const tlsIndex = header.indexOf('TLS');
+
+ const ipAddressIndex = 0;// IP地址在 CSV 头部的位置
+ const portIndex = 1;// 端口在 CSV 头部的位置
+ const dataCenterIndex = tlsIndex + 1; // 数据中心是 TLS 的后一个字段
+
+ if (tlsIndex === -1) {
+ console.error('CSV文件缺少必需的字段');
+ continue;
+ }
+
+ // 从第二行开始遍历CSV行
+ for (let i = 1; i < lines.length; i++) {
+ const columns = lines[i].split(',');
+ const speedIndex = columns.length - 1; // 最后一个字段
+ // 检查TLS是否为"TRUE"且速度大于DLS
+ if (columns[tlsIndex].toUpperCase() === tls && parseFloat(columns[speedIndex]) > DLS) {
+ const ipAddress = columns[ipAddressIndex];
+ const port = columns[portIndex];
+ const dataCenter = columns[dataCenterIndex];
+
+ const formattedAddress = `${ipAddress}:${port}#${dataCenter}`;
+ newAddressescsv.push(formattedAddress);
+ if (csvUrl.includes('proxyip=true') && columns[tlsIndex].toUpperCase() == 'true' && !httpsPorts.includes(port)) {
+ // 如果URL带有'proxyip=true',则将内容添加到proxyIPPool
+ proxyIPPool.push(`${ipAddress}:${port}`);
+ }
+ }
+ }
+ } catch (error) {
+ console.error('获取CSV地址时出错:', error);
+ continue;
+ }
+ }
+
+ return newAddressescsv;
+}
+
+function surge(content, url) {
+ let 每行内容;
+ if (content.includes('\r\n')){
+ 每行内容 = content.split('\r\n');
+ } else {
+ 每行内容 = content.split('\n');
+ }
+
+ let 输出内容 = "";
+ for (let x of 每行内容) {
+ if (x.includes('= trojan,')) {
+ const host = x.split("sni=")[1].split(",")[0];
+ const 备改内容 = `skip-cert-verify=true, tfo=false, udp-relay=false`;
+ const 正确内容 = `skip-cert-verify=true, ws=true, ws-path=/?ed=2560, ws-headers=Host:"${host}", tfo=false, udp-relay=false`;
+ 输出内容 += x.replace(new RegExp(备改内容, 'g'), 正确内容).replace("[", "").replace("]", "") + '\n';
+ } else {
+ 输出内容 += x + '\n';
+ }
+ }
+
+ 输出内容 = `#!MANAGED-CONFIG ${url} interval=86400 strict=false` + 输出内容.substring(输出内容.indexOf('\n'));
+ return 输出内容;
+}
+
+/**
* [js-sha256]{@link https://github.com/emn178/js-sha256}
*
* @version 0.11.0
@@ -58,4 +1302,526 @@ const _0x2751a8=_0x1cb6;function _0x8aa5(){const _0x31c850=['/sub?target=singbox
* @copyright Chen, Yi-Cyuan 2014-2024
* @license MIT
*/
-(function(){'use strict';const _0x43d3a7=_0x2751a8;var _0x427cd9=_0x43d3a7(0x142),_0x51e73e=typeof window===_0x43d3a7(0x1c5),_0x38e2e8=_0x51e73e?window:{};_0x38e2e8['JS_SHA256_NO_WINDOW']&&(_0x51e73e=![]);var _0x4e8be7=!_0x51e73e&&typeof self===_0x43d3a7(0x1c5),_0x402200=!_0x38e2e8['JS_SHA256_NO_NODE_JS']&&typeof process===_0x43d3a7(0x1c5)&&process['versions']&&process['versions'][_0x43d3a7(0xdc)];if(_0x402200)_0x38e2e8=global;else _0x4e8be7&&(_0x38e2e8=self);var _0x5d9596=!_0x38e2e8[_0x43d3a7(0x12d)]&&typeof module==='object'&&module[_0x43d3a7(0x1b2)],_0x520679=typeof define==='function'&&define[_0x43d3a7(0xe1)],_0xef50b7=!_0x38e2e8[_0x43d3a7(0xdb)]&&typeof ArrayBuffer!==_0x43d3a7(0xba),_0x59a329='0123456789abcdef'['split'](''),_0x1d77ac=[-0x80000000,0x800000,0x8000,0x80],_0x2eb701=[0x18,0x10,0x8,0x0],_0x2dd3e4=[0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0xfc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x6ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2],_0x1c8a8b=[_0x43d3a7(0x1c7),_0x43d3a7(0x11c),_0x43d3a7(0x188),'arrayBuffer'],_0x3431b4=[];(_0x38e2e8['JS_SHA256_NO_NODE_JS']||!Array['isArray'])&&(Array[_0x43d3a7(0x125)]=function(_0x1d6745){const _0x423937=_0x43d3a7;return Object[_0x423937(0x18e)][_0x423937(0x14c)][_0x423937(0xd5)](_0x1d6745)===_0x423937(0x14b);});_0xef50b7&&(_0x38e2e8['JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW']||!ArrayBuffer[_0x43d3a7(0x12c)])&&(ArrayBuffer['isView']=function(_0x17d8c9){const _0x290e42=_0x43d3a7;return typeof _0x17d8c9===_0x290e42(0x1c5)&&_0x17d8c9[_0x290e42(0x1c8)]&&_0x17d8c9['buffer'][_0x290e42(0x15d)]===ArrayBuffer;});var _0x13be1b=function(_0x4b8f18,_0x248f6d){return function(_0x48be71){const _0x5df7a0=_0x1cb6;return new _0x417bc8(_0x248f6d,!![])[_0x5df7a0(0x158)](_0x48be71)[_0x4b8f18]();};},_0x2b41df=function(_0x2a0af2){var _0x106ed5=_0x13be1b('hex',_0x2a0af2);_0x402200&&(_0x106ed5=_0x2c955e(_0x106ed5,_0x2a0af2));_0x106ed5['create']=function(){return new _0x417bc8(_0x2a0af2);},_0x106ed5['update']=function(_0x624676){const _0x108e02=_0x1cb6;return _0x106ed5['create']()[_0x108e02(0x158)](_0x624676);};for(var _0x4b92e8=0x0;_0x4b92e8<_0x1c8a8b['length'];++_0x4b92e8){var _0xfea8fe=_0x1c8a8b[_0x4b92e8];_0x106ed5[_0xfea8fe]=_0x13be1b(_0xfea8fe,_0x2a0af2);}return _0x106ed5;},_0x2c955e=function(_0xb91316,_0x1eaa59){const _0x421560=_0x43d3a7;var _0x2d01da=require(_0x421560(0x1e8)),_0x3cd303=require(_0x421560(0x1c8))[_0x421560(0x1b3)],_0x2c3363=_0x1eaa59?'sha224':_0x421560(0x13e),_0x4e3c00;_0x3cd303[_0x421560(0x1d1)]&&!_0x38e2e8[_0x421560(0x1dd)]?_0x4e3c00=_0x3cd303['from']:_0x4e3c00=function(_0x196db7){return new _0x3cd303(_0x196db7);};var _0x125677=function(_0x50624f){const _0x3a31fa=_0x421560;if(typeof _0x50624f===_0x3a31fa(0x1e3))return _0x2d01da['createHash'](_0x2c3363)[_0x3a31fa(0x158)](_0x50624f,_0x3a31fa(0xbc))['digest'](_0x3a31fa(0x1c7));else{if(_0x50624f===null||_0x50624f===undefined)throw new Error(_0x427cd9);else _0x50624f[_0x3a31fa(0x15d)]===ArrayBuffer&&(_0x50624f=new Uint8Array(_0x50624f));}return Array[_0x3a31fa(0x125)](_0x50624f)||ArrayBuffer[_0x3a31fa(0x12c)](_0x50624f)||_0x50624f[_0x3a31fa(0x15d)]===_0x3cd303?_0x2d01da[_0x3a31fa(0xa9)](_0x2c3363)[_0x3a31fa(0x158)](_0x4e3c00(_0x50624f))[_0x3a31fa(0x188)](_0x3a31fa(0x1c7)):_0xb91316(_0x50624f);};return _0x125677;},_0x5a9d6a=function(_0x3688ad,_0x4da58b){return function(_0x2b82d3,_0x1cb325){return new _0x11e336(_0x2b82d3,_0x4da58b,!![])['update'](_0x1cb325)[_0x3688ad]();};},_0x7a8f90=function(_0x3ca4c){const _0x3c4ba9=_0x43d3a7;var _0x178a5e=_0x5a9d6a('hex',_0x3ca4c);_0x178a5e[_0x3c4ba9(0xcc)]=function(_0x3437df){return new _0x11e336(_0x3437df,_0x3ca4c);},_0x178a5e[_0x3c4ba9(0x158)]=function(_0x465cc6,_0x1379c5){const _0x2f33de=_0x3c4ba9;return _0x178a5e[_0x2f33de(0xcc)](_0x465cc6)[_0x2f33de(0x158)](_0x1379c5);};for(var _0xb39d71=0x0;_0xb39d71<_0x1c8a8b[_0x3c4ba9(0x145)];++_0xb39d71){var _0x26f424=_0x1c8a8b[_0xb39d71];_0x178a5e[_0x26f424]=_0x5a9d6a(_0x26f424,_0x3ca4c);}return _0x178a5e;};function _0x417bc8(_0x15a5a6,_0x134ea1){const _0x2b4f16=_0x43d3a7;_0x134ea1?(_0x3431b4[0x0]=_0x3431b4[0x10]=_0x3431b4[0x1]=_0x3431b4[0x2]=_0x3431b4[0x3]=_0x3431b4[0x4]=_0x3431b4[0x5]=_0x3431b4[0x6]=_0x3431b4[0x7]=_0x3431b4[0x8]=_0x3431b4[0x9]=_0x3431b4[0xa]=_0x3431b4[0xb]=_0x3431b4[0xc]=_0x3431b4[0xd]=_0x3431b4[0xe]=_0x3431b4[0xf]=0x0,this[_0x2b4f16(0x123)]=_0x3431b4):this[_0x2b4f16(0x123)]=[0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0],_0x15a5a6?(this['h0']=0xc1059ed8,this['h1']=0x367cd507,this['h2']=0x3070dd17,this['h3']=0xf70e5939,this['h4']=0xffc00b31,this['h5']=0x68581511,this['h6']=0x64f98fa7,this['h7']=0xbefa4fa4):(this['h0']=0x6a09e667,this['h1']=0xbb67ae85,this['h2']=0x3c6ef372,this['h3']=0xa54ff53a,this['h4']=0x510e527f,this['h5']=0x9b05688c,this['h6']=0x1f83d9ab,this['h7']=0x5be0cd19),this[_0x2b4f16(0x162)]=this['start']=this[_0x2b4f16(0xf8)]=this[_0x2b4f16(0xfd)]=0x0,this[_0x2b4f16(0xeb)]=this[_0x2b4f16(0x1d2)]=![],this['first']=!![],this[_0x2b4f16(0x1c3)]=_0x15a5a6;}_0x417bc8[_0x43d3a7(0x18e)][_0x43d3a7(0x158)]=function(_0x4c8149){const _0x4b1f5f=_0x43d3a7;if(this['finalized'])return;var _0x1d0008,_0x3a924f=typeof _0x4c8149;if(_0x3a924f!=='string'){if(_0x3a924f===_0x4b1f5f(0x1c5)){if(_0x4c8149===null)throw new Error(_0x427cd9);else{if(_0xef50b7&&_0x4c8149[_0x4b1f5f(0x15d)]===ArrayBuffer)_0x4c8149=new Uint8Array(_0x4c8149);else{if(!Array[_0x4b1f5f(0x125)](_0x4c8149)){if(!_0xef50b7||!ArrayBuffer[_0x4b1f5f(0x12c)](_0x4c8149))throw new Error(_0x427cd9);}}}}else throw new Error(_0x427cd9);_0x1d0008=!![];}var _0x4d7364,_0x1c8440=0x0,_0x252433,_0xba56c2=_0x4c8149[_0x4b1f5f(0x145)],_0x3053bc=this['blocks'];while(_0x1c8440<_0xba56c2){this[_0x4b1f5f(0x1d2)]&&(this[_0x4b1f5f(0x1d2)]=![],_0x3053bc[0x0]=this[_0x4b1f5f(0x162)],this[_0x4b1f5f(0x162)]=_0x3053bc[0x10]=_0x3053bc[0x1]=_0x3053bc[0x2]=_0x3053bc[0x3]=_0x3053bc[0x4]=_0x3053bc[0x5]=_0x3053bc[0x6]=_0x3053bc[0x7]=_0x3053bc[0x8]=_0x3053bc[0x9]=_0x3053bc[0xa]=_0x3053bc[0xb]=_0x3053bc[0xc]=_0x3053bc[0xd]=_0x3053bc[0xe]=_0x3053bc[0xf]=0x0);if(_0x1d0008)for(_0x252433=this['start'];_0x1c8440<_0xba56c2&&_0x252433<0x40;++_0x1c8440){_0x3053bc[_0x252433>>>0x2]|=_0x4c8149[_0x1c8440]<<_0x2eb701[_0x252433++&0x3];}else for(_0x252433=this[_0x4b1f5f(0x17f)];_0x1c8440<_0xba56c2&&_0x252433<0x40;++_0x1c8440){_0x4d7364=_0x4c8149[_0x4b1f5f(0x11b)](_0x1c8440);if(_0x4d7364<0x80)_0x3053bc[_0x252433>>>0x2]|=_0x4d7364<<_0x2eb701[_0x252433++&0x3];else{if(_0x4d7364<0x800)_0x3053bc[_0x252433>>>0x2]|=(0xc0|_0x4d7364>>>0x6)<<_0x2eb701[_0x252433++&0x3],_0x3053bc[_0x252433>>>0x2]|=(0x80|_0x4d7364&0x3f)<<_0x2eb701[_0x252433++&0x3];else _0x4d7364<0xd800||_0x4d7364>=0xe000?(_0x3053bc[_0x252433>>>0x2]|=(0xe0|_0x4d7364>>>0xc)<<_0x2eb701[_0x252433++&0x3],_0x3053bc[_0x252433>>>0x2]|=(0x80|_0x4d7364>>>0x6&0x3f)<<_0x2eb701[_0x252433++&0x3],_0x3053bc[_0x252433>>>0x2]|=(0x80|_0x4d7364&0x3f)<<_0x2eb701[_0x252433++&0x3]):(_0x4d7364=0x10000+((_0x4d7364&0x3ff)<<0xa|_0x4c8149[_0x4b1f5f(0x11b)](++_0x1c8440)&0x3ff),_0x3053bc[_0x252433>>>0x2]|=(0xf0|_0x4d7364>>>0x12)<<_0x2eb701[_0x252433++&0x3],_0x3053bc[_0x252433>>>0x2]|=(0x80|_0x4d7364>>>0xc&0x3f)<<_0x2eb701[_0x252433++&0x3],_0x3053bc[_0x252433>>>0x2]|=(0x80|_0x4d7364>>>0x6&0x3f)<<_0x2eb701[_0x252433++&0x3],_0x3053bc[_0x252433>>>0x2]|=(0x80|_0x4d7364&0x3f)<<_0x2eb701[_0x252433++&0x3]);}}this[_0x4b1f5f(0x13a)]=_0x252433,this[_0x4b1f5f(0xf8)]+=_0x252433-this[_0x4b1f5f(0x17f)],_0x252433>=0x40?(this['block']=_0x3053bc[0x10],this[_0x4b1f5f(0x17f)]=_0x252433-0x40,this[_0x4b1f5f(0x1d9)](),this[_0x4b1f5f(0x1d2)]=!![]):this[_0x4b1f5f(0x17f)]=_0x252433;}return this[_0x4b1f5f(0xf8)]>0xffffffff&&(this[_0x4b1f5f(0xfd)]+=this[_0x4b1f5f(0xf8)]/0x100000000<<0x0,this[_0x4b1f5f(0xf8)]=this['bytes']%0x100000000),this;},_0x417bc8[_0x43d3a7(0x18e)]['finalize']=function(){const _0x13cfa4=_0x43d3a7;if(this[_0x13cfa4(0xeb)])return;this['finalized']=!![];var _0x11c652=this['blocks'],_0x5bc872=this['lastByteIndex'];_0x11c652[0x10]=this[_0x13cfa4(0x162)],_0x11c652[_0x5bc872>>>0x2]|=_0x1d77ac[_0x5bc872&0x3],this[_0x13cfa4(0x162)]=_0x11c652[0x10],_0x5bc872>=0x38&&(!this['hashed']&&this['hash'](),_0x11c652[0x0]=this[_0x13cfa4(0x162)],_0x11c652[0x10]=_0x11c652[0x1]=_0x11c652[0x2]=_0x11c652[0x3]=_0x11c652[0x4]=_0x11c652[0x5]=_0x11c652[0x6]=_0x11c652[0x7]=_0x11c652[0x8]=_0x11c652[0x9]=_0x11c652[0xa]=_0x11c652[0xb]=_0x11c652[0xc]=_0x11c652[0xd]=_0x11c652[0xe]=_0x11c652[0xf]=0x0),_0x11c652[0xe]=this[_0x13cfa4(0xfd)]<<0x3|this['bytes']>>>0x1d,_0x11c652[0xf]=this['bytes']<<0x3,this[_0x13cfa4(0x1d9)]();},_0x417bc8[_0x43d3a7(0x18e)][_0x43d3a7(0x1d9)]=function(){const _0x3fa08f=_0x43d3a7;var _0x51e426=this['h0'],_0x53b363=this['h1'],_0x48dd62=this['h2'],_0x40d72e=this['h3'],_0x59801f=this['h4'],_0x3d4aa6=this['h5'],_0x4ba560=this['h6'],_0x15c42c=this['h7'],_0x50c13e=this['blocks'],_0x386c37,_0x8c0423,_0x37dcc0,_0x48c5af,_0x24d60e,_0x240219,_0x3c3fab,_0x3e080d,_0xebeeb5,_0x2839b2,_0x56d276;for(_0x386c37=0x10;_0x386c37<0x40;++_0x386c37){_0x24d60e=_0x50c13e[_0x386c37-0xf],_0x8c0423=(_0x24d60e>>>0x7|_0x24d60e<<0x19)^(_0x24d60e>>>0x12|_0x24d60e<<0xe)^_0x24d60e>>>0x3,_0x24d60e=_0x50c13e[_0x386c37-0x2],_0x37dcc0=(_0x24d60e>>>0x11|_0x24d60e<<0xf)^(_0x24d60e>>>0x13|_0x24d60e<<0xd)^_0x24d60e>>>0xa,_0x50c13e[_0x386c37]=_0x50c13e[_0x386c37-0x10]+_0x8c0423+_0x50c13e[_0x386c37-0x7]+_0x37dcc0<<0x0;}_0x56d276=_0x53b363&_0x48dd62;for(_0x386c37=0x0;_0x386c37<0x40;_0x386c37+=0x4){this['first']?(this[_0x3fa08f(0x1c3)]?(_0x3e080d=0x49400,_0x24d60e=_0x50c13e[0x0]-0x543c9a5b,_0x15c42c=_0x24d60e-0x8f1a6c7<<0x0,_0x40d72e=_0x24d60e+0x170e9b5<<0x0):(_0x3e080d=0x2a01a605,_0x24d60e=_0x50c13e[0x0]-0xc881298,_0x15c42c=_0x24d60e-0x5ab00ac6<<0x0,_0x40d72e=_0x24d60e+0x8909ae5<<0x0),this[_0x3fa08f(0xf7)]=![]):(_0x8c0423=(_0x51e426>>>0x2|_0x51e426<<0x1e)^(_0x51e426>>>0xd|_0x51e426<<0x13)^(_0x51e426>>>0x16|_0x51e426<<0xa),_0x37dcc0=(_0x59801f>>>0x6|_0x59801f<<0x1a)^(_0x59801f>>>0xb|_0x59801f<<0x15)^(_0x59801f>>>0x19|_0x59801f<<0x7),_0x3e080d=_0x51e426&_0x53b363,_0x48c5af=_0x3e080d^_0x51e426&_0x48dd62^_0x56d276,_0x3c3fab=_0x59801f&_0x3d4aa6^~_0x59801f&_0x4ba560,_0x24d60e=_0x15c42c+_0x37dcc0+_0x3c3fab+_0x2dd3e4[_0x386c37]+_0x50c13e[_0x386c37],_0x240219=_0x8c0423+_0x48c5af,_0x15c42c=_0x40d72e+_0x24d60e<<0x0,_0x40d72e=_0x24d60e+_0x240219<<0x0),_0x8c0423=(_0x40d72e>>>0x2|_0x40d72e<<0x1e)^(_0x40d72e>>>0xd|_0x40d72e<<0x13)^(_0x40d72e>>>0x16|_0x40d72e<<0xa),_0x37dcc0=(_0x15c42c>>>0x6|_0x15c42c<<0x1a)^(_0x15c42c>>>0xb|_0x15c42c<<0x15)^(_0x15c42c>>>0x19|_0x15c42c<<0x7),_0xebeeb5=_0x40d72e&_0x51e426,_0x48c5af=_0xebeeb5^_0x40d72e&_0x53b363^_0x3e080d,_0x3c3fab=_0x15c42c&_0x59801f^~_0x15c42c&_0x3d4aa6,_0x24d60e=_0x4ba560+_0x37dcc0+_0x3c3fab+_0x2dd3e4[_0x386c37+0x1]+_0x50c13e[_0x386c37+0x1],_0x240219=_0x8c0423+_0x48c5af,_0x4ba560=_0x48dd62+_0x24d60e<<0x0,_0x48dd62=_0x24d60e+_0x240219<<0x0,_0x8c0423=(_0x48dd62>>>0x2|_0x48dd62<<0x1e)^(_0x48dd62>>>0xd|_0x48dd62<<0x13)^(_0x48dd62>>>0x16|_0x48dd62<<0xa),_0x37dcc0=(_0x4ba560>>>0x6|_0x4ba560<<0x1a)^(_0x4ba560>>>0xb|_0x4ba560<<0x15)^(_0x4ba560>>>0x19|_0x4ba560<<0x7),_0x2839b2=_0x48dd62&_0x40d72e,_0x48c5af=_0x2839b2^_0x48dd62&_0x51e426^_0xebeeb5,_0x3c3fab=_0x4ba560&_0x15c42c^~_0x4ba560&_0x59801f,_0x24d60e=_0x3d4aa6+_0x37dcc0+_0x3c3fab+_0x2dd3e4[_0x386c37+0x2]+_0x50c13e[_0x386c37+0x2],_0x240219=_0x8c0423+_0x48c5af,_0x3d4aa6=_0x53b363+_0x24d60e<<0x0,_0x53b363=_0x24d60e+_0x240219<<0x0,_0x8c0423=(_0x53b363>>>0x2|_0x53b363<<0x1e)^(_0x53b363>>>0xd|_0x53b363<<0x13)^(_0x53b363>>>0x16|_0x53b363<<0xa),_0x37dcc0=(_0x3d4aa6>>>0x6|_0x3d4aa6<<0x1a)^(_0x3d4aa6>>>0xb|_0x3d4aa6<<0x15)^(_0x3d4aa6>>>0x19|_0x3d4aa6<<0x7),_0x56d276=_0x53b363&_0x48dd62,_0x48c5af=_0x56d276^_0x53b363&_0x40d72e^_0x2839b2,_0x3c3fab=_0x3d4aa6&_0x4ba560^~_0x3d4aa6&_0x15c42c,_0x24d60e=_0x59801f+_0x37dcc0+_0x3c3fab+_0x2dd3e4[_0x386c37+0x3]+_0x50c13e[_0x386c37+0x3],_0x240219=_0x8c0423+_0x48c5af,_0x59801f=_0x51e426+_0x24d60e<<0x0,_0x51e426=_0x24d60e+_0x240219<<0x0,this[_0x3fa08f(0xe5)]=!![];}this['h0']=this['h0']+_0x51e426<<0x0,this['h1']=this['h1']+_0x53b363<<0x0,this['h2']=this['h2']+_0x48dd62<<0x0,this['h3']=this['h3']+_0x40d72e<<0x0,this['h4']=this['h4']+_0x59801f<<0x0,this['h5']=this['h5']+_0x3d4aa6<<0x0,this['h6']=this['h6']+_0x4ba560<<0x0,this['h7']=this['h7']+_0x15c42c<<0x0;},_0x417bc8[_0x43d3a7(0x18e)][_0x43d3a7(0x1c7)]=function(){const _0x406b39=_0x43d3a7;this[_0x406b39(0xc2)]();var _0x580836=this['h0'],_0x5448b4=this['h1'],_0x17532b=this['h2'],_0x571f70=this['h3'],_0x4c4fa3=this['h4'],_0x40e153=this['h5'],_0x3a28be=this['h6'],_0x4eeebf=this['h7'],_0xd987d9=_0x59a329[_0x580836>>>0x1c&0xf]+_0x59a329[_0x580836>>>0x18&0xf]+_0x59a329[_0x580836>>>0x14&0xf]+_0x59a329[_0x580836>>>0x10&0xf]+_0x59a329[_0x580836>>>0xc&0xf]+_0x59a329[_0x580836>>>0x8&0xf]+_0x59a329[_0x580836>>>0x4&0xf]+_0x59a329[_0x580836&0xf]+_0x59a329[_0x5448b4>>>0x1c&0xf]+_0x59a329[_0x5448b4>>>0x18&0xf]+_0x59a329[_0x5448b4>>>0x14&0xf]+_0x59a329[_0x5448b4>>>0x10&0xf]+_0x59a329[_0x5448b4>>>0xc&0xf]+_0x59a329[_0x5448b4>>>0x8&0xf]+_0x59a329[_0x5448b4>>>0x4&0xf]+_0x59a329[_0x5448b4&0xf]+_0x59a329[_0x17532b>>>0x1c&0xf]+_0x59a329[_0x17532b>>>0x18&0xf]+_0x59a329[_0x17532b>>>0x14&0xf]+_0x59a329[_0x17532b>>>0x10&0xf]+_0x59a329[_0x17532b>>>0xc&0xf]+_0x59a329[_0x17532b>>>0x8&0xf]+_0x59a329[_0x17532b>>>0x4&0xf]+_0x59a329[_0x17532b&0xf]+_0x59a329[_0x571f70>>>0x1c&0xf]+_0x59a329[_0x571f70>>>0x18&0xf]+_0x59a329[_0x571f70>>>0x14&0xf]+_0x59a329[_0x571f70>>>0x10&0xf]+_0x59a329[_0x571f70>>>0xc&0xf]+_0x59a329[_0x571f70>>>0x8&0xf]+_0x59a329[_0x571f70>>>0x4&0xf]+_0x59a329[_0x571f70&0xf]+_0x59a329[_0x4c4fa3>>>0x1c&0xf]+_0x59a329[_0x4c4fa3>>>0x18&0xf]+_0x59a329[_0x4c4fa3>>>0x14&0xf]+_0x59a329[_0x4c4fa3>>>0x10&0xf]+_0x59a329[_0x4c4fa3>>>0xc&0xf]+_0x59a329[_0x4c4fa3>>>0x8&0xf]+_0x59a329[_0x4c4fa3>>>0x4&0xf]+_0x59a329[_0x4c4fa3&0xf]+_0x59a329[_0x40e153>>>0x1c&0xf]+_0x59a329[_0x40e153>>>0x18&0xf]+_0x59a329[_0x40e153>>>0x14&0xf]+_0x59a329[_0x40e153>>>0x10&0xf]+_0x59a329[_0x40e153>>>0xc&0xf]+_0x59a329[_0x40e153>>>0x8&0xf]+_0x59a329[_0x40e153>>>0x4&0xf]+_0x59a329[_0x40e153&0xf]+_0x59a329[_0x3a28be>>>0x1c&0xf]+_0x59a329[_0x3a28be>>>0x18&0xf]+_0x59a329[_0x3a28be>>>0x14&0xf]+_0x59a329[_0x3a28be>>>0x10&0xf]+_0x59a329[_0x3a28be>>>0xc&0xf]+_0x59a329[_0x3a28be>>>0x8&0xf]+_0x59a329[_0x3a28be>>>0x4&0xf]+_0x59a329[_0x3a28be&0xf];return!this[_0x406b39(0x1c3)]&&(_0xd987d9+=_0x59a329[_0x4eeebf>>>0x1c&0xf]+_0x59a329[_0x4eeebf>>>0x18&0xf]+_0x59a329[_0x4eeebf>>>0x14&0xf]+_0x59a329[_0x4eeebf>>>0x10&0xf]+_0x59a329[_0x4eeebf>>>0xc&0xf]+_0x59a329[_0x4eeebf>>>0x8&0xf]+_0x59a329[_0x4eeebf>>>0x4&0xf]+_0x59a329[_0x4eeebf&0xf]),_0xd987d9;},_0x417bc8[_0x43d3a7(0x18e)]['toString']=_0x417bc8[_0x43d3a7(0x18e)][_0x43d3a7(0x1c7)],_0x417bc8['prototype'][_0x43d3a7(0x188)]=function(){const _0x605eb9=_0x43d3a7;this[_0x605eb9(0xc2)]();var _0x204f26=this['h0'],_0xe4d16d=this['h1'],_0x3eeaab=this['h2'],_0x260448=this['h3'],_0x117ed8=this['h4'],_0x3f7990=this['h5'],_0x54333e=this['h6'],_0x49da47=this['h7'],_0xdd0927=[_0x204f26>>>0x18&0xff,_0x204f26>>>0x10&0xff,_0x204f26>>>0x8&0xff,_0x204f26&0xff,_0xe4d16d>>>0x18&0xff,_0xe4d16d>>>0x10&0xff,_0xe4d16d>>>0x8&0xff,_0xe4d16d&0xff,_0x3eeaab>>>0x18&0xff,_0x3eeaab>>>0x10&0xff,_0x3eeaab>>>0x8&0xff,_0x3eeaab&0xff,_0x260448>>>0x18&0xff,_0x260448>>>0x10&0xff,_0x260448>>>0x8&0xff,_0x260448&0xff,_0x117ed8>>>0x18&0xff,_0x117ed8>>>0x10&0xff,_0x117ed8>>>0x8&0xff,_0x117ed8&0xff,_0x3f7990>>>0x18&0xff,_0x3f7990>>>0x10&0xff,_0x3f7990>>>0x8&0xff,_0x3f7990&0xff,_0x54333e>>>0x18&0xff,_0x54333e>>>0x10&0xff,_0x54333e>>>0x8&0xff,_0x54333e&0xff];return!this[_0x605eb9(0x1c3)]&&_0xdd0927['push'](_0x49da47>>>0x18&0xff,_0x49da47>>>0x10&0xff,_0x49da47>>>0x8&0xff,_0x49da47&0xff),_0xdd0927;},_0x417bc8[_0x43d3a7(0x18e)][_0x43d3a7(0x11c)]=_0x417bc8[_0x43d3a7(0x18e)]['digest'],_0x417bc8[_0x43d3a7(0x18e)][_0x43d3a7(0x1ce)]=function(){const _0xe25e61=_0x43d3a7;this['finalize']();var _0x1ff29e=new ArrayBuffer(this['is224']?0x1c:0x20),_0x2cb71d=new DataView(_0x1ff29e);return _0x2cb71d['setUint32'](0x0,this['h0']),_0x2cb71d['setUint32'](0x4,this['h1']),_0x2cb71d[_0xe25e61(0x1a0)](0x8,this['h2']),_0x2cb71d[_0xe25e61(0x1a0)](0xc,this['h3']),_0x2cb71d['setUint32'](0x10,this['h4']),_0x2cb71d[_0xe25e61(0x1a0)](0x14,this['h5']),_0x2cb71d['setUint32'](0x18,this['h6']),!this[_0xe25e61(0x1c3)]&&_0x2cb71d['setUint32'](0x1c,this['h7']),_0x1ff29e;};function _0x11e336(_0x1e94e9,_0x4bd775,_0x34ec2b){const _0x37723b=_0x43d3a7;var _0x3d9ad2,_0x500db1=typeof _0x1e94e9;if(_0x500db1===_0x37723b(0x1e3)){var _0x553231=[],_0x1347b2=_0x1e94e9[_0x37723b(0x145)],_0x4fa55a=0x0,_0x538d2a;for(_0x3d9ad2=0x0;_0x3d9ad2<_0x1347b2;++_0x3d9ad2){_0x538d2a=_0x1e94e9[_0x37723b(0x11b)](_0x3d9ad2);if(_0x538d2a<0x80)_0x553231[_0x4fa55a++]=_0x538d2a;else{if(_0x538d2a<0x800)_0x553231[_0x4fa55a++]=0xc0|_0x538d2a>>>0x6,_0x553231[_0x4fa55a++]=0x80|_0x538d2a&0x3f;else _0x538d2a<0xd800||_0x538d2a>=0xe000?(_0x553231[_0x4fa55a++]=0xe0|_0x538d2a>>>0xc,_0x553231[_0x4fa55a++]=0x80|_0x538d2a>>>0x6&0x3f,_0x553231[_0x4fa55a++]=0x80|_0x538d2a&0x3f):(_0x538d2a=0x10000+((_0x538d2a&0x3ff)<<0xa|_0x1e94e9[_0x37723b(0x11b)](++_0x3d9ad2)&0x3ff),_0x553231[_0x4fa55a++]=0xf0|_0x538d2a>>>0x12,_0x553231[_0x4fa55a++]=0x80|_0x538d2a>>>0xc&0x3f,_0x553231[_0x4fa55a++]=0x80|_0x538d2a>>>0x6&0x3f,_0x553231[_0x4fa55a++]=0x80|_0x538d2a&0x3f);}}_0x1e94e9=_0x553231;}else{if(_0x500db1===_0x37723b(0x1c5)){if(_0x1e94e9===null)throw new Error(_0x427cd9);else{if(_0xef50b7&&_0x1e94e9[_0x37723b(0x15d)]===ArrayBuffer)_0x1e94e9=new Uint8Array(_0x1e94e9);else{if(!Array['isArray'](_0x1e94e9)){if(!_0xef50b7||!ArrayBuffer[_0x37723b(0x12c)](_0x1e94e9))throw new Error(_0x427cd9);}}}}else throw new Error(_0x427cd9);}_0x1e94e9['length']>0x40&&(_0x1e94e9=new _0x417bc8(_0x4bd775,!![])[_0x37723b(0x158)](_0x1e94e9)['array']());var _0x371378=[],_0x287983=[];for(_0x3d9ad2=0x0;_0x3d9ad2<0x40;++_0x3d9ad2){var _0x45e154=_0x1e94e9[_0x3d9ad2]||0x0;_0x371378[_0x3d9ad2]=0x5c^_0x45e154,_0x287983[_0x3d9ad2]=0x36^_0x45e154;}_0x417bc8[_0x37723b(0xd5)](this,_0x4bd775,_0x34ec2b),this[_0x37723b(0x158)](_0x287983),this[_0x37723b(0x18c)]=_0x371378,this[_0x37723b(0xad)]=!![],this[_0x37723b(0x101)]=_0x34ec2b;}_0x11e336[_0x43d3a7(0x18e)]=new _0x417bc8(),_0x11e336[_0x43d3a7(0x18e)][_0x43d3a7(0xc2)]=function(){const _0x2f9bc2=_0x43d3a7;_0x417bc8[_0x2f9bc2(0x18e)][_0x2f9bc2(0xc2)][_0x2f9bc2(0xd5)](this);if(this['inner']){this[_0x2f9bc2(0xad)]=![];var _0x17a026=this[_0x2f9bc2(0x11c)]();_0x417bc8['call'](this,this[_0x2f9bc2(0x1c3)],this[_0x2f9bc2(0x101)]),this[_0x2f9bc2(0x158)](this[_0x2f9bc2(0x18c)]),this['update'](_0x17a026),_0x417bc8['prototype']['finalize'][_0x2f9bc2(0xd5)](this);}};var _0x2a6e96=_0x2b41df();_0x2a6e96['sha256']=_0x2a6e96,_0x2a6e96['sha224']=_0x2b41df(!![]),_0x2a6e96['sha256'][_0x43d3a7(0x1a3)]=_0x7a8f90(),_0x2a6e96[_0x43d3a7(0x14a)]['hmac']=_0x7a8f90(!![]),_0x5d9596?module['exports']=_0x2a6e96:(_0x38e2e8[_0x43d3a7(0x13e)]=_0x2a6e96[_0x43d3a7(0x13e)],_0x38e2e8[_0x43d3a7(0x14a)]=_0x2a6e96[_0x43d3a7(0x14a)],_0x520679&&define(function(){return _0x2a6e96;}));}());async function socks5Connect(_0x220817,_0xe3d6c4,_0x532295,_0x234ec5){const _0x414b67=_0x2751a8,{username:_0x5e6914,password:_0x559185,hostname:_0x2d8d99,port:_0x234a00}=parsedSocks5Address,_0x4b30c6=connect({'hostname':_0x2d8d99,'port':_0x234a00}),_0xce3cfd=new Uint8Array([0x5,0x2,0x0,0x2]),_0x571feb=_0x4b30c6[_0x414b67(0x15c)][_0x414b67(0xd4)]();await _0x571feb[_0x414b67(0x1e7)](_0xce3cfd),_0x234ec5(_0x414b67(0x13b));const _0x524b01=_0x4b30c6[_0x414b67(0x16a)][_0x414b67(0x103)](),_0x1ac670=new TextEncoder();let _0x53216e=(await _0x524b01[_0x414b67(0x1bc)]())[_0x414b67(0xe6)];if(_0x53216e[0x0]!==0x5){_0x234ec5(_0x414b67(0xe9)+_0x53216e[0x0]+_0x414b67(0xff));return;}if(_0x53216e[0x1]===0xff){_0x234ec5('no\x20acceptable\x20methods');return;}if(_0x53216e[0x1]===0x2){_0x234ec5(_0x414b67(0x143));if(!_0x5e6914||!_0x559185){_0x234ec5(_0x414b67(0x1c0));return;}const _0x45ba29=new Uint8Array([0x1,_0x5e6914[_0x414b67(0x145)],..._0x1ac670[_0x414b67(0x1df)](_0x5e6914),_0x559185[_0x414b67(0x145)],..._0x1ac670[_0x414b67(0x1df)](_0x559185)]);await _0x571feb[_0x414b67(0x1e7)](_0x45ba29),_0x53216e=(await _0x524b01['read']())[_0x414b67(0xe6)];if(_0x53216e[0x0]!==0x1||_0x53216e[0x1]!==0x0){_0x234ec5(_0x414b67(0xda));return;}}let _0x43b392;switch(_0x220817){case 0x1:_0x43b392=new Uint8Array([0x1,..._0xe3d6c4[_0x414b67(0x16e)]('.')[_0x414b67(0x114)](Number)]);break;case 0x3:_0x43b392=new Uint8Array([0x3,_0xe3d6c4[_0x414b67(0x145)],..._0x1ac670[_0x414b67(0x1df)](_0xe3d6c4)]);break;case 0x4:_0x43b392=new Uint8Array([0x4,..._0xe3d6c4['split'](':')[_0x414b67(0xb7)](_0x1def7f=>[parseInt(_0x1def7f[_0x414b67(0x181)](0x0,0x2),0x10),parseInt(_0x1def7f[_0x414b67(0x181)](0x2),0x10)])]);break;default:_0x234ec5(_0x414b67(0x1e0)+_0x220817);return;}const _0x2cde29=new Uint8Array([0x5,0x1,0x0,..._0x43b392,_0x532295>>0x8,_0x532295&0xff]);await _0x571feb['write'](_0x2cde29),_0x234ec5(_0x414b67(0x16f)),_0x53216e=(await _0x524b01[_0x414b67(0x1bc)]())['value'];if(_0x53216e[0x1]===0x0)_0x234ec5('socks\x20connection\x20opened');else{_0x234ec5(_0x414b67(0xf6));return;}return _0x571feb[_0x414b67(0x190)](),_0x524b01[_0x414b67(0x190)](),_0x4b30c6;}function socks5AddressParser(_0x6e32cd){const _0x105268=_0x2751a8;let [_0x1c7a32,_0x55655b]=_0x6e32cd['split']('@')[_0x105268(0x196)](),_0xa9a886,_0x7296ef,_0x462f36,_0x3a5a9d;if(_0x55655b){const _0x21aac5=_0x55655b[_0x105268(0x16e)](':');if(_0x21aac5[_0x105268(0x145)]!==0x2)throw new Error(_0x105268(0xe2));[_0xa9a886,_0x7296ef]=_0x21aac5;}const _0x46180e=_0x1c7a32[_0x105268(0x16e)](':');_0x3a5a9d=Number(_0x46180e[_0x105268(0x1b7)]());if(isNaN(_0x3a5a9d))throw new Error('Invalid\x20SOCKS\x20address\x20format');_0x462f36=_0x46180e[_0x105268(0x168)](':');const _0x58cdc=/^\[.*\]$/;if(_0x462f36[_0x105268(0xc8)](':')&&!_0x58cdc[_0x105268(0xb8)](_0x462f36))throw new Error(_0x105268(0xe2));return{'username':_0xa9a886,'password':_0x7296ef,'hostname':_0x462f36,'port':_0x3a5a9d};}function isValidIPv4(_0x525e4c){const _0x12f263=/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;return _0x12f263['test'](_0x525e4c);}
\ No newline at end of file
+/*jslint bitwise: true */
+(function () {
+ 'use strict';
+
+ var ERROR = 'input is invalid type';
+ var WINDOW = typeof window === 'object';
+ var root = WINDOW ? window : {};
+ if (root.JS_SHA256_NO_WINDOW) {
+ WINDOW = false;
+ }
+ var WEB_WORKER = !WINDOW && typeof self === 'object';
+ var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
+ if (NODE_JS) {
+ root = global;
+ } else if (WEB_WORKER) {
+ root = self;
+ }
+ var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports;
+ var AMD = typeof define === 'function' && define.amd;
+ var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
+ var HEX_CHARS = '0123456789abcdef'.split('');
+ var EXTRA = [-2147483648, 8388608, 32768, 128];
+ var SHIFT = [24, 16, 8, 0];
+ var K = [
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ ];
+ var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
+
+ var blocks = [];
+
+ if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) {
+ Array.isArray = function (obj) {
+ return Object.prototype.toString.call(obj) === '[object Array]';
+ };
+ }
+
+ if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
+ ArrayBuffer.isView = function (obj) {
+ return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
+ };
+ }
+
+ var createOutputMethod = function (outputType, is224) {
+ return function (message) {
+ return new Sha256(is224, true).update(message)[outputType]();
+ };
+ };
+
+ var createMethod = function (is224) {
+ var method = createOutputMethod('hex', is224);
+ if (NODE_JS) {
+ method = nodeWrap(method, is224);
+ }
+ method.create = function () {
+ return new Sha256(is224);
+ };
+ method.update = function (message) {
+ return method.create().update(message);
+ };
+ for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
+ var type = OUTPUT_TYPES[i];
+ method[type] = createOutputMethod(type, is224);
+ }
+ return method;
+ };
+
+ var nodeWrap = function (method, is224) {
+ var crypto = require('node:crypto')
+ var Buffer = require('node:buffer').Buffer;
+ var algorithm = is224 ? 'sha224' : 'sha256';
+ var bufferFrom;
+ if (Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM) {
+ bufferFrom = Buffer.from;
+ } else {
+ bufferFrom = function (message) {
+ return new Buffer(message);
+ };
+ }
+ var nodeMethod = function (message) {
+ if (typeof message === 'string') {
+ return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
+ } else {
+ if (message === null || message === undefined) {
+ throw new Error(ERROR);
+ } else if (message.constructor === ArrayBuffer) {
+ message = new Uint8Array(message);
+ }
+ }
+ if (Array.isArray(message) || ArrayBuffer.isView(message) ||
+ message.constructor === Buffer) {
+ return crypto.createHash(algorithm).update(bufferFrom(message)).digest('hex');
+ } else {
+ return method(message);
+ }
+ };
+ return nodeMethod;
+ };
+
+ var createHmacOutputMethod = function (outputType, is224) {
+ return function (key, message) {
+ return new HmacSha256(key, is224, true).update(message)[outputType]();
+ };
+ };
+
+ var createHmacMethod = function (is224) {
+ var method = createHmacOutputMethod('hex', is224);
+ method.create = function (key) {
+ return new HmacSha256(key, is224);
+ };
+ method.update = function (key, message) {
+ return method.create(key).update(message);
+ };
+ for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
+ var type = OUTPUT_TYPES[i];
+ method[type] = createHmacOutputMethod(type, is224);
+ }
+ return method;
+ };
+
+ function Sha256(is224, sharedMemory) {
+ if (sharedMemory) {
+ blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
+ blocks[4] = blocks[5] = blocks[6] = blocks[7] =
+ blocks[8] = blocks[9] = blocks[10] = blocks[11] =
+ blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
+ this.blocks = blocks;
+ } else {
+ this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ }
+
+ if (is224) {
+ this.h0 = 0xc1059ed8;
+ this.h1 = 0x367cd507;
+ this.h2 = 0x3070dd17;
+ this.h3 = 0xf70e5939;
+ this.h4 = 0xffc00b31;
+ this.h5 = 0x68581511;
+ this.h6 = 0x64f98fa7;
+ this.h7 = 0xbefa4fa4;
+ } else { // 256
+ this.h0 = 0x6a09e667;
+ this.h1 = 0xbb67ae85;
+ this.h2 = 0x3c6ef372;
+ this.h3 = 0xa54ff53a;
+ this.h4 = 0x510e527f;
+ this.h5 = 0x9b05688c;
+ this.h6 = 0x1f83d9ab;
+ this.h7 = 0x5be0cd19;
+ }
+
+ this.block = this.start = this.bytes = this.hBytes = 0;
+ this.finalized = this.hashed = false;
+ this.first = true;
+ this.is224 = is224;
+ }
+
+ Sha256.prototype.update = function (message) {
+ if (this.finalized) {
+ return;
+ }
+ var notString, type = typeof message;
+ if (type !== 'string') {
+ if (type === 'object') {
+ if (message === null) {
+ throw new Error(ERROR);
+ } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
+ message = new Uint8Array(message);
+ } else if (!Array.isArray(message)) {
+ if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
+ throw new Error(ERROR);
+ }
+ }
+ } else {
+ throw new Error(ERROR);
+ }
+ notString = true;
+ }
+ var code, index = 0, i, length = message.length, blocks = this.blocks;
+ while (index < length) {
+ if (this.hashed) {
+ this.hashed = false;
+ blocks[0] = this.block;
+ this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
+ blocks[4] = blocks[5] = blocks[6] = blocks[7] =
+ blocks[8] = blocks[9] = blocks[10] = blocks[11] =
+ blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
+ }
+
+ if (notString) {
+ for (i = this.start; index < length && i < 64; ++index) {
+ blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
+ }
+ } else {
+ for (i = this.start; index < length && i < 64; ++index) {
+ code = message.charCodeAt(index);
+ if (code < 0x80) {
+ blocks[i >>> 2] |= code << SHIFT[i++ & 3];
+ } else if (code < 0x800) {
+ blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3];
+ blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
+ } else if (code < 0xd800 || code >= 0xe000) {
+ blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3];
+ blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
+ blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
+ } else {
+ code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
+ blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3];
+ blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3];
+ blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
+ blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
+ }
+ }
+ }
+
+ this.lastByteIndex = i;
+ this.bytes += i - this.start;
+ if (i >= 64) {
+ this.block = blocks[16];
+ this.start = i - 64;
+ this.hash();
+ this.hashed = true;
+ } else {
+ this.start = i;
+ }
+ }
+ if (this.bytes > 4294967295) {
+ this.hBytes += this.bytes / 4294967296 << 0;
+ this.bytes = this.bytes % 4294967296;
+ }
+ return this;
+ };
+
+ Sha256.prototype.finalize = function () {
+ if (this.finalized) {
+ return;
+ }
+ this.finalized = true;
+ var blocks = this.blocks, i = this.lastByteIndex;
+ blocks[16] = this.block;
+ blocks[i >>> 2] |= EXTRA[i & 3];
+ this.block = blocks[16];
+ if (i >= 56) {
+ if (!this.hashed) {
+ this.hash();
+ }
+ blocks[0] = this.block;
+ blocks[16] = blocks[1] = blocks[2] = blocks[3] =
+ blocks[4] = blocks[5] = blocks[6] = blocks[7] =
+ blocks[8] = blocks[9] = blocks[10] = blocks[11] =
+ blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
+ }
+ blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
+ blocks[15] = this.bytes << 3;
+ this.hash();
+ };
+
+ Sha256.prototype.hash = function () {
+ var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
+ h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
+
+ for (j = 16; j < 64; ++j) {
+ // rightrotate
+ t1 = blocks[j - 15];
+ s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
+ t1 = blocks[j - 2];
+ s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
+ blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
+ }
+
+ bc = b & c;
+ for (j = 0; j < 64; j += 4) {
+ if (this.first) {
+ if (this.is224) {
+ ab = 300032;
+ t1 = blocks[0] - 1413257819;
+ h = t1 - 150054599 << 0;
+ d = t1 + 24177077 << 0;
+ } else {
+ ab = 704751109;
+ t1 = blocks[0] - 210244248;
+ h = t1 - 1521486534 << 0;
+ d = t1 + 143694565 << 0;
+ }
+ this.first = false;
+ } else {
+ s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
+ s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
+ ab = a & b;
+ maj = ab ^ (a & c) ^ bc;
+ ch = (e & f) ^ (~e & g);
+ t1 = h + s1 + ch + K[j] + blocks[j];
+ t2 = s0 + maj;
+ h = d + t1 << 0;
+ d = t1 + t2 << 0;
+ }
+ s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
+ s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
+ da = d & a;
+ maj = da ^ (d & b) ^ ab;
+ ch = (h & e) ^ (~h & f);
+ t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
+ t2 = s0 + maj;
+ g = c + t1 << 0;
+ c = t1 + t2 << 0;
+ s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
+ s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
+ cd = c & d;
+ maj = cd ^ (c & a) ^ da;
+ ch = (g & h) ^ (~g & e);
+ t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
+ t2 = s0 + maj;
+ f = b + t1 << 0;
+ b = t1 + t2 << 0;
+ s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
+ s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
+ bc = b & c;
+ maj = bc ^ (b & d) ^ cd;
+ ch = (f & g) ^ (~f & h);
+ t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
+ t2 = s0 + maj;
+ e = a + t1 << 0;
+ a = t1 + t2 << 0;
+ this.chromeBugWorkAround = true;
+ }
+
+ this.h0 = this.h0 + a << 0;
+ this.h1 = this.h1 + b << 0;
+ this.h2 = this.h2 + c << 0;
+ this.h3 = this.h3 + d << 0;
+ this.h4 = this.h4 + e << 0;
+ this.h5 = this.h5 + f << 0;
+ this.h6 = this.h6 + g << 0;
+ this.h7 = this.h7 + h << 0;
+ };
+
+ Sha256.prototype.hex = function () {
+ this.finalize();
+
+ var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
+ h6 = this.h6, h7 = this.h7;
+
+ var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
+ HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
+ HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
+ HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
+ HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
+ HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
+ HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
+ HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
+ HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
+ HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
+ HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
+ HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
+ HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
+ HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
+ HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
+ HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
+ HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
+ HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
+ HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
+ HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
+ HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
+ HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
+ HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
+ HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
+ HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
+ HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
+ HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
+ HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
+ if (!this.is224) {
+ hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
+ HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
+ HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
+ HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
+ }
+ return hex;
+ };
+
+ Sha256.prototype.toString = Sha256.prototype.hex;
+
+ Sha256.prototype.digest = function () {
+ this.finalize();
+
+ var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
+ h6 = this.h6, h7 = this.h7;
+
+ var arr = [
+ (h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
+ (h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
+ (h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
+ (h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
+ (h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
+ (h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
+ (h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
+ ];
+ if (!this.is224) {
+ arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
+ }
+ return arr;
+ };
+
+ Sha256.prototype.array = Sha256.prototype.digest;
+
+ Sha256.prototype.arrayBuffer = function () {
+ this.finalize();
+
+ var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
+ var dataView = new DataView(buffer);
+ dataView.setUint32(0, this.h0);
+ dataView.setUint32(4, this.h1);
+ dataView.setUint32(8, this.h2);
+ dataView.setUint32(12, this.h3);
+ dataView.setUint32(16, this.h4);
+ dataView.setUint32(20, this.h5);
+ dataView.setUint32(24, this.h6);
+ if (!this.is224) {
+ dataView.setUint32(28, this.h7);
+ }
+ return buffer;
+ };
+
+ function HmacSha256(key, is224, sharedMemory) {
+ var i, type = typeof key;
+ if (type === 'string') {
+ var bytes = [], length = key.length, index = 0, code;
+ for (i = 0; i < length; ++i) {
+ code = key.charCodeAt(i);
+ if (code < 0x80) {
+ bytes[index++] = code;
+ } else if (code < 0x800) {
+ bytes[index++] = (0xc0 | (code >>> 6));
+ bytes[index++] = (0x80 | (code & 0x3f));
+ } else if (code < 0xd800 || code >= 0xe000) {
+ bytes[index++] = (0xe0 | (code >>> 12));
+ bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
+ bytes[index++] = (0x80 | (code & 0x3f));
+ } else {
+ code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
+ bytes[index++] = (0xf0 | (code >>> 18));
+ bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
+ bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
+ bytes[index++] = (0x80 | (code & 0x3f));
+ }
+ }
+ key = bytes;
+ } else {
+ if (type === 'object') {
+ if (key === null) {
+ throw new Error(ERROR);
+ } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
+ key = new Uint8Array(key);
+ } else if (!Array.isArray(key)) {
+ if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
+ throw new Error(ERROR);
+ }
+ }
+ } else {
+ throw new Error(ERROR);
+ }
+ }
+
+ if (key.length > 64) {
+ key = (new Sha256(is224, true)).update(key).array();
+ }
+
+ var oKeyPad = [], iKeyPad = [];
+ for (i = 0; i < 64; ++i) {
+ var b = key[i] || 0;
+ oKeyPad[i] = 0x5c ^ b;
+ iKeyPad[i] = 0x36 ^ b;
+ }
+
+ Sha256.call(this, is224, sharedMemory);
+
+ this.update(iKeyPad);
+ this.oKeyPad = oKeyPad;
+ this.inner = true;
+ this.sharedMemory = sharedMemory;
+ }
+ HmacSha256.prototype = new Sha256();
+
+ HmacSha256.prototype.finalize = function () {
+ Sha256.prototype.finalize.call(this);
+ if (this.inner) {
+ this.inner = false;
+ var innerHash = this.array();
+ Sha256.call(this, this.is224, this.sharedMemory);
+ this.update(this.oKeyPad);
+ this.update(innerHash);
+ Sha256.prototype.finalize.call(this);
+ }
+ };
+
+ function createSha224() {
+ var sha224 = createMethod(true);
+ sha224.hmac = createHmacMethod(true);
+ return sha224;
+ }
+
+ const sha224 = createSha224();
+
+ if (COMMON_JS) {
+ module.exports = {
+ sha224: sha224
+ };
+ } else {
+ root.sha224 = sha224;
+ if (AMD) {
+ define(function () {
+ return {
+ sha224: sha224
+ };
+ });
+ }
+ }
+ })();
\ No newline at end of file
diff --git a/_worker.src.js b/_worker.src.js
deleted file mode 100644
index e40fb451..00000000
--- a/_worker.src.js
+++ /dev/null
@@ -1,1821 +0,0 @@
-// _worker.src.js
-import { connect } from "cloudflare:sockets";
-let password = '';
-let proxyIP = '';
-// The user name and password do not contain special characters
-// Setting the address will ignore proxyIP
-// Example: user:pass@host:port or host:port
-let socks5Address = '';
-
-let addresses = [
- //当sub为空时启用本地优选域名/优选IP,若不带端口号 TLS默认端口为443,#号后为备注别名
-];
-
-let sub = '';
-let subconverter = 'SUBAPI.fxxk.dedyn.io';// clash订阅转换后端,目前使用CM的订阅转换功能。自带虚假节点信息防泄露
-let subconfig = "https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online_Mini_MultiMode.ini"; //订阅配置文件
-let subProtocol = 'https';
-let RproxyIP = 'false';
-
-let addressesapi = [];
-let addressescsv = [];
-let DLS = 8;
-
-let FileName = 'epeius';
-let BotToken ='';
-let ChatID ='';
-let proxyhosts = [];//本地代理域名池
-let proxyhostsURL = '';
-let go2Socks5s = [
- '*ttvnw.net',
- '*tapecontent.net',
- '*cloudatacdn.com',
- '*.loadshare.org',
-];
-
-let fakeUserID ;
-let fakeHostName ;
-let proxyIPs ;
-let socks5s;
-let sha224Password ;
-const expire = 4102329600;//2099-12-31
-const regex = /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[.*\]):?(\d+)?#?(.*)?$/;
-
-let parsedSocks5Address = {};
-let enableSocks = false;
-let httpsPorts = ["2053","2083","2087","2096","8443"];
-/*Obfuscate-cmliu*/
-/*
-if (!isValidSHA224(sha224Password)) {
- throw new Error('sha224Password is not valid');
-}
-*/
-export default {
- async fetch(request, env, ctx) {
- try {
- const UA = request.headers.get('User-Agent') || 'null';
- const userAgent = UA.toLowerCase();
- password = env.PASSWORD || password;
- if (!password) {
- return new Response('请设置你的PASSWORD变量,或尝试重试部署,检查变量是否生效?', {
- status: 404,
- headers: {
- "Content-Type": "text/plain;charset=utf-8",
- }
- });
- }
- sha224Password = env.SHA224 || env.SHA224PASS || sha256.sha224(password);
- //console.log(sha224Password);
-
- const currentDate = new Date();
- currentDate.setHours(0, 0, 0, 0); // 设置时间为当天
- const timestamp = Math.ceil(currentDate.getTime() / 1000);
- const fakeUserIDMD5 = await MD5MD5(`${password}${timestamp}`);
- fakeUserID = fakeUserIDMD5.slice(0, 8) + "-" + fakeUserIDMD5.slice(8, 12) + "-" + fakeUserIDMD5.slice(12, 16) + "-" + fakeUserIDMD5.slice(16, 20) + "-" + fakeUserIDMD5.slice(20);
- fakeHostName = fakeUserIDMD5.slice(6, 9) + "." + fakeUserIDMD5.slice(13, 19);
- //console.log(fakeUserID); // 打印fakeID
-
- proxyIP = env.PROXYIP || proxyIP;
- proxyIPs = await ADD(proxyIP);
- proxyIP = proxyIPs[Math.floor(Math.random() * proxyIPs.length)];
- socks5Address = env.SOCKS5 || socks5Address;
- socks5s = await ADD(socks5Address);
- socks5Address = socks5s[Math.floor(Math.random() * socks5s.length)];
- socks5Address = socks5Address.split('//')[1] || socks5Address;
- if (env.CFPORTS) httpsPorts = await ADD(env.CFPORTS);
- sub = env.SUB || sub;
- subconverter = env.SUBAPI || subconverter;
- if( subconverter.includes("http://") ){
- subconverter = subconverter.split("//")[1];
- subProtocol = 'http';
- } else {
- subconverter = subconverter.split("//")[1] || subconverter;
- }
- subconfig = env.SUBCONFIG || subconfig;
- if (socks5Address) {
- try {
- parsedSocks5Address = socks5AddressParser(socks5Address);
- RproxyIP = env.RPROXYIP || 'false';
- enableSocks = true;
- } catch (err) {
- /** @type {Error} */
- let e = err;
- console.log(e.toString());
- RproxyIP = env.RPROXYIP || !proxyIP ? 'true' : 'false';
- enableSocks = false;
- }
- } else {
- RproxyIP = env.RPROXYIP || !proxyIP ? 'true' : 'false';
- }
- if (env.ADD) addresses = await ADD(env.ADD);
- if (env.ADDAPI) addressesapi = await ADD(env.ADDAPI);
- if (env.ADDCSV) addressescsv = await ADD(env.ADDCSV);
- DLS = env.DLS || DLS;
- BotToken = env.TGTOKEN || BotToken;
- ChatID = env.TGID || ChatID;
- if(env.GO2SOCKS5) go2Socks5s = await ADD(env.GO2SOCKS5);
- const upgradeHeader = request.headers.get("Upgrade");
- const url = new URL(request.url);
- if (url.searchParams.has('sub') && url.searchParams.get('sub') !== '') sub = url.searchParams.get('sub');
- FileName = env.SUBNAME || FileName;
- if (!upgradeHeader || upgradeHeader !== "websocket") {
- //const url = new URL(request.url);
- switch (url.pathname) {
- case '/':
- if (env.URL302) return Response.redirect(env.URL302, 302);
- else if (env.URL) return await proxyURL(env.URL, url);
- else return new Response(JSON.stringify(request.cf, null, 4), {
- status: 200,
- headers: {
- 'content-type': 'application/json',
- },
- });
- case `/${fakeUserID}`:
- const fakeConfig = await getTrojanConfig(password, request.headers.get('Host'), sub, 'CF-Workers-SUB', RproxyIP, url);
- return new Response(`${fakeConfig}`, { status: 200 });
- case `/${password}`:
- await sendMessage(`#获取订阅 ${FileName}`, request.headers.get('CF-Connecting-IP'), `UA: ${UA}\n域名: ${url.hostname}\n入口: ${url.pathname + url.search}`);
- const trojanConfig = await getTrojanConfig(password, request.headers.get('Host'), sub, UA, RproxyIP, url);
- const now = Date.now();
- //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);
- let pagesSum = UD;
- let workersSum = UD;
- let total = 24 * 1099511627776 ;
-
- if (userAgent && (userAgent.includes('mozilla') || userAgent.includes('subconverter'))){
- return new Response(`${trojanConfig}`, {
- status: 200,
- headers: {
- "Content-Type": "text/plain;charset=utf-8",
- "Profile-Update-Interval": "6",
- "Subscription-Userinfo": `upload=${pagesSum}; download=${workersSum}; total=${total}; expire=${expire}`,
- }
- });
- } else {
- return new Response(`${trojanConfig}`, {
- status: 200,
- headers: {
- "Content-Disposition": `attachment; filename=${FileName}; filename*=utf-8''${encodeURIComponent(FileName)}`,
- "Content-Type": "text/plain;charset=utf-8",
- "Profile-Update-Interval": "6",
- "Subscription-Userinfo": `upload=${pagesSum}; download=${workersSum}; total=${total}; expire=${expire}`,
- }
- });
- }
- default:
- if (env.URL302) return Response.redirect(env.URL302, 302);
- else if (env.URL) return await proxyURL(env.URL, url);
- else return new Response('不用怀疑!你PASSWORD就是错的!!!', { status: 404 });
- }
- } else {
- proxyIP = url.searchParams.get('proxyip') || proxyIP;
- if (new RegExp('/proxyip=', 'i').test(url.pathname)) proxyIP = url.pathname.toLowerCase().split('/proxyip=')[1];
- else if (new RegExp('/proxyip.', 'i').test(url.pathname)) proxyIP = `proxyip.${url.pathname.toLowerCase().split("/proxyip.")[1]}`;
-
- socks5Address = url.searchParams.get('socks5') || socks5Address;
- 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('@')){
- 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);
- socks5Address = `${userPassword}@${socks5Address.split('@')[1]}`;
- }
- }
- if (socks5Address) {
- try {
- parsedSocks5Address = socks5AddressParser(socks5Address);
- enableSocks = true;
- } catch (err) {
- /** @type {Error} */
- let e = err;
- console.log(e.toString());
- enableSocks = false;
- }
- } else {
- enableSocks = false;
- }
- return await trojanOverWSHandler(request);
- }
- } catch (err) {
- let e = err;
- return new Response(e.toString());
- }
- }
-};
-
-async function trojanOverWSHandler(request) {
- const webSocketPair = new WebSocketPair();
- const [client, webSocket] = Object.values(webSocketPair);
- webSocket.accept();
- let address = "";
- let portWithRandomLog = "";
- const log = (info, event) => {
- console.log(`[${address}:${portWithRandomLog}] ${info}`, event || "");
- };
- const earlyDataHeader = request.headers.get("sec-websocket-protocol") || "";
- const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log);
- let remoteSocketWapper = {
- value: null
- };
- let udpStreamWrite = null;
- readableWebSocketStream.pipeTo(new WritableStream({
- async write(chunk, controller) {
- if (udpStreamWrite) {
- return udpStreamWrite(chunk);
- }
- if (remoteSocketWapper.value) {
- const writer = remoteSocketWapper.value.writable.getWriter();
- await writer.write(chunk);
- writer.releaseLock();
- return;
- }
- const {
- hasError,
- message,
- portRemote = 443,
- addressRemote = "",
- rawClientData,
- addressType
- } = await parseTrojanHeader(chunk);
- address = addressRemote;
- portWithRandomLog = `${portRemote}--${Math.random()} tcp`;
- if (hasError) {
- throw new Error(message);
- return;
- }
- handleTCPOutBound(remoteSocketWapper, addressRemote, portRemote, rawClientData, webSocket, log, addressType);
- },
- close() {
- log(`readableWebSocketStream is closed`);
- },
- abort(reason) {
- log(`readableWebSocketStream is aborted`, JSON.stringify(reason));
- }
- })).catch((err) => {
- log("readableWebSocketStream pipeTo error", err);
- });
- return new Response(null, {
- status: 101,
- // @ts-ignore
- webSocket: client
- });
-}
-
-async function parseTrojanHeader(buffer) {
- if (buffer.byteLength < 56) {
- return {
- hasError: true,
- message: "invalid data"
- };
- }
- let crLfIndex = 56;
- if (new Uint8Array(buffer.slice(56, 57))[0] !== 0x0d || new Uint8Array(buffer.slice(57, 58))[0] !== 0x0a) {
- return {
- hasError: true,
- message: "invalid header format (missing CR LF)"
- };
- }
- const password = new TextDecoder().decode(buffer.slice(0, crLfIndex));
- if (password !== sha224Password) {
- return {
- hasError: true,
- message: "invalid password"
- };
- }
-
- const socks5DataBuffer = buffer.slice(crLfIndex + 2);
- if (socks5DataBuffer.byteLength < 6) {
- return {
- hasError: true,
- message: "invalid SOCKS5 request data"
- };
- }
-
- const view = new DataView(socks5DataBuffer);
- const cmd = view.getUint8(0);
- if (cmd !== 1) {
- return {
- hasError: true,
- message: "unsupported command, only TCP (CONNECT) is allowed"
- };
- }
-
- const atype = view.getUint8(1);
- // 0x01: IPv4 address
- // 0x03: Domain name
- // 0x04: IPv6 address
- let addressLength = 0;
- let addressIndex = 2;
- let address = "";
- switch (atype) {
- case 1:
- addressLength = 4;
- address = new Uint8Array(
- socks5DataBuffer.slice(addressIndex, addressIndex + addressLength)
- ).join(".");
- break;
- case 3:
- addressLength = new Uint8Array(
- socks5DataBuffer.slice(addressIndex, addressIndex + 1)
- )[0];
- addressIndex += 1;
- address = new TextDecoder().decode(
- socks5DataBuffer.slice(addressIndex, addressIndex + addressLength)
- );
- break;
- case 4:
- addressLength = 16;
- const dataView = new DataView(socks5DataBuffer.slice(addressIndex, addressIndex + addressLength));
- const ipv6 = [];
- for (let i = 0; i < 8; i++) {
- ipv6.push(dataView.getUint16(i * 2).toString(16));
- }
- address = ipv6.join(":");
- break;
- default:
- return {
- hasError: true,
- message: `invalid addressType is ${atype}`
- };
- }
-
- if (!address) {
- return {
- hasError: true,
- message: `address is empty, addressType is ${atype}`
- };
- }
-
- const portIndex = addressIndex + addressLength;
- const portBuffer = socks5DataBuffer.slice(portIndex, portIndex + 2);
- const portRemote = new DataView(portBuffer).getUint16(0);
- return {
- hasError: false,
- addressRemote: address,
- portRemote,
- rawClientData: socks5DataBuffer.slice(portIndex + 4),
- addressType: atype
- };
-}
-
-async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawClientData, webSocket, log, addressType) {
- async function useSocks5Pattern(address) {
- 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');
- return regex.test(address);
- });
- }
- async function connectAndWrite(address, port, socks = false) {
- log(`connected to ${address}:${port}`);
- //if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(address)) address = `${atob('d3d3Lg==')}${address}${atob('LmlwLjA5MDIyNy54eXo=')}`;
- const tcpSocket = socks ? await socks5Connect(addressType, address, port, log)
- : connect({
- hostname: address,
- port
- });
- remoteSocket.value = tcpSocket;
- //log(`connected to ${address}:${port}`);
- const writer = tcpSocket.writable.getWriter();
- await writer.write(rawClientData);
- writer.releaseLock();
- return tcpSocket;
- }
- async function retry() {
- if (enableSocks) {
- tcpSocket = await connectAndWrite(addressRemote, portRemote, true);
- } else {
- if (!proxyIP || proxyIP == '') {
- proxyIP = atob('UFJPWFlJUC50cDEuZnh4ay5kZWR5bi5pbw==');
- } else if (proxyIP.includes(']:')) {
- portRemote = proxyIP.split(']:')[1] || portRemote;
- proxyIP = proxyIP.split(']:')[0] || proxyIP;
- } else if (proxyIP.split(':').length === 2) {
- portRemote = proxyIP.split(':')[1] || portRemote;
- proxyIP = proxyIP.split(':')[0] || proxyIP;
- }
- if (proxyIP.includes('.tp')) portRemote = proxyIP.split('.tp')[1].split('.')[0] || portRemote;
- tcpSocket = await connectAndWrite(proxyIP || addressRemote, portRemote);
- }
- tcpSocket.closed.catch((error) => {
- console.log("retry tcpSocket closed error", error);
- }).finally(() => {
- safeCloseWebSocket(webSocket);
- });
- remoteSocketToWS(tcpSocket, webSocket, null, log);
- }
- let useSocks = false;
- if( go2Socks5s.length > 0 && enableSocks ) useSocks = await useSocks5Pattern(addressRemote);
- let tcpSocket = await connectAndWrite(addressRemote, portRemote, useSocks);
- remoteSocketToWS(tcpSocket, webSocket, retry, log);
-}
-
-function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) {
- let readableStreamCancel = false;
- const stream = new ReadableStream({
- start(controller) {
- webSocketServer.addEventListener("message", (event) => {
- if (readableStreamCancel) {
- return;
- }
- const message = event.data;
- controller.enqueue(message);
- });
- webSocketServer.addEventListener("close", () => {
- safeCloseWebSocket(webSocketServer);
- if (readableStreamCancel) {
- return;
- }
- controller.close();
- });
- webSocketServer.addEventListener("error", (err) => {
- log("webSocketServer error");
- controller.error(err);
- });
- const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader);
- if (error) {
- controller.error(error);
- } else if (earlyData) {
- controller.enqueue(earlyData);
- }
- },
- pull(controller) {},
- cancel(reason) {
- if (readableStreamCancel) {
- return;
- }
- log(`readableStream was canceled, due to ${reason}`);
- readableStreamCancel = true;
- safeCloseWebSocket(webSocketServer);
- }
- });
- return stream;
-}
-
-async function remoteSocketToWS(remoteSocket, webSocket, retry, log) {
- let hasIncomingData = false;
- await remoteSocket.readable.pipeTo(
- new WritableStream({
- start() {},
- /**
- *
- * @param {Uint8Array} chunk
- * @param {*} controller
- */
- async write(chunk, controller) {
- hasIncomingData = true;
- if (webSocket.readyState !== WS_READY_STATE_OPEN) {
- controller.error(
- "webSocket connection is not open"
- );
- }
- webSocket.send(chunk);
- },
- close() {
- log(`remoteSocket.readable is closed, hasIncomingData: ${hasIncomingData}`);
- },
- abort(reason) {
- console.error("remoteSocket.readable abort", reason);
- }
- })
- ).catch((error) => {
- console.error(
- `remoteSocketToWS error:`,
- error.stack || error
- );
- safeCloseWebSocket(webSocket);
- });
- if (hasIncomingData === false && retry) {
- log(`retry`);
- retry();
- }
-}
-/*
-function isValidSHA224(hash) {
- const sha224Regex = /^[0-9a-f]{56}$/i;
- return sha224Regex.test(hash);
-}
-*/
-function base64ToArrayBuffer(base64Str) {
- if (!base64Str) {
- return { error: null };
- }
- try {
- base64Str = base64Str.replace(/-/g, "+").replace(/_/g, "/");
- const decode = atob(base64Str);
- const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0));
- return { earlyData: arryBuffer.buffer, error: null };
- } catch (error) {
- return { error };
- }
-}
-
-let WS_READY_STATE_OPEN = 1;
-let WS_READY_STATE_CLOSING = 2;
-
-function safeCloseWebSocket(socket) {
- try {
- if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) {
- socket.close();
- }
- } catch (error) {
- console.error("safeCloseWebSocket error", error);
- }
-}
-
-/*
-export {
- worker_default as
- default
-};
-//# sourceMappingURL=worker.js.map
-*/
-
-function revertFakeInfo(content, userID, hostName, isBase64) {
- if (isBase64) content = atob(content);//Base64解码
- content = content.replace(new RegExp(fakeUserID, 'g'), userID).replace(new RegExp(fakeHostName, 'g'), hostName);
- //console.log(content);
- if (isBase64) content = btoa(content);//Base64编码
-
- return content;
-}
-
-async function MD5MD5(text) {
- const encoder = new TextEncoder();
-
- const firstPass = await crypto.subtle.digest('MD5', encoder.encode(text));
- const firstPassArray = Array.from(new Uint8Array(firstPass));
- const firstHex = firstPassArray.map(b => b.toString(16).padStart(2, '0')).join('');
-
- const secondPass = await crypto.subtle.digest('MD5', encoder.encode(firstHex.slice(7, 27)));
- const secondPassArray = Array.from(new Uint8Array(secondPass));
- const secondHex = secondPassArray.map(b => b.toString(16).padStart(2, '0')).join('');
-
- return secondHex.toLowerCase();
-}
-
-async function ADD(内容) {
- // 将制表符、双引号、单引号和换行符都替换为逗号
- // 然后将连续的多个逗号替换为单个逗号
- var 替换后的内容 = 内容.replace(/[ |"'\r\n]+/g, ',').replace(/,+/g, ',');
-
- // 删除开头和结尾的逗号(如果有的话)
- if (替换后的内容.charAt(0) == ',') 替换后的内容 = 替换后的内容.slice(1);
- if (替换后的内容.charAt(替换后的内容.length - 1) == ',') 替换后的内容 = 替换后的内容.slice(0, 替换后的内容.length - 1);
-
- // 使用逗号分割字符串,得到地址数组
- const 地址数组 = 替换后的内容.split(',');
-
- return 地址数组;
-}
-
-async function proxyURL(proxyURL, url) {
- const URLs = await ADD(proxyURL);
- const fullURL = URLs[Math.floor(Math.random() * URLs.length)];
- // 解析目标 URL
- let parsedURL = new URL(fullURL);
- console.log(parsedURL);
- // 提取并可能修改 URL 组件
- let URLProtocol = parsedURL.protocol.slice(0, -1) || 'https';
- let URLHostname = parsedURL.hostname;
- let URLPathname = parsedURL.pathname;
- let URLSearch = parsedURL.search;
- // 处理 pathname
- if (URLPathname.charAt(URLPathname.length - 1) == '/') {
- URLPathname = URLPathname.slice(0, -1);
- }
- URLPathname += url.pathname;
- // 构建新的 URL
- let newURL = `${URLProtocol}://${URLHostname}${URLPathname}${URLSearch}`;
- // 反向代理请求
- let response = await fetch(newURL);
- // 创建新的响应
- let newResponse = new Response(response.body, {
- status: response.status,
- statusText: response.statusText,
- headers: response.headers
- });
- // 添加自定义头部,包含 URL 信息
- //newResponse.headers.set('X-Proxied-By', 'Cloudflare Worker');
- //newResponse.headers.set('X-Original-URL', fullURL);
- newResponse.headers.set('X-New-URL', newURL);
- return newResponse;
-}
-
-function 配置信息(密码, 域名地址) {
- const 啥啥啥_写的这是啥啊 = 'dHJvamFu';
- const 协议类型 = atob(啥啥啥_写的这是啥啊);
-
- const 别名 = FileName;
- let 地址 = 域名地址;
- let 端口 = 443;
-
- const 传输层协议 = 'ws';
- const 伪装域名 = 域名地址;
- const 路径 = '/?ed=2560';
-
- let 传输层安全 = ['tls',true];
- const SNI = 域名地址;
- const 指纹 = 'randomized';
-
- const v2ray = `${协议类型}://${encodeURIComponent(密码)}@${地址}:${端口}?security=${传输层安全[0]}&sni=${SNI}&alpn=h3&fp=${指纹}&allowInsecure=1&type=${传输层协议}&host=${伪装域名}&path=${encodeURIComponent(路径)}#${encodeURIComponent(别名)}`
- const clash = `- {name: ${别名}, server: ${地址}, port: ${端口}, udp: false, client-fingerprint: ${指纹}, type: ${协议类型}, password: ${密码}, sni: ${SNI}, alpn: [h3], skip-cert-verify: true, network: ${传输层协议}, ws-opts: {path: "${路径}", headers: {Host: ${伪装域名}}}}`;
-
- return [v2ray,clash];
-}
-
-let subParams = ['sub','base64','b64','clash','singbox','sb','surge'];
-async function getTrojanConfig(password, hostName, sub, UA, RproxyIP, _url) {
- if (sub) {
- const match = sub.match(/^(?:https?:\/\/)?([^\/]+)/);
- if (match) {
- sub = match[1];
- }
- } else if ((addresses.length + addressesapi.length + addressescsv.length) == 0){
- // 定义 Cloudflare IP 范围的 CIDR 列表
- let cfips = [
- '103.21.244.0/23',
- '104.16.0.0/13',
- '104.24.0.0/14',
- '172.64.0.0/14',
- '103.21.244.0/23',
- '104.16.0.0/14',
- '104.24.0.0/15',
- '141.101.64.0/19',
- '172.64.0.0/14',
- '188.114.96.0/21',
- '190.93.240.0/21',
- ];
-
- // 生成符合给定 CIDR 范围的随机 IP 地址
- function generateRandomIPFromCIDR(cidr) {
- const [base, mask] = cidr.split('/');
- const baseIP = base.split('.').map(Number);
- 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');
- addresses = addresses.concat(cfips.map(cidr => generateRandomIPFromCIDR(cidr) + '#CF随机节点'));
- }
- const userAgent = UA.toLowerCase();
- const Config = 配置信息(password , hostName);
- const v2ray = Config[0];
- const clash = Config[1];
- let proxyhost = "";
- if(hostName.includes(".workers.dev")){
- if ( proxyhostsURL && (!proxyhosts || proxyhosts.length == 0)) {
- try {
- 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)] + "/";
- }
-
- if ( userAgent.includes('mozilla') && !subParams.some(_searchParams => _url.searchParams.has(_searchParams))) {
- let surge = `Surge订阅地址:\nhttps://${proxyhost}${hostName}/${password}?surge`;
- if (hostName.includes(".workers.dev")) surge = "Surge订阅必须绑定自定义域";
- const newSocks5s = socks5s.map(socks5Address => {
- if (socks5Address.includes('@')) return socks5Address.split('@')[1];
- else if (socks5Address.includes('//')) return socks5Address.split('//')[1];
- else return socks5Address;
- });
-
- let socks5List = '';
- 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')}\n`;
- else socks5List += `\n ${go2Socks5s.join('\n ')}\n`;
- }
-
- let 订阅器 = '';
- if (!sub || sub == '') {
- if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5\n ${newSocks5s.join('\n ')}\n${socks5List}`;
- else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP\n ${proxyIPs.join('\n ')}\n`;
- else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!\n`;
- 订阅器 += `\n您的订阅内容由 内置 addresses/ADD* 参数变量提供\n`;
- if (addresses.length > 0) 订阅器 += `ADD(TLS优选域名&IP): \n ${addresses.join('\n ')}\n`;
- if (addressesapi.length > 0) 订阅器 += `ADDAPI(TLS优选域名&IP 的 API): \n ${addressesapi.join('\n ')}\n`;
- if (addressescsv.length > 0) 订阅器 += `ADDCSV(IPTest测速csv文件 限速 ${DLS} ): \n ${addressescsv.join('\n ')}\n`;
- } else {
- if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5\n ${newSocks5s.join('\n ')}\n${socks5List}`;
- else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP\n ${proxyIPs.join('\n ')}\n`;
- else if (RproxyIP == 'true') 订阅器 += `CFCDN(访问方式): 自动获取ProxyIP\n`;
- else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!\n`
- 订阅器 += `\nSUB(优选订阅生成器): ${sub}`;
- }
-
- return `
-################################################################
-Subscribe / sub 订阅地址, 支持 Base64、clash-meta、sing-box 订阅格式
----------------------------------------------------------------
-快速自适应订阅地址:
-https://${proxyhost}${hostName}/${password}
-https://${proxyhost}${hostName}/${password}?sub
-
-Base64订阅地址:
-https://${proxyhost}${hostName}/${password}?b64
-https://${proxyhost}${hostName}/${password}?base64
-
-clash订阅地址:
-https://${proxyhost}${hostName}/${password}?clash
-
-singbox订阅地址:
-https://${proxyhost}${hostName}/${password}?sb
-https://${proxyhost}${hostName}/${password}?singbox
-
-${surge}
----------------------------------------------------------------
-################################################################
-${FileName} 配置信息
----------------------------------------------------------------
-HOST: ${hostName}
-PASSWORD: ${password}
-SHA224: ${sha224Password}
-FAKEPASS: ${fakeUserID}
-UA: ${UA}
-
-${订阅器}
-SUBAPI(订阅转换后端): ${subProtocol}://${subconverter}
-SUBCONFIG(订阅转换配置文件): ${subconfig}
----------------------------------------------------------------
-################################################################
-v2ray
----------------------------------------------------------------
-${v2ray}
----------------------------------------------------------------
-################################################################
-clash-meta
----------------------------------------------------------------
-${clash}
----------------------------------------------------------------
-################################################################
-${atob(`dGVsZWdyYW0g5Lqk5rWB576kIOaKgOacr+Wkp+S9rH7lnKjnur/lj5HniYwhCmh0dHBzOi8vdC5tZS9DTUxpdXNzc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmdpdGh1YiDpobnnm67lnLDlnYAgU3RhciFTdGFyIVN0YXIhISEKaHR0cHM6Ly9naXRodWIuY29tL2NtbGl1L2VwZWl1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw==`)}
-`;
- } else {
- if (typeof fetch != 'function') {
- return 'Error: fetch is not available in this environment.';
- }
- // 如果是使用默认域名,则改成一个workers的域名,订阅器会加上代理
- if (hostName.includes(".workers.dev")){
- fakeHostName = `${fakeHostName}.workers.dev`;
- } else {
- fakeHostName = `${fakeHostName}.xyz`
- }
-
- let url = `https://${sub}/sub?host=${fakeHostName}&pw=${fakeUserID}&password=${fakeUserID + atob('JmVwZWl1cz1jbWxpdSZwcm94eWlwPQ==') + RproxyIP}`;
- let isBase64 = true;
- let newAddressesapi = [];
- let newAddressescsv = [];
-
- if (!sub || sub == "") {
- if(hostName.includes('workers.dev')) {
- if (proxyhostsURL && (!proxyhosts || proxyhosts.length == 0)) {
- try {
- 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);
- }
- }
- // 使用Set对象去重
- proxyhosts = [...new Set(proxyhosts)];
- }
-
- newAddressesapi = await getAddressesapi(addressesapi);
- newAddressescsv = await getAddressescsv('TRUE');
- url = `https://${hostName}/${fakeUserID}`;
- }
-
- if (!userAgent.includes(('CF-Workers-SUB').toLowerCase())){
- if ((userAgent.includes('clash') && !userAgent.includes('nekobox')) || ( _url.searchParams.has('clash'))) {
- url = `${subProtocol}://${subconverter}/sub?target=clash&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`;
- isBase64 = false;
- } else if (userAgent.includes('sing-box') || userAgent.includes('singbox') || _url.searchParams.has('singbox') || _url.searchParams.has('sb')) {
- url = `${subProtocol}://${subconverter}/sub?target=singbox&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`;
- isBase64 = false;
- } else if (userAgent.includes('surge') || _url.searchParams.has('surge')) {
- url = `${subProtocol}://${subconverter}/sub?target=surge&ver=4&url=${encodeURIComponent(url)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&xudp=false&udp=false&tfo=false&expand=true&scv=true&fdn=false`;
- isBase64 = false;
- }
- }
-
- try {
- let content;
- if ((!sub || sub == "") && isBase64 == true) {
- content = await subAddresses(fakeHostName,fakeUserID,userAgent,newAddressesapi,newAddressescsv);
- } else {
- const response = await fetch(url ,{
- headers: {
- 'User-Agent': atob('Q0YtV29ya2Vycy1lcGVpdXMvY21saXU='),
- }});
- content = await response.text();
- }
-
- if (_url.pathname == `/${fakeUserID}`) return content;
-
- content = revertFakeInfo(content, password, hostName, isBase64);
- if (userAgent.includes('surge') || _url.searchParams.has('surge')) content = surge(content, `https://${hostName}/${password}?surge`);
- return content;
- } catch (error) {
- console.error('Error fetching content:', error);
- return `Error fetching content: ${error.message}`;
- }
- }
-}
-
-async function sendMessage(type, ip, add_data = "") {
- if ( BotToken !== '' && ChatID !== ''){
- let msg = "";
- const response = await fetch(`http://ip-api.com/json/${ip}?lang=zh-CN`);
- if (response.status == 200) {
- const ipInfo = await response.json();
- msg = `${type}\nIP: ${ip}\n国家: ${ipInfo.country}\n城市: ${ipInfo.city}\n组织: ${ipInfo.org}\nASN: ${ipInfo.as}\n${add_data}`;
- } else {
- msg = `${type}\nIP: ${ip}\n${add_data}`;
- }
-
- let url = "https://api.telegram.org/bot"+ BotToken +"/sendMessage?chat_id=" + ChatID + "&parse_mode=HTML&text=" + encodeURIComponent(msg);
- return fetch(url, {
- method: 'get',
- headers: {
- 'Accept': 'text/html,application/xhtml+xml,application/xml;',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'User-Agent': 'Mozilla/5.0 Chrome/90.0.4430.72'
- }
- });
- }
-}
-let proxyIPPool = [];
-function subAddresses(host,pw,userAgent,newAddressesapi,newAddressescsv) {
- addresses = addresses.concat(newAddressesapi);
- addresses = addresses.concat(newAddressescsv);
- // 使用Set对象去重
- const uniqueAddresses = [...new Set(addresses)];
-
- const responseBody = uniqueAddresses.map(address => {
- let port = "-1";
- let addressid = address;
-
- const match = addressid.match(regex);
- if (!match) {
- if (address.includes(':') && address.includes('#')) {
- const parts = address.split(':');
- address = parts[0];
- const subParts = parts[1].split('#');
- port = subParts[0];
- addressid = subParts[1];
- } else if (address.includes(':')) {
- const parts = address.split(':');
- address = parts[0];
- port = parts[1];
- } else if (address.includes('#')) {
- const parts = address.split('#');
- address = parts[0];
- addressid = parts[1];
- }
-
- if (addressid.includes(':')) {
- addressid = addressid.split(':')[0];
- }
- } else {
- address = match[1];
- port = match[2] || port;
- addressid = match[3] || address;
- }
-
- const httpsPorts = ["2053","2083","2087","2096","8443"];
- if (!isValidIPv4(address) && port == "-1") {
- for (let httpsPort of httpsPorts) {
- if (address.includes(httpsPort)) {
- port = httpsPort;
- break;
- }
- }
- }
- if (port == "-1") port = "443";
-
- let 伪装域名 = host ;
- let 最终路径 = '/?ed=2560' ;
- let 节点备注 = '';
-
- if(proxyhosts.length > 0 && (伪装域名.includes('.workers.dev'))) {
- 最终路径 = `/${伪装域名}${最终路径}`;
- 伪装域名 = proxyhosts[Math.floor(Math.random() * proxyhosts.length)];
- 节点备注 = ` 已启用临时域名中转服务,请尽快绑定自定义域!`;
- }
- const matchingProxyIP = proxyIPPool.find(proxyIP => proxyIP.includes(address));
- if (matchingProxyIP) 最终路径 += `&proxyip=${matchingProxyIP}`;
- let 密码 = pw;
- if (!userAgent.includes('subconverter')) 密码 = encodeURIComponent(pw);
-
- const 啥啥啥_写的这是啥啊 = 'dHJvamFu';
- const 协议类型 = atob(啥啥啥_写的这是啥啊);
- const trojanLink = `${协议类型}://${密码}@${address}:${port}?security=tls&sni=${伪装域名}&fp=randomized&type=ws&host=${伪装域名}&path=${encodeURIComponent(最终路径)}#${encodeURIComponent(addressid + 节点备注)}`;
-
- return trojanLink;
- }).join('\n');
-
- const base64Response = btoa(responseBody); // 重新进行 Base64 编码
-
- return base64Response;
-}
-
-async function getAddressesapi(api) {
- if (!api || api.length === 0) return [];
-
- let newapi = "";
-
- // 创建一个AbortController对象,用于控制fetch请求的取消
- const controller = new AbortController();
-
- const timeout = setTimeout(() => {
- controller.abort(); // 取消所有请求
- }, 2000); // 2秒后触发
-
- try {
- // 使用Promise.allSettled等待所有API请求完成,无论成功或失败
- // 对api数组进行遍历,对每个API地址发起fetch请求
- const responses = await Promise.allSettled(api.map(apiUrl => fetch(apiUrl, {
- method: 'get',
- headers: {
- 'Accept': 'text/html,application/xhtml+xml,application/xml;',
- 'User-Agent': atob('Q0YtV29ya2Vycy1lcGVpdXMvY21saXU=')
- },
- signal: controller.signal // 将AbortController的信号量添加到fetch请求中,以便于需要时可以取消请求
- }).then(response => response.ok ? response.text() : Promise.reject())));
-
- // 遍历所有响应
- for (const [index, response] of responses.entries()) {
- // 检查响应状态是否为'fulfilled',即请求成功完成
- if (response.status === 'fulfilled') {
- // 获取响应的内容
- const content = await response.value;
-
- // 验证当前apiUrl是否带有'proxyip=true'
- if (api[index].includes('proxyip=true')) {
- // 如果URL带有'proxyip=true',则将内容添加到proxyIPPool
- proxyIPPool = proxyIPPool.concat((await ADD(content)).map(item => {
- const baseItem = item.split('#')[0] || item;
- if (baseItem.includes(':')) {
- const port = baseItem.split(':')[1];
- if (!httpsPorts.includes(port)) {
- return baseItem;
- }
- } else {
- return `${baseItem}:443`;
- }
- return null; // 不符合条件时返回 null
- }).filter(Boolean)); // 过滤掉 null 值
- }
- // 将内容添加到newapi中
- newapi += content + '\n';
- }
- }
- } catch (error) {
- console.error(error);
- } finally {
- // 无论成功或失败,最后都清除设置的超时定时器
- clearTimeout(timeout);
- }
-
- const newAddressesapi = await ADD(newapi);
-
- // 返回处理后的结果
- return newAddressesapi;
-}
-
-async function getAddressescsv(tls) {
- if (!addressescsv || addressescsv.length === 0) {
- return [];
- }
-
- let newAddressescsv = [];
-
- for (const csvUrl of addressescsv) {
- try {
- const response = await fetch(csvUrl);
-
- if (!response.ok) {
- console.error('获取CSV地址时出错:', response.status, response.statusText);
- continue;
- }
-
- const text = await response.text();// 使用正确的字符编码解析文本内容
- let lines;
- if (text.includes('\r\n')){
- lines = text.split('\r\n');
- } else {
- lines = text.split('\n');
- }
-
- // 检查CSV头部是否包含必需字段
- const header = lines[0].split(',');
- const tlsIndex = header.indexOf('TLS');
-
- const ipAddressIndex = 0;// IP地址在 CSV 头部的位置
- const portIndex = 1;// 端口在 CSV 头部的位置
- const dataCenterIndex = tlsIndex + 1; // 数据中心是 TLS 的后一个字段
-
- if (tlsIndex === -1) {
- console.error('CSV文件缺少必需的字段');
- continue;
- }
-
- // 从第二行开始遍历CSV行
- for (let i = 1; i < lines.length; i++) {
- const columns = lines[i].split(',');
- const speedIndex = columns.length - 1; // 最后一个字段
- // 检查TLS是否为"TRUE"且速度大于DLS
- if (columns[tlsIndex].toUpperCase() === tls && parseFloat(columns[speedIndex]) > DLS) {
- const ipAddress = columns[ipAddressIndex];
- const port = columns[portIndex];
- const dataCenter = columns[dataCenterIndex];
-
- const formattedAddress = `${ipAddress}:${port}#${dataCenter}`;
- newAddressescsv.push(formattedAddress);
- if (csvUrl.includes('proxyip=true') && columns[tlsIndex].toUpperCase() == 'true' && !httpsPorts.includes(port)) {
- // 如果URL带有'proxyip=true',则将内容添加到proxyIPPool
- proxyIPPool.push(`${ipAddress}:${port}`);
- }
- }
- }
- } catch (error) {
- console.error('获取CSV地址时出错:', error);
- continue;
- }
- }
-
- return newAddressescsv;
-}
-
-function surge(content, url) {
- let 每行内容;
- if (content.includes('\r\n')){
- 每行内容 = content.split('\r\n');
- } else {
- 每行内容 = content.split('\n');
- }
-
- let 输出内容 = "";
- for (let x of 每行内容) {
- if (x.includes('= trojan,')) {
- const host = x.split("sni=")[1].split(",")[0];
- const 备改内容 = `skip-cert-verify=true, tfo=false, udp-relay=false`;
- const 正确内容 = `skip-cert-verify=true, ws=true, ws-path=/?ed=2560, ws-headers=Host:"${host}", tfo=false, udp-relay=false`;
- 输出内容 += x.replace(new RegExp(备改内容, 'g'), 正确内容).replace("[", "").replace("]", "") + '\n';
- } else {
- 输出内容 += x + '\n';
- }
- }
-
- 输出内容 = `#!MANAGED-CONFIG ${url} interval=86400 strict=false` + 输出内容.substring(输出内容.indexOf('\n'));
- return 输出内容;
-}
-
-/**
- * [js-sha256]{@link https://github.com/emn178/js-sha256}
- *
- * @version 0.11.0
- * @author Chen, Yi-Cyuan [emn178@gmail.com]
- * @copyright Chen, Yi-Cyuan 2014-2024
- * @license MIT
- */
-/*jslint bitwise: true */
-(function () {
- 'use strict';
-
- var ERROR = 'input is invalid type';
- var WINDOW = typeof window === 'object';
- var root = WINDOW ? window : {};
- if (root.JS_SHA256_NO_WINDOW) {
- WINDOW = false;
- }
- var WEB_WORKER = !WINDOW && typeof self === 'object';
- var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
- if (NODE_JS) {
- root = global;
- } else if (WEB_WORKER) {
- root = self;
- }
- var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && typeof module === 'object' && module.exports;
- var AMD = typeof define === 'function' && define.amd;
- var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
- var HEX_CHARS = '0123456789abcdef'.split('');
- var EXTRA = [-2147483648, 8388608, 32768, 128];
- var SHIFT = [24, 16, 8, 0];
- var K = [
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
- ];
- var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
-
- var blocks = [];
-
- if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) {
- Array.isArray = function (obj) {
- return Object.prototype.toString.call(obj) === '[object Array]';
- };
- }
-
- if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
- ArrayBuffer.isView = function (obj) {
- return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
- };
- }
-
- var createOutputMethod = function (outputType, is224) {
- return function (message) {
- return new Sha256(is224, true).update(message)[outputType]();
- };
- };
-
- var createMethod = function (is224) {
- var method = createOutputMethod('hex', is224);
- if (NODE_JS) {
- method = nodeWrap(method, is224);
- }
- method.create = function () {
- return new Sha256(is224);
- };
- method.update = function (message) {
- return method.create().update(message);
- };
- for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
- var type = OUTPUT_TYPES[i];
- method[type] = createOutputMethod(type, is224);
- }
- return method;
- };
-
- var nodeWrap = function (method, is224) {
- var crypto = require('crypto')
- var Buffer = require('buffer').Buffer;
- var algorithm = is224 ? 'sha224' : 'sha256';
- var bufferFrom;
- if (Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM) {
- bufferFrom = Buffer.from;
- } else {
- bufferFrom = function (message) {
- return new Buffer(message);
- };
- }
- var nodeMethod = function (message) {
- if (typeof message === 'string') {
- return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
- } else {
- if (message === null || message === undefined) {
- throw new Error(ERROR);
- } else if (message.constructor === ArrayBuffer) {
- message = new Uint8Array(message);
- }
- }
- if (Array.isArray(message) || ArrayBuffer.isView(message) ||
- message.constructor === Buffer) {
- return crypto.createHash(algorithm).update(bufferFrom(message)).digest('hex');
- } else {
- return method(message);
- }
- };
- return nodeMethod;
- };
-
- var createHmacOutputMethod = function (outputType, is224) {
- return function (key, message) {
- return new HmacSha256(key, is224, true).update(message)[outputType]();
- };
- };
-
- var createHmacMethod = function (is224) {
- var method = createHmacOutputMethod('hex', is224);
- method.create = function (key) {
- return new HmacSha256(key, is224);
- };
- method.update = function (key, message) {
- return method.create(key).update(message);
- };
- for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
- var type = OUTPUT_TYPES[i];
- method[type] = createHmacOutputMethod(type, is224);
- }
- return method;
- };
-
- function Sha256(is224, sharedMemory) {
- if (sharedMemory) {
- blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
- blocks[4] = blocks[5] = blocks[6] = blocks[7] =
- blocks[8] = blocks[9] = blocks[10] = blocks[11] =
- blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
- this.blocks = blocks;
- } else {
- this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
- }
-
- if (is224) {
- this.h0 = 0xc1059ed8;
- this.h1 = 0x367cd507;
- this.h2 = 0x3070dd17;
- this.h3 = 0xf70e5939;
- this.h4 = 0xffc00b31;
- this.h5 = 0x68581511;
- this.h6 = 0x64f98fa7;
- this.h7 = 0xbefa4fa4;
- } else { // 256
- this.h0 = 0x6a09e667;
- this.h1 = 0xbb67ae85;
- this.h2 = 0x3c6ef372;
- this.h3 = 0xa54ff53a;
- this.h4 = 0x510e527f;
- this.h5 = 0x9b05688c;
- this.h6 = 0x1f83d9ab;
- this.h7 = 0x5be0cd19;
- }
-
- this.block = this.start = this.bytes = this.hBytes = 0;
- this.finalized = this.hashed = false;
- this.first = true;
- this.is224 = is224;
- }
-
- Sha256.prototype.update = function (message) {
- if (this.finalized) {
- return;
- }
- var notString, type = typeof message;
- if (type !== 'string') {
- if (type === 'object') {
- if (message === null) {
- throw new Error(ERROR);
- } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
- message = new Uint8Array(message);
- } else if (!Array.isArray(message)) {
- if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
- throw new Error(ERROR);
- }
- }
- } else {
- throw new Error(ERROR);
- }
- notString = true;
- }
- var code, index = 0, i, length = message.length, blocks = this.blocks;
- while (index < length) {
- if (this.hashed) {
- this.hashed = false;
- blocks[0] = this.block;
- this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
- blocks[4] = blocks[5] = blocks[6] = blocks[7] =
- blocks[8] = blocks[9] = blocks[10] = blocks[11] =
- blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
- }
-
- if (notString) {
- for (i = this.start; index < length && i < 64; ++index) {
- blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
- }
- } else {
- for (i = this.start; index < length && i < 64; ++index) {
- code = message.charCodeAt(index);
- if (code < 0x80) {
- blocks[i >>> 2] |= code << SHIFT[i++ & 3];
- } else if (code < 0x800) {
- blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3];
- blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
- } else if (code < 0xd800 || code >= 0xe000) {
- blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3];
- blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
- blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
- } else {
- code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
- blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3];
- blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3];
- blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
- blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
- }
- }
- }
-
- this.lastByteIndex = i;
- this.bytes += i - this.start;
- if (i >= 64) {
- this.block = blocks[16];
- this.start = i - 64;
- this.hash();
- this.hashed = true;
- } else {
- this.start = i;
- }
- }
- if (this.bytes > 4294967295) {
- this.hBytes += this.bytes / 4294967296 << 0;
- this.bytes = this.bytes % 4294967296;
- }
- return this;
- };
-
- Sha256.prototype.finalize = function () {
- if (this.finalized) {
- return;
- }
- this.finalized = true;
- var blocks = this.blocks, i = this.lastByteIndex;
- blocks[16] = this.block;
- blocks[i >>> 2] |= EXTRA[i & 3];
- this.block = blocks[16];
- if (i >= 56) {
- if (!this.hashed) {
- this.hash();
- }
- blocks[0] = this.block;
- blocks[16] = blocks[1] = blocks[2] = blocks[3] =
- blocks[4] = blocks[5] = blocks[6] = blocks[7] =
- blocks[8] = blocks[9] = blocks[10] = blocks[11] =
- blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
- }
- blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
- blocks[15] = this.bytes << 3;
- this.hash();
- };
-
- Sha256.prototype.hash = function () {
- var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
- h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
-
- for (j = 16; j < 64; ++j) {
- // rightrotate
- t1 = blocks[j - 15];
- s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
- t1 = blocks[j - 2];
- s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
- blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
- }
-
- bc = b & c;
- for (j = 0; j < 64; j += 4) {
- if (this.first) {
- if (this.is224) {
- ab = 300032;
- t1 = blocks[0] - 1413257819;
- h = t1 - 150054599 << 0;
- d = t1 + 24177077 << 0;
- } else {
- ab = 704751109;
- t1 = blocks[0] - 210244248;
- h = t1 - 1521486534 << 0;
- d = t1 + 143694565 << 0;
- }
- this.first = false;
- } else {
- s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
- s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
- ab = a & b;
- maj = ab ^ (a & c) ^ bc;
- ch = (e & f) ^ (~e & g);
- t1 = h + s1 + ch + K[j] + blocks[j];
- t2 = s0 + maj;
- h = d + t1 << 0;
- d = t1 + t2 << 0;
- }
- s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
- s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
- da = d & a;
- maj = da ^ (d & b) ^ ab;
- ch = (h & e) ^ (~h & f);
- t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
- t2 = s0 + maj;
- g = c + t1 << 0;
- c = t1 + t2 << 0;
- s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
- s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
- cd = c & d;
- maj = cd ^ (c & a) ^ da;
- ch = (g & h) ^ (~g & e);
- t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
- t2 = s0 + maj;
- f = b + t1 << 0;
- b = t1 + t2 << 0;
- s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
- s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
- bc = b & c;
- maj = bc ^ (b & d) ^ cd;
- ch = (f & g) ^ (~f & h);
- t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
- t2 = s0 + maj;
- e = a + t1 << 0;
- a = t1 + t2 << 0;
- this.chromeBugWorkAround = true;
- }
-
- this.h0 = this.h0 + a << 0;
- this.h1 = this.h1 + b << 0;
- this.h2 = this.h2 + c << 0;
- this.h3 = this.h3 + d << 0;
- this.h4 = this.h4 + e << 0;
- this.h5 = this.h5 + f << 0;
- this.h6 = this.h6 + g << 0;
- this.h7 = this.h7 + h << 0;
- };
-
- Sha256.prototype.hex = function () {
- this.finalize();
-
- var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
- h6 = this.h6, h7 = this.h7;
-
- var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
- HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
- HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
- HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
- HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
- HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
- HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
- HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
- HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
- HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
- HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
- HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
- HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
- HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
- HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
- HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
- HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
- HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
- HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
- HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
- HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
- HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
- HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
- HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
- HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
- HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
- HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
- HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
- if (!this.is224) {
- hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
- HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
- HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
- HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
- }
- return hex;
- };
-
- Sha256.prototype.toString = Sha256.prototype.hex;
-
- Sha256.prototype.digest = function () {
- this.finalize();
-
- var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
- h6 = this.h6, h7 = this.h7;
-
- var arr = [
- (h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
- (h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
- (h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
- (h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
- (h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
- (h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
- (h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
- ];
- if (!this.is224) {
- arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
- }
- return arr;
- };
-
- Sha256.prototype.array = Sha256.prototype.digest;
-
- Sha256.prototype.arrayBuffer = function () {
- this.finalize();
-
- var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
- var dataView = new DataView(buffer);
- dataView.setUint32(0, this.h0);
- dataView.setUint32(4, this.h1);
- dataView.setUint32(8, this.h2);
- dataView.setUint32(12, this.h3);
- dataView.setUint32(16, this.h4);
- dataView.setUint32(20, this.h5);
- dataView.setUint32(24, this.h6);
- if (!this.is224) {
- dataView.setUint32(28, this.h7);
- }
- return buffer;
- };
-
- function HmacSha256(key, is224, sharedMemory) {
- var i, type = typeof key;
- if (type === 'string') {
- var bytes = [], length = key.length, index = 0, code;
- for (i = 0; i < length; ++i) {
- code = key.charCodeAt(i);
- if (code < 0x80) {
- bytes[index++] = code;
- } else if (code < 0x800) {
- bytes[index++] = (0xc0 | (code >>> 6));
- bytes[index++] = (0x80 | (code & 0x3f));
- } else if (code < 0xd800 || code >= 0xe000) {
- bytes[index++] = (0xe0 | (code >>> 12));
- bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
- bytes[index++] = (0x80 | (code & 0x3f));
- } else {
- code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
- bytes[index++] = (0xf0 | (code >>> 18));
- bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
- bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
- bytes[index++] = (0x80 | (code & 0x3f));
- }
- }
- key = bytes;
- } else {
- if (type === 'object') {
- if (key === null) {
- throw new Error(ERROR);
- } else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
- key = new Uint8Array(key);
- } else if (!Array.isArray(key)) {
- if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
- throw new Error(ERROR);
- }
- }
- } else {
- throw new Error(ERROR);
- }
- }
-
- if (key.length > 64) {
- key = (new Sha256(is224, true)).update(key).array();
- }
-
- var oKeyPad = [], iKeyPad = [];
- for (i = 0; i < 64; ++i) {
- var b = key[i] || 0;
- oKeyPad[i] = 0x5c ^ b;
- iKeyPad[i] = 0x36 ^ b;
- }
-
- Sha256.call(this, is224, sharedMemory);
-
- this.update(iKeyPad);
- this.oKeyPad = oKeyPad;
- this.inner = true;
- this.sharedMemory = sharedMemory;
- }
- HmacSha256.prototype = new Sha256();
-
- HmacSha256.prototype.finalize = function () {
- Sha256.prototype.finalize.call(this);
- if (this.inner) {
- this.inner = false;
- var innerHash = this.array();
- Sha256.call(this, this.is224, this.sharedMemory);
- this.update(this.oKeyPad);
- this.update(innerHash);
- Sha256.prototype.finalize.call(this);
- }
- };
-
- var exports = createMethod();
- exports.sha256 = exports;
- exports.sha224 = createMethod(true);
- exports.sha256.hmac = createHmacMethod();
- exports.sha224.hmac = createHmacMethod(true);
-
- if (COMMON_JS) {
- module.exports = exports;
- } else {
- root.sha256 = exports.sha256;
- root.sha224 = exports.sha224;
- if (AMD) {
- define(function () {
- return exports;
- });
- }
- }
-})();
-
-/**
- *
- * @param {number} addressType
- * @param {string} addressRemote
- * @param {number} portRemote
- * @param {function} log The logging function.
- */
-async function socks5Connect(addressType, addressRemote, portRemote, log) {
- const { username, password, hostname, port } = parsedSocks5Address;
- // Connect to the SOCKS server
- const socket = connect({
- hostname,
- port,
- });
-
- // Request head format (Worker -> Socks Server):
- // +----+----------+----------+
- // |VER | NMETHODS | METHODS |
- // +----+----------+----------+
- // | 1 | 1 | 1 to 255 |
- // +----+----------+----------+
-
- // https://en.wikipedia.org/wiki/SOCKS#SOCKS5
- // For METHODS:
- // 0x00 NO AUTHENTICATION REQUIRED
- // 0x02 USERNAME/PASSWORD https://datatracker.ietf.org/doc/html/rfc1929
- const socksGreeting = new Uint8Array([5, 2, 0, 2]);
-
- const writer = socket.writable.getWriter();
-
- await writer.write(socksGreeting);
- log('sent socks greeting');
-
- const reader = socket.readable.getReader();
- const encoder = new TextEncoder();
- let res = (await reader.read()).value;
- // Response format (Socks Server -> Worker):
- // +----+--------+
- // |VER | METHOD |
- // +----+--------+
- // | 1 | 1 |
- // +----+--------+
- if (res[0] !== 0x05) {
- log(`socks server version error: ${res[0]} expected: 5`);
- return;
- }
- if (res[1] === 0xff) {
- log("no acceptable methods");
- return;
- }
-
- // if return 0x0502
- if (res[1] === 0x02) {
- log("socks server needs auth");
- if (!username || !password) {
- log("please provide username/password");
- return;
- }
- // +----+------+----------+------+----------+
- // |VER | ULEN | UNAME | PLEN | PASSWD |
- // +----+------+----------+------+----------+
- // | 1 | 1 | 1 to 255 | 1 | 1 to 255 |
- // +----+------+----------+------+----------+
- const authRequest = new Uint8Array([
- 1,
- username.length,
- ...encoder.encode(username),
- password.length,
- ...encoder.encode(password)
- ]);
- await writer.write(authRequest);
- res = (await reader.read()).value;
- // expected 0x0100
- if (res[0] !== 0x01 || res[1] !== 0x00) {
- log("fail to auth socks server");
- return;
- }
- }
-
- // Request data format (Worker -> Socks Server):
- // +----+-----+-------+------+----------+----------+
- // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
- // +----+-----+-------+------+----------+----------+
- // | 1 | 1 | X'00' | 1 | Variable | 2 |
- // +----+-----+-------+------+----------+----------+
- // ATYP: address type of following address
- // 0x01: IPv4 address
- // 0x03: Domain name
- // 0x04: IPv6 address
- // DST.ADDR: desired destination address
- // DST.PORT: desired destination port in network octet order
-
- // addressType
- // 0x01: IPv4 address
- // 0x03: Domain name
- // 0x04: IPv6 address
- // 1--> ipv4 addressLength =4
- // 2--> domain name
- // 3--> ipv6 addressLength =16
- let DSTADDR; // DSTADDR = ATYP + DST.ADDR
- switch (addressType) {
- case 1:
- DSTADDR = new Uint8Array(
- [1, ...addressRemote.split('.').map(Number)]
- );
- break;
- case 3:
- DSTADDR = new Uint8Array(
- [3, addressRemote.length, ...encoder.encode(addressRemote)]
- );
- break;
- case 4:
- DSTADDR = new Uint8Array(
- [4, ...addressRemote.split(':').flatMap(x => [parseInt(x.slice(0, 2), 16), parseInt(x.slice(2), 16)])]
- );
- break;
- default:
- log(`invild addressType is ${addressType}`);
- return;
- }
- const socksRequest = new Uint8Array([5, 1, 0, ...DSTADDR, portRemote >> 8, portRemote & 0xff]);
- await writer.write(socksRequest);
- log('sent socks request');
-
- res = (await reader.read()).value;
- // Response format (Socks Server -> Worker):
- // +----+-----+-------+------+----------+----------+
- // |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
- // +----+-----+-------+------+----------+----------+
- // | 1 | 1 | X'00' | 1 | Variable | 2 |
- // +----+-----+-------+------+----------+----------+
- if (res[1] === 0x00) {
- log("socks connection opened");
- } else {
- log("fail to open socks connection");
- return;
- }
- writer.releaseLock();
- reader.releaseLock();
- return socket;
-}
-
-
-/**
- *
- * @param {string} address
- */
-function socks5AddressParser(address) {
- let [latter, former] = address.split("@").reverse();
- let username, password, hostname, port;
- if (former) {
- const formers = former.split(":");
- if (formers.length !== 2) {
- throw new Error('Invalid SOCKS address format');
- }
- [username, password] = formers;
- }
- const latters = latter.split(":");
- port = Number(latters.pop());
- if (isNaN(port)) {
- throw new Error('Invalid SOCKS address format');
- }
- hostname = latters.join(":");
- const regex = /^\[.*\]$/;
- if (hostname.includes(":") && !regex.test(hostname)) {
- throw new Error('Invalid SOCKS address format');
- }
- //if (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(hostname)) hostname = `${atob('d3d3Lg==')}${hostname}${atob('LmlwLjA5MDIyNy54eXo=')}`;
- return {
- username,
- password,
- hostname,
- port,
- }
-}
-
-function isValidIPv4(address) {
- const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
- return ipv4Regex.test(address);
-}