Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion public/assets/js/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ function closeModal() {
background.classList.add("hidden");
}

function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

// WebSocket
const chatConnection = new WebSocket('ws://sockets.comus-party.com/chat/' + gameCode);
chatConnection.onopen = function (e) {
Expand All @@ -130,7 +138,28 @@ const gameConnection = new WebSocket('ws://localhost:8315/game/' + gameCode);
gameConnection.onopen = function (e) {
console.log("Connexion établie avec GAME_SOCKET !");

gameConnection.send(JSON.stringify({uuid: playerUuid, command: 'joinGame', game: gameCode}));
// génère un uuid et un username
const guestUuid = generateUUID();
const guestUsername = "Guest_" + Math.floor(Math.random() * 9000 + 1000);

// stock les informations du guest en session
sessionStorage.setItem('uuid', guestUuid);
sessionStorage.setItem('username', guestUsername);
sessionStorage.setItem('elo', '0');
sessionStorage.setItem('xp', '0');
sessionStorage.setItem('pfpPath', 'default-pfp.jpg');
sessionStorage.setItem('is_guest', 'true');

const sessionData = {
uuid: sessionStorage.getItem('uuid'),
username: sessionStorage.getItem('username'),
elo: sessionStorage.getItem('elo'),
xp: sessionStorage.getItem('xp'),
pfpPath: sessionStorage.getItem('pfpPath'),
is_guest: sessionStorage.getItem('is_guest')
};

gameConnection.send(JSON.stringify({uuid: playerUuid, command: 'joinGame', game: gameCode, sessionData: sessionData}));
};
gameConnection.onmessage = function (e) {
const data = JSON.parse(e.data);
Expand Down
18 changes: 15 additions & 3 deletions src/App/Sockets/Game.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function onMessage(ConnectionInterface $from, $msg): void
$uuid = $data['uuid'];
$game = $data['game'];
$command = $data['command'];
$sessionData = $data['sessionData'];

if (!isset($this->games[$game])) {
$this->games[$game] = [];
Expand All @@ -58,7 +59,7 @@ function onMessage(ConnectionInterface $from, $msg): void
switch ($command) {
case 'quitGame':
case 'joinGame':
$this->updatePlayer($game);
$this->updatePlayer($game, $sessionData);
break;
case 'startGame':
$this->redirectUserToGame($game, $uuid);
Expand All @@ -68,7 +69,7 @@ function onMessage(ConnectionInterface $from, $msg): void
}
}

private function updatePlayer(string $game): void
private function updatePlayer(string $game, array | null $sessionData): void
{
$gameRecord = (new GameRecordDAO(Db::getInstance()->getConnection()))->findByCode($game);

Expand All @@ -79,6 +80,17 @@ private function updatePlayer(string $game): void
"pfp" => $player['player']->getActivePfp()
], $players);

if (isset($sessionData['is_guest']) && $sessionData['is_guest'] === 'true') {
$guestPlayer = [
"uuid" => $sessionData['uuid'],
"username" => $sessionData['username'],
"elo" => $sessionData['elo'],
"xp" => $sessionData['xp'],
"pfp" => $sessionData['pfpPath']
];
$jsonPlayer[] = $guestPlayer;
}

$this->sendToGame($game, "updatePlayer", json_encode($jsonPlayer));
}

Expand All @@ -104,7 +116,7 @@ public function onClose(ConnectionInterface $conn): void
foreach ($this->games as $game => $clients) {
$key = array_search($conn, $clients);
if ($key !== false) {
$this->updatePlayer($game);
$this->updatePlayer($game, null);
unset($this->games[$game][$key]);
}
}
Expand Down
48 changes: 34 additions & 14 deletions src/Controllers/controllerGame.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\Loader\FilesystemLoader;
use Ramsey\Uuid\Uuid;

/**
* @brief Classe ControllerGame
Expand Down Expand Up @@ -296,20 +297,40 @@ private function showGameSettings(GameRecord $gameRecord): void
} else {
$settings = [];
}

$template = $this->getTwig()->load('player/game-settings.twig');
echo $template->render([
"code" => $gameRecord->getCode(),
"isHost" => $gameRecord->getHostedBy()->getUuid() == $_SESSION['uuid'],
"players" => array_map(fn($player) => $player['player'], $gameRecord->getPlayers()),
"game" => $gameRecord->getGame(),
"chat" => $gameSettings["settings"]["allowChat"],
"gameFileInfos" => $gameSettings["game"],
"settings" => $settings,
"isPrivate" => $gameRecord->isPrivate(),
]);

// récupération des joueurs de la base de données
$players = array_map(fn($player) => $player['player'], $gameRecord->getPlayers());

// si le joueur est un guest, créer un player guest avec les informations en session et l'ajouter au tableau des joueurs
if (isset($_SESSION['is_guest']) && $_SESSION['is_guest'] === true) {
$guestPlayer = [
'uuid' => $_SESSION['uuid'],
'username' => $_SESSION['username'],
'comusCoin' => $_SESSION['comusCoin'],
'elo' => $_SESSION['elo'],
'xp' => $_SESSION['xp'],
'pfpPath' => $_SESSION['pfpPath']
];
$players[] = (object) $guestPlayer;
}

// créer le gameState avec toutes les informations
$gameState = [
"code" => $gameRecord->getCode(),
"isHost" => $gameRecord->getHostedBy()->getUuid() == $_SESSION['uuid'],
"players" => $players,
"game" => $gameRecord->getGame(),
"chat" => $gameSettings["settings"]["allowChat"],
"gameFileInfos" => $gameSettings["game"],
"settings" => $settings,
"isPrivate" => $gameRecord->isPrivate(),
];

echo $template->render($gameState);
}


/**
* @brief Rejoint une partie avec un code (Méthode GET ou POST autorisée)
* @param string $method Méthode HTTP utilisée
Expand Down Expand Up @@ -358,14 +379,13 @@ private function joinGame(string $code, ?string $playerUuid = null): string

$player = (new PlayerDAO($this->getPdo()))->findByUuid($playerUuid);

// TODO: Fonctionnement pour un joueur non connecté a insérer ici

if ($gameRecord->getState() != GameRecordState::WAITING) {
throw new GameUnavailableException("La partie a déjà commencé");
}

if (!in_array($playerUuid, array_map(fn($player) => $player['player']->getUuid(), $gameRecord->getPlayers()))) {
$gameRecordManager->addPlayer($gameRecord, $player);
if(!isset($_SESSION['is_guest']) || $_SESSION['is_guest'] === false) {
$gameRecordManager->addPlayer($gameRecord, $player);}
}

return json_encode([
Expand Down
31 changes: 31 additions & 0 deletions src/Models/player.dao.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,37 @@ public function createPlayer(string $username, string $email): bool
return $stmtPlayer->execute();
}

/**
* @brief Crée un nouveau joueur invité dans la base de données
*
* @details Cette méthode génère un UUID unique pour le joueur, et insère un nouvel enregistrement dans la table des joueurs avec l'UUID et le nom d'utilisateur.
*
* @param string $username Le nom d'utilisateur du joueur
* @return bool Retourne true si le joueur a été créé avec succès, false sinon
* @throws DateMalformedStringException Exception levée dans le cas d'une date malformée
*/
public function createGuestPlayer(string $username): bool
{
// Récupère l'ID du dernier joueur enregistré
$stmt = $this->pdo->query('SELECT MAX(id) as max_id FROM ' . DB_PREFIX . 'user');
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$result = $stmt->fetch();

$userId = $result['max_id'] + 1;


// Genération de l'uuid du joueur guest
$uuid = "guest" . Uuid::uuid4()->toString();

$stmtPlayer = $this->pdo->prepare("INSERT INTO " . DB_PREFIX . "player (uuid, username, user_id) VALUES (:uuid, :username, :user_id)");

$stmtPlayer->bindParam(':uuid', $uuid);
$stmtPlayer->bindParam(':username', $username);
$stmtPlayer->bindParam(':user_id', $userId);

return $stmtPlayer->execute();
}

/**
* @brief Retourne un objet Player (ou null) à partir du nom d'utilisateur passé en paramètre
* @param string|null $username Le nom d'utilisateur du joueur à retrouver
Expand Down