forked from yixiu001/ct8-script
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
49 lines (38 loc) · 1.8 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const fs = require('fs');
const net = require('net');
const WebSocket = require('ws');
const logcb = (...args) => console.log.bind(this, ...args);
const errcb = (...args) => console.error.bind(this, ...args);
// 读取配置文件
let config;
try {
const data = fs.readFileSync('config.json', 'utf8');
config = JSON.parse(data);
} catch (err) {
console.error('Error reading config.json:', err);
process.exit(1);
}
const uuid = config.uuid.replace(/-/g, '');
const port = config.port;
const wss = new WebSocket.Server({ port }, logcb('listen:', port));
wss.on('connection', ws => {
console.log("on connection");
ws.once('message', msg => {
const [VERSION] = msg;
const id = msg.slice(1, 17);
if (!id.every((v, i) => v === parseInt(uuid.substr(i * 2, 2), 16))) return;
let i = msg.slice(17, 18).readUInt8() + 19;
const targetPort = msg.slice(i, i += 2).readUInt16BE(0);
const ATYP = msg.slice(i, i += 1).readUInt8();
const host = ATYP === 1 ? msg.slice(i, i += 4).join('.') : // IPV4
(ATYP === 2 ? new TextDecoder().decode(msg.slice(i + 1, i += 1 + msg.slice(i, i + 1).readUInt8())) : // domain
(ATYP === 3 ? msg.slice(i, i += 16).reduce((s, b, i, a) => (i % 2 ? s.concat(a.slice(i - 1, i + 1)) : s), []).map(b => b.readUInt16BE(0).toString(16)).join(':') : '')); // IPV6
logcb('conn:', host, targetPort);
ws.send(new Uint8Array([VERSION, 0]));
const duplex = WebSocket.createWebSocketStream(ws);
net.connect({ host, port: targetPort }, function () {
this.write(msg.slice(i));
duplex.on('error', errcb('E1:')).pipe(this).on('error', errcb('E2:')).pipe(duplex);
}).on('error', errcb('Conn-Err:', { host, port: targetPort }));
}).on('error', errcb('EE:'));
});