nonstopmmd/mousie-server.js
2023-10-13 20:34:08 -07:00

77 lines
1.8 KiB
JavaScript

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);
});