var {WebSocket, WebSocketServer} = require("ws"); var {server} = require("./index.js"); var wss = new WebSocketServer({ server, clientTracking: true }); wss.on('connection', ws => { for (let w of wss.clients) { if (w.id == null) continue; if (w.m) { let b = Buffer.alloc(5); b.writeUInt8(w.id, 0); b.writeInt16BE(w.m.x, 1); b.writeInt16BE(w.m.y, 3); ws.send(b); } if (w.txt) { ws.send(JSON.stringify(["type", w.id, w.txt])); } } ws.id = (function newId(){ var used_ids = [...wss.clients].map(ws => ws.id); for (var id = 0; id < 256; id++) { if (!used_ids.includes(id)) return id; } ws.close(); })(); function broadcast(data) { if (typeof data == "object" && !Buffer.isBuffer(data)) data = JSON.stringify(data); wss.clients.forEach(client => { if (client != ws && client.readyState == WebSocket.OPEN) { client.send(data, { binary: typeof data != "string" }); } }); } broadcast(["join", ws.id]); ws.on("close", () => { broadcast(["gone", ws.id]); }); ws.on('message', (data, isBinary) => { try { if (isBinary) { if (data.length == 1) { // click broadcast(Buffer.from([ws.id, data.readUint8(0)])); } else { // move var x = data.readInt16BE(0); var y = data.readInt16BE(2); var b = Buffer.alloc(5); b.writeUInt8(ws.id, 0); b.writeInt16BE(x, 1); b.writeInt16BE(y, 3); broadcast(b); ws.m = {x, y}; } } else { var txt = data.toString(); broadcast(["type", ws.id, txt]); if (txt == "") { ws.txt = ""; } else if (txt == "Backspace") { ws.txt = ws.txt.slice(0, -1); } else if (txt == "Delete") { ws.txt = ws.txt.slice(1); } else { ws.txt ||= ""; ws.txt += txt; } } } catch (error) { console.error(error.message); } }); ws.on('error', console.error); });