From 79d439e10aa5af04fda01a5a1c371b6f3049b71f Mon Sep 17 00:00:00 2001 From: Andrew nuark G Date: Fri, 3 Mar 2023 21:27:48 +0700 Subject: [PATCH] Implemented game room as chat for now --- package.json | 6 ++- pnpm-lock.yaml | 21 ++++++-- src/index.ts | 140 ++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 150 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 355de73..deede2b 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,15 @@ "@socket.io/admin-ui": "^0.5.1", "dotenv": "^16.0.3", "express": "^4.18.2", - "socket.io": "^4.6.1" + "socket.io": "^4.6.1", + "uuid": "^9.0.0" }, "devDependencies": { "@types/express": "^4.17.17", "@types/node": "^18.14.4", + "@types/uuid": "^9.0.1", + "concurrently": "^7.6.0", + "nodemon": "^2.0.21", "typescript": "^4.9.5" } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8c3c99..661a7a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,24 +4,28 @@ specifiers: '@socket.io/admin-ui': ^0.5.1 '@types/express': ^4.17.17 '@types/node': ^18.14.4 + '@types/uuid': ^9.0.1 concurrently: ^7.6.0 dotenv: ^16.0.3 express: ^4.18.2 - nodemon: ^2.0.20 + nodemon: ^2.0.21 socket.io: ^4.6.1 typescript: ^4.9.5 + uuid: ^9.0.0 dependencies: '@socket.io/admin-ui': 0.5.1_socket.io@4.6.1 dotenv: 16.0.3 express: 4.18.2 socket.io: 4.6.1 + uuid: 9.0.0 devDependencies: '@types/express': 4.17.17 '@types/node': 18.14.4 + '@types/uuid': 9.0.1 concurrently: 7.6.0 - nodemon: 2.0.20 + nodemon: 2.0.21 typescript: 4.9.5 packages: @@ -109,6 +113,10 @@ packages: '@types/node': 18.14.4 dev: true + /@types/uuid/9.0.1: + resolution: {integrity: sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==} + dev: true + /abbrev/1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: true @@ -656,8 +664,8 @@ packages: engines: {node: '>= 0.6'} dev: false - /nodemon/2.0.20: - resolution: {integrity: sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==} + /nodemon/2.0.21: + resolution: {integrity: sha512-djN/n2549DUtY33S7o1djRCd7dEm0kBnj9c7S9XVXqRUbuggN1MZH/Nqa+5RFQr63Fbefq37nFXAE9VU86yL1A==} engines: {node: '>=8.10.0'} hasBin: true dependencies: @@ -978,6 +986,11 @@ packages: engines: {node: '>= 0.4.0'} dev: false + /uuid/9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: false + /vary/1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} diff --git a/src/index.ts b/src/index.ts index d1d60c7..341942c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import express, { Express, Request, Response } from "express"; import http from "http"; +import { v4 as uuidv4 } from "uuid"; import { Server, Socket } from "socket.io"; import { instrument } from "@socket.io/admin-ui"; @@ -7,7 +8,12 @@ import { instrument } from "@socket.io/admin-ui"; const app = express(); const server = http.createServer(app); -const io = new Server(server); +const io = new Server(server, { + cors: { + origin: ["https://admin.socket.io"], + credentials: true, + }, +}); class Client { private _login: String; @@ -33,23 +39,49 @@ class Client { public setInGame(inGame: Boolean) { this._inGame = inGame; } + + public simplify() { + return { + login: this.login, + inGame: this.inGame, + }; + } } class Game { + private id: String; private player1: Client; private player2: Client; - private turn: Number; - private board: Number[][]; - constructor(player1: Client, player2: Client) { + public get Id() { + return this.id; + } + public get Player1() { + return this.player1; + } + public get Player2() { + return this.player2; + } + + constructor(id: String, player1: Client, player2: Client) { + this.id = id; this.player1 = player1; this.player2 = player2; - this.turn = 1; - this.board = [ - [0, 0, 0], - [0, 0, 0], - [0, 0, 0], - ]; + } + + public Opponent(player: Client): Client { + if (this.player1 === player) { + return this.player2; + } + return this.player1; + } + + public simplify() { + return { + id: this.id, + player1: this.player1.login, + player2: this.player2.login, + }; } } @@ -77,6 +109,7 @@ let registeredClients: Client[] = []; let onlineClients: Map = new Map(); let guessersRoom: Room = new Room(); let suggestersRoom: Room = new Room(); +let runningGames: Map = new Map(); app.get("/", (req, res) => { res.send("

Hello world

"); @@ -209,7 +242,7 @@ io.on("connection", (socket) => { return; } - const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)!!.login === sendTo); + const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === sendTo); if (otherClientSocket === undefined) { socket.emit("sendRequestResponse", false, 404); return; @@ -219,12 +252,90 @@ io.on("connection", (socket) => { socket.emit("sendRequestResponse", [true]); }); + socket.on("requestResponse", (requester: String, response: Boolean) => { + const client = onlineClients.get(socket); + if (client === undefined) { + socket.emit("requestResponseResult", false, 403); + return; + } + + if (client.inGame || requester === client.login) { + socket.emit("requestResponseResult", false, 400); + return; + } + + const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === requester); + if (otherClientSocket === undefined) { + socket.emit("requestResponseResult", false, 404); + return; + } + + if (response) { + const game = new Game(uuidv4(), client, onlineClients.get(otherClientSocket)!); + runningGames.set(game.Id, game); + client.setInGame(true); + onlineClients.get(otherClientSocket)!.setInGame(true); + socket.emit("requestResponseResult", true, game.simplify()); + otherClientSocket.emit("requestResponseResult", true, game.simplify()); + } else { + socket.emit("requestResponseResult", false, `You declined ${client.login} request`); + otherClientSocket.emit("requestResponseResult", false, `${client.login} declined your request`); + } + }); + + socket.on("chat", (gameId, message) => { + const client = onlineClients.get(socket); + if (client === undefined) { + socket.emit("chatResponse", false, 403); + return; + } + + const game = runningGames.get(gameId); + if (game === undefined || !client.inGame) { + socket.emit("chatResponse", false, 400); + console.log("user " + client.login + " tried to chat in non existing game"); + + return; + } + + const opponentPlayer = game.Opponent(client); + const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === opponentPlayer.login); + if (otherClientSocket === undefined) { + socket.emit("chatResponse", false, 404); + console.log("user " + client.login + " tried to chat with non existing user"); + + return; + } + + socket.emit("chatResponse", true, { + from: client.login, + message, + }); + otherClientSocket.emit("chatResponse", true, { + from: client.login, + message, + }); + }); + socket.on("disconnect", () => { const client = onlineClients.get(socket); if (client !== undefined) { console.log("user " + client.login + " disconnected"); guessersRoom.removePlayer(client); suggestersRoom.removePlayer(client); + if (client.inGame) { + const game = Array.from(runningGames.values()).find((game) => game.Player1 === client || game.Player2 === client); + if (game !== undefined) { + const opponentPlayer = game.Opponent(client); + const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === opponentPlayer.login); + if (otherClientSocket !== undefined) { + // TODO: For now chatResponse used + otherClientSocket.emit("chatResponse", false, 410); + } + + runningGames.delete(game.Id); + } + } onlineClients.delete(socket); } else { console.log("anonymous disconnected"); @@ -235,7 +346,12 @@ io.on("connection", (socket) => { }); instrument(io, { - auth: false, + mode: "development", + auth: { + type: "basic", + username: "admin", + password: "$2a$12$84FqmSh7yVv46tdygZ2rNuJYqWPXYtYC3JxjSJBY8PyXB0Oe8qCfO", + }, }); server.listen(9800, () => {