const { WebSocketServer } = require('ws'); const crypto = require('crypto'); const version = 1; const wss = new WebSocketServer({ port: 12378 }); // wss://ponies.equestria.horse/_PairingServices-WebSocket-EntryPoint/socket let clients = {}; function generateCode() { return crypto.randomBytes(32).toString("base64").replace(/[\/=+]/gm, "").substring(0, 5).toUpperCase(); } wss.on('connection', (ws, req) => { ws.code = generateCode(); ws.ipAddress = req.headers['x-forwarded-for'] ? req.headers['x-forwarded-for'].split(',')[0].trim() : req.socket.remoteAddress; ws.on('error', (e) => { console.error(e); ws.close(); }); ws.on('close', () => { if (clients[ws.code]) { delete clients[ws.code]; } }); ws.on('message', function message(raw) { try { let data = JSON.parse(raw.toString()); switch (data.type) { case "fetch": if (clients[data.code ?? ""] && clients[data.code ?? ""].socket) { clients[data.code ?? ""].socket.send(JSON.stringify({ type: "preflight", identity: { name: data.identity ? (data.identity.name ?? "") : "", platform: data.identity ? (data.identity.platform ?? "") : "" } })); ws.send(JSON.stringify({ type: "device", identity: { name: clients[data.code ?? ""].name, address: clients[data.code ?? ""].socket.ipAddress } })) } else { ws.send(JSON.stringify({ type: "invalid" })); } break; case "confirm": if (clients[data.code ?? ""] && clients[data.code ?? ""].socket && data.token && ws.token) { clients[data.code ?? ""].socket.send(JSON.stringify({ type: "confirm", token: data.token })); delete clients[data.code ?? ""]; } else { ws.send(JSON.stringify({ type: "invalid" })); } break; case "reject": if (clients[data.code ?? ""] && clients[data.code ?? ""].socket && ws.token) { clients[data.code ?? ""].socket.send(JSON.stringify({ type: "reject", token: null })); delete clients[data.code ?? ""]; } else { ws.send(JSON.stringify({ type: "invalid" })); } break; case "init": if (data.token) { ws.token = data.token; } else { clients[ws.code] = { socket: ws, name: (typeof data.name === "string" && data.name.length > 2 && data.name.length < 50) ? data.name : "" } ws.send(JSON.stringify({ type: "waiting", code: ws.code })) } break; default: ws.close(); } } catch (e) { console.error(e); ws.close(); } }); ws.send(JSON.stringify({ version, type: "init" })); });