some hotfixes
This commit is contained in:
@@ -242,6 +242,13 @@ body {
|
|||||||
}
|
}
|
||||||
.btn-call:hover { background: var(--green); color: #000; }
|
.btn-call:hover { background: var(--green); color: #000; }
|
||||||
|
|
||||||
|
.btn-stay {
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(77, 166, 255, 1);
|
||||||
|
border: 2px solid rgba(77, 166, 255, 1);
|
||||||
|
}
|
||||||
|
.btn-stay:hover { background: rgba(77, 166, 255, 0.4); color: #fff; }
|
||||||
|
|
||||||
.btn-allin {
|
.btn-allin {
|
||||||
background: linear-gradient(45deg, #8b0000, #e60000);
|
background: linear-gradient(45deg, #8b0000, #e60000);
|
||||||
color: white;
|
color: white;
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/* Importation d'une police élégante */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&family=Playfair+Display:wght@700&display=swap');
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: radial-gradient(circle at center, #1a2a23 0%, #0a0f0d 100%);
|
||||||
|
font-family: 'Montserrat', sans-serif;
|
||||||
|
color: #e0e0e0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Background décoratif (Optionnel : petits motifs de cartes) */
|
||||||
|
body::before {
|
||||||
|
content: "♠ ♥ ♣ ♦";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-size: 20rem;
|
||||||
|
opacity: 0.03;
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conteneur principal */
|
||||||
|
.login-container {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background: rgba(255, 255, 255, 0.03);
|
||||||
|
backdrop-filter: blur(15px);
|
||||||
|
border: 1px solid rgba(255, 215, 0, 0.2);
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: 'Playfair Display', serif;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
color: #f1c40f; /* Or */
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 3px;
|
||||||
|
text-shadow: 0 2px 4px rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Formulaire */
|
||||||
|
#admin-login-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #bdc3c7;
|
||||||
|
margin-bottom: -10px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input password style premium */
|
||||||
|
input[type="password"] {
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
border: 2px solid #2c3e50;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
text-align: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="password"]:focus {
|
||||||
|
border-color: #f1c40f;
|
||||||
|
box-shadow: 0 0 15px rgba(241, 196, 15, 0.2);
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bouton Login */
|
||||||
|
button {
|
||||||
|
background: linear-gradient(135deg, #f1c40f 0%, #d4ac0d 100%);
|
||||||
|
color: #1a1a1a;
|
||||||
|
border: none;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 15px rgba(241, 196, 15, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 20px rgba(241, 196, 15, 0.4);
|
||||||
|
filter: brightness(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animation d'entrée */
|
||||||
|
.login-container {
|
||||||
|
animation: fadeInContainer 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeInContainer {
|
||||||
|
from { opacity: 0; transform: translateY(20px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-back-home {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 15px;
|
||||||
|
color: #4da6ff;
|
||||||
|
opacity: 0.6;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-back-home:hover {
|
||||||
|
opacity: 1;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
// Fonction et variables essentiel
|
// Fonction et variables essentiel
|
||||||
|
|
||||||
async function SqlRequest(action, params = {}) {
|
async function SqlRequest(action, params = {}) {
|
||||||
@@ -96,6 +94,7 @@ loginForm.addEventListener('submit', async function(event) {
|
|||||||
await SqlRequest('addPlayer', {game_id: gameId, name: player.value, money: start_money});
|
await SqlRequest('addPlayer', {game_id: gameId, name: player.value, money: start_money});
|
||||||
}
|
}
|
||||||
const result = await SqlRequest('setFirstPlayer', {game_id: gameId})
|
const result = await SqlRequest('setFirstPlayer', {game_id: gameId})
|
||||||
|
console.log(result)
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
window.location.href = 'admin-login.html?game_id=' + gameId;
|
window.location.href = 'admin-login.html?game_id=' + gameId;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+39
-1
@@ -81,20 +81,22 @@ async function updateClientInterface() {
|
|||||||
const actionPanel = document.querySelector('.action-panel');
|
const actionPanel = document.querySelector('.action-panel');
|
||||||
|
|
||||||
// --- 1. GESTION DES PANNEAUX DE VICTOIRE (SYNCHRO SSE) ---
|
// --- 1. GESTION DES PANNEAUX DE VICTOIRE (SYNCHRO SSE) ---
|
||||||
|
|
||||||
console.log("DEBUG STATUS SSE:", gameData.status);
|
console.log("DEBUG STATUS SSE:", gameData.status);
|
||||||
if (gameData.status === 'deciding') {
|
if (gameData.status === 'deciding') {
|
||||||
// L'admin est en train de choisir : on affiche "Attente"
|
// L'admin est en train de choisir : on affiche "Attente"
|
||||||
showWaitingForWinner();
|
showWaitingForWinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (gameData.status === 'finished' && gameData.winner_id) {
|
else if (gameData.status === 'finished' && gameData.winner_id) {
|
||||||
// Un gagnant a été validé en BDD
|
// Un gagnant a été validé en BDD
|
||||||
const winner = playersData.find(p => Number(p.id) === Number(gameData.winner_id));
|
const winner = playersData.find(p => Number(p.id) === Number(gameData.winner_id));
|
||||||
const winnerName = winner ? winner.name : "Un joueur";
|
const winnerName = winner ? winner.name : "Un joueur";
|
||||||
|
|
||||||
// showVictoryScreen s'occupe maintenant de supprimer l'ancien panneau
|
// showVictoryScreen s'occupe maintenant de supprimer l'ancien panneau
|
||||||
// avant d'afficher le nouveau avec les confettis.
|
// avant d'afficher le nouveau avec les confettis.
|
||||||
showVictoryScreen(winnerName, gameData.pot);
|
showVictoryScreen(winnerName, gameData.pot);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (gameData.status === 'playing') {
|
else if (gameData.status === 'playing') {
|
||||||
// Si l'admin a relancé la partie (StartNewGame), on nettoie les panneaux
|
// Si l'admin a relancé la partie (StartNewGame), on nettoie les panneaux
|
||||||
// pour ceux qui n'auraient pas cliqué sur "OK"
|
// pour ceux qui n'auraient pas cliqué sur "OK"
|
||||||
@@ -118,8 +120,10 @@ async function updateClientInterface() {
|
|||||||
const inputs = document.querySelectorAll('.action-buttons button, .raise-group input, .raise-group button');
|
const inputs = document.querySelectorAll('.action-buttons button, .raise-group input, .raise-group button');
|
||||||
|
|
||||||
// Bordure de tour
|
// Bordure de tour
|
||||||
|
|
||||||
if (!isLocked && isMyTurn && gameData.status === 'playing') {
|
if (!isLocked && isMyTurn && gameData.status === 'playing') {
|
||||||
actionPanel.classList.add('my-turn-border');
|
actionPanel.classList.add('my-turn-border');
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
actionPanel.classList.remove('my-turn-border');
|
actionPanel.classList.remove('my-turn-border');
|
||||||
}
|
}
|
||||||
@@ -127,15 +131,45 @@ async function updateClientInterface() {
|
|||||||
if (isLocked) {
|
if (isLocked) {
|
||||||
if (turnInfo) turnInfo.innerHTML = `<span style="color: #f1c40f; font-weight: bold;">🔒 Jeu verrouillé. En attente de l'Admin...</span>`;
|
if (turnInfo) turnInfo.innerHTML = `<span style="color: #f1c40f; font-weight: bold;">🔒 Jeu verrouillé. En attente de l'Admin...</span>`;
|
||||||
inputs.forEach(el => el.disabled = true);
|
inputs.forEach(el => el.disabled = true);
|
||||||
|
|
||||||
} else if (!isMyTurn) {
|
} else if (!isMyTurn) {
|
||||||
if (turnInfo && currentPlayer) {
|
if (turnInfo && currentPlayer) {
|
||||||
turnInfo.innerHTML = `Attente de <strong style="color: #e74c3c;">${currentPlayer.name}</strong>...`;
|
turnInfo.innerHTML = `Attente de <strong style="color: #e74c3c;">${currentPlayer.name}</strong>...`;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputs.forEach(el => el.disabled = true);
|
inputs.forEach(el => el.disabled = true);
|
||||||
} else {
|
} else {
|
||||||
if (turnInfo) turnInfo.innerHTML = `<span style="color: #2ecc71; font-weight: bold;">✅ C'est à vous de jouer !</span>`;
|
if (turnInfo) turnInfo.innerHTML = `<span style="color: #2ecc71; font-weight: bold;">✅ C'est à vous de jouer !</span>`;
|
||||||
inputs.forEach(el => el.disabled = false);
|
inputs.forEach(el => el.disabled = false);
|
||||||
}
|
}
|
||||||
|
// --- 3.bis BOUTON INTELLIGENT (Seulement si c'est mon tour) ---
|
||||||
|
const currentMiseTable = Number(gameData.last_bet);
|
||||||
|
const btnFollow = document.getElementById('btn-call');
|
||||||
|
const btnFold = document.getElementById('btn-fold');
|
||||||
|
|
||||||
|
if (currentMiseTable === 0) {
|
||||||
|
// PERSONNE N'A MISÉ : "Rester"
|
||||||
|
if (btnFollow) {
|
||||||
|
btnFollow.textContent = `Rester (Passer son tour)`;
|
||||||
|
btnFollow.onclick = () => playerCall();
|
||||||
|
btnFollow.className = "btn btn-stay";
|
||||||
|
}
|
||||||
|
if (btnFold) {
|
||||||
|
btnFold.disabled = true; // Désactivé car inutile de se coucher
|
||||||
|
btnFold.style.opacity = "0.5";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// UNE MISE EXISTE : "Suivre"
|
||||||
|
if (btnFollow) {
|
||||||
|
btnFollow.textContent = `Suivre (${currentMiseTable} 🪙)`;
|
||||||
|
btnFollow.onclick = () => playerFollow();
|
||||||
|
btnFollow.className = "btn btn-call";
|
||||||
|
}
|
||||||
|
if (btnFold) {
|
||||||
|
btnFold.disabled = false;
|
||||||
|
btnFold.style.opacity = "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mise à jour du label du haut
|
// Mise à jour du label du haut
|
||||||
if (currentPlayer && activePlayerLabel) {
|
if (currentPlayer && activePlayerLabel) {
|
||||||
@@ -414,6 +448,10 @@ async function playerFollow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function playerCall() {
|
||||||
|
changePlayer();
|
||||||
|
}
|
||||||
|
|
||||||
async function playerAllIn() {
|
async function playerAllIn() {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
const viewerId = Number(urlParams.get('player_id'));
|
const viewerId = Number(urlParams.get('player_id'));
|
||||||
|
|||||||
@@ -394,8 +394,18 @@ async function declareWinner(playerId) {
|
|||||||
if (resStatus && resStatus.success) {
|
if (resStatus && resStatus.success) {
|
||||||
console.log("✅ Statut passé à 'finished'");
|
console.log("✅ Statut passé à 'finished'");
|
||||||
|
|
||||||
|
// On met a jour les valeurs dans BDD
|
||||||
|
const result = await SqlRequest('declare_winner', {
|
||||||
|
game_id: gameData.id,
|
||||||
|
player_id: playerId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result && result.success){
|
||||||
// Mise à jour de l'interface Admin
|
// Mise à jour de l'interface Admin
|
||||||
showAdminWinPanel(playerId);
|
showAdminWinPanel(playerId);
|
||||||
|
} else {
|
||||||
|
console.log("Dommage tu y étais presque")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert("Erreur lors de la mise à jour du gagnant.");
|
alert("Erreur lors de la mise à jour du gagnant.");
|
||||||
|
|||||||
@@ -62,6 +62,61 @@ switch ($action) {
|
|||||||
echo json_encode(['success' => true]);
|
echo json_encode(['success' => true]);
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
case 'setFirstPlayer':
|
||||||
|
$game_id = (int)$params['game_id'];
|
||||||
|
|
||||||
|
// 1. Récupérer le premier joueur (id le plus petit)
|
||||||
|
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
|
||||||
|
$stmt->execute([$game_id]);
|
||||||
|
$player = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($player) {
|
||||||
|
$firstPlayerId = $player['id'];
|
||||||
|
|
||||||
|
// 2. Définir ce joueur comme dealer
|
||||||
|
$stmt = $pdo->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
|
||||||
|
$stmt->execute([$firstPlayerId]);
|
||||||
|
|
||||||
|
// 3. IMPORTANT : Définir aussi ce joueur comme "joueur actuel" dans la table games
|
||||||
|
// pour que le jeu sache qui doit commencer à parler
|
||||||
|
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$firstPlayerId, $game_id]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'player_id' => $firstPlayerId
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => 'Aucun joueur trouvé pour cette partie.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
|
||||||
|
case 'call':
|
||||||
|
$game_id = $params['game_id'];
|
||||||
|
$player_id = $params['player_id'];
|
||||||
|
|
||||||
|
// 1. Récupérer la mise actuelle de la table
|
||||||
|
$stmt = $pdo->prepare("SELECT last_bet FROM games WHERE id = ?");
|
||||||
|
$stmt->execute([$game_id]);
|
||||||
|
$last_bet = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
// 2. Mettre à jour la mise du joueur (si c'est un call, il paye, si c'est un check, last_bet est 0)
|
||||||
|
$stmt = $pdo->prepare("UPDATE players SET current_bet = ?, money = money - ? WHERE id = ?");
|
||||||
|
$stmt->execute([$last_bet, $last_bet, $player_id]);
|
||||||
|
|
||||||
|
// 3. Ajouter la mise au pot global
|
||||||
|
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
|
||||||
|
$stmt->execute([$last_bet, $game_id]);
|
||||||
|
|
||||||
|
// 4. Passer au joueur suivant (ta fonction habituelle)
|
||||||
|
moveToNextPlayer($game_id, $pdo);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
|
||||||
case 'next_player':
|
case 'next_player':
|
||||||
$game_id = (int)$params['game_id'];
|
$game_id = (int)$params['game_id'];
|
||||||
$current_id = (int)$params['current_player_id'];
|
$current_id = (int)$params['current_player_id'];
|
||||||
|
|||||||
@@ -3,15 +3,18 @@
|
|||||||
<title>Connexion Administrateur - PokerPaf</title>
|
<title>Connexion Administrateur - PokerPaf</title>
|
||||||
<link rel="stylesheet" type="text/css" href="css/admin-login.css">
|
<link rel="stylesheet" type="text/css" href="css/admin-login.css">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||||
|
<meta charset='utf-8'>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Admin Login</h1>
|
<div class="login-container">
|
||||||
<form id="admin-login-form">
|
<a href="index.html" class="btn-back-home">◀️ Retourner à l'accueil</a>
|
||||||
|
<h1>Admin Login</h1>
|
||||||
|
<form id="admin-login-form">
|
||||||
<label for="adminPassword">Mot de passe administrateur :</label>
|
<label for="adminPassword">Mot de passe administrateur :</label>
|
||||||
<input type="password" id="adminPassword" name="adminPassword" required>
|
<input type="password" id="adminPassword" name="adminPassword" required="" placeholder="••••••••">
|
||||||
<br><br>
|
<button type="submit">Accéder au Panneau</button>
|
||||||
<button type="submit">Login</button>
|
</form>
|
||||||
</form>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
const hashedAdminPassword = "7215d31f702fe2faf2a7df114c6427007bd254740c6b9cbaa2a5505060088929";
|
const hashedAdminPassword = "7215d31f702fe2faf2a7df114c6427007bd254740c6b9cbaa2a5505060088929";
|
||||||
|
|||||||
+2
-2
@@ -26,8 +26,8 @@
|
|||||||
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
|
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
|
||||||
|
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="btn btn-fold" onclick="playerFold()">Se coucher</button>
|
<button class="btn btn-fold" id="btn-fold" onclick="playerFold()">Se coucher</button>
|
||||||
<button class="btn btn-call" onclick="playerFollow()">Suivre</button>
|
<button class="btn btn-call" id="btn-call" onclick="playerFollow()">Suivre</button>
|
||||||
<div class="raise-group">
|
<div class="raise-group">
|
||||||
<input type="number" id="raise-amount" placeholder="Mise" min="0">
|
<input type="number" id="raise-amount" placeholder="Mise" min="0">
|
||||||
<button class="btn-validate" onclick="playerRaise()">OK</button>
|
<button class="btn-validate" onclick="playerRaise()">OK</button>
|
||||||
|
|||||||
+17
-7
@@ -7,20 +7,20 @@ $host = 'localhost'; $db = 'poker_paf'; $user = 'root'; $pass = '';
|
|||||||
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
|
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
|
||||||
|
|
||||||
$game_id = $_GET['game_id'] ?? 0;
|
$game_id = $_GET['game_id'] ?? 0;
|
||||||
// On stocke l'état précédent pour ne pas envoyer de doublons
|
|
||||||
$last_state_hash = "";
|
$last_state_hash = "";
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// On récupère l'état global de la partie et des joueurs
|
// 1. Récupérer les données de la partie
|
||||||
$stmt = $pdo->prepare("SELECT g.*, (SELECT COUNT(*) FROM players WHERE game_id = g.id AND is_folded=0) as active_count FROM games g WHERE g.id = ?");
|
$stmt = $pdo->prepare("SELECT g.*, (SELECT COUNT(*) FROM players WHERE game_id = g.id AND is_folded=0) as active_count FROM games g WHERE g.id = ?");
|
||||||
$stmt->execute([$game_id]);
|
$stmt->execute([$game_id]);
|
||||||
$game = $stmt->fetch(PDO::FETCH_ASSOC);
|
$game = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// 2. Récupérer les données des joueurs
|
||||||
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
|
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
|
||||||
$stmt->execute([$game_id]);
|
$stmt->execute([$game_id]);
|
||||||
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$full_state = ['game' => $game, 'players' => $players];
|
// 3. Typage propre AVANT de mettre dans le full_state
|
||||||
foreach ($players as &$player) {
|
foreach ($players as &$player) {
|
||||||
$player['id'] = (int)$player['id'];
|
$player['id'] = (int)$player['id'];
|
||||||
$player['money'] = (int)$player['money'];
|
$player['money'] = (int)$player['money'];
|
||||||
@@ -28,16 +28,26 @@ while (true) {
|
|||||||
$player['is_dealer'] = (int)$player['is_dealer'];
|
$player['is_dealer'] = (int)$player['is_dealer'];
|
||||||
$player['is_folded'] = (int)$player['is_folded'];
|
$player['is_folded'] = (int)$player['is_folded'];
|
||||||
}
|
}
|
||||||
unset($player); // Nettoyage de la référence
|
unset($player);
|
||||||
|
|
||||||
|
// 4. Construction de l'objet final
|
||||||
|
$full_state = [
|
||||||
|
'game' => $game,
|
||||||
|
'players' => $players
|
||||||
|
];
|
||||||
|
|
||||||
|
// 5. Calcul du hash sur l'objet finalisé
|
||||||
$current_hash = md5(json_encode($full_state));
|
$current_hash = md5(json_encode($full_state));
|
||||||
|
|
||||||
// Si le hash a changé, c'est qu'une action a eu lieu (mise, tour suivant, fold...)
|
|
||||||
if ($current_hash !== $last_state_hash) {
|
if ($current_hash !== $last_state_hash) {
|
||||||
echo "data: " . json_encode($full_state) . "\n\n";
|
echo "data: " . json_encode($full_state) . "\n\n";
|
||||||
$last_state_hash = $current_hash;
|
$last_state_hash = $current_hash;
|
||||||
}
|
|
||||||
|
|
||||||
|
// On force l'envoi
|
||||||
ob_flush();
|
ob_flush();
|
||||||
flush();
|
flush();
|
||||||
sleep(0.01); // On vérifie toutes les secondes
|
}
|
||||||
|
|
||||||
|
// 6. Pause raisonnable (500ms) pour ne pas tuer le CPU/Base de données
|
||||||
|
sleep(0.01);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user