From a804f4195695f2e62cf96eadc6b0fdb4f513b57b Mon Sep 17 00:00:00 2001 From: Tiago Ramos <2222055@my.ipleiria.pt> Date: Fri, 2 Jan 2026 22:11:47 +0000 Subject: [PATCH] Final touches --- api/app/Http/Controllers/GameController.php | 35 +++++++++----- websockets/events/connection.js | 2 - websockets/state/game.js | 51 +++++++++------------ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/api/app/Http/Controllers/GameController.php b/api/app/Http/Controllers/GameController.php index 057306e..f4d5cf4 100644 --- a/api/app/Http/Controllers/GameController.php +++ b/api/app/Http/Controllers/GameController.php @@ -55,42 +55,55 @@ class GameController extends Controller $validated = $request->validate([ "type" => "required|in:3,9", + "player2_user_id" => "nullable|integer|exists:users,id", + "match_id" => "nullable|integer|exists:matches,id", + "status" => "nullable|in:Pending,Playing", + "began_at" => "nullable|date" ]); $user = Auth::user(); $activeGame = Game::where(function ($q) use ($user) { - $q->where("player1_user_id", $user->id) - ->orWhere("player2_user_id", $user->id); + $q->where("player1_user_id", $user->id) + ->orWhere("player2_user_id", $user->id); }) ->whereIn("status", ["Pending", "Playing"]) ->exists(); if ($activeGame) { - return response()->json(["message" => "You already have an active game."], 400); + return response()->json(["message" => "You already have an active game."], 400); + } + + $player2Id = $request->input('player2_user_id', self::GHOST_ID); + + $initialStatus = $request->input('status', 'Pending'); + + if ($player2Id !== self::GHOST_ID && !$request->has('status')) { + $initialStatus = 'Playing'; } $game = Game::create([ "type" => $validated["type"], - "status" => "Pending", + "status" => $initialStatus, "player1_user_id" => $user->id, - "player2_user_id" => self::GHOST_ID, - "winner_user_id" => self::GHOST_ID, - "loser_user_id" => self::GHOST_ID, - "began_at" => now(), + "player2_user_id" => $player2Id, + "winner_user_id" => null, + "loser_user_id" => null, + "match_id" => $request->input('match_id', null), + "began_at" => $request->input('began_at', now()), "player1_points" => 0, "player2_points" => 0, "custom" => null, ]); return response()->json([ - "message" => "Multiplayer game room created", + "message" => "Game created", "game" => $game, ], 201); } -public function join(Request $request, Game $game) -{ + public function join(Request $request, Game $game) + { // Prevent joining if already full or started if ($game->status !== 'Pending' || $game->player2_user_id !== 1) { return response()->json(['message' => 'Game is not available'], 400); diff --git a/websockets/events/connection.js b/websockets/events/connection.js index f73afac..bc87427 100644 --- a/websockets/events/connection.js +++ b/websockets/events/connection.js @@ -1,6 +1,4 @@ import { addUser, removeUser } from "../state/connection.js"; -import { addUser, removeUser } from "../state/connection.js"; - const HEARTBEAT_INTERVAL = 30000; // 30 seconds const HEARTBEAT_TIMEOUT = 10000; // 10 seconds diff --git a/websockets/state/game.js b/websockets/state/game.js index 4fb5af1..e3caa9e 100644 --- a/websockets/state/game.js +++ b/websockets/state/game.js @@ -2,40 +2,33 @@ import BiscaGame from "../classes/BiscaGame.js"; const activeGames = new Map(); -const createGame = (id, type, player1, player2) => { - const existingGame = activeGames.get(id); - if (existingGame) { - console.log( - `[Game State] Game ${id} already exists, returning existing instance`, - ); - return existingGame; - } - const game = new BiscaGame(id, type, player1, player2); +export const createGame = (id, type, player1, player2) => { + const existingGame = activeGames.get(id); + if (existingGame) { + console.log( + `[Game State] Game ${id} already exists, returning existing instance` + ); + return existingGame; + } + const game = new BiscaGame(id, type, player1, player2); - game.init(); + game.init(); - activeGames.set(id, game); + activeGames.set(id, game); - console.log(`[Game State] Game created: ${id} (Type: ${type})`); - return game; + console.log(`[Game State] Game created: ${id} (Type: ${type})`); + return game; }; -const getGame = (id) => { - return activeGames.get(id); +export const getGame = (id) => { + return activeGames.get(id); }; -const removeGame = (id) => { - const game = activeGames.get(id); - if (game) { - game.stopTimer(); - activeGames.delete(id); - console.log(`[Game State] Game removed: ${id}`); - } +export const removeGame = (id) => { + const game = activeGames.get(id); + if (game) { + game.stopTimer(); + activeGames.delete(id); + console.log(`[Game State] Game removed: ${id}`); + } }; - -module.exports = { - createGame, - getGame, - removeGame, -}; -