From cb411b59b3972b40cb5b74570e75b0875d4830dd Mon Sep 17 00:00:00 2001 From: Andrew nuark G Date: Sat, 4 Mar 2023 15:05:34 +0700 Subject: [PATCH] A lot of refactoring for new lobby --- src/index.ts | 390 +++++++++++++++++++++++++-------------------------- 1 file changed, 189 insertions(+), 201 deletions(-) diff --git a/src/index.ts b/src/index.ts index d2260f4..4cac358 100644 --- a/src/index.ts +++ b/src/index.ts @@ -52,8 +52,9 @@ class Client { class Game { private id: String; - private player1: Client; - private player2: Client; + private guesser: Client; + private suggester: Client; + private tries: number; private guesses: Set; private colors: Set; @@ -62,10 +63,13 @@ class Game { return this.id; } public get Guesser() { - return this.player1; + return this.guesser; } public get Suggester() { - return this.player2; + return this.suggester; + } + public get Tries() { + return this.tries; } public get Guesses() { return this.guesses; @@ -74,10 +78,11 @@ class Game { return this.colors; } - constructor(id: String, player1: Client, player2: Client) { + constructor(id: String, guesser: Client, suggester: Client, tries: number) { this.id = id; - this.player1 = player1; - this.player2 = player2; + this.guesser = guesser; + this.suggester = suggester; + this.tries = tries; this.guesses = new Set(); this.colors = new Set(); @@ -88,10 +93,10 @@ class Game { } public Opponent(player: Client): Client { - if (this.player1 === player) { - return this.player2; + if (this.guesser === player) { + return this.suggester; } - return this.player1; + return this.guesser; } public Guess(player: Client, guess: String) { @@ -120,42 +125,60 @@ class Game { } public GameLost() { - return this.guesses.size >= 10; + const countOfGuesses = this.guesses.size; + const countOfCorrectGuesses = Array.from(this.guesses).filter((guess) => this.colors.has(guess)).length; + return countOfGuesses - countOfCorrectGuesses >= this.tries; } public simplify() { return { id: this.id, - player1: this.player1.login, - player2: this.player2.login, + guesser: this.guesser.login, + suggester: this.suggester.login, + tries: this.tries, }; } } -class Room { - private _availablePlayers: Map; +class AvailableGame { + private _id: String; + private _player: Client; + private _tries: number; + private _neededRole: String; - public get availablePlayers() { - return this._availablePlayers; + public get id(): String { + return this._id; + } + public get player(): Client { + return this._player; + } + public get tries(): number { + return this._tries; + } + public get neededRole(): String { + return this._neededRole; } - constructor() { - this._availablePlayers = new Map(); + constructor(id: String, player: Client, tries: number, neededRole: String) { + this._id = id; + this._player = player; + this._tries = tries; + this._neededRole = neededRole; } - public addPlayer(player: Client) { - this._availablePlayers.set(player.login, player); - } - - public removePlayer(player: Client) { - this._availablePlayers.delete(player.login); + simplify() { + return { + id: this.id, + player: this.player.login, + tries: this.tries, + neededRole: this.neededRole, + }; } } let registeredClients: Client[] = []; let onlineClients: Map = new Map(); -let guessersRoom: Room = new Room(); -let suggestersRoom: Room = new Room(); +let availableGames: Map = new Map(); let runningGames: Map = new Map(); app.get("/", (req, res) => { @@ -209,146 +232,164 @@ io.on("connection", (socket) => { onlineClients.set(socket, new Client(login, password)); socket.emit("login", true, "User logged in successfully"); + registerSocketLoggedInFunctions(socket); + io.emit("updateNeeded"); }); - socket.on("getUpdate", () => { + socket.on("disconnect", () => { const client = onlineClients.get(socket); - if (client === undefined) { - socket.emit("update", false, 403); - return; + if (client !== undefined) { + console.log("user " + client.login + " disconnected"); + for (const game of Array.from(availableGames.values())) { + if (game.player === client) { + availableGames.delete(game.id); + return; + } + } + if (client.inGame) { + const game = Array.from(runningGames.values()).find((game) => game.Guesser === client || game.Suggester === 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) { + otherClientSocket.emit("leaveGameResponse", true, 410); + } + client.setInGame(false); + opponentPlayer.setInGame(false); + + runningGames.delete(game.Id); + } + } + onlineClients.delete(socket); + } else { + console.log("anonymous disconnected"); } + io.emit("updateNeeded"); + }); +}); + +instrument(io, { + mode: "development", + auth: { + type: "basic", + username: "admin", + password: "$2a$12$84FqmSh7yVv46tdygZ2rNuJYqWPXYtYC3JxjSJBY8PyXB0Oe8qCfO", + }, +}); + +server.listen(9800, () => { + console.log("⚡️ listening on *:9800"); +}); + +function registerSocketLoggedInFunctions(socket: Socket) { + socket.on("getUpdate", getUpdateEventHandler); + socket.on("createGame", createGameEventHandler); + socket.on("joinGame", joinGameEventHandler); + socket.on("removeGame", removeGameEventHandler); + socket.on("chat", chatEventHandler); + socket.on("guess", guessEventHandler); + socket.on("leaveGame", leaveGameEventHandler); + + const client = onlineClients.get(socket)!; + + function getUpdateEventHandler(): void { socket.emit("update", true, { - guessers: Array.from(guessersRoom.availablePlayers.values()).map((e) => e.login), - suggesters: Array.from(suggestersRoom.availablePlayers.values()).map((e) => e.login), + availableGames: Array.from(availableGames.values()).map((e) => e.simplify()), }); - }); + } - socket.on("join", (room) => { - const client = onlineClients.get(socket); - if (client === undefined) { - socket.emit("joinResponse", false, 403); + function createGameEventHandler(tries: number, role: String): void { + if (client.inGame) { + socket.emit("createGameResponse", false, "Player is already in game"); return; } - if (client.inGame || guessersRoom.availablePlayers.has(client.login) || suggestersRoom.availablePlayers.has(client.login)) { - socket.emit("joinResponse", false, 400); + if (tries < 20 || tries > 50) { + socket.emit("createGameResponse", false, "Tries must be between 20 and 50"); return; } - if (room === "guessers") { - guessersRoom.addPlayer(client); - console.log("user " + client.login + " joined guessers"); - socket.emit("joinResponse", [true]); - io.emit("updateNeeded"); - } else if (room === "suggesters") { - suggestersRoom.addPlayer(client); - console.log("user " + client.login + " joined suggesters"); - socket.emit("joinResponse", [true]); - io.emit("updateNeeded"); + if (role !== "guesser" && role !== "suggester") { + socket.emit("createGameResponse", false, "Role must be 'guesser' or 'suggester'"); + return; + } + + for (const game of Array.from(availableGames.values())) { + if (game.player.login === client.login) { + socket.emit("createGameResponse", false, "You already created a game"); + return; + } + } + + const game = new AvailableGame(uuidv4(), client, tries, role); + availableGames.set(game.id, game); + io.emit("updateNeeded"); + } + + function joinGameEventHandler(gameId: String): void { + const game = availableGames.get(gameId); + if (game === undefined) { + socket.emit("joinGameResponse", false, "Game does not exist"); + return; + } + + if (game.player.login === client.login) { + socket.emit("joinGameResponse", false, "You cannot join your own game"); + return; + } + + if (game.player.inGame) { + socket.emit("joinGameResponse", false, "Player is already in game"); + return; + } + + const gameSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === game.player.login); + if (gameSocket === undefined) { + socket.emit("joinGameResponse", false, "Player is not online"); + return; + } + + availableGames.delete(gameId); + io.emit("updateNeeded"); + + let suggester: Client; + let guesser: Client; + if (game.neededRole === "suggester") { + suggester = client; + guesser = game.player; } else { - socket.emit("joinResponse", false, 400); - console.log("user " + client.login + " tried to join non existing room"); + suggester = game.player; + guesser = client; } - }); + suggester.setInGame(true); + guesser.setInGame(true); + const gameInfo = new Game(uuidv4(), guesser, suggester, game.tries); + const suggesterSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === suggester.login)!; + const guesserSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === guesser.login)!; + suggesterSocket.emit("joinGameResponse", true, gameInfo.simplify(), Array.from(gameInfo.Colors)); + guesserSocket.emit("joinGameResponse", true, gameInfo.simplify(), []); + runningGames.set(gameInfo.Id, gameInfo); + } - socket.on("leave", (room) => { - const client = onlineClients.get(socket); - if (client === undefined) { - socket.emit("leaveResponse", false, 403); + function removeGameEventHandler(gameId: String): void { + const game = availableGames.get(gameId); + if (game === undefined) { + socket.emit("removeGameResponse", false, "Game does not exist"); return; } - if (client.inGame || (!guessersRoom.availablePlayers.has(client.login) && !suggestersRoom.availablePlayers.has(client.login))) { - socket.emit("leaveResponse", false, 400); + if (game.player.login !== client.login) { + socket.emit("removeGameResponse", false, "You cannot remove game that is not yours"); return; } - if (room === "guessers") { - guessersRoom.removePlayer(client); - console.log("user " + client.login + " left guessers"); - socket.emit("leaveResponse", [true]); - io.emit("updateNeeded"); - } else if (room === "suggesters") { - suggestersRoom.removePlayer(client); - console.log("user " + client.login + " left suggesters"); - socket.emit("leaveResponse", [true]); - io.emit("updateNeeded"); - } else { - socket.emit("leaveResponse", false, 400); - console.log("user " + client.login + " tried to left non existing room"); - } - }); - - socket.on("sendRequest", (sendTo) => { - const client = onlineClients.get(socket); - if (client === undefined) { - socket.emit("sendRequestResponse", false, 403); - return; - } - - if (client.inGame || sendTo === client.login) { - socket.emit("sendRequestResponse", false, 400); - return; - } - - const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === sendTo); - if (otherClientSocket === undefined) { - socket.emit("sendRequestResponse", false, 404); - return; - } - - otherClientSocket.emit("gameRequest", client.login); - 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; - } - const otherClient = onlineClients.get(otherClientSocket)!; - - if (response) { - const isClientInGuessers = guessersRoom.availablePlayers.has(client.login); - guessersRoom.removePlayer(client); - suggestersRoom.removePlayer(client); - guessersRoom.removePlayer(otherClient); - suggestersRoom.removePlayer(otherClient); - io.emit("updateNeeded"); - - const game = new Game(uuidv4(), isClientInGuessers ? client : otherClient, isClientInGuessers ? otherClient : client); - runningGames.set(game.Id, game); - client.setInGame(true); - otherClient.setInGame(true); - socket.emit("requestResponseResult", true, game.simplify(), Array.from(game.Guesses)); - otherClientSocket.emit("requestResponseResult", true, game.simplify(), Array.from(game.Colors)); - } 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; - } + availableGames.delete(gameId); + io.emit("updateNeeded"); + } + function chatEventHandler(gameId: String, message: String): void { const game = runningGames.get(gameId); if (game === undefined || !client.inGame) { socket.emit("chatResponse", false, 400); @@ -374,15 +415,9 @@ io.on("connection", (socket) => { from: client.login, message, }); - }); - - socket.on("guess", (gameId, guess) => { - const client = onlineClients.get(socket); - if (client === undefined) { - socket.emit("guessResponse", false, 403); - return; - } + } + function guessEventHandler(gameId: String, guess: String): void { const game = runningGames.get(gameId); if (game === undefined || !client.inGame) { socket.emit("guessResponse", false, 400); @@ -428,15 +463,9 @@ io.on("connection", (socket) => { opponentPlayer.setInGame(false); runningGames.delete(gameId); } - }); - - socket.on("leaveGame", (gameId) => { - const client = onlineClients.get(socket); - if (client === undefined) { - socket.emit("guessResponse", false, 403); - return; - } + } + function leaveGameEventHandler(gameId: String): void { const game = runningGames.get(gameId); if (game === undefined || !client.inGame) { socket.emit("guessResponse", false, 400); @@ -455,46 +484,5 @@ io.on("connection", (socket) => { client.setInGame(false); opponentPlayer.setInGame(false); runningGames.delete(game.Id); - }); - - 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.Guesser === client || game.Suggester === 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) { - otherClientSocket.emit("leaveGameResponse", true, 410); - } - client.setInGame(false); - opponentPlayer.setInGame(false); - - runningGames.delete(game.Id); - } - } - onlineClients.delete(socket); - } else { - console.log("anonymous disconnected"); - } - - io.emit("updateNeeded"); - }); -}); - -instrument(io, { - mode: "development", - auth: { - type: "basic", - username: "admin", - password: "$2a$12$84FqmSh7yVv46tdygZ2rNuJYqWPXYtYC3JxjSJBY8PyXB0Oe8qCfO", - }, -}); - -server.listen(9800, () => { - console.log("⚡️ listening on *:9800"); -}); + } +}