2022-11-19 22:15:05 +00:00
|
|
|
const rgb = (r, g, b, msg) => `\x1b[38;2;${r};${g};${b}m${msg}\x1b[0m`;
|
|
|
|
const log = (...args) => console.log(`[${rgb(88, 101, 242, "arRPC")} > ${rgb(235, 69, 158, "websocket")}]`, ...args);
|
|
|
|
|
2022-11-20 12:48:07 +00:00
|
|
|
const {WebSocketServer} = require("ws");
|
|
|
|
const {createServer} = require("http");
|
|
|
|
const {parse} = require("querystring");
|
|
|
|
var exportPort = 0000;
|
|
|
|
const portRange = [6463, 6472]; // ports available/possible: 6463-6472
|
2022-11-19 22:15:05 +00:00
|
|
|
|
|
|
|
class WSServer {
|
|
|
|
constructor(messageHandler, connectionHandler) {
|
2022-11-20 12:48:07 +00:00
|
|
|
return (async () => {
|
2022-11-19 22:15:05 +00:00
|
|
|
this.messageHandler = messageHandler;
|
|
|
|
this.connectionHandler = connectionHandler;
|
|
|
|
|
|
|
|
this.onConnection = this.onConnection.bind(this);
|
|
|
|
this.onMessage = this.onMessage.bind(this);
|
|
|
|
|
|
|
|
let port = portRange[0];
|
|
|
|
|
|
|
|
let http, wss;
|
|
|
|
while (port <= portRange[1]) {
|
2022-11-20 12:48:07 +00:00
|
|
|
log("trying port", port);
|
|
|
|
|
|
|
|
if (
|
|
|
|
await new Promise((res) => {
|
|
|
|
http = createServer();
|
|
|
|
http.on("error", (e) => {
|
|
|
|
// log('http error', e);
|
|
|
|
|
|
|
|
if (e.code === "EADDRINUSE") {
|
|
|
|
log(port, "in use!");
|
|
|
|
res(false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
wss = new WebSocketServer({server: http});
|
|
|
|
wss.on("error", (e) => {
|
|
|
|
// log('wss error', e);
|
|
|
|
});
|
|
|
|
|
|
|
|
wss.on("connection", this.onConnection);
|
|
|
|
|
|
|
|
http.listen(port, "127.0.0.1", () => {
|
|
|
|
log("listening on", port);
|
|
|
|
exportPort = port;
|
|
|
|
this.http = http;
|
|
|
|
this.wss = wss;
|
|
|
|
|
|
|
|
res(true);
|
|
|
|
});
|
|
|
|
})
|
|
|
|
)
|
|
|
|
break;
|
|
|
|
port++;
|
2022-11-19 22:15:05 +00:00
|
|
|
}
|
2022-11-20 12:48:07 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
})();
|
2022-11-19 22:15:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onConnection(socket, req) {
|
2022-11-20 12:48:07 +00:00
|
|
|
const params = parse(req.url.split("?")[1]);
|
2022-11-19 22:15:05 +00:00
|
|
|
const ver = parseInt(params.v ?? 1);
|
2022-11-20 12:48:07 +00:00
|
|
|
const encoding = params.encoding ?? "json"; // json | etf (erlpack)
|
2022-11-19 22:15:05 +00:00
|
|
|
const clientId = params.client_id ?? "";
|
|
|
|
|
|
|
|
const origin = req.headers.origin ?? "";
|
|
|
|
|
|
|
|
log(`new connection! origin:`, origin, JSON.parse(JSON.stringify(params)));
|
|
|
|
|
2022-11-20 12:48:07 +00:00
|
|
|
if (
|
|
|
|
origin !== "" &&
|
|
|
|
!["https://discord.com", "https://ptb.discord.com", "https://canary.discord.com/"].includes(origin)
|
|
|
|
) {
|
|
|
|
log("disallowed origin", origin);
|
2022-11-19 22:15:05 +00:00
|
|
|
|
|
|
|
socket.close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (encoding !== "json") {
|
|
|
|
log("unsupported encoding requested", encoding);
|
|
|
|
|
|
|
|
socket.close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ver !== 1) {
|
|
|
|
log("unsupported version requested", ver);
|
|
|
|
|
|
|
|
socket.close();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-11-20 12:48:07 +00:00
|
|
|
/* if (clientId === '') {
|
|
|
|
log('client id required');
|
2022-11-19 22:15:05 +00:00
|
|
|
|
2022-11-20 12:48:07 +00:00
|
|
|
socket.close();
|
|
|
|
return;
|
|
|
|
} */
|
2022-11-19 22:15:05 +00:00
|
|
|
|
|
|
|
socket.clientId = clientId;
|
|
|
|
socket.encoding = encoding;
|
|
|
|
|
|
|
|
socket.on("error", (e) => {
|
|
|
|
log("socket error", e);
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("close", (e, r) => {
|
|
|
|
log("socket closed", e);
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("message", this.onMessage.bind(this, socket));
|
|
|
|
|
|
|
|
socket._send = socket.send;
|
|
|
|
socket.send = (msg) => {
|
|
|
|
log("sending", msg);
|
|
|
|
socket._send(JSON.stringify(msg));
|
|
|
|
};
|
|
|
|
|
|
|
|
this.connectionHandler(socket);
|
|
|
|
}
|
|
|
|
|
|
|
|
onMessage(socket, msg) {
|
|
|
|
log("message", JSON.parse(msg));
|
|
|
|
this.messageHandler(socket, JSON.parse(msg));
|
|
|
|
}
|
|
|
|
}
|
2022-11-20 12:48:07 +00:00
|
|
|
module.exports = {WSServer, exportPort};
|