diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2023-11-04 21:28:11 +0000 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2023-11-04 21:28:11 +0000 |
| commit | 7d8cca54e548d2a85287fd2325db88f2697be55a (patch) | |
| tree | 3daa82c6a709363f2f08d9f875d849e4babe1f8f /backend/src | |
| parent | e1633f3348ff7fc5e9131eeae2f2feba09f04838 (diff) | |
Add more shit
Diffstat (limited to 'backend/src')
| -rw-r--r-- | backend/src/app.ts | 22 | ||||
| -rw-r--r-- | backend/src/config/session-store.ts | 77 | ||||
| -rw-r--r-- | backend/src/router.ts | 8 | ||||
| -rw-r--r-- | backend/src/routes/session.route.ts | 7 | ||||
| -rw-r--r-- | backend/src/websocket/game.ts | 95 |
5 files changed, 209 insertions, 0 deletions
diff --git a/backend/src/app.ts b/backend/src/app.ts new file mode 100644 index 0000000..41b8821 --- /dev/null +++ b/backend/src/app.ts @@ -0,0 +1,22 @@ +import express from 'express'; +import router from './router.js'; +import cors from 'cors'; +import createWebsocketServer from './websocket/game.js'; +import { WebSocketServer } from 'ws'; + +const app = express(); + +app.use(express.json()); +app.use(express.urlencoded({ extended : true})) + +app.use(cors()); + +app.use('/', router); + +const port = parseInt(process.env.PORT || "3000"); + +const server = app.listen(port, () => { + console.log(`Server listening on port ${port}`); +}); + +const websocketServer: WebSocketServer = createWebsocketServer(server);
\ No newline at end of file diff --git a/backend/src/config/session-store.ts b/backend/src/config/session-store.ts new file mode 100644 index 0000000..283031b --- /dev/null +++ b/backend/src/config/session-store.ts @@ -0,0 +1,77 @@ +export type Session = { + id: string; + state: string; + host?: string; + clients: string[]; +}; + +const sessions: { [key: string]: Session } = {}; + +function makeid(length) { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + const charactersLength = characters.length; + let counter = 0; + while (counter < length) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + counter += 1; + } + return result; +} + + +export const createNewSession = (): Session => { + const id = makeid(10); + const session = { + id, + state: "waiting", + host: undefined, + clients: [], + }; + sessions[id] = session; + return session; +}; + +export const setSessionState = (id: string, state: string): void => { + if (!sessions[id]) { + return; + } + + sessions[id].state = state; +}; + +export const setSessionHost = (id: string, clientId: string): void => { + if (!sessions[id]) { + return; + } + + sessions[id].host = clientId; +}; + +export const addSessionClient = (id: string, clientId: string): void => { + if (!sessions[id]) { + return; + } + + sessions[id]?.clients.push(clientId); +}; + +export const cleanupSession = (id: string): void => { + if (!sessions[id]) { + return; + } + +// if (sessions[id].host) { +// sessions[id].host!.close(); +// } +// +// sessions[id].clients.forEach((client) => { +// client.close(); +// }); + + delete sessions[id]; +} + +export const getSession = (id: string): Session => { + return sessions[id]; +};
\ No newline at end of file diff --git a/backend/src/router.ts b/backend/src/router.ts new file mode 100644 index 0000000..b05ce02 --- /dev/null +++ b/backend/src/router.ts @@ -0,0 +1,8 @@ +import express from "express"; +import { createSession } from "./routes/session.route.js"; + +const router = express.Router(); + +router.post("/session", createSession); + +export default router;
\ No newline at end of file diff --git a/backend/src/routes/session.route.ts b/backend/src/routes/session.route.ts new file mode 100644 index 0000000..3ac8525 --- /dev/null +++ b/backend/src/routes/session.route.ts @@ -0,0 +1,7 @@ +import { createNewSession } from "../config/session-store.js"; +import { Request, Response } from "express"; + +export function createSession(req: Request, res: Response) { + const session = createNewSession(); + res.status(201).send(session); +} diff --git a/backend/src/websocket/game.ts b/backend/src/websocket/game.ts new file mode 100644 index 0000000..63c537a --- /dev/null +++ b/backend/src/websocket/game.ts @@ -0,0 +1,95 @@ +import { Server } from "http"; +import { addSessionClient, getSession, setSessionHost } from "../config/session-store.js"; +import { WebSocketServer } from "ws"; +import { v4 as uuidv4 } from "uuid"; + +const wss = new WebSocketServer({ noServer: true }); + +const sendToClient = (clientId: string, message: any) => { + wss.clients.forEach((client: any) => { + if (client.clientId === clientId) { + client.send(JSON.stringify(message)); + } + }); +}; + +const broadcastToClients = (clientIds: string[], message: any) => { + wss.clients.forEach((client: any) => { + if (clientIds.includes(client.clientId)) { + client.send(JSON.stringify(message)); + } + }); +}; + +export const createWebsocketServer = (server: Server): WebSocketServer => { + server.on("upgrade", (req, socket, head) => { + wss.handleUpgrade(req, socket, head, (ws) => { + wss.emit("connection", ws, req); + }); + }); + + wss.on("connection", (ws: any) => { + ws.clientId = uuidv4(); + + ws.on("message", (message) => { + console.log("received: %s", message); + let data; + try { + data = JSON.parse(message.toString()); + } catch (e) { + console.log("Invalid JSON"); + return; + } + + if (data.action === "host") { + setSessionHost(data.sessionId, ws.clientId); + } else if (data.action === "move") { + const session = getSession(data.sessionId); + if (!session) { + return; + } + + sendToClient(session.host!, { + action: "move", + move: data.move, + }); + } else if (data.action === "join") { + const session = getSession(data.sessionId); + if (!session) { + return; + } + + addSessionClient(data.sessionId, ws.clientId); + + sendToClient(session.host!, { + action: "join", + clients: session.clients.length, + }); + + ws.send(JSON.stringify({ + action: "state", + state: session.state, + })); + } else if (data.action === "start") { + const session = getSession(data.sessionId); + if (!session) { + return; + } + + sendToClient(session.host!, { + action: "state", + state: "playing", + }); + + broadcastToClients(session.clients, { + action: "state", + state: "playing", + }); + } + }); + }); + + return wss; +}; + +export default createWebsocketServer; |
