79 lines
2.4 KiB
JavaScript
79 lines
2.4 KiB
JavaScript
var express = require("express");
|
|
var qs = require("qs");
|
|
var proxyaddr = require("proxy-addr");
|
|
var {WebSocketServer} = require("ws");
|
|
|
|
var app = express();
|
|
app.set("trust proxy", "loopback");
|
|
app.use(express.static("frontend"));
|
|
var server = app.listen(process.env.PORT || 924, process.env.ADDRESS);
|
|
|
|
var wss = new WebSocketServer({server, clientTracking: true});
|
|
|
|
var chatlog = [];
|
|
|
|
wss.on("connection", (ws, req) => {
|
|
req.ip = proxyaddr(req, app.get("trust proxy"));
|
|
req.query = qs.parse(req.url.substr(req.url.indexOf('?')+1));
|
|
|
|
function broadcast(msg, excludeSelf) {
|
|
if (typeof msg == "object" && !(msg instanceof Buffer)) msg = JSON.stringify(msg);
|
|
for (let ows of wss.clients) if (!(ows == ws && excludeSelf)) ows.send(msg);
|
|
}
|
|
function broadcastChat(message) {
|
|
broadcast({type: "chat", message});
|
|
chatlog.push(message);
|
|
if (chatlog.length >= 100) chatlog.shift();
|
|
}
|
|
|
|
ws.user = {
|
|
uid: req.ip,
|
|
nick: req.query.nick || req.ip,
|
|
color: [Math.floor(Math.random()*256),Math.floor(Math.random()*256),Math.floor(Math.random()*256)]
|
|
}
|
|
let t = Array.from(wss.clients).map(ws => ws.user.id);
|
|
for (let i = 0; i < 256; i++) if (!t.includes(i)) { ws.user.id = i; break; }
|
|
if (ws.user.id == null) return ws.close();
|
|
|
|
console.log("join", ws.user);
|
|
|
|
ws.send(JSON.stringify({
|
|
type: "load",
|
|
id: ws.user.id,
|
|
uid: ws.user.uid,
|
|
users: Array.from(wss.clients).map(x => x.user),
|
|
chatlog
|
|
}));
|
|
|
|
broadcast({type: "join", id: ws.user.id, uid: ws.user.uid, nick: ws.user.nick, color: ws.user.color}, true);
|
|
broadcastChat({type: "join", id: ws.user.id, uid: ws.user.uid, nick: ws.user.nick});
|
|
ws.on("close", () => {
|
|
console.log("leave", ws.user);
|
|
broadcast({type: "leave", id: ws.user.id, uid: ws.user.uid, nick: ws.user.nick, color: ws.user.color}, true);
|
|
broadcastChat({type: "leave", id: ws.user.id, uid: ws.user.uid, nick: ws.user.nick})
|
|
});
|
|
|
|
ws.on("message", (msg, isBinary) => {
|
|
if (isBinary) {
|
|
broadcast(Buffer.concat([msg, Buffer.from([ws.user.id])]), true);
|
|
} else {
|
|
msg = msg.toString();
|
|
try {
|
|
msg = JSON.parse(msg);
|
|
} catch (error) { return }
|
|
console.log(msg);
|
|
switch (msg.type) {
|
|
case "chat":
|
|
broadcastChat({type: "message", content: msg.message, user: ws.user});
|
|
break;
|
|
case "nick":
|
|
ws.user.nick = msg.nick;
|
|
broadcast({type: "nick", nick: ws.user.nick, id: ws.user.id, uid: ws.user.uid});
|
|
broadcastChat({type: "nick", nick: ws.user.nick, id: ws.user.id});
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|