A lot of refactoring for new lobby

This commit is contained in:
Andrew 2023-03-04 15:05:34 +07:00
parent 943af813e6
commit cb411b59b3

View file

@ -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<String>;
private colors: Set<String>;
@ -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<String>();
this.colors = new Set<String>();
@ -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<String, Client>;
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<String, Client>();
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<Socket, Client> = new Map<Socket, Client>();
let guessersRoom: Room = new Room();
let suggestersRoom: Room = new Room();
let availableGames: Map<String, AvailableGame> = new Map<String, AvailableGame>();
let runningGames: Map<String, Game> = new Map<String, Game>();
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);
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]);
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");
} else if (room === "suggesters") {
suggestersRoom.addPlayer(client);
console.log("user " + client.login + " joined suggesters");
socket.emit("joinResponse", [true]);
}
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]);
availableGames.delete(gameId);
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;
}
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);
@ -454,47 +483,6 @@ 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");
});