fix:websocket errors & polict change #92

Merged
AfonsoCMSousa merged 1 commits from fix/websocket-errors into develop 2026-01-02 14:29:39 +00:00
6 changed files with 64 additions and 42 deletions
Showing only changes of commit 3a7b1b9794 - Show all commits
+17 -9
View File
@@ -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";
}
/**
+15
View File
@@ -0,0 +1,15 @@
meta {
name: Create Game
type: http
seq: 3
}
post {
url: {{api_url}}/games
body: none
auth: inherit
}
settings {
encodeUrl: true
}
+15 -13
View File
@@ -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,7 +74,9 @@ 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);
@@ -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;
+8 -8
View File
@@ -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);
});
};
+1
View File
@@ -2,6 +2,7 @@
"name": "websockets",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"dev": "nodemon index.js",
"start": "bun index.js "
+6 -10
View File
@@ -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 };