feature/websockets-matches #95
@@ -55,42 +55,55 @@ class GameController extends Controller
|
|||||||
|
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
"type" => "required|in:3,9",
|
"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();
|
$user = Auth::user();
|
||||||
|
|
||||||
$activeGame = Game::where(function ($q) use ($user) {
|
$activeGame = Game::where(function ($q) use ($user) {
|
||||||
$q->where("player1_user_id", $user->id)
|
$q->where("player1_user_id", $user->id)
|
||||||
->orWhere("player2_user_id", $user->id);
|
->orWhere("player2_user_id", $user->id);
|
||||||
})
|
})
|
||||||
->whereIn("status", ["Pending", "Playing"])
|
->whereIn("status", ["Pending", "Playing"])
|
||||||
->exists();
|
->exists();
|
||||||
|
|
||||||
if ($activeGame) {
|
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([
|
$game = Game::create([
|
||||||
"type" => $validated["type"],
|
"type" => $validated["type"],
|
||||||
"status" => "Pending",
|
"status" => $initialStatus,
|
||||||
"player1_user_id" => $user->id,
|
"player1_user_id" => $user->id,
|
||||||
"player2_user_id" => self::GHOST_ID,
|
"player2_user_id" => $player2Id,
|
||||||
"winner_user_id" => self::GHOST_ID,
|
"winner_user_id" => null,
|
||||||
"loser_user_id" => self::GHOST_ID,
|
"loser_user_id" => null,
|
||||||
"began_at" => now(),
|
"match_id" => $request->input('match_id', null),
|
||||||
|
"began_at" => $request->input('began_at', now()),
|
||||||
"player1_points" => 0,
|
"player1_points" => 0,
|
||||||
"player2_points" => 0,
|
"player2_points" => 0,
|
||||||
"custom" => null,
|
"custom" => null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
"message" => "Multiplayer game room created",
|
"message" => "Game created",
|
||||||
"game" => $game,
|
"game" => $game,
|
||||||
], 201);
|
], 201);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function join(Request $request, Game $game)
|
public function join(Request $request, Game $game)
|
||||||
{
|
{
|
||||||
// Prevent joining if already full or started
|
// Prevent joining if already full or started
|
||||||
if ($game->status !== 'Pending' || $game->player2_user_id !== 1) {
|
if ($game->status !== 'Pending' || $game->player2_user_id !== 1) {
|
||||||
return response()->json(['message' => 'Game is not available'], 400);
|
return response()->json(['message' => 'Game is not available'], 400);
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { addUser, removeUser } from "../state/connection.js";
|
import { addUser, removeUser } from "../state/connection.js";
|
||||||
import { addUser, removeUser } from "../state/connection.js";
|
|
||||||
|
|
||||||
|
|
||||||
const HEARTBEAT_INTERVAL = 30000; // 30 seconds
|
const HEARTBEAT_INTERVAL = 30000; // 30 seconds
|
||||||
const HEARTBEAT_TIMEOUT = 10000; // 10 seconds
|
const HEARTBEAT_TIMEOUT = 10000; // 10 seconds
|
||||||
|
|||||||
+22
-29
@@ -2,40 +2,33 @@ import BiscaGame from "../classes/BiscaGame.js";
|
|||||||
|
|
||||||
const activeGames = new Map();
|
const activeGames = new Map();
|
||||||
|
|
||||||
const createGame = (id, type, player1, player2) => {
|
export const createGame = (id, type, player1, player2) => {
|
||||||
const existingGame = activeGames.get(id);
|
const existingGame = activeGames.get(id);
|
||||||
if (existingGame) {
|
if (existingGame) {
|
||||||
console.log(
|
console.log(
|
||||||
`[Game State] Game ${id} already exists, returning existing instance`,
|
`[Game State] Game ${id} already exists, returning existing instance`
|
||||||
);
|
);
|
||||||
return existingGame;
|
return existingGame;
|
||||||
}
|
}
|
||||||
const game = new BiscaGame(id, type, player1, player2);
|
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})`);
|
console.log(`[Game State] Game created: ${id} (Type: ${type})`);
|
||||||
return game;
|
return game;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGame = (id) => {
|
export const getGame = (id) => {
|
||||||
return activeGames.get(id);
|
return activeGames.get(id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeGame = (id) => {
|
export const removeGame = (id) => {
|
||||||
const game = activeGames.get(id);
|
const game = activeGames.get(id);
|
||||||
if (game) {
|
if (game) {
|
||||||
game.stopTimer();
|
game.stopTimer();
|
||||||
activeGames.delete(id);
|
activeGames.delete(id);
|
||||||
console.log(`[Game State] Game removed: ${id}`);
|
console.log(`[Game State] Game removed: ${id}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
createGame,
|
|
||||||
getGame,
|
|
||||||
removeGame,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user