From 3a7b1b9794e4115cbb4d1944a37a2e686f6e3d2b Mon Sep 17 00:00:00 2001 From: FernandoJVideira <03.pleaser-minster@icloud.com> Date: Fri, 2 Jan 2026 14:26:54 +0000 Subject: [PATCH] fix:websocket errors & polict change --- api/app/Policies/GamePolicy.php | 26 +++++++++++++-------- bruno_collection/Games/Create Game.bru | 15 ++++++++++++ websockets/classes/BiscaGame.js | 32 ++++++++++++++------------ websockets/events/connection.js | 16 ++++++------- websockets/package.json | 1 + websockets/state/game.js | 16 +++++-------- 6 files changed, 64 insertions(+), 42 deletions(-) create mode 100644 bruno_collection/Games/Create Game.bru diff --git a/api/app/Policies/GamePolicy.php b/api/app/Policies/GamePolicy.php index 157f98c..7345bfb 100644 --- a/api/app/Policies/GamePolicy.php +++ b/api/app/Policies/GamePolicy.php @@ -20,7 +20,7 @@ class GamePolicy */ public function view(User $user, Game $game): bool { - if ($user->type === 'A') { + if ($user->type === "A") { return true; } @@ -31,6 +31,10 @@ class GamePolicy return true; } + if ($game->status === "Pending") { + return true; + } + return false; } @@ -39,7 +43,7 @@ class GamePolicy */ public function create(User $user): bool { - if ($user->type === 'A') { + if ($user->type === "A") { return false; } @@ -48,28 +52,32 @@ class GamePolicy public function join(User $user, Game $game): bool { - if ($user->type === 'A') { + if ($user->type === "A") { return false; } if ( - $game->status !== 'waiting' || + $game->status !== "Pending" || $game->player1_user_id === $user->id ) { return false; } + if ($game->player2_user_id !== null && $game->player2_user_id !== 1) { + return false; + } + return true; } public function resign(User $user, Game $game): bool { - if ($user->type === 'A') { + if ($user->type === "A") { return false; } if ( - $game->status !== 'ongoing' || + $game->status !== "Playing" || ($game->player1_user_id !== $user->id && $game->player2_user_id !== $user->id) ) { @@ -84,12 +92,12 @@ class GamePolicy */ public function update(User $user, Game $game): bool { - if ($user->type === 'A') { + if ($user->type === "A") { return false; } if ( - $game->status !== 'ongoing' || + $game->status !== "Playing" || ($game->player1_user_id !== $user->id && $game->player2_user_id !== $user->id) ) { @@ -105,7 +113,7 @@ class GamePolicy public function delete(User $user, Game $game): bool { // Only admins can delete games - return $user->type === 'A'; + return $user->type === "A"; } /** diff --git a/bruno_collection/Games/Create Game.bru b/bruno_collection/Games/Create Game.bru new file mode 100644 index 0000000..d027b66 --- /dev/null +++ b/bruno_collection/Games/Create Game.bru @@ -0,0 +1,15 @@ +meta { + name: Create Game + type: http + seq: 3 +} + +post { + url: {{api_url}}/games + body: none + auth: inherit +} + +settings { + encodeUrl: true +} diff --git a/websockets/classes/BiscaGame.js b/websockets/classes/BiscaGame.js index 8ee4574..8ee957b 100644 --- a/websockets/classes/BiscaGame.js +++ b/websockets/classes/BiscaGame.js @@ -17,7 +17,7 @@ class BiscaGame { }; this.currentTurn = null; - this.status = "pending"; + this.status = 'pending'; this.startTime = null; this.players = { @@ -50,7 +50,7 @@ class BiscaGame { this.currentTurn = playerIds.find((id) => id != 1) || playerIds[0]; this.startTime = Date.now(); - this.status = "playing"; + this.status = 'playing'; } startTurnTimer(callback) { @@ -74,10 +74,12 @@ class BiscaGame { } handleTimeout() { - console.log(`[Game ${this.id}] Timeout! Auto-playing for ${this.currentTurn}`); - + console.log( + `[Game ${this.id}] Timeout! Auto-playing for ${this.currentTurn}`, + ); + const lowestCard = this.getLowestCard(this.currentTurn); - + if (lowestCard && this.timeoutCallback) { this.timeoutCallback(this.currentTurn, lowestCard.id); } @@ -92,7 +94,7 @@ class BiscaGame { } createDeck() { - const suits = ["c", "e", "o", "p"]; + const suits = ['c', 'e', 'o', 'p']; const ranks = [1, 2, 3, 4, 5, 6, 7, 11, 12, 13]; let deck = []; @@ -128,7 +130,7 @@ class BiscaGame { } playCard(userId, cardId) { - if (this.currentTurn != userId) return { error: "Not your turn!" }; + if (this.currentTurn != userId) return { error: 'Not your turn!' }; const player = this.players[userId]; const cardIndex = player.hand.findIndex((c) => c.id === cardId); @@ -142,7 +144,7 @@ class BiscaGame { const suitToFollow = this.table.playerCard.suit; const hasSuit = player.hand.some((c) => c.suit === suitToFollow); if (hasSuit && card.suit !== suitToFollow) { - return { error: "You must follow the suit!" }; + return { error: 'You must follow the suit!' }; } } @@ -154,7 +156,7 @@ class BiscaGame { this.table.playerCard = card; this.table.firstPlayerId = userId; this.currentTurn = this.getOpponentId(userId); - return { action: "next_turn" }; + return { action: 'next_turn' }; } else { this.table.opponentCard = card; return this.resolveTrick(); @@ -194,7 +196,7 @@ class BiscaGame { this.table = { playerCard: null, opponentCard: null, firstPlayerId: null }; if (this.players[winnerId].hand.length === 0) { - this.status = "finished"; + this.status = 'finished'; this.stopTimer(); const pIds = Object.keys(this.players); @@ -214,11 +216,11 @@ class BiscaGame { const finalLoser = isDraw ? null : gameWinnerId == p1Obj.id - ? p2Obj.id - : p1Obj.id; + ? p2Obj.id + : p1Obj.id; return { - action: "game_ended", + action: 'game_ended', trickResult, winnerId: finalWinner, loserId: finalLoser, @@ -231,7 +233,7 @@ class BiscaGame { }; } - return { action: "trick_resolved", trickResult }; + return { action: 'trick_resolved', trickResult }; } getStateForPlayer(userId) { @@ -277,4 +279,4 @@ class BiscaGame { } } -module.exports = BiscaGame; +export default BiscaGame; diff --git a/websockets/events/connection.js b/websockets/events/connection.js index b4f914b..dcc5f9c 100644 --- a/websockets/events/connection.js +++ b/websockets/events/connection.js @@ -1,4 +1,4 @@ -import { addUser, removeUser } from "../state/connection"; +import { addUser, removeUser } from '../state/connection.js'; const HEARTBEAT_INTERVAL = 30000; // 30 seconds const HEARTBEAT_TIMEOUT = 10000; // 10 seconds @@ -8,36 +8,36 @@ export const handleConnectionEvents = (io, socket) => { let heartbeatTimeout; const startHeartbeat = () => { heartbeatInterval = setInterval(() => { - socket.emit("heartbeat"); + socket.emit('heartbeat'); heartbeatTimeout = setTimeout(() => { console.log( - `[Heartbeat] No response from ${socket.id}, disconnecting...` + `[Heartbeat] No response from ${socket.id}, disconnecting...`, ); socket.disconnect(true); }, HEARTBEAT_TIMEOUT); }, HEARTBEAT_INTERVAL); }; - socket.on("heartbeat_ack", () => { + socket.on('heartbeat_ack', () => { clearTimeout(heartbeatTimeout); console.log(`[Heartbeat] Received pong from ${socket.id}`); }); - socket.on("join", (user) => { + socket.on('join', (user) => { addUser(socket, user); console.log(`[Connection] User ${user.name} has joined the server`); }); - socket.on("leave", () => { + socket.on('leave', () => { const user = removeUser(socket.id); if (user) { console.log(`[Connection] User ${user.name} has left the server`); } }); - socket.on("disconnect", () => { - console.log("Connection Lost:", socket.id); + socket.on('disconnect', () => { + console.log('Connection Lost:', socket.id); removeUser(socket.id); }); }; diff --git a/websockets/package.json b/websockets/package.json index 1dc9741..c5fbd36 100644 --- a/websockets/package.json +++ b/websockets/package.json @@ -2,6 +2,7 @@ "name": "websockets", "version": "1.0.0", "main": "index.js", + "type": "module", "scripts": { "dev": "nodemon index.js", "start": "bun index.js " diff --git a/websockets/state/game.js b/websockets/state/game.js index 2a3f7d8..79a1d6e 100644 --- a/websockets/state/game.js +++ b/websockets/state/game.js @@ -1,4 +1,4 @@ -const BiscaGame = require("../classes/BiscaGame"); +import BiscaGame from '../classes/BiscaGame.js'; const activeGames = new Map(); @@ -18,16 +18,12 @@ const getGame = (id) => { }; const removeGame = (id) => { -const game = activeGames.get(id); + const game = activeGames.get(id); if (game) { - game.stopTimer(); - activeGames.delete(id); - console.log(`[Game State] Game removed: ${id}`); + game.stopTimer(); + activeGames.delete(id); + console.log(`[Game State] Game removed: ${id}`); } }; -module.exports = { - createGame, - getGame, - removeGame, -}; +export { createGame, getGame, removeGame }; -- 2.54.0