1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
import Express, { static as estatic, json } from "express";
import { join } from "path";
import Webpack from "webpack"
import WebpackDevMiddleware from "webpack-dev-middleware"
import { existsSync, readFile, readFileSync } from "fs";
import http from "http"
import https from "https"
import expressWs from "express-ws";
import { CSPacket, SCPacket } from "../client/types";
type Room = Map<string, any>
const rooms: Map<string, Room> = new Map()
function ws_send(ws: any, data: string) {
try { ws.send(data) }
catch (e) { console.warn("i hate express-ws") }
}
async function main() {
const app_e = Express();
const app = expressWs(app_e).app
if (process.env.PRODUCTION) {
app.use("/scripts", estatic(join(__dirname, "../../public/dist")))
} else {
const webpackConfig = require('../../webpack.config');
const compiler = Webpack(webpackConfig)
const devMiddleware = WebpackDevMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath
})
app.use("/scripts", devMiddleware)
}
app.disable("x-powered-by");
app.use(json());
app.get("/", (req, res) => {
res.sendFile(join(__dirname, "../../public/index.html"));
});
app.get("/room/:id", (req, res) => {
res.sendFile(join(__dirname, "../../public/index.html"));
});
app.use("/static", estatic(join(__dirname, "../../public")));
app.ws("/room/:id", (ws, req) => {
const room_name = req.params.id
const room = rooms.get(req.params.id) ?? new Map()
let initialized = false
let user_name = ""
const init = (n: string) => {
initialized = true
user_name = n
rooms.set(req.params.id, room)
room.forEach((_, uws) => ws_send(uws, JSON.stringify({ sender: user_name, join: true })))
room.set(user_name, ws)
console.log(`[${room_name}] ${user_name} joined`)
}
ws.onclose = () => {
room.delete(user_name)
room.forEach((_, uws) => ws_send(uws, JSON.stringify({ sender: user_name, leave: true })))
if (room.size == 0) rooms.delete(room_name)
console.log(`[${room_name}] ${user_name} left`)
}
ws.onmessage = ev => {
const message = ev.data.toString()
let in_packet: CSPacket;
try { in_packet = JSON.parse(message) }
catch (e) { return }
if (!initialized) return init(message)
console.log(`[${room_name}] ${user_name} -> ${in_packet.receiver ?? "*"}: ${message}`)
const out_packet: SCPacket = { sender: user_name, data: in_packet }
if (in_packet.receiver) {
const rws = room.get(in_packet.receiver)
if (rws) ws_send(rws, JSON.stringify(out_packet))
} else {
room.forEach((uname, uws) => {
if (uname != user_name) ws_send(uws, JSON.stringify(out_packet))
})
}
}
})
app.use((req, res, next) => {
res.status(404);
res.send("This is an error page");
});
const port = parseInt(process.env.PORT ?? "8080")
app.listen(port, process.env.HOST ?? "127.0.0.1", () => {
console.log(`Server listening on ${process.env.HOST ?? "127.0.0.1"}:${port}`);
})
}
main();
|