Import initial du site depuis le serveur

This commit is contained in:
WhyKorp's server
2026-04-27 06:52:16 +00:00
parent 81b39e856b
commit f57f9fe1d5
1871 changed files with 214417 additions and 32138 deletions
@@ -1,3 +1,3 @@
43383623A09386DA6B59E2BB309D95588F709C4F32A6BFDBAF7D48CAC9ED7E6D
comodoca.com
43383623A09386DA6B59E2BB309D95588F709C4F32A6BFDBAF7D48CAC9ED7E6D
comodoca.com
a735c87cc7dd56e
+97 -97
View File
@@ -1,97 +1,97 @@
<?php
require_once __DIR__ . '/config.php';
if (session_status() === PHP_SESSION_NONE) { session_start(); }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
exit('Méthode non autorisée');
}
// CSRF
if (empty($_POST['csrf_token']) || $_POST['csrf_token'] !== ($_SESSION['csrf_token'] ?? '')) {
http_response_code(400);
exit('Token CSRF invalide.');
}
// Vérif login
if (empty($_SESSION['user_id'])) {
http_response_code(403);
exit('Tu dois être connecté pour acheter.');
}
$user_id = (int)$_SESSION['user_id'];
$item_id = isset($_POST['item_id']) ? (int)$_POST['item_id'] : 0;
$pdo = pdo_connect();
try {
$pdo->beginTransaction();
// Vérifie si le user possède déjà un item
$stmt = $pdo->prepare("SELECT ui.id, i.name
FROM user_items ui
JOIN items i ON ui.item_id = i.id
WHERE ui.user_id = :uid
LIMIT 1 FOR UPDATE");
$stmt->execute([':uid' => $user_id]);
$existing = $stmt->fetch();
if ($existing) {
$pdo->rollBack();
exit("Tu possèdes déjà un item actif : " . htmlspecialchars($existing['name']));
}
// Récupère item
$stmt = $pdo->prepare("SELECT id, name, price FROM items WHERE id = :id FOR UPDATE");
$stmt->execute([':id' => $item_id]);
$item = $stmt->fetch();
if (!$item) {
$pdo->rollBack();
exit('Item introuvable.');
}
$total = (int)$item['price'];
// Vérifie aura
$stmt = $pdo->prepare("SELECT aura FROM users WHERE id = :uid FOR UPDATE");
$stmt->execute([':uid' => $user_id]);
$u = $stmt->fetch();
if (!$u) {
$pdo->rollBack();
exit('Utilisateur introuvable.');
}
$aura = (int)$u['aura'];
if ($aura < $total) {
$pdo->rollBack();
exit('Tu n\'as pas assez d\'aura pour cet achat.');
}
// Débite l'aura
$stmt = $pdo->prepare("UPDATE users SET aura = aura - :amt WHERE id = :uid");
$stmt->execute([':amt' => $total, ':uid' => $user_id]);
// Ajoute item à user_items
$stmt = $pdo->prepare("INSERT INTO user_items (user_id, item_id) VALUES (:uid, :iid)");
$stmt->execute([':uid' => $user_id, ':iid' => $item_id]);
// Log (version simplifiée, sans actor_discord_id ni type)
$stmt = $pdo->prepare("INSERT INTO logs (user_id, amount, reason)
VALUES (:uid, :amount, :reason)");
$stmt->execute([
':uid' => $user_id,
':amount' => -$total,
':reason' => 'Achat: ' . $item['name']
]);
$pdo->commit();
header('Location: shop.php?buy=ok');
exit;
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo "Erreur détaillée : " . $e->getMessage();
var_dump($item_id, $user_id, $total, $aura);
exit;
}
<?php
require_once __DIR__ . '/config.php';
if (session_status() === PHP_SESSION_NONE) { session_start(); }
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
exit('Méthode non autorisée');
}
// CSRF
if (empty($_POST['csrf_token']) || $_POST['csrf_token'] !== ($_SESSION['csrf_token'] ?? '')) {
http_response_code(400);
exit('Token CSRF invalide.');
}
// Vérif login
if (empty($_SESSION['user_id'])) {
http_response_code(403);
exit('Tu dois être connecté pour acheter.');
}
$user_id = (int)$_SESSION['user_id'];
$item_id = isset($_POST['item_id']) ? (int)$_POST['item_id'] : 0;
$pdo = pdo_connect();
try {
$pdo->beginTransaction();
// Vérifie si le user possède déjà un item
$stmt = $pdo->prepare("SELECT ui.id, i.name
FROM user_items ui
JOIN items i ON ui.item_id = i.id
WHERE ui.user_id = :uid
LIMIT 1 FOR UPDATE");
$stmt->execute([':uid' => $user_id]);
$existing = $stmt->fetch();
if ($existing) {
$pdo->rollBack();
exit("Tu possèdes déjà un item actif : " . htmlspecialchars($existing['name']));
}
// Récupère item
$stmt = $pdo->prepare("SELECT id, name, price FROM items WHERE id = :id FOR UPDATE");
$stmt->execute([':id' => $item_id]);
$item = $stmt->fetch();
if (!$item) {
$pdo->rollBack();
exit('Item introuvable.');
}
$total = (int)$item['price'];
// Vérifie aura
$stmt = $pdo->prepare("SELECT aura FROM users WHERE id = :uid FOR UPDATE");
$stmt->execute([':uid' => $user_id]);
$u = $stmt->fetch();
if (!$u) {
$pdo->rollBack();
exit('Utilisateur introuvable.');
}
$aura = (int)$u['aura'];
if ($aura < $total) {
$pdo->rollBack();
exit('Tu n\'as pas assez d\'aura pour cet achat.');
}
// Débite l'aura
$stmt = $pdo->prepare("UPDATE users SET aura = aura - :amt WHERE id = :uid");
$stmt->execute([':amt' => $total, ':uid' => $user_id]);
// Ajoute item à user_items
$stmt = $pdo->prepare("INSERT INTO user_items (user_id, item_id) VALUES (:uid, :iid)");
$stmt->execute([':uid' => $user_id, ':iid' => $item_id]);
// Log (version simplifiée, sans actor_discord_id ni type)
$stmt = $pdo->prepare("INSERT INTO logs (user_id, amount, reason)
VALUES (:uid, :amount, :reason)");
$stmt->execute([
':uid' => $user_id,
':amount' => -$total,
':reason' => 'Achat: ' . $item['name']
]);
$pdo->commit();
header('Location: shop.php?buy=ok');
exit;
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo "Erreur détaillée : " . $e->getMessage();
var_dump($item_id, $user_id, $total, $aura);
exit;
}
+120 -120
View File
@@ -1,120 +1,120 @@
<?php
require_once __DIR__ . '/config.php';
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (!isset($_GET['code']) || !isset($_GET['state'])) {
http_response_code(400);
exit("Paramètres manquants.");
}
// CSRF : vérifier state
if (!isset($_SESSION['oauth2_state']) || $_GET['state'] !== $_SESSION['oauth2_state']) {
unset($_SESSION['oauth2_state']);
http_response_code(400);
exit("Échec de la vérification de sécurité (state).");
}
unset($_SESSION['oauth2_state']);
$code = $_GET['code'];
// Étape 1 : échange du code contre un access_token
$token_url = "https://discord.com/api/oauth2/token";
$post_fields = [
'client_id' => DISCORD_CLIENT_ID,
'client_secret' => DISCORD_CLIENT_SECRET,
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => DISCORD_REDIRECT_URI,
'scope' => 'identify email'
];
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
// ⚠️ remet le SSL, mieux pour la prod
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$response = curl_exec($ch);
if ($response === false) {
exit("Erreur cURL token: " . curl_error($ch));
}
curl_close($ch);
$token_data = json_decode($response, true);
if (!isset($token_data['access_token'])) {
exit("Échec de l'échange de token: " . htmlspecialchars($response));
}
$access_token = $token_data['access_token'];
// Étape 2 : récupérer infos utilisateur
$ch = curl_init("https://discord.com/api/users/@me");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $access_token"
]);
$user_json = curl_exec($ch);
if ($user_json === false) {
exit("Erreur cURL user: " . curl_error($ch));
}
curl_close($ch);
$user_data = json_decode($user_json, true);
if (!isset($user_data['id'])) {
exit("Impossible de récupérer l'utilisateur Discord. Réponse: " . htmlspecialchars($user_json));
}
// Préparation des données
$discord_id = $user_data['id'];
$username = $user_data['username'] . (isset($user_data['discriminator']) && $user_data['discriminator'] !== "0" ? '#' . $user_data['discriminator'] : "");
$email = $user_data['email'] ?? null;
$avatar = !empty($user_data['avatar'])
? "https://cdn.discordapp.com/avatars/{$discord_id}/{$user_data['avatar']}.png"
: null;
// Étape 3 : DB
try {
$pdo = pdo_connect();
} catch (Exception $e) {
exit("Erreur DB : " . $e->getMessage());
}
$stmt = $pdo->prepare("SELECT id FROM users WHERE discord_id = :did LIMIT 1");
$stmt->execute([':did' => $discord_id]);
$u = $stmt->fetch();
if ($u) {
$stmt = $pdo->prepare("UPDATE users SET username = :username, email = :email, profile_picture = :avatar WHERE discord_id = :did");
$stmt->execute([
':username' => $username,
':email' => $email,
':avatar' => $avatar,
':did' => $discord_id
]);
$user_id = $u['id'];
} else {
$stmt = $pdo->prepare("INSERT INTO users (discord_id, username, email, profile_picture, aura, tier)
VALUES (:did, :username, :email, :avatar, 0, 'Aura')");
$stmt->execute([
':did' => $discord_id,
':username' => $username,
':email' => $email,
':avatar' => $avatar
]);
$user_id = $pdo->lastInsertId();
}
// Étape 4 : session
$_SESSION['user_id'] = $user_id;
$_SESSION['discord_id'] = $discord_id;
$_SESSION['username'] = $username;
$_SESSION['profile_picture'] = $avatar;
// Étape 5 : redirection
header("Location: index.php");
exit;
<?php
require_once __DIR__ . '/config.php';
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (!isset($_GET['code']) || !isset($_GET['state'])) {
http_response_code(400);
exit("Paramètres manquants.");
}
// CSRF : vérifier state
if (!isset($_SESSION['oauth2_state']) || $_GET['state'] !== $_SESSION['oauth2_state']) {
unset($_SESSION['oauth2_state']);
http_response_code(400);
exit("Échec de la vérification de sécurité (state).");
}
unset($_SESSION['oauth2_state']);
$code = $_GET['code'];
// Étape 1 : échange du code contre un access_token
$token_url = "https://discord.com/api/oauth2/token";
$post_fields = [
'client_id' => DISCORD_CLIENT_ID,
'client_secret' => DISCORD_CLIENT_SECRET,
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => DISCORD_REDIRECT_URI,
'scope' => 'identify email'
];
$ch = curl_init($token_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
// ⚠️ remet le SSL, mieux pour la prod
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$response = curl_exec($ch);
if ($response === false) {
exit("Erreur cURL token: " . curl_error($ch));
}
curl_close($ch);
$token_data = json_decode($response, true);
if (!isset($token_data['access_token'])) {
exit("Échec de l'échange de token: " . htmlspecialchars($response));
}
$access_token = $token_data['access_token'];
// Étape 2 : récupérer infos utilisateur
$ch = curl_init("https://discord.com/api/users/@me");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $access_token"
]);
$user_json = curl_exec($ch);
if ($user_json === false) {
exit("Erreur cURL user: " . curl_error($ch));
}
curl_close($ch);
$user_data = json_decode($user_json, true);
if (!isset($user_data['id'])) {
exit("Impossible de récupérer l'utilisateur Discord. Réponse: " . htmlspecialchars($user_json));
}
// Préparation des données
$discord_id = $user_data['id'];
$username = $user_data['username'] . (isset($user_data['discriminator']) && $user_data['discriminator'] !== "0" ? '#' . $user_data['discriminator'] : "");
$email = $user_data['email'] ?? null;
$avatar = !empty($user_data['avatar'])
? "https://cdn.discordapp.com/avatars/{$discord_id}/{$user_data['avatar']}.png"
: null;
// Étape 3 : DB
try {
$pdo = pdo_connect();
} catch (Exception $e) {
exit("Erreur DB : " . $e->getMessage());
}
$stmt = $pdo->prepare("SELECT id FROM users WHERE discord_id = :did LIMIT 1");
$stmt->execute([':did' => $discord_id]);
$u = $stmt->fetch();
if ($u) {
$stmt = $pdo->prepare("UPDATE users SET username = :username, email = :email, profile_picture = :avatar WHERE discord_id = :did");
$stmt->execute([
':username' => $username,
':email' => $email,
':avatar' => $avatar,
':did' => $discord_id
]);
$user_id = $u['id'];
} else {
$stmt = $pdo->prepare("INSERT INTO users (discord_id, username, email, profile_picture, aura, tier)
VALUES (:did, :username, :email, :avatar, 0, 'Aura')");
$stmt->execute([
':did' => $discord_id,
':username' => $username,
':email' => $email,
':avatar' => $avatar
]);
$user_id = $pdo->lastInsertId();
}
// Étape 4 : session
$_SESSION['user_id'] = $user_id;
$_SESSION['discord_id'] = $discord_id;
$_SESSION['username'] = $username;
$_SESSION['profile_picture'] = $avatar;
// Étape 5 : redirection
header("Location: index.php");
exit;
+25 -25
View File
@@ -1,25 +1,25 @@
<?php
// config.php
session_start();
define('DB_HOST', '127.0.0.1');
define('DB_PORT', '3306'); // ou 8035 si tu as changé
define('DB_NAME', 'banque_aura');
define('DB_USER', 'root');
define('DB_PASS', 'root');
define('DISCORD_CLIENT_ID', '1318190631914307645');
define('DISCORD_CLIENT_SECRET', 'zRXVwXeAYSSL1YbSwPkNVgrgBJN6-i1_');
define('DISCORD_REDIRECT_URI', 'http://128.78.3.237:8082/aura_bank/callback.php'); // adapter
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
];
function pdo_connect(){
global $options;
$dsn = "mysql:host=".DB_HOST.";port=".DB_PORT.";dbname=".DB_NAME.";charset=utf8mb4";
return new PDO($dsn, DB_USER, DB_PASS, $options);
}
<?php
// config.php
session_start();
define('DB_HOST', '127.0.0.1');
define('DB_PORT', '3306'); // ou 8035 si tu as changé
define('DB_NAME', 'banque_aura');
define('DB_USER', 'root');
define('DB_PASS', 'root');
define('DISCORD_CLIENT_ID', '1318190631914307645');
define('DISCORD_CLIENT_SECRET', 'zRXVwXeAYSSL1YbSwPkNVgrgBJN6-i1_');
define('DISCORD_REDIRECT_URI', 'http://128.78.3.237:8082/aura_bank/callback.php'); // adapter
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
];
function pdo_connect(){
global $options;
$dsn = "mysql:host=".DB_HOST.";port=".DB_PORT.";dbname=".DB_NAME.";charset=utf8mb4";
return new PDO($dsn, DB_USER, DB_PASS, $options);
}
+26 -26
View File
@@ -1,26 +1,26 @@
<?php
// functions.php
require_once __DIR__ . '/config.php';
function get_top_users($limit = 10) {
$pdo = pdo_connect();
$stmt = $pdo->prepare("SELECT username, aura, discord_id, tier, profile_picture FROM users ORDER BY aura DESC LIMIT :lim");
$stmt->bindValue(':lim', (int)$limit, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll();
}
function get_user_by_discord($discord_id) {
$pdo = pdo_connect();
$stmt = $pdo->prepare("SELECT * FROM users WHERE discord_id = :did LIMIT 1");
$stmt->execute([':did' => $discord_id]);
return $stmt->fetch();
}
function get_user_rank($aura) {
$pdo = pdo_connect();
$stmt = $pdo->prepare("SELECT COUNT(*) + 1 AS 'rank' FROM users WHERE aura > :aura");
$stmt->execute([':aura' => $aura]);
$r = $stmt->fetch();
return $r ? (int)$r['rank'] : null;
}
<?php
// functions.php
require_once __DIR__ . '/config.php';
function get_top_users($limit = 10) {
$pdo = pdo_connect();
$stmt = $pdo->prepare("SELECT username, aura, discord_id, tier, profile_picture FROM users ORDER BY aura DESC LIMIT :lim");
$stmt->bindValue(':lim', (int)$limit, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll();
}
function get_user_by_discord($discord_id) {
$pdo = pdo_connect();
$stmt = $pdo->prepare("SELECT * FROM users WHERE discord_id = :did LIMIT 1");
$stmt->execute([':did' => $discord_id]);
return $stmt->fetch();
}
function get_user_rank($aura) {
$pdo = pdo_connect();
$stmt = $pdo->prepare("SELECT COUNT(*) + 1 AS 'rank' FROM users WHERE aura > :aura");
$stmt->execute([':aura' => $aura]);
$r = $stmt->fetch();
return $r ? (int)$r['rank'] : null;
}
+78 -78
View File
@@ -1,78 +1,78 @@
<?php
require_once __DIR__ . '/functions.php';
$top = get_top_users(10);
require_once __DIR__ . '/config.php';
$logged = isset($_SESSION['discord_id']);
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Banque de l'Aura — Classement</title>
<style>
body{font-family:Arial,Helvetica,sans-serif;background:#f4f4f9;color:#222;padding:20px}
.card{max-width:800px;margin:0 auto;background:#fff;padding:18px;border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,.06)}
h1{margin:0 0 12px}
table{width:100%;border-collapse:collapse}
th,td{padding:10px;border-bottom:1px solid #eee;text-align:left;vertical-align:middle}
th{background:#fbfbfc}
.pos-1::before{content:"🥇 ";}
.pos-2::before{content:"🥈 ";}
.pos-3::before{content:"🥉 ";}
.avatar{width:32px;height:32px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-right:8px}
.user-link{display:flex;align-items:center;text-decoration:none;color:#222}
.user-link:hover{text-decoration:underline}
.user-id{font-size:12px;color:#666;margin-left:40px;margin-top:-4px}
.welcome{display:flex;align-items:center;gap:12px;margin-bottom:18px;font-size:16px}
.welcome img{width:40px;height:40px;border-radius:50%;object-fit:cover}
</style>
</head>
<body>
<div class="card">
<?php if ($logged): ?>
<div class="welcome" style="display:flex;align-items:center;gap:12px;margin-bottom:16px;">
<?php if(!empty($_SESSION['profile_picture'])): ?>
<a href="profile.php?discord_id=<?= urlencode($_SESSION['discord_id']) ?>">
<img src="<?= htmlspecialchars($_SESSION['profile_picture']) ?>" alt="Avatar" style="width:40px;height:40px;border-radius:50%;object-fit:cover;">
</a>
<?php endif; ?>
<span style="font-size:16px;">
Bienvenue,
<a href="profile.php?discord_id=<?= urlencode($_SESSION['discord_id']) ?>" style="text-decoration:none;color:#222;">
<strong><?= htmlspecialchars($_SESSION['username']) ?></strong>
</a>
</span>
</div>
<?php else: ?>
<a href="login.php">Se connecter avec Discord</a>
<?php endif; ?>
<h1>🏆 Classement des meilleures auras</h1>
<?php if(empty($top)): ?>
<p>Le classement est vide.</p>
<?php else: ?>
<table>
<thead><tr><th>#</th><th>Utilisateur</th><th>Aura</th><th>Grade</th></tr></thead>
<tbody>
<?php foreach($top as $i => $row): ?>
<?php $pos = $i + 1; $cls = $pos<=3 ? "pos-{$pos}" : ""; ?>
<tr>
<td class="<?= htmlspecialchars($cls) ?>"><?= $pos ?></td>
<td>
<?php if(!empty($row['profile_picture'])): ?>
<img src="<?= htmlspecialchars($row['profile_picture']) ?>" alt="" class="avatar">
<?php endif; ?>
<strong><?= htmlspecialchars($row['username']) ?></strong>
<div class="user-id">ID: <?= htmlspecialchars($row['discord_id']) ?></div>
</td>
<td><?= (int)$row['aura'] ?></td>
<td><?= htmlspecialchars($row['tier']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</body>
</html>
<?php
require_once __DIR__ . '/functions.php';
$top = get_top_users(10);
require_once __DIR__ . '/config.php';
$logged = isset($_SESSION['discord_id']);
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Banque de l'Aura — Classement</title>
<style>
body{font-family:Arial,Helvetica,sans-serif;background:#f4f4f9;color:#222;padding:20px}
.card{max-width:800px;margin:0 auto;background:#fff;padding:18px;border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,.06)}
h1{margin:0 0 12px}
table{width:100%;border-collapse:collapse}
th,td{padding:10px;border-bottom:1px solid #eee;text-align:left;vertical-align:middle}
th{background:#fbfbfc}
.pos-1::before{content:"🥇 ";}
.pos-2::before{content:"🥈 ";}
.pos-3::before{content:"🥉 ";}
.avatar{width:32px;height:32px;border-radius:50%;object-fit:cover;vertical-align:middle;margin-right:8px}
.user-link{display:flex;align-items:center;text-decoration:none;color:#222}
.user-link:hover{text-decoration:underline}
.user-id{font-size:12px;color:#666;margin-left:40px;margin-top:-4px}
.welcome{display:flex;align-items:center;gap:12px;margin-bottom:18px;font-size:16px}
.welcome img{width:40px;height:40px;border-radius:50%;object-fit:cover}
</style>
</head>
<body>
<div class="card">
<?php if ($logged): ?>
<div class="welcome" style="display:flex;align-items:center;gap:12px;margin-bottom:16px;">
<?php if(!empty($_SESSION['profile_picture'])): ?>
<a href="profile.php?discord_id=<?= urlencode($_SESSION['discord_id']) ?>">
<img src="<?= htmlspecialchars($_SESSION['profile_picture']) ?>" alt="Avatar" style="width:40px;height:40px;border-radius:50%;object-fit:cover;">
</a>
<?php endif; ?>
<span style="font-size:16px;">
Bienvenue,
<a href="profile.php?discord_id=<?= urlencode($_SESSION['discord_id']) ?>" style="text-decoration:none;color:#222;">
<strong><?= htmlspecialchars($_SESSION['username']) ?></strong>
</a>
</span>
</div>
<?php else: ?>
<a href="login.php">Se connecter avec Discord</a>
<?php endif; ?>
<h1>🏆 Classement des meilleures auras</h1>
<?php if(empty($top)): ?>
<p>Le classement est vide.</p>
<?php else: ?>
<table>
<thead><tr><th>#</th><th>Utilisateur</th><th>Aura</th><th>Grade</th></tr></thead>
<tbody>
<?php foreach($top as $i => $row): ?>
<?php $pos = $i + 1; $cls = $pos<=3 ? "pos-{$pos}" : ""; ?>
<tr>
<td class="<?= htmlspecialchars($cls) ?>"><?= $pos ?></td>
<td>
<?php if(!empty($row['profile_picture'])): ?>
<img src="<?= htmlspecialchars($row['profile_picture']) ?>" alt="" class="avatar">
<?php endif; ?>
<strong><?= htmlspecialchars($row['username']) ?></strong>
<div class="user-id">ID: <?= htmlspecialchars($row['discord_id']) ?></div>
</td>
<td><?= (int)$row['aura'] ?></td>
<td><?= htmlspecialchars($row['tier']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</body>
</html>
+30 -30
View File
@@ -1,30 +1,30 @@
<?php
require_once __DIR__ . '/config.php';
// scopes : identify pour ID + username, email si tu veux email
$scope = 'identify email';
// génère un state CSRF
$state = bin2hex(random_bytes(16));
$_SESSION['oauth2_state'] = $state;
$params = http_build_query([
'client_id' => DISCORD_CLIENT_ID,
'redirect_uri' => DISCORD_REDIRECT_URI,
'response_type' => 'code',
'scope' => $scope,
'state' => $state,
'prompt' => 'consent'
]);
$discord_authorize_url = "https://discord.com/oauth2/authorize?$params";
?>
<!doctype html>
<html>
<head><meta charset="utf-8"><title>Login Discord</title></head>
<body>
<a href="<?= htmlspecialchars($discord_authorize_url) ?>">
<img src="https://raw.githubusercontent.com/DiscordAssets/discord-open-graph/main/discord_logo.png" alt="Discord" style="height:28px;vertical-align:middle"> Se connecter avec Discord
</a>
</body>
</html>
<?php
require_once __DIR__ . '/config.php';
// scopes : identify pour ID + username, email si tu veux email
$scope = 'identify email';
// génère un state CSRF
$state = bin2hex(random_bytes(16));
$_SESSION['oauth2_state'] = $state;
$params = http_build_query([
'client_id' => DISCORD_CLIENT_ID,
'redirect_uri' => DISCORD_REDIRECT_URI,
'response_type' => 'code',
'scope' => $scope,
'state' => $state,
'prompt' => 'consent'
]);
$discord_authorize_url = "https://discord.com/oauth2/authorize?$params";
?>
<!doctype html>
<html>
<head><meta charset="utf-8"><title>Login Discord</title></head>
<body>
<a href="<?= htmlspecialchars($discord_authorize_url) ?>">
<img src="https://raw.githubusercontent.com/DiscordAssets/discord-open-graph/main/discord_logo.png" alt="Discord" style="height:28px;vertical-align:middle"> Se connecter avec Discord
</a>
</body>
</html>
+5 -5
View File
@@ -1,5 +1,5 @@
<?php
require_once __DIR__ . '/config.php';
session_destroy();
header('Location: index.php');
exit;
<?php
require_once __DIR__ . '/config.php';
session_destroy();
header('Location: index.php');
exit;
+102 -102
View File
@@ -1,102 +1,102 @@
<?php
require_once __DIR__ . '/functions.php';
$discord_id = isset($_GET['discord_id']) ? trim($_GET['discord_id']) : null;
if (!$discord_id) {
http_response_code(400);
echo "Paramètre discord_id manquant.";
exit;
}
$user = get_user_by_discord($discord_id);
if (!$user) {
http_response_code(404);
echo "Utilisateur introuvable.";
exit;
}
$rank = get_user_rank($user['aura']);
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Profil de <?= htmlspecialchars($user['username']) ?></title>
<style>
body{font-family:Arial,Helvetica,sans-serif;background:#f4f4f9;color:#222;padding:20px}
.card{max-width:700px;margin:0 auto;background:#fff;padding:18px;border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,.06)}
.avatar{width:96px;height:96px;border-radius:50%;object-fit:cover}
.header{display:flex;align-items:center;gap:16px;justify-content:space-between}
.user-info{flex:1}
.btn-group{display:flex;gap:8px;margin-top:4px}
.btn{padding:6px 12px;border:none;border-radius:4px;background:#4CAF50;color:white;text-decoration:none;cursor:pointer;}
.btn.logout{background:#f44336;}
table{width:100%;border-collapse:collapse;margin-top:8px;}
th, td{padding:8px;border-bottom:1px solid #ccc;text-align:left;}
</style>
</head>
<body>
<div class="card">
<div class="header">
<div style="display:flex;align-items:center;gap:16px">
<?php if(!empty($user['profile_picture'])): ?>
<img src="<?= htmlspecialchars($user['profile_picture']) ?>" alt="" class="avatar">
<?php endif; ?>
<div class="user-info">
<h2><?= htmlspecialchars($user['username']) ?></h2>
<div>ID Discord: <?= htmlspecialchars($user['discord_id']) ?></div>
<div style="margin-top:8px;"><strong>Aura:</strong> <?= (int)$user['aura'] ?> — <strong>Grade:</strong> <?= htmlspecialchars($user['tier']) ?></div>
<div style="margin-top:6px;"><strong>Rang:</strong> #<?= (int)$rank ?></div>
</div>
</div>
<div class="btn-group">
<a href="index.php" class="btn">Accueil</a>
<a href="shop.php" class="btn">Boutique</a>
<a href="logout.php" class="btn logout">Se déconnecter</a>
</div>
</div>
<hr style="margin:14px 0">
<h3>Historique récent</h3>
<?php
$pdo = pdo_connect();
$stmt = $pdo->prepare("
SELECT amount, reason, created_at
FROM logs
WHERE user_id = :uid OR user_id = :discord_id
ORDER BY created_at DESC
");
$stmt->execute([
':uid' => $user['id'],
':discord_id' => $user['discord_id']
]);
$logs = $stmt->fetchAll();
if (!$logs): ?>
<p>Aucun historique.</p>
<?php else: ?>
<table style="width:100%;border-collapse:collapse;margin-top:8px;">
<thead>
<tr style="background:#f0f0f0;text-align:left;">
<th style="padding:8px;border-bottom:1px solid #ccc;">Date</th>
<th style="padding:8px;border-bottom:1px solid #ccc;">Montant</th>
<th style="padding:8px;border-bottom:1px solid #ccc;">Raison</th>
</tr>
</thead>
<tbody>
<?php foreach($logs as $l):
$amount = (int)$l['amount'];
$bg_color = $amount >= 0 ? '#d4f7d4' : '#f7d4d4'; // vert pale si gain, rouge pale si perte
?>
<tr style="background:<?= $bg_color ?>;border-bottom:1px solid #eee;">
<td style="padding:10px;"><?= htmlspecialchars($l['created_at']) ?></td>
<td style="padding:10px;"><?= $amount ?></td>
<td style="padding:10px;"><?= htmlspecialchars($l['reason']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</body>
</html>
<?php
require_once __DIR__ . '/functions.php';
$discord_id = isset($_GET['discord_id']) ? trim($_GET['discord_id']) : null;
if (!$discord_id) {
http_response_code(400);
echo "Paramètre discord_id manquant.";
exit;
}
$user = get_user_by_discord($discord_id);
if (!$user) {
http_response_code(404);
echo "Utilisateur introuvable.";
exit;
}
$rank = get_user_rank($user['aura']);
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Profil de <?= htmlspecialchars($user['username']) ?></title>
<style>
body{font-family:Arial,Helvetica,sans-serif;background:#f4f4f9;color:#222;padding:20px}
.card{max-width:700px;margin:0 auto;background:#fff;padding:18px;border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,.06)}
.avatar{width:96px;height:96px;border-radius:50%;object-fit:cover}
.header{display:flex;align-items:center;gap:16px;justify-content:space-between}
.user-info{flex:1}
.btn-group{display:flex;gap:8px;margin-top:4px}
.btn{padding:6px 12px;border:none;border-radius:4px;background:#4CAF50;color:white;text-decoration:none;cursor:pointer;}
.btn.logout{background:#f44336;}
table{width:100%;border-collapse:collapse;margin-top:8px;}
th, td{padding:8px;border-bottom:1px solid #ccc;text-align:left;}
</style>
</head>
<body>
<div class="card">
<div class="header">
<div style="display:flex;align-items:center;gap:16px">
<?php if(!empty($user['profile_picture'])): ?>
<img src="<?= htmlspecialchars($user['profile_picture']) ?>" alt="" class="avatar">
<?php endif; ?>
<div class="user-info">
<h2><?= htmlspecialchars($user['username']) ?></h2>
<div>ID Discord: <?= htmlspecialchars($user['discord_id']) ?></div>
<div style="margin-top:8px;"><strong>Aura:</strong> <?= (int)$user['aura'] ?> — <strong>Grade:</strong> <?= htmlspecialchars($user['tier']) ?></div>
<div style="margin-top:6px;"><strong>Rang:</strong> #<?= (int)$rank ?></div>
</div>
</div>
<div class="btn-group">
<a href="index.php" class="btn">Accueil</a>
<a href="shop.php" class="btn">Boutique</a>
<a href="logout.php" class="btn logout">Se déconnecter</a>
</div>
</div>
<hr style="margin:14px 0">
<h3>Historique récent</h3>
<?php
$pdo = pdo_connect();
$stmt = $pdo->prepare("
SELECT amount, reason, created_at
FROM logs
WHERE user_id = :uid OR user_id = :discord_id
ORDER BY created_at DESC
");
$stmt->execute([
':uid' => $user['id'],
':discord_id' => $user['discord_id']
]);
$logs = $stmt->fetchAll();
if (!$logs): ?>
<p>Aucun historique.</p>
<?php else: ?>
<table style="width:100%;border-collapse:collapse;margin-top:8px;">
<thead>
<tr style="background:#f0f0f0;text-align:left;">
<th style="padding:8px;border-bottom:1px solid #ccc;">Date</th>
<th style="padding:8px;border-bottom:1px solid #ccc;">Montant</th>
<th style="padding:8px;border-bottom:1px solid #ccc;">Raison</th>
</tr>
</thead>
<tbody>
<?php foreach($logs as $l):
$amount = (int)$l['amount'];
$bg_color = $amount >= 0 ? '#d4f7d4' : '#f7d4d4'; // vert pale si gain, rouge pale si perte
?>
<tr style="background:<?= $bg_color ?>;border-bottom:1px solid #eee;">
<td style="padding:10px;"><?= htmlspecialchars($l['created_at']) ?></td>
<td style="padding:10px;"><?= $amount ?></td>
<td style="padding:10px;"><?= htmlspecialchars($l['reason']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</body>
</html>
+143 -143
View File
@@ -1,143 +1,143 @@
<?php
require_once __DIR__ . '/config.php'; // contient pdo_connect() et session start
require_once __DIR__ . '/functions.php'; // si nécessaire
// Vérifie session
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$pdo = pdo_connect();
// Récupère les items
$stmt = $pdo->query("SELECT id, name, description, price FROM items ORDER BY price ASC");
$items = $stmt->fetchAll();
// Génère token CSRF simple
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
}
// Récupère saldo de l'utilisateur si connecté
$logged = isset($_SESSION['user_id']);
$userAura = null;
if ($logged) {
$stmt = $pdo->prepare("SELECT aura FROM users WHERE id = :uid LIMIT 1");
$stmt->execute([':uid' => $_SESSION['user_id']]);
$row = $stmt->fetch();
$userAura = $row ? (int)$row['aura'] : 0;
}
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Boutique — Banque de l'Aura</title>
<style>
body{font-family:Arial,Helvetica,sans-serif;background:#f4f4f9;color:#222;padding:20px}
.card{max-width:1000px;margin:0 auto;background:#fff;padding:18px;border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,.06)}
h1{margin:0 0 12px}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}
.item{border:1px solid #eee;padding:12px;border-radius:8px;background:#fafafa;display:flex;flex-direction:column;gap:8px}
.badge{width:32px;height:32px;object-fit:cover}
.item-icon{width:32px;height:32px;object-fit:cover;vertical-align:middle;margin-right:8px}
.price{font-weight:700}
.stock{font-size:13px;color:#666}
.buy-form{margin-top:auto}
.btn{display:inline-block;padding:8px 12px;border-radius:6px;background:#2d8aef;color:#fff;text-decoration:none;border:none;cursor:pointer}
.btn.disabled{opacity:.5;cursor:not-allowed;background:#9bbbed}
.row-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
padding: 10px 16px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
.row-top .user-info {
display: flex;
align-items: center;
gap: 10px;
}
.row-top img {
width: 32px;
height: 32px;
border-radius: 50%;
object-fit: cover;
}
.balance{font-weight:700}
</style>
</head>
<body>
<div class="card">
<div class="row-top">
<h1>🛒 Boutique</h1>
<?php if ($logged): ?>
<div class="user-info">
<div class="balance">
💎 Solde : <strong><?= htmlspecialchars($userAura ?? 0) ?> aura</strong>
</div>
<div class="active_item">
<?php
$stmt = $pdo->prepare("SELECT i.name
FROM user_items ui
JOIN items i ON ui.item_id = i.id
WHERE ui.user_id = :uid
LIMIT 1");
$stmt->execute([':uid' => $_SESSION['user_id']]);
$activeItem = $stmt->fetch();
?>
<?php if ($activeItem): ?>
🎖️ Item actif : <strong><?= htmlspecialchars($activeItem['name']) ?></strong>
<?php else: ?>
🎖️ Aucun item actif
<?php endif; ?>
</div>
<div class="profile-link">
<a href="profile.php?discord_id=<?= urlencode($_SESSION['discord_id']) ?>">Voir mon profil</a>
</div>
</div>
<?php else: ?>
<div class="login-link">
<a href="login.php">Se connecter avec Discord pour acheter</a>
</div>
<?php endif; ?>
</div>
<div class="grid">
<?php foreach($items as $it): ?>
<div class="item">
<div>
<span class="badge"><img class="item-icon" src="img/items/<?= htmlspecialchars($it['id']) ?>.png"></span>
<strong><?= htmlspecialchars($it['name']) ?></strong>
</div>
<?php if(!empty($it['description'])): ?>
<div style="font-size:14px;color:#333"><?= htmlspecialchars($it['description']) ?></div>
<?php endif; ?>
<div class="price"><?= (int)$it['price'] ?> aura</div>
<form class="buy-form" method="post" action="buy.php">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="item_id" value="<?= (int)$it['id'] ?>">
<?php
$canBuy = $logged && ($userAura !== null && $userAura >= (int)$it['price']);
?>
<button class="btn <?= $canBuy ? '' : 'disabled' ?>" <?= $canBuy ? '' : 'disabled' ?>>
Acheter
</button>
</form>
</div>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
<?php
require_once __DIR__ . '/config.php'; // contient pdo_connect() et session start
require_once __DIR__ . '/functions.php'; // si nécessaire
// Vérifie session
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$pdo = pdo_connect();
// Récupère les items
$stmt = $pdo->query("SELECT id, name, description, price FROM items ORDER BY price ASC");
$items = $stmt->fetchAll();
// Génère token CSRF simple
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
}
// Récupère saldo de l'utilisateur si connecté
$logged = isset($_SESSION['user_id']);
$userAura = null;
if ($logged) {
$stmt = $pdo->prepare("SELECT aura FROM users WHERE id = :uid LIMIT 1");
$stmt->execute([':uid' => $_SESSION['user_id']]);
$row = $stmt->fetch();
$userAura = $row ? (int)$row['aura'] : 0;
}
?>
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Boutique — Banque de l'Aura</title>
<style>
body{font-family:Arial,Helvetica,sans-serif;background:#f4f4f9;color:#222;padding:20px}
.card{max-width:1000px;margin:0 auto;background:#fff;padding:18px;border-radius:8px;box-shadow:0 6px 18px rgba(0,0,0,.06)}
h1{margin:0 0 12px}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px}
.item{border:1px solid #eee;padding:12px;border-radius:8px;background:#fafafa;display:flex;flex-direction:column;gap:8px}
.badge{width:32px;height:32px;object-fit:cover}
.item-icon{width:32px;height:32px;object-fit:cover;vertical-align:middle;margin-right:8px}
.price{font-weight:700}
.stock{font-size:13px;color:#666}
.buy-form{margin-top:auto}
.btn{display:inline-block;padding:8px 12px;border-radius:6px;background:#2d8aef;color:#fff;text-decoration:none;border:none;cursor:pointer}
.btn.disabled{opacity:.5;cursor:not-allowed;background:#9bbbed}
.row-top {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 14px;
padding: 10px 16px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
.row-top .user-info {
display: flex;
align-items: center;
gap: 10px;
}
.row-top img {
width: 32px;
height: 32px;
border-radius: 50%;
object-fit: cover;
}
.balance{font-weight:700}
</style>
</head>
<body>
<div class="card">
<div class="row-top">
<h1>🛒 Boutique</h1>
<?php if ($logged): ?>
<div class="user-info">
<div class="balance">
💎 Solde : <strong><?= htmlspecialchars($userAura ?? 0) ?> aura</strong>
</div>
<div class="active_item">
<?php
$stmt = $pdo->prepare("SELECT i.name
FROM user_items ui
JOIN items i ON ui.item_id = i.id
WHERE ui.user_id = :uid
LIMIT 1");
$stmt->execute([':uid' => $_SESSION['user_id']]);
$activeItem = $stmt->fetch();
?>
<?php if ($activeItem): ?>
🎖️ Item actif : <strong><?= htmlspecialchars($activeItem['name']) ?></strong>
<?php else: ?>
🎖️ Aucun item actif
<?php endif; ?>
</div>
<div class="profile-link">
<a href="profile.php?discord_id=<?= urlencode($_SESSION['discord_id']) ?>">Voir mon profil</a>
</div>
</div>
<?php else: ?>
<div class="login-link">
<a href="login.php">Se connecter avec Discord pour acheter</a>
</div>
<?php endif; ?>
</div>
<div class="grid">
<?php foreach($items as $it): ?>
<div class="item">
<div>
<span class="badge"><img class="item-icon" src="img/items/<?= htmlspecialchars($it['id']) ?>.png"></span>
<strong><?= htmlspecialchars($it['name']) ?></strong>
</div>
<?php if(!empty($it['description'])): ?>
<div style="font-size:14px;color:#333"><?= htmlspecialchars($it['description']) ?></div>
<?php endif; ?>
<div class="price"><?= (int)$it['price'] ?> aura</div>
<form class="buy-form" method="post" action="buy.php">
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
<input type="hidden" name="item_id" value="<?= (int)$it['id'] ?>">
<?php
$canBuy = $logged && ($userAura !== null && $userAura >= (int)$it['price']);
?>
<button class="btn <?= $canBuy ? '' : 'disabled' ?>" <?= $canBuy ? '' : 'disabled' ?>>
Acheter
</button>
</form>
</div>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
+47 -47
View File
@@ -1,47 +1,47 @@
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link rel="icon" href="img/logo.png">
<title>love</title>
</head>
<body>
<div class="container">
<header>
<a href="https://www.youtube.com/@whykioh" target="_blank">
<img class="logo" src="img/logo.png" alt="Logo">
</a>
<h1 class="title">WhyKorp</h1>
</header>
<div class="nav">
<a href="#">Accueil</a>
<a href="infos/index.php">Infos</a>
<a href="https://artists.magroove.com/en/lt/whykioh/" target="_blank">Link Tree</a>
<a href="tools/index.html">Outils</a>
<a href="ruty/index.php">Ruty</a>
<a href="lolivator/index.php">LoLivator</a>
<a href="jpc/index.html">JPC</a>
<a href="archives/index.php">Archives</a>
</div>
<p><br></p>
<hr>
<h1>Bienvenue sur le site officiel de la WhyKorp !</h1>
<p>Vous y trouverez tout sur Whykioh aka Noah, et la WhyKorp.<br>Attention ! Site en cours de développement !<br>Si un disfonctionnement est trouvé veuillez le signaler.</p>
<hr>
<h1>Flash Info !</h1>
<div class="flash">
<p class="flash">Noah a enfin terminé l'EP 4 Elements, <br>il sera disponible sur toutes les plateformes <br>le 25 Décembre 2023</p>
<img class="flash" src="img/last cover.png">
</div>
<hr>
<h1>Voici la dernière vidéo de <a href="https://www.youtube.com/@whykioh">Whykioh</a> :</h1>
<div class="video-container">
<iframe width="557,55" height="315" src="https://www.youtube.com/embed/-ZPjXjvdZFc?si=ldsNogAHy636GnzU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
</div>
<div class="footer">
Copyright | Whykorp® 2021-2024 | ajoute le nom du site après l'url et un /
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link rel="icon" href="img/logo.png">
<title>love</title>
</head>
<body>
<div class="container">
<header>
<a href="https://www.youtube.com/@whykioh" target="_blank">
<img class="logo" src="img/logo.png" alt="Logo">
</a>
<h1 class="title">WhyKorp</h1>
</header>
<div class="nav">
<a href="#">Accueil</a>
<a href="infos/index.php">Infos</a>
<a href="https://artists.magroove.com/en/lt/whykioh/" target="_blank">Link Tree</a>
<a href="tools/index.html">Outils</a>
<a href="ruty/index.php">Ruty</a>
<a href="lolivator/index.php">LoLivator</a>
<a href="jpc/index.html">JPC</a>
<a href="archives/index.php">Archives</a>
</div>
<p><br></p>
<hr>
<h1>Bienvenue sur le site officiel de la WhyKorp !</h1>
<p>Vous y trouverez tout sur Whykioh aka Noah, et la WhyKorp.<br>Attention ! Site en cours de développement !<br>Si un disfonctionnement est trouvé veuillez le signaler.</p>
<hr>
<h1>Flash Info !</h1>
<div class="flash">
<p class="flash">Noah a enfin terminé l'EP 4 Elements, <br>il sera disponible sur toutes les plateformes <br>le 25 Décembre 2023</p>
<img class="flash" src="img/last cover.png">
</div>
<hr>
<h1>Voici la dernière vidéo de <a href="https://www.youtube.com/@whykioh">Whykioh</a> :</h1>
<div class="video-container">
<iframe width="557,55" height="315" src="https://www.youtube.com/embed/-ZPjXjvdZFc?si=ldsNogAHy636GnzU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
</div>
</div>
<div class="footer">
Copyright | Whykorp® 2021-2024 | ajoute le nom du site après l'url et un /
</div>
</body>
</html>
+109 -109
View File
@@ -1,109 +1,109 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animated Wallpaper</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: black;
}
.background-image {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -1;
}
.animated-image {
position: absolute;
width: 400px;
height: 400px;
z-index: 1;
}
</style>
</head>
<body>
<img id="background-image" class="background-image" src="sketch_231005a/bg/jpc1.png" alt="Background Image">
<img id="animated-image" class="animated-image" src="sketch_231005a/jpc1.png" alt="Animated Image">
<script>
const images = [
'sketch_231005a/jpc1.png',
'sketch_231005a/jpc2.png',
'sketch_231005a/jpc3.png',
'sketch_231005a/jpc4.png',
'sketch_231005a/jpc5.png',
'sketch_231005a/jpc6.png',
'sketch_231005a/jpc7.png',
'sketch_231005a/jpc8.png',
'sketch_231005a/jpc9.png',
'sketch_231005a/jpc10.png',
'sketch_231005a/jpc11.png',
'sketch_231005a/jpc12.png',
'sketch_231005a/jpc13.png',
'sketch_231005a/jpc14.png',
'sketch_231005a/jpc15.png',
'sketch_231005a/jpc16.png',
];
const imagesbg = [
'sketch_231005a/bg/jpc1.png',
'sketch_231005a/bg/jpc2.png',
'sketch_231005a/bg/jpc3.png',
'sketch_231005a/bg/jpc4.png',
'sketch_231005a/bg/jpc5.png',
'sketch_231005a/bg/jpc6.png',
'sketch_231005a/bg/jpc7.png',
'sketch_231005a/bg/jpc8.png',
'sketch_231005a/bg/jpc9.png',
'sketch_231005a/bg/jpc10.png',
'sketch_231005a/bg/jpc11.png',
'sketch_231005a/bg/jpc12.png',
'sketch_231005a/bg/jpc13.png',
'sketch_231005a/bg/jpc14.png',
'sketch_231005a/bg/jpc15.png',
'sketch_231005a/bg/jpc16.png',
];
let imgIndex = 0;
let x = (window.innerWidth - 100) /2;
let y = (window.innerHeight - 100) /2;
let xSpeed = 2;
let ySpeed = 2;
const imgElement = document.getElementById('animated-image');
const bgElement = document.getElementById('background-image');
imgElement.src = images[imgIndex];
bgElement.src = imagesbg[imgIndex];
function updatePosition() {
x += xSpeed;
y += ySpeed;
if (x + imgElement.width >= window.innerWidth || x <= 0) {
xSpeed *= -1;
changeImage();
}
if (y + imgElement.height >= window.innerHeight || y <= 0) {
ySpeed *= -1;
changeImage();
}
imgElement.style.left = x + 'px';
imgElement.style.top = y + 'px';
requestAnimationFrame(updatePosition);
}
function changeImage() {
imgIndex = (imgIndex + 1) % images.length;
imgElement.src = images[imgIndex];
bgElement.src = imagesbg[imgIndex];
}
updatePosition();
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animated Wallpaper</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: black;
}
.background-image {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -1;
}
.animated-image {
position: absolute;
width: 400px;
height: 400px;
z-index: 1;
}
</style>
</head>
<body>
<img id="background-image" class="background-image" src="sketch_231005a/bg/jpc1.png" alt="Background Image">
<img id="animated-image" class="animated-image" src="sketch_231005a/jpc1.png" alt="Animated Image">
<script>
const images = [
'sketch_231005a/jpc1.png',
'sketch_231005a/jpc2.png',
'sketch_231005a/jpc3.png',
'sketch_231005a/jpc4.png',
'sketch_231005a/jpc5.png',
'sketch_231005a/jpc6.png',
'sketch_231005a/jpc7.png',
'sketch_231005a/jpc8.png',
'sketch_231005a/jpc9.png',
'sketch_231005a/jpc10.png',
'sketch_231005a/jpc11.png',
'sketch_231005a/jpc12.png',
'sketch_231005a/jpc13.png',
'sketch_231005a/jpc14.png',
'sketch_231005a/jpc15.png',
'sketch_231005a/jpc16.png',
];
const imagesbg = [
'sketch_231005a/bg/jpc1.png',
'sketch_231005a/bg/jpc2.png',
'sketch_231005a/bg/jpc3.png',
'sketch_231005a/bg/jpc4.png',
'sketch_231005a/bg/jpc5.png',
'sketch_231005a/bg/jpc6.png',
'sketch_231005a/bg/jpc7.png',
'sketch_231005a/bg/jpc8.png',
'sketch_231005a/bg/jpc9.png',
'sketch_231005a/bg/jpc10.png',
'sketch_231005a/bg/jpc11.png',
'sketch_231005a/bg/jpc12.png',
'sketch_231005a/bg/jpc13.png',
'sketch_231005a/bg/jpc14.png',
'sketch_231005a/bg/jpc15.png',
'sketch_231005a/bg/jpc16.png',
];
let imgIndex = 0;
let x = (window.innerWidth - 100) /2;
let y = (window.innerHeight - 100) /2;
let xSpeed = 2;
let ySpeed = 2;
const imgElement = document.getElementById('animated-image');
const bgElement = document.getElementById('background-image');
imgElement.src = images[imgIndex];
bgElement.src = imagesbg[imgIndex];
function updatePosition() {
x += xSpeed;
y += ySpeed;
if (x + imgElement.width >= window.innerWidth || x <= 0) {
xSpeed *= -1;
changeImage();
}
if (y + imgElement.height >= window.innerHeight || y <= 0) {
ySpeed *= -1;
changeImage();
}
imgElement.style.left = x + 'px';
imgElement.style.top = y + 'px';
requestAnimationFrame(updatePosition);
}
function changeImage() {
imgIndex = (imgIndex + 1) % images.length;
imgElement.src = images[imgIndex];
bgElement.src = imagesbg[imgIndex];
}
updatePosition();
</script>
</body>
</html>
+26 -26
View File
@@ -1,26 +1,26 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Pour Clara 💌</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="img/logo.png">
</head>
<body>
<div class="container">
<h1>Ma Semaine sans Toi ❤️</h1>
<p class="intro"> Coucou mon amoureuse damour que jaime tant❤️. Comme tu le vois je te fais un petit journal de mes journées, je vais beaucoup mennuyer sans toi donc je me suis dis que jallais moccuper un peu tout les jours à t’écrire deux trois mots que tu liras à ton retour. Le site te plaît ? Il est joli et tout rose héhé je lai fais moi même pour toi. Dans ce journal je te raconterai mes journées comme ça tu verras que sans toi cest pas pareil😣.</p>
<hr>
<div class="button-grid">
<button onclick="location.href='journals/1_dimanche.html'">Dimanche 27 Avril</button>
<button onclick="location.href='journals/2_lundi.html'">Lundi 28 Avril</button>
<button onclick="location.href='journals/3_mardi.html'">Mardi 29 Avril</button>
<button onclick="location.href='journals/4_mercredi.html'">Mercredi 30 Avril</button>
<button onclick="location.href='journals/5_jeudi.html'">Jeudi 1er Mai</button>
<button onclick="location.href='journals/6_vendredi.html'">Vendredi 2 Mai</button>
<button onclick="location.href='journals/7_samedi.html'">Samedi 3 Mai</button>
<button onclick="location.href='journals/8_dimanche.html'">Dimanche 4 Mai</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Pour Clara 💌</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="img/logo.png">
</head>
<body>
<div class="container">
<h1>Ma Semaine sans Toi ❤️</h1>
<p class="intro"> Coucou mon amoureuse damour que jaime tant❤️. Comme tu le vois je te fais un petit journal de mes journées, je vais beaucoup mennuyer sans toi donc je me suis dis que jallais moccuper un peu tout les jours à t’écrire deux trois mots que tu liras à ton retour. Le site te plaît ? Il est joli et tout rose héhé je lai fais moi même pour toi. Dans ce journal je te raconterai mes journées comme ça tu verras que sans toi cest pas pareil😣.</p>
<hr>
<div class="button-grid">
<button onclick="location.href='journals/1_dimanche.html'">Dimanche 27 Avril</button>
<button onclick="location.href='journals/2_lundi.html'">Lundi 28 Avril</button>
<button onclick="location.href='journals/3_mardi.html'">Mardi 29 Avril</button>
<button onclick="location.href='journals/4_mercredi.html'">Mercredi 30 Avril</button>
<button onclick="location.href='journals/5_jeudi.html'">Jeudi 1er Mai</button>
<button onclick="location.href='journals/6_vendredi.html'">Vendredi 2 Mai</button>
<button onclick="location.href='journals/7_samedi.html'">Samedi 3 Mai</button>
<button onclick="location.href='journals/8_dimanche.html'">Dimanche 4 Mai</button>
</div>
</div>
</body>
</html>
+31 -31
View File
@@ -1,31 +1,31 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 1 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 1 - Dimanche 27 Avril</h1>
<p>Là cest dimanche, tu me manques déjà beaucoup… Est-ce que cest parce que cest le début ? Ou bien mon manque est bel est bien justifié. Là il est 11h30 j’écoute Shaka Ponk en t’écrivant ses mots Lets baaaanng bang baaaang (pardon jsuis a fond) Je taime trop vraiment. Je tai envoyé deux images que mon père ma envoyé, une de moi avec Mathieu et Fabien et mon père où est en mode <a href="https://www.youtube.com/watch?v=_VfwZSygTeI&t=9s">WAAAAHH</a> (ptddr cest Waluigi) et la deuxième un meme que mon père ma envoyé qui est plutot drôle mais tu les as pas vus donc jimagine que tu dors sur la route (même si je pense que cest pas a 3h de route) ou que tu as déjà commencer. </p>
<p><em>Je viens juste de réaliser mais ce que je suis en train de te faire cest ton rêve, cest juste moi qui raconte ma vie et tu adores ça🤭.</em></p>
<p>Je te fais mon programme de la journée : Tout dabord je vais aller manger cest un bon début, pourquoi pas me laver ça serait une bonne option mdrr ensuite je pense que je vais ranger tout mon bordel dans ma chambre, ma mère me ramènera ensuite chez mon père, je rangerais tout et je retrouverai ROBEEERTT !!🤭Après jirai manger chez ma mamie je lui mettrai sa Wii ça va être drôle je pense, par contre jy reste jusqu’à mardi et ça membête un peu… Je voulais déprimer tout seul mdrr</p>
<p>Je pense que je vais laisser le document ouvert sur mon PC et des fois je viendrai t’écrire un peu. En plus j'ai mis une note sur Insta en mode "J'espère qu'elle lira tout" ahah c'est trop drôle tout le monde veut savoir pourquoi</p>
<p>Re coucouuu là il est 16h j'ai pas encore fais mon gouter mais ça ne saurait tarder ! Je suis allé voir ma mère on a jouer à un jeu rigolo avec les coques de pistaches en mode "si je la mets tu fais ça" c'était marrant mais personne n'a réussi de lancer... Après on a manger vite fait en regardant Le fabuleux destin d'Amélie Poulain je l'avais déjà vu et ça m'a fait plaisir de le revoir. Pendant le film m'a mère a voulu me faire une coupe de fou, t'as du voir les buddies même en ayant retiré les élastiques mes cheveux volaient mdrr j'en pouvais plus. Après ça ma mère m'a dit de ranger ma chambre car je vais bientôt partir, mais évidemment je me suis laisser m'égarer en fait j'ai regarder tous les images de plannings de live que Matreox avait fait et j'ai tout jugé mdrr t'aurais trop kiffé m'entendre juger je pense. Là je pense que je vais essayer de faire mon planning de lives pour cette semaine du moins un brouillon, je vais live tout les jours a partir de mardi, j'espère que tu viendras au moins pour faire un petit coucou. Je t'aime mon amour, j'espère que ça se passe bien de ton côté et que tu t'amuses. Bisouuus !❤️</p>
<p>Je pense beaucoup à toi c'est pas la première fois où je me surprends à regarder le vide tout en pensant à toi quand je m'en rends compte j'ai les yeux lourds, la boule au ventre et le coeur qui bat vite, presque en train de pleurer. Ça fait qu'un jour, c'est déjà trop long. Je passe souvent dans ma galerie pour regarder des photos de nous, on est trop mignons tous les deux. J'ai encore rien mis dans mon sac mais tant de "je t'aime" à t'écrire... Je pourrais faire ça toute la journée. Ça y est je pleure, j'ai trop regardé nos photos. Je te laisse je dois ranger ma chambre❤️</p>
<p>Coucouuu jai rangé ma chambre et mes affaires et jai fais le trajet vers chez mon père je suis vite aller dans ma chambre pour voir Robert, il était la il mattendait, je lui ai fait un gros gros calin et je suis allé me doucher. Tas déjà pleuré sous la douche toi ? Cest trop bizarre, ça mest arrivé je pensais trop à toi je crois. Jai refais mes sacs pour chez ma mamie, la je suis sur le trajet, je te dirai quand jy serai. Je taime mon amour❤️</p>
<p>Coucouuu, oh j'suis content tu m'as envoyé des messages🤭et j'ai mangé c'était bon ça va. Là je suis en voc avec Julien, il est trop happy de me montrer ce qu'il a eu sur Minecraft. J'espère qu'il va me remonter le moral. Il a fait vla les trucs vraiment, je vais rajouter des mods sinon on va s'ennuyer il a tout dans le jeu mdrr. Bon je te laisse mon amour, en plus y a peut etre Eudes et Enzo qui vont rejoindre. Bisouuus !❤️</p>
<p>Coucouu, tu dors alors je vais écrire pas trop fort. Là y a une ambiance trop chill j'adore, même s'il manque toi... Tout à l'heure j'étais en appel avec Julien, Enzo et Eudes Je te l'ai dis en plus et Eudes m'à dit que Simon à dit cette phrase "En vrai si Adrian vient pas avec nous au Pal tu pourras dire à Noah de venir" AAAAHHH Je te jure j'suis trop heureux, ça veut dire que ça va mieux avec Simon et que je vais pouvoir partir en vacances avec toi et avec mes potes, trop bien ! J'ai du bouger parce que j'étais dans la chambre de ma mamie et quand je suis revenu sur mon ordi y avait plus personne... Pas grave, alors j'ai commencé l'article d'Adrian, je te jure que j'adore faire ça genre vraiment si un jour t'as la flemme j'suis là hein (stp) Du coup là j'ai fini son article. Je suis posé sur la table à manger sur un siège de bureau avec du Shaka Ponk à fond I dont give a They dont give a We dont give a fuuuuck !! - mon frère regarde un film sur la télé et je vais continuer d'écrire mon article je pense. Ou alors je vais regarder youtube parce que je suis un peu fatigué je ferai ça demain. Putain je crois que j'ai un putain de moustique qui me tourne autour, pitié sauve moi mon amour... J'ai trop hâte de dormir parce que demain y a petit dej et le petit dej chez ma mamie c'est trop trop trop booon, donc en fait je vais dodo devant youtube, j'ai ramener Robert et Monsieur Plouf et le pull pour dormir dedans mais pas le plaid parce que le chien de ma mamie à le même plaid et elle les manges donc je veux pas qu'elle mange mon plaid.</p>
<hr>
<p>Bon je pense que je te reparlerai pas de la journée (en plus il est minuit passé là (00h20) du coup je vais te faire un débrief ! Aujourd'hui c'était dur.. J'ai pu te parler ce matin... un peu... Je pense vraiment que ce moment était le meilleur de la semaine. J'espère que ta lecture te plait jusqu'ici, je sais pas encore si je vais te le faire lire quand je serai là ou pas.. J'ai même hésiter à te faire lire un jour par jour, genre dimanche prochain tu lis que cette journée là. Je sais pas trop... Je me suis beaucoup ennuyer aujourd'hui et en plus mon père et ma mamie m'ont dit que j'avais l'air perdu toute la soirée. Je leur ai pas dis que tu me manquais, je pense que si ma mamie me demande demain je lui dirai et mon père je lui dirai sans doute mardi ou mercredi, aujourd'hui c'était pas le jour, je pouvais pas en parler sans pleurer Je l'ai dis a Julien j'ai chialer... en plus a un moment je sortais enfin de ma chambre parce que je faisais que de pleurer mon père a parlé de toi je sais plus pourquoi et j'ai couru dans ma chambre pour re pleurer. Mdrr je fais pitié je t'ai fais un word ou je te dis toutes les deux ligne que je chiale... Bonne nuit mon amour❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton amoureux d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='2_lundi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 1 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 1 - Dimanche 27 Avril</h1>
<p>Là cest dimanche, tu me manques déjà beaucoup… Est-ce que cest parce que cest le début ? Ou bien mon manque est bel est bien justifié. Là il est 11h30 j’écoute Shaka Ponk en t’écrivant ses mots Lets baaaanng bang baaaang (pardon jsuis a fond) Je taime trop vraiment. Je tai envoyé deux images que mon père ma envoyé, une de moi avec Mathieu et Fabien et mon père où est en mode <a href="https://www.youtube.com/watch?v=_VfwZSygTeI&t=9s">WAAAAHH</a> (ptddr cest Waluigi) et la deuxième un meme que mon père ma envoyé qui est plutot drôle mais tu les as pas vus donc jimagine que tu dors sur la route (même si je pense que cest pas a 3h de route) ou que tu as déjà commencer. </p>
<p><em>Je viens juste de réaliser mais ce que je suis en train de te faire cest ton rêve, cest juste moi qui raconte ma vie et tu adores ça🤭.</em></p>
<p>Je te fais mon programme de la journée : Tout dabord je vais aller manger cest un bon début, pourquoi pas me laver ça serait une bonne option mdrr ensuite je pense que je vais ranger tout mon bordel dans ma chambre, ma mère me ramènera ensuite chez mon père, je rangerais tout et je retrouverai ROBEEERTT !!🤭Après jirai manger chez ma mamie je lui mettrai sa Wii ça va être drôle je pense, par contre jy reste jusqu’à mardi et ça membête un peu… Je voulais déprimer tout seul mdrr</p>
<p>Je pense que je vais laisser le document ouvert sur mon PC et des fois je viendrai t’écrire un peu. En plus j'ai mis une note sur Insta en mode "J'espère qu'elle lira tout" ahah c'est trop drôle tout le monde veut savoir pourquoi</p>
<p>Re coucouuu là il est 16h j'ai pas encore fais mon gouter mais ça ne saurait tarder ! Je suis allé voir ma mère on a jouer à un jeu rigolo avec les coques de pistaches en mode "si je la mets tu fais ça" c'était marrant mais personne n'a réussi de lancer... Après on a manger vite fait en regardant Le fabuleux destin d'Amélie Poulain je l'avais déjà vu et ça m'a fait plaisir de le revoir. Pendant le film m'a mère a voulu me faire une coupe de fou, t'as du voir les buddies même en ayant retiré les élastiques mes cheveux volaient mdrr j'en pouvais plus. Après ça ma mère m'a dit de ranger ma chambre car je vais bientôt partir, mais évidemment je me suis laisser m'égarer en fait j'ai regarder tous les images de plannings de live que Matreox avait fait et j'ai tout jugé mdrr t'aurais trop kiffé m'entendre juger je pense. Là je pense que je vais essayer de faire mon planning de lives pour cette semaine du moins un brouillon, je vais live tout les jours a partir de mardi, j'espère que tu viendras au moins pour faire un petit coucou. Je t'aime mon amour, j'espère que ça se passe bien de ton côté et que tu t'amuses. Bisouuus !❤️</p>
<p>Je pense beaucoup à toi c'est pas la première fois où je me surprends à regarder le vide tout en pensant à toi quand je m'en rends compte j'ai les yeux lourds, la boule au ventre et le coeur qui bat vite, presque en train de pleurer. Ça fait qu'un jour, c'est déjà trop long. Je passe souvent dans ma galerie pour regarder des photos de nous, on est trop mignons tous les deux. J'ai encore rien mis dans mon sac mais tant de "je t'aime" à t'écrire... Je pourrais faire ça toute la journée. Ça y est je pleure, j'ai trop regardé nos photos. Je te laisse je dois ranger ma chambre❤️</p>
<p>Coucouuu jai rangé ma chambre et mes affaires et jai fais le trajet vers chez mon père je suis vite aller dans ma chambre pour voir Robert, il était la il mattendait, je lui ai fait un gros gros calin et je suis allé me doucher. Tas déjà pleuré sous la douche toi ? Cest trop bizarre, ça mest arrivé je pensais trop à toi je crois. Jai refais mes sacs pour chez ma mamie, la je suis sur le trajet, je te dirai quand jy serai. Je taime mon amour❤️</p>
<p>Coucouuu, oh j'suis content tu m'as envoyé des messages🤭et j'ai mangé c'était bon ça va. Là je suis en voc avec Julien, il est trop happy de me montrer ce qu'il a eu sur Minecraft. J'espère qu'il va me remonter le moral. Il a fait vla les trucs vraiment, je vais rajouter des mods sinon on va s'ennuyer il a tout dans le jeu mdrr. Bon je te laisse mon amour, en plus y a peut etre Eudes et Enzo qui vont rejoindre. Bisouuus !❤️</p>
<p>Coucouu, tu dors alors je vais écrire pas trop fort. Là y a une ambiance trop chill j'adore, même s'il manque toi... Tout à l'heure j'étais en appel avec Julien, Enzo et Eudes Je te l'ai dis en plus et Eudes m'à dit que Simon à dit cette phrase "En vrai si Adrian vient pas avec nous au Pal tu pourras dire à Noah de venir" AAAAHHH Je te jure j'suis trop heureux, ça veut dire que ça va mieux avec Simon et que je vais pouvoir partir en vacances avec toi et avec mes potes, trop bien ! J'ai du bouger parce que j'étais dans la chambre de ma mamie et quand je suis revenu sur mon ordi y avait plus personne... Pas grave, alors j'ai commencé l'article d'Adrian, je te jure que j'adore faire ça genre vraiment si un jour t'as la flemme j'suis là hein (stp) Du coup là j'ai fini son article. Je suis posé sur la table à manger sur un siège de bureau avec du Shaka Ponk à fond I dont give a They dont give a We dont give a fuuuuck !! - mon frère regarde un film sur la télé et je vais continuer d'écrire mon article je pense. Ou alors je vais regarder youtube parce que je suis un peu fatigué je ferai ça demain. Putain je crois que j'ai un putain de moustique qui me tourne autour, pitié sauve moi mon amour... J'ai trop hâte de dormir parce que demain y a petit dej et le petit dej chez ma mamie c'est trop trop trop booon, donc en fait je vais dodo devant youtube, j'ai ramener Robert et Monsieur Plouf et le pull pour dormir dedans mais pas le plaid parce que le chien de ma mamie à le même plaid et elle les manges donc je veux pas qu'elle mange mon plaid.</p>
<hr>
<p>Bon je pense que je te reparlerai pas de la journée (en plus il est minuit passé là (00h20) du coup je vais te faire un débrief ! Aujourd'hui c'était dur.. J'ai pu te parler ce matin... un peu... Je pense vraiment que ce moment était le meilleur de la semaine. J'espère que ta lecture te plait jusqu'ici, je sais pas encore si je vais te le faire lire quand je serai là ou pas.. J'ai même hésiter à te faire lire un jour par jour, genre dimanche prochain tu lis que cette journée là. Je sais pas trop... Je me suis beaucoup ennuyer aujourd'hui et en plus mon père et ma mamie m'ont dit que j'avais l'air perdu toute la soirée. Je leur ai pas dis que tu me manquais, je pense que si ma mamie me demande demain je lui dirai et mon père je lui dirai sans doute mardi ou mercredi, aujourd'hui c'était pas le jour, je pouvais pas en parler sans pleurer Je l'ai dis a Julien j'ai chialer... en plus a un moment je sortais enfin de ma chambre parce que je faisais que de pleurer mon père a parlé de toi je sais plus pourquoi et j'ai couru dans ma chambre pour re pleurer. Mdrr je fais pitié je t'ai fais un word ou je te dis toutes les deux ligne que je chiale... Bonne nuit mon amour❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton amoureux d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='2_lundi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
+22 -22
View File
@@ -1,22 +1,22 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 3 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 3 - Mardi 29 Avril</h1>
<p>Coucouu, alors aujourd'hui était une journée bien plus chargée que prévu du coup j'ai pas trop pu prendre la parole ici... Là il est 23h30 et il s'est passé beaucoup de trucs. Du coup je vais tout te raconter mais rapidement parce que j'ai un peu (beaucoup) envie de faire de l'ASMR.. Désolé. Donc j'ai fais mon petit dej trop bienn dehors comme hier ensuite on a tout rangé et je me suis remis sur ma Wii qui voulait pas ajouter les nouveaux jeux à la liste je cherche mais je trouve pas. En même temps ma mamie me parle d'un de ses vieil ordi (très vieux hein de 2007) qui marchait très bien mais qui est juste bloqué. Bon pas grave je lance un transfert sur la Wii et en attendant je m'occupe de cet ordi. En l'allumant l'écran n'affiche rien, j'en conclu que l'écran est HS alors je le branche à la télé et BOUM y a un truc. Alors c'est rempli de "!!" et entre ces "!!" il y a du texte mais écrit bizarrement, on aurait dit qu'il manquait des lettre ou que certaines lettre n'étaient pas les bonnes. Je me décide de réinstaller un Windows dessus tant qu'a faire j'en mets un vieux pour pas que l'ordi lag trop je choisi un Windows 7, qui n'est certes plus assuré par les mises à jour mais qui fera bien le taff. Et là ma mamie me dit que Yannick (mon tonton) avait déjà essayé de réparer l'ordi mais n'avait pas réussi donc il a démonté le disque dur pour récupérer les photos et askip il a gardé le disque... Je démonte l'ordi et effectivement il manque le disque dur.. Merde ! Je décide de tout démonter afin de vérifier que l'ordi est entier et que mon tonton ne se soit pas servit dedans (il aurait pu le faire). Et là je vois un emplacement vide.. De la RAM en plus ? Non l'emplacement est trop petit.. Je demande à ChatGPT et d'après lui c'est un emplacement IDE. Pour l'info les disques durs de nos jours sont soit des SSD (les très rapides) soit des HDD. Aujourd'hui on connecte les HDD avec des prises SATA (comme on connecterait un téléphone en Type-C) mais avant il éxistait une antiquité, la prise IDE avec des nappes. C'était la même vitesse qu'une disquette. Bref je m'égare. En tout cas il manque rien a part le disque dûr. Ma mamie m'a donc confié l'ordi pour que je m'en occupe dans la semaine (je ferai ça Samedi ou Vendredi) Entre temps le disque dur de la Wii avait tout fini je lance et là rien... Je fouille les paramètre de l'appli Wii où y a tous mes jeux, je décoche une option et ça y est ! Ça marche !! Et là on joue a Wii Sport Resort pendant que je faisais des steaks (oui pour encore manger des burgers mdrr) et c'était marrant, genre on faisait le bowling chacun son tour, c'était assez fun. On mange dehors il fait beau il fait bon c'est cool. Je vais donc à la douche (j'ai fais ton buddies🤭) Et juste après paf on rentre pour chez mon père. Sur le chemin j'ai un peu dormi, mais vite fait j'avais juste les yeux fermés et le vent sur la tête, trop confort. On arrive je mon mes affaires enfin heureux de ENFIN retrouver ma chambre putain (et aussi de retrouver ta boîte à goûter) ma mamie boit le café vite fait puis ils s'en vont. Avec mon père on règle un problème avec le serveur puis on fait un petit apéro en finissant un spéctacle qu'on avait commencé et ensuite on va voir Pierre Emmanuel Barré. Oh j'étais trop content tu m'as appelé. Son spectacle était drôle mais je t'en dirai plus en voc j'ai un peu la flemme mon amour. On est rentré on a fait burger king mdrr j'ai branché mon ordi et je t'écris ceci avant de te parler pas messages. Là tu m'en envoies j'suis trop heureux</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton homme, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='2_lundi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 3 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 3 - Mardi 29 Avril</h1>
<p>Coucouu, alors aujourd'hui était une journée bien plus chargée que prévu du coup j'ai pas trop pu prendre la parole ici... Là il est 23h30 et il s'est passé beaucoup de trucs. Du coup je vais tout te raconter mais rapidement parce que j'ai un peu (beaucoup) envie de faire de l'ASMR.. Désolé. Donc j'ai fais mon petit dej trop bienn dehors comme hier ensuite on a tout rangé et je me suis remis sur ma Wii qui voulait pas ajouter les nouveaux jeux à la liste je cherche mais je trouve pas. En même temps ma mamie me parle d'un de ses vieil ordi (très vieux hein de 2007) qui marchait très bien mais qui est juste bloqué. Bon pas grave je lance un transfert sur la Wii et en attendant je m'occupe de cet ordi. En l'allumant l'écran n'affiche rien, j'en conclu que l'écran est HS alors je le branche à la télé et BOUM y a un truc. Alors c'est rempli de "!!" et entre ces "!!" il y a du texte mais écrit bizarrement, on aurait dit qu'il manquait des lettre ou que certaines lettre n'étaient pas les bonnes. Je me décide de réinstaller un Windows dessus tant qu'a faire j'en mets un vieux pour pas que l'ordi lag trop je choisi un Windows 7, qui n'est certes plus assuré par les mises à jour mais qui fera bien le taff. Et là ma mamie me dit que Yannick (mon tonton) avait déjà essayé de réparer l'ordi mais n'avait pas réussi donc il a démonté le disque dur pour récupérer les photos et askip il a gardé le disque... Je démonte l'ordi et effectivement il manque le disque dur.. Merde ! Je décide de tout démonter afin de vérifier que l'ordi est entier et que mon tonton ne se soit pas servit dedans (il aurait pu le faire). Et là je vois un emplacement vide.. De la RAM en plus ? Non l'emplacement est trop petit.. Je demande à ChatGPT et d'après lui c'est un emplacement IDE. Pour l'info les disques durs de nos jours sont soit des SSD (les très rapides) soit des HDD. Aujourd'hui on connecte les HDD avec des prises SATA (comme on connecterait un téléphone en Type-C) mais avant il éxistait une antiquité, la prise IDE avec des nappes. C'était la même vitesse qu'une disquette. Bref je m'égare. En tout cas il manque rien a part le disque dûr. Ma mamie m'a donc confié l'ordi pour que je m'en occupe dans la semaine (je ferai ça Samedi ou Vendredi) Entre temps le disque dur de la Wii avait tout fini je lance et là rien... Je fouille les paramètre de l'appli Wii où y a tous mes jeux, je décoche une option et ça y est ! Ça marche !! Et là on joue a Wii Sport Resort pendant que je faisais des steaks (oui pour encore manger des burgers mdrr) et c'était marrant, genre on faisait le bowling chacun son tour, c'était assez fun. On mange dehors il fait beau il fait bon c'est cool. Je vais donc à la douche (j'ai fais ton buddies🤭) Et juste après paf on rentre pour chez mon père. Sur le chemin j'ai un peu dormi, mais vite fait j'avais juste les yeux fermés et le vent sur la tête, trop confort. On arrive je mon mes affaires enfin heureux de ENFIN retrouver ma chambre putain (et aussi de retrouver ta boîte à goûter) ma mamie boit le café vite fait puis ils s'en vont. Avec mon père on règle un problème avec le serveur puis on fait un petit apéro en finissant un spéctacle qu'on avait commencé et ensuite on va voir Pierre Emmanuel Barré. Oh j'étais trop content tu m'as appelé. Son spectacle était drôle mais je t'en dirai plus en voc j'ai un peu la flemme mon amour. On est rentré on a fait burger king mdrr j'ai branché mon ordi et je t'écris ceci avant de te parler pas messages. Là tu m'en envoies j'suis trop heureux</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton homme, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='2_lundi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+29 -29
View File
@@ -1,29 +1,29 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 4 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 4 - Mercredi 30 Avril</h1>
<p>Coucouuu ça va ? Bien dormi ? Moi oui mais il me manquait ma femme.. Je me suis levé grave tôt il était 9h, là il est 10h et je suis en pleine écriture de mon article, je charbone pour pouvoir le rendre vers midi je pense. J'ai fais a peu près 1000 mots là et j'ai pas fini encore. Avant de commencer à écrire j'ai checké vite fait un peu tout, le pdf et le site voir si Adrian ne s'était pas planté et il a oublié les mots en gras sur le site... Du coup je te le dis et là tu me dis la pire chose que tu pourrais me dire "Dis lui de le mettre" WAAAAA MAIS JE VAIS ME FAIRE SOULEVER. Bon tu sais que je ferai tout pour toi hein je vais surmonter ma peur et je vais lui dire vu que t'es occupée... Là je vais lui envoyer un message, changer de pentalon (je me serai chié dessus) prier et retourner écrire mon article. Au fait tant que j'y pense Vendredi je me fais couper les cheveux haha. Bon je te laisse je vais écrire mon testament mdrr. Bisouus !</p>
<p>Coucouu euh je t'écrire vraiment une minute après ce qu'il y a au dessus mdrr mais j'ai un soucis mon Spotify ne veux plus que j'écoute l'album Toxicity de System genre je lance l'album et ça me met une seconde de chaque son jusqu'au dernier et ça coupe, je vais mourir vraiment mdrr bon aller bisous ! Même mon père ! Est dans le coup...</p>
<img src="../img/screen_cheh_papa.png" alt="Screen de la conversation avec mon père" class="screenshot">
<p>Coucouuu ça va ? Il est 14h bientôt j'ai bien mangé, mon père a fait des pâtes et on y a mit du gruyère sauf que je sens une odeur bizarre, un fois à table. Je dis à mon père "le gruyère est pas périmé ? Mon père dit non et puis je regarde attentivement. Mdrr y avait des taches bleues dans le gruyère.. Du coup on a jetté et on s'est reservi à contre coeur... Et j'ai fini mon article je vais le mettre sur le pdf. Il fait 1600 mots donc ça va en vrai, comme celui à Célia si je dis pas de bêtises. Bref je m'y mets parce que je dois prendre une douche après ça pour aller au cinéma, je vais voir Thunderbolts* Bref Bisouuu mon amouuuur (j'ai vu que tu as fais des buddies j'suis content)</p>
<p>Coucouuu Il est 16h45 là je vais bien de fou ! J'ai tout fini sur mon article j'ai mis en page et j'ai planifié mon article. Adrian n'a toujours pas vu mon message alors qu'il a posté une note sur Insta y a 2h... On te voit en fait. Après ça j'ai pris une douche et mon frère est arrivé avec ma mamie et mon père, je les ait laisser discuter pour envoyer le message sur le groupe du Gay-Lu Times. J'ai géré de fouuu. Je t'aime mon amour, j'espère que tu es fière de moi même si tu es loin de moi... </p>
<p>Coucouu mon amour ! Je suis si bouleversé, tu m'as appelé. Mais avant je suis allé au cinéma pour voir Thunderbolts* Le film est... Je sais pas, bof je dirai. Ni nul ni bien en fait.. Après ça je suis allé au Quick et on a eu un burger gratuit, truc de fou ! Mais bon ça tu le sais déjà du coup j'ai moins de trucs à te dire ce soir... Ah si quand on rentrait au feu rouge ou y a le Legrand on avait la music A.N.U.S. de Ultra Vomit et au même moment y a un vieux aigri qui s'est arrêté à côté de nous. Mon père à monté le son progressivement en faisant exprès mdrr c'était très drole.</p>
<hr>
<p>Je t'aime mon amour, tu me manques trop je pensais que j'avais passé le cap mais j'ai pleuré quand tu as raccroché tout à l'heure. Pour te l'avouer j'avais déjà commencer avant que tu quittes (un peu comme quand on fait de l'asmr tout les deux en appel). J'aimerai trop te serrer dans mes bras, enfin ressentir la chaleur de ton corps contre le miens, goûter à tes belles et douces lèvres, désirer ton regard et observer les étoiles à travers tes yeux, caresser des belles joues et jouer avec tes soyeux cheveux. Je m'égard là.. Bref, bonne nuit mon amour je t'aime tellement</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ta crotte d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='3_mardi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 4 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 4 - Mercredi 30 Avril</h1>
<p>Coucouuu ça va ? Bien dormi ? Moi oui mais il me manquait ma femme.. Je me suis levé grave tôt il était 9h, là il est 10h et je suis en pleine écriture de mon article, je charbone pour pouvoir le rendre vers midi je pense. J'ai fais a peu près 1000 mots là et j'ai pas fini encore. Avant de commencer à écrire j'ai checké vite fait un peu tout, le pdf et le site voir si Adrian ne s'était pas planté et il a oublié les mots en gras sur le site... Du coup je te le dis et là tu me dis la pire chose que tu pourrais me dire "Dis lui de le mettre" WAAAAA MAIS JE VAIS ME FAIRE SOULEVER. Bon tu sais que je ferai tout pour toi hein je vais surmonter ma peur et je vais lui dire vu que t'es occupée... Là je vais lui envoyer un message, changer de pentalon (je me serai chié dessus) prier et retourner écrire mon article. Au fait tant que j'y pense Vendredi je me fais couper les cheveux haha. Bon je te laisse je vais écrire mon testament mdrr. Bisouus !</p>
<p>Coucouu euh je t'écrire vraiment une minute après ce qu'il y a au dessus mdrr mais j'ai un soucis mon Spotify ne veux plus que j'écoute l'album Toxicity de System genre je lance l'album et ça me met une seconde de chaque son jusqu'au dernier et ça coupe, je vais mourir vraiment mdrr bon aller bisous ! Même mon père ! Est dans le coup...</p>
<img src="../img/screen_cheh_papa.png" alt="Screen de la conversation avec mon père" class="screenshot">
<p>Coucouuu ça va ? Il est 14h bientôt j'ai bien mangé, mon père a fait des pâtes et on y a mit du gruyère sauf que je sens une odeur bizarre, un fois à table. Je dis à mon père "le gruyère est pas périmé ? Mon père dit non et puis je regarde attentivement. Mdrr y avait des taches bleues dans le gruyère.. Du coup on a jetté et on s'est reservi à contre coeur... Et j'ai fini mon article je vais le mettre sur le pdf. Il fait 1600 mots donc ça va en vrai, comme celui à Célia si je dis pas de bêtises. Bref je m'y mets parce que je dois prendre une douche après ça pour aller au cinéma, je vais voir Thunderbolts* Bref Bisouuu mon amouuuur (j'ai vu que tu as fais des buddies j'suis content)</p>
<p>Coucouuu Il est 16h45 là je vais bien de fou ! J'ai tout fini sur mon article j'ai mis en page et j'ai planifié mon article. Adrian n'a toujours pas vu mon message alors qu'il a posté une note sur Insta y a 2h... On te voit en fait. Après ça j'ai pris une douche et mon frère est arrivé avec ma mamie et mon père, je les ait laisser discuter pour envoyer le message sur le groupe du Gay-Lu Times. J'ai géré de fouuu. Je t'aime mon amour, j'espère que tu es fière de moi même si tu es loin de moi... </p>
<p>Coucouu mon amour ! Je suis si bouleversé, tu m'as appelé. Mais avant je suis allé au cinéma pour voir Thunderbolts* Le film est... Je sais pas, bof je dirai. Ni nul ni bien en fait.. Après ça je suis allé au Quick et on a eu un burger gratuit, truc de fou ! Mais bon ça tu le sais déjà du coup j'ai moins de trucs à te dire ce soir... Ah si quand on rentrait au feu rouge ou y a le Legrand on avait la music A.N.U.S. de Ultra Vomit et au même moment y a un vieux aigri qui s'est arrêté à côté de nous. Mon père à monté le son progressivement en faisant exprès mdrr c'était très drole.</p>
<hr>
<p>Je t'aime mon amour, tu me manques trop je pensais que j'avais passé le cap mais j'ai pleuré quand tu as raccroché tout à l'heure. Pour te l'avouer j'avais déjà commencer avant que tu quittes (un peu comme quand on fait de l'asmr tout les deux en appel). J'aimerai trop te serrer dans mes bras, enfin ressentir la chaleur de ton corps contre le miens, goûter à tes belles et douces lèvres, désirer ton regard et observer les étoiles à travers tes yeux, caresser des belles joues et jouer avec tes soyeux cheveux. Je m'égard là.. Bref, bonne nuit mon amour je t'aime tellement</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ta crotte d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='3_mardi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+29 -29
View File
@@ -1,29 +1,29 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 5 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 5 - Jeudi 1er Mai</h1>
<p>Coucouu mon amour alors là il est 3h du matin, juste pour te dire que je vais aller me coucher mais je venais de faire le site que tu regardes là. Hehe j'suis trop fier de ce que j'ai fais c'est tout kiki, comme toi ❤️</p>
<p>Coucouuu ça va mon amour ? ❤️ J'ai bien dormi perso, je me suis levé à midi mais j'avais fais un rêve trop bizarre je me souviens pas de tout, mais je sais qu'à un moment mon frère fouille ce site là. Et à la fin je vais dans le garage de mes grands parents pour prendre une bouteille de Pepsi sauf qu'elle est chaude de fou vu qu'elle est restée au soleil, du coup je la mets au congélateur pour la refroidir un peu. Mais je remarque que depuis le début j'avais les yeux fermés et flous, tu sais comme quand tu viens de te réveiller. Du coup je cours en montant à l'étage pour me débarbouiller le visage. Et là je monte et c'est l'étage de ma maison à Feytiat, et en fait je cours parce qu'il y a quelqu'un derière moi qui veut me tuer, je sais pas qui c'est. J'arrive dans la salle de bain et je cherche un gant, j'en trouve pas du coup je fais ça avec une serviette et là le mec qui veut me tuer s'approche et me rend la bouteille de pepsi. Wesh.. Et là je me réveille... Bizarre. Bon après j'ai fais un Fifa pendant que mon père faisait à manger - c'est à dire des frites - et après ça j'ai mangé le burger en trop d'hier. On a regardé le Hot Ones avec Alain Chabat c'est trop bien. Et là il est 14h33 je sais pas ce que je vais faire, je vais surement brancher mon volant pour jouer à un jeu, pourquoi pas à BeamNG Drive. Bref je te laisse mon amour. Bisouuus</p>
<p>Je suis vraiment premier degrès en train de péter un plomb, j'en ai marre je sais pas quoi faire. J'ai littéralement fais tout ce que je pouvais faire. J'ai passé 2h sur un jeu de merde qui me plaisait pas juste parce que je savais pas quoi faire, bah j'ai vite abandonné. Et là je suis à deux doigts de casser mon écran ou de je jeter par la fenêtre, voire même de me jeter par la fenêtre. Je suis en train de devenir fou j'en peux plus. Reviens s'il te plait, je m'ennuie sans toi...</p>
<p>Euh j'allais t'écrire là mais je vois ça ⬇️ Il faut savoir que l'IA du logiciel de code prédis ce que je vais écrire. Bon là il essaye de prédire des truc nul mais wesh pourquoi il sait pour Feytiat. C'est mentionné nulle part ailleurs. Trop bizarre</p>
<img src="../img/ia.png" alt="IA qui prédit Feytiat" class="ia" width="90%">
<p>MDRRR Et là il m'a prédis la ligne pour mettre l'image en mettant le titre "IA qui prédit Feytiat" j'vais cabler</p>
<p>Bon du coup je voulais te dire. Là il est 3h du mat oui je triche on est vendredi techniquement mdrr. Je m'ennuyais trop à jouer à GT4 que du coup j'ai fais du casque et pour la vanne j'ai testé les jeux 18+. Mdrr comment c'est claqué au sol c'est juste pas pratique en fait je vois pas comment tu peux faire l'asmr en vrai en jouant à ça t'as constament les mains prises. Bref. Après ça je suis allé faire le gouter et je me suis dis que j'allais live à 20h J'ai rejoins Julien et Enzo en vocal. Enzo est parti quand j'ai lancé le live parce qu'il devait manger. Pas grave. J'ai d'abord fais du bedwars comme à l'ancienne mais mon ordi buggait trop c'est une dinguerie du coup j'ai changé pour Arcade Paradise (j'avais déjà commencé le jeu en live) Après ça Julien m'a rappelé l'existance du jeu The Exit 8 en fait ça fait un an je pense que je veux faire une vidéo dessus mais que j'y pensse pas. Du coup j'ai fais un live dessus et le concept est trop bien, y aura un montage sur ma chaine de ce gameplay. Ensuite j'ai coupé le live il était 23h30 mdrr et avec julien on a trainé sur les activités discord on a trouvé un Uno trop bien et on a joué au golf après. J'ai dis que je voulais dormir et il a lancé le tableau blanc commun mdrr. Evidemment on a fait des ref à 39-45 tu connais mdrr et après je t'écris et je vais dodo.</p>
<hr>
<p>Tu me manques trop vraiment. Aujourd'hui j'ai pas répondu à tes messages Insta et tu vas peut être trouver ça bizarre et me prendre pour un fou mais hier j'ai eu peur. Hier t'as envoyé des emojis que t'envoies jamais mais genre vraiment jamais. Ils faisaient quoi dans les récents alors ? Surtout celui qui regarde à travers ses yeux là. Tu l'envoie jamais et tu l'as envoyé à quelqu'un, je vois pas à qui ça peut être à part un amant, en mode "chut ça reste entre nous on lui dis pas"... Désolé je continue avec ça tu sais que c'est mon pire cauchemar.. Et en vrai j'ai aucune raison de pas te répondre. Je me doute trop de ce genre de choses. Mais comprends moi t'es loin si jamais tu en aurais l'envie tu aurais pu me tromper à cette distance je n'en saurai rien.. J'ai un peu déprimé aujourd'hui à cause de ça et je sais très bien que te le dire là par message n'arrangera rien parce que tu vas répéter comme d'habitude que tu n'oserai jamais faire ça. Bref désolé j'ai écris tout ça pour rien je vais effacer je pense.<br>Demain je vais chez le coiffeur à 11h fini les cheveux longs en plus après je vais acheter pleins de fringues je vais vraiment changer premier degrés ça va être cool. J'espère. En vrai j'aurai préféré faire ça avec toi, les boutiques et tout.. Bref je te laisse je vais dormir bonne nuit bisous ❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton cocu ?, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 5 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 5 - Jeudi 1er Mai</h1>
<p>Coucouu mon amour alors là il est 3h du matin, juste pour te dire que je vais aller me coucher mais je venais de faire le site que tu regardes là. Hehe j'suis trop fier de ce que j'ai fais c'est tout kiki, comme toi ❤️</p>
<p>Coucouuu ça va mon amour ? ❤️ J'ai bien dormi perso, je me suis levé à midi mais j'avais fais un rêve trop bizarre je me souviens pas de tout, mais je sais qu'à un moment mon frère fouille ce site là. Et à la fin je vais dans le garage de mes grands parents pour prendre une bouteille de Pepsi sauf qu'elle est chaude de fou vu qu'elle est restée au soleil, du coup je la mets au congélateur pour la refroidir un peu. Mais je remarque que depuis le début j'avais les yeux fermés et flous, tu sais comme quand tu viens de te réveiller. Du coup je cours en montant à l'étage pour me débarbouiller le visage. Et là je monte et c'est l'étage de ma maison à Feytiat, et en fait je cours parce qu'il y a quelqu'un derière moi qui veut me tuer, je sais pas qui c'est. J'arrive dans la salle de bain et je cherche un gant, j'en trouve pas du coup je fais ça avec une serviette et là le mec qui veut me tuer s'approche et me rend la bouteille de pepsi. Wesh.. Et là je me réveille... Bizarre. Bon après j'ai fais un Fifa pendant que mon père faisait à manger - c'est à dire des frites - et après ça j'ai mangé le burger en trop d'hier. On a regardé le Hot Ones avec Alain Chabat c'est trop bien. Et là il est 14h33 je sais pas ce que je vais faire, je vais surement brancher mon volant pour jouer à un jeu, pourquoi pas à BeamNG Drive. Bref je te laisse mon amour. Bisouuus</p>
<p>Je suis vraiment premier degrès en train de péter un plomb, j'en ai marre je sais pas quoi faire. J'ai littéralement fais tout ce que je pouvais faire. J'ai passé 2h sur un jeu de merde qui me plaisait pas juste parce que je savais pas quoi faire, bah j'ai vite abandonné. Et là je suis à deux doigts de casser mon écran ou de je jeter par la fenêtre, voire même de me jeter par la fenêtre. Je suis en train de devenir fou j'en peux plus. Reviens s'il te plait, je m'ennuie sans toi...</p>
<p>Euh j'allais t'écrire là mais je vois ça ⬇️ Il faut savoir que l'IA du logiciel de code prédis ce que je vais écrire. Bon là il essaye de prédire des truc nul mais wesh pourquoi il sait pour Feytiat. C'est mentionné nulle part ailleurs. Trop bizarre</p>
<img src="../img/ia.png" alt="IA qui prédit Feytiat" class="ia" width="90%">
<p>MDRRR Et là il m'a prédis la ligne pour mettre l'image en mettant le titre "IA qui prédit Feytiat" j'vais cabler</p>
<p>Bon du coup je voulais te dire. Là il est 3h du mat oui je triche on est vendredi techniquement mdrr. Je m'ennuyais trop à jouer à GT4 que du coup j'ai fais du casque et pour la vanne j'ai testé les jeux 18+. Mdrr comment c'est claqué au sol c'est juste pas pratique en fait je vois pas comment tu peux faire l'asmr en vrai en jouant à ça t'as constament les mains prises. Bref. Après ça je suis allé faire le gouter et je me suis dis que j'allais live à 20h J'ai rejoins Julien et Enzo en vocal. Enzo est parti quand j'ai lancé le live parce qu'il devait manger. Pas grave. J'ai d'abord fais du bedwars comme à l'ancienne mais mon ordi buggait trop c'est une dinguerie du coup j'ai changé pour Arcade Paradise (j'avais déjà commencé le jeu en live) Après ça Julien m'a rappelé l'existance du jeu The Exit 8 en fait ça fait un an je pense que je veux faire une vidéo dessus mais que j'y pensse pas. Du coup j'ai fais un live dessus et le concept est trop bien, y aura un montage sur ma chaine de ce gameplay. Ensuite j'ai coupé le live il était 23h30 mdrr et avec julien on a trainé sur les activités discord on a trouvé un Uno trop bien et on a joué au golf après. J'ai dis que je voulais dormir et il a lancé le tableau blanc commun mdrr. Evidemment on a fait des ref à 39-45 tu connais mdrr et après je t'écris et je vais dodo.</p>
<hr>
<p>Tu me manques trop vraiment. Aujourd'hui j'ai pas répondu à tes messages Insta et tu vas peut être trouver ça bizarre et me prendre pour un fou mais hier j'ai eu peur. Hier t'as envoyé des emojis que t'envoies jamais mais genre vraiment jamais. Ils faisaient quoi dans les récents alors ? Surtout celui qui regarde à travers ses yeux là. Tu l'envoie jamais et tu l'as envoyé à quelqu'un, je vois pas à qui ça peut être à part un amant, en mode "chut ça reste entre nous on lui dis pas"... Désolé je continue avec ça tu sais que c'est mon pire cauchemar.. Et en vrai j'ai aucune raison de pas te répondre. Je me doute trop de ce genre de choses. Mais comprends moi t'es loin si jamais tu en aurais l'envie tu aurais pu me tromper à cette distance je n'en saurai rien.. J'ai un peu déprimé aujourd'hui à cause de ça et je sais très bien que te le dire là par message n'arrangera rien parce que tu vas répéter comme d'habitude que tu n'oserai jamais faire ça. Bref désolé j'ai écris tout ça pour rien je vais effacer je pense.<br>Demain je vais chez le coiffeur à 11h fini les cheveux longs en plus après je vais acheter pleins de fringues je vais vraiment changer premier degrés ça va être cool. J'espère. En vrai j'aurai préféré faire ça avec toi, les boutiques et tout.. Bref je te laisse je vais dormir bonne nuit bisous ❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton cocu ?, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+23 -23
View File
@@ -1,23 +1,23 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 6 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 6 - Vendredi 2 Mai</h1>
<p>Coucou mon amour ! Je vais tout t'écrire en une fois et y a plein de trucs à dire en plus ! Aujourd'hui je me suis levé et je suis allé dans la boite aux lettre récupérer le lecteur de disques durs pour pouvoir améliorer le serveur et mon ordi, je le débale je met le 2to que mon père m'a donné et je me dis que je vais mettre mon disque C dedans, remettre à 0 mon ordi pour l'ocasion. Bon j'ai que transféré là. Après ça je suis allé chez le coiffeur, elle a bien réussi ma coupe je trouve genre excatement ce à quoi je pensais. Donc nickel. Mais mon frère y est allé après et la coiffeuse à dit "Tu veux quoi comme coupe ?" Mon frère à dit "court." Bon.. ça tête ressemble à une mousse de micro mdrr, on dirait un télétubbies mais sans l'antenne bref avec mon frère on a vanné sa coupe toute la journée mdrr. Après fallait manger, moi je voulais manger à l'appart parce que flemme d'encore manger dehors. On a manger à Monsieur le Baron. Tu sais c'est le gros resto deluxe qui a pris feut pas loin du lycée. J'ai suivi mon père et mon frère à contre coeur j'en peux plus de manger des burgers mdrr. C'était bon en vrai. Après on est allés à Family Village on est allé à Inter Sport pour prendre des vetement pour moi puis à la halle puis à décatelon (on a fait une escale à boulanger pour que mon père se renseigne sur sa future télé mdrr) du coup j'ai pleins de nouveux vetements c'est trop bien. J'ai aussi pris un maillot de bain mais pas de claquette vu que je prendrais des Crocs vu que madame n'a d'yeux que pour les crocs. Je suis rentré et j'ai reset mon ordi pendant que je jouais à Mortal Kombat 1 avec mon père. J'ai galéré de fou, en fait mon ordi et sur protégé du coup pour formater bah c'est chiant. J'ai appliqué la méthode forte sauf qu'après j'avais plus rien qui marchait à part la souris et le clavier genre la luminosité de l'écran non et le wifi non plus. Après des heures de recherches j'ai rétabli le wifi le bluetooth la luminosité et d'autres trucs. J'ai mangé une petite salade et j'ai installé Need For Speed Most Wanted, la version de 2005, ce jeu est ouf pour 2005 vraiment. J'y jouais en étant en vocal avec Julien Enzo et Eudes qui est parti tôt.</p>
<hr>
<p>Je suis désolé mon amour j'ai pas osé répondre à tes messages, déjà parce que tu me les envoyais toujours au mauvais moment et en plus j'osais pas, je sais jamais quoi dire après t'avoir mis un remis, je m'en veux d'un côté mais d'un autre je trouve ça toujours aussi louche.. Désolé je force avec ça, je changerai jamais.. Bref Bisous Je t'aime mon amour dort bien❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton informaticien du dimanche, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='7_samedi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 6 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 6 - Vendredi 2 Mai</h1>
<p>Coucou mon amour ! Je vais tout t'écrire en une fois et y a plein de trucs à dire en plus ! Aujourd'hui je me suis levé et je suis allé dans la boite aux lettre récupérer le lecteur de disques durs pour pouvoir améliorer le serveur et mon ordi, je le débale je met le 2to que mon père m'a donné et je me dis que je vais mettre mon disque C dedans, remettre à 0 mon ordi pour l'ocasion. Bon j'ai que transféré là. Après ça je suis allé chez le coiffeur, elle a bien réussi ma coupe je trouve genre excatement ce à quoi je pensais. Donc nickel. Mais mon frère y est allé après et la coiffeuse à dit "Tu veux quoi comme coupe ?" Mon frère à dit "court." Bon.. ça tête ressemble à une mousse de micro mdrr, on dirait un télétubbies mais sans l'antenne bref avec mon frère on a vanné sa coupe toute la journée mdrr. Après fallait manger, moi je voulais manger à l'appart parce que flemme d'encore manger dehors. On a manger à Monsieur le Baron. Tu sais c'est le gros resto deluxe qui a pris feut pas loin du lycée. J'ai suivi mon père et mon frère à contre coeur j'en peux plus de manger des burgers mdrr. C'était bon en vrai. Après on est allés à Family Village on est allé à Inter Sport pour prendre des vetement pour moi puis à la halle puis à décatelon (on a fait une escale à boulanger pour que mon père se renseigne sur sa future télé mdrr) du coup j'ai pleins de nouveux vetements c'est trop bien. J'ai aussi pris un maillot de bain mais pas de claquette vu que je prendrais des Crocs vu que madame n'a d'yeux que pour les crocs. Je suis rentré et j'ai reset mon ordi pendant que je jouais à Mortal Kombat 1 avec mon père. J'ai galéré de fou, en fait mon ordi et sur protégé du coup pour formater bah c'est chiant. J'ai appliqué la méthode forte sauf qu'après j'avais plus rien qui marchait à part la souris et le clavier genre la luminosité de l'écran non et le wifi non plus. Après des heures de recherches j'ai rétabli le wifi le bluetooth la luminosité et d'autres trucs. J'ai mangé une petite salade et j'ai installé Need For Speed Most Wanted, la version de 2005, ce jeu est ouf pour 2005 vraiment. J'y jouais en étant en vocal avec Julien Enzo et Eudes qui est parti tôt.</p>
<hr>
<p>Je suis désolé mon amour j'ai pas osé répondre à tes messages, déjà parce que tu me les envoyais toujours au mauvais moment et en plus j'osais pas, je sais jamais quoi dire après t'avoir mis un remis, je m'en veux d'un côté mais d'un autre je trouve ça toujours aussi louche.. Désolé je force avec ça, je changerai jamais.. Bref Bisous Je t'aime mon amour dort bien❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton informaticien du dimanche, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='7_samedi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+26 -26
View File
@@ -1,26 +1,26 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 7 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 7 - Samedi 3 Mai</h1>
<p>Coucouuu mon amouuur ! Tellement de choses à te dire alors qu'il est même pas 15h mdrr Déjà je me suis levé et jme suis fais un kiff j'ai fais le super p'tit dej comme chez ma grand mère, c'était moins bon y avait pas la vibe de chez elle mais bon. Après je me suis dis que j'allais m'attaquer à l'ordi de ma mamie justement. Alors je branche tout et là je remarque qu'elle n'a pas donné son alim... J'utilise mon alim les prises on l'air de correspondre. Sauf que, rien ça marche pas, alors je rends l'écran que j'ai volé a mon frère pour le brancher et je remets l'alim sur mon ordi. ET C'EST LE DRAME. Mon ordi ne charge plus, yess.. Je suis à ça de chialer alors je vais chercher une pince et j'essaye de remettre la tige qui n'était plus droite et là y a des étincelles mdrr. Du coup j'abandonne la mission et je dis ça à mon père. Mon père il s'énerve après ma mamie en mode "Ouais elle soule avec ses vieux trucs de merdes qui marchent pas et tout" Moi j'étais à côté en mode "ok". Du coup on va à LDLC pour voir s'ils en ont un. C'est fermé ça ouvre à 14h il est 13h20 là. Du coup on va a boulanger et on est super bien accueilli (c'est faux) par le mec qui dit "Ouais 120 balles ! Vous l'aurez Mardi en livraison ou Mercredi voire Jeudi" bon on à laissé le gars mdrr. On est aller voir les télés à Darty parce que mon père hésite à en acheter une. Et aussi pour passer le temps. Une fois qu'il est 14h on va à LDLC et là tout de suite ça change, le mec est trop sympa. Il nous donne un truc avec genre 9 embouts différents mdrr et on rentre. J'essaye.. Hallelujah !! C'est bon, ça marche ! Et du coup je t'écris là et je pense que je vais me re-regarder tous les Fast & Furious parce que j'sais pas j'ai eu envie d'un coup. Bon je te laisse bisouuuus</p>
<p>Coucouu ça va ? J'ai regardé Fast and Furious 1 j'ai aimé c'est vraiment trop bien. Je me dis qu'en vrai on pourrait les continuer tout les deux quand tu seras revenue ! Après ça j'ai rangé mes habits que j'ai acheté hier et Julien m'a proposé de venir en vocal avec Enzo et Eudes, je suis arrivé. On a fait un golf discord là et après du Gartic Phone c'était marrant. Ah oui et j'ai appris un truc. Adrian veut bien me reparler genre ça le dérangerait pas mais à une condition : que je lui donne 700 balles. Bah non mdrr il est con lui. J'ai raccroché pour aller manger j'ai mangé poulet paprika avec des patates miam. Par contre j'ai des gaz de fou genre j'arrête pas de péter et ça pue la mort en plus à chaque fois c'est infame ça me fait chier. (sans mauvais jeu de mot) Et là il est 21h40 je suis de retour en voc avec eux on va Gartic Phonner mdrr Je te laisse bisouus !</p>
<P>Bonsoiiiir je viens de faire un petit live sympa on a fait du gartic phone c'était cool. Après j'ai coupé parce qu'il était tard et de 00h à 1h30 on a jouer a des jeux discord avec julien et enzo mdrr c'était trop cool. Par contre tu m'as un peu énervé.. A absolument vouloir voir ma coupe alors que tu peux juste attendre, je voulais te faire la surprise mais t'as tout gaché. Je veux voir ta réaction moi pas juste un "Wow" qui ne répresentent que trois pauves lettres à mes yeux.. Mais non madame est trop pressée. En plus j'étais avec mes potes tu me dérangeais un peu. Plus ça va plus je me demande si ce site est une bonne idée..</P>
<hr>
<p>Aujourd'hui c'était particulier, c'était techniquement le dernier jour sans toi même si c'était chiant. Il s'est passé pas mal de trucs relou notemment l'alim de mon ordi. En plus je commence à douter de mon idée. Je suis sûr que tu vas lire tout ça mais qu'au fond tu vas t'en foutre, ou même que tu vas pas lire. Ou que tu ne trouves pas le lien du site. Puis j'écris pour rien là, il est 2h du matin faut que je dorme. Au début j'aimais bien écrire là, c'était un peu mon vide pensée, maintenant je me force un peu pour toi. Alors que tu ne liras surment pas ça. J'espère que les gateaux que je t'ai laissé étaient bon, je sais que t'aimes pas le chocolat mais j'avais rien d'autre.. Bref Bonne nuit ❤️</p>
<h2>Je t'aime ❤️</h2>
<p class="author">A quoi bon.., Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='8_dimanche.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 7 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 7 - Samedi 3 Mai</h1>
<p>Coucouuu mon amouuur ! Tellement de choses à te dire alors qu'il est même pas 15h mdrr Déjà je me suis levé et jme suis fais un kiff j'ai fais le super p'tit dej comme chez ma grand mère, c'était moins bon y avait pas la vibe de chez elle mais bon. Après je me suis dis que j'allais m'attaquer à l'ordi de ma mamie justement. Alors je branche tout et là je remarque qu'elle n'a pas donné son alim... J'utilise mon alim les prises on l'air de correspondre. Sauf que, rien ça marche pas, alors je rends l'écran que j'ai volé a mon frère pour le brancher et je remets l'alim sur mon ordi. ET C'EST LE DRAME. Mon ordi ne charge plus, yess.. Je suis à ça de chialer alors je vais chercher une pince et j'essaye de remettre la tige qui n'était plus droite et là y a des étincelles mdrr. Du coup j'abandonne la mission et je dis ça à mon père. Mon père il s'énerve après ma mamie en mode "Ouais elle soule avec ses vieux trucs de merdes qui marchent pas et tout" Moi j'étais à côté en mode "ok". Du coup on va à LDLC pour voir s'ils en ont un. C'est fermé ça ouvre à 14h il est 13h20 là. Du coup on va a boulanger et on est super bien accueilli (c'est faux) par le mec qui dit "Ouais 120 balles ! Vous l'aurez Mardi en livraison ou Mercredi voire Jeudi" bon on à laissé le gars mdrr. On est aller voir les télés à Darty parce que mon père hésite à en acheter une. Et aussi pour passer le temps. Une fois qu'il est 14h on va à LDLC et là tout de suite ça change, le mec est trop sympa. Il nous donne un truc avec genre 9 embouts différents mdrr et on rentre. J'essaye.. Hallelujah !! C'est bon, ça marche ! Et du coup je t'écris là et je pense que je vais me re-regarder tous les Fast & Furious parce que j'sais pas j'ai eu envie d'un coup. Bon je te laisse bisouuuus</p>
<p>Coucouu ça va ? J'ai regardé Fast and Furious 1 j'ai aimé c'est vraiment trop bien. Je me dis qu'en vrai on pourrait les continuer tout les deux quand tu seras revenue ! Après ça j'ai rangé mes habits que j'ai acheté hier et Julien m'a proposé de venir en vocal avec Enzo et Eudes, je suis arrivé. On a fait un golf discord là et après du Gartic Phone c'était marrant. Ah oui et j'ai appris un truc. Adrian veut bien me reparler genre ça le dérangerait pas mais à une condition : que je lui donne 700 balles. Bah non mdrr il est con lui. J'ai raccroché pour aller manger j'ai mangé poulet paprika avec des patates miam. Par contre j'ai des gaz de fou genre j'arrête pas de péter et ça pue la mort en plus à chaque fois c'est infame ça me fait chier. (sans mauvais jeu de mot) Et là il est 21h40 je suis de retour en voc avec eux on va Gartic Phonner mdrr Je te laisse bisouus !</p>
<P>Bonsoiiiir je viens de faire un petit live sympa on a fait du gartic phone c'était cool. Après j'ai coupé parce qu'il était tard et de 00h à 1h30 on a jouer a des jeux discord avec julien et enzo mdrr c'était trop cool. Par contre tu m'as un peu énervé.. A absolument vouloir voir ma coupe alors que tu peux juste attendre, je voulais te faire la surprise mais t'as tout gaché. Je veux voir ta réaction moi pas juste un "Wow" qui ne répresentent que trois pauves lettres à mes yeux.. Mais non madame est trop pressée. En plus j'étais avec mes potes tu me dérangeais un peu. Plus ça va plus je me demande si ce site est une bonne idée..</P>
<hr>
<p>Aujourd'hui c'était particulier, c'était techniquement le dernier jour sans toi même si c'était chiant. Il s'est passé pas mal de trucs relou notemment l'alim de mon ordi. En plus je commence à douter de mon idée. Je suis sûr que tu vas lire tout ça mais qu'au fond tu vas t'en foutre, ou même que tu vas pas lire. Ou que tu ne trouves pas le lien du site. Puis j'écris pour rien là, il est 2h du matin faut que je dorme. Au début j'aimais bien écrire là, c'était un peu mon vide pensée, maintenant je me force un peu pour toi. Alors que tu ne liras surment pas ça. J'espère que les gateaux que je t'ai laissé étaient bon, je sais que t'aimes pas le chocolat mais j'avais rien d'autre.. Bref Bonne nuit ❤️</p>
<h2>Je t'aime ❤️</h2>
<p class="author">A quoi bon.., Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='8_dimanche.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+21 -21
View File
@@ -1,21 +1,21 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 8 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 8 - Dimanche 4 Mai</h1>
<p>Coucou mon amour, bien dormi ? Je sais que là t'es chez toi je crois (il est 17h30) mais j'ai pas eu de nouvelles, tant pis je dirai que je le mérite un peu. J'écris vite parce que je vais bientot partir pour aller chez ma mère. Aujourd'hui après m'être levé j'ai graille et j'ai fais mes sacs, mon père m'a donné un big sac qui est trop bien on peut mettre plein de trucs dedans. J'y pense un peu là mais je sais que même si on est dimanche et que c'est ton retour je pourrais pas te parler soit parce que tu auras pas le temps ou que tu m'oublira voire que tu ne veuilles pas c'est possible aussi. Même si tu me manques je dirai que j'ai grandi là dessus. Donc ne me parle pas si tu n'en as pas envie... Bisous</p>
<p>Puis aussi je vais arrêter d'écrire ici voilà, ça sert à rien, je ne te donnerai peut etre pas ce papier avec le lien du site, je vais enlever la papier de la boite à gouter quand j'y penserai. Je touche plus à ce site</p>
<h2>Je t'aime ❤️</h2>
<p class="author">, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='7_samedi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 8 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 8 - Dimanche 4 Mai</h1>
<p>Coucou mon amour, bien dormi ? Je sais que là t'es chez toi je crois (il est 17h30) mais j'ai pas eu de nouvelles, tant pis je dirai que je le mérite un peu. J'écris vite parce que je vais bientot partir pour aller chez ma mère. Aujourd'hui après m'être levé j'ai graille et j'ai fais mes sacs, mon père m'a donné un big sac qui est trop bien on peut mettre plein de trucs dedans. J'y pense un peu là mais je sais que même si on est dimanche et que c'est ton retour je pourrais pas te parler soit parce que tu auras pas le temps ou que tu m'oublira voire que tu ne veuilles pas c'est possible aussi. Même si tu me manques je dirai que j'ai grandi là dessus. Donc ne me parle pas si tu n'en as pas envie... Bisous</p>
<p>Puis aussi je vais arrêter d'écrire ici voilà, ça sert à rien, je ne te donnerai peut etre pas ce papier avec le lien du site, je vais enlever la papier de la boite à gouter quand j'y penserai. Je touche plus à ce site</p>
<h2>Je t'aime ❤️</h2>
<p class="author">, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='7_samedi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
</div>
</div>
</body>
</html>
+143 -143
View File
@@ -1,144 +1,144 @@
body {
margin: 0;
padding: 0;
background: linear-gradient(to right, #ffc5ee, #ff80fb);
font-family: 'Segoe UI', sans-serif;
color: #333;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 30px;
border-radius: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
max-width: 600px;
text-align: center;
}
h1 {
font-size: 2em;
color: #e63946;
}
.intro {
font-size: 1.2em;
margin: 20px 0;
}
.nav {
list-style: none;
padding: 0;
}
.nav li {
margin: 10px 0;
}
.nav a {
text-decoration: none;
color: #ff00bf;
font-weight: bold;
transition: color 0.3s;
}
.nav a:hover {
color: #a4007b;
}
.author {
text-align: right;
text-decoration: underline;
font-style: italic; /* optionnel si tu veux une vibe douce */
font-weight: 500;
margin-top: 40px;
color: #934c7e; /* une ptite couleur romantique */
}
h2 {
color: #ff4d6d;
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
animation: glow 2s ease-in-out infinite;
}
@keyframes glow {
0%, 100% {
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
}
50% {
text-shadow: 0 0 20px #ff85a2, 0 0 30px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
padding: 12px 30px;
background-color: #ff4d6d;
color: white;
border: 2px solid #cc2f4d; /* plus foncé que le fond */
border-radius: 30px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
transition: all 0.3s ease-in-out;
}
.glow-button:hover {
background-color: #ff85a2;
border-color: #cc5a7d; /* version plus foncée du hover */
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
transform: scale(1.07);
}
@keyframes pulse {
0%, 100% {
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
}
50% {
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
animation: pulse 2s infinite;
}
.button-grid {
display: flex;
flex-direction: column;
gap: 12px;
max-width: 300px;
margin: 40px auto;
}
.button-grid button {
padding: 12px 20px;
background-color: #ffd3e0;
border: 2px solid #cc2f4d;
border-radius: 25px;
color: #b4003a;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 0 6px #ffc2d4;
}
.button-grid button:hover {
background-color: #ffc2d4;
border-color: #b4003a;
color: #800026;
transform: scale(1.05);
box-shadow: 0 0 12px #ffa3bd;
}
.nav-bar {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 40px;
}
body {
margin: 0;
padding: 0;
background: linear-gradient(to right, #ffc5ee, #ff80fb);
font-family: 'Segoe UI', sans-serif;
color: #333;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 30px;
border-radius: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
max-width: 600px;
text-align: center;
}
h1 {
font-size: 2em;
color: #e63946;
}
.intro {
font-size: 1.2em;
margin: 20px 0;
}
.nav {
list-style: none;
padding: 0;
}
.nav li {
margin: 10px 0;
}
.nav a {
text-decoration: none;
color: #ff00bf;
font-weight: bold;
transition: color 0.3s;
}
.nav a:hover {
color: #a4007b;
}
.author {
text-align: right;
text-decoration: underline;
font-style: italic; /* optionnel si tu veux une vibe douce */
font-weight: 500;
margin-top: 40px;
color: #934c7e; /* une ptite couleur romantique */
}
h2 {
color: #ff4d6d;
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
animation: glow 2s ease-in-out infinite;
}
@keyframes glow {
0%, 100% {
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
}
50% {
text-shadow: 0 0 20px #ff85a2, 0 0 30px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
padding: 12px 30px;
background-color: #ff4d6d;
color: white;
border: 2px solid #cc2f4d; /* plus foncé que le fond */
border-radius: 30px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
transition: all 0.3s ease-in-out;
}
.glow-button:hover {
background-color: #ff85a2;
border-color: #cc5a7d; /* version plus foncée du hover */
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
transform: scale(1.07);
}
@keyframes pulse {
0%, 100% {
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
}
50% {
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
animation: pulse 2s infinite;
}
.button-grid {
display: flex;
flex-direction: column;
gap: 12px;
max-width: 300px;
margin: 40px auto;
}
.button-grid button {
padding: 12px 20px;
background-color: #ffd3e0;
border: 2px solid #cc2f4d;
border-radius: 25px;
color: #b4003a;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 0 6px #ffc2d4;
}
.button-grid button:hover {
background-color: #ffc2d4;
border-color: #b4003a;
color: #800026;
transform: scale(1.05);
box-shadow: 0 0 12px #ffa3bd;
}
.nav-bar {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 40px;
}
+15 -15
View File
@@ -1,15 +1,15 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Pour Clara 💌</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="img/logo.png">
</head>
<body>
<div class="container">
<h1>Rendez vous 16h ici</h1>
<p class="intro"> Coucou mon amoureuse damour que jaime tant❤️. Je sais que tu n'es pas partie mais je tenais à recommencer les journaux que je t'écrivais. Le tout nouveau site arrive à 16h accompagné du journal du jour !</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Pour Clara 💌</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="img/logo.png">
</head>
<body>
<div class="container">
<h1>Rendez vous 16h ici</h1>
<p class="intro"> Coucou mon amoureuse damour que jaime tant❤️. Je sais que tu n'es pas partie mais je tenais à recommencer les journaux que je t'écrivais. Le tout nouveau site arrive à 16h accompagné du journal du jour !</p>
</div>
</body>
</html>
+31 -31
View File
@@ -1,31 +1,31 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 1 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 1 - Dimanche 27 Avril</h1>
<p>Là cest dimanche, tu me manques déjà beaucoup… Est-ce que cest parce que cest le début ? Ou bien mon manque est bel est bien justifié. Là il est 11h30 j’écoute Shaka Ponk en t’écrivant ses mots Lets baaaanng bang baaaang (pardon jsuis a fond) Je taime trop vraiment. Je tai envoyé deux images que mon père ma envoyé, une de moi avec Mathieu et Fabien et mon père où est en mode <a href="https://www.youtube.com/watch?v=_VfwZSygTeI&t=9s">WAAAAHH</a> (ptddr cest Waluigi) et la deuxième un meme que mon père ma envoyé qui est plutot drôle mais tu les as pas vus donc jimagine que tu dors sur la route (même si je pense que cest pas a 3h de route) ou que tu as déjà commencer. </p>
<p><em>Je viens juste de réaliser mais ce que je suis en train de te faire cest ton rêve, cest juste moi qui raconte ma vie et tu adores ça🤭.</em></p>
<p>Je te fais mon programme de la journée : Tout dabord je vais aller manger cest un bon début, pourquoi pas me laver ça serait une bonne option mdrr ensuite je pense que je vais ranger tout mon bordel dans ma chambre, ma mère me ramènera ensuite chez mon père, je rangerais tout et je retrouverai ROBEEERTT !!🤭Après jirai manger chez ma mamie je lui mettrai sa Wii ça va être drôle je pense, par contre jy reste jusqu’à mardi et ça membête un peu… Je voulais déprimer tout seul mdrr</p>
<p>Je pense que je vais laisser le document ouvert sur mon PC et des fois je viendrai t’écrire un peu. En plus j'ai mis une note sur Insta en mode "J'espère qu'elle lira tout" ahah c'est trop drôle tout le monde veut savoir pourquoi</p>
<p>Re coucouuu là il est 16h j'ai pas encore fais mon gouter mais ça ne saurait tarder ! Je suis allé voir ma mère on a jouer à un jeu rigolo avec les coques de pistaches en mode "si je la mets tu fais ça" c'était marrant mais personne n'a réussi de lancer... Après on a manger vite fait en regardant Le fabuleux destin d'Amélie Poulain je l'avais déjà vu et ça m'a fait plaisir de le revoir. Pendant le film m'a mère a voulu me faire une coupe de fou, t'as du voir les buddies même en ayant retiré les élastiques mes cheveux volaient mdrr j'en pouvais plus. Après ça ma mère m'a dit de ranger ma chambre car je vais bientôt partir, mais évidemment je me suis laisser m'égarer en fait j'ai regarder tous les images de plannings de live que Matreox avait fait et j'ai tout jugé mdrr t'aurais trop kiffé m'entendre juger je pense. Là je pense que je vais essayer de faire mon planning de lives pour cette semaine du moins un brouillon, je vais live tout les jours a partir de mardi, j'espère que tu viendras au moins pour faire un petit coucou. Je t'aime mon amour, j'espère que ça se passe bien de ton côté et que tu t'amuses. Bisouuus !❤️</p>
<p>Je pense beaucoup à toi c'est pas la première fois où je me surprends à regarder le vide tout en pensant à toi quand je m'en rends compte j'ai les yeux lourds, la boule au ventre et le coeur qui bat vite, presque en train de pleurer. Ça fait qu'un jour, c'est déjà trop long. Je passe souvent dans ma galerie pour regarder des photos de nous, on est trop mignons tous les deux. J'ai encore rien mis dans mon sac mais tant de "je t'aime" à t'écrire... Je pourrais faire ça toute la journée. Ça y est je pleure, j'ai trop regardé nos photos. Je te laisse je dois ranger ma chambre❤️</p>
<p>Coucouuu jai rangé ma chambre et mes affaires et jai fais le trajet vers chez mon père je suis vite aller dans ma chambre pour voir Robert, il était la il mattendait, je lui ai fait un gros gros calin et je suis allé me doucher. Tas déjà pleuré sous la douche toi ? Cest trop bizarre, ça mest arrivé je pensais trop à toi je crois. Jai refais mes sacs pour chez ma mamie, la je suis sur le trajet, je te dirai quand jy serai. Je taime mon amour❤️</p>
<p>Coucouuu, oh j'suis content tu m'as envoyé des messages🤭et j'ai mangé c'était bon ça va. Là je suis en voc avec Julien, il est trop happy de me montrer ce qu'il a eu sur Minecraft. J'espère qu'il va me remonter le moral. Il a fait vla les trucs vraiment, je vais rajouter des mods sinon on va s'ennuyer il a tout dans le jeu mdrr. Bon je te laisse mon amour, en plus y a peut etre Eudes et Enzo qui vont rejoindre. Bisouuus !❤️</p>
<p>Coucouu, tu dors alors je vais écrire pas trop fort. Là y a une ambiance trop chill j'adore, même s'il manque toi... Tout à l'heure j'étais en appel avec Julien, Enzo et Eudes Je te l'ai dis en plus et Eudes m'à dit que Simon à dit cette phrase "En vrai si Adrian vient pas avec nous au Pal tu pourras dire à Noah de venir" AAAAHHH Je te jure j'suis trop heureux, ça veut dire que ça va mieux avec Simon et que je vais pouvoir partir en vacances avec toi et avec mes potes, trop bien ! J'ai du bouger parce que j'étais dans la chambre de ma mamie et quand je suis revenu sur mon ordi y avait plus personne... Pas grave, alors j'ai commencé l'article d'Adrian, je te jure que j'adore faire ça genre vraiment si un jour t'as la flemme j'suis là hein (stp) Du coup là j'ai fini son article. Je suis posé sur la table à manger sur un siège de bureau avec du Shaka Ponk à fond I dont give a They dont give a We dont give a fuuuuck !! - mon frère regarde un film sur la télé et je vais continuer d'écrire mon article je pense. Ou alors je vais regarder youtube parce que je suis un peu fatigué je ferai ça demain. Putain je crois que j'ai un putain de moustique qui me tourne autour, pitié sauve moi mon amour... J'ai trop hâte de dormir parce que demain y a petit dej et le petit dej chez ma mamie c'est trop trop trop booon, donc en fait je vais dodo devant youtube, j'ai ramener Robert et Monsieur Plouf et le pull pour dormir dedans mais pas le plaid parce que le chien de ma mamie à le même plaid et elle les manges donc je veux pas qu'elle mange mon plaid.</p>
<hr>
<p>Bon je pense que je te reparlerai pas de la journée (en plus il est minuit passé là (00h20) du coup je vais te faire un débrief ! Aujourd'hui c'était dur.. J'ai pu te parler ce matin... un peu... Je pense vraiment que ce moment était le meilleur de la semaine. J'espère que ta lecture te plait jusqu'ici, je sais pas encore si je vais te le faire lire quand je serai là ou pas.. J'ai même hésiter à te faire lire un jour par jour, genre dimanche prochain tu lis que cette journée là. Je sais pas trop... Je me suis beaucoup ennuyer aujourd'hui et en plus mon père et ma mamie m'ont dit que j'avais l'air perdu toute la soirée. Je leur ai pas dis que tu me manquais, je pense que si ma mamie me demande demain je lui dirai et mon père je lui dirai sans doute mardi ou mercredi, aujourd'hui c'était pas le jour, je pouvais pas en parler sans pleurer Je l'ai dis a Julien j'ai chialer... en plus a un moment je sortais enfin de ma chambre parce que je faisais que de pleurer mon père a parlé de toi je sais plus pourquoi et j'ai couru dans ma chambre pour re pleurer. Mdrr je fais pitié je t'ai fais un word ou je te dis toutes les deux ligne que je chiale... Bonne nuit mon amour❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton amoureux d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='2_lundi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 1 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 1 - Dimanche 27 Avril</h1>
<p>Là cest dimanche, tu me manques déjà beaucoup… Est-ce que cest parce que cest le début ? Ou bien mon manque est bel est bien justifié. Là il est 11h30 j’écoute Shaka Ponk en t’écrivant ses mots Lets baaaanng bang baaaang (pardon jsuis a fond) Je taime trop vraiment. Je tai envoyé deux images que mon père ma envoyé, une de moi avec Mathieu et Fabien et mon père où est en mode <a href="https://www.youtube.com/watch?v=_VfwZSygTeI&t=9s">WAAAAHH</a> (ptddr cest Waluigi) et la deuxième un meme que mon père ma envoyé qui est plutot drôle mais tu les as pas vus donc jimagine que tu dors sur la route (même si je pense que cest pas a 3h de route) ou que tu as déjà commencer. </p>
<p><em>Je viens juste de réaliser mais ce que je suis en train de te faire cest ton rêve, cest juste moi qui raconte ma vie et tu adores ça🤭.</em></p>
<p>Je te fais mon programme de la journée : Tout dabord je vais aller manger cest un bon début, pourquoi pas me laver ça serait une bonne option mdrr ensuite je pense que je vais ranger tout mon bordel dans ma chambre, ma mère me ramènera ensuite chez mon père, je rangerais tout et je retrouverai ROBEEERTT !!🤭Après jirai manger chez ma mamie je lui mettrai sa Wii ça va être drôle je pense, par contre jy reste jusqu’à mardi et ça membête un peu… Je voulais déprimer tout seul mdrr</p>
<p>Je pense que je vais laisser le document ouvert sur mon PC et des fois je viendrai t’écrire un peu. En plus j'ai mis une note sur Insta en mode "J'espère qu'elle lira tout" ahah c'est trop drôle tout le monde veut savoir pourquoi</p>
<p>Re coucouuu là il est 16h j'ai pas encore fais mon gouter mais ça ne saurait tarder ! Je suis allé voir ma mère on a jouer à un jeu rigolo avec les coques de pistaches en mode "si je la mets tu fais ça" c'était marrant mais personne n'a réussi de lancer... Après on a manger vite fait en regardant Le fabuleux destin d'Amélie Poulain je l'avais déjà vu et ça m'a fait plaisir de le revoir. Pendant le film m'a mère a voulu me faire une coupe de fou, t'as du voir les buddies même en ayant retiré les élastiques mes cheveux volaient mdrr j'en pouvais plus. Après ça ma mère m'a dit de ranger ma chambre car je vais bientôt partir, mais évidemment je me suis laisser m'égarer en fait j'ai regarder tous les images de plannings de live que Matreox avait fait et j'ai tout jugé mdrr t'aurais trop kiffé m'entendre juger je pense. Là je pense que je vais essayer de faire mon planning de lives pour cette semaine du moins un brouillon, je vais live tout les jours a partir de mardi, j'espère que tu viendras au moins pour faire un petit coucou. Je t'aime mon amour, j'espère que ça se passe bien de ton côté et que tu t'amuses. Bisouuus !❤️</p>
<p>Je pense beaucoup à toi c'est pas la première fois où je me surprends à regarder le vide tout en pensant à toi quand je m'en rends compte j'ai les yeux lourds, la boule au ventre et le coeur qui bat vite, presque en train de pleurer. Ça fait qu'un jour, c'est déjà trop long. Je passe souvent dans ma galerie pour regarder des photos de nous, on est trop mignons tous les deux. J'ai encore rien mis dans mon sac mais tant de "je t'aime" à t'écrire... Je pourrais faire ça toute la journée. Ça y est je pleure, j'ai trop regardé nos photos. Je te laisse je dois ranger ma chambre❤️</p>
<p>Coucouuu jai rangé ma chambre et mes affaires et jai fais le trajet vers chez mon père je suis vite aller dans ma chambre pour voir Robert, il était la il mattendait, je lui ai fait un gros gros calin et je suis allé me doucher. Tas déjà pleuré sous la douche toi ? Cest trop bizarre, ça mest arrivé je pensais trop à toi je crois. Jai refais mes sacs pour chez ma mamie, la je suis sur le trajet, je te dirai quand jy serai. Je taime mon amour❤️</p>
<p>Coucouuu, oh j'suis content tu m'as envoyé des messages🤭et j'ai mangé c'était bon ça va. Là je suis en voc avec Julien, il est trop happy de me montrer ce qu'il a eu sur Minecraft. J'espère qu'il va me remonter le moral. Il a fait vla les trucs vraiment, je vais rajouter des mods sinon on va s'ennuyer il a tout dans le jeu mdrr. Bon je te laisse mon amour, en plus y a peut etre Eudes et Enzo qui vont rejoindre. Bisouuus !❤️</p>
<p>Coucouu, tu dors alors je vais écrire pas trop fort. Là y a une ambiance trop chill j'adore, même s'il manque toi... Tout à l'heure j'étais en appel avec Julien, Enzo et Eudes Je te l'ai dis en plus et Eudes m'à dit que Simon à dit cette phrase "En vrai si Adrian vient pas avec nous au Pal tu pourras dire à Noah de venir" AAAAHHH Je te jure j'suis trop heureux, ça veut dire que ça va mieux avec Simon et que je vais pouvoir partir en vacances avec toi et avec mes potes, trop bien ! J'ai du bouger parce que j'étais dans la chambre de ma mamie et quand je suis revenu sur mon ordi y avait plus personne... Pas grave, alors j'ai commencé l'article d'Adrian, je te jure que j'adore faire ça genre vraiment si un jour t'as la flemme j'suis là hein (stp) Du coup là j'ai fini son article. Je suis posé sur la table à manger sur un siège de bureau avec du Shaka Ponk à fond I dont give a They dont give a We dont give a fuuuuck !! - mon frère regarde un film sur la télé et je vais continuer d'écrire mon article je pense. Ou alors je vais regarder youtube parce que je suis un peu fatigué je ferai ça demain. Putain je crois que j'ai un putain de moustique qui me tourne autour, pitié sauve moi mon amour... J'ai trop hâte de dormir parce que demain y a petit dej et le petit dej chez ma mamie c'est trop trop trop booon, donc en fait je vais dodo devant youtube, j'ai ramener Robert et Monsieur Plouf et le pull pour dormir dedans mais pas le plaid parce que le chien de ma mamie à le même plaid et elle les manges donc je veux pas qu'elle mange mon plaid.</p>
<hr>
<p>Bon je pense que je te reparlerai pas de la journée (en plus il est minuit passé là (00h20) du coup je vais te faire un débrief ! Aujourd'hui c'était dur.. J'ai pu te parler ce matin... un peu... Je pense vraiment que ce moment était le meilleur de la semaine. J'espère que ta lecture te plait jusqu'ici, je sais pas encore si je vais te le faire lire quand je serai là ou pas.. J'ai même hésiter à te faire lire un jour par jour, genre dimanche prochain tu lis que cette journée là. Je sais pas trop... Je me suis beaucoup ennuyer aujourd'hui et en plus mon père et ma mamie m'ont dit que j'avais l'air perdu toute la soirée. Je leur ai pas dis que tu me manquais, je pense que si ma mamie me demande demain je lui dirai et mon père je lui dirai sans doute mardi ou mercredi, aujourd'hui c'était pas le jour, je pouvais pas en parler sans pleurer Je l'ai dis a Julien j'ai chialer... en plus a un moment je sortais enfin de ma chambre parce que je faisais que de pleurer mon père a parlé de toi je sais plus pourquoi et j'ai couru dans ma chambre pour re pleurer. Mdrr je fais pitié je t'ai fais un word ou je te dis toutes les deux ligne que je chiale... Bonne nuit mon amour❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton amoureux d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='2_lundi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
File diff suppressed because one or more lines are too long
+22 -22
View File
@@ -1,22 +1,22 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 3 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 3 - Mardi 29 Avril</h1>
<p>Coucouu, alors aujourd'hui était une journée bien plus chargée que prévu du coup j'ai pas trop pu prendre la parole ici... Là il est 23h30 et il s'est passé beaucoup de trucs. Du coup je vais tout te raconter mais rapidement parce que j'ai un peu (beaucoup) envie de faire de l'ASMR.. Désolé. Donc j'ai fais mon petit dej trop bienn dehors comme hier ensuite on a tout rangé et je me suis remis sur ma Wii qui voulait pas ajouter les nouveaux jeux à la liste je cherche mais je trouve pas. En même temps ma mamie me parle d'un de ses vieil ordi (très vieux hein de 2007) qui marchait très bien mais qui est juste bloqué. Bon pas grave je lance un transfert sur la Wii et en attendant je m'occupe de cet ordi. En l'allumant l'écran n'affiche rien, j'en conclu que l'écran est HS alors je le branche à la télé et BOUM y a un truc. Alors c'est rempli de "!!" et entre ces "!!" il y a du texte mais écrit bizarrement, on aurait dit qu'il manquait des lettre ou que certaines lettre n'étaient pas les bonnes. Je me décide de réinstaller un Windows dessus tant qu'a faire j'en mets un vieux pour pas que l'ordi lag trop je choisi un Windows 7, qui n'est certes plus assuré par les mises à jour mais qui fera bien le taff. Et là ma mamie me dit que Yannick (mon tonton) avait déjà essayé de réparer l'ordi mais n'avait pas réussi donc il a démonté le disque dur pour récupérer les photos et askip il a gardé le disque... Je démonte l'ordi et effectivement il manque le disque dur.. Merde ! Je décide de tout démonter afin de vérifier que l'ordi est entier et que mon tonton ne se soit pas servit dedans (il aurait pu le faire). Et là je vois un emplacement vide.. De la RAM en plus ? Non l'emplacement est trop petit.. Je demande à ChatGPT et d'après lui c'est un emplacement IDE. Pour l'info les disques durs de nos jours sont soit des SSD (les très rapides) soit des HDD. Aujourd'hui on connecte les HDD avec des prises SATA (comme on connecterait un téléphone en Type-C) mais avant il éxistait une antiquité, la prise IDE avec des nappes. C'était la même vitesse qu'une disquette. Bref je m'égare. En tout cas il manque rien a part le disque dûr. Ma mamie m'a donc confié l'ordi pour que je m'en occupe dans la semaine (je ferai ça Samedi ou Vendredi) Entre temps le disque dur de la Wii avait tout fini je lance et là rien... Je fouille les paramètre de l'appli Wii où y a tous mes jeux, je décoche une option et ça y est ! Ça marche !! Et là on joue a Wii Sport Resort pendant que je faisais des steaks (oui pour encore manger des burgers mdrr) et c'était marrant, genre on faisait le bowling chacun son tour, c'était assez fun. On mange dehors il fait beau il fait bon c'est cool. Je vais donc à la douche (j'ai fais ton buddies🤭) Et juste après paf on rentre pour chez mon père. Sur le chemin j'ai un peu dormi, mais vite fait j'avais juste les yeux fermés et le vent sur la tête, trop confort. On arrive je mon mes affaires enfin heureux de ENFIN retrouver ma chambre putain (et aussi de retrouver ta boîte à goûter) ma mamie boit le café vite fait puis ils s'en vont. Avec mon père on règle un problème avec le serveur puis on fait un petit apéro en finissant un spéctacle qu'on avait commencé et ensuite on va voir Pierre Emmanuel Barré. Oh j'étais trop content tu m'as appelé. Son spectacle était drôle mais je t'en dirai plus en voc j'ai un peu la flemme mon amour. On est rentré on a fait burger king mdrr j'ai branché mon ordi et je t'écris ceci avant de te parler pas messages. Là tu m'en envoies j'suis trop heureux</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton homme, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='2_lundi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 3 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 3 - Mardi 29 Avril</h1>
<p>Coucouu, alors aujourd'hui était une journée bien plus chargée que prévu du coup j'ai pas trop pu prendre la parole ici... Là il est 23h30 et il s'est passé beaucoup de trucs. Du coup je vais tout te raconter mais rapidement parce que j'ai un peu (beaucoup) envie de faire de l'ASMR.. Désolé. Donc j'ai fais mon petit dej trop bienn dehors comme hier ensuite on a tout rangé et je me suis remis sur ma Wii qui voulait pas ajouter les nouveaux jeux à la liste je cherche mais je trouve pas. En même temps ma mamie me parle d'un de ses vieil ordi (très vieux hein de 2007) qui marchait très bien mais qui est juste bloqué. Bon pas grave je lance un transfert sur la Wii et en attendant je m'occupe de cet ordi. En l'allumant l'écran n'affiche rien, j'en conclu que l'écran est HS alors je le branche à la télé et BOUM y a un truc. Alors c'est rempli de "!!" et entre ces "!!" il y a du texte mais écrit bizarrement, on aurait dit qu'il manquait des lettre ou que certaines lettre n'étaient pas les bonnes. Je me décide de réinstaller un Windows dessus tant qu'a faire j'en mets un vieux pour pas que l'ordi lag trop je choisi un Windows 7, qui n'est certes plus assuré par les mises à jour mais qui fera bien le taff. Et là ma mamie me dit que Yannick (mon tonton) avait déjà essayé de réparer l'ordi mais n'avait pas réussi donc il a démonté le disque dur pour récupérer les photos et askip il a gardé le disque... Je démonte l'ordi et effectivement il manque le disque dur.. Merde ! Je décide de tout démonter afin de vérifier que l'ordi est entier et que mon tonton ne se soit pas servit dedans (il aurait pu le faire). Et là je vois un emplacement vide.. De la RAM en plus ? Non l'emplacement est trop petit.. Je demande à ChatGPT et d'après lui c'est un emplacement IDE. Pour l'info les disques durs de nos jours sont soit des SSD (les très rapides) soit des HDD. Aujourd'hui on connecte les HDD avec des prises SATA (comme on connecterait un téléphone en Type-C) mais avant il éxistait une antiquité, la prise IDE avec des nappes. C'était la même vitesse qu'une disquette. Bref je m'égare. En tout cas il manque rien a part le disque dûr. Ma mamie m'a donc confié l'ordi pour que je m'en occupe dans la semaine (je ferai ça Samedi ou Vendredi) Entre temps le disque dur de la Wii avait tout fini je lance et là rien... Je fouille les paramètre de l'appli Wii où y a tous mes jeux, je décoche une option et ça y est ! Ça marche !! Et là on joue a Wii Sport Resort pendant que je faisais des steaks (oui pour encore manger des burgers mdrr) et c'était marrant, genre on faisait le bowling chacun son tour, c'était assez fun. On mange dehors il fait beau il fait bon c'est cool. Je vais donc à la douche (j'ai fais ton buddies🤭) Et juste après paf on rentre pour chez mon père. Sur le chemin j'ai un peu dormi, mais vite fait j'avais juste les yeux fermés et le vent sur la tête, trop confort. On arrive je mon mes affaires enfin heureux de ENFIN retrouver ma chambre putain (et aussi de retrouver ta boîte à goûter) ma mamie boit le café vite fait puis ils s'en vont. Avec mon père on règle un problème avec le serveur puis on fait un petit apéro en finissant un spéctacle qu'on avait commencé et ensuite on va voir Pierre Emmanuel Barré. Oh j'étais trop content tu m'as appelé. Son spectacle était drôle mais je t'en dirai plus en voc j'ai un peu la flemme mon amour. On est rentré on a fait burger king mdrr j'ai branché mon ordi et je t'écris ceci avant de te parler pas messages. Là tu m'en envoies j'suis trop heureux</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton homme, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='2_lundi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+29 -29
View File
@@ -1,29 +1,29 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 4 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 4 - Mercredi 30 Avril</h1>
<p>Coucouuu ça va ? Bien dormi ? Moi oui mais il me manquait ma femme.. Je me suis levé grave tôt il était 9h, là il est 10h et je suis en pleine écriture de mon article, je charbone pour pouvoir le rendre vers midi je pense. J'ai fais a peu près 1000 mots là et j'ai pas fini encore. Avant de commencer à écrire j'ai checké vite fait un peu tout, le pdf et le site voir si Adrian ne s'était pas planté et il a oublié les mots en gras sur le site... Du coup je te le dis et là tu me dis la pire chose que tu pourrais me dire "Dis lui de le mettre" WAAAAA MAIS JE VAIS ME FAIRE SOULEVER. Bon tu sais que je ferai tout pour toi hein je vais surmonter ma peur et je vais lui dire vu que t'es occupée... Là je vais lui envoyer un message, changer de pentalon (je me serai chié dessus) prier et retourner écrire mon article. Au fait tant que j'y pense Vendredi je me fais couper les cheveux haha. Bon je te laisse je vais écrire mon testament mdrr. Bisouus !</p>
<p>Coucouu euh je t'écrire vraiment une minute après ce qu'il y a au dessus mdrr mais j'ai un soucis mon Spotify ne veux plus que j'écoute l'album Toxicity de System genre je lance l'album et ça me met une seconde de chaque son jusqu'au dernier et ça coupe, je vais mourir vraiment mdrr bon aller bisous ! Même mon père ! Est dans le coup...</p>
<img src="../img/screen_cheh_papa.png" alt="Screen de la conversation avec mon père" class="screenshot">
<p>Coucouuu ça va ? Il est 14h bientôt j'ai bien mangé, mon père a fait des pâtes et on y a mit du gruyère sauf que je sens une odeur bizarre, un fois à table. Je dis à mon père "le gruyère est pas périmé ? Mon père dit non et puis je regarde attentivement. Mdrr y avait des taches bleues dans le gruyère.. Du coup on a jetté et on s'est reservi à contre coeur... Et j'ai fini mon article je vais le mettre sur le pdf. Il fait 1600 mots donc ça va en vrai, comme celui à Célia si je dis pas de bêtises. Bref je m'y mets parce que je dois prendre une douche après ça pour aller au cinéma, je vais voir Thunderbolts* Bref Bisouuu mon amouuuur (j'ai vu que tu as fais des buddies j'suis content)</p>
<p>Coucouuu Il est 16h45 là je vais bien de fou ! J'ai tout fini sur mon article j'ai mis en page et j'ai planifié mon article. Adrian n'a toujours pas vu mon message alors qu'il a posté une note sur Insta y a 2h... On te voit en fait. Après ça j'ai pris une douche et mon frère est arrivé avec ma mamie et mon père, je les ait laisser discuter pour envoyer le message sur le groupe du Gay-Lu Times. J'ai géré de fouuu. Je t'aime mon amour, j'espère que tu es fière de moi même si tu es loin de moi... </p>
<p>Coucouu mon amour ! Je suis si bouleversé, tu m'as appelé. Mais avant je suis allé au cinéma pour voir Thunderbolts* Le film est... Je sais pas, bof je dirai. Ni nul ni bien en fait.. Après ça je suis allé au Quick et on a eu un burger gratuit, truc de fou ! Mais bon ça tu le sais déjà du coup j'ai moins de trucs à te dire ce soir... Ah si quand on rentrait au feu rouge ou y a le Legrand on avait la music A.N.U.S. de Ultra Vomit et au même moment y a un vieux aigri qui s'est arrêté à côté de nous. Mon père à monté le son progressivement en faisant exprès mdrr c'était très drole.</p>
<hr>
<p>Je t'aime mon amour, tu me manques trop je pensais que j'avais passé le cap mais j'ai pleuré quand tu as raccroché tout à l'heure. Pour te l'avouer j'avais déjà commencer avant que tu quittes (un peu comme quand on fait de l'asmr tout les deux en appel). J'aimerai trop te serrer dans mes bras, enfin ressentir la chaleur de ton corps contre le miens, goûter à tes belles et douces lèvres, désirer ton regard et observer les étoiles à travers tes yeux, caresser des belles joues et jouer avec tes soyeux cheveux. Je m'égard là.. Bref, bonne nuit mon amour je t'aime tellement</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ta crotte d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='3_mardi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 4 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 4 - Mercredi 30 Avril</h1>
<p>Coucouuu ça va ? Bien dormi ? Moi oui mais il me manquait ma femme.. Je me suis levé grave tôt il était 9h, là il est 10h et je suis en pleine écriture de mon article, je charbone pour pouvoir le rendre vers midi je pense. J'ai fais a peu près 1000 mots là et j'ai pas fini encore. Avant de commencer à écrire j'ai checké vite fait un peu tout, le pdf et le site voir si Adrian ne s'était pas planté et il a oublié les mots en gras sur le site... Du coup je te le dis et là tu me dis la pire chose que tu pourrais me dire "Dis lui de le mettre" WAAAAA MAIS JE VAIS ME FAIRE SOULEVER. Bon tu sais que je ferai tout pour toi hein je vais surmonter ma peur et je vais lui dire vu que t'es occupée... Là je vais lui envoyer un message, changer de pentalon (je me serai chié dessus) prier et retourner écrire mon article. Au fait tant que j'y pense Vendredi je me fais couper les cheveux haha. Bon je te laisse je vais écrire mon testament mdrr. Bisouus !</p>
<p>Coucouu euh je t'écrire vraiment une minute après ce qu'il y a au dessus mdrr mais j'ai un soucis mon Spotify ne veux plus que j'écoute l'album Toxicity de System genre je lance l'album et ça me met une seconde de chaque son jusqu'au dernier et ça coupe, je vais mourir vraiment mdrr bon aller bisous ! Même mon père ! Est dans le coup...</p>
<img src="../img/screen_cheh_papa.png" alt="Screen de la conversation avec mon père" class="screenshot">
<p>Coucouuu ça va ? Il est 14h bientôt j'ai bien mangé, mon père a fait des pâtes et on y a mit du gruyère sauf que je sens une odeur bizarre, un fois à table. Je dis à mon père "le gruyère est pas périmé ? Mon père dit non et puis je regarde attentivement. Mdrr y avait des taches bleues dans le gruyère.. Du coup on a jetté et on s'est reservi à contre coeur... Et j'ai fini mon article je vais le mettre sur le pdf. Il fait 1600 mots donc ça va en vrai, comme celui à Célia si je dis pas de bêtises. Bref je m'y mets parce que je dois prendre une douche après ça pour aller au cinéma, je vais voir Thunderbolts* Bref Bisouuu mon amouuuur (j'ai vu que tu as fais des buddies j'suis content)</p>
<p>Coucouuu Il est 16h45 là je vais bien de fou ! J'ai tout fini sur mon article j'ai mis en page et j'ai planifié mon article. Adrian n'a toujours pas vu mon message alors qu'il a posté une note sur Insta y a 2h... On te voit en fait. Après ça j'ai pris une douche et mon frère est arrivé avec ma mamie et mon père, je les ait laisser discuter pour envoyer le message sur le groupe du Gay-Lu Times. J'ai géré de fouuu. Je t'aime mon amour, j'espère que tu es fière de moi même si tu es loin de moi... </p>
<p>Coucouu mon amour ! Je suis si bouleversé, tu m'as appelé. Mais avant je suis allé au cinéma pour voir Thunderbolts* Le film est... Je sais pas, bof je dirai. Ni nul ni bien en fait.. Après ça je suis allé au Quick et on a eu un burger gratuit, truc de fou ! Mais bon ça tu le sais déjà du coup j'ai moins de trucs à te dire ce soir... Ah si quand on rentrait au feu rouge ou y a le Legrand on avait la music A.N.U.S. de Ultra Vomit et au même moment y a un vieux aigri qui s'est arrêté à côté de nous. Mon père à monté le son progressivement en faisant exprès mdrr c'était très drole.</p>
<hr>
<p>Je t'aime mon amour, tu me manques trop je pensais que j'avais passé le cap mais j'ai pleuré quand tu as raccroché tout à l'heure. Pour te l'avouer j'avais déjà commencer avant que tu quittes (un peu comme quand on fait de l'asmr tout les deux en appel). J'aimerai trop te serrer dans mes bras, enfin ressentir la chaleur de ton corps contre le miens, goûter à tes belles et douces lèvres, désirer ton regard et observer les étoiles à travers tes yeux, caresser des belles joues et jouer avec tes soyeux cheveux. Je m'égard là.. Bref, bonne nuit mon amour je t'aime tellement</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ta crotte d'amour, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='3_mardi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+29 -29
View File
@@ -1,29 +1,29 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 5 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 5 - Jeudi 1er Mai</h1>
<p>Coucouu mon amour alors là il est 3h du matin, juste pour te dire que je vais aller me coucher mais je venais de faire le site que tu regardes là. Hehe j'suis trop fier de ce que j'ai fais c'est tout kiki, comme toi ❤️</p>
<p>Coucouuu ça va mon amour ? ❤️ J'ai bien dormi perso, je me suis levé à midi mais j'avais fais un rêve trop bizarre je me souviens pas de tout, mais je sais qu'à un moment mon frère fouille ce site là. Et à la fin je vais dans le garage de mes grands parents pour prendre une bouteille de Pepsi sauf qu'elle est chaude de fou vu qu'elle est restée au soleil, du coup je la mets au congélateur pour la refroidir un peu. Mais je remarque que depuis le début j'avais les yeux fermés et flous, tu sais comme quand tu viens de te réveiller. Du coup je cours en montant à l'étage pour me débarbouiller le visage. Et là je monte et c'est l'étage de ma maison à Feytiat, et en fait je cours parce qu'il y a quelqu'un derière moi qui veut me tuer, je sais pas qui c'est. J'arrive dans la salle de bain et je cherche un gant, j'en trouve pas du coup je fais ça avec une serviette et là le mec qui veut me tuer s'approche et me rend la bouteille de pepsi. Wesh.. Et là je me réveille... Bizarre. Bon après j'ai fais un Fifa pendant que mon père faisait à manger - c'est à dire des frites - et après ça j'ai mangé le burger en trop d'hier. On a regardé le Hot Ones avec Alain Chabat c'est trop bien. Et là il est 14h33 je sais pas ce que je vais faire, je vais surement brancher mon volant pour jouer à un jeu, pourquoi pas à BeamNG Drive. Bref je te laisse mon amour. Bisouuus</p>
<p>Je suis vraiment premier degrès en train de péter un plomb, j'en ai marre je sais pas quoi faire. J'ai littéralement fais tout ce que je pouvais faire. J'ai passé 2h sur un jeu de merde qui me plaisait pas juste parce que je savais pas quoi faire, bah j'ai vite abandonné. Et là je suis à deux doigts de casser mon écran ou de je jeter par la fenêtre, voire même de me jeter par la fenêtre. Je suis en train de devenir fou j'en peux plus. Reviens s'il te plait, je m'ennuie sans toi...</p>
<p>Euh j'allais t'écrire là mais je vois ça ⬇️ Il faut savoir que l'IA du logiciel de code prédis ce que je vais écrire. Bon là il essaye de prédire des truc nul mais wesh pourquoi il sait pour Feytiat. C'est mentionné nulle part ailleurs. Trop bizarre</p>
<img src="../img/ia.png" alt="IA qui prédit Feytiat" class="ia" width="90%">
<p>MDRRR Et là il m'a prédis la ligne pour mettre l'image en mettant le titre "IA qui prédit Feytiat" j'vais cabler</p>
<p>Bon du coup je voulais te dire. Là il est 3h du mat oui je triche on est vendredi techniquement mdrr. Je m'ennuyais trop à jouer à GT4 que du coup j'ai fais du casque et pour la vanne j'ai testé les jeux 18+. Mdrr comment c'est claqué au sol c'est juste pas pratique en fait je vois pas comment tu peux faire l'asmr en vrai en jouant à ça t'as constament les mains prises. Bref. Après ça je suis allé faire le gouter et je me suis dis que j'allais live à 20h J'ai rejoins Julien et Enzo en vocal. Enzo est parti quand j'ai lancé le live parce qu'il devait manger. Pas grave. J'ai d'abord fais du bedwars comme à l'ancienne mais mon ordi buggait trop c'est une dinguerie du coup j'ai changé pour Arcade Paradise (j'avais déjà commencé le jeu en live) Après ça Julien m'a rappelé l'existance du jeu The Exit 8 en fait ça fait un an je pense que je veux faire une vidéo dessus mais que j'y pensse pas. Du coup j'ai fais un live dessus et le concept est trop bien, y aura un montage sur ma chaine de ce gameplay. Ensuite j'ai coupé le live il était 23h30 mdrr et avec julien on a trainé sur les activités discord on a trouvé un Uno trop bien et on a joué au golf après. J'ai dis que je voulais dormir et il a lancé le tableau blanc commun mdrr. Evidemment on a fait des ref à 39-45 tu connais mdrr et après je t'écris et je vais dodo.</p>
<hr>
<p>Tu me manques trop vraiment. Aujourd'hui j'ai pas répondu à tes messages Insta et tu vas peut être trouver ça bizarre et me prendre pour un fou mais hier j'ai eu peur. Hier t'as envoyé des emojis que t'envoies jamais mais genre vraiment jamais. Ils faisaient quoi dans les récents alors ? Surtout celui qui regarde à travers ses yeux là. Tu l'envoie jamais et tu l'as envoyé à quelqu'un, je vois pas à qui ça peut être à part un amant, en mode "chut ça reste entre nous on lui dis pas"... Désolé je continue avec ça tu sais que c'est mon pire cauchemar.. Et en vrai j'ai aucune raison de pas te répondre. Je me doute trop de ce genre de choses. Mais comprends moi t'es loin si jamais tu en aurais l'envie tu aurais pu me tromper à cette distance je n'en saurai rien.. J'ai un peu déprimé aujourd'hui à cause de ça et je sais très bien que te le dire là par message n'arrangera rien parce que tu vas répéter comme d'habitude que tu n'oserai jamais faire ça. Bref désolé j'ai écris tout ça pour rien je vais effacer je pense.<br>Demain je vais chez le coiffeur à 11h fini les cheveux longs en plus après je vais acheter pleins de fringues je vais vraiment changer premier degrés ça va être cool. J'espère. En vrai j'aurai préféré faire ça avec toi, les boutiques et tout.. Bref je te laisse je vais dormir bonne nuit bisous ❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton cocu ?, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 5 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 5 - Jeudi 1er Mai</h1>
<p>Coucouu mon amour alors là il est 3h du matin, juste pour te dire que je vais aller me coucher mais je venais de faire le site que tu regardes là. Hehe j'suis trop fier de ce que j'ai fais c'est tout kiki, comme toi ❤️</p>
<p>Coucouuu ça va mon amour ? ❤️ J'ai bien dormi perso, je me suis levé à midi mais j'avais fais un rêve trop bizarre je me souviens pas de tout, mais je sais qu'à un moment mon frère fouille ce site là. Et à la fin je vais dans le garage de mes grands parents pour prendre une bouteille de Pepsi sauf qu'elle est chaude de fou vu qu'elle est restée au soleil, du coup je la mets au congélateur pour la refroidir un peu. Mais je remarque que depuis le début j'avais les yeux fermés et flous, tu sais comme quand tu viens de te réveiller. Du coup je cours en montant à l'étage pour me débarbouiller le visage. Et là je monte et c'est l'étage de ma maison à Feytiat, et en fait je cours parce qu'il y a quelqu'un derière moi qui veut me tuer, je sais pas qui c'est. J'arrive dans la salle de bain et je cherche un gant, j'en trouve pas du coup je fais ça avec une serviette et là le mec qui veut me tuer s'approche et me rend la bouteille de pepsi. Wesh.. Et là je me réveille... Bizarre. Bon après j'ai fais un Fifa pendant que mon père faisait à manger - c'est à dire des frites - et après ça j'ai mangé le burger en trop d'hier. On a regardé le Hot Ones avec Alain Chabat c'est trop bien. Et là il est 14h33 je sais pas ce que je vais faire, je vais surement brancher mon volant pour jouer à un jeu, pourquoi pas à BeamNG Drive. Bref je te laisse mon amour. Bisouuus</p>
<p>Je suis vraiment premier degrès en train de péter un plomb, j'en ai marre je sais pas quoi faire. J'ai littéralement fais tout ce que je pouvais faire. J'ai passé 2h sur un jeu de merde qui me plaisait pas juste parce que je savais pas quoi faire, bah j'ai vite abandonné. Et là je suis à deux doigts de casser mon écran ou de je jeter par la fenêtre, voire même de me jeter par la fenêtre. Je suis en train de devenir fou j'en peux plus. Reviens s'il te plait, je m'ennuie sans toi...</p>
<p>Euh j'allais t'écrire là mais je vois ça ⬇️ Il faut savoir que l'IA du logiciel de code prédis ce que je vais écrire. Bon là il essaye de prédire des truc nul mais wesh pourquoi il sait pour Feytiat. C'est mentionné nulle part ailleurs. Trop bizarre</p>
<img src="../img/ia.png" alt="IA qui prédit Feytiat" class="ia" width="90%">
<p>MDRRR Et là il m'a prédis la ligne pour mettre l'image en mettant le titre "IA qui prédit Feytiat" j'vais cabler</p>
<p>Bon du coup je voulais te dire. Là il est 3h du mat oui je triche on est vendredi techniquement mdrr. Je m'ennuyais trop à jouer à GT4 que du coup j'ai fais du casque et pour la vanne j'ai testé les jeux 18+. Mdrr comment c'est claqué au sol c'est juste pas pratique en fait je vois pas comment tu peux faire l'asmr en vrai en jouant à ça t'as constament les mains prises. Bref. Après ça je suis allé faire le gouter et je me suis dis que j'allais live à 20h J'ai rejoins Julien et Enzo en vocal. Enzo est parti quand j'ai lancé le live parce qu'il devait manger. Pas grave. J'ai d'abord fais du bedwars comme à l'ancienne mais mon ordi buggait trop c'est une dinguerie du coup j'ai changé pour Arcade Paradise (j'avais déjà commencé le jeu en live) Après ça Julien m'a rappelé l'existance du jeu The Exit 8 en fait ça fait un an je pense que je veux faire une vidéo dessus mais que j'y pensse pas. Du coup j'ai fais un live dessus et le concept est trop bien, y aura un montage sur ma chaine de ce gameplay. Ensuite j'ai coupé le live il était 23h30 mdrr et avec julien on a trainé sur les activités discord on a trouvé un Uno trop bien et on a joué au golf après. J'ai dis que je voulais dormir et il a lancé le tableau blanc commun mdrr. Evidemment on a fait des ref à 39-45 tu connais mdrr et après je t'écris et je vais dodo.</p>
<hr>
<p>Tu me manques trop vraiment. Aujourd'hui j'ai pas répondu à tes messages Insta et tu vas peut être trouver ça bizarre et me prendre pour un fou mais hier j'ai eu peur. Hier t'as envoyé des emojis que t'envoies jamais mais genre vraiment jamais. Ils faisaient quoi dans les récents alors ? Surtout celui qui regarde à travers ses yeux là. Tu l'envoie jamais et tu l'as envoyé à quelqu'un, je vois pas à qui ça peut être à part un amant, en mode "chut ça reste entre nous on lui dis pas"... Désolé je continue avec ça tu sais que c'est mon pire cauchemar.. Et en vrai j'ai aucune raison de pas te répondre. Je me doute trop de ce genre de choses. Mais comprends moi t'es loin si jamais tu en aurais l'envie tu aurais pu me tromper à cette distance je n'en saurai rien.. J'ai un peu déprimé aujourd'hui à cause de ça et je sais très bien que te le dire là par message n'arrangera rien parce que tu vas répéter comme d'habitude que tu n'oserai jamais faire ça. Bref désolé j'ai écris tout ça pour rien je vais effacer je pense.<br>Demain je vais chez le coiffeur à 11h fini les cheveux longs en plus après je vais acheter pleins de fringues je vais vraiment changer premier degrés ça va être cool. J'espère. En vrai j'aurai préféré faire ça avec toi, les boutiques et tout.. Bref je te laisse je vais dormir bonne nuit bisous ❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton cocu ?, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='4_mercredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+23 -23
View File
@@ -1,23 +1,23 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 6 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 6 - Vendredi 2 Mai</h1>
<p>Coucou mon amour ! Je vais tout t'écrire en une fois et y a plein de trucs à dire en plus ! Aujourd'hui je me suis levé et je suis allé dans la boite aux lettre récupérer le lecteur de disques durs pour pouvoir améliorer le serveur et mon ordi, je le débale je met le 2to que mon père m'a donné et je me dis que je vais mettre mon disque C dedans, remettre à 0 mon ordi pour l'ocasion. Bon j'ai que transféré là. Après ça je suis allé chez le coiffeur, elle a bien réussi ma coupe je trouve genre excatement ce à quoi je pensais. Donc nickel. Mais mon frère y est allé après et la coiffeuse à dit "Tu veux quoi comme coupe ?" Mon frère à dit "court." Bon.. ça tête ressemble à une mousse de micro mdrr, on dirait un télétubbies mais sans l'antenne bref avec mon frère on a vanné sa coupe toute la journée mdrr. Après fallait manger, moi je voulais manger à l'appart parce que flemme d'encore manger dehors. On a manger à Monsieur le Baron. Tu sais c'est le gros resto deluxe qui a pris feut pas loin du lycée. J'ai suivi mon père et mon frère à contre coeur j'en peux plus de manger des burgers mdrr. C'était bon en vrai. Après on est allés à Family Village on est allé à Inter Sport pour prendre des vetement pour moi puis à la halle puis à décatelon (on a fait une escale à boulanger pour que mon père se renseigne sur sa future télé mdrr) du coup j'ai pleins de nouveux vetements c'est trop bien. J'ai aussi pris un maillot de bain mais pas de claquette vu que je prendrais des Crocs vu que madame n'a d'yeux que pour les crocs. Je suis rentré et j'ai reset mon ordi pendant que je jouais à Mortal Kombat 1 avec mon père. J'ai galéré de fou, en fait mon ordi et sur protégé du coup pour formater bah c'est chiant. J'ai appliqué la méthode forte sauf qu'après j'avais plus rien qui marchait à part la souris et le clavier genre la luminosité de l'écran non et le wifi non plus. Après des heures de recherches j'ai rétabli le wifi le bluetooth la luminosité et d'autres trucs. J'ai mangé une petite salade et j'ai installé Need For Speed Most Wanted, la version de 2005, ce jeu est ouf pour 2005 vraiment. J'y jouais en étant en vocal avec Julien Enzo et Eudes qui est parti tôt.</p>
<hr>
<p>Je suis désolé mon amour j'ai pas osé répondre à tes messages, déjà parce que tu me les envoyais toujours au mauvais moment et en plus j'osais pas, je sais jamais quoi dire après t'avoir mis un remis, je m'en veux d'un côté mais d'un autre je trouve ça toujours aussi louche.. Désolé je force avec ça, je changerai jamais.. Bref Bisous Je t'aime mon amour dort bien❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton informaticien du dimanche, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='7_samedi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 6 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 6 - Vendredi 2 Mai</h1>
<p>Coucou mon amour ! Je vais tout t'écrire en une fois et y a plein de trucs à dire en plus ! Aujourd'hui je me suis levé et je suis allé dans la boite aux lettre récupérer le lecteur de disques durs pour pouvoir améliorer le serveur et mon ordi, je le débale je met le 2to que mon père m'a donné et je me dis que je vais mettre mon disque C dedans, remettre à 0 mon ordi pour l'ocasion. Bon j'ai que transféré là. Après ça je suis allé chez le coiffeur, elle a bien réussi ma coupe je trouve genre excatement ce à quoi je pensais. Donc nickel. Mais mon frère y est allé après et la coiffeuse à dit "Tu veux quoi comme coupe ?" Mon frère à dit "court." Bon.. ça tête ressemble à une mousse de micro mdrr, on dirait un télétubbies mais sans l'antenne bref avec mon frère on a vanné sa coupe toute la journée mdrr. Après fallait manger, moi je voulais manger à l'appart parce que flemme d'encore manger dehors. On a manger à Monsieur le Baron. Tu sais c'est le gros resto deluxe qui a pris feut pas loin du lycée. J'ai suivi mon père et mon frère à contre coeur j'en peux plus de manger des burgers mdrr. C'était bon en vrai. Après on est allés à Family Village on est allé à Inter Sport pour prendre des vetement pour moi puis à la halle puis à décatelon (on a fait une escale à boulanger pour que mon père se renseigne sur sa future télé mdrr) du coup j'ai pleins de nouveux vetements c'est trop bien. J'ai aussi pris un maillot de bain mais pas de claquette vu que je prendrais des Crocs vu que madame n'a d'yeux que pour les crocs. Je suis rentré et j'ai reset mon ordi pendant que je jouais à Mortal Kombat 1 avec mon père. J'ai galéré de fou, en fait mon ordi et sur protégé du coup pour formater bah c'est chiant. J'ai appliqué la méthode forte sauf qu'après j'avais plus rien qui marchait à part la souris et le clavier genre la luminosité de l'écran non et le wifi non plus. Après des heures de recherches j'ai rétabli le wifi le bluetooth la luminosité et d'autres trucs. J'ai mangé une petite salade et j'ai installé Need For Speed Most Wanted, la version de 2005, ce jeu est ouf pour 2005 vraiment. J'y jouais en étant en vocal avec Julien Enzo et Eudes qui est parti tôt.</p>
<hr>
<p>Je suis désolé mon amour j'ai pas osé répondre à tes messages, déjà parce que tu me les envoyais toujours au mauvais moment et en plus j'osais pas, je sais jamais quoi dire après t'avoir mis un remis, je m'en veux d'un côté mais d'un autre je trouve ça toujours aussi louche.. Désolé je force avec ça, je changerai jamais.. Bref Bisous Je t'aime mon amour dort bien❤️</p>
<h2 id="love">Je t'aime ❤️</h2>
<p class="author">Ton informaticien du dimanche, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='5_jeudi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='7_samedi.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+26 -26
View File
@@ -1,26 +1,26 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 7 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 7 - Samedi 3 Mai</h1>
<p>Coucouuu mon amouuur ! Tellement de choses à te dire alors qu'il est même pas 15h mdrr Déjà je me suis levé et jme suis fais un kiff j'ai fais le super p'tit dej comme chez ma grand mère, c'était moins bon y avait pas la vibe de chez elle mais bon. Après je me suis dis que j'allais m'attaquer à l'ordi de ma mamie justement. Alors je branche tout et là je remarque qu'elle n'a pas donné son alim... J'utilise mon alim les prises on l'air de correspondre. Sauf que, rien ça marche pas, alors je rends l'écran que j'ai volé a mon frère pour le brancher et je remets l'alim sur mon ordi. ET C'EST LE DRAME. Mon ordi ne charge plus, yess.. Je suis à ça de chialer alors je vais chercher une pince et j'essaye de remettre la tige qui n'était plus droite et là y a des étincelles mdrr. Du coup j'abandonne la mission et je dis ça à mon père. Mon père il s'énerve après ma mamie en mode "Ouais elle soule avec ses vieux trucs de merdes qui marchent pas et tout" Moi j'étais à côté en mode "ok". Du coup on va à LDLC pour voir s'ils en ont un. C'est fermé ça ouvre à 14h il est 13h20 là. Du coup on va a boulanger et on est super bien accueilli (c'est faux) par le mec qui dit "Ouais 120 balles ! Vous l'aurez Mardi en livraison ou Mercredi voire Jeudi" bon on à laissé le gars mdrr. On est aller voir les télés à Darty parce que mon père hésite à en acheter une. Et aussi pour passer le temps. Une fois qu'il est 14h on va à LDLC et là tout de suite ça change, le mec est trop sympa. Il nous donne un truc avec genre 9 embouts différents mdrr et on rentre. J'essaye.. Hallelujah !! C'est bon, ça marche ! Et du coup je t'écris là et je pense que je vais me re-regarder tous les Fast & Furious parce que j'sais pas j'ai eu envie d'un coup. Bon je te laisse bisouuuus</p>
<p>Coucouu ça va ? J'ai regardé Fast and Furious 1 j'ai aimé c'est vraiment trop bien. Je me dis qu'en vrai on pourrait les continuer tout les deux quand tu seras revenue ! Après ça j'ai rangé mes habits que j'ai acheté hier et Julien m'a proposé de venir en vocal avec Enzo et Eudes, je suis arrivé. On a fait un golf discord là et après du Gartic Phone c'était marrant. Ah oui et j'ai appris un truc. Adrian veut bien me reparler genre ça le dérangerait pas mais à une condition : que je lui donne 700 balles. Bah non mdrr il est con lui. J'ai raccroché pour aller manger j'ai mangé poulet paprika avec des patates miam. Par contre j'ai des gaz de fou genre j'arrête pas de péter et ça pue la mort en plus à chaque fois c'est infame ça me fait chier. (sans mauvais jeu de mot) Et là il est 21h40 je suis de retour en voc avec eux on va Gartic Phonner mdrr Je te laisse bisouus !</p>
<P>Bonsoiiiir je viens de faire un petit live sympa on a fait du gartic phone c'était cool. Après j'ai coupé parce qu'il était tard et de 00h à 1h30 on a jouer a des jeux discord avec julien et enzo mdrr c'était trop cool. Par contre tu m'as un peu énervé.. A absolument vouloir voir ma coupe alors que tu peux juste attendre, je voulais te faire la surprise mais t'as tout gaché. Je veux voir ta réaction moi pas juste un "Wow" qui ne répresentent que trois pauves lettres à mes yeux.. Mais non madame est trop pressée. En plus j'étais avec mes potes tu me dérangeais un peu. Plus ça va plus je me demande si ce site est une bonne idée..</P>
<hr>
<p>Aujourd'hui c'était particulier, c'était techniquement le dernier jour sans toi même si c'était chiant. Il s'est passé pas mal de trucs relou notemment l'alim de mon ordi. En plus je commence à douter de mon idée. Je suis sûr que tu vas lire tout ça mais qu'au fond tu vas t'en foutre, ou même que tu vas pas lire. Ou que tu ne trouves pas le lien du site. Puis j'écris pour rien là, il est 2h du matin faut que je dorme. Au début j'aimais bien écrire là, c'était un peu mon vide pensée, maintenant je me force un peu pour toi. Alors que tu ne liras surment pas ça. J'espère que les gateaux que je t'ai laissé étaient bon, je sais que t'aimes pas le chocolat mais j'avais rien d'autre.. Bref Bonne nuit ❤️</p>
<h2>Je t'aime ❤️</h2>
<p class="author">A quoi bon.., Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='8_dimanche.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 7 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 7 - Samedi 3 Mai</h1>
<p>Coucouuu mon amouuur ! Tellement de choses à te dire alors qu'il est même pas 15h mdrr Déjà je me suis levé et jme suis fais un kiff j'ai fais le super p'tit dej comme chez ma grand mère, c'était moins bon y avait pas la vibe de chez elle mais bon. Après je me suis dis que j'allais m'attaquer à l'ordi de ma mamie justement. Alors je branche tout et là je remarque qu'elle n'a pas donné son alim... J'utilise mon alim les prises on l'air de correspondre. Sauf que, rien ça marche pas, alors je rends l'écran que j'ai volé a mon frère pour le brancher et je remets l'alim sur mon ordi. ET C'EST LE DRAME. Mon ordi ne charge plus, yess.. Je suis à ça de chialer alors je vais chercher une pince et j'essaye de remettre la tige qui n'était plus droite et là y a des étincelles mdrr. Du coup j'abandonne la mission et je dis ça à mon père. Mon père il s'énerve après ma mamie en mode "Ouais elle soule avec ses vieux trucs de merdes qui marchent pas et tout" Moi j'étais à côté en mode "ok". Du coup on va à LDLC pour voir s'ils en ont un. C'est fermé ça ouvre à 14h il est 13h20 là. Du coup on va a boulanger et on est super bien accueilli (c'est faux) par le mec qui dit "Ouais 120 balles ! Vous l'aurez Mardi en livraison ou Mercredi voire Jeudi" bon on à laissé le gars mdrr. On est aller voir les télés à Darty parce que mon père hésite à en acheter une. Et aussi pour passer le temps. Une fois qu'il est 14h on va à LDLC et là tout de suite ça change, le mec est trop sympa. Il nous donne un truc avec genre 9 embouts différents mdrr et on rentre. J'essaye.. Hallelujah !! C'est bon, ça marche ! Et du coup je t'écris là et je pense que je vais me re-regarder tous les Fast & Furious parce que j'sais pas j'ai eu envie d'un coup. Bon je te laisse bisouuuus</p>
<p>Coucouu ça va ? J'ai regardé Fast and Furious 1 j'ai aimé c'est vraiment trop bien. Je me dis qu'en vrai on pourrait les continuer tout les deux quand tu seras revenue ! Après ça j'ai rangé mes habits que j'ai acheté hier et Julien m'a proposé de venir en vocal avec Enzo et Eudes, je suis arrivé. On a fait un golf discord là et après du Gartic Phone c'était marrant. Ah oui et j'ai appris un truc. Adrian veut bien me reparler genre ça le dérangerait pas mais à une condition : que je lui donne 700 balles. Bah non mdrr il est con lui. J'ai raccroché pour aller manger j'ai mangé poulet paprika avec des patates miam. Par contre j'ai des gaz de fou genre j'arrête pas de péter et ça pue la mort en plus à chaque fois c'est infame ça me fait chier. (sans mauvais jeu de mot) Et là il est 21h40 je suis de retour en voc avec eux on va Gartic Phonner mdrr Je te laisse bisouus !</p>
<P>Bonsoiiiir je viens de faire un petit live sympa on a fait du gartic phone c'était cool. Après j'ai coupé parce qu'il était tard et de 00h à 1h30 on a jouer a des jeux discord avec julien et enzo mdrr c'était trop cool. Par contre tu m'as un peu énervé.. A absolument vouloir voir ma coupe alors que tu peux juste attendre, je voulais te faire la surprise mais t'as tout gaché. Je veux voir ta réaction moi pas juste un "Wow" qui ne répresentent que trois pauves lettres à mes yeux.. Mais non madame est trop pressée. En plus j'étais avec mes potes tu me dérangeais un peu. Plus ça va plus je me demande si ce site est une bonne idée..</P>
<hr>
<p>Aujourd'hui c'était particulier, c'était techniquement le dernier jour sans toi même si c'était chiant. Il s'est passé pas mal de trucs relou notemment l'alim de mon ordi. En plus je commence à douter de mon idée. Je suis sûr que tu vas lire tout ça mais qu'au fond tu vas t'en foutre, ou même que tu vas pas lire. Ou que tu ne trouves pas le lien du site. Puis j'écris pour rien là, il est 2h du matin faut que je dorme. Au début j'aimais bien écrire là, c'était un peu mon vide pensée, maintenant je me force un peu pour toi. Alors que tu ne liras surment pas ça. J'espère que les gateaux que je t'ai laissé étaient bon, je sais que t'aimes pas le chocolat mais j'avais rien d'autre.. Bref Bonne nuit ❤️</p>
<h2>Je t'aime ❤️</h2>
<p class="author">A quoi bon.., Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='6_vendredi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
<button class="glow-button" onclick="window.location.href='8_dimanche.html'">➡ Suivant</button>
</div>
</div>
</body>
</html>
+21 -21
View File
@@ -1,21 +1,21 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 8 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 8 - Dimanche 4 Mai</h1>
<p>Coucou mon amour, bien dormi ? Je sais que là t'es chez toi je crois (il est 17h30) mais j'ai pas eu de nouvelles, tant pis je dirai que je le mérite un peu. J'écris vite parce que je vais bientot partir pour aller chez ma mère. Aujourd'hui après m'être levé j'ai graille et j'ai fais mes sacs, mon père m'a donné un big sac qui est trop bien on peut mettre plein de trucs dedans. J'y pense un peu là mais je sais que même si on est dimanche et que c'est ton retour je pourrais pas te parler soit parce que tu auras pas le temps ou que tu m'oublira voire que tu ne veuilles pas c'est possible aussi. Même si tu me manques je dirai que j'ai grandi là dessus. Donc ne me parle pas si tu n'en as pas envie... Bisous</p>
<p>Puis aussi je vais arrêter d'écrire ici voilà, ça sert à rien, je ne te donnerai peut etre pas ce papier avec le lien du site, je vais enlever la papier de la boite à gouter quand j'y penserai. Je touche plus à ce site</p>
<h2>Je t'aime ❤️</h2>
<p class="author">, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='7_samedi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Jour 8 💌</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1>Jour 8 - Dimanche 4 Mai</h1>
<p>Coucou mon amour, bien dormi ? Je sais que là t'es chez toi je crois (il est 17h30) mais j'ai pas eu de nouvelles, tant pis je dirai que je le mérite un peu. J'écris vite parce que je vais bientot partir pour aller chez ma mère. Aujourd'hui après m'être levé j'ai graille et j'ai fais mes sacs, mon père m'a donné un big sac qui est trop bien on peut mettre plein de trucs dedans. J'y pense un peu là mais je sais que même si on est dimanche et que c'est ton retour je pourrais pas te parler soit parce que tu auras pas le temps ou que tu m'oublira voire que tu ne veuilles pas c'est possible aussi. Même si tu me manques je dirai que j'ai grandi là dessus. Donc ne me parle pas si tu n'en as pas envie... Bisous</p>
<p>Puis aussi je vais arrêter d'écrire ici voilà, ça sert à rien, je ne te donnerai peut etre pas ce papier avec le lien du site, je vais enlever la papier de la boite à gouter quand j'y penserai. Je touche plus à ce site</p>
<h2>Je t'aime ❤️</h2>
<p class="author">, Noah ❤️</p>
<div class="nav-bar">
<button class="glow-button" onclick="window.location.href='7_samedi.html'">⬅ Précédent</button>
<button class="glow-button" onclick="window.location.href='../index.html'">🏠 Accueil</button>
</div>
</div>
</body>
</html>
+143 -143
View File
@@ -1,144 +1,144 @@
body {
margin: 0;
padding: 0;
background: linear-gradient(to right, #ffc5ee, #ff80fb);
font-family: 'Segoe UI', sans-serif;
color: #333;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 30px;
border-radius: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
max-width: 600px;
text-align: center;
}
h1 {
font-size: 2em;
color: #e63946;
}
.intro {
font-size: 1.2em;
margin: 20px 0;
}
.nav {
list-style: none;
padding: 0;
}
.nav li {
margin: 10px 0;
}
.nav a {
text-decoration: none;
color: #ff00bf;
font-weight: bold;
transition: color 0.3s;
}
.nav a:hover {
color: #a4007b;
}
.author {
text-align: right;
text-decoration: underline;
font-style: italic; /* optionnel si tu veux une vibe douce */
font-weight: 500;
margin-top: 40px;
color: #934c7e; /* une ptite couleur romantique */
}
h2 {
color: #ff4d6d;
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
animation: glow 2s ease-in-out infinite;
}
@keyframes glow {
0%, 100% {
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
}
50% {
text-shadow: 0 0 20px #ff85a2, 0 0 30px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
padding: 12px 30px;
background-color: #ff4d6d;
color: white;
border: 2px solid #cc2f4d; /* plus foncé que le fond */
border-radius: 30px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
transition: all 0.3s ease-in-out;
}
.glow-button:hover {
background-color: #ff85a2;
border-color: #cc5a7d; /* version plus foncée du hover */
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
transform: scale(1.07);
}
@keyframes pulse {
0%, 100% {
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
}
50% {
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
animation: pulse 2s infinite;
}
.button-grid {
display: flex;
flex-direction: column;
gap: 12px;
max-width: 300px;
margin: 40px auto;
}
.button-grid button {
padding: 12px 20px;
background-color: #ffd3e0;
border: 2px solid #cc2f4d;
border-radius: 25px;
color: #b4003a;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 0 6px #ffc2d4;
}
.button-grid button:hover {
background-color: #ffc2d4;
border-color: #b4003a;
color: #800026;
transform: scale(1.05);
box-shadow: 0 0 12px #ffa3bd;
}
.nav-bar {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 40px;
}
body {
margin: 0;
padding: 0;
background: linear-gradient(to right, #ffc5ee, #ff80fb);
font-family: 'Segoe UI', sans-serif;
color: #333;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 30px;
border-radius: 20px;
box-shadow: 0 5px 20px rgba(0,0,0,0.2);
max-width: 600px;
text-align: center;
}
h1 {
font-size: 2em;
color: #e63946;
}
.intro {
font-size: 1.2em;
margin: 20px 0;
}
.nav {
list-style: none;
padding: 0;
}
.nav li {
margin: 10px 0;
}
.nav a {
text-decoration: none;
color: #ff00bf;
font-weight: bold;
transition: color 0.3s;
}
.nav a:hover {
color: #a4007b;
}
.author {
text-align: right;
text-decoration: underline;
font-style: italic; /* optionnel si tu veux une vibe douce */
font-weight: 500;
margin-top: 40px;
color: #934c7e; /* une ptite couleur romantique */
}
h2 {
color: #ff4d6d;
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
animation: glow 2s ease-in-out infinite;
}
@keyframes glow {
0%, 100% {
text-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d, 0 0 30px #ff4d6d;
}
50% {
text-shadow: 0 0 20px #ff85a2, 0 0 30px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
padding: 12px 30px;
background-color: #ff4d6d;
color: white;
border: 2px solid #cc2f4d; /* plus foncé que le fond */
border-radius: 30px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
transition: all 0.3s ease-in-out;
}
.glow-button:hover {
background-color: #ff85a2;
border-color: #cc5a7d; /* version plus foncée du hover */
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
transform: scale(1.07);
}
@keyframes pulse {
0%, 100% {
box-shadow: 0 0 10px #ff4d6d, 0 0 20px #ff4d6d;
}
50% {
box-shadow: 0 0 20px #ff85a2, 0 0 40px #ff85a2;
}
}
.glow-button {
animation: pulse 2s infinite;
}
.button-grid {
display: flex;
flex-direction: column;
gap: 12px;
max-width: 300px;
margin: 40px auto;
}
.button-grid button {
padding: 12px 20px;
background-color: #ffd3e0;
border: 2px solid #cc2f4d;
border-radius: 25px;
color: #b4003a;
font-size: 16px;
font-weight: bold;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 0 6px #ffc2d4;
}
.button-grid button:hover {
background-color: #ffc2d4;
border-color: #b4003a;
color: #800026;
transform: scale(1.05);
box-shadow: 0 0 12px #ffa3bd;
}
.nav-bar {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 40px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+93 -93
View File
@@ -1,94 +1,94 @@
body {
font-family: 'Noto Sans', sans-serif;
background-color: #333;
color: #fff;
}
.container {
width: 80%;
margin: auto;
border: 2px solid #8C0312;
border-radius: 25px;
padding: 20px;
background-color: #444;
}
.nav a {
text-decoration: none;
color: #fff;
padding: 10px 20px;
border: 2px solid #8C0312;
border-radius: 25px;
background-color: #333;
transition: all 0.3s ease-in-out;
}
.nav a:hover {
background-color: #8C0312;
color: #333;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.video-container {
width: 80%;
margin: 20px auto;
border: 2px solid #8C0312;
border-radius: 25px;
overflow: hidden;
padding-bottom: 56.25%;
position: relative;
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
header {
text-align: left;
}
.logo {
width: 9.5%;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
.title {
display: inline-block;
font-size: 48px;
line-height: 60px;
vertical-align: middle;
}
div.footer {
width: 80%;
margin: auto;
border: 2px solid #8C0312;
border-radius: 25px;
padding: 20px;
background-color: #444;
display: flex;
justify-content: center;
align-items: center;
}
img.flash {
display: inline-block;
width: 128px;
transition: 0.4s;
};
img.flash:hover {
transition: 0.4s;
width: 800px
};
#results {
list-style-type: none;
padding: 0;
}
#results li {
margin-bottom: 5px;
cursor: pointer;
body {
font-family: 'Noto Sans', sans-serif;
background-color: #333;
color: #fff;
}
.container {
width: 80%;
margin: auto;
border: 2px solid #8C0312;
border-radius: 25px;
padding: 20px;
background-color: #444;
}
.nav a {
text-decoration: none;
color: #fff;
padding: 10px 20px;
border: 2px solid #8C0312;
border-radius: 25px;
background-color: #333;
transition: all 0.3s ease-in-out;
}
.nav a:hover {
background-color: #8C0312;
color: #333;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.video-container {
width: 80%;
margin: 20px auto;
border: 2px solid #8C0312;
border-radius: 25px;
overflow: hidden;
padding-bottom: 56.25%;
position: relative;
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
header {
text-align: left;
}
.logo {
width: 9.5%;
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
.title {
display: inline-block;
font-size: 48px;
line-height: 60px;
vertical-align: middle;
}
div.footer {
width: 80%;
margin: auto;
border: 2px solid #8C0312;
border-radius: 25px;
padding: 20px;
background-color: #444;
display: flex;
justify-content: center;
align-items: center;
}
img.flash {
display: inline-block;
width: 128px;
transition: 0.4s;
};
img.flash:hover {
transition: 0.4s;
width: 800px
};
#results {
list-style-type: none;
padding: 0;
}
#results li {
margin-bottom: 5px;
cursor: pointer;
}
+37 -37
View File
@@ -1,37 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="img/logo.png">
<title>Mik'A'Muz</title>
</head>
<body>
<div class="container">
<header>
<a href="https://www.facebook.com/mikamuzdj" target="_blank">
<img class="logo" src="img/logo.png" alt="Logo">
</a>
<h1 class="title">Mik'A'Muz</h1>
<h4>DJ amateur depuis plus de 15 ans passionné de musique depuis petit, je me ferai un plaisir de vous aMUZer sur des MUZiques de tous styles.</h4>
</header>
<hr>
<h1>Liste de karaokés - 2026</h1>
<p>Vous pouvez télécharger la liste des karaokés entière. Ou effectuer une recherche dans la liste tout en bas.</p>
<div class="nav">
<a href="Liste karaoké 2026 v2.pdf" target="_BLANK">Liste Karaoké 2026</a>
</div>
<br>
<hr>
<h1>Recherche dans la liste de karaoké</h1>
<input type="text" id="searchInput" placeholder="Rechercher...">
<ul id="results"></ul>
</div>
<div class="footer">
Copyright | Whykorp® 2021-2026
</div>
<script src="script.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="img/logo.png">
<title>Mik'A'Muz</title>
</head>
<body>
<div class="container">
<header>
<a href="https://www.facebook.com/mikamuzdj" target="_blank">
<img class="logo" src="img/logo.png" alt="Logo">
</a>
<h1 class="title">Mik'A'Muz</h1>
<h4>DJ amateur depuis plus de 15 ans passionné de musique depuis petit, je me ferai un plaisir de vous aMUZer sur des MUZiques de tous styles.</h4>
</header>
<hr>
<h1>Liste de karaokés - 2026</h1>
<p>Vous pouvez télécharger la liste des karaokés entière. Ou effectuer une recherche dans la liste tout en bas.</p>
<div class="nav">
<a href="Liste karaoké 2026 v2.pdf" target="_BLANK">Liste Karaoké 2026</a>
</div>
<br>
<hr>
<h1>Recherche dans la liste de karaoké</h1>
<input type="text" id="searchInput" placeholder="Rechercher...">
<ul id="results"></ul>
</div>
<div class="footer">
Copyright | Whykorp® 2021-2026
</div>
<script src="script.js"></script>
</body>
</html>
+32 -32
View File
@@ -1,33 +1,33 @@
document.addEventListener('DOMContentLoaded', function () {
const searchInput = document.getElementById('searchInput');
const resultsList = document.getElementById('results');
// Charger le fichier CSV
fetch('Liste karaoké 2026 v2.csv')
.then(response => response.text())
.then(data => {
const lines = data.split('\n');
const items = lines.map(line => line.trim());
// Fonction de recherche
function search(query) {
resultsList.innerHTML = '';
const filteredItems = items.filter(item =>
item.toLowerCase().includes(query.toLowerCase())
);
filteredItems.forEach(item => {
let displayedItem = item.replace('.mp4', '').replace(';;;', '');
const li = document.createElement('li');
li.textContent = displayedItem;
resultsList.appendChild(li);
});
}
// Écouter les changements de la barre de recherche
searchInput.addEventListener('input', function () {
search(searchInput.value);
});
})
.catch(error => console.error('Erreur de chargement du fichier :', error));
document.addEventListener('DOMContentLoaded', function () {
const searchInput = document.getElementById('searchInput');
const resultsList = document.getElementById('results');
// Charger le fichier CSV
fetch('Liste karaoké 2026 v2.csv')
.then(response => response.text())
.then(data => {
const lines = data.split('\n');
const items = lines.map(line => line.trim());
// Fonction de recherche
function search(query) {
resultsList.innerHTML = '';
const filteredItems = items.filter(item =>
item.toLowerCase().includes(query.toLowerCase())
);
filteredItems.forEach(item => {
let displayedItem = item.replace('.mp4', '').replace(';;;', '');
const li = document.createElement('li');
li.textContent = displayedItem;
resultsList.appendChild(li);
});
}
// Écouter les changements de la barre de recherche
searchInput.addEventListener('input', function () {
search(searchInput.value);
});
})
.catch(error => console.error('Erreur de chargement du fichier :', error));
});
+207 -207
View File
@@ -1,208 +1,208 @@
/* config.css - Version Poker PAF Harmonisée */
:root {
--table-green: radial-gradient(circle, #277d46 0%, #1a5e33 100%);
--poker-border: #2c1b18;
--gold: #d4af37;
--gold-light: #f9e27d;
--dark-bg: #0a0a0a;
--white: #ffffff;
--wood-dark: #1a0f0d;
--danger: #b71c1c;
}
body {
background-color: var(--dark-bg);
background-image: radial-gradient(circle at center, #1a1a1a 0%, #050505 100%);
color: var(--white);
font-family: 'Segoe UI', Roboto, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
/* --- LE CONTENEUR (Exactement comme l'accueil) --- */
.container {
background: var(--table-green);
padding: 40px 50px;
border-radius: 40px; /* Carré arrondi comme l'accueil */
border: 15px solid var(--poker-border);
box-shadow: 0 25px 50px rgba(0,0,0,0.9), inset 0 0 40px rgba(0,0,0,0.6);
width: 100%;
max-width: 500px;
position: relative;
outline: 2px solid #3d2b27;
}
/* --- LE LISERÉ BLANC --- */
.container::before {
content: '';
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 30px;
pointer-events: none;
z-index: 1;
}
h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 1.8rem;
margin-bottom: 30px;
text-align: center;
letter-spacing: 1px;
text-shadow: 2px 2px 0px rgba(0,0,0,0.8);
position: relative;
z-index: 2;
}
/* --- FORMULAIRE ET INPUTS --- */
form {
position: relative;
z-index: 2;
}
label {
display: block;
color: var(--gold);
font-weight: bold;
margin-bottom: 8px;
text-transform: uppercase;
font-size: 0.9rem;
}
label.info {
text-transform: none;
font-size: 0.8rem;
color: rgba(255,255,255,0.5);
margin-bottom: 15px;
}
input[type="number"],
input[type="text"] {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 2px solid rgba(212, 175, 55, 0.5);
border-radius: 10px;
background: rgba(0, 0, 0, 0.3);
color: white;
font-size: 1rem;
transition: border-color 0.3s;
}
input:focus {
outline: none;
border-color: var(--gold);
background: rgba(0, 0, 0, 0.5);
}
/* --- LIGNES JOUEURS --- */
.player-row {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.player-row p {
color: var(--gold);
font-weight: bold;
margin: 0;
min-width: 20px;
}
.player-row input {
margin-bottom: 0;
}
/* --- BOUTONS --- */
button, input[type="submit"] {
cursor: pointer;
font-weight: bold;
transition: all 0.3s;
border: none;
}
/* Ajouter un joueur */
button[type="button"] {
background-color: rgba(0,0,0,0.4);
color: var(--white);
border: 1px solid rgba(255,255,255,0.2);
padding: 10px 15px;
border-radius: 8px;
margin: 10px 0 20px 0;
width: 100%;
}
button[type="button"]:hover {
background-color: rgba(255,255,255,0.1);
border-color: var(--white);
}
/* Poubelle */
.player-row button {
background-color: var(--danger);
color: white;
padding: 10px;
border-radius: 8px;
width: auto;
margin: 0;
}
/* Bouton Démarrer (Gros bouton doré comme l'accueil) */
input[type="submit"] {
width: 100%;
background: linear-gradient(135deg, var(--gold) 0%, var(--gold-light) 50%, var(--gold) 100%);
color: var(--wood-dark);
padding: 18px;
font-size: 1.2rem;
border-radius: 50px;
margin-top: 10px;
box-shadow: 0 8px 0px #927521, 0 15px 20px rgba(0,0,0,0.4);
text-transform: uppercase;
}
input[type="submit"]:hover {
transform: translateY(-2px);
box-shadow: 0 10px 0px #927521, 0 20px 25px rgba(0,0,0,0.5);
}
/* Bouton Retour */
.btn-back {
position: absolute;
top: 25px;
left: 30px;
color: var(--gold);
text-decoration: none;
font-weight: bold;
font-size: 0.8rem;
background: none !important;
border: none !important;
padding: 0 !important;
z-index: 10;
opacity: 0.8;
}
.btn-back:hover {
opacity: 1;
transform: translateX(-3px);
}
/* --- ADAPTATION MOBILE --- */
@media (max-width: 600px) {
body { align-items: flex-start; }
.container {
padding: 30px 20px;
border-width: 10px;
border-radius: 30px;
}
.container::before { top: 7px; left: 7px; right: 7px; bottom: 7px; }
.btn-back { position: relative; top: 0; left: 0; margin-bottom: 20px; }
/* config.css - Version Poker PAF Harmonisée */
:root {
--table-green: radial-gradient(circle, #277d46 0%, #1a5e33 100%);
--poker-border: #2c1b18;
--gold: #d4af37;
--gold-light: #f9e27d;
--dark-bg: #0a0a0a;
--white: #ffffff;
--wood-dark: #1a0f0d;
--danger: #b71c1c;
}
body {
background-color: var(--dark-bg);
background-image: radial-gradient(circle at center, #1a1a1a 0%, #050505 100%);
color: var(--white);
font-family: 'Segoe UI', Roboto, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
/* --- LE CONTENEUR (Exactement comme l'accueil) --- */
.container {
background: var(--table-green);
padding: 40px 50px;
border-radius: 40px; /* Carré arrondi comme l'accueil */
border: 15px solid var(--poker-border);
box-shadow: 0 25px 50px rgba(0,0,0,0.9), inset 0 0 40px rgba(0,0,0,0.6);
width: 100%;
max-width: 500px;
position: relative;
outline: 2px solid #3d2b27;
}
/* --- LE LISERÉ BLANC --- */
.container::before {
content: '';
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 30px;
pointer-events: none;
z-index: 1;
}
h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 1.8rem;
margin-bottom: 30px;
text-align: center;
letter-spacing: 1px;
text-shadow: 2px 2px 0px rgba(0,0,0,0.8);
position: relative;
z-index: 2;
}
/* --- FORMULAIRE ET INPUTS --- */
form {
position: relative;
z-index: 2;
}
label {
display: block;
color: var(--gold);
font-weight: bold;
margin-bottom: 8px;
text-transform: uppercase;
font-size: 0.9rem;
}
label.info {
text-transform: none;
font-size: 0.8rem;
color: rgba(255,255,255,0.5);
margin-bottom: 15px;
}
input[type="number"],
input[type="text"] {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 2px solid rgba(212, 175, 55, 0.5);
border-radius: 10px;
background: rgba(0, 0, 0, 0.3);
color: white;
font-size: 1rem;
transition: border-color 0.3s;
}
input:focus {
outline: none;
border-color: var(--gold);
background: rgba(0, 0, 0, 0.5);
}
/* --- LIGNES JOUEURS --- */
.player-row {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.player-row p {
color: var(--gold);
font-weight: bold;
margin: 0;
min-width: 20px;
}
.player-row input {
margin-bottom: 0;
}
/* --- BOUTONS --- */
button, input[type="submit"] {
cursor: pointer;
font-weight: bold;
transition: all 0.3s;
border: none;
}
/* Ajouter un joueur */
button[type="button"] {
background-color: rgba(0,0,0,0.4);
color: var(--white);
border: 1px solid rgba(255,255,255,0.2);
padding: 10px 15px;
border-radius: 8px;
margin: 10px 0 20px 0;
width: 100%;
}
button[type="button"]:hover {
background-color: rgba(255,255,255,0.1);
border-color: var(--white);
}
/* Poubelle */
.player-row button {
background-color: var(--danger);
color: white;
padding: 10px;
border-radius: 8px;
width: auto;
margin: 0;
}
/* Bouton Démarrer (Gros bouton doré comme l'accueil) */
input[type="submit"] {
width: 100%;
background: linear-gradient(135deg, var(--gold) 0%, var(--gold-light) 50%, var(--gold) 100%);
color: var(--wood-dark);
padding: 18px;
font-size: 1.2rem;
border-radius: 50px;
margin-top: 10px;
box-shadow: 0 8px 0px #927521, 0 15px 20px rgba(0,0,0,0.4);
text-transform: uppercase;
}
input[type="submit"]:hover {
transform: translateY(-2px);
box-shadow: 0 10px 0px #927521, 0 20px 25px rgba(0,0,0,0.5);
}
/* Bouton Retour */
.btn-back {
position: absolute;
top: 25px;
left: 30px;
color: var(--gold);
text-decoration: none;
font-weight: bold;
font-size: 0.8rem;
background: none !important;
border: none !important;
padding: 0 !important;
z-index: 10;
opacity: 0.8;
}
.btn-back:hover {
opacity: 1;
transform: translateX(-3px);
}
/* --- ADAPTATION MOBILE --- */
@media (max-width: 600px) {
body { align-items: flex-start; }
.container {
padding: 30px 20px;
border-width: 10px;
border-radius: 30px;
}
.container::before { top: 7px; left: 7px; right: 7px; bottom: 7px; }
.btn-back { position: relative; top: 0; left: 0; margin-bottom: 20px; }
}
+761 -761
View File
File diff suppressed because it is too large Load Diff
+230 -230
View File
@@ -1,231 +1,231 @@
/* --- VARIABLES GLOBALES --- */
:root {
--table-green: radial-gradient(circle, #277d46 0%, #1a5e33 100%);
--table-dark: radial-gradient(circle, #1a1a1a 0%, #0a0a0a 100%); /* Couleur pour la table sombre */
--poker-border: #2c1b18;
--gold: #d4af37;
--gold-light: #f9e27d;
--dark-bg: #0a0a0a;
--white: #ffffff;
--wood-dark: #1a0f0d;
}
/* --- STRUCTURE DE LA PAGE --- */
body {
background-color: var(--dark-bg);
background-image: radial-gradient(circle at center, #1a1a1a 0%, #050505 100%);
color: var(--white);
font-family: 'Segoe UI', Roboto, sans-serif;
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
}
.main-wrapper {
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 20px;
width: 100%;
max-width: 1000px; /* Réduit pour garder une forme de table sympa */
}
/* --- STYLE COMMUN DES TABLES --- */
.poker-table {
position: relative;
padding: 30px;
border-radius: 80px;
border: 15px solid var(--poker-border);
box-shadow: 0 25px 50px rgba(0,0,0,0.9), inset 0 0 40px rgba(0,0,0,0.6);
width: 100%;
outline: 2px solid #3d2b27;
margin-bottom: 40px;
box-sizing: border-box;
}
.poker-table::before {
content: '';
position: absolute;
top: 12px; left: 12px; right: 12px; bottom: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 65px;
pointer-events: none;
}
.table-inner {
position: relative;
z-index: 2;
text-align: center;
}
/* --- SPECIFICITÉS TABLE HEADER (SOMBRE) --- */
.table-header {
background: var(--table-dark);
max-width: 800px;
border-color: #1a1a1a; /* Bordure plus noire pour le header */
}
.table-header h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 1.2rem;
margin: 0 0 10px 0;
letter-spacing: 2px;
}
/* --- SPECIFICITÉS TABLE MAIN (VERTE) --- */
.table-main {
background: var(--table-green);
}
.tables-hall {
width: 100%;
display: flex;
justify-content: center;
}
/* --- CENTRAGE DU BOUTON --- */
.button-center-wrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 20px 0 40px 0; /* Espace le bouton du titre de la liste */
}
/* --- LOGO --- */
.logo-paf {
width: 220px;
height: auto;
filter: drop-shadow(0 0 15px rgba(180, 50, 255, 0.6));
transition: transform 0.3s ease;
}
.logo-paf:hover {
transform: scale(1.05);
}
/* --- BOUTON CRÉER --- */
.btn-main-create {
background: linear-gradient(135deg, var(--gold) 0%, var(--gold-light) 50%, var(--gold) 100%);
color: var(--wood-dark);
padding: 18px 45px;
font-weight: 900;
font-size: 1.2rem;
border-radius: 50px;
border: none;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow: 0 8px 0px #927521, 0 15px 20px rgba(0,0,0,0.4);
text-transform: uppercase;
}
.btn-main-create:hover {
transform: translateY(-2px);
box-shadow: 0 10px 0px #927521, 0 20px 25px rgba(0,0,0,0.5);
}
/* --- TITRES ET LISTES --- */
.table-main h2 {
font-size: 1.1rem;
color: rgba(255,255,255,0.7);
text-transform: uppercase;
margin-bottom: 20px;
}
#games_list ul {
list-style: none;
padding: 0;
max-width: 500px;
margin: 0 auto;
}
.mon-accordeon {
background-color: rgba(0,0,0,0.5);
border-radius: 15px;
border: 2px solid #333;
margin-bottom: 12px;
text-align: left;
}
summary {
padding: 12px 20px;
color: var(--gold);
font-weight: bold;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
outline: none;
}
.container-parent {
display: flex;
justify-content: space-between;
background: rgba(0,0,0,0.2);
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all 0.4s ease;
}
details[open] .container-parent {
max-height: 500px;
opacity: 1;
padding: 20px;
}
/* --- ZONES INTERNES ACCORDÉON --- */
.left { flex: 1.2; border-left: 2px solid rgba(212, 175, 55, 0.2); padding-left: 15px; }
.left p { margin: 3px 0; font-size: 0.9rem; color: #eee; }
.right { flex: 1; display: flex; flex-direction: column; }
.right p { font-size: 0.8rem; color: var(--gold); margin-bottom: 10px; }
.btn-join-list, .btn-admin-join-list {
width: 100%;
margin-bottom: 8px;
padding: 10px;
border-radius: 6px;
border: 1px solid var(--gold);
background: transparent;
color: var(--gold);
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
font-size: 0.7rem;
transition: 0.2s;
}
.btn-join-list:hover { background: var(--gold); color: black; }
.btn-admin-join-list { border-color: rgba(255,255,255,0.3); color: rgba(255,255,255,0.5); }
/* --- RESPONSIVE --- */
@media (max-width: 600px) {
.poker-table { border-radius: 40px; padding: 15px; border-width: 10px; }
.logo-paf { width: 160px; }
.btn-main-create { padding: 12px 25px; font-size: 1rem; }
/* --- VARIABLES GLOBALES --- */
:root {
--table-green: radial-gradient(circle, #277d46 0%, #1a5e33 100%);
--table-dark: radial-gradient(circle, #1a1a1a 0%, #0a0a0a 100%); /* Couleur pour la table sombre */
--poker-border: #2c1b18;
--gold: #d4af37;
--gold-light: #f9e27d;
--dark-bg: #0a0a0a;
--white: #ffffff;
--wood-dark: #1a0f0d;
}
/* --- STRUCTURE DE LA PAGE --- */
body {
background-color: var(--dark-bg);
background-image: radial-gradient(circle at center, #1a1a1a 0%, #050505 100%);
color: var(--white);
font-family: 'Segoe UI', Roboto, sans-serif;
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
}
.main-wrapper {
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 20px;
width: 100%;
max-width: 1000px; /* Réduit pour garder une forme de table sympa */
}
/* --- STYLE COMMUN DES TABLES --- */
.poker-table {
position: relative;
padding: 30px;
border-radius: 80px;
border: 15px solid var(--poker-border);
box-shadow: 0 25px 50px rgba(0,0,0,0.9), inset 0 0 40px rgba(0,0,0,0.6);
width: 100%;
outline: 2px solid #3d2b27;
margin-bottom: 40px;
box-sizing: border-box;
}
.poker-table::before {
content: '';
position: absolute;
top: 12px; left: 12px; right: 12px; bottom: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 65px;
pointer-events: none;
}
.table-inner {
position: relative;
z-index: 2;
text-align: center;
}
/* --- SPECIFICITÉS TABLE HEADER (SOMBRE) --- */
.table-header {
background: var(--table-dark);
max-width: 800px;
border-color: #1a1a1a; /* Bordure plus noire pour le header */
}
.table-header h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 1.2rem;
margin: 0 0 10px 0;
letter-spacing: 2px;
}
/* --- SPECIFICITÉS TABLE MAIN (VERTE) --- */
.table-main {
background: var(--table-green);
}
.tables-hall {
width: 100%;
display: flex;
justify-content: center;
}
/* --- CENTRAGE DU BOUTON --- */
.button-center-wrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 20px 0 40px 0; /* Espace le bouton du titre de la liste */
}
/* --- LOGO --- */
.logo-paf {
width: 220px;
height: auto;
filter: drop-shadow(0 0 15px rgba(180, 50, 255, 0.6));
transition: transform 0.3s ease;
}
.logo-paf:hover {
transform: scale(1.05);
}
/* --- BOUTON CRÉER --- */
.btn-main-create {
background: linear-gradient(135deg, var(--gold) 0%, var(--gold-light) 50%, var(--gold) 100%);
color: var(--wood-dark);
padding: 18px 45px;
font-weight: 900;
font-size: 1.2rem;
border-radius: 50px;
border: none;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow: 0 8px 0px #927521, 0 15px 20px rgba(0,0,0,0.4);
text-transform: uppercase;
}
.btn-main-create:hover {
transform: translateY(-2px);
box-shadow: 0 10px 0px #927521, 0 20px 25px rgba(0,0,0,0.5);
}
/* --- TITRES ET LISTES --- */
.table-main h2 {
font-size: 1.1rem;
color: rgba(255,255,255,0.7);
text-transform: uppercase;
margin-bottom: 20px;
}
#games_list ul {
list-style: none;
padding: 0;
max-width: 500px;
margin: 0 auto;
}
.mon-accordeon {
background-color: rgba(0,0,0,0.5);
border-radius: 15px;
border: 2px solid #333;
margin-bottom: 12px;
text-align: left;
}
summary {
padding: 12px 20px;
color: var(--gold);
font-weight: bold;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
outline: none;
}
.container-parent {
display: flex;
justify-content: space-between;
background: rgba(0,0,0,0.2);
max-height: 0;
opacity: 0;
overflow: hidden;
transition: all 0.4s ease;
}
details[open] .container-parent {
max-height: 500px;
opacity: 1;
padding: 20px;
}
/* --- ZONES INTERNES ACCORDÉON --- */
.left { flex: 1.2; border-left: 2px solid rgba(212, 175, 55, 0.2); padding-left: 15px; }
.left p { margin: 3px 0; font-size: 0.9rem; color: #eee; }
.right { flex: 1; display: flex; flex-direction: column; }
.right p { font-size: 0.8rem; color: var(--gold); margin-bottom: 10px; }
.btn-join-list, .btn-admin-join-list {
width: 100%;
margin-bottom: 8px;
padding: 10px;
border-radius: 6px;
border: 1px solid var(--gold);
background: transparent;
color: var(--gold);
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
font-size: 0.7rem;
transition: 0.2s;
}
.btn-join-list:hover { background: var(--gold); color: black; }
.btn-admin-join-list { border-color: rgba(255,255,255,0.3); color: rgba(255,255,255,0.5); }
/* --- RESPONSIVE --- */
@media (max-width: 600px) {
.poker-table { border-radius: 40px; padding: 15px; border-width: 10px; }
.logo-paf { width: 160px; }
.btn-main-create { padding: 12px 25px; font-size: 1rem; }
}
+135 -135
View File
@@ -1,136 +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;
/* 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;
}
File diff suppressed because it is too large Load Diff
+152 -152
View File
@@ -1,152 +1,152 @@
/* --- gameMobile.css Refondu --- */
@media screen and (max-width: 900px) {
/* 1. Structure Globale : On bloque le défilement et on utilise tout l'écran */
body {
height: 100dvh; /* Utilise la hauteur réelle dynamique sur mobile */
overflow: hidden;
position: fixed;
width: 100%;
}
.game-container {
flex-direction: column;
height: 100%;
}
/* 2. La Table : Plus ronde (Arène) */
.table-container {
flex: 1;
padding: 40px 10px;
display: flex;
align-items: center;
justify-content: center;
min-height: 0;
}
.poker-table {
width: 100%;
max-width: 340px;
height: 240px; /* Un peu plus haute pour l'aspect rond */
border-width: 10px;
border-radius: 140px; /* Plus grand rayon pour arrondir les coins */
box-shadow: inset 0 0 30px rgba(0,0,0,0.8), 0 10px 20px rgba(0,0,0,0.5);
}
/* 3. Le Pot : Ajustement taille */
.total-pot {
font-size: 1.8rem;
}
.total-pot::before { font-size: 0.7rem; }
.current-bet-display { font-size: 0.8rem; }
/* 4. Les Joueurs : Positionnement Arène Symétrique */
.player-slot {
width: 78px;
}
.player-info {
padding: 4px;
border-radius: 12px;
border-width: 1px;
}
.player-name { font-size: 0.65rem; margin-bottom: 2px; }
.player-money { font-size: 0.8rem; }
.player-bet { font-size: 0.6rem; padding: 1px 5px; }
.dealer-badge {
width: 20px;
height: 20px;
font-size: 0.7rem;
top: -8px;
right: -8px;
}
/* --- POSITIONNEMENT DES SLOTS --- */
/* Haut et Bas Milieu */
.slot-0 { top: -50px; left: 50%; transform: translateX(-50%); }
.slot-4 { bottom: -50px; left: 50%; transform: translateX(-50%); }
/* Les 4 coins (Diagonales à distance égale) */
/* En haut à droite */
.slot-1 { top: 5%; right: -15px; }
/* En bas à droite */
.slot-3 { bottom: 5%; right: -15px; }
/* En bas à gauche */
.slot-5 { bottom: 5%; left: -15px; }
/* En haut à gauche */
.slot-7 { top: 5%; left: -15px; }
/* Milieux latéraux */
.slot-2 { top: 50%; right: -10px; transform: translateY(-50%); }
.slot-6 { top: 50%; left: -10px; transform: translateY(-50%); }
/* 5. Panneau d'Action : Le "Deck" du bas */
.action-panel {
width: 100% !important;
height: auto;
padding: 15px 10px 25px 10px;
border-left: none;
border-top: 2px solid var(--gold);
background: #151515;
}
.turn-info {
font-size: 0.9rem;
margin-bottom: 12px;
}
.action-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-areas:
"fold call"
"raise raise"
"allin allin"
"quit quit";
gap: 8px;
width: 100%;
}
.btn {
width: 100%;
padding: 12px 5px;
font-size: 0.8rem;
}
.btn-fold { grid-area: fold; }
.btn-call { grid-area: call; }
.raise-group {
grid-area: raise;
display: flex;
width: 100%;
}
.btn-allin { grid-area: allin; }
.btn-back {
grid-area: quit;
margin: 0;
background: rgba(255,0,0,0.1);
color: #ff4d4d;
opacity: 0.8;
}
#raise-amount { flex: 1; height: 40px; }
.btn-validate { width: 80px; }
}
/* 6. Optimisation Paysage (Landscape) */
@media screen and (max-height: 500px) and (orientation: landscape) {
.poker-table { height: 160px; max-width: 480px; border-radius: 100px; }
.player-slot { width: 70px; }
/* Ajustement slots en paysage pour ne pas sortir de l'écran */
.slot-1, .slot-7 { top: -10%; }
.slot-3, .slot-5 { bottom: -10%; }
.action-panel { padding: 5px; }
.action-buttons { grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-areas: none; }
.btn-allin, .raise-group, .btn-back { grid-column: auto; }
}
/* --- gameMobile.css Refondu --- */
@media screen and (max-width: 900px) {
/* 1. Structure Globale : On bloque le défilement et on utilise tout l'écran */
body {
height: 100dvh; /* Utilise la hauteur réelle dynamique sur mobile */
overflow: hidden;
position: fixed;
width: 100%;
}
.game-container {
flex-direction: column;
height: 100%;
}
/* 2. La Table : Plus ronde (Arène) */
.table-container {
flex: 1;
padding: 40px 10px;
display: flex;
align-items: center;
justify-content: center;
min-height: 0;
}
.poker-table {
width: 100%;
max-width: 340px;
height: 240px; /* Un peu plus haute pour l'aspect rond */
border-width: 10px;
border-radius: 140px; /* Plus grand rayon pour arrondir les coins */
box-shadow: inset 0 0 30px rgba(0,0,0,0.8), 0 10px 20px rgba(0,0,0,0.5);
}
/* 3. Le Pot : Ajustement taille */
.total-pot {
font-size: 1.8rem;
}
.total-pot::before { font-size: 0.7rem; }
.current-bet-display { font-size: 0.8rem; }
/* 4. Les Joueurs : Positionnement Arène Symétrique */
.player-slot {
width: 78px;
}
.player-info {
padding: 4px;
border-radius: 12px;
border-width: 1px;
}
.player-name { font-size: 0.65rem; margin-bottom: 2px; }
.player-money { font-size: 0.8rem; }
.player-bet { font-size: 0.6rem; padding: 1px 5px; }
.dealer-badge {
width: 20px;
height: 20px;
font-size: 0.7rem;
top: -8px;
right: -8px;
}
/* --- POSITIONNEMENT DES SLOTS --- */
/* Haut et Bas Milieu */
.slot-0 { top: -50px; left: 50%; transform: translateX(-50%); }
.slot-4 { bottom: -50px; left: 50%; transform: translateX(-50%); }
/* Les 4 coins (Diagonales à distance égale) */
/* En haut à droite */
.slot-1 { top: 5%; right: -15px; }
/* En bas à droite */
.slot-3 { bottom: 5%; right: -15px; }
/* En bas à gauche */
.slot-5 { bottom: 5%; left: -15px; }
/* En haut à gauche */
.slot-7 { top: 5%; left: -15px; }
/* Milieux latéraux */
.slot-2 { top: 50%; right: -10px; transform: translateY(-50%); }
.slot-6 { top: 50%; left: -10px; transform: translateY(-50%); }
/* 5. Panneau d'Action : Le "Deck" du bas */
.action-panel {
width: 100% !important;
height: auto;
padding: 15px 10px 25px 10px;
border-left: none;
border-top: 2px solid var(--gold);
background: #151515;
}
.turn-info {
font-size: 0.9rem;
margin-bottom: 12px;
}
.action-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-areas:
"fold call"
"raise raise"
"allin allin"
"quit quit";
gap: 8px;
width: 100%;
}
.btn {
width: 100%;
padding: 12px 5px;
font-size: 0.8rem;
}
.btn-fold { grid-area: fold; }
.btn-call { grid-area: call; }
.raise-group {
grid-area: raise;
display: flex;
width: 100%;
}
.btn-allin { grid-area: allin; }
.btn-back {
grid-area: quit;
margin: 0;
background: rgba(255,0,0,0.1);
color: #ff4d4d;
opacity: 0.8;
}
#raise-amount { flex: 1; height: 40px; }
.btn-validate { width: 80px; }
}
/* 6. Optimisation Paysage (Landscape) */
@media screen and (max-height: 500px) and (orientation: landscape) {
.poker-table { height: 160px; max-width: 480px; border-radius: 100px; }
.player-slot { width: 70px; }
/* Ajustement slots en paysage pour ne pas sortir de l'écran */
.slot-1, .slot-7 { top: -10%; }
.slot-3, .slot-5 { bottom: -10%; }
.action-panel { padding: 5px; }
.action-buttons { grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-areas: none; }
.btn-allin, .raise-group, .btn-back { grid-column: auto; }
}
+162 -162
View File
@@ -1,163 +1,163 @@
/* main.css - Sélection du Joueur Poker PAF */
:root {
--table-green: radial-gradient(circle, #277d46 0%, #1a5e33 100%);
--poker-border: #2c1b18;
--gold: #d4af37;
--gold-light: #f9e27d;
--dark-bg: #0a0a0a;
--white: #ffffff;
--wood-dark: #1a0f0d;
}
body {
background-color: var(--dark-bg);
background-image: radial-gradient(circle at center, #1a1a1a 0%, #050505 100%);
color: var(--white);
font-family: 'Segoe UI', Roboto, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
/* --- LE CONTENEUR TABLE --- */
.container {
background: var(--table-green);
padding: 40px;
border-radius: 40px;
border: 15px solid var(--poker-border);
box-shadow: 0 25px 50px rgba(0,0,0,0.9), inset 0 0 40px rgba(0,0,0,0.6);
text-align: center;
width: 95%;
max-width: 700px;
position: relative;
outline: 2px solid #3d2b27;
}
/* --- LE LISERÉ BLANC --- */
.container::before {
content: '';
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 30px;
pointer-events: none;
z-index: 1;
}
h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 1.6rem;
margin-bottom: 10px;
position: relative;
z-index: 2;
text-shadow: 2px 2px 0px rgba(0,0,0,0.8);
}
h2 {
font-size: 1.1rem;
color: var(--white);
margin-bottom: 5px;
position: relative;
z-index: 2;
}
p {
color: rgba(255,255,255,0.7);
font-size: 0.9rem;
margin-bottom: 30px;
position: relative;
z-index: 2;
}
/* --- GRILLE DE SÉLECTION DES JOUEURS --- */
.player-selection {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 15px;
position: relative;
z-index: 2;
}
.join-player-btn {
background: rgba(0, 0, 0, 0.4);
color: var(--gold);
border: 2px solid rgba(212, 175, 55, 0.3);
padding: 20px 10px;
border-radius: 12px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
transition: all 0.2s ease;
display: flex;
justify-content: center;
align-items: center;
min-height: 80px;
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
}
.join-player-btn:hover {
background: var(--gold);
color: var(--wood-dark);
transform: translateY(-3px);
border-color: var(--gold-light);
box-shadow: 0 8px 15px rgba(0,0,0,0.5);
}
/* Effet au clic */
.join-player-btn:active {
transform: translateY(0);
}
.back-btn {
position: absolute;
top: 25px;
left: 30px;
color: var(--gold);
background: none !important;
border: none !important;
font-weight: bold;
font-size: 0.8rem;
cursor: pointer;
z-index: 10;
opacity: 0.8;
transition: opacity 0.3s, transform 0.2s;
text-transform: uppercase;
display: flex;
align-items: center;
gap: 5px;
}
.back-btn:hover {
opacity: 1;
transform: translateX(-3px);
}
/* --- MOBILE --- */
@media (max-width: 600px) {
.container {
padding: 25px 15px;
border-width: 10px;
}
.player-selection {
grid-template-columns: repeat(2, 1fr); /* 2 colonnes sur mobile */
gap: 10px;
}
.back-btn {
position: relative;
top: 0;
left: 0;
margin-bottom: 20px;
justify-content: flex-start;
}
.join-player-btn {
padding: 15px 5px;
font-size: 0.9rem;
}
/* main.css - Sélection du Joueur Poker PAF */
:root {
--table-green: radial-gradient(circle, #277d46 0%, #1a5e33 100%);
--poker-border: #2c1b18;
--gold: #d4af37;
--gold-light: #f9e27d;
--dark-bg: #0a0a0a;
--white: #ffffff;
--wood-dark: #1a0f0d;
}
body {
background-color: var(--dark-bg);
background-image: radial-gradient(circle at center, #1a1a1a 0%, #050505 100%);
color: var(--white);
font-family: 'Segoe UI', Roboto, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
/* --- LE CONTENEUR TABLE --- */
.container {
background: var(--table-green);
padding: 40px;
border-radius: 40px;
border: 15px solid var(--poker-border);
box-shadow: 0 25px 50px rgba(0,0,0,0.9), inset 0 0 40px rgba(0,0,0,0.6);
text-align: center;
width: 95%;
max-width: 700px;
position: relative;
outline: 2px solid #3d2b27;
}
/* --- LE LISERÉ BLANC --- */
.container::before {
content: '';
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 30px;
pointer-events: none;
z-index: 1;
}
h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 1.6rem;
margin-bottom: 10px;
position: relative;
z-index: 2;
text-shadow: 2px 2px 0px rgba(0,0,0,0.8);
}
h2 {
font-size: 1.1rem;
color: var(--white);
margin-bottom: 5px;
position: relative;
z-index: 2;
}
p {
color: rgba(255,255,255,0.7);
font-size: 0.9rem;
margin-bottom: 30px;
position: relative;
z-index: 2;
}
/* --- GRILLE DE SÉLECTION DES JOUEURS --- */
.player-selection {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 15px;
position: relative;
z-index: 2;
}
.join-player-btn {
background: rgba(0, 0, 0, 0.4);
color: var(--gold);
border: 2px solid rgba(212, 175, 55, 0.3);
padding: 20px 10px;
border-radius: 12px;
cursor: pointer;
font-weight: bold;
font-size: 1rem;
transition: all 0.2s ease;
display: flex;
justify-content: center;
align-items: center;
min-height: 80px;
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
}
.join-player-btn:hover {
background: var(--gold);
color: var(--wood-dark);
transform: translateY(-3px);
border-color: var(--gold-light);
box-shadow: 0 8px 15px rgba(0,0,0,0.5);
}
/* Effet au clic */
.join-player-btn:active {
transform: translateY(0);
}
.back-btn {
position: absolute;
top: 25px;
left: 30px;
color: var(--gold);
background: none !important;
border: none !important;
font-weight: bold;
font-size: 0.8rem;
cursor: pointer;
z-index: 10;
opacity: 0.8;
transition: opacity 0.3s, transform 0.2s;
text-transform: uppercase;
display: flex;
align-items: center;
gap: 5px;
}
.back-btn:hover {
opacity: 1;
transform: translateX(-3px);
}
/* --- MOBILE --- */
@media (max-width: 600px) {
.container {
padding: 25px 15px;
border-width: 10px;
}
.player-selection {
grid-template-columns: repeat(2, 1fr); /* 2 colonnes sur mobile */
gap: 10px;
}
.back-btn {
position: relative;
top: 0;
left: 0;
margin-bottom: 20px;
justify-content: flex-start;
}
.join-player-btn {
padding: 15px 5px;
font-size: 0.9rem;
}
}
+105 -105
View File
@@ -1,106 +1,106 @@
// Fonction et variables essentiel
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
// ------------------------------------
function addPlayer() {
// 1. On récupère le conteneur
const container = document.getElementById('players_container');
// 2. On crée une nouvelle ligne
const newRow = document.createElement('div');
newRow.className = 'player-row';
console.log(container.children.length); // Affiche le nombre de joueurs actuels (pour le debug)
// 3. On met le HTML dedans (avec le bouton supprimer intégré)
newRow.innerHTML = `
<p>${container.children.length+1}</p>
<input type="text" name="players[]" placeholder="Nom du joueur" required>
<button type="button" onclick="removePlayer(this)">🗑️</button>
`;
// 4. On l'ajoute au conteneur
container.appendChild(newRow);
}
function removePlayer(btn) {
// On supprime le parent du bouton (la div 'player-row')
btn.parentElement.remove();
}
function deleteGame(idPartie) {
if (confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Tous les joueurs associés seront effacés.")) {
// On prépare les données à envoyer
let formData = new FormData();
formData.append('game_id', idPartie);
fetch('delete_game.php', {
method: 'POST',
body: formData // On envoie l'ID au PHP
})
.then(response => response.text())
.then(data => {
alert(data);
// Au lieu de reload, on peut rediriger vers l'accueil
window.location.href = 'index.php';
})
.catch(error => {
console.error('Erreur:', error);
alert('Impossible de supprimer la partie.');
});
}
}
const loginForm = document.getElementById('create_game_form');
loginForm.addEventListener('submit', async function(event) {
event.preventDefault();
const start_money = parseInt(this.querySelector('input[name="start_money"]').value);
const blind = parseInt(this.querySelector('input[name="blind"]').value);
const name = this.querySelector('input[name="game_name"]').value;
const players = this.querySelectorAll('input[name="players[]"]');
let response = await SqlRequest('createGame', {name: name, start_money: start_money, blind: blind});
console.log(response, response.success, response.game_id, parseInt(response.game_id));
if (response.success) {
const gameId = parseInt(response.game_id);
for (const player of players) {
await SqlRequest('addPlayer', {game_id: gameId, name: player.value, money: start_money});
}
const result = await SqlRequest('setFirstPlayer', {game_id: gameId})
console.log(result)
if (result.success) {
window.location.href = 'admin-login.html?game_id=' + gameId;
} else {
console.error("Erreur lors de la définition du premier joueur :", result.error);
}
} else {
console.error("Erreur lors de la création de la partie :", response.error);
}
// Fonction et variables essentiel
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
// ------------------------------------
function addPlayer() {
// 1. On récupère le conteneur
const container = document.getElementById('players_container');
// 2. On crée une nouvelle ligne
const newRow = document.createElement('div');
newRow.className = 'player-row';
console.log(container.children.length); // Affiche le nombre de joueurs actuels (pour le debug)
// 3. On met le HTML dedans (avec le bouton supprimer intégré)
newRow.innerHTML = `
<p>${container.children.length+1}</p>
<input type="text" name="players[]" placeholder="Nom du joueur" required>
<button type="button" onclick="removePlayer(this)">🗑️</button>
`;
// 4. On l'ajoute au conteneur
container.appendChild(newRow);
}
function removePlayer(btn) {
// On supprime le parent du bouton (la div 'player-row')
btn.parentElement.remove();
}
function deleteGame(idPartie) {
if (confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Tous les joueurs associés seront effacés.")) {
// On prépare les données à envoyer
let formData = new FormData();
formData.append('game_id', idPartie);
fetch('delete_game.php', {
method: 'POST',
body: formData // On envoie l'ID au PHP
})
.then(response => response.text())
.then(data => {
alert(data);
// Au lieu de reload, on peut rediriger vers l'accueil
window.location.href = 'index.php';
})
.catch(error => {
console.error('Erreur:', error);
alert('Impossible de supprimer la partie.');
});
}
}
const loginForm = document.getElementById('create_game_form');
loginForm.addEventListener('submit', async function(event) {
event.preventDefault();
const start_money = parseInt(this.querySelector('input[name="start_money"]').value);
const blind = parseInt(this.querySelector('input[name="blind"]').value);
const name = this.querySelector('input[name="game_name"]').value;
const players = this.querySelectorAll('input[name="players[]"]');
let response = await SqlRequest('createGame', {name: name, start_money: start_money, blind: blind});
console.log(response, response.success, response.game_id, parseInt(response.game_id));
if (response.success) {
const gameId = parseInt(response.game_id);
for (const player of players) {
await SqlRequest('addPlayer', {game_id: gameId, name: player.value, money: start_money});
}
const result = await SqlRequest('setFirstPlayer', {game_id: gameId})
console.log(result)
if (result.success) {
window.location.href = 'admin-login.html?game_id=' + gameId;
} else {
console.error("Erreur lors de la définition du premier joueur :", result.error);
}
} else {
console.error("Erreur lors de la création de la partie :", response.error);
}
});
+550 -550
View File
File diff suppressed because it is too large Load Diff
+91 -91
View File
@@ -1,91 +1,91 @@
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
window.onload = async function() {
loadData();
};
async function loadData() {
const container = document.getElementById('games_list');
const response = await SqlRequest('get_all_games');
const games = response.games;
if (Object.keys(games).length <= 0) {
container.innerHTML = "<p>Aucune partie en cours.</p>";
return;
}
let futurHtml = "";
for (const game of games) {
// 1. On récupère les joueurs de manière asynchrone AVANT de construire le HTML du jeu
const players = await getPlayers(game.id);
// 2. On prépare le HTML de la liste des joueurs
let playersHtml = "";
players.forEach(player => {
if (player.game_id === game.id) {
playersHtml += `<p>${player.name}</p>`;
}
});
// 3. On assemble le tout
futurHtml += `
<li>
<details class="mon-accordeon">
<summary>${game.name}</summary>
<div class='container-parent'>
<div class='right'>
<p>Start Money: ${game.start_money}</p>
<p>Blind: ${game.start_blind}</p>
<button class="btn-join-list" onclick="window.location.href='player-selector.php?game_id=${game.id}'">Rejoindre</button>
<button class="btn-admin-join-list" onclick="joinGameAsAdmin(${game.id})">Rejoindre en tant qu'Admin</button>
</div>
<div class='left'>
${playersHtml}
</div>
</div>
</details>
</li>
`;
}
container.innerHTML = '<ul>' + futurHtml + "</ul>";
}
async function getPlayers(id) {
const response = await SqlRequest('getPlayers', {game_id: id});
const players = response.players;
return players;
}
async function joinGameAsAdmin(gameId) {
// Redirige vers la page de connexion admin avec le gameId en paramètre
window.location.href = `admin-login.html?game_id=${gameId}`;
}
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
window.onload = async function() {
loadData();
};
async function loadData() {
const container = document.getElementById('games_list');
const response = await SqlRequest('get_all_games');
const games = response.games;
if (Object.keys(games).length <= 0) {
container.innerHTML = "<p>Aucune partie en cours.</p>";
return;
}
let futurHtml = "";
for (const game of games) {
// 1. On récupère les joueurs de manière asynchrone AVANT de construire le HTML du jeu
const players = await getPlayers(game.id);
// 2. On prépare le HTML de la liste des joueurs
let playersHtml = "";
players.forEach(player => {
if (player.game_id === game.id) {
playersHtml += `<p>${player.name}</p>`;
}
});
// 3. On assemble le tout
futurHtml += `
<li>
<details class="mon-accordeon">
<summary>${game.name}</summary>
<div class='container-parent'>
<div class='right'>
<p>Start Money: ${game.start_money}</p>
<p>Blind: ${game.start_blind}</p>
<button class="btn-join-list" onclick="window.location.href='player-selector.php?game_id=${game.id}'">Rejoindre</button>
<button class="btn-admin-join-list" onclick="joinGameAsAdmin(${game.id})">Rejoindre en tant qu'Admin</button>
</div>
<div class='left'>
${playersHtml}
</div>
</div>
</details>
</li>
`;
}
container.innerHTML = '<ul>' + futurHtml + "</ul>";
}
async function getPlayers(id) {
const response = await SqlRequest('getPlayers', {game_id: id});
const players = response.players;
return players;
}
async function joinGameAsAdmin(gameId) {
// Redirige vers la page de connexion admin avec le gameId en paramètre
window.location.href = `admin-login.html?game_id=${gameId}`;
}
+489 -489
View File
@@ -1,489 +1,489 @@
// Fonction et variables essentiel
const activePlayerLabel = document.getElementById('active-player-name');
let gameData = null;
let currentPlayer = null;
let playersData = [];
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
function startRealTimeSync(gameId) {
const evtSource = new EventSource(`stream.php?game_id=${gameId}`);
evtSource.onmessage = function(event) {
const data = JSON.parse(event.data);
// On met à jour nos variables globales avec les données fraîches du serveur
gameData = data.game;
playersData = data.players;
console.log("🔄 Table synchronisée");
// On rafraîchit l'affichage sans recharger la page
updateClientInterface();
};
evtSource.onerror = function() {
console.log("⚠️ Connexion perdue, tentative de reconnexion...");
};
}
// Fonction pour ouvrir le menu administrateur
function toggleAdminMenu() {
const menu = document.getElementById('admin-menu');
menu.classList.toggle('active');
}
// Fonctions pour démarrer la page
window.onload = async function() {
const urlParams = new URLSearchParams(window.location.search);
const gId = urlParams.get('game_id');
const result = await SqlRequest('is_admin');
console.log("Vérification des droits administrateur :", result);
if (!result.is_admin) {
alert("Vous n'avez pas les droits pour accéder à cette page.");
window.location.href = 'index.html';
}
gameData = await getGame();
playersData = await getPlayers();
document.getElementById('title_page').textContent = "Vue Administrateur - " + gameData.name + " - PokerPaf";
updateClientInterface();
startRealTimeSync(gId);
}
async function updateClientInterface() {
setupPlayers();
getCurrentPlayer();
refreshAdminPanel();
activePlayerLabel.textContent = `${currentPlayer.name} (${currentPlayer.money} 🪙)`;
}
function refreshAdminPanel() {
const adminPanel = document.getElementById('admin-lock-control');
if (!adminPanel) return;
let statsItem = document.getElementById('stat-item');
if (statsItem) {
statsItem.innerHTML = `
MISE ACTUELLE: <strong id="current-bet">${gameData.last_bet}</strong><br>
POT ACTUEL <strong id="current-pot">${gameData.pot}</strong>
`;
}
const isLocked = Number(gameData.is_locked) === 1;
let lockSwitch = document.getElementById('lock-switch');
// On ne crée le HTML que s'il n'existe pas encore
if (!lockSwitch) {
adminPanel.innerHTML = `
<div class="admin-control-group">
<span>Autoriser le jeu :</span>
<label class="switch">
<input type="checkbox" id="lock-switch" ${!isLocked ? 'checked' : ''} onchange="toggleGameLock(this)">
<span class="slider"></span>
</label>
</div>
`;
} else {
// Si le switch existe, on met à jour son état SEULEMENT si l'admin ne le touche pas
if (document.activeElement !== lockSwitch) {
lockSwitch.checked = !isLocked;
}
}
}
// Fonction pour envoyer l'ordre au serveur
async function toggleGameLock(checkbox) {
const status = checkbox.checked ? 0 : 1;
// 1. On change d'abord le statut de verrouillage
const response = await SqlRequest('toggle_lock', {
game_id: gameData.id,
status: status
});
if (response && response.success) {
// 2. Si on vient de DÉVERROUILLER (status 0), on reset le joueur actif
if (status === 0) {
console.log("🔓 Déverrouillage : Réinitialisation au joueur après le Dealer...");
await resetToPostDealerPlayer();
}
} else {
alert("Erreur lors du changement de statut");
checkbox.checked = !checkbox.checked;
}
}
async function resetToPostDealerPlayer() {
// On cherche l'index du dealer dans playersData
const dealerIndex = playersData.findIndex(p => Number(p.is_dealer) === 1);
// Le premier joueur à parler est (dealer + 1), mais on doit gérer la boucle du tableau
// et sauter les joueurs qui se sont couchés (is_folded)
let nextIndex = (dealerIndex + 1) % playersData.length;
// Sécurité : on cherche le prochain qui n'est pas couché
let attempts = 0;
while (playersData[nextIndex].is_folded && attempts < playersData.length) {
nextIndex = (nextIndex + 1) % playersData.length;
attempts++;
}
const firstPlayerId = playersData[nextIndex].id;
// On envoie l'ordre au serveur de mettre ce joueur en actif
await SqlRequest('set_current_player', {
game_id: gameData.id,
player_id: firstPlayerId
});
}
async function setupPlayers() {
const PokerTable = document.getElementById('table');
PokerTable.innerHTML = ''; // Clear existing players
let newHtml = ``;
newHtml += `
<div class="pot-area">
<div class="total-pot">${gameData.pot}</div>
<div id="Mise" class="current-bet-display">Mise: ${gameData.last_bet}</div>
</div>
`;
playersData.forEach((player, index) => {
// On s'assure de comparer avec le nombre 1 car la BDD renvoie souvent des strings ou des entiers
const isDealer = Number(player.is_dealer) === 1;
newHtml += `
<div class="player-slot slot-${index}${player.is_folded ? ' blur-effect' : ''}${player.money <= 0 ? ' All-in-Blur' : ''}" onclick="changePlayer(${player.id})" data-id="${player.id}">
<div class="player-info${gameData.current_player_id == player.id ? ' active' : ''}">
${isDealer ? '<div class="dealer-badge">D</div>' : ''}
<span class="player-name">J${index + 1} : ${player.name}</span>
<span class="player-money">${player.money} 🪙</span><br>
<span class="player-bet">Mise: ${player.current_bet} 🪙</span>
</div>
</div>
`;
});
PokerTable.innerHTML = newHtml;
}
async function getGame(id = null) {
let gameId;
if (id === null) {
const urlParams = new URLSearchParams(window.location.search);
gameId = urlParams.get('game_id');
} else {
gameId = id;
}
const response = await SqlRequest('getGame', { game_id: gameId });
if (response.success) {
return response.game;
} else {
console.error("Erreur lors de la récupération du jeu :", response.error);
return null;
}
}
async function getPlayers() {
const response = await SqlRequest('getPlayers', { game_id: gameData.id });
if (response.success) {
return response.players;
} else {
console.error("Erreur lors de la récupération des joueurs :", response.error);
return [];
}
}
async function getCurrentPlayer() {
currentPlayer = playersData.find(player => player.id === gameData.current_player_id);
}
// -----------------------------------------------------
// Fonctions pour les actions
async function changePlayer(id = null) {
if (id === null) {
const response = await SqlRequest('next_player', { game_id: gameData.id, current_player_id: gameData.current_player_id });
if (response.success) {
gameData.current_player_id = response.next_player_id;
} else {
console.error("Erreur lors du passage au joueur suivant :", response.error);
}
} else {
const response = await SqlRequest('set_current_player', { game_id: gameData.id, player_id: id });
if (response.success) {
gameData.current_player_id = id;
} else {
console.error("Erreur lors du changement de joueur :", response.error);
}
}
updateClientInterface();
}
async function playerFold() {
const response = await SqlRequest('fold', { player_id: gameData.current_player_id });
if (response.success) {
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du fold :", response.error);
}
}
async function playerRaise() {
const betAmount = parseInt(document.getElementById('raise-amount').value);
if (betAmount <= 0) {
alert("Veuillez entrer un montant de mise valide.");
return;
}
const amount = betAmount + gameData.last_bet - currentPlayer.current_bet;
if (currentPlayer.money < amount) {
alert("Vous n'avez pas assez d'argent pour cette mise.");
return;
}
const response = await SqlRequest('raise', { game_id: gameData.id, player_id: gameData.current_player_id, amount: amount, current_bet: currentPlayer.current_bet });
if (response.success) {
gameData.last_bet = currentPlayer.current_bet + amount;
gameData.pot += amount;
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du raise :", response.error);
}
}
async function playerFollow() {
if (currentPlayer.current_bet >= gameData.last_bet) {
changePlayer();
return;
}
let delta_amount = gameData.last_bet - currentPlayer.current_bet;
if (currentPlayer.money < delta_amount) {
delta_amount = currentPlayer.money;
}
const response = await SqlRequest('follow', { game_id: gameData.id, player_id: gameData.current_player_id, amount: delta_amount });
if (response.success) {
gameData.pot += delta_amount;
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du follow :", response.error);
}
}
async function playerAllIn() {
const response = await SqlRequest('all_in', { game_id: gameData.id, player_id: gameData.current_player_id });
if (response.success) {
gameData = await getGame(gameData.id);
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du all-in :", response.error);
}
}
// -----------------------------------------------------
// Fonctions pour les actions administratives
async function endGame() {
await SqlRequest('update_game_status', {
game_id: gameData.id,
status: 'deciding'
});
// 1. On vérifie si le panel existe déjà pour éviter les doublons
if (document.querySelector('.win-overlay')) return;
// 2. Création de l'overlay (on l'appelle win-overlay pour le CSS)
const winOverlay = document.createElement('div');
winOverlay.className = 'win-overlay';
// 3. Création du panel blanc/bleu
const winPanel = document.createElement('div');
winPanel.className = 'win-panel';
winPanel.innerHTML = `
<h2>🏆 La partie est terminée ! 🏆<br>Qui a gagné ?</h2>
<div id="winner-buttons-area"></div>
<button class="btn-spaction" onclick="this.parentElement.parentElement.remove()">Annuler</button>
`;
winOverlay.appendChild(winPanel);
// IMPORTANCE : On l'attache au BODY pour qu'il soit au-dessus de TOUT (même l'admin)
document.body.appendChild(winOverlay);
const area = document.getElementById('winner-buttons-area');
const playerElements = document.querySelectorAll('.player-slot');
playerElements.forEach(slot => {
const id = slot.getAttribute('data-id');
// On récupère le nom proprement
const nameElement = slot.querySelector('.player-name');
const name = nameElement ? nameElement.textContent.replace('VOUS', '').replace(':', '').trim() : "Joueur " + id;
const btn = document.createElement('button');
btn.className = 'btn-win';
btn.innerText = name;
btn.onclick = () => declareWinner(id);
area.appendChild(btn);
});
// On supprime la ligne qui cherchait 'end-game-screen' car winOverlay fait déjà le job
}
async function declareWinner(playerId) {
console.log("Début de la procédure de victoire...");
// 1. Première requête : On définit le gagnant
const resWinner = await SqlRequest('set_winner', {
game_id: gameData.id,
player_id: playerId
});
if (resWinner && resWinner.success) {
console.log("✅ Winner ID mis à jour en BDD");
// 2. Deuxième requête : On passe le statut à 'finished'
// C'est cette requête qui va déclencher l'écran de victoire chez les joueurs via le SSE
const resStatus = await SqlRequest('update_game_status', {
game_id: gameData.id,
status: 'finished'
});
if (resStatus && resStatus.success) {
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
showAdminWinPanel(playerId);
} else {
console.log("Dommage tu y étais presque")
}
}
} else {
alert("Erreur lors de la mise à jour du gagnant.");
}
}
// Fonction isolée pour l'affichage du panel admin (plus propre)
function showAdminWinPanel(playerId) {
const container = document.querySelector('.table-container');
if (container) container.classList.remove('blur-effect');
const winPanel = document.querySelector('.win-panel');
if (winPanel) {
const winner = playersData.find(p => p.id == playerId);
winPanel.innerHTML = `
<h2>🏆 Victoire de ${winner ? winner.name : 'Joueur'}</h2>
<p>Le pot de ${gameData.pot} 🪙 lui a été attribué.</p>
<button class="btn-spaction" onclick="StartNewGame()">Nouvelle Manche</button>
`;
}
}
async function StartNewGame() {
// 1. On force le verrouillage (status: 1) avant de relancer
try {
const response = await SqlRequest('toggle_lock', {
game_id: gameData.id,
status: 1 // 1 pour verrouillé
});
if (response.success) {
console.log("Partie verrouillée, relance en cours...");
// 2. On recharge la page pour démarrer la nouvelle main
const response = await SqlRequest('update_game_status', {
game_id: gameData.id,
status: 'playing'
});
if(response.success){
window.location.reload();
} else {
console.error("Erreur de changement de status :", response.error);
}
} else {
console.error("Erreur de verrouillage :", response.error);
// Optionnel : on recharge quand même ou on affiche une alerte
window.location.reload();
}
} catch (error) {
console.error("Erreur réseau :", error);
window.location.reload();
}
}
async function addMoney() {
let amount = parseInt(document.getElementById('money-amount').value);
if (isNaN(amount)) {
alert("Veuillez entrer un montant valide.");
return;
}
const response = await SqlRequest('add_money', { player_id: gameData.current_player_id, amount: amount });
if (response.success) {
playersData = await getPlayers();
updateClientInterface();
} else {
console.error("Erreur lors de l'ajout d'argent :", response.error);
}
}
async function deleteGame() {
const confirmation = confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Cette action est irréversible.");
if (!confirmation) return;
const response = await SqlRequest('delete_game', { game_id: gameData.id });
if (response.success) {
console.log("Partie supprimée avec succès.", response.success);
window.location.replace('index.html');
} else {
console.error("Erreur lors de la suppression du jeu :", response.error);
}
}
// Fonction et variables essentiel
const activePlayerLabel = document.getElementById('active-player-name');
let gameData = null;
let currentPlayer = null;
let playersData = [];
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
function startRealTimeSync(gameId) {
const evtSource = new EventSource(`stream.php?game_id=${gameId}`);
evtSource.onmessage = function(event) {
const data = JSON.parse(event.data);
// On met à jour nos variables globales avec les données fraîches du serveur
gameData = data.game;
playersData = data.players;
console.log("🔄 Table synchronisée");
// On rafraîchit l'affichage sans recharger la page
updateClientInterface();
};
evtSource.onerror = function() {
console.log("⚠️ Connexion perdue, tentative de reconnexion...");
};
}
// Fonction pour ouvrir le menu administrateur
function toggleAdminMenu() {
const menu = document.getElementById('admin-menu');
menu.classList.toggle('active');
}
// Fonctions pour démarrer la page
window.onload = async function() {
const urlParams = new URLSearchParams(window.location.search);
const gId = urlParams.get('game_id');
const result = await SqlRequest('is_admin');
console.log("Vérification des droits administrateur :", result);
if (!result.is_admin) {
alert("Vous n'avez pas les droits pour accéder à cette page.");
window.location.href = 'index.html';
}
gameData = await getGame();
playersData = await getPlayers();
document.getElementById('title_page').textContent = "Vue Administrateur - " + gameData.name + " - PokerPaf";
updateClientInterface();
startRealTimeSync(gId);
}
async function updateClientInterface() {
setupPlayers();
getCurrentPlayer();
refreshAdminPanel();
activePlayerLabel.textContent = `${currentPlayer.name} (${currentPlayer.money} 🪙)`;
}
function refreshAdminPanel() {
const adminPanel = document.getElementById('admin-lock-control');
if (!adminPanel) return;
let statsItem = document.getElementById('stat-item');
if (statsItem) {
statsItem.innerHTML = `
MISE ACTUELLE: <strong id="current-bet">${gameData.last_bet}</strong><br>
POT ACTUEL <strong id="current-pot">${gameData.pot}</strong>
`;
}
const isLocked = Number(gameData.is_locked) === 1;
let lockSwitch = document.getElementById('lock-switch');
// On ne crée le HTML que s'il n'existe pas encore
if (!lockSwitch) {
adminPanel.innerHTML = `
<div class="admin-control-group">
<span>Autoriser le jeu :</span>
<label class="switch">
<input type="checkbox" id="lock-switch" ${!isLocked ? 'checked' : ''} onchange="toggleGameLock(this)">
<span class="slider"></span>
</label>
</div>
`;
} else {
// Si le switch existe, on met à jour son état SEULEMENT si l'admin ne le touche pas
if (document.activeElement !== lockSwitch) {
lockSwitch.checked = !isLocked;
}
}
}
// Fonction pour envoyer l'ordre au serveur
async function toggleGameLock(checkbox) {
const status = checkbox.checked ? 0 : 1;
// 1. On change d'abord le statut de verrouillage
const response = await SqlRequest('toggle_lock', {
game_id: gameData.id,
status: status
});
if (response && response.success) {
// 2. Si on vient de DÉVERROUILLER (status 0), on reset le joueur actif
if (status === 0) {
console.log("🔓 Déverrouillage : Réinitialisation au joueur après le Dealer...");
await resetToPostDealerPlayer();
}
} else {
alert("Erreur lors du changement de statut");
checkbox.checked = !checkbox.checked;
}
}
async function resetToPostDealerPlayer() {
// On cherche l'index du dealer dans playersData
const dealerIndex = playersData.findIndex(p => Number(p.is_dealer) === 1);
// Le premier joueur à parler est (dealer + 1), mais on doit gérer la boucle du tableau
// et sauter les joueurs qui se sont couchés (is_folded)
let nextIndex = (dealerIndex + 1) % playersData.length;
// Sécurité : on cherche le prochain qui n'est pas couché
let attempts = 0;
while (playersData[nextIndex].is_folded && attempts < playersData.length) {
nextIndex = (nextIndex + 1) % playersData.length;
attempts++;
}
const firstPlayerId = playersData[nextIndex].id;
// On envoie l'ordre au serveur de mettre ce joueur en actif
await SqlRequest('set_current_player', {
game_id: gameData.id,
player_id: firstPlayerId
});
}
async function setupPlayers() {
const PokerTable = document.getElementById('table');
PokerTable.innerHTML = ''; // Clear existing players
let newHtml = ``;
newHtml += `
<div class="pot-area">
<div class="total-pot">${gameData.pot}</div>
<div id="Mise" class="current-bet-display">Mise: ${gameData.last_bet}</div>
</div>
`;
playersData.forEach((player, index) => {
// On s'assure de comparer avec le nombre 1 car la BDD renvoie souvent des strings ou des entiers
const isDealer = Number(player.is_dealer) === 1;
newHtml += `
<div class="player-slot slot-${index}${player.is_folded ? ' blur-effect' : ''}${player.money <= 0 ? ' All-in-Blur' : ''}" onclick="changePlayer(${player.id})" data-id="${player.id}">
<div class="player-info${gameData.current_player_id == player.id ? ' active' : ''}">
${isDealer ? '<div class="dealer-badge">D</div>' : ''}
<span class="player-name">J${index + 1} : ${player.name}</span>
<span class="player-money">${player.money} 🪙</span><br>
<span class="player-bet">Mise: ${player.current_bet} 🪙</span>
</div>
</div>
`;
});
PokerTable.innerHTML = newHtml;
}
async function getGame(id = null) {
let gameId;
if (id === null) {
const urlParams = new URLSearchParams(window.location.search);
gameId = urlParams.get('game_id');
} else {
gameId = id;
}
const response = await SqlRequest('getGame', { game_id: gameId });
if (response.success) {
return response.game;
} else {
console.error("Erreur lors de la récupération du jeu :", response.error);
return null;
}
}
async function getPlayers() {
const response = await SqlRequest('getPlayers', { game_id: gameData.id });
if (response.success) {
return response.players;
} else {
console.error("Erreur lors de la récupération des joueurs :", response.error);
return [];
}
}
async function getCurrentPlayer() {
currentPlayer = playersData.find(player => player.id === gameData.current_player_id);
}
// -----------------------------------------------------
// Fonctions pour les actions
async function changePlayer(id = null) {
if (id === null) {
const response = await SqlRequest('next_player', { game_id: gameData.id, current_player_id: gameData.current_player_id });
if (response.success) {
gameData.current_player_id = response.next_player_id;
} else {
console.error("Erreur lors du passage au joueur suivant :", response.error);
}
} else {
const response = await SqlRequest('set_current_player', { game_id: gameData.id, player_id: id });
if (response.success) {
gameData.current_player_id = id;
} else {
console.error("Erreur lors du changement de joueur :", response.error);
}
}
updateClientInterface();
}
async function playerFold() {
const response = await SqlRequest('fold', { player_id: gameData.current_player_id });
if (response.success) {
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du fold :", response.error);
}
}
async function playerRaise() {
const betAmount = parseInt(document.getElementById('raise-amount').value);
if (betAmount <= 0) {
alert("Veuillez entrer un montant de mise valide.");
return;
}
const amount = betAmount + gameData.last_bet - currentPlayer.current_bet;
if (currentPlayer.money < amount) {
alert("Vous n'avez pas assez d'argent pour cette mise.");
return;
}
const response = await SqlRequest('raise', { game_id: gameData.id, player_id: gameData.current_player_id, amount: amount, current_bet: currentPlayer.current_bet });
if (response.success) {
gameData.last_bet = currentPlayer.current_bet + amount;
gameData.pot += amount;
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du raise :", response.error);
}
}
async function playerFollow() {
if (currentPlayer.current_bet >= gameData.last_bet) {
changePlayer();
return;
}
let delta_amount = gameData.last_bet - currentPlayer.current_bet;
if (currentPlayer.money < delta_amount) {
delta_amount = currentPlayer.money;
}
const response = await SqlRequest('follow', { game_id: gameData.id, player_id: gameData.current_player_id, amount: delta_amount });
if (response.success) {
gameData.pot += delta_amount;
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du follow :", response.error);
}
}
async function playerAllIn() {
const response = await SqlRequest('all_in', { game_id: gameData.id, player_id: gameData.current_player_id });
if (response.success) {
gameData = await getGame(gameData.id);
playersData = await getPlayers();
changePlayer();
} else {
console.error("Erreur lors du all-in :", response.error);
}
}
// -----------------------------------------------------
// Fonctions pour les actions administratives
async function endGame() {
await SqlRequest('update_game_status', {
game_id: gameData.id,
status: 'deciding'
});
// 1. On vérifie si le panel existe déjà pour éviter les doublons
if (document.querySelector('.win-overlay')) return;
// 2. Création de l'overlay (on l'appelle win-overlay pour le CSS)
const winOverlay = document.createElement('div');
winOverlay.className = 'win-overlay';
// 3. Création du panel blanc/bleu
const winPanel = document.createElement('div');
winPanel.className = 'win-panel';
winPanel.innerHTML = `
<h2>🏆 La partie est terminée ! 🏆<br>Qui a gagné ?</h2>
<div id="winner-buttons-area"></div>
<button class="btn-spaction" onclick="this.parentElement.parentElement.remove()">Annuler</button>
`;
winOverlay.appendChild(winPanel);
// IMPORTANCE : On l'attache au BODY pour qu'il soit au-dessus de TOUT (même l'admin)
document.body.appendChild(winOverlay);
const area = document.getElementById('winner-buttons-area');
const playerElements = document.querySelectorAll('.player-slot');
playerElements.forEach(slot => {
const id = slot.getAttribute('data-id');
// On récupère le nom proprement
const nameElement = slot.querySelector('.player-name');
const name = nameElement ? nameElement.textContent.replace('VOUS', '').replace(':', '').trim() : "Joueur " + id;
const btn = document.createElement('button');
btn.className = 'btn-win';
btn.innerText = name;
btn.onclick = () => declareWinner(id);
area.appendChild(btn);
});
// On supprime la ligne qui cherchait 'end-game-screen' car winOverlay fait déjà le job
}
async function declareWinner(playerId) {
console.log("Début de la procédure de victoire...");
// 1. Première requête : On définit le gagnant
const resWinner = await SqlRequest('set_winner', {
game_id: gameData.id,
player_id: playerId
});
if (resWinner && resWinner.success) {
console.log("✅ Winner ID mis à jour en BDD");
// 2. Deuxième requête : On passe le statut à 'finished'
// C'est cette requête qui va déclencher l'écran de victoire chez les joueurs via le SSE
const resStatus = await SqlRequest('update_game_status', {
game_id: gameData.id,
status: 'finished'
});
if (resStatus && resStatus.success) {
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
showAdminWinPanel(playerId);
} else {
console.log("Dommage tu y étais presque")
}
}
} else {
alert("Erreur lors de la mise à jour du gagnant.");
}
}
// Fonction isolée pour l'affichage du panel admin (plus propre)
function showAdminWinPanel(playerId) {
const container = document.querySelector('.table-container');
if (container) container.classList.remove('blur-effect');
const winPanel = document.querySelector('.win-panel');
if (winPanel) {
const winner = playersData.find(p => p.id == playerId);
winPanel.innerHTML = `
<h2>🏆 Victoire de ${winner ? winner.name : 'Joueur'}</h2>
<p>Le pot de ${gameData.pot} 🪙 lui a été attribué.</p>
<button class="btn-spaction" onclick="StartNewGame()">Nouvelle Manche</button>
`;
}
}
async function StartNewGame() {
// 1. On force le verrouillage (status: 1) avant de relancer
try {
const response = await SqlRequest('toggle_lock', {
game_id: gameData.id,
status: 1 // 1 pour verrouillé
});
if (response.success) {
console.log("Partie verrouillée, relance en cours...");
// 2. On recharge la page pour démarrer la nouvelle main
const response = await SqlRequest('update_game_status', {
game_id: gameData.id,
status: 'playing'
});
if(response.success){
window.location.reload();
} else {
console.error("Erreur de changement de status :", response.error);
}
} else {
console.error("Erreur de verrouillage :", response.error);
// Optionnel : on recharge quand même ou on affiche une alerte
window.location.reload();
}
} catch (error) {
console.error("Erreur réseau :", error);
window.location.reload();
}
}
async function addMoney() {
let amount = parseInt(document.getElementById('money-amount').value);
if (isNaN(amount)) {
alert("Veuillez entrer un montant valide.");
return;
}
const response = await SqlRequest('add_money', { player_id: gameData.current_player_id, amount: amount });
if (response.success) {
playersData = await getPlayers();
updateClientInterface();
} else {
console.error("Erreur lors de l'ajout d'argent :", response.error);
}
}
async function deleteGame() {
const confirmation = confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Cette action est irréversible.");
if (!confirmation) return;
const response = await SqlRequest('delete_game', { game_id: gameData.id });
if (response.success) {
console.log("Partie supprimée avec succès.", response.success);
window.location.replace('index.html');
} else {
console.error("Erreur lors de la suppression du jeu :", response.error);
}
}
+403 -403
View File
@@ -1,404 +1,404 @@
<?php
// On commence par session_start AVANT tout envoi de texte
session_start();
header('Content-Type: application/json');
// Configuration BDD
$host = 'localhost';
$db = 'poker_paf';
$user = 'root';
$pass = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false,
];
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass, $options);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => 'Connexion échouée']);
exit;
}
// Lecture de l'input
$json = file_get_contents('php://input');
$data = json_decode($json, true);
if (!$data || !isset($data['action'])) {
echo json_encode(['success' => false, 'error' => 'Aucune action spécifiée']);
exit;
}
$action = $data['action'];
$params = $data['params'] ?? [];
switch ($action) {
case 'getGame':
$stmt = $pdo->prepare("SELECT * FROM games WHERE id = ?");
$stmt->execute([(int)$params['game_id']]);
$game = $stmt->fetch();
echo json_encode(['success' => true, 'game' => $game]);
exit;
case 'getPlayers':
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
$stmt->execute([(int)$params['game_id']]);
$players = $stmt->fetchAll();
echo json_encode(['success' => true, 'players' => $players]);
exit;
case 'createGame':
$stmt = $pdo->prepare("INSERT INTO games (start_money, start_blind, name) VALUES (?, ?, ?)");
$stmt->execute([(int)$params['start_money'], (int)$params['blind'], $params['name']]);
echo json_encode(['success' => true, 'game_id' => $pdo->lastInsertId()]);
exit;
case 'addPlayer':
$stmt = $pdo->prepare("INSERT INTO players (name, game_id, money) VALUES (?, ?, ?)");
$stmt->execute([$params['name'], (int)$params['game_id'], (int)$params['money']]);
echo json_encode(['success' => true]);
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':
$game_id = (int)$params['game_id'];
$current_id = (int)$params['current_player_id'];
// On cherche le prochain joueur (ID plus grand, non couché, pas ruiné)
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_folded = 0 AND money > 0 AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_id]);
$next = $stmt->fetch();
if (!$next) {
// Boucle : on revient au tout premier de la liste
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_folded = 0 AND money > 0 ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next = $stmt->fetch();
}
if ($next) {
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$next['id'], $game_id]);
echo json_encode(['success' => true, 'next_player_id' => $next['id']]);
} else {
echo json_encode(['success' => false, 'error' => 'Aucun joueur actif trouvé']);
}
exit;
case 'set_current_player':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$player_id, $game_id]);
echo json_encode(['success' => true]);
exit;
case 'fold':
$stmt = $pdo->prepare("UPDATE players SET is_folded = 1 WHERE id = ?");
$stmt->execute([(int)$params['player_id']]);
echo json_encode(['success' => true]);
exit;
case 'raise':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
$bet_input = (int)$params['bet_input'];
$stmt = $pdo->prepare("SELECT last_bet FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$last_bet_table = (int)$stmt->fetchColumn();
$stmt = $pdo->prepare("SELECT money, current_bet FROM players WHERE id = ?");
$stmt->execute([$player_id]);
$player = $stmt->fetch();
$target_bet = $last_bet_table + $bet_input;
$to_withdraw = $target_bet - (int)$player['current_bet'];
if ((int)$player['money'] < $to_withdraw) {
echo json_encode(['success' => false, 'error' => 'Fonds insuffisants']);
exit;
}
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE players SET money = money - ?, current_bet = ? WHERE id = ?");
$stmt->execute([$to_withdraw, $target_bet, $player_id]);
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ?, last_bet = ? WHERE id = ?");
$stmt->execute([$to_withdraw, $target_bet, $game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur transaction']);
}
exit;
case 'follow':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
$stmt = $pdo->prepare("SELECT last_bet FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$target = (int)$stmt->fetchColumn();
$stmt = $pdo->prepare("SELECT money, current_bet FROM players WHERE id = ?");
$stmt->execute([$player_id]);
$player = $stmt->fetch();
$to_pay = $target - (int)$player['current_bet'];
if ($to_pay > (int)$player['money']) {
echo json_encode(['success' => false, 'error' => 'Pas assez pour suivre, faites Tapis !']);
exit;
}
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE players SET money = money - ?, current_bet = ? WHERE id = ?");
$stmt->execute([$to_pay, $target, $player_id]);
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$to_pay, $game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur follow']);
}
exit;
case 'all_in':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
try {
$pdo->beginTransaction();
// 1. Récupérer les jetons restants du joueur
$stmt = $pdo->prepare("SELECT money, current_bet FROM players WHERE id = ?");
$stmt->execute([$player_id]);
$player = $stmt->fetch();
$all_in_amount = (int)$player['money'];
$new_player_bet = (int)$player['current_bet'] + $all_in_amount;
// 2. Le joueur mise TOUT : money tombe à 0
$stmt = $pdo->prepare("UPDATE players SET money = 0, current_bet = ? WHERE id = ?");
$stmt->execute([$new_player_bet, $player_id]);
// 3. Mise à jour de la table : on ajoute l'argent au pot
// Et on met à jour le 'last_bet' SEULEMENT si le tapis est supérieur à la mise actuelle
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ?, last_bet = GREATEST(last_bet, ?) WHERE id = ?");
$stmt->execute([$all_in_amount, $new_player_bet, $game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur All-in']);
}
exit;
case 'declare_winner':
$game_id = (int)$params['game_id'];
$winner_id = (int)$params['player_id'];
try {
$pdo->beginTransaction();
// 1. Récupérer le pot total
$stmt = $pdo->prepare("SELECT pot FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$pot = (int)$stmt->fetchColumn();
// 2. Donner le pot au gagnant et remettre ses stats à zéro pour le prochain tour
$stmt = $pdo->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$pot, $winner_id]);
// 3. Reset de la table (Pot et Mise à suivre)
$stmt = $pdo->prepare("UPDATE games SET pot = 0, last_bet = 0 WHERE id = ?");
$stmt->execute([$game_id]);
// 4. Reset de TOUS les joueurs (Mises engagées et Fold) en une seule requête
$stmt = $pdo->prepare("UPDATE players SET current_bet = 0, is_folded = 0 WHERE game_id = ?");
$stmt->execute([$game_id]);
// 5. Rotation du Dealer
// On cherche le dealer actuel
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_dealer = 1 LIMIT 1");
$stmt->execute([$game_id]);
$current_dealer = $stmt->fetchColumn();
if ($current_dealer) {
// On enlève l'ancien badge
$pdo->prepare("UPDATE players SET is_dealer = 0 WHERE id = ?")->execute([$current_dealer]);
// On cherche le suivant (ID plus grand)
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_dealer]);
$next_dealer = $stmt->fetchColumn();
// Si pas de suivant, on revient au premier
if (!$next_dealer) {
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next_dealer = $stmt->fetchColumn();
}
$pdo->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?")->execute([$next_dealer]);
}
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur lors de la désignation du vainqueur']);
}
exit;
case 'add_money':
$stmt = $pdo->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([(int)$params['amount'], (int)$params['player_id']]);
echo json_encode(['success' => true]);
exit;
case 'delete_game':
$game_id = (int)$params['game_id'];
try {
$pdo->beginTransaction();
$pdo->prepare("DELETE FROM players WHERE game_id = ?")->execute([$game_id]);
$pdo->prepare("DELETE FROM games WHERE id = ?")->execute([$game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false]);
}
exit;
case 'get_all_games':
$stmt = $pdo->query("SELECT * FROM games ORDER BY id ASC");
echo json_encode(['success' => true, 'games' => $stmt->fetchAll()]);
exit;
// Actions d'administration
case 'adminLogin':
$_SESSION['admin_logged_in'] = true;
echo json_encode(['success' => true]);
exit;
case 'is_admin':
echo json_encode([
'success' => true,
'is_admin' => (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true)
]);
exit;
case 'toggle_lock':
$game_id = (int)$params['game_id'];
$status = (int)$params['status']; // 1 pour verrouillé, 0 pour ouvert
$stmt = $pdo->prepare("UPDATE games SET is_locked = ? WHERE id = ?");
$stmt->execute([$status, $game_id]);
echo json_encode(['success' => true]);
exit;
case 'update_game_status':
$game_id = $params['game_id'];
$status = $params['status'];
$stmt = $pdo->prepare("UPDATE games SET status = ? WHERE id = ?");
$success = $stmt->execute([$status, $game_id]);
echo json_encode(['success' => $success]);
exit; // Important pour ne rien envoyer d'autre après
// --- ACTION 1 : Changer uniquement le statut (ex: 'deciding', 'playing') ---
case 'update_game_status':
$game_id = $params['game_id'] ?? 0;
$status = $params['status'] ?? '';
$stmt = $pdo->prepare("UPDATE games SET status = ? WHERE id = ?");
$success = $stmt->execute([$status, $game_id]);
echo json_encode(['success' => $success]);
exit;
// --- ACTION 2 : Enregistrer le gagnant ---
case 'set_winner':
$game_id = $params['game_id'] ?? 0;
$player_id = $params['player_id'] ?? 0;
// Ici on ne change QUE le winner_id
$stmt = $pdo->prepare("UPDATE games SET winner_id = ? WHERE id = ?");
$success = $stmt->execute([$player_id, $game_id]);
echo json_encode(['success' => $success]);
exit;
default:
echo json_encode(['success' => false, 'error' => 'Action inconnue']);
exit;
<?php
// On commence par session_start AVANT tout envoi de texte
session_start();
header('Content-Type: application/json');
// Configuration BDD
$host = 'localhost';
$db = 'poker_paf';
$user = 'root';
$pass = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_STRINGIFY_FETCHES => false,
];
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass, $options);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => 'Connexion échouée']);
exit;
}
// Lecture de l'input
$json = file_get_contents('php://input');
$data = json_decode($json, true);
if (!$data || !isset($data['action'])) {
echo json_encode(['success' => false, 'error' => 'Aucune action spécifiée']);
exit;
}
$action = $data['action'];
$params = $data['params'] ?? [];
switch ($action) {
case 'getGame':
$stmt = $pdo->prepare("SELECT * FROM games WHERE id = ?");
$stmt->execute([(int)$params['game_id']]);
$game = $stmt->fetch();
echo json_encode(['success' => true, 'game' => $game]);
exit;
case 'getPlayers':
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
$stmt->execute([(int)$params['game_id']]);
$players = $stmt->fetchAll();
echo json_encode(['success' => true, 'players' => $players]);
exit;
case 'createGame':
$stmt = $pdo->prepare("INSERT INTO games (start_money, start_blind, name) VALUES (?, ?, ?)");
$stmt->execute([(int)$params['start_money'], (int)$params['blind'], $params['name']]);
echo json_encode(['success' => true, 'game_id' => $pdo->lastInsertId()]);
exit;
case 'addPlayer':
$stmt = $pdo->prepare("INSERT INTO players (name, game_id, money) VALUES (?, ?, ?)");
$stmt->execute([$params['name'], (int)$params['game_id'], (int)$params['money']]);
echo json_encode(['success' => true]);
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':
$game_id = (int)$params['game_id'];
$current_id = (int)$params['current_player_id'];
// On cherche le prochain joueur (ID plus grand, non couché, pas ruiné)
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_folded = 0 AND money > 0 AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_id]);
$next = $stmt->fetch();
if (!$next) {
// Boucle : on revient au tout premier de la liste
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_folded = 0 AND money > 0 ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next = $stmt->fetch();
}
if ($next) {
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$next['id'], $game_id]);
echo json_encode(['success' => true, 'next_player_id' => $next['id']]);
} else {
echo json_encode(['success' => false, 'error' => 'Aucun joueur actif trouvé']);
}
exit;
case 'set_current_player':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
$stmt = $pdo->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$player_id, $game_id]);
echo json_encode(['success' => true]);
exit;
case 'fold':
$stmt = $pdo->prepare("UPDATE players SET is_folded = 1 WHERE id = ?");
$stmt->execute([(int)$params['player_id']]);
echo json_encode(['success' => true]);
exit;
case 'raise':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
$bet_input = (int)$params['bet_input'];
$stmt = $pdo->prepare("SELECT last_bet FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$last_bet_table = (int)$stmt->fetchColumn();
$stmt = $pdo->prepare("SELECT money, current_bet FROM players WHERE id = ?");
$stmt->execute([$player_id]);
$player = $stmt->fetch();
$target_bet = $last_bet_table + $bet_input;
$to_withdraw = $target_bet - (int)$player['current_bet'];
if ((int)$player['money'] < $to_withdraw) {
echo json_encode(['success' => false, 'error' => 'Fonds insuffisants']);
exit;
}
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE players SET money = money - ?, current_bet = ? WHERE id = ?");
$stmt->execute([$to_withdraw, $target_bet, $player_id]);
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ?, last_bet = ? WHERE id = ?");
$stmt->execute([$to_withdraw, $target_bet, $game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur transaction']);
}
exit;
case 'follow':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
$stmt = $pdo->prepare("SELECT last_bet FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$target = (int)$stmt->fetchColumn();
$stmt = $pdo->prepare("SELECT money, current_bet FROM players WHERE id = ?");
$stmt->execute([$player_id]);
$player = $stmt->fetch();
$to_pay = $target - (int)$player['current_bet'];
if ($to_pay > (int)$player['money']) {
echo json_encode(['success' => false, 'error' => 'Pas assez pour suivre, faites Tapis !']);
exit;
}
try {
$pdo->beginTransaction();
$stmt = $pdo->prepare("UPDATE players SET money = money - ?, current_bet = ? WHERE id = ?");
$stmt->execute([$to_pay, $target, $player_id]);
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$to_pay, $game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur follow']);
}
exit;
case 'all_in':
$game_id = (int)$params['game_id'];
$player_id = (int)$params['player_id'];
try {
$pdo->beginTransaction();
// 1. Récupérer les jetons restants du joueur
$stmt = $pdo->prepare("SELECT money, current_bet FROM players WHERE id = ?");
$stmt->execute([$player_id]);
$player = $stmt->fetch();
$all_in_amount = (int)$player['money'];
$new_player_bet = (int)$player['current_bet'] + $all_in_amount;
// 2. Le joueur mise TOUT : money tombe à 0
$stmt = $pdo->prepare("UPDATE players SET money = 0, current_bet = ? WHERE id = ?");
$stmt->execute([$new_player_bet, $player_id]);
// 3. Mise à jour de la table : on ajoute l'argent au pot
// Et on met à jour le 'last_bet' SEULEMENT si le tapis est supérieur à la mise actuelle
$stmt = $pdo->prepare("UPDATE games SET pot = pot + ?, last_bet = GREATEST(last_bet, ?) WHERE id = ?");
$stmt->execute([$all_in_amount, $new_player_bet, $game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur All-in']);
}
exit;
case 'declare_winner':
$game_id = (int)$params['game_id'];
$winner_id = (int)$params['player_id'];
try {
$pdo->beginTransaction();
// 1. Récupérer le pot total
$stmt = $pdo->prepare("SELECT pot FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$pot = (int)$stmt->fetchColumn();
// 2. Donner le pot au gagnant et remettre ses stats à zéro pour le prochain tour
$stmt = $pdo->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$pot, $winner_id]);
// 3. Reset de la table (Pot et Mise à suivre)
$stmt = $pdo->prepare("UPDATE games SET pot = 0, last_bet = 0 WHERE id = ?");
$stmt->execute([$game_id]);
// 4. Reset de TOUS les joueurs (Mises engagées et Fold) en une seule requête
$stmt = $pdo->prepare("UPDATE players SET current_bet = 0, is_folded = 0 WHERE game_id = ?");
$stmt->execute([$game_id]);
// 5. Rotation du Dealer
// On cherche le dealer actuel
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND is_dealer = 1 LIMIT 1");
$stmt->execute([$game_id]);
$current_dealer = $stmt->fetchColumn();
if ($current_dealer) {
// On enlève l'ancien badge
$pdo->prepare("UPDATE players SET is_dealer = 0 WHERE id = ?")->execute([$current_dealer]);
// On cherche le suivant (ID plus grand)
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_dealer]);
$next_dealer = $stmt->fetchColumn();
// Si pas de suivant, on revient au premier
if (!$next_dealer) {
$stmt = $pdo->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next_dealer = $stmt->fetchColumn();
}
$pdo->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?")->execute([$next_dealer]);
}
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false, 'error' => 'Erreur lors de la désignation du vainqueur']);
}
exit;
case 'add_money':
$stmt = $pdo->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([(int)$params['amount'], (int)$params['player_id']]);
echo json_encode(['success' => true]);
exit;
case 'delete_game':
$game_id = (int)$params['game_id'];
try {
$pdo->beginTransaction();
$pdo->prepare("DELETE FROM players WHERE game_id = ?")->execute([$game_id]);
$pdo->prepare("DELETE FROM games WHERE id = ?")->execute([$game_id]);
$pdo->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
if ($pdo->inTransaction()) $pdo->rollBack();
echo json_encode(['success' => false]);
}
exit;
case 'get_all_games':
$stmt = $pdo->query("SELECT * FROM games ORDER BY id ASC");
echo json_encode(['success' => true, 'games' => $stmt->fetchAll()]);
exit;
// Actions d'administration
case 'adminLogin':
$_SESSION['admin_logged_in'] = true;
echo json_encode(['success' => true]);
exit;
case 'is_admin':
echo json_encode([
'success' => true,
'is_admin' => (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true)
]);
exit;
case 'toggle_lock':
$game_id = (int)$params['game_id'];
$status = (int)$params['status']; // 1 pour verrouillé, 0 pour ouvert
$stmt = $pdo->prepare("UPDATE games SET is_locked = ? WHERE id = ?");
$stmt->execute([$status, $game_id]);
echo json_encode(['success' => true]);
exit;
case 'update_game_status':
$game_id = $params['game_id'];
$status = $params['status'];
$stmt = $pdo->prepare("UPDATE games SET status = ? WHERE id = ?");
$success = $stmt->execute([$status, $game_id]);
echo json_encode(['success' => $success]);
exit; // Important pour ne rien envoyer d'autre après
// --- ACTION 1 : Changer uniquement le statut (ex: 'deciding', 'playing') ---
case 'update_game_status':
$game_id = $params['game_id'] ?? 0;
$status = $params['status'] ?? '';
$stmt = $pdo->prepare("UPDATE games SET status = ? WHERE id = ?");
$success = $stmt->execute([$status, $game_id]);
echo json_encode(['success' => $success]);
exit;
// --- ACTION 2 : Enregistrer le gagnant ---
case 'set_winner':
$game_id = $params['game_id'] ?? 0;
$player_id = $params['player_id'] ?? 0;
// Ici on ne change QUE le winner_id
$stmt = $pdo->prepare("UPDATE games SET winner_id = ? WHERE id = ?");
$success = $stmt->execute([$player_id, $game_id]);
echo json_encode(['success' => $success]);
exit;
default:
echo json_encode(['success' => false, 'error' => 'Action inconnue']);
exit;
}
+73 -73
View File
@@ -1,73 +1,73 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title id="title_page"></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' type='text/css' href='css/game.css' deffer>
<link rel='stylesheet' type='text/css' href='css/gameMobile.css' deffer>
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js"></script>
</head>
<body>
<div class="game-container">
<button class="admin-toggle" onclick="toggleAdminMenu()">⚙️ Admin</button>
<div id="admin-menu" class="admin-overlay">
<div class="admin-content">
<button class="close-admin" onclick="toggleAdminMenu()"></button>
<h3>Administration de la Table</h3>
<div class="admin-section">
<div id="admin-lock-control" class="admin-section">
</div>
<label>Ajouter jetons au joueur actif</label>
<div class="money-group">
<input type="number" id="money-amount" placeholder="Montant">
<button class="btn-validate" onclick="addMoney()">OK</button>
</div>
</div>
<div class="stat-item"id="stat-item">
MISE ACTUELLE: <strong id="current-bet">0</strong><br>
POT ACTUEL <strong id="current-pot">0</strong>
</div>
<div class="admin-actions">
<button onclick="changePlayer()" class="btn-spaction">Joueur suivant</button>
<button onclick="endGame()" class="btn-spaction">Terminer la partie</button>
<button onclick="deleteGame()" class="btn-spaction btn-danger">Fermer la table</button>
</div>
<a href="index.html" class="btn-back-home">◀️ Quitter la partie</a>
</div>
</div>
<div class="table-container">
<div class="poker-table" id="table">
<div class="pot-area">
<div class="total-pot"></div>
<div id="Mise" class="current-bet-display">Mise: </div>
</div>
</div>
</div>
<div class="action-panel">
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
<div class="action-buttons">
<button class="btn btn-fold" onclick="playerFold()">Se coucher</button>
<button class="btn btn-call" onclick="playerFollow()">Suivre</button>
<div class="raise-group">
<input type="number" id="raise-amount" placeholder="Mise" min="0">
<button class="btn-validate" onclick="playerRaise()">OK</button>
</div>
<button class="btn btn-allin" onclick="playerAllIn()">TAPIS</button>
</div>
</div>
</div>
</body>
<script src="js/admin-game.js"></script>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title id="title_page"></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' type='text/css' href='css/game.css' deffer>
<link rel='stylesheet' type='text/css' href='css/gameMobile.css' deffer>
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js"></script>
</head>
<body>
<div class="game-container">
<button class="admin-toggle" onclick="toggleAdminMenu()">⚙️ Admin</button>
<div id="admin-menu" class="admin-overlay">
<div class="admin-content">
<button class="close-admin" onclick="toggleAdminMenu()"></button>
<h3>Administration de la Table</h3>
<div class="admin-section">
<div id="admin-lock-control" class="admin-section">
</div>
<label>Ajouter jetons au joueur actif</label>
<div class="money-group">
<input type="number" id="money-amount" placeholder="Montant">
<button class="btn-validate" onclick="addMoney()">OK</button>
</div>
</div>
<div class="stat-item"id="stat-item">
MISE ACTUELLE: <strong id="current-bet">0</strong><br>
POT ACTUEL <strong id="current-pot">0</strong>
</div>
<div class="admin-actions">
<button onclick="changePlayer()" class="btn-spaction">Joueur suivant</button>
<button onclick="endGame()" class="btn-spaction">Terminer la partie</button>
<button onclick="deleteGame()" class="btn-spaction btn-danger">Fermer la table</button>
</div>
<a href="index.html" class="btn-back-home">◀️ Quitter la partie</a>
</div>
</div>
<div class="table-container">
<div class="poker-table" id="table">
<div class="pot-area">
<div class="total-pot"></div>
<div id="Mise" class="current-bet-display">Mise: </div>
</div>
</div>
</div>
<div class="action-panel">
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
<div class="action-buttons">
<button class="btn btn-fold" onclick="playerFold()">Se coucher</button>
<button class="btn btn-call" onclick="playerFollow()">Suivre</button>
<div class="raise-group">
<input type="number" id="raise-amount" placeholder="Mise" min="0">
<button class="btn-validate" onclick="playerRaise()">OK</button>
</div>
<button class="btn btn-allin" onclick="playerAllIn()">TAPIS</button>
</div>
</div>
</div>
</body>
<script src="js/admin-game.js"></script>
</html>
+73 -73
View File
@@ -1,74 +1,74 @@
<html></html>
<head>
<title>Connexion Administrateur - PokerPaf</title>
<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>
<meta charset='utf-8'>
</head>
<body>
<div class="login-container">
<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>
<input type="password" id="adminPassword" name="adminPassword" required="" placeholder="••••••••">
<button type="submit">Accéder au Panneau</button>
</form>
</div>
<script>
const hashedAdminPassword = "7215d31f702fe2faf2a7df114c6427007bd254740c6b9cbaa2a5505060088929";
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
// Récupérer le formulaire de admin-login
const adminLoginForm = document.getElementById('admin-login-form');
adminLoginForm.addEventListener('submit', async function(event) {
event.preventDefault();
const password = this.querySelector('input[type="password"]').value;
const urlParams = new URLSearchParams(window.location.search);
const gameId = urlParams.get('game_id');
// Vérification du mot de passe
const hashedInputPassword = CryptoJS.SHA256(password).toString();
if (hashedInputPassword !== hashedAdminPassword) {
alert("Mot de passe incorrect. Veuillez réessayer.");
return;
}
// Requete SQL pour définir l'utilisateur comme admin du jeu
const response = await SqlRequest('adminLogin', {game_id: gameId});
if (response.success) {
window.location.href = `admin-game.html?game_id=${gameId}`; // Redirige vers la page d'administration du jeu
} else {
alert("Erreur lors de la connexion. Veuillez réessayer."); // Affiche une alerte en cas d'erreur
}
});
</script>
</body>
<html></html>
<head>
<title>Connexion Administrateur - PokerPaf</title>
<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>
<meta charset='utf-8'>
</head>
<body>
<div class="login-container">
<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>
<input type="password" id="adminPassword" name="adminPassword" required="" placeholder="••••••••">
<button type="submit">Accéder au Panneau</button>
</form>
</div>
<script>
const hashedAdminPassword = "7215d31f702fe2faf2a7df114c6427007bd254740c6b9cbaa2a5505060088929";
async function SqlRequest(action, params = {}) {
try {
const response = await fetch('RequestsHandler.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
action: action,
params: params
})
});
const resultat = await response.json();
if (resultat.success) {
return resultat;
} else {
console.error("Erreur :", resultat.error);
}
} catch (erreur) {
console.error("Erreur de communication :", erreur);
}
}
// Récupérer le formulaire de admin-login
const adminLoginForm = document.getElementById('admin-login-form');
adminLoginForm.addEventListener('submit', async function(event) {
event.preventDefault();
const password = this.querySelector('input[type="password"]').value;
const urlParams = new URLSearchParams(window.location.search);
const gameId = urlParams.get('game_id');
// Vérification du mot de passe
const hashedInputPassword = CryptoJS.SHA256(password).toString();
if (hashedInputPassword !== hashedAdminPassword) {
alert("Mot de passe incorrect. Veuillez réessayer.");
return;
}
// Requete SQL pour définir l'utilisateur comme admin du jeu
const response = await SqlRequest('adminLogin', {game_id: gameId});
if (response.success) {
window.location.href = `admin-game.html?game_id=${gameId}`; // Redirige vers la page d'administration du jeu
} else {
alert("Erreur lors de la connexion. Veuillez réessayer."); // Affiche une alerte en cas d'erreur
}
});
</script>
</body>
</html>
+42 -42
View File
@@ -1,43 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Créer une partie - PokerPaf</title>
<style>
.player-row { margin-bottom: 10px; }
</style>
<link rel="stylesheet" href="css/config.css">
</head>
<body>
<div class="container">
<button onclick="window.location.href='index.html'" class="btn-back">◀️ Accueil</button>
<h1>Configuration de la partie</h1>
<form id="create_game_form">
<label>Nom de partie :</label>
<input type="text" name="game_name" placeholder="Nom de partie" required><br><br>
<label>Somme de départ :</label>
<input type="number" name="start_money" value="1000" required><br><br>
<label>Blind :</label>
<input type="number" name="blind" value="20" required><br><br>
<label>Joueurs :</label>
<label class="info">(Maximum 8 joueurs)</label><br>
<div id="players_container">
<div class="player-row">
<p>1</p><input type="text" name="players[]" placeholder="Nom du joueur" required>
</div>
</div>
<br>
<button type="button" onclick="addPlayer()"> Ajouter un joueur</button>
<br>
<input type="submit" value="Démarrer la partie">
</form>
</div>
</body>
<script src="js/config.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Créer une partie - PokerPaf</title>
<style>
.player-row { margin-bottom: 10px; }
</style>
<link rel="stylesheet" href="css/config.css">
</head>
<body>
<div class="container">
<button onclick="window.location.href='index.html'" class="btn-back">◀️ Accueil</button>
<h1>Configuration de la partie</h1>
<form id="create_game_form">
<label>Nom de partie :</label>
<input type="text" name="game_name" placeholder="Nom de partie" required><br><br>
<label>Somme de départ :</label>
<input type="number" name="start_money" value="1000" required><br><br>
<label>Blind :</label>
<input type="number" name="blind" value="20" required><br><br>
<label>Joueurs :</label>
<label class="info">(Maximum 8 joueurs)</label><br>
<div id="players_container">
<div class="player-row">
<p>1</p><input type="text" name="players[]" placeholder="Nom du joueur" required>
</div>
</div>
<br>
<button type="button" onclick="addPlayer()"> Ajouter un joueur</button>
<br>
<input type="submit" value="Démarrer la partie">
</form>
</div>
</body>
<script src="js/config.js"></script>
</html>
+45 -45
View File
@@ -1,45 +1,45 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title id="title_page"></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' type='text/css' href='css/game.css' deffer>
<link rel='stylesheet' type='text/css' href='css/gameMobile.css' deffer>
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js"></script>
</head>
<body>
<div class="game-container">
<div class="table-container">
<div class="poker-table" id="table">
<div class="pot-area">
<div class="total-pot"></div>
<div id="Mise" class="current-bet-display">Mise: </div>
</div>
</div>
</div>
<div class="action-panel">
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
<div class="action-buttons">
<button class="btn btn-fold" id="btn-fold" onclick="playerFold()">Se coucher</button>
<button class="btn btn-call" id="btn-call" onclick="playerFollow()">Suivre</button>
<div class="raise-group">
<input type="number" id="raise-amount" placeholder="Mise" min="0">
<button class="btn-validate" onclick="playerRaise()">OK</button>
</div>
<button class="btn btn-allin" onclick="playerAllIn()">TAPIS</button>
<br><br>
<a href="index.html" class="btn-back">◀️ Quitter</a>
</div>
</div>
</div>
</body>
<script src="js/game.js"></script>
</html>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title id="title_page"></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel='stylesheet' type='text/css' href='css/game.css' deffer>
<link rel='stylesheet' type='text/css' href='css/gameMobile.css' deffer>
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.5.1/dist/confetti.browser.min.js"></script>
</head>
<body>
<div class="game-container">
<div class="table-container">
<div class="poker-table" id="table">
<div class="pot-area">
<div class="total-pot"></div>
<div id="Mise" class="current-bet-display">Mise: </div>
</div>
</div>
</div>
<div class="action-panel">
<p class="turn-info">Au tour de : <strong id="active-player-name"></strong></p>
<div class="action-buttons">
<button class="btn btn-fold" id="btn-fold" onclick="playerFold()">Se coucher</button>
<button class="btn btn-call" id="btn-call" onclick="playerFollow()">Suivre</button>
<div class="raise-group">
<input type="number" id="raise-amount" placeholder="Mise" min="0">
<button class="btn-validate" onclick="playerRaise()">OK</button>
</div>
<button class="btn btn-allin" onclick="playerAllIn()">TAPIS</button>
<br><br>
<a href="index.html" class="btn-back">◀️ Quitter</a>
</div>
</div>
</div>
</body>
<script src="js/game.js"></script>
</html>
+39 -39
View File
@@ -1,40 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Accueil - PokerPaf</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='css/index.css'>
<link rel="icon" type="image/x-icon" href="favicon.png">
</head>
<body>
<div class="main-wrapper">
<header class="poker-table table-header">
<div class="table-inner">
<h1>Welcome to</h1>
<div class="logo-wrapper">
<img src="favicon.png" alt="Poker PAF Logo" class="logo-paf">
</div>
</div>
</header>
<div class="tables-hall">
<div class="poker-table table-main">
<div class="table-inner">
<div class="button-center-wrapper">
<button class="btn-main-create" onclick="window.location.href='config.html'">
Créer une partie
</button>
</div>
<h2>Parties en cours</h2>
<div id="games_list">
</div>
</div>
</div>
</div>
</div>
<script src="js/index.js"></script>
</body>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Accueil - PokerPaf</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='css/index.css'>
<link rel="icon" type="image/x-icon" href="favicon.png">
</head>
<body>
<div class="main-wrapper">
<header class="poker-table table-header">
<div class="table-inner">
<h1>Welcome to</h1>
<div class="logo-wrapper">
<img src="favicon.png" alt="Poker PAF Logo" class="logo-paf">
</div>
</div>
</header>
<div class="tables-hall">
<div class="poker-table table-main">
<div class="table-inner">
<div class="button-center-wrapper">
<button class="btn-main-create" onclick="window.location.href='config.html'">
Créer une partie
</button>
</div>
<h2>Parties en cours</h2>
<div id="games_list">
</div>
</div>
</div>
</div>
</div>
<script src="js/index.js"></script>
</body>
</html>
+172 -172
View File
@@ -1,173 +1,173 @@
/* Le panneau qui contient tout le message de fin */
/* Le rideau qui floute l'arrière-plan */
.win-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7); /* Fond noir semi-transparent */
backdrop-filter: blur(8px); /* C'est ici qu'on met le flou ! */
z-index: 9998; /* Juste en dessous du panel */
display: flex;
justify-content: center;
align-items: center;
}
/* On ajuste le win-panel pour qu'il soit propre à l'intérieur */
.win-panel {
position: relative; /* Plus besoin de fixed ici car l'overlay l'est déjà */
background: #1a1a1a;
padding: 40px;
border-radius: 20px;
border: 3px solid #ffd700;
box-shadow: 0 0 50px rgba(0, 0, 0, 1);
z-index: 9999;
text-align: center;
min-width: 400px;
display: flex;
flex-direction: column;
gap: 25px;
}
/* Le titre dans le panel */
.win-panel h2 {
color: #fff;
margin: 0;
font-family: 'Arial Black', sans-serif;
text-transform: uppercase;
line-height: 1.4;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
/* Zone qui contient les boutons des joueurs */
#winner-buttons-area {
display: flex;
flex-wrap: wrap; /* Si beaucoup de joueurs, ils vont à la ligne */
justify-content: center;
gap: 15px;
width: 100%;
}
/* Tes boutons .btn-win (on réutilise le style Or précédent) */
.btn-win {
background: linear-gradient(to bottom, #ffd700, #b8860b);
border: 2px solid #8b4513;
color: #000;
padding: 15px 30px;
font-weight: bold;
cursor: pointer;
border-radius: 8px;
transition: transform 0.2s;
}
.btn-win:hover {
transform: scale(1.1);
}
.btn-win:active {
transform: translateY(3px);
box-shadow: 0 1px 0 #5d2e0a;
}
/* Base commune pour tous les boutons de l'interface */
.btn-back, .btn-replay {
border-radius: 8px;
color: white;
cursor: pointer;
font-size: 1rem;
font-weight: bold;
padding: 10px 20px;
text-transform: uppercase;
transition: all 0.2s ease;
border: 2px solid rgba(0,0,0,0.2);
}
/* Style spécifique : Retour (Style plus sobre / Alerte) */
.btn-back {
background: linear-gradient(to bottom, #d9534f, #a94442); /* Rouge profond */
box-shadow: 0 4px 0 #7b2e2c;
}
.btn-back:hover {
filter: brightness(1.1);
transform: translateY(-2px);
box-shadow: 0 6px 0 #7b2e2c;
}
/* Style spécifique : Rejouer (Style Action / Casino) */
.btn-replay {
background: linear-gradient(to bottom, #5bc0de, #2aabd2); /* Bleu électrique */
box-shadow: 0 4px 0 #1b728c;
}
.btn-replay:hover {
filter: brightness(1.1);
transform: translateY(-2px);
box-shadow: 0 6px 0 #1b728c;
}
/* Animation au clic pour les deux */
.btn-back:active, .btn-replay:active {
transform: translateY(3px);
box-shadow: 0 1px 0 rgba(0,0,0,0.5);
}
.blur-effect {
filter: blur(5px);
pointer-events: none; /* Empêche de cliquer sur la table derrière */
}
/* Le conteneur avec la bordure dorée fine */
.money-group {
display: inline-flex;
align-items: stretch; /* Force le bouton à prendre toute la hauteur */
background: #1e1e1e; /* Fond très sombre pour faire ressortir l'or */
border: 1px solid #c5a059; /* Bordure Or mat (plus sobre que le jaune brillant) */
border-radius: 8px;
overflow: hidden; /* Pour que le bouton épouse l'arrondi de la bordure */
height: 40px; /* Hauteur fixe pour un look plus pro */
}
/* Le champ de saisie */
#money-amount {
background: transparent;
border: none;
color: #ffffff;
font-size: 1rem;
padding: 0 15px;
width: 100px; /* Ajustable selon tes besoins */
outline: none;
}
/* Le bouton OK qui occupe tout l'espace à droite */
.btn-money {
background: linear-gradient(45deg, #d4af37, #f9e27d); /* Fond Or mat */
border: none;
color: #1e1e1e; /* Texte sombre pour le contraste */
cursor: pointer;
font-weight: 800;
padding: 0 20px; /* Largeur du bouton */
text-transform: uppercase;
transition: background 0.2s ease;
display: flex;
align-items: center; /* Centre le texte "OK" verticalement */
}
.btn-money:hover {
filter: brightness(1.2); /* Or un peu plus clair au survol */
}
.btn-money:active {
filter: brightness(0.8); /* Or plus sombre au clic */
}
/* Suppression des flèches de l'input */
#money-amount::-webkit-inner-spin-button,
#money-amount::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
/* Le panneau qui contient tout le message de fin */
/* Le rideau qui floute l'arrière-plan */
.win-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7); /* Fond noir semi-transparent */
backdrop-filter: blur(8px); /* C'est ici qu'on met le flou ! */
z-index: 9998; /* Juste en dessous du panel */
display: flex;
justify-content: center;
align-items: center;
}
/* On ajuste le win-panel pour qu'il soit propre à l'intérieur */
.win-panel {
position: relative; /* Plus besoin de fixed ici car l'overlay l'est déjà */
background: #1a1a1a;
padding: 40px;
border-radius: 20px;
border: 3px solid #ffd700;
box-shadow: 0 0 50px rgba(0, 0, 0, 1);
z-index: 9999;
text-align: center;
min-width: 400px;
display: flex;
flex-direction: column;
gap: 25px;
}
/* Le titre dans le panel */
.win-panel h2 {
color: #fff;
margin: 0;
font-family: 'Arial Black', sans-serif;
text-transform: uppercase;
line-height: 1.4;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
/* Zone qui contient les boutons des joueurs */
#winner-buttons-area {
display: flex;
flex-wrap: wrap; /* Si beaucoup de joueurs, ils vont à la ligne */
justify-content: center;
gap: 15px;
width: 100%;
}
/* Tes boutons .btn-win (on réutilise le style Or précédent) */
.btn-win {
background: linear-gradient(to bottom, #ffd700, #b8860b);
border: 2px solid #8b4513;
color: #000;
padding: 15px 30px;
font-weight: bold;
cursor: pointer;
border-radius: 8px;
transition: transform 0.2s;
}
.btn-win:hover {
transform: scale(1.1);
}
.btn-win:active {
transform: translateY(3px);
box-shadow: 0 1px 0 #5d2e0a;
}
/* Base commune pour tous les boutons de l'interface */
.btn-back, .btn-replay {
border-radius: 8px;
color: white;
cursor: pointer;
font-size: 1rem;
font-weight: bold;
padding: 10px 20px;
text-transform: uppercase;
transition: all 0.2s ease;
border: 2px solid rgba(0,0,0,0.2);
}
/* Style spécifique : Retour (Style plus sobre / Alerte) */
.btn-back {
background: linear-gradient(to bottom, #d9534f, #a94442); /* Rouge profond */
box-shadow: 0 4px 0 #7b2e2c;
}
.btn-back:hover {
filter: brightness(1.1);
transform: translateY(-2px);
box-shadow: 0 6px 0 #7b2e2c;
}
/* Style spécifique : Rejouer (Style Action / Casino) */
.btn-replay {
background: linear-gradient(to bottom, #5bc0de, #2aabd2); /* Bleu électrique */
box-shadow: 0 4px 0 #1b728c;
}
.btn-replay:hover {
filter: brightness(1.1);
transform: translateY(-2px);
box-shadow: 0 6px 0 #1b728c;
}
/* Animation au clic pour les deux */
.btn-back:active, .btn-replay:active {
transform: translateY(3px);
box-shadow: 0 1px 0 rgba(0,0,0,0.5);
}
.blur-effect {
filter: blur(5px);
pointer-events: none; /* Empêche de cliquer sur la table derrière */
}
/* Le conteneur avec la bordure dorée fine */
.money-group {
display: inline-flex;
align-items: stretch; /* Force le bouton à prendre toute la hauteur */
background: #1e1e1e; /* Fond très sombre pour faire ressortir l'or */
border: 1px solid #c5a059; /* Bordure Or mat (plus sobre que le jaune brillant) */
border-radius: 8px;
overflow: hidden; /* Pour que le bouton épouse l'arrondi de la bordure */
height: 40px; /* Hauteur fixe pour un look plus pro */
}
/* Le champ de saisie */
#money-amount {
background: transparent;
border: none;
color: #ffffff;
font-size: 1rem;
padding: 0 15px;
width: 100px; /* Ajustable selon tes besoins */
outline: none;
}
/* Le bouton OK qui occupe tout l'espace à droite */
.btn-money {
background: linear-gradient(45deg, #d4af37, #f9e27d); /* Fond Or mat */
border: none;
color: #1e1e1e; /* Texte sombre pour le contraste */
cursor: pointer;
font-weight: 800;
padding: 0 20px; /* Largeur du bouton */
text-transform: uppercase;
transition: background 0.2s ease;
display: flex;
align-items: center; /* Centre le texte "OK" verticalement */
}
.btn-money:hover {
filter: brightness(1.2); /* Or un peu plus clair au survol */
}
.btn-money:active {
filter: brightness(0.8); /* Or plus sombre au clic */
}
/* Suppression des flèches de l'input */
#money-amount::-webkit-inner-spin-button,
#money-amount::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
+108 -108
View File
@@ -1,108 +1,108 @@
// ################# Ces infos sont a changer en fonction de la BDD ##########################################################
let text = document.getElementById("text");
let money_input = document.getElementById("Money");
let money = { // Se rapelle de l'argent que chaque joueur a au début de la partie
"Ender": 10000,
"Sophie": 1000,
"Léo": 1000,
"Mélanie": 1000,
"Jean": 500,
"Lucie": 1000
};
let blinds = { // Se rapelle de l'argent actuellement mis en jeu par chaque joueur
"Ender": 20,
"Sophie": 30,
"Léo": 20,
"Mélanie": 20,
"Jean": 20,
"Lucie": 20
};
let player_list = ["Ender", "Sophie", "Léo", "Mélanie", "Jean", "Lucie"]; // Liste des joueurs encore en jeu a replir avec la BDD
let current_player = "Ender"; // Joueur actuel a prendre depuis la BDD
let start_blind = 20; // Blinde de départ a prendre depuis la BDD
// ##########################################################################################################################
let current_blind = 0; // Initialistation de la blinde actuelle en variable globale, mis a jour automatiquement
function ChangePlayer(player) { // Uniquement pour les tests, à remplacer par une fonction qui change de joueur dans la Boucle de jeu
current_player = player;
}
function UpdateStatus() { // Fonction mettant à jour la blinde actuel en fonction des blinds de chaque joueur
current_blind = Math.max(...Object.values(blinds));
}
function UpdateLabels() { // Fonction pour mettre à jour les labels
let pot = Object.values(blinds).reduce((a, b) => a + b, 0);
let money_labels = {}
for (key of Object.keys(money)) {
money_labels[key] = money[key] - blinds[key];
}
// Reste à faire avec ton code
}
function SeCoucher() { // fonction pour se coucher, elle vérifie si le joueur est en jeu et si sa mise actuelle est inférieure a la blinde actuel, si c'est le cas, il se couche et est retiré de la liste des joueurs encore en jeu
UpdateStatus();
if (current_blind > blinds[current_player] && player_list.includes(current_player)) { // Si le joueur est en jeu et que sa mise actuelle est inférieure a la blinde actuel, il se couche
player_list.splice(player_list.indexOf(current_player), 1);
}
UpdateLabels();
}
function Suivre() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il suit
UpdateStatus();
if (current_blind > blinds[current_player] && money[current_player] >= current_blind) { // Si la blinde actuelle est supérieur a la sienne et qu'il est en capacité de la payer
blinds[current_player] = current_blind;
} else {
Tapis();
}
UpdateLabels();
}
}
function Relancer() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu
UpdateStatus();
if (+money_input.value >= Math.max(...Object.values(money))){
Tapis();
} else {
if (money[current_player] > (current_blind) && +money_input.value <= money[current_player] - current_blind && +money_input.value > 0 && +money_input.value % (start_blind / 2) == 0) { // Si le joueur a assez d'argent pour suivre la blinde actuelle et relancer
blinds[current_player] = current_blind + +money_input.value;
}
}
UpdateLabels();
}
}
function Tapis() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il fait tapis
UpdateStatus();
if (money[current_player] < Math.max(...Object.values(money))) { // Si le joueur n'est pas le plus riche
blinds[current_player] = money[current_player];
} else { // Si le joueur est le plus riche
let temp_money = {...money};
temp_money[current_player] = 0;
let second_most_rich = Math.max(...Object.values(temp_money));
blinds[current_player] = second_most_rich;
}
UpdateLabels();
}
}
// ################# Ces infos sont a changer en fonction de la BDD ##########################################################
let text = document.getElementById("text");
let money_input = document.getElementById("Money");
let money = { // Se rapelle de l'argent que chaque joueur a au début de la partie
"Ender": 10000,
"Sophie": 1000,
"Léo": 1000,
"Mélanie": 1000,
"Jean": 500,
"Lucie": 1000
};
let blinds = { // Se rapelle de l'argent actuellement mis en jeu par chaque joueur
"Ender": 20,
"Sophie": 30,
"Léo": 20,
"Mélanie": 20,
"Jean": 20,
"Lucie": 20
};
let player_list = ["Ender", "Sophie", "Léo", "Mélanie", "Jean", "Lucie"]; // Liste des joueurs encore en jeu a replir avec la BDD
let current_player = "Ender"; // Joueur actuel a prendre depuis la BDD
let start_blind = 20; // Blinde de départ a prendre depuis la BDD
// ##########################################################################################################################
let current_blind = 0; // Initialistation de la blinde actuelle en variable globale, mis a jour automatiquement
function ChangePlayer(player) { // Uniquement pour les tests, à remplacer par une fonction qui change de joueur dans la Boucle de jeu
current_player = player;
}
function UpdateStatus() { // Fonction mettant à jour la blinde actuel en fonction des blinds de chaque joueur
current_blind = Math.max(...Object.values(blinds));
}
function UpdateLabels() { // Fonction pour mettre à jour les labels
let pot = Object.values(blinds).reduce((a, b) => a + b, 0);
let money_labels = {}
for (key of Object.keys(money)) {
money_labels[key] = money[key] - blinds[key];
}
// Reste à faire avec ton code
}
function SeCoucher() { // fonction pour se coucher, elle vérifie si le joueur est en jeu et si sa mise actuelle est inférieure a la blinde actuel, si c'est le cas, il se couche et est retiré de la liste des joueurs encore en jeu
UpdateStatus();
if (current_blind > blinds[current_player] && player_list.includes(current_player)) { // Si le joueur est en jeu et que sa mise actuelle est inférieure a la blinde actuel, il se couche
player_list.splice(player_list.indexOf(current_player), 1);
}
UpdateLabels();
}
function Suivre() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il suit
UpdateStatus();
if (current_blind > blinds[current_player] && money[current_player] >= current_blind) { // Si la blinde actuelle est supérieur a la sienne et qu'il est en capacité de la payer
blinds[current_player] = current_blind;
} else {
Tapis();
}
UpdateLabels();
}
}
function Relancer() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu
UpdateStatus();
if (+money_input.value >= Math.max(...Object.values(money))){
Tapis();
} else {
if (money[current_player] > (current_blind) && +money_input.value <= money[current_player] - current_blind && +money_input.value > 0 && +money_input.value % (start_blind / 2) == 0) { // Si le joueur a assez d'argent pour suivre la blinde actuelle et relancer
blinds[current_player] = current_blind + +money_input.value;
}
}
UpdateLabels();
}
}
function Tapis() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il fait tapis
UpdateStatus();
if (money[current_player] < Math.max(...Object.values(money))) { // Si le joueur n'est pas le plus riche
blinds[current_player] = money[current_player];
} else { // Si le joueur est le plus riche
let temp_money = {...money};
temp_money[current_player] = 0;
let second_most_rich = Math.max(...Object.values(temp_money));
blinds[current_player] = second_most_rich;
}
UpdateLabels();
}
}
+28 -28
View File
@@ -1,29 +1,29 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Ajouter l'argent au blind du joueur actuel
$stmt = $db->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$amount, $current_player_id]);
// 3. Ajouter le montant au pot de la partie
$stmt = $db->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Ajouter l'argent au blind du joueur actuel
$stmt = $db->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$amount, $current_player_id]);
// 3. Ajouter le montant au pot de la partie
$stmt = $db->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+22 -22
View File
@@ -1,23 +1,23 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Ajouter de l'argent au joueur actuel
$stmt = $db->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$amount, $current_player_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Ajouter de l'argent au joueur actuel
$stmt = $db->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$amount, $current_player_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+37 -37
View File
@@ -1,38 +1,38 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer l'argent du joueur actuel
$stmt = $db->prepare("SELECT * FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$money = $player['money'];
// 3. Mettre à jour la blinde du joueur actuel avec tout son argent
$stmt = $db->prepare("UPDATE players SET current_bet = ? WHERE id = ?");
$stmt->execute([$money + $player['current_bet'], $current_player_id]);
// 4. Retirer tout l'argent du joueur actuel
$stmt = $db->prepare("UPDATE players SET money = 0 WHERE id = ?");
$stmt->execute([$current_player_id]);
// 5. Ajouter le montant au pot de la partie
$stmt = $db->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$money, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer l'argent du joueur actuel
$stmt = $db->prepare("SELECT * FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$money = $player['money'];
// 3. Mettre à jour la blinde du joueur actuel avec tout son argent
$stmt = $db->prepare("UPDATE players SET current_bet = ? WHERE id = ?");
$stmt->execute([$money + $player['current_bet'], $current_player_id]);
// 4. Retirer tout l'argent du joueur actuel
$stmt = $db->prepare("UPDATE players SET money = 0 WHERE id = ?");
$stmt->execute([$current_player_id]);
// 5. Ajouter le montant au pot de la partie
$stmt = $db->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$money, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+16 -16
View File
@@ -1,17 +1,17 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Changer la blind de la partie
$stmt = $db->prepare("UPDATE games SET last_bet = ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Changer la blind de la partie
$stmt = $db->prepare("UPDATE games SET last_bet = ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+47 -47
View File
@@ -1,48 +1,48 @@
<?php
require_once 'db.php'; // Ta connexion PDO
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$action = $_POST['action'];
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Logique de changement de joueur (Simplifiée)
$stmt = $db->prepare("SELECT id FROM players WHERE is_folded = 0 AND game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_player_id]);
$next_player = $stmt->fetch();
if (!$next_player) { // Si on est au dernier, on revient au premier
$stmt = $db->prepare("SELECT id FROM players WHERE is_folded=0 AND game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next_player = $stmt->fetch();
}
// On cherche si le joueur est couché ou pas
$stmt = $db->prepare("SELECT is_folded FROM players WHERE id = ?");
$stmt->execute([$next_player['id']]);
$is_folded = $stmt->fetchColumn();
if ($is_folded == 1 || $is_folded === '1') {
// Si le joueur est couché, on appelle récursivement pour sauter au suivant
$_POST['game_id'] = $game_id; // On remet le game_id pour l'appel récursif
echo json_encode(['success' => true, 'message' => 'Joueur couché, passage au suivant.']);
exit;
}
$next_id = $next_player['id'];
// 3. Mise à jour de la BDD
$stmt = $db->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$next_id, $game_id]);
echo json_encode(['success' => true, 'next_player_id' => $next_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
<?php
require_once 'db.php'; // Ta connexion PDO
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$action = $_POST['action'];
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Logique de changement de joueur (Simplifiée)
$stmt = $db->prepare("SELECT id FROM players WHERE is_folded = 0 AND game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_player_id]);
$next_player = $stmt->fetch();
if (!$next_player) { // Si on est au dernier, on revient au premier
$stmt = $db->prepare("SELECT id FROM players WHERE is_folded=0 AND game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next_player = $stmt->fetch();
}
// On cherche si le joueur est couché ou pas
$stmt = $db->prepare("SELECT is_folded FROM players WHERE id = ?");
$stmt->execute([$next_player['id']]);
$is_folded = $stmt->fetchColumn();
if ($is_folded == 1 || $is_folded === '1') {
// Si le joueur est couché, on appelle récursivement pour sauter au suivant
$_POST['game_id'] = $game_id; // On remet le game_id pour l'appel récursif
echo json_encode(['success' => true, 'message' => 'Joueur couché, passage au suivant.']);
exit;
}
$next_id = $next_player['id'];
// 3. Mise à jour de la BDD
$stmt = $db->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$next_id, $game_id]);
echo json_encode(['success' => true, 'next_player_id' => $next_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
+233 -233
View File
@@ -1,234 +1,234 @@
/* config.css */
:root {
--poker-green: #0e5d32;
--gold: #d4af37;
--wood: #3e2723;
--white: #ffffff;
--danger: #b71c1c;
}
label.info {
font-size: 0.8rem;
color: rgb(141, 141, 141);
margin-left: 10px;
}
body {
background-color: #121212;
background-image: radial-gradient(circle, #1a1a1a 0%, #000000 100%);
color: var(--white);
font-family: 'Segoe UI', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
.container {
background-color: var(--poker-green);
padding: 30px 50px;
border-radius: 60px;
border: 12px solid var(--wood);
box-shadow: 0 0 50px rgba(0,0,0,0.9), inset 0 0 20px rgba(0,0,0,0.5);
width: 100%;
max-width: 500px;
}
h1 {
color: var(--gold);
text-align: center;
text-transform: uppercase;
font-size: 1.8rem;
margin-bottom: 30px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
label {
display: block;
color: var(--gold);
font-weight: bold;
margin-bottom: 8px;
}
input[type="number"],
input[type="text"] {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 2px solid var(--gold);
border-radius: 8px;
background: rgba(255, 255, 255, 0.9);
box-sizing: border-box; /* Pour que le padding ne dépasse pas */
font-size: 1rem;
}
/* Style spécifique pour la ligne joueur */
.player-row {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.player-row input {
margin-bottom: 0; /* On annule la marge pour l'alignement */
}
/* Boutons */
button, input[type="submit"] {
cursor: pointer;
font-weight: bold;
transition: all 0.2s;
border: none;
}
button[type="button"] {
background-color: var(--wood);
color: var(--gold);
border: 1px solid var(--gold);
padding: 10px 15px;
border-radius: 5px;
margin-bottom: 10px;
}
button[type="button"]:hover {
background-color: #4e342e;
}
/* Bouton Poubelle */
.player-row button {
background-color: var(--danger);
color: white;
border: none;
margin-bottom: 0;
}
/* Bouton Démarrer (le gros bouton doré) */
input[type="submit"] {
width: 100%;
background: linear-gradient(135deg, #d4af37 0%, #f9e27d 50%, #d4af37 100%);
color: var(--wood);
padding: 15px;
font-size: 1.2rem;
border-radius: 30px;
margin-top: 20px;
box-shadow: 0 4px 15px rgba(0,0,0,0.3);
}
input[type="submit"]:hover {
transform: scale(1.02);
filter: brightness(1.1);
}
/* Bouton Debug discret en bas */
.btn-debug {
background: transparent !important;
color: rgba(255,255,255,0.3) !important;
border: 1px dashed rgba(255,255,255,0.3) !important;
width: 100%;
margin-top: 30px;
font-size: 0.8rem;
}
.btn-back {
position: absolute;
top: 25px; /* Ajuste selon tes goûts */
left: 35px; /* Aligné avec le bord du cadre */
color: var(--gold);
text-decoration: none;
font-weight: bold;
font-size: 0.9rem;
opacity: 0.7;
transition: opacity 0.3s, transform 0.2s;
width: 20px;
}
.btn-back:hover {
opacity: 1;
transform: translateX(-5px); /* Petit effet de glissement vers la gauche */
}
/* --- Mode Mobile ---*/
/* --- ADAPTATION MOBILE POUR LA CONFIGURATION --- */
@media (max-width: 600px) {
body {
padding: 10px; /* On réduit la marge extérieure */
align-items: flex-start; /* On aligne en haut pour que le scroll soit naturel */
}
.container {
padding: 20px; /* On réduit le padding interne (30px 50px -> 20px) */
border-width: 8px; /* Bordure bois plus fine */
border-radius: 30px; /* Moins arrondi pour gagner de la place */
width: 100%;
box-sizing: border-box;
}
h1 {
font-size: 1.4rem;
margin-bottom: 20px;
}
/* Le bouton "Retour" */
.btn-back {
position: relative; /* On le sort de l'absolute pour qu'il ne chevauche pas le titre */
top: 0;
left: 0;
display: block;
margin-bottom: 15px;
width: auto;
}
/* 1. Ligne joueur : Le plus important ! */
.player-row {
flex-direction: column; /* On empile Nom et Poubelle verticalement */
align-items: stretch;
background: rgba(0,0,0,0.1);
padding: 10px;
border-radius: 8px;
border: 1px solid rgba(212, 175, 55, 0.3);
}
.player-row input {
width: 100%; /* Le champ de nom prend toute la largeur */
}
.player-row button {
width: 100%; /* Le bouton supprimer devient une large barre rouge */
padding: 12px;
margin-top: 5px;
}
/* 2. Inputs plus gros pour le tactile */
input[type="number"],
input[type="text"] {
padding: 15px;
font-size: 1.1rem; /* Évite le zoom auto sur iPhone */
}
/* 3. Boutons d'action */
button[type="button"] {
width: 100%; /* "Ajouter un joueur" prend toute la largeur */
padding: 15px;
font-size: 1rem;
}
input[type="submit"] {
padding: 18px;
font-size: 1.1rem;
border-radius: 15px; /* Un peu moins arrondi pour le look mobile */
}
/* Infos de mise (les petits labels gris) */
label.info {
margin-left: 0;
margin-top: -15px;
margin-bottom: 15px;
display: block;
}
/* config.css */
:root {
--poker-green: #0e5d32;
--gold: #d4af37;
--wood: #3e2723;
--white: #ffffff;
--danger: #b71c1c;
}
label.info {
font-size: 0.8rem;
color: rgb(141, 141, 141);
margin-left: 10px;
}
body {
background-color: #121212;
background-image: radial-gradient(circle, #1a1a1a 0%, #000000 100%);
color: var(--white);
font-family: 'Segoe UI', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
.container {
background-color: var(--poker-green);
padding: 30px 50px;
border-radius: 60px;
border: 12px solid var(--wood);
box-shadow: 0 0 50px rgba(0,0,0,0.9), inset 0 0 20px rgba(0,0,0,0.5);
width: 100%;
max-width: 500px;
}
h1 {
color: var(--gold);
text-align: center;
text-transform: uppercase;
font-size: 1.8rem;
margin-bottom: 30px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
label {
display: block;
color: var(--gold);
font-weight: bold;
margin-bottom: 8px;
}
input[type="number"],
input[type="text"] {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 2px solid var(--gold);
border-radius: 8px;
background: rgba(255, 255, 255, 0.9);
box-sizing: border-box; /* Pour que le padding ne dépasse pas */
font-size: 1rem;
}
/* Style spécifique pour la ligne joueur */
.player-row {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.player-row input {
margin-bottom: 0; /* On annule la marge pour l'alignement */
}
/* Boutons */
button, input[type="submit"] {
cursor: pointer;
font-weight: bold;
transition: all 0.2s;
border: none;
}
button[type="button"] {
background-color: var(--wood);
color: var(--gold);
border: 1px solid var(--gold);
padding: 10px 15px;
border-radius: 5px;
margin-bottom: 10px;
}
button[type="button"]:hover {
background-color: #4e342e;
}
/* Bouton Poubelle */
.player-row button {
background-color: var(--danger);
color: white;
border: none;
margin-bottom: 0;
}
/* Bouton Démarrer (le gros bouton doré) */
input[type="submit"] {
width: 100%;
background: linear-gradient(135deg, #d4af37 0%, #f9e27d 50%, #d4af37 100%);
color: var(--wood);
padding: 15px;
font-size: 1.2rem;
border-radius: 30px;
margin-top: 20px;
box-shadow: 0 4px 15px rgba(0,0,0,0.3);
}
input[type="submit"]:hover {
transform: scale(1.02);
filter: brightness(1.1);
}
/* Bouton Debug discret en bas */
.btn-debug {
background: transparent !important;
color: rgba(255,255,255,0.3) !important;
border: 1px dashed rgba(255,255,255,0.3) !important;
width: 100%;
margin-top: 30px;
font-size: 0.8rem;
}
.btn-back {
position: absolute;
top: 25px; /* Ajuste selon tes goûts */
left: 35px; /* Aligné avec le bord du cadre */
color: var(--gold);
text-decoration: none;
font-weight: bold;
font-size: 0.9rem;
opacity: 0.7;
transition: opacity 0.3s, transform 0.2s;
width: 20px;
}
.btn-back:hover {
opacity: 1;
transform: translateX(-5px); /* Petit effet de glissement vers la gauche */
}
/* --- Mode Mobile ---*/
/* --- ADAPTATION MOBILE POUR LA CONFIGURATION --- */
@media (max-width: 600px) {
body {
padding: 10px; /* On réduit la marge extérieure */
align-items: flex-start; /* On aligne en haut pour que le scroll soit naturel */
}
.container {
padding: 20px; /* On réduit le padding interne (30px 50px -> 20px) */
border-width: 8px; /* Bordure bois plus fine */
border-radius: 30px; /* Moins arrondi pour gagner de la place */
width: 100%;
box-sizing: border-box;
}
h1 {
font-size: 1.4rem;
margin-bottom: 20px;
}
/* Le bouton "Retour" */
.btn-back {
position: relative; /* On le sort de l'absolute pour qu'il ne chevauche pas le titre */
top: 0;
left: 0;
display: block;
margin-bottom: 15px;
width: auto;
}
/* 1. Ligne joueur : Le plus important ! */
.player-row {
flex-direction: column; /* On empile Nom et Poubelle verticalement */
align-items: stretch;
background: rgba(0,0,0,0.1);
padding: 10px;
border-radius: 8px;
border: 1px solid rgba(212, 175, 55, 0.3);
}
.player-row input {
width: 100%; /* Le champ de nom prend toute la largeur */
}
.player-row button {
width: 100%; /* Le bouton supprimer devient une large barre rouge */
padding: 12px;
margin-top: 5px;
}
/* 2. Inputs plus gros pour le tactile */
input[type="number"],
input[type="text"] {
padding: 15px;
font-size: 1.1rem; /* Évite le zoom auto sur iPhone */
}
/* 3. Boutons d'action */
button[type="button"] {
width: 100%; /* "Ajouter un joueur" prend toute la largeur */
padding: 15px;
font-size: 1rem;
}
input[type="submit"] {
padding: 18px;
font-size: 1.1rem;
border-radius: 15px; /* Un peu moins arrondi pour le look mobile */
}
/* Infos de mise (les petits labels gris) */
label.info {
margin-left: 0;
margin-top: -15px;
margin-bottom: 15px;
display: block;
}
}
+92 -92
View File
@@ -1,93 +1,93 @@
<?php
require_once 'db.php';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Configuration Poker</title>
<style>
.player-row { margin-bottom: 10px; }
</style>
<link rel="stylesheet" href="config.css">
</head>
<body>
<div class="container">
<button onclick="window.location.href='index.php'" class="btn-back">⬅ Accueil</button>
<h1>Configuration de la partie</h1>
<form action="start_game.php" method="post">
<label>Somme de départ :</label>
<input type="number" name="start_money" value="1000" required><br><br>
<label>Blind :</label>
<input type="number" name="blind" value="20" required><br><br>
<label>Joueurs :</label>
<label class="info">(Maximum 8 joueurs)</label><br>
<div id="players_container">
<div class="player-row">
<p>1</p><input type="text" name="players[]" placeholder="Nom du joueur" required>
</div>
</div>
<br>
<button type="button" onclick="addPlayer()"> Ajouter un joueur</button>
<br>
<input type="submit" value="Démarrer la partie">
</form>
</div>
<script>
function addPlayer() {
// 1. On récupère le conteneur
const container = document.getElementById('players_container');
// 2. On crée une nouvelle ligne
const newRow = document.createElement('div');
newRow.className = 'player-row';
// 3. On met le HTML dedans (avec le bouton supprimer intégré)
newRow.innerHTML = `
<p>${container.children.length + 1}</p>
<input type="text" name="players[]" placeholder="Nom du joueur" required>
<button type="button" onclick="removePlayer(this)">🗑️</button>
`;
// 4. On l'ajoute au conteneur
container.appendChild(newRow);
}
function removePlayer(btn) {
// On supprime le parent du bouton (la div 'player-row')
btn.parentElement.remove();
}
function deleteGame(idPartie) {
if (confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Tous les joueurs associés seront effacés.")) {
// On prépare les données à envoyer
let formData = new FormData();
formData.append('game_id', idPartie);
fetch('delete_game.php', {
method: 'POST',
body: formData // On envoie l'ID au PHP
})
.then(response => response.text())
.then(data => {
alert(data);
// Au lieu de reload, on peut rediriger vers l'accueil
window.location.href = 'index.php';
})
.catch(error => {
console.error('Erreur:', error);
alert('Impossible de supprimer la partie.');
});
}
}
</script>
</body>
<?php
require_once 'db.php';
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Configuration Poker</title>
<style>
.player-row { margin-bottom: 10px; }
</style>
<link rel="stylesheet" href="config.css">
</head>
<body>
<div class="container">
<button onclick="window.location.href='index.php'" class="btn-back">⬅ Accueil</button>
<h1>Configuration de la partie</h1>
<form action="start_game.php" method="post">
<label>Somme de départ :</label>
<input type="number" name="start_money" value="1000" required><br><br>
<label>Blind :</label>
<input type="number" name="blind" value="20" required><br><br>
<label>Joueurs :</label>
<label class="info">(Maximum 8 joueurs)</label><br>
<div id="players_container">
<div class="player-row">
<p>1</p><input type="text" name="players[]" placeholder="Nom du joueur" required>
</div>
</div>
<br>
<button type="button" onclick="addPlayer()"> Ajouter un joueur</button>
<br>
<input type="submit" value="Démarrer la partie">
</form>
</div>
<script>
function addPlayer() {
// 1. On récupère le conteneur
const container = document.getElementById('players_container');
// 2. On crée une nouvelle ligne
const newRow = document.createElement('div');
newRow.className = 'player-row';
// 3. On met le HTML dedans (avec le bouton supprimer intégré)
newRow.innerHTML = `
<p>${container.children.length + 1}</p>
<input type="text" name="players[]" placeholder="Nom du joueur" required>
<button type="button" onclick="removePlayer(this)">🗑️</button>
`;
// 4. On l'ajoute au conteneur
container.appendChild(newRow);
}
function removePlayer(btn) {
// On supprime le parent du bouton (la div 'player-row')
btn.parentElement.remove();
}
function deleteGame(idPartie) {
if (confirm("Êtes-vous sûr de vouloir supprimer cette partie ? Tous les joueurs associés seront effacés.")) {
// On prépare les données à envoyer
let formData = new FormData();
formData.append('game_id', idPartie);
fetch('delete_game.php', {
method: 'POST',
body: formData // On envoie l'ID au PHP
})
.then(response => response.text())
.then(data => {
alert(data);
// Au lieu de reload, on peut rediriger vers l'accueil
window.location.href = 'index.php';
})
.catch(error => {
console.error('Erreur:', error);
alert('Impossible de supprimer la partie.');
});
}
}
</script>
</body>
</html>
+13 -13
View File
@@ -1,14 +1,14 @@
<?php
// db.php
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'poker_paf';
try {
$db = new PDO("mysql:host=$host;dbname=$database;charset=utf8", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Erreur de connexion : " . $e->getMessage());
}
<?php
// db.php
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'poker_paf';
try {
$db = new PDO("mysql:host=$host;dbname=$database;charset=utf8", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Erreur de connexion : " . $e->getMessage());
}
?>
+62 -62
View File
@@ -1,63 +1,63 @@
<?php
// Désactiver l'affichage des erreurs en sortie pour ne pas polluer le JSON
error_reporting(0);
ini_set('display_errors', 0);
require_once 'db.php';
header('Content-Type: application/json');
$game_id = isset($_POST['game_id']) ? intval($_POST['game_id']) : 0;
$winner_id = isset($_POST['winner_id']) ? intval($_POST['winner_id']) : 0;
try {
if ($game_id === 0 || $winner_id === 0) {
throw new Exception("ID de partie ou de joueur invalide.");
}
// 1. On récupère le pot de la table et le nom du gagnant
$stmt = $db->prepare("SELECT pot FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$stmt = $db->prepare("SELECT name FROM players WHERE id = ?");
$stmt->execute([$winner_id]);
$player = $stmt->fetch();
if (!$game || !$player) {
throw new Exception("Données introuvables en base.");
}
$total_pot = intval($game['pot']);
$winner_name = $player['name'];
// 2. On effectue les mises à jour
$db->beginTransaction();
// Ajouter l'argent au gagnant
$stmt = $db->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$total_pot, $winner_id]);
// Vider le pot de la partie et reset la mise actuelle
$stmt = $db->prepare("UPDATE games SET pot = 0, last_bet = 0 WHERE id = ?");
$stmt->execute([$game_id]);
// Reset les mises individuelles
$stmt = $db->prepare("UPDATE players SET current_bet = 0 WHERE game_id = ?");
$stmt->execute([$game_id]);
$db->commit();
echo json_encode([
'success' => true,
'winner_name' => $winner_name,
'amount_won' => $total_pot
]);
} catch (Exception $e) {
if (isset($db) && $db->inTransaction()) $db->rollBack();
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
<?php
// Désactiver l'affichage des erreurs en sortie pour ne pas polluer le JSON
error_reporting(0);
ini_set('display_errors', 0);
require_once 'db.php';
header('Content-Type: application/json');
$game_id = isset($_POST['game_id']) ? intval($_POST['game_id']) : 0;
$winner_id = isset($_POST['winner_id']) ? intval($_POST['winner_id']) : 0;
try {
if ($game_id === 0 || $winner_id === 0) {
throw new Exception("ID de partie ou de joueur invalide.");
}
// 1. On récupère le pot de la table et le nom du gagnant
$stmt = $db->prepare("SELECT pot FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$stmt = $db->prepare("SELECT name FROM players WHERE id = ?");
$stmt->execute([$winner_id]);
$player = $stmt->fetch();
if (!$game || !$player) {
throw new Exception("Données introuvables en base.");
}
$total_pot = intval($game['pot']);
$winner_name = $player['name'];
// 2. On effectue les mises à jour
$db->beginTransaction();
// Ajouter l'argent au gagnant
$stmt = $db->prepare("UPDATE players SET money = money + ? WHERE id = ?");
$stmt->execute([$total_pot, $winner_id]);
// Vider le pot de la partie et reset la mise actuelle
$stmt = $db->prepare("UPDATE games SET pot = 0, last_bet = 0 WHERE id = ?");
$stmt->execute([$game_id]);
// Reset les mises individuelles
$stmt = $db->prepare("UPDATE players SET current_bet = 0 WHERE game_id = ?");
$stmt->execute([$game_id]);
$db->commit();
echo json_encode([
'success' => true,
'winner_name' => $winner_name,
'amount_won' => $total_pot
]);
} catch (Exception $e) {
if (isset($db) && $db->inTransaction()) $db->rollBack();
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
exit;
+31 -31
View File
@@ -1,32 +1,32 @@
<?php
require_once 'db.php';
session_start(); // Obligatoire si tu veux toucher aux sessions
header('Content-Type: application/json');
// 1. Récupérer l'ID envoyé par le JavaScript ($_POST)
$game_id = isset($_POST['game_id']) ? intval($_POST['game_id']) : null;
if ($game_id) {
try {
// Supprimer les joueurs associés d'abord (intégrité BDD)
$stmt = $db->prepare("DELETE FROM players WHERE game_id = ?");
$stmt->execute([$game_id]);
// Supprimer la partie
$stmt = $db->prepare("DELETE FROM games WHERE id = ?");
$stmt->execute([$game_id]);
// Nettoyer la session si besoin
if (isset($_SESSION['game_id']) && $_SESSION['game_id'] == $game_id) {
unset($_SESSION['game_id']);
}
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'message' => 'ID de partie manquant.']);
}
exit;
<?php
require_once 'db.php';
session_start(); // Obligatoire si tu veux toucher aux sessions
header('Content-Type: application/json');
// 1. Récupérer l'ID envoyé par le JavaScript ($_POST)
$game_id = isset($_POST['game_id']) ? intval($_POST['game_id']) : null;
if ($game_id) {
try {
// Supprimer les joueurs associés d'abord (intégrité BDD)
$stmt = $db->prepare("DELETE FROM players WHERE game_id = ?");
$stmt->execute([$game_id]);
// Supprimer la partie
$stmt = $db->prepare("DELETE FROM games WHERE id = ?");
$stmt->execute([$game_id]);
// Nettoyer la session si besoin
if (isset($_SESSION['game_id']) && $_SESSION['game_id'] == $game_id) {
unset($_SESSION['game_id']);
}
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
} else {
echo json_encode(['success' => false, 'message' => 'ID de partie manquant.']);
}
exit;
?>
+23 -23
View File
@@ -1,24 +1,24 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Coucher le joueur actuel
$stmt = $db->prepare("UPDATE players SET is_folded = 1 WHERE id = ?");
$stmt->execute([$current_player_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Coucher le joueur actuel
$stmt = $db->prepare("UPDATE players SET is_folded = 1 WHERE id = ?");
$stmt->execute([$current_player_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+436 -436
View File
@@ -1,437 +1,437 @@
:root {
--poker-green: #1a5e33;
--poker-border: #3e2723;
--gold: #d4af37;
--dark-bg: #0a0a0a;
--panel-bg: #1a1a1a;
--white: #ffffff;
}
body {
background-color: var(--dark-bg);
color: var(--white);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.game-container {
display: flex;
flex-direction: column;
height: 100%;
}
/* 1. Barre de stats */
.stats-bar {
background: rgba(0,0,0,0.8);
padding: 15px 30px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid var(--poker-border);
}
.stat-item {
font-size: 1.2rem;
color: var(--gold);
}
.btn-back {
color: var(--white);
text-decoration: none;
font-size: 0.9rem;
padding: 5px 10px;
border: 1px solid var(--poker-border);
border-radius: 4px;
}
/* 2. Table de jeu */
.table-container {
flex-grow: 1;
display: flex;
justify-content: center;
align-items: center;
position: relative;
padding: 60px; /* Espace pour les noms des joueurs */
}
.poker-table {
width: 800px;
height: 400px;
background-color: var(--poker-green);
border: 15px solid var(--poker-border);
border-radius: 200px;
position: relative;
box-shadow: inset 0 0 80px rgba(0,0,0,0.8), 0 10px 30px rgba(0,0,0,0.5);
}
.pot-area {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
pointer-events: none;
}
.total-pot {
font-size: 3rem;
font-weight: bold;
color: var(--white);
text-shadow: 2px 2px 10px rgba(0,0,0,0.8);
}
.current-bet-display {
font-size: 1.2rem;
opacity: 0.8;
}
/* 3. Positionnement des joueurs (8 slots) */
.player-slot {
position: absolute;
width: 140px;
z-index: 5;
}
.player-info {
background: rgba(0, 0, 0, 0.9);
border: 2px solid var(--gold);
border-radius: 12px;
padding: 8px;
text-align: center;
position: relative;
}
.player-info.active {
box-shadow: 0 0 25px var(--gold);
transform: scale(1.1);
border-color: #fff;
}
.player-name {
display: block;
font-weight: bold;
color: var(--gold);
font-size: 0.9rem;
}
.player-money {
font-size: 1.1rem;
font-weight: bold;
}
/* Coordonnées autour de l'ovale */
.slot-0 { top: -60px; left: 50%; transform: translateX(-50%); }
.slot-1 { top: 0%; right: -110px; }
.slot-2 { top: 50%; right: -150px; transform: translateY(-50%); }
.slot-3 { bottom: 0%; right: -110px; }
.slot-4 { bottom: -60px; left: 50%; transform: translateX(-50%); }
.slot-5 { bottom: 0%; left: -110px; }
.slot-6 { top: 50%; left: -150px; transform: translateY(-50%); }
.slot-7 { top: 0%; left: -110px; }
/* 4. Panneau d'action */
.action-panel {
background: var(--panel-bg);
border-top: 4px solid var(--gold);
padding: 20px;
text-align: center;
}
.turn-info {
margin: 0 0 15px 0;
font-size: 1.2rem;
}
.action-buttons {
display: flex;
justify-content: center;
gap: 15px;
}
.btn {
padding: 15px 30px;
border-radius: 8px;
border: none;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
transition: 0.2s;
min-width: 120px;
}
.btn-fold { background: #444; color: white; }
.btn-call { background: var(--poker-green); color: white; border: 1px solid var(--gold); }
.btn-raise { background: #1e88e5; color: white; }
.btn-allin {
background: linear-gradient(45deg, #d4af37, #f9e27d);
color: #3e2723;
box-shadow: 0 4px 15px rgba(212, 175, 55, 0.4);
}
.btn:hover {
transform: translateY(-5px);
filter: brightness(1.2);
}
/* --- Styles pour le bloc Augmenter --- */
.raise-group {
display: flex;
align-items: stretch; /* Pour que l'input et le bouton aient la même hauteur */
margin: 0 10px;
}
#raise-amount {
width: 100px;
padding: 10px;
border: 2px solid var(--gold);
border-right: none; /* On retire la bordure droite pour coller au bouton */
border-radius: 8px 0 0 8px; /* Arrondi seulement à gauche */
background: #222;
color: white;
font-weight: bold;
outline: none;
}
.btn-validate {
padding: 10px 15px;
background: var(--gold);
color: var(--poker-border);
border: 2px solid var(--gold);
border-radius: 0 8px 8px 0; /* Arrondi seulement à droite */
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
transition: 0.2s;
}
.btn-validate:hover {
background: #f9e27d;
filter: brightness(1.1);
}
/* Suppression des flèches par défaut de l'input number pour un look plus propre */
#raise-amount::-webkit-inner-spin-button,
#raise-amount::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.guide-overlay {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.9);
border: 2px solid var(--gold);
padding: 20px;
border-radius: 15px;
z-index: 1000;
text-align: center;
box-shadow: 0 0 30px rgba(212, 175, 55, 0.5);
min-width: 300px;
}
.guide-content h2 {
margin: 0 0 15px 0;
color: white;
font-size: 1.5rem;
}
#guide-btn {
background: var(--gold);
color: black;
border: none;
padding: 10px 20px;
border-radius: 5px;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
}
.dealer-badge {
position: absolute;
top: -15px;
right: -15px;
background: linear-gradient(45deg, #ffd700, #b8860b);
color: #000;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 14px;
border: 2px solid #fff;
box-shadow: 0 4px 8px rgba(0,0,0,0.5);
z-index: 20;
}
/* On peut aussi ajouter un effet d'ombre sur le joueur qui commence */
.player-info.is-dealer {
border-color: #ffd700;
}
.btn-next-round {
margin-top: 15px;
padding: 10px 20px;
background: var(--gold);
border: none;
border-radius: 20px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
transition: 0.3s;
z-index: 10;
}
.btn-next-round:hover {
transform: scale(1.1);
background: #fff;
z-index: 10;
}
button.btn-back {
background: transparent;
border: 1px solid var(--gold);
color: var(--gold);
padding: 5px 10px;
border-radius: 5px;
font-size: 0.9rem;
transition: background 0.3s, color 0.3s;
}
.player-bet {
font-size: 0.9rem;
color: rgb(141, 141, 141);
margin-top: 5px;
}
/* --- Mode Mobile (pour les petits écrans) --- */
/* --- ADAPTATION MOBILE --- */
@media (max-width: 900px) {
/* 1. On permet au corps de défiler si besoin, mais on réduit les espaces */
body {
height: auto;
overflow-y: auto;
}
/* 2. Barre de stats plus compacte */
.stats-bar {
padding: 10px;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}
.stat-item {
font-size: 1rem;
}
/* 3. LA TABLE : On la réduit pour qu'elle tienne en largeur */
.table-container {
padding: 40px 10px; /* Moins d'espace autour */
min-height: 450px;
}
.poker-table {
width: 100%; /* Elle prend toute la largeur dispo */
max-width: 350px; /* Mais pas trop non plus */
height: 300px;
border-width: 8px;
border-radius: 100px; /* Plus arrondie pour le format portrait */
}
.total-pot {
font-size: 1.8rem;
}
/* 4. POSITION DES JOUEURS : On resserre tout */
.player-slot {
width: 100px; /* Joueurs plus petits sur mobile */
}
.player-name { font-size: 0.7rem; }
.player-money { font-size: 0.9rem; }
.player-bet { font-size: 0.7rem; }
/* Ajustement des positions pour que ça ne sorte pas de l'écran */
.slot-0 { top: -45px; }
.slot-1 { right: -20px; top: 10%; }
.slot-2 { right: -40px; }
.slot-3 { right: -20px; bottom: 10%; }
.slot-4 { bottom: -45px; }
.slot-5 { left: -20px; bottom: 10%; }
.slot-6 { left: -40px; }
.slot-7 { left: -20px; top: 10%; }
/* 5. PANNEAU D'ACTION : On empile les boutons */
.action-panel {
padding: 15px 10px;
position: sticky;
bottom: 0;
z-index: 100;
}
.action-buttons {
display: grid;
grid-template-columns: 1fr 1fr; /* 2 colonnes de boutons */
gap: 10px;
}
.btn {
padding: 12px 5px;
min-width: 0; /* On laisse la grille gérer la largeur */
font-size: 0.8rem;
}
/* Le groupe de relance prend toute la largeur sur une ligne de la grille */
.raise-group {
grid-column: span 2;
margin: 0;
justify-content: center;
}
#raise-amount {
flex-grow: 1;
}
.btn-allin {
grid-column: span 2; /* Le tapis prend toute la largeur pour bien le voir */
}
/* 6. Guide de bienvenue */
.guide-overlay {
width: 90%;
box-sizing: border-box;
}
}
/* Optionnel : Pour les très petits écrans (iPhone SE, etc.) */
@media (max-width: 380px) {
.poker-table {
height: 250px;
}
.player-slot {
width: 85px;
}
}
@media (max-width: 600px) {
.win-panel {
padding: 20px;
width: 95%;
}
.win-panel h2 {
font-size: 1.3rem;
}
:root {
--poker-green: #1a5e33;
--poker-border: #3e2723;
--gold: #d4af37;
--dark-bg: #0a0a0a;
--panel-bg: #1a1a1a;
--white: #ffffff;
}
body {
background-color: var(--dark-bg);
color: var(--white);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.game-container {
display: flex;
flex-direction: column;
height: 100%;
}
/* 1. Barre de stats */
.stats-bar {
background: rgba(0,0,0,0.8);
padding: 15px 30px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid var(--poker-border);
}
.stat-item {
font-size: 1.2rem;
color: var(--gold);
}
.btn-back {
color: var(--white);
text-decoration: none;
font-size: 0.9rem;
padding: 5px 10px;
border: 1px solid var(--poker-border);
border-radius: 4px;
}
/* 2. Table de jeu */
.table-container {
flex-grow: 1;
display: flex;
justify-content: center;
align-items: center;
position: relative;
padding: 60px; /* Espace pour les noms des joueurs */
}
.poker-table {
width: 800px;
height: 400px;
background-color: var(--poker-green);
border: 15px solid var(--poker-border);
border-radius: 200px;
position: relative;
box-shadow: inset 0 0 80px rgba(0,0,0,0.8), 0 10px 30px rgba(0,0,0,0.5);
}
.pot-area {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
pointer-events: none;
}
.total-pot {
font-size: 3rem;
font-weight: bold;
color: var(--white);
text-shadow: 2px 2px 10px rgba(0,0,0,0.8);
}
.current-bet-display {
font-size: 1.2rem;
opacity: 0.8;
}
/* 3. Positionnement des joueurs (8 slots) */
.player-slot {
position: absolute;
width: 140px;
z-index: 5;
}
.player-info {
background: rgba(0, 0, 0, 0.9);
border: 2px solid var(--gold);
border-radius: 12px;
padding: 8px;
text-align: center;
position: relative;
}
.player-info.active {
box-shadow: 0 0 25px var(--gold);
transform: scale(1.1);
border-color: #fff;
}
.player-name {
display: block;
font-weight: bold;
color: var(--gold);
font-size: 0.9rem;
}
.player-money {
font-size: 1.1rem;
font-weight: bold;
}
/* Coordonnées autour de l'ovale */
.slot-0 { top: -60px; left: 50%; transform: translateX(-50%); }
.slot-1 { top: 0%; right: -110px; }
.slot-2 { top: 50%; right: -150px; transform: translateY(-50%); }
.slot-3 { bottom: 0%; right: -110px; }
.slot-4 { bottom: -60px; left: 50%; transform: translateX(-50%); }
.slot-5 { bottom: 0%; left: -110px; }
.slot-6 { top: 50%; left: -150px; transform: translateY(-50%); }
.slot-7 { top: 0%; left: -110px; }
/* 4. Panneau d'action */
.action-panel {
background: var(--panel-bg);
border-top: 4px solid var(--gold);
padding: 20px;
text-align: center;
}
.turn-info {
margin: 0 0 15px 0;
font-size: 1.2rem;
}
.action-buttons {
display: flex;
justify-content: center;
gap: 15px;
}
.btn {
padding: 15px 30px;
border-radius: 8px;
border: none;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
transition: 0.2s;
min-width: 120px;
}
.btn-fold { background: #444; color: white; }
.btn-call { background: var(--poker-green); color: white; border: 1px solid var(--gold); }
.btn-raise { background: #1e88e5; color: white; }
.btn-allin {
background: linear-gradient(45deg, #d4af37, #f9e27d);
color: #3e2723;
box-shadow: 0 4px 15px rgba(212, 175, 55, 0.4);
}
.btn:hover {
transform: translateY(-5px);
filter: brightness(1.2);
}
/* --- Styles pour le bloc Augmenter --- */
.raise-group {
display: flex;
align-items: stretch; /* Pour que l'input et le bouton aient la même hauteur */
margin: 0 10px;
}
#raise-amount {
width: 100px;
padding: 10px;
border: 2px solid var(--gold);
border-right: none; /* On retire la bordure droite pour coller au bouton */
border-radius: 8px 0 0 8px; /* Arrondi seulement à gauche */
background: #222;
color: white;
font-weight: bold;
outline: none;
}
.btn-validate {
padding: 10px 15px;
background: var(--gold);
color: var(--poker-border);
border: 2px solid var(--gold);
border-radius: 0 8px 8px 0; /* Arrondi seulement à droite */
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
transition: 0.2s;
}
.btn-validate:hover {
background: #f9e27d;
filter: brightness(1.1);
}
/* Suppression des flèches par défaut de l'input number pour un look plus propre */
#raise-amount::-webkit-inner-spin-button,
#raise-amount::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.guide-overlay {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.9);
border: 2px solid var(--gold);
padding: 20px;
border-radius: 15px;
z-index: 1000;
text-align: center;
box-shadow: 0 0 30px rgba(212, 175, 55, 0.5);
min-width: 300px;
}
.guide-content h2 {
margin: 0 0 15px 0;
color: white;
font-size: 1.5rem;
}
#guide-btn {
background: var(--gold);
color: black;
border: none;
padding: 10px 20px;
border-radius: 5px;
font-weight: bold;
cursor: pointer;
text-transform: uppercase;
}
.dealer-badge {
position: absolute;
top: -15px;
right: -15px;
background: linear-gradient(45deg, #ffd700, #b8860b);
color: #000;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 14px;
border: 2px solid #fff;
box-shadow: 0 4px 8px rgba(0,0,0,0.5);
z-index: 20;
}
/* On peut aussi ajouter un effet d'ombre sur le joueur qui commence */
.player-info.is-dealer {
border-color: #ffd700;
}
.btn-next-round {
margin-top: 15px;
padding: 10px 20px;
background: var(--gold);
border: none;
border-radius: 20px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
transition: 0.3s;
z-index: 10;
}
.btn-next-round:hover {
transform: scale(1.1);
background: #fff;
z-index: 10;
}
button.btn-back {
background: transparent;
border: 1px solid var(--gold);
color: var(--gold);
padding: 5px 10px;
border-radius: 5px;
font-size: 0.9rem;
transition: background 0.3s, color 0.3s;
}
.player-bet {
font-size: 0.9rem;
color: rgb(141, 141, 141);
margin-top: 5px;
}
/* --- Mode Mobile (pour les petits écrans) --- */
/* --- ADAPTATION MOBILE --- */
@media (max-width: 900px) {
/* 1. On permet au corps de défiler si besoin, mais on réduit les espaces */
body {
height: auto;
overflow-y: auto;
}
/* 2. Barre de stats plus compacte */
.stats-bar {
padding: 10px;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}
.stat-item {
font-size: 1rem;
}
/* 3. LA TABLE : On la réduit pour qu'elle tienne en largeur */
.table-container {
padding: 40px 10px; /* Moins d'espace autour */
min-height: 450px;
}
.poker-table {
width: 100%; /* Elle prend toute la largeur dispo */
max-width: 350px; /* Mais pas trop non plus */
height: 300px;
border-width: 8px;
border-radius: 100px; /* Plus arrondie pour le format portrait */
}
.total-pot {
font-size: 1.8rem;
}
/* 4. POSITION DES JOUEURS : On resserre tout */
.player-slot {
width: 100px; /* Joueurs plus petits sur mobile */
}
.player-name { font-size: 0.7rem; }
.player-money { font-size: 0.9rem; }
.player-bet { font-size: 0.7rem; }
/* Ajustement des positions pour que ça ne sorte pas de l'écran */
.slot-0 { top: -45px; }
.slot-1 { right: -20px; top: 10%; }
.slot-2 { right: -40px; }
.slot-3 { right: -20px; bottom: 10%; }
.slot-4 { bottom: -45px; }
.slot-5 { left: -20px; bottom: 10%; }
.slot-6 { left: -40px; }
.slot-7 { left: -20px; top: 10%; }
/* 5. PANNEAU D'ACTION : On empile les boutons */
.action-panel {
padding: 15px 10px;
position: sticky;
bottom: 0;
z-index: 100;
}
.action-buttons {
display: grid;
grid-template-columns: 1fr 1fr; /* 2 colonnes de boutons */
gap: 10px;
}
.btn {
padding: 12px 5px;
min-width: 0; /* On laisse la grille gérer la largeur */
font-size: 0.8rem;
}
/* Le groupe de relance prend toute la largeur sur une ligne de la grille */
.raise-group {
grid-column: span 2;
margin: 0;
justify-content: center;
}
#raise-amount {
flex-grow: 1;
}
.btn-allin {
grid-column: span 2; /* Le tapis prend toute la largeur pour bien le voir */
}
/* 6. Guide de bienvenue */
.guide-overlay {
width: 90%;
box-sizing: border-box;
}
}
/* Optionnel : Pour les très petits écrans (iPhone SE, etc.) */
@media (max-width: 380px) {
.poker-table {
height: 250px;
}
.player-slot {
width: 85px;
}
}
@media (max-width: 600px) {
.win-panel {
padding: 20px;
width: 95%;
}
.win-panel h2 {
font-size: 1.3rem;
}
}
+312 -312
View File
@@ -1,313 +1,313 @@
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'poker_paf'
});
let actualPlayerID = null; // Variable globale pour stocker l'ID du joueur actuel
let actualGameID = null; // Variable globale pour stocker l'ID de la partie actuelle
let playerChips = {}; // Objet pour stocker les jetons de chaque joueur
let playerNames = {}; // Objet pour stocker les noms de chaque joueur
let startBlind = 20; // Blinde de départ à prendre depuis la BDD
let blinds = {}; // Objet pour stocker les blinds de chaque joueur
// ############################################################################################################################
let current_blind = 0; // Initialisation de la blinde actuelle en variable globale, mis à jour automatiquement
function changePlayer() { // Uniquement pour les tests, à remplacer par une fonction qui change de joueur dans la Boucle de jeu
// Récupération du joueur actuel depuis la base de données
connection.connect(err => {
if (err) {
console.error('Erreur de connexion : ' + err.stack);
return;
}
console.log('Connecté à MySQL avec l\'ID ' + connection.threadId);
});
const sql = "SELECT current_player_id FROM games WHERE game_id = ?";
const values = [actualGameID];
connection.query(sql, values, (error, results) => {
if (error) {
console.error('Erreur lors de la récupération du joueur actuel : ' + error.stack);
return;
}
if (results.length > 0) {
actualPlayerID = results[0].current_player_id;
console.log('Joueur actuel : ' + actualPlayerID);
} else {
console.log('Aucun résultat trouvé pour le joueur actuel.');
}
});
// Changement du joueur actuel dans la base de données (pour les tests)
// On cherche le numéro d'ID du joueur suivant l'actuel qui a le même game_id
const sql2 = "SELECT player_id FROM players WHERE game_id = ? AND player_id > ? ORDER BY player_id ASC LIMIT 1";
const values2 = [actualGameID, actualPlayerID];
connection.query(sql2, values2, (error, results) => {
if (error) {
console.error('Erreur lors de la récupération du joueur suivant : ' + error.stack);
return;
}
if (results.length > 0) {
const nextPlayerID = results[0].player_id;
const sqlUpdate = "UPDATE games SET current_player_id = ? WHERE game_id = ?";
const valuesUpdate = [nextPlayerID, actualGameID];
connection.query(sqlUpdate, valuesUpdate, (error, results) => {
if (error) {
console.error('Erreur lors de la mise à jour du joueur actuel : ' + error.stack);
return;
}
console.log('Joueur actuel mis à jour avec succès.');
});
} else {
console.log('Aucun résultat trouvé pour le joueur suivant.');
}
});
console.log('Changement de joueur : ' + player);
}
function UpdateStatus() { // Fonction mettant à jour la blinde actuel en fonction des blinds de chaque joueur
current_blind = Math.max(...Object.values(blinds));
}
function UpdateLabels() { // Fonction pour mettre à jour les labels
let pot = Object.values(blinds).reduce((a, b) => a + b, 0);
let money_labels = {}
for (key of Object.keys(money)) {
money_labels[key] = money[key] - blinds[key];
}
for (const key of Object.keys(money_labels)) {
const label = document.getElementById(`label-${key}`);
if (label) {
label.innerText = money_labels[key] + " 🪙";
}
}
}
function SeCoucher() { // fonction pour se coucher, elle vérifie si le joueur est en jeu et si sa mise actuelle est inférieure a la blinde actuel, si c'est le cas, il se couche et est retiré de la liste des joueurs encore en jeu
UpdateStatus();
if (current_blind > blinds[current_player] && player_list.includes(current_player)) { // Si le joueur est en jeu et que sa mise actuelle est inférieure a la blinde actuel, il se couche
player_list.splice(player_list.indexOf(current_player), 1);
}
UpdateLabels();
}
function Suivre() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il suit
UpdateStatus();
if (current_blind > blinds[current_player] && money[current_player] >= current_blind) { // Si la blinde actuelle est supérieur a la sienne et qu'il est en capacité de la payer
blinds[current_player] = current_blind;
} else {
Tapis();
}
UpdateLabels();
}
}
function Relancer() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu
UpdateStatus();
if (+money_input.value >= Math.max(...Object.values(money))){
Tapis();
} else {
if (money[current_player] > (current_blind) && +money_input.value <= money[current_player] - current_blind && +money_input.value > 0 && +money_input.value % (start_blind / 2) == 0) { // Si le joueur a assez d'argent pour suivre la blinde actuelle et relancer
blinds[current_player] = current_blind + +money_input.value;
}
}
UpdateLabels();
}
}
function Tapis() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il fait tapis
UpdateStatus();
if (money[current_player] < Math.max(...Object.values(money))) { // Si le joueur n'est pas le plus riche
blinds[current_player] = money[current_player];
} else { // Si le joueur est le plus riche
let temp_money = {...money};
temp_money[current_player] = 0;
let second_most_rich = Math.max(...Object.values(temp_money));
blinds[current_player] = second_most_rich;
}
UpdateLabels();
}
}
// Fonction pour mettre à jour les jetons (Chips)
function updateChips(playerId, amount, btnElement) {
// 1. MISE À JOUR VISUELLE IMMÉDIATE (Optimiste)
const playerCard = btnElement.closest('.player-card');
const chipsDisplay = playerCard.querySelector('.player-chips');
// On sauvegarde l'ancienne valeur au cas où le serveur plante
const oldChipsValue = chipsDisplay.innerText;
let currentChips = parseInt(oldChipsValue);
let newChips = currentChips + amount;
// On change l'affichage tout de suite
chipsDisplay.innerHTML = newChips + " 🪙";
// 2. ENVOI À LA BASE DE DONNÉES
const formData = new FormData();
formData.append('player_id', playerId);
formData.append('amount', amount);
fetch('update_chips.php', {
method: 'POST',
body: formData
})
.then(response => response.text()) // On récupère en texte pour débugger
.then(text => {
try {
const data = JSON.parse(text);
if (!data.success) {
throw new Error(data.message);
}
console.log("Sync DB OK pour joueur " + playerId);
} catch (e) {
// 3. ANNULATION SI ERREUR
console.error("Erreur serveur, retour à l'ancien solde. Réponse reçue :", text);
chipsDisplay.innerHTML = oldChipsValue;
alert("Erreur de synchronisation : " + text);
}
})
.catch(error => {
chipsDisplay.innerHTML = oldChipsValue;
console.error('Erreur réseau :', error);
});
}
let currentStep = 0;
const steps = [
{ text: "Mélangez et distribuez les cartes (2 par joueur)", btn: "C'est fait !" },
{ text: "Au tour de J1 : Posez la Petite Blind", btn: "OK" },
{ text: "Au tour de J2 : Posez la Grosse Blind", btn: "OK" },
{ text: "Place au jeu ! Suivez les tours en bas.", btn: "Masquer le guide" }
];
function nextStep() {
const guideBox = document.getElementById('game-guide');
const textZone = document.getElementById('guide-text');
const btnZone = document.getElementById('guide-btn');
if (currentStep < steps.length) {
textZone.innerText = steps[currentStep].text;
btnZone.innerText = steps[currentStep].btn;
currentStep++;
} else {
// Une fois fini, on cache le guide ou on le réduit
guideBox.style.display = 'none';
// Ici, on pourrait activer les boutons d'action (Suivre, Miser...)
enableActions(true);
}
}
function enableActions(status) {
const btns = document.querySelectorAll('.btn-action, .btn-gold, .btn-validate');
btns.forEach(b => b.disabled = !status);
if(!status) {
document.querySelector('.action-panel').style.opacity = "0.5";
} else {
document.querySelector('.action-panel').style.opacity = "1";
}
}
// Au chargement, on bloque les actions tant que le guide n'est pas fini
window.onload = () => enableActions(false);
// Ta fonction deleteGame déjà existante (rappel)
function deleteGame(idPartie) {
if (confirm("Supprimer la partie ?")) {
let formData = new FormData();
formData.append('game_id', idPartie);
fetch('delete_game.php', { method: 'POST', body: formData })
.then(() => window.location.href = 'index.php');
}
}
function playerAction(type) {
const raiseInput = document.getElementById('raise-amount');
let amount = (type === 'raise') ? raiseInput.value : 0;
const gameId = new URLSearchParams(window.location.search).get('game_id');
// On prépare les données pour le PHP
let fd = new FormData();
fd.append('action', type);
fd.append('amount', amount);
fd.append('game_id', gameId);
fetch('play_action.php', { method: 'POST', body: fd })
.then(r => r.json())
.then(data => {
if (data.success) {
// --- ÉTAPE 1 : Gérer le Halo (Tu m'as dit que ça c'est OK) ---
document.querySelectorAll('.player-info').forEach(p => p.classList.remove('active'));
// On trouve la "carte" du nouveau joueur grâce à son ID
const nextPlayerSlot = document.querySelector(`[data-id="${data.next_player_id}"]`);
const nextInfoBox = nextPlayerSlot.querySelector('.player-info');
nextInfoBox.classList.add('active');
// --- ÉTAPE 2 : Mettre à jour le NOM en bas (C'est ça qui te manque) ---
// On récupère le texte du nom à l'intérieur de la carte du nouveau joueur
const nextNameRaw = nextInfoBox.querySelector('.player-name').innerText;
// On nettoie un peu le texte (pour enlever le "J1 :" par exemple)
const cleanName = nextNameRaw.split(':').pop().trim();
// On l'injecte dans le texte "Au tour de : ..."
document.getElementById('active-player-name').innerText = cleanName;
// --- ÉTAPE 3 : Mettre à jour le POT et vider l'input ---
if(data.new_pot) document.getElementById('main-pot').innerText = data.new_pot;
if(raiseInput) raiseInput.value = "";
}
})
.catch(err => console.error("Erreur action:", err));
}
function startNewRound() {
// Récupère l'ID dans l'URL (?game_id=4)
const urlParams = new URLSearchParams(window.location.search);
const gId = urlParams.get('game_id');
if (!gId) return alert("ID de partie manquant dans l'URL !");
let fd = new FormData();
fd.append('game_id', gId);
fetch('next_round.php', {
method: 'POST',
body: fd
})
.then(r => r.json())
.then(data => {
if (data.success) {
location.reload(); // On recharge pour voir le nouveau Dealer
}
})
.catch(err => console.error("Erreur bouton :", err));
}
function closeTable() {
if (confirm("Fermer la table ?")) {
// Supprimer la partie et les joueurs associés à la partie dans la db
const gameId = new URLSearchParams(window.location.search).get('game_id');
fetch('delete_game.php', {
method: 'POST',
body: new URLSearchParams({'game_id': gameId})
})
.then(() => window.location.href = 'index.php');
}
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'poker_paf'
});
let actualPlayerID = null; // Variable globale pour stocker l'ID du joueur actuel
let actualGameID = null; // Variable globale pour stocker l'ID de la partie actuelle
let playerChips = {}; // Objet pour stocker les jetons de chaque joueur
let playerNames = {}; // Objet pour stocker les noms de chaque joueur
let startBlind = 20; // Blinde de départ à prendre depuis la BDD
let blinds = {}; // Objet pour stocker les blinds de chaque joueur
// ############################################################################################################################
let current_blind = 0; // Initialisation de la blinde actuelle en variable globale, mis à jour automatiquement
function changePlayer() { // Uniquement pour les tests, à remplacer par une fonction qui change de joueur dans la Boucle de jeu
// Récupération du joueur actuel depuis la base de données
connection.connect(err => {
if (err) {
console.error('Erreur de connexion : ' + err.stack);
return;
}
console.log('Connecté à MySQL avec l\'ID ' + connection.threadId);
});
const sql = "SELECT current_player_id FROM games WHERE game_id = ?";
const values = [actualGameID];
connection.query(sql, values, (error, results) => {
if (error) {
console.error('Erreur lors de la récupération du joueur actuel : ' + error.stack);
return;
}
if (results.length > 0) {
actualPlayerID = results[0].current_player_id;
console.log('Joueur actuel : ' + actualPlayerID);
} else {
console.log('Aucun résultat trouvé pour le joueur actuel.');
}
});
// Changement du joueur actuel dans la base de données (pour les tests)
// On cherche le numéro d'ID du joueur suivant l'actuel qui a le même game_id
const sql2 = "SELECT player_id FROM players WHERE game_id = ? AND player_id > ? ORDER BY player_id ASC LIMIT 1";
const values2 = [actualGameID, actualPlayerID];
connection.query(sql2, values2, (error, results) => {
if (error) {
console.error('Erreur lors de la récupération du joueur suivant : ' + error.stack);
return;
}
if (results.length > 0) {
const nextPlayerID = results[0].player_id;
const sqlUpdate = "UPDATE games SET current_player_id = ? WHERE game_id = ?";
const valuesUpdate = [nextPlayerID, actualGameID];
connection.query(sqlUpdate, valuesUpdate, (error, results) => {
if (error) {
console.error('Erreur lors de la mise à jour du joueur actuel : ' + error.stack);
return;
}
console.log('Joueur actuel mis à jour avec succès.');
});
} else {
console.log('Aucun résultat trouvé pour le joueur suivant.');
}
});
console.log('Changement de joueur : ' + player);
}
function UpdateStatus() { // Fonction mettant à jour la blinde actuel en fonction des blinds de chaque joueur
current_blind = Math.max(...Object.values(blinds));
}
function UpdateLabels() { // Fonction pour mettre à jour les labels
let pot = Object.values(blinds).reduce((a, b) => a + b, 0);
let money_labels = {}
for (key of Object.keys(money)) {
money_labels[key] = money[key] - blinds[key];
}
for (const key of Object.keys(money_labels)) {
const label = document.getElementById(`label-${key}`);
if (label) {
label.innerText = money_labels[key] + " 🪙";
}
}
}
function SeCoucher() { // fonction pour se coucher, elle vérifie si le joueur est en jeu et si sa mise actuelle est inférieure a la blinde actuel, si c'est le cas, il se couche et est retiré de la liste des joueurs encore en jeu
UpdateStatus();
if (current_blind > blinds[current_player] && player_list.includes(current_player)) { // Si le joueur est en jeu et que sa mise actuelle est inférieure a la blinde actuel, il se couche
player_list.splice(player_list.indexOf(current_player), 1);
}
UpdateLabels();
}
function Suivre() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il suit
UpdateStatus();
if (current_blind > blinds[current_player] && money[current_player] >= current_blind) { // Si la blinde actuelle est supérieur a la sienne et qu'il est en capacité de la payer
blinds[current_player] = current_blind;
} else {
Tapis();
}
UpdateLabels();
}
}
function Relancer() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu
UpdateStatus();
if (+money_input.value >= Math.max(...Object.values(money))){
Tapis();
} else {
if (money[current_player] > (current_blind) && +money_input.value <= money[current_player] - current_blind && +money_input.value > 0 && +money_input.value % (start_blind / 2) == 0) { // Si le joueur a assez d'argent pour suivre la blinde actuelle et relancer
blinds[current_player] = current_blind + +money_input.value;
}
}
UpdateLabels();
}
}
function Tapis() {
if (player_list.includes(current_player)) { // Si le joueur est en jeu, il fait tapis
UpdateStatus();
if (money[current_player] < Math.max(...Object.values(money))) { // Si le joueur n'est pas le plus riche
blinds[current_player] = money[current_player];
} else { // Si le joueur est le plus riche
let temp_money = {...money};
temp_money[current_player] = 0;
let second_most_rich = Math.max(...Object.values(temp_money));
blinds[current_player] = second_most_rich;
}
UpdateLabels();
}
}
// Fonction pour mettre à jour les jetons (Chips)
function updateChips(playerId, amount, btnElement) {
// 1. MISE À JOUR VISUELLE IMMÉDIATE (Optimiste)
const playerCard = btnElement.closest('.player-card');
const chipsDisplay = playerCard.querySelector('.player-chips');
// On sauvegarde l'ancienne valeur au cas où le serveur plante
const oldChipsValue = chipsDisplay.innerText;
let currentChips = parseInt(oldChipsValue);
let newChips = currentChips + amount;
// On change l'affichage tout de suite
chipsDisplay.innerHTML = newChips + " 🪙";
// 2. ENVOI À LA BASE DE DONNÉES
const formData = new FormData();
formData.append('player_id', playerId);
formData.append('amount', amount);
fetch('update_chips.php', {
method: 'POST',
body: formData
})
.then(response => response.text()) // On récupère en texte pour débugger
.then(text => {
try {
const data = JSON.parse(text);
if (!data.success) {
throw new Error(data.message);
}
console.log("Sync DB OK pour joueur " + playerId);
} catch (e) {
// 3. ANNULATION SI ERREUR
console.error("Erreur serveur, retour à l'ancien solde. Réponse reçue :", text);
chipsDisplay.innerHTML = oldChipsValue;
alert("Erreur de synchronisation : " + text);
}
})
.catch(error => {
chipsDisplay.innerHTML = oldChipsValue;
console.error('Erreur réseau :', error);
});
}
let currentStep = 0;
const steps = [
{ text: "Mélangez et distribuez les cartes (2 par joueur)", btn: "C'est fait !" },
{ text: "Au tour de J1 : Posez la Petite Blind", btn: "OK" },
{ text: "Au tour de J2 : Posez la Grosse Blind", btn: "OK" },
{ text: "Place au jeu ! Suivez les tours en bas.", btn: "Masquer le guide" }
];
function nextStep() {
const guideBox = document.getElementById('game-guide');
const textZone = document.getElementById('guide-text');
const btnZone = document.getElementById('guide-btn');
if (currentStep < steps.length) {
textZone.innerText = steps[currentStep].text;
btnZone.innerText = steps[currentStep].btn;
currentStep++;
} else {
// Une fois fini, on cache le guide ou on le réduit
guideBox.style.display = 'none';
// Ici, on pourrait activer les boutons d'action (Suivre, Miser...)
enableActions(true);
}
}
function enableActions(status) {
const btns = document.querySelectorAll('.btn-action, .btn-gold, .btn-validate');
btns.forEach(b => b.disabled = !status);
if(!status) {
document.querySelector('.action-panel').style.opacity = "0.5";
} else {
document.querySelector('.action-panel').style.opacity = "1";
}
}
// Au chargement, on bloque les actions tant que le guide n'est pas fini
window.onload = () => enableActions(false);
// Ta fonction deleteGame déjà existante (rappel)
function deleteGame(idPartie) {
if (confirm("Supprimer la partie ?")) {
let formData = new FormData();
formData.append('game_id', idPartie);
fetch('delete_game.php', { method: 'POST', body: formData })
.then(() => window.location.href = 'index.php');
}
}
function playerAction(type) {
const raiseInput = document.getElementById('raise-amount');
let amount = (type === 'raise') ? raiseInput.value : 0;
const gameId = new URLSearchParams(window.location.search).get('game_id');
// On prépare les données pour le PHP
let fd = new FormData();
fd.append('action', type);
fd.append('amount', amount);
fd.append('game_id', gameId);
fetch('play_action.php', { method: 'POST', body: fd })
.then(r => r.json())
.then(data => {
if (data.success) {
// --- ÉTAPE 1 : Gérer le Halo (Tu m'as dit que ça c'est OK) ---
document.querySelectorAll('.player-info').forEach(p => p.classList.remove('active'));
// On trouve la "carte" du nouveau joueur grâce à son ID
const nextPlayerSlot = document.querySelector(`[data-id="${data.next_player_id}"]`);
const nextInfoBox = nextPlayerSlot.querySelector('.player-info');
nextInfoBox.classList.add('active');
// --- ÉTAPE 2 : Mettre à jour le NOM en bas (C'est ça qui te manque) ---
// On récupère le texte du nom à l'intérieur de la carte du nouveau joueur
const nextNameRaw = nextInfoBox.querySelector('.player-name').innerText;
// On nettoie un peu le texte (pour enlever le "J1 :" par exemple)
const cleanName = nextNameRaw.split(':').pop().trim();
// On l'injecte dans le texte "Au tour de : ..."
document.getElementById('active-player-name').innerText = cleanName;
// --- ÉTAPE 3 : Mettre à jour le POT et vider l'input ---
if(data.new_pot) document.getElementById('main-pot').innerText = data.new_pot;
if(raiseInput) raiseInput.value = "";
}
})
.catch(err => console.error("Erreur action:", err));
}
function startNewRound() {
// Récupère l'ID dans l'URL (?game_id=4)
const urlParams = new URLSearchParams(window.location.search);
const gId = urlParams.get('game_id');
if (!gId) return alert("ID de partie manquant dans l'URL !");
let fd = new FormData();
fd.append('game_id', gId);
fetch('next_round.php', {
method: 'POST',
body: fd
})
.then(r => r.json())
.then(data => {
if (data.success) {
location.reload(); // On recharge pour voir le nouveau Dealer
}
})
.catch(err => console.error("Erreur bouton :", err));
}
function closeTable() {
if (confirm("Fermer la table ?")) {
// Supprimer la partie et les joueurs associés à la partie dans la db
const gameId = new URLSearchParams(window.location.search).get('game_id');
fetch('delete_game.php', {
method: 'POST',
body: new URLSearchParams({'game_id': gameId})
})
.then(() => window.location.href = 'index.php');
}
}
+636 -636
View File
File diff suppressed because it is too large Load Diff
+18 -18
View File
@@ -1,19 +1,19 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer la blind de la partie
$stmt = $db->prepare("SELECT last_bet FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$last_bet = $game['last_bet'];
echo json_encode(['success' => true, 'blind' => $last_bet]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer la blind de la partie
$stmt = $db->prepare("SELECT last_bet FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$last_bet = $game['last_bet'];
echo json_encode(['success' => true, 'blind' => $last_bet]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+18 -18
View File
@@ -1,19 +1,19 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
echo json_encode(['success' => true, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
echo json_encode(['success' => true, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+24 -24
View File
@@ -1,25 +1,25 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer la blind du joueur actuel
$stmt = $db->prepare("SELECT current_bet FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$blind = $player['current_bet'];
echo json_encode(['success' => true, 'blind' => $blind, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer la blind du joueur actuel
$stmt = $db->prepare("SELECT current_bet FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$blind = $player['current_bet'];
echo json_encode(['success' => true, 'blind' => $blind, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+24 -24
View File
@@ -1,25 +1,25 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer l'argent du joueur actuel
$stmt = $db->prepare("SELECT money FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$money = $player['money'];
echo json_encode(['success' => true, 'money' => $money, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer l'argent du joueur actuel
$stmt = $db->prepare("SELECT money FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$money = $player['money'];
echo json_encode(['success' => true, 'money' => $money, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+18 -18
View File
@@ -1,19 +1,19 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer la blind de la partie
$stmt = $db->prepare("SELECT pot FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$pot = $game['pot'];
echo json_encode(['success' => true, 'total_blind' => $pot]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Récupérer la blind de la partie
$stmt = $db->prepare("SELECT pot FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$pot = $game['pot'];
echo json_encode(['success' => true, 'total_blind' => $pot]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+181 -181
View File
@@ -1,182 +1,182 @@
/* index.css */
:root {
--poker-green: #0e5d32;
--gold: #d4af37;
--wood: #3e2723;
--white: #ffffff;
}
body {
background-color: #121212;
background-image: radial-gradient(circle, #1a1a1a 0%, #000000 100%);
color: var(--white);
font-family: 'Segoe UI', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.welcome-container {
background-color: var(--poker-green);
padding: 50px;
border-radius: 80px;
border: 15px solid var(--wood);
box-shadow: 0 0 60px rgba(0,0,0,0.9), inset 0 0 30px rgba(0,0,0,0.5);
text-align: center;
width: 90%;
max-width: 450px;
}
h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 2.2rem;
margin-bottom: 40px;
text-shadow: 3px 3px 6px rgba(0,0,0,0.7);
}
/* Style pour le lien "Démarrer une partie" */
.btn-start {
display: inline-block;
background: linear-gradient(135deg, #d4af37 0%, #f9e27d 50%, #d4af37 100%);
color: var(--wood);
text-decoration: none;
padding: 15px 30px;
font-weight: bold;
font-size: 1.2rem;
border-radius: 40px;
margin-bottom: 40px;
transition: transform 0.2s, box-shadow 0.2s;
box-shadow: 0 5px 15px rgba(0,0,0,0.4);
}
.btn-start:hover {
transform: scale(1.05);
box-shadow: 0 0 20px rgba(212, 175, 55, 0.6);
}
/* Section rejoindre */
.join-section {
border-top: 1px solid rgba(255,255,255,0.2);
padding-top: 30px;
}
label {
display: block;
color: var(--gold);
margin-bottom: 15px;
font-weight: bold;
}
input[type="text"] {
background: rgba(255, 255, 255, 0.9);
border: 2px solid var(--gold);
border-radius: 5px;
padding: 12px;
width: 60%;
font-size: 1rem;
margin-bottom: 15px;
outline: none;
text-align: center;
}
button {
background-color: var(--wood);
color: var(--gold);
border: 2px solid var(--gold);
padding: 10px 20px;
font-weight: bold;
border-radius: 5px;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background-color: #5d3a3a;
}
.btn-join-list{
background-color: transparent;
color: var(--gold);
padding-left: 12px;
border: 1px solid var(--gold);
padding: 8px 12px;
border-radius: 5px;
margin-bottom: 10px;
}
.btn-join-list:hover {
background-color: var(--gold);
color: var(--wood);
}
li {
display: flex;
justify-content: space-between;
align-items: center;
}
/* --- Mode Mobile --- */
/* --- ADAPTATION MOBILE POUR L'ACCUEIL --- */
@media (max-width: 600px) {
body {
/* On permet le scroll si le contenu est plus haut que l'écran */
height: auto;
padding: 20px 0;
}
.welcome-container {
/* On réduit les bordures massives et le padding */
padding: 30px 20px;
border-width: 8px; /* Bordure en bois moins épaisse */
border-radius: 40px; /* Moins arrondi pour gagner de la place */
width: 85%;
}
h1 {
font-size: 1.6rem; /* Titre plus petit */
margin-bottom: 30px;
}
/* Le bouton principal doit être bien large pour le pouce */
.btn-start {
width: 100%;
box-sizing: border-box; /* Pour que le padding n'agrandisse pas la largeur */
padding: 18px 20px;
font-size: 1.1rem;
}
/* Section rejoindre */
input[type="text"] {
width: 100%; /* L'input prend toute la largeur */
box-sizing: border-box;
padding: 15px;
font-size: 1.1rem; /* Évite le zoom auto de l'iPhone sur les inputs */
}
button {
width: 100%; /* Les boutons de validation passent en pleine largeur */
padding: 15px;
margin-top: 10px;
}
/* Pour la liste des parties */
li {
flex-direction: column; /* On empile le nom et le bouton */
gap: 10px;
background: rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
margin-bottom: 15px;
}
.btn-join-list {
width: 100%;
text-align: center;
}
/* index.css */
:root {
--poker-green: #0e5d32;
--gold: #d4af37;
--wood: #3e2723;
--white: #ffffff;
}
body {
background-color: #121212;
background-image: radial-gradient(circle, #1a1a1a 0%, #000000 100%);
color: var(--white);
font-family: 'Segoe UI', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.welcome-container {
background-color: var(--poker-green);
padding: 50px;
border-radius: 80px;
border: 15px solid var(--wood);
box-shadow: 0 0 60px rgba(0,0,0,0.9), inset 0 0 30px rgba(0,0,0,0.5);
text-align: center;
width: 90%;
max-width: 450px;
}
h1 {
color: var(--gold);
text-transform: uppercase;
font-size: 2.2rem;
margin-bottom: 40px;
text-shadow: 3px 3px 6px rgba(0,0,0,0.7);
}
/* Style pour le lien "Démarrer une partie" */
.btn-start {
display: inline-block;
background: linear-gradient(135deg, #d4af37 0%, #f9e27d 50%, #d4af37 100%);
color: var(--wood);
text-decoration: none;
padding: 15px 30px;
font-weight: bold;
font-size: 1.2rem;
border-radius: 40px;
margin-bottom: 40px;
transition: transform 0.2s, box-shadow 0.2s;
box-shadow: 0 5px 15px rgba(0,0,0,0.4);
}
.btn-start:hover {
transform: scale(1.05);
box-shadow: 0 0 20px rgba(212, 175, 55, 0.6);
}
/* Section rejoindre */
.join-section {
border-top: 1px solid rgba(255,255,255,0.2);
padding-top: 30px;
}
label {
display: block;
color: var(--gold);
margin-bottom: 15px;
font-weight: bold;
}
input[type="text"] {
background: rgba(255, 255, 255, 0.9);
border: 2px solid var(--gold);
border-radius: 5px;
padding: 12px;
width: 60%;
font-size: 1rem;
margin-bottom: 15px;
outline: none;
text-align: center;
}
button {
background-color: var(--wood);
color: var(--gold);
border: 2px solid var(--gold);
padding: 10px 20px;
font-weight: bold;
border-radius: 5px;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background-color: #5d3a3a;
}
.btn-join-list{
background-color: transparent;
color: var(--gold);
padding-left: 12px;
border: 1px solid var(--gold);
padding: 8px 12px;
border-radius: 5px;
margin-bottom: 10px;
}
.btn-join-list:hover {
background-color: var(--gold);
color: var(--wood);
}
li {
display: flex;
justify-content: space-between;
align-items: center;
}
/* --- Mode Mobile --- */
/* --- ADAPTATION MOBILE POUR L'ACCUEIL --- */
@media (max-width: 600px) {
body {
/* On permet le scroll si le contenu est plus haut que l'écran */
height: auto;
padding: 20px 0;
}
.welcome-container {
/* On réduit les bordures massives et le padding */
padding: 30px 20px;
border-width: 8px; /* Bordure en bois moins épaisse */
border-radius: 40px; /* Moins arrondi pour gagner de la place */
width: 85%;
}
h1 {
font-size: 1.6rem; /* Titre plus petit */
margin-bottom: 30px;
}
/* Le bouton principal doit être bien large pour le pouce */
.btn-start {
width: 100%;
box-sizing: border-box; /* Pour que le padding n'agrandisse pas la largeur */
padding: 18px 20px;
font-size: 1.1rem;
}
/* Section rejoindre */
input[type="text"] {
width: 100%; /* L'input prend toute la largeur */
box-sizing: border-box;
padding: 15px;
font-size: 1.1rem; /* Évite le zoom auto de l'iPhone sur les inputs */
}
button {
width: 100%; /* Les boutons de validation passent en pleine largeur */
padding: 15px;
margin-top: 10px;
}
/* Pour la liste des parties */
li {
flex-direction: column; /* On empile le nom et le bouton */
gap: 10px;
background: rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
margin-bottom: 15px;
}
.btn-join-list {
width: 100%;
text-align: center;
}
}
+57 -57
View File
@@ -1,58 +1,58 @@
<?php
require_once 'db.php';
session_start();
session_destroy(); // On détruit la session pour supprimer l'ID de la partie en cours
// Récupérer la liste des parties en cours
$stmt = $db->query("SELECT id, start_money, start_blind FROM games ORDER BY id DESC");
$games = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Poker PAF</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='index.css'>
<script src='main.js'></script>
</head>
<body>
<div class="welcome-container">
<h1>Welcome to Poker PAF</h1>
<button onclick="window.location.href='config.php'">Créer une partie</button><br><br>
<label>Rejoindre une partie :</label><br>
<input type="text" id="join_game_id" placeholder="ID de la partie">
<button onclick="joinGame()">Rejoindre</button><br><br>
<h2>Parties en cours :</h2>
<div id="games_list">
<?php if (count($games) > 0): ?>
<ul>
<?php foreach ($games as $game): ?>
<li>
ID: <?php echo $game['id']; ?> -
Start Money: <?php echo $game['start_money']; ?> -
Blind: <?php echo $game['start_blind']; ?>
<button class="btn-join-list" onclick="window.location.href='game.php?game_id=<?php echo $game['id']; ?>'">Rejoindre</button>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>Aucune partie en cours.</p>
<?php endif; ?>
</div>
</div>
</body>
<script>
function joinGame() {
const gameId = document.getElementById('join_game_id').value;
if (gameId) {
// Rediriger vers une page de jeu avec l'ID en paramètre
window.location.href = `game.php?game_id=${gameId}`;
} else {
alert('Veuillez entrer un ID de partie valide.');
}
}
<?php
require_once 'db.php';
session_start();
session_destroy(); // On détruit la session pour supprimer l'ID de la partie en cours
// Récupérer la liste des parties en cours
$stmt = $db->query("SELECT id, start_money, start_blind FROM games ORDER BY id DESC");
$games = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Poker PAF</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='index.css'>
<script src='main.js'></script>
</head>
<body>
<div class="welcome-container">
<h1>Welcome to Poker PAF</h1>
<button onclick="window.location.href='config.php'">Créer une partie</button><br><br>
<label>Rejoindre une partie :</label><br>
<input type="text" id="join_game_id" placeholder="ID de la partie">
<button onclick="joinGame()">Rejoindre</button><br><br>
<h2>Parties en cours :</h2>
<div id="games_list">
<?php if (count($games) > 0): ?>
<ul>
<?php foreach ($games as $game): ?>
<li>
ID: <?php echo $game['id']; ?> -
Start Money: <?php echo $game['start_money']; ?> -
Blind: <?php echo $game['start_blind']; ?>
<button class="btn-join-list" onclick="window.location.href='game.php?game_id=<?php echo $game['id']; ?>'">Rejoindre</button>
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>Aucune partie en cours.</p>
<?php endif; ?>
</div>
</div>
</body>
<script>
function joinGame() {
const gameId = document.getElementById('join_game_id').value;
if (gameId) {
// Rediriger vers une page de jeu avec l'ID en paramètre
window.location.href = `game.php?game_id=${gameId}`;
} else {
alert('Veuillez entrer un ID de partie valide.');
}
}
</html>
+30 -30
View File
@@ -1,31 +1,31 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = intval($_POST['amount']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer l'argent du joueur actuel
$stmt = $db->prepare("SELECT money FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$money = $player['money'];
// 3. Mettre à jour l'argent du joueur actuel
$new_money = $money + $amount;
$stmt = $db->prepare("UPDATE players SET money = ? WHERE id = ?");
$stmt->execute([$new_money, $current_player_id]);
echo json_encode(['success' => true, 'money' => $money, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = intval($_POST['amount']);
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Récupérer l'argent du joueur actuel
$stmt = $db->prepare("SELECT money FROM players WHERE id = ?");
$stmt->execute([$current_player_id]);
$player = $stmt->fetch();
$money = $player['money'];
// 3. Mettre à jour l'argent du joueur actuel
$new_money = $money + $amount;
$stmt = $db->prepare("UPDATE players SET money = ? WHERE id = ?");
$stmt->execute([$new_money, $current_player_id]);
echo json_encode(['success' => true, 'money' => $money, 'player_id' => $current_player_id]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+39 -39
View File
@@ -1,40 +1,40 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. On récupère tous les joueurs
$stmt = $db->prepare("SELECT id, is_dealer FROM players WHERE game_id = ? ORDER BY id ASC");
$stmt->execute([$game_id]);
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($players) == 0) throw new Exception("Pas de joueurs");
// 2. On trouve l'ancien dealer pour désigner le nouveau
$oldDealerIndex = -1;
foreach ($players as $index => $p) {
if ($p['is_dealer'] == 1) { $oldDealerIndex = $index; break; }
}
$nextDealerIndex = ($oldDealerIndex + 1) % count($players);
$newDealerId = $players[$nextDealerIndex]['id'];
// 3. Qui doit parler en premier ? (Normalement c'est celui après le Dealer)
$firstPlayerIndex = ($nextDealerIndex + 1) % count($players);
$firstPlayerId = $players[$firstPlayerIndex]['id'];
// 4. MISE À JOUR DE LA BDD
// On reset les dealers
$db->prepare("UPDATE players SET is_dealer = 0 WHERE game_id = ?")->execute([$game_id]);
// On met le nouveau dealer
$db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?")->execute([$newDealerId]);
// On reset le POT, la MISE et on définit le JOUEUR ACTIF
$db->prepare("UPDATE games SET pot = 0, last_bet = 0, current_player_id = ? WHERE id = ?")
->execute([$firstPlayerId, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. On récupère tous les joueurs
$stmt = $db->prepare("SELECT id, is_dealer FROM players WHERE game_id = ? ORDER BY id ASC");
$stmt->execute([$game_id]);
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($players) == 0) throw new Exception("Pas de joueurs");
// 2. On trouve l'ancien dealer pour désigner le nouveau
$oldDealerIndex = -1;
foreach ($players as $index => $p) {
if ($p['is_dealer'] == 1) { $oldDealerIndex = $index; break; }
}
$nextDealerIndex = ($oldDealerIndex + 1) % count($players);
$newDealerId = $players[$nextDealerIndex]['id'];
// 3. Qui doit parler en premier ? (Normalement c'est celui après le Dealer)
$firstPlayerIndex = ($nextDealerIndex + 1) % count($players);
$firstPlayerId = $players[$firstPlayerIndex]['id'];
// 4. MISE À JOUR DE LA BDD
// On reset les dealers
$db->prepare("UPDATE players SET is_dealer = 0 WHERE game_id = ?")->execute([$game_id]);
// On met le nouveau dealer
$db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?")->execute([$newDealerId]);
// On reset le POT, la MISE et on définit le JOUEUR ACTIF
$db->prepare("UPDATE games SET pot = 0, last_bet = 0, current_player_id = ? WHERE id = ?")
->execute([$firstPlayerId, $game_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
+266 -266
View File
@@ -1,266 +1,266 @@
#### 9.0.0
* 27/05/2019
* For compatibility with legacy browsers, remove `Symbol` references.
#### 8.1.1
* 24/02/2019
* [BUGFIX] #222 Restore missing `var` to `export BigNumber`.
* Allow any key in BigNumber.Instance in *bignumber.d.ts*.
#### 8.1.0
* 23/02/2019
* [NEW FEATURE] #220 Create a BigNumber using `{s, e, c}`.
* [NEW FEATURE] `isBigNumber`: if `BigNumber.DEBUG` is `true`, also check that the BigNumber instance is well-formed.
* Remove `instanceof` checks; just use `_isBigNumber` to identify a BigNumber instance.
* Add `_isBigNumber` to prototype in *bignumber.mjs*.
* Add tests for BigNumber creation from object.
* Update *API.html*.
#### 8.0.2
* 13/01/2019
* #209 `toPrecision` without argument should follow `toString`.
* Improve *Use* section of *README*.
* Optimise `toString(10)`.
* Add verson number to API doc.
#### 8.0.1
* 01/11/2018
* Rest parameter must be array type in *bignumber.d.ts*.
#### 8.0.0
* 01/11/2018
* [NEW FEATURE] Add `BigNumber.sum` method.
* [NEW FEATURE]`toFormat`: add `prefix` and `suffix` options.
* [NEW FEATURE] #178 Pass custom formatting to `toFormat`.
* [BREAKING CHANGE] #184 `toFraction`: return array of BigNumbers not strings.
* [NEW FEATURE] #185 Enable overwrite of `valueOf` to prevent accidental addition to string.
* #183 Add Node.js `crypto` requirement to documentation.
* [BREAKING CHANGE] #198 Disallow signs and whitespace in custom alphabet.
* [NEW FEATURE] #188 Implement `util.inspect.custom` for Node.js REPL.
* #170 Make `isBigNumber` a type guard in *bignumber.d.ts*.
* [BREAKING CHANGE] `BigNumber.min` and `BigNumber.max`: don't accept an array.
* Update *.travis.yml*.
* Remove *bower.json*.
#### 7.2.1
* 24/05/2018
* Add `browser` field to *package.json*.
#### 7.2.0
* 22/05/2018
* #166 Correct *.mjs* file. Remove extension from `main` field in *package.json*.
#### 7.1.0
* 18/05/2018
* Add `module` field to *package.json* for *bignumber.mjs*.
#### 7.0.2
* 17/05/2018
* #165 Bugfix: upper-case letters for bases 11-36 in a custom alphabet.
* Add note to *README* regarding creating BigNumbers from Number values.
#### 7.0.1
* 26/04/2018
* #158 Fix global object variable name typo.
#### 7.0.0
* 26/04/2018
* #143 Remove global BigNumber from typings.
* #144 Enable compatibility with `Object.freeze(Object.prototype)`.
* #148 #123 #11 Only throw on a number primitive with more than 15 significant digits if `BigNumber.DEBUG` is `true`.
* Only throw on an invalid BigNumber value if `BigNumber.DEBUG` is `true`. Return BigNumber `NaN` instead.
* #154 `exponentiatedBy`: allow BigNumber exponent.
* #156 Prevent Content Security Policy *unsafe-eval* issue.
* `toFraction`: allow `Infinity` maximum denominator.
* Comment-out some excess tests to reduce test time.
* Amend indentation and other spacing.
#### 6.0.0
* 26/01/2018
* #137 Implement `APLHABET` configuration option.
* Remove `ERRORS` configuration option.
* Remove `toDigits` method; extend `precision` method accordingly.
* Remove s`round` method; extend `decimalPlaces` method accordingly.
* Remove methods: `ceil`, `floor`, and `truncated`.
* Remove method aliases: `add`, `cmp`, `isInt`, `isNeg`, `trunc`, `mul`, `neg` and `sub`.
* Rename methods: `shift` to `shiftedBy`, `another` to `clone`, `toPower` to `exponentiatedBy`, and `equals` to `isEqualTo`.
* Rename methods: add `is` prefix to `greaterThan`, `greaterThanOrEqualTo`, `lessThan` and `lessThanOrEqualTo`.
* Add methods: `multipliedBy`, `isBigNumber`, `isPositive`, `integerValue`, `maximum` and `minimum`.
* Refactor test suite.
* Add *CHANGELOG.md*.
* Rewrite *bignumber.d.ts*.
* Redo API image.
#### 5.0.0
* 27/11/2017
* #81 Don't throw on constructor call without `new`.
#### 4.1.0
* 26/09/2017
* Remove node 0.6 from *.travis.yml*.
* Add *bignumber.mjs*.
#### 4.0.4
* 03/09/2017
* Add missing aliases to *bignumber.d.ts*.
#### 4.0.3
* 30/08/2017
* Add types: *bignumber.d.ts*.
#### 4.0.2
* 03/05/2017
* #120 Workaround Safari/Webkit bug.
#### 4.0.1
* 05/04/2017
* #121 BigNumber.default to BigNumber['default'].
#### 4.0.0
* 09/01/2017
* Replace BigNumber.isBigNumber method with isBigNumber prototype property.
#### 3.1.2
* 08/01/2017
* Minor documentation edit.
#### 3.1.1
* 08/01/2017
* Uncomment `isBigNumber` tests.
* Ignore dot files.
#### 3.1.0
* 08/01/2017
* Add `isBigNumber` method.
#### 3.0.2
* 08/01/2017
* Bugfix: Possible incorrect value of `ERRORS` after a `BigNumber.another` call (due to `parseNumeric` declaration in outer scope).
#### 3.0.1
* 23/11/2016
* Apply fix for old ipads with `%` issue, see #57 and #102.
* Correct error message.
#### 3.0.0
* 09/11/2016
* Remove `require('crypto')` - leave it to the user.
* Add `BigNumber.set` as `BigNumber.config` alias.
* Default `POW_PRECISION` to `0`.
#### 2.4.0
* 14/07/2016
* #97 Add exports to support ES6 imports.
#### 2.3.0
* 07/03/2016
* #86 Add modulus parameter to `toPower`.
#### 2.2.0
* 03/03/2016
* #91 Permit larger JS integers.
#### 2.1.4
* 15/12/2015
* Correct UMD.
#### 2.1.3
* 13/12/2015
* Refactor re global object and crypto availability when bundling.
#### 2.1.2
* 10/12/2015
* Bugfix: `window.crypto` not assigned to `crypto`.
#### 2.1.1
* 09/12/2015
* Prevent code bundler from adding `crypto` shim.
#### 2.1.0
* 26/10/2015
* For `valueOf` and `toJSON`, include the minus sign with negative zero.
#### 2.0.8
* 2/10/2015
* Internal round function bugfix.
#### 2.0.6
* 31/03/2015
* Add bower.json. Tweak division after in-depth review.
#### 2.0.5
* 25/03/2015
* Amend README. Remove bitcoin address.
#### 2.0.4
* 25/03/2015
* Critical bugfix #58: division.
#### 2.0.3
* 18/02/2015
* Amend README. Add source map.
#### 2.0.2
* 18/02/2015
* Correct links.
#### 2.0.1
* 18/02/2015
* Add `max`, `min`, `precision`, `random`, `shiftedBy`, `toDigits` and `truncated` methods.
* Add the short-forms: `add`, `mul`, `sd`, `sub` and `trunc`.
* Add an `another` method to enable multiple independent constructors to be created.
* Add support for the base 2, 8 and 16 prefixes `0b`, `0o` and `0x`.
* Enable a rounding mode to be specified as a second parameter to `toExponential`, `toFixed`, `toFormat` and `toPrecision`.
* Add a `CRYPTO` configuration property so cryptographically-secure pseudo-random number generation can be specified.
* Add a `MODULO_MODE` configuration property to enable the rounding mode used by the `modulo` operation to be specified.
* Add a `POW_PRECISION` configuration property to enable the number of significant digits calculated by the power operation to be limited.
* Improve code quality.
* Improve documentation.
#### 2.0.0
* 29/12/2014
* Add `dividedToIntegerBy`, `isInteger` and `toFormat` methods.
* Remove the following short-forms: `isF`, `isZ`, `toE`, `toF`, `toFr`, `toN`, `toP`, `toS`.
* Store a BigNumber's coefficient in base 1e14, rather than base 10.
* Add fast path for integers to BigNumber constructor.
* Incorporate the library into the online documentation.
#### 1.5.0
* 13/11/2014
* Add `toJSON` and `decimalPlaces` methods.
#### 1.4.1
* 08/06/2014
* Amend README.
#### 1.4.0
* 08/05/2014
* Add `toNumber`.
#### 1.3.0
* 08/11/2013
* Ensure correct rounding of `sqrt` in all, rather than almost all, cases.
* Maximum radix to 64.
#### 1.2.1
* 17/10/2013
* Sign of zero when x < 0 and x + (-x) = 0.
#### 1.2.0
* 19/9/2013
* Throw Error objects for stack.
#### 1.1.1
* 22/8/2013
* Show original value in constructor error message.
#### 1.1.0
* 1/8/2013
* Allow numbers with trailing radix point.
#### 1.0.1
* Bugfix: error messages with incorrect method name
#### 1.0.0
* 8/11/2012
* Initial release
#### 9.0.0
* 27/05/2019
* For compatibility with legacy browsers, remove `Symbol` references.
#### 8.1.1
* 24/02/2019
* [BUGFIX] #222 Restore missing `var` to `export BigNumber`.
* Allow any key in BigNumber.Instance in *bignumber.d.ts*.
#### 8.1.0
* 23/02/2019
* [NEW FEATURE] #220 Create a BigNumber using `{s, e, c}`.
* [NEW FEATURE] `isBigNumber`: if `BigNumber.DEBUG` is `true`, also check that the BigNumber instance is well-formed.
* Remove `instanceof` checks; just use `_isBigNumber` to identify a BigNumber instance.
* Add `_isBigNumber` to prototype in *bignumber.mjs*.
* Add tests for BigNumber creation from object.
* Update *API.html*.
#### 8.0.2
* 13/01/2019
* #209 `toPrecision` without argument should follow `toString`.
* Improve *Use* section of *README*.
* Optimise `toString(10)`.
* Add verson number to API doc.
#### 8.0.1
* 01/11/2018
* Rest parameter must be array type in *bignumber.d.ts*.
#### 8.0.0
* 01/11/2018
* [NEW FEATURE] Add `BigNumber.sum` method.
* [NEW FEATURE]`toFormat`: add `prefix` and `suffix` options.
* [NEW FEATURE] #178 Pass custom formatting to `toFormat`.
* [BREAKING CHANGE] #184 `toFraction`: return array of BigNumbers not strings.
* [NEW FEATURE] #185 Enable overwrite of `valueOf` to prevent accidental addition to string.
* #183 Add Node.js `crypto` requirement to documentation.
* [BREAKING CHANGE] #198 Disallow signs and whitespace in custom alphabet.
* [NEW FEATURE] #188 Implement `util.inspect.custom` for Node.js REPL.
* #170 Make `isBigNumber` a type guard in *bignumber.d.ts*.
* [BREAKING CHANGE] `BigNumber.min` and `BigNumber.max`: don't accept an array.
* Update *.travis.yml*.
* Remove *bower.json*.
#### 7.2.1
* 24/05/2018
* Add `browser` field to *package.json*.
#### 7.2.0
* 22/05/2018
* #166 Correct *.mjs* file. Remove extension from `main` field in *package.json*.
#### 7.1.0
* 18/05/2018
* Add `module` field to *package.json* for *bignumber.mjs*.
#### 7.0.2
* 17/05/2018
* #165 Bugfix: upper-case letters for bases 11-36 in a custom alphabet.
* Add note to *README* regarding creating BigNumbers from Number values.
#### 7.0.1
* 26/04/2018
* #158 Fix global object variable name typo.
#### 7.0.0
* 26/04/2018
* #143 Remove global BigNumber from typings.
* #144 Enable compatibility with `Object.freeze(Object.prototype)`.
* #148 #123 #11 Only throw on a number primitive with more than 15 significant digits if `BigNumber.DEBUG` is `true`.
* Only throw on an invalid BigNumber value if `BigNumber.DEBUG` is `true`. Return BigNumber `NaN` instead.
* #154 `exponentiatedBy`: allow BigNumber exponent.
* #156 Prevent Content Security Policy *unsafe-eval* issue.
* `toFraction`: allow `Infinity` maximum denominator.
* Comment-out some excess tests to reduce test time.
* Amend indentation and other spacing.
#### 6.0.0
* 26/01/2018
* #137 Implement `APLHABET` configuration option.
* Remove `ERRORS` configuration option.
* Remove `toDigits` method; extend `precision` method accordingly.
* Remove s`round` method; extend `decimalPlaces` method accordingly.
* Remove methods: `ceil`, `floor`, and `truncated`.
* Remove method aliases: `add`, `cmp`, `isInt`, `isNeg`, `trunc`, `mul`, `neg` and `sub`.
* Rename methods: `shift` to `shiftedBy`, `another` to `clone`, `toPower` to `exponentiatedBy`, and `equals` to `isEqualTo`.
* Rename methods: add `is` prefix to `greaterThan`, `greaterThanOrEqualTo`, `lessThan` and `lessThanOrEqualTo`.
* Add methods: `multipliedBy`, `isBigNumber`, `isPositive`, `integerValue`, `maximum` and `minimum`.
* Refactor test suite.
* Add *CHANGELOG.md*.
* Rewrite *bignumber.d.ts*.
* Redo API image.
#### 5.0.0
* 27/11/2017
* #81 Don't throw on constructor call without `new`.
#### 4.1.0
* 26/09/2017
* Remove node 0.6 from *.travis.yml*.
* Add *bignumber.mjs*.
#### 4.0.4
* 03/09/2017
* Add missing aliases to *bignumber.d.ts*.
#### 4.0.3
* 30/08/2017
* Add types: *bignumber.d.ts*.
#### 4.0.2
* 03/05/2017
* #120 Workaround Safari/Webkit bug.
#### 4.0.1
* 05/04/2017
* #121 BigNumber.default to BigNumber['default'].
#### 4.0.0
* 09/01/2017
* Replace BigNumber.isBigNumber method with isBigNumber prototype property.
#### 3.1.2
* 08/01/2017
* Minor documentation edit.
#### 3.1.1
* 08/01/2017
* Uncomment `isBigNumber` tests.
* Ignore dot files.
#### 3.1.0
* 08/01/2017
* Add `isBigNumber` method.
#### 3.0.2
* 08/01/2017
* Bugfix: Possible incorrect value of `ERRORS` after a `BigNumber.another` call (due to `parseNumeric` declaration in outer scope).
#### 3.0.1
* 23/11/2016
* Apply fix for old ipads with `%` issue, see #57 and #102.
* Correct error message.
#### 3.0.0
* 09/11/2016
* Remove `require('crypto')` - leave it to the user.
* Add `BigNumber.set` as `BigNumber.config` alias.
* Default `POW_PRECISION` to `0`.
#### 2.4.0
* 14/07/2016
* #97 Add exports to support ES6 imports.
#### 2.3.0
* 07/03/2016
* #86 Add modulus parameter to `toPower`.
#### 2.2.0
* 03/03/2016
* #91 Permit larger JS integers.
#### 2.1.4
* 15/12/2015
* Correct UMD.
#### 2.1.3
* 13/12/2015
* Refactor re global object and crypto availability when bundling.
#### 2.1.2
* 10/12/2015
* Bugfix: `window.crypto` not assigned to `crypto`.
#### 2.1.1
* 09/12/2015
* Prevent code bundler from adding `crypto` shim.
#### 2.1.0
* 26/10/2015
* For `valueOf` and `toJSON`, include the minus sign with negative zero.
#### 2.0.8
* 2/10/2015
* Internal round function bugfix.
#### 2.0.6
* 31/03/2015
* Add bower.json. Tweak division after in-depth review.
#### 2.0.5
* 25/03/2015
* Amend README. Remove bitcoin address.
#### 2.0.4
* 25/03/2015
* Critical bugfix #58: division.
#### 2.0.3
* 18/02/2015
* Amend README. Add source map.
#### 2.0.2
* 18/02/2015
* Correct links.
#### 2.0.1
* 18/02/2015
* Add `max`, `min`, `precision`, `random`, `shiftedBy`, `toDigits` and `truncated` methods.
* Add the short-forms: `add`, `mul`, `sd`, `sub` and `trunc`.
* Add an `another` method to enable multiple independent constructors to be created.
* Add support for the base 2, 8 and 16 prefixes `0b`, `0o` and `0x`.
* Enable a rounding mode to be specified as a second parameter to `toExponential`, `toFixed`, `toFormat` and `toPrecision`.
* Add a `CRYPTO` configuration property so cryptographically-secure pseudo-random number generation can be specified.
* Add a `MODULO_MODE` configuration property to enable the rounding mode used by the `modulo` operation to be specified.
* Add a `POW_PRECISION` configuration property to enable the number of significant digits calculated by the power operation to be limited.
* Improve code quality.
* Improve documentation.
#### 2.0.0
* 29/12/2014
* Add `dividedToIntegerBy`, `isInteger` and `toFormat` methods.
* Remove the following short-forms: `isF`, `isZ`, `toE`, `toF`, `toFr`, `toN`, `toP`, `toS`.
* Store a BigNumber's coefficient in base 1e14, rather than base 10.
* Add fast path for integers to BigNumber constructor.
* Incorporate the library into the online documentation.
#### 1.5.0
* 13/11/2014
* Add `toJSON` and `decimalPlaces` methods.
#### 1.4.1
* 08/06/2014
* Amend README.
#### 1.4.0
* 08/05/2014
* Add `toNumber`.
#### 1.3.0
* 08/11/2013
* Ensure correct rounding of `sqrt` in all, rather than almost all, cases.
* Maximum radix to 64.
#### 1.2.1
* 17/10/2013
* Sign of zero when x < 0 and x + (-x) = 0.
#### 1.2.0
* 19/9/2013
* Throw Error objects for stack.
#### 1.1.1
* 22/8/2013
* Show original value in constructor error message.
#### 1.1.0
* 1/8/2013
* Allow numbers with trailing radix point.
#### 1.0.1
* Bugfix: error messages with incorrect method name
#### 1.0.0
* 8/11/2012
* Initial release
+23 -23
View File
@@ -1,23 +1,23 @@
The MIT Licence.
Copyright (c) 2019 Michael Mclaughlin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The MIT Licence.
Copyright (c) 2019 Michael Mclaughlin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+268 -268
View File
@@ -1,268 +1,268 @@
![bignumber.js](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/bignumberjs.png)
A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic.
[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.svg)](https://travis-ci.org/MikeMcl/bignumber.js)
<br />
## Features
- Integers and decimals
- Simple API but full-featured
- Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal
- 8 KB minified and gzipped
- Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type
- Includes a `toFraction` and a correctly-rounded `squareRoot` method
- Supports cryptographically-secure pseudo-random number generation
- No dependencies
- Wide platform compatibility: uses JavaScript 1.5 (ECMAScript 3) features only
- Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set
![API](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/API.png)
If a smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/).
It's less than half the size but only works with decimal numbers and only has half the methods.
It also does not allow `NaN` or `Infinity`, or have the configuration options of this library.
See also [decimal.js](https://github.com/MikeMcl/decimal.js/), which among other things adds support for non-integer powers, and performs all operations to a specified number of significant digits.
## Load
The library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*).
Browser:
```html
<script src='path/to/bignumber.js'></script>
```
[Node.js](http://nodejs.org):
```bash
$ npm install bignumber.js
```
```javascript
const BigNumber = require('bignumber.js');
```
ES6 module:
```javascript
import BigNumber from "./bignumber.mjs"
```
AMD loader libraries such as [requireJS](http://requirejs.org/):
```javascript
require(['bignumber'], function(BigNumber) {
// Use BigNumber here in local scope. No global BigNumber.
});
```
## Use
The library exports a single constructor function, [`BigNumber`](http://mikemcl.github.io/bignumber.js/#bignumber), which accepts a value of type Number, String or BigNumber,
```javascript
let x = new BigNumber(123.4567);
let y = BigNumber('123456.7e-3');
let z = new BigNumber(x);
x.isEqualTo(y) && y.isEqualTo(z) && x.isEqualTo(z); // true
```
To get the string value of a BigNumber use [`toString()`](http://mikemcl.github.io/bignumber.js/#toS) or [`toFixed()`](http://mikemcl.github.io/bignumber.js/#toFix). Using `toFixed()` prevents exponential notation being returned, no matter how large or small the value.
```javascript
let x = new BigNumber('1111222233334444555566');
x.toString(); // "1.111222233334444555566e+21"
x.toFixed(); // "1111222233334444555566"
```
If the limited precision of Number values is not well understood, it is recommended to create BigNumbers from String values rather than Number values to avoid a potential loss of precision.
*In all further examples below, `let`, semicolons and `toString` calls are not shown. If a commented-out value is in quotes it means `toString` has been called on the preceding expression.*
```javascript
// Precision loss from using numeric literals with more than 15 significant digits.
new BigNumber(1.0000000000000001) // '1'
new BigNumber(88259496234518.57) // '88259496234518.56'
new BigNumber(99999999999999999999) // '100000000000000000000'
// Precision loss from using numeric literals outside the range of Number values.
new BigNumber(2e+308) // 'Infinity'
new BigNumber(1e-324) // '0'
// Precision loss from the unexpected result of arithmetic with Number values.
new BigNumber(0.7 + 0.1) // '0.7999999999999999'
```
When creating a BigNumber from a Number, note that a BigNumber is created from a Number's decimal `toString()` value not from its underlying binary value. If the latter is required, then pass the Number's `toString(2)` value and specify base 2.
```javascript
new BigNumber(Number.MAX_VALUE.toString(2), 2)
```
BigNumbers can be created from values in bases from 2 to 36. See [`ALPHABET`](http://mikemcl.github.io/bignumber.js/#alphabet) to extend this range.
```javascript
a = new BigNumber(1011, 2) // "11"
b = new BigNumber('zz.9', 36) // "1295.25"
c = a.plus(b) // "1306.25"
```
Performance is better if base 10 is NOT specified for decimal values. Only specify base 10 when it is desired that the number of decimal places of the input value be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting.
A BigNumber is immutable in the sense that it is not changed by its methods.
```javascript
0.3 - 0.1 // 0.19999999999999998
x = new BigNumber(0.3)
x.minus(0.1) // "0.2"
x // "0.3"
```
The methods that return a BigNumber can be chained.
```javascript
x.dividedBy(y).plus(z).times(9)
x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').integerValue()
```
Some of the longer method names have a shorter alias.
```javascript
x.squareRoot().dividedBy(y).exponentiatedBy(3).isEqualTo(x.sqrt().div(y).pow(3)) // true
x.modulo(y).multipliedBy(z).eq(x.mod(y).times(z)) // true
```
As with JavaScript's Number type, there are [`toExponential`](http://mikemcl.github.io/bignumber.js/#toE), [`toFixed`](http://mikemcl.github.io/bignumber.js/#toFix) and [`toPrecision`](http://mikemcl.github.io/bignumber.js/#toP) methods.
```javascript
x = new BigNumber(255.5)
x.toExponential(5) // "2.55500e+2"
x.toFixed(5) // "255.50000"
x.toPrecision(5) // "255.50"
x.toNumber() // 255.5
```
A base can be specified for [`toString`](http://mikemcl.github.io/bignumber.js/#toS). Performance is better if base 10 is NOT specified, i.e. use `toString()` not `toString(10)`. Only specify base 10 when it is desired that the number of decimal places be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting.
```javascript
x.toString(16) // "ff.8"
```
There is a [`toFormat`](http://mikemcl.github.io/bignumber.js/#toFor) method which may be useful for internationalisation.
```javascript
y = new BigNumber('1234567.898765')
y.toFormat(2) // "1,234,567.90"
```
The maximum number of decimal places of the result of an operation involving division (i.e. a division, square root, base conversion or negative power operation) is set using the `set` or `config` method of the `BigNumber` constructor.
The other arithmetic operations always give the exact result.
```javascript
BigNumber.set({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 })
x = new BigNumber(2)
y = new BigNumber(3)
z = x.dividedBy(y) // "0.6666666667"
z.squareRoot() // "0.8164965809"
z.exponentiatedBy(-3) // "3.3749999995"
z.toString(2) // "0.1010101011"
z.multipliedBy(z) // "0.44444444448888888889"
z.multipliedBy(z).decimalPlaces(10) // "0.4444444445"
```
There is a [`toFraction`](http://mikemcl.github.io/bignumber.js/#toFr) method with an optional *maximum denominator* argument
```javascript
y = new BigNumber(355)
pi = y.dividedBy(113) // "3.1415929204"
pi.toFraction() // [ "7853982301", "2500000000" ]
pi.toFraction(1000) // [ "355", "113" ]
```
and [`isNaN`](http://mikemcl.github.io/bignumber.js/#isNaN) and [`isFinite`](http://mikemcl.github.io/bignumber.js/#isF) methods, as `NaN` and `Infinity` are valid `BigNumber` values.
```javascript
x = new BigNumber(NaN) // "NaN"
y = new BigNumber(Infinity) // "Infinity"
x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true
```
The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign.
```javascript
x = new BigNumber(-123.456);
x.c // [ 123, 45600000000000 ] coefficient (i.e. significand)
x.e // 2 exponent
x.s // -1 sign
```
For advanced usage, multiple BigNumber constructors can be created, each with their own independent configuration.
```javascript
// Set DECIMAL_PLACES for the original BigNumber constructor
BigNumber.set({ DECIMAL_PLACES: 10 })
// Create another BigNumber constructor, optionally passing in a configuration object
BN = BigNumber.clone({ DECIMAL_PLACES: 5 })
x = new BigNumber(1)
y = new BN(1)
x.div(3) // '0.3333333333'
y.div(3) // '0.33333'
```
For further information see the [API](http://mikemcl.github.io/bignumber.js/) reference in the *doc* directory.
## Test
The *test/modules* directory contains the test scripts for each method.
The tests can be run with Node.js or a browser. For Node.js use
$ npm test
or
$ node test/test
To test a single method, use, for example
$ node test/methods/toFraction
For the browser, open *test/test.html*.
## Build
For Node, if [uglify-js](https://github.com/mishoo/UglifyJS2) is installed
npm install uglify-js -g
then
npm run build
will create *bignumber.min.js*.
A source map will also be created in the root directory.
## Feedback
Open an issue, or email
Michael
<a href="mailto:M8ch88l@gmail.com">M8ch88l@gmail.com</a>
## Licence
The MIT Licence.
See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE).
![bignumber.js](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/bignumberjs.png)
A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic.
[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.svg)](https://travis-ci.org/MikeMcl/bignumber.js)
<br />
## Features
- Integers and decimals
- Simple API but full-featured
- Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal
- 8 KB minified and gzipped
- Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type
- Includes a `toFraction` and a correctly-rounded `squareRoot` method
- Supports cryptographically-secure pseudo-random number generation
- No dependencies
- Wide platform compatibility: uses JavaScript 1.5 (ECMAScript 3) features only
- Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set
![API](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/API.png)
If a smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/).
It's less than half the size but only works with decimal numbers and only has half the methods.
It also does not allow `NaN` or `Infinity`, or have the configuration options of this library.
See also [decimal.js](https://github.com/MikeMcl/decimal.js/), which among other things adds support for non-integer powers, and performs all operations to a specified number of significant digits.
## Load
The library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*).
Browser:
```html
<script src='path/to/bignumber.js'></script>
```
[Node.js](http://nodejs.org):
```bash
$ npm install bignumber.js
```
```javascript
const BigNumber = require('bignumber.js');
```
ES6 module:
```javascript
import BigNumber from "./bignumber.mjs"
```
AMD loader libraries such as [requireJS](http://requirejs.org/):
```javascript
require(['bignumber'], function(BigNumber) {
// Use BigNumber here in local scope. No global BigNumber.
});
```
## Use
The library exports a single constructor function, [`BigNumber`](http://mikemcl.github.io/bignumber.js/#bignumber), which accepts a value of type Number, String or BigNumber,
```javascript
let x = new BigNumber(123.4567);
let y = BigNumber('123456.7e-3');
let z = new BigNumber(x);
x.isEqualTo(y) && y.isEqualTo(z) && x.isEqualTo(z); // true
```
To get the string value of a BigNumber use [`toString()`](http://mikemcl.github.io/bignumber.js/#toS) or [`toFixed()`](http://mikemcl.github.io/bignumber.js/#toFix). Using `toFixed()` prevents exponential notation being returned, no matter how large or small the value.
```javascript
let x = new BigNumber('1111222233334444555566');
x.toString(); // "1.111222233334444555566e+21"
x.toFixed(); // "1111222233334444555566"
```
If the limited precision of Number values is not well understood, it is recommended to create BigNumbers from String values rather than Number values to avoid a potential loss of precision.
*In all further examples below, `let`, semicolons and `toString` calls are not shown. If a commented-out value is in quotes it means `toString` has been called on the preceding expression.*
```javascript
// Precision loss from using numeric literals with more than 15 significant digits.
new BigNumber(1.0000000000000001) // '1'
new BigNumber(88259496234518.57) // '88259496234518.56'
new BigNumber(99999999999999999999) // '100000000000000000000'
// Precision loss from using numeric literals outside the range of Number values.
new BigNumber(2e+308) // 'Infinity'
new BigNumber(1e-324) // '0'
// Precision loss from the unexpected result of arithmetic with Number values.
new BigNumber(0.7 + 0.1) // '0.7999999999999999'
```
When creating a BigNumber from a Number, note that a BigNumber is created from a Number's decimal `toString()` value not from its underlying binary value. If the latter is required, then pass the Number's `toString(2)` value and specify base 2.
```javascript
new BigNumber(Number.MAX_VALUE.toString(2), 2)
```
BigNumbers can be created from values in bases from 2 to 36. See [`ALPHABET`](http://mikemcl.github.io/bignumber.js/#alphabet) to extend this range.
```javascript
a = new BigNumber(1011, 2) // "11"
b = new BigNumber('zz.9', 36) // "1295.25"
c = a.plus(b) // "1306.25"
```
Performance is better if base 10 is NOT specified for decimal values. Only specify base 10 when it is desired that the number of decimal places of the input value be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting.
A BigNumber is immutable in the sense that it is not changed by its methods.
```javascript
0.3 - 0.1 // 0.19999999999999998
x = new BigNumber(0.3)
x.minus(0.1) // "0.2"
x // "0.3"
```
The methods that return a BigNumber can be chained.
```javascript
x.dividedBy(y).plus(z).times(9)
x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').integerValue()
```
Some of the longer method names have a shorter alias.
```javascript
x.squareRoot().dividedBy(y).exponentiatedBy(3).isEqualTo(x.sqrt().div(y).pow(3)) // true
x.modulo(y).multipliedBy(z).eq(x.mod(y).times(z)) // true
```
As with JavaScript's Number type, there are [`toExponential`](http://mikemcl.github.io/bignumber.js/#toE), [`toFixed`](http://mikemcl.github.io/bignumber.js/#toFix) and [`toPrecision`](http://mikemcl.github.io/bignumber.js/#toP) methods.
```javascript
x = new BigNumber(255.5)
x.toExponential(5) // "2.55500e+2"
x.toFixed(5) // "255.50000"
x.toPrecision(5) // "255.50"
x.toNumber() // 255.5
```
A base can be specified for [`toString`](http://mikemcl.github.io/bignumber.js/#toS). Performance is better if base 10 is NOT specified, i.e. use `toString()` not `toString(10)`. Only specify base 10 when it is desired that the number of decimal places be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting.
```javascript
x.toString(16) // "ff.8"
```
There is a [`toFormat`](http://mikemcl.github.io/bignumber.js/#toFor) method which may be useful for internationalisation.
```javascript
y = new BigNumber('1234567.898765')
y.toFormat(2) // "1,234,567.90"
```
The maximum number of decimal places of the result of an operation involving division (i.e. a division, square root, base conversion or negative power operation) is set using the `set` or `config` method of the `BigNumber` constructor.
The other arithmetic operations always give the exact result.
```javascript
BigNumber.set({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 })
x = new BigNumber(2)
y = new BigNumber(3)
z = x.dividedBy(y) // "0.6666666667"
z.squareRoot() // "0.8164965809"
z.exponentiatedBy(-3) // "3.3749999995"
z.toString(2) // "0.1010101011"
z.multipliedBy(z) // "0.44444444448888888889"
z.multipliedBy(z).decimalPlaces(10) // "0.4444444445"
```
There is a [`toFraction`](http://mikemcl.github.io/bignumber.js/#toFr) method with an optional *maximum denominator* argument
```javascript
y = new BigNumber(355)
pi = y.dividedBy(113) // "3.1415929204"
pi.toFraction() // [ "7853982301", "2500000000" ]
pi.toFraction(1000) // [ "355", "113" ]
```
and [`isNaN`](http://mikemcl.github.io/bignumber.js/#isNaN) and [`isFinite`](http://mikemcl.github.io/bignumber.js/#isF) methods, as `NaN` and `Infinity` are valid `BigNumber` values.
```javascript
x = new BigNumber(NaN) // "NaN"
y = new BigNumber(Infinity) // "Infinity"
x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true
```
The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign.
```javascript
x = new BigNumber(-123.456);
x.c // [ 123, 45600000000000 ] coefficient (i.e. significand)
x.e // 2 exponent
x.s // -1 sign
```
For advanced usage, multiple BigNumber constructors can be created, each with their own independent configuration.
```javascript
// Set DECIMAL_PLACES for the original BigNumber constructor
BigNumber.set({ DECIMAL_PLACES: 10 })
// Create another BigNumber constructor, optionally passing in a configuration object
BN = BigNumber.clone({ DECIMAL_PLACES: 5 })
x = new BigNumber(1)
y = new BN(1)
x.div(3) // '0.3333333333'
y.div(3) // '0.33333'
```
For further information see the [API](http://mikemcl.github.io/bignumber.js/) reference in the *doc* directory.
## Test
The *test/modules* directory contains the test scripts for each method.
The tests can be run with Node.js or a browser. For Node.js use
$ npm test
or
$ node test/test
To test a single method, use, for example
$ node test/methods/toFraction
For the browser, open *test/test.html*.
## Build
For Node, if [uglify-js](https://github.com/mishoo/UglifyJS2) is installed
npm install uglify-js -g
then
npm run build
will create *bignumber.min.js*.
A source map will also be created in the root directory.
## Feedback
Open an issue, or email
Michael
<a href="mailto:M8ch88l@gmail.com">M8ch88l@gmail.com</a>
## Licence
The MIT Licence.
See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE).
+1829 -1829
View File
File diff suppressed because it is too large Load Diff
+2902 -2902
View File
File diff suppressed because it is too large Load Diff
+2888 -2888
View File
File diff suppressed because it is too large Load Diff
+2237 -2237
View File
File diff suppressed because it is too large Load Diff
+40 -40
View File
@@ -1,40 +1,40 @@
{
"name": "bignumber.js",
"description": "A library for arbitrary-precision decimal and non-decimal arithmetic",
"version": "9.0.0",
"keywords": [
"arbitrary",
"precision",
"arithmetic",
"big",
"number",
"decimal",
"float",
"biginteger",
"bigdecimal",
"bignumber",
"bigint",
"bignum"
],
"repository": {
"type": "git",
"url": "https://github.com/MikeMcl/bignumber.js.git"
},
"main": "bignumber",
"module": "bignumber.mjs",
"browser": "bignumber.js",
"types": "bignumber.d.ts",
"author": {
"name": "Michael Mclaughlin",
"email": "M8ch88l@gmail.com"
},
"engines": {
"node": "*"
},
"license": "MIT",
"scripts": {
"test": "node test/test",
"build": "uglifyjs bignumber.js --source-map -c -m -o bignumber.min.js"
},
"dependencies": {}
}
{
"name": "bignumber.js",
"description": "A library for arbitrary-precision decimal and non-decimal arithmetic",
"version": "9.0.0",
"keywords": [
"arbitrary",
"precision",
"arithmetic",
"big",
"number",
"decimal",
"float",
"biginteger",
"bigdecimal",
"bignumber",
"bigint",
"bignum"
],
"repository": {
"type": "git",
"url": "https://github.com/MikeMcl/bignumber.js.git"
},
"main": "bignumber",
"module": "bignumber.mjs",
"browser": "bignumber.js",
"types": "bignumber.d.ts",
"author": {
"name": "Michael Mclaughlin",
"email": "M8ch88l@gmail.com"
},
"engines": {
"node": "*"
},
"license": "MIT",
"scripts": {
"test": "node test/test",
"build": "uglifyjs bignumber.js --source-map -c -m -o bignumber.min.js"
},
"dependencies": {}
}
+38 -38
View File
@@ -1,39 +1,39 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = intval($_POST['amount']);
try {
$db->beginTransaction();
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$player_id = $game['current_player_id'];
// 2. Retirer l'argent au joueur
$stmt = $db->prepare("UPDATE players SET money = money - ? WHERE id = ?");
$stmt->execute([$amount, $player_id]);
// 3. Ajouter l'argent au POT de la partie
$stmt = $db->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
// 4. Mettre à jour la mise actuelle (last_bet) pour les suivants
$stmt = $db->prepare("UPDATE games SET last_bet = ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
// 5. Mettre à jour la mise actuelle du joueur
$stmt = $db->prepare("UPDATE players SET current_bet = current_bet + ? WHERE id = ?");
$stmt->execute([$amount, $player_id]);
$db->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
$db->rollBack();
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = intval($_POST['amount']);
try {
$db->beginTransaction();
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$player_id = $game['current_player_id'];
// 2. Retirer l'argent au joueur
$stmt = $db->prepare("UPDATE players SET money = money - ? WHERE id = ?");
$stmt->execute([$amount, $player_id]);
// 3. Ajouter l'argent au POT de la partie
$stmt = $db->prepare("UPDATE games SET pot = pot + ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
// 4. Mettre à jour la mise actuelle (last_bet) pour les suivants
$stmt = $db->prepare("UPDATE games SET last_bet = ? WHERE id = ?");
$stmt->execute([$amount, $game_id]);
// 5. Mettre à jour la mise actuelle du joueur
$stmt = $db->prepare("UPDATE players SET current_bet = current_bet + ? WHERE id = ?");
$stmt->execute([$amount, $player_id]);
$db->commit();
echo json_encode(['success' => true]);
} catch (Exception $e) {
$db->rollBack();
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
+24 -24
View File
@@ -1,25 +1,25 @@
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Retirer de l'argent au joueur actuel
$stmt = $db->prepare("UPDATE players SET money = money - ? WHERE id = ?");
$stmt->execute([$amount, $current_player_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
$amount = isset($_POST['amount']) ? intval($_POST['amount']) : 0;
try {
// 1. Récupérer l'ID du joueur actuel
$stmt = $db->prepare("SELECT current_player_id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game = $stmt->fetch();
$current_player_id = $game['current_player_id'];
// 2. Retirer de l'argent au joueur actuel
$stmt = $db->prepare("UPDATE players SET money = money - ? WHERE id = ?");
$stmt->execute([$amount, $current_player_id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+45 -45
View File
@@ -1,46 +1,46 @@
<?php
require_once 'db.php';
// Création d'un partie
$start_money = $_POST['start_money'];
$start_blind = $_POST['blind'];
$stmt = $db->prepare("INSERT INTO games (start_money, start_blind) VALUES (:start_money, :start_blind)");
$stmt->execute([
':start_money' => $start_money,
':start_blind' => $start_blind
]);
// Récupération de l'ID de la partie créée
$game_id = $db->lastInsertId();
// Création des joueurs
$players = $_POST['players'];
foreach ($players as $player_name) {
$stmt = $db->prepare("INSERT INTO players (name, game_id, money) VALUES (:name, :game_id, :start_money)");
$stmt->execute([
':name' => $player_name,
':game_id' => $game_id,
':start_money' => $start_money
]);
}
// Définir le premier joueur comme dealer
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$first_player = $stmt->fetch();
$first_player_id = $first_player['id'];
$stmt = $db->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$first_player_id, $game_id]);
$stmt = $db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
$stmt->execute([$first_player_id]);
// Redirection vers la page de jeu
header("Location: game.php?game_id=$game_id");
session_start();
$_SESSION['game_id'] = $game_id; // Stocker l'ID de la partie dans la session pour y accéder plus tard
exit();
<?php
require_once 'db.php';
// Création d'un partie
$start_money = $_POST['start_money'];
$start_blind = $_POST['blind'];
$stmt = $db->prepare("INSERT INTO games (start_money, start_blind) VALUES (:start_money, :start_blind)");
$stmt->execute([
':start_money' => $start_money,
':start_blind' => $start_blind
]);
// Récupération de l'ID de la partie créée
$game_id = $db->lastInsertId();
// Création des joueurs
$players = $_POST['players'];
foreach ($players as $player_name) {
$stmt = $db->prepare("INSERT INTO players (name, game_id, money) VALUES (:name, :game_id, :start_money)");
$stmt->execute([
':name' => $player_name,
':game_id' => $game_id,
':start_money' => $start_money
]);
}
// Définir le premier joueur comme dealer
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$first_player = $stmt->fetch();
$first_player_id = $first_player['id'];
$stmt = $db->prepare("UPDATE games SET current_player_id = ? WHERE id = ?");
$stmt->execute([$first_player_id, $game_id]);
$stmt = $db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
$stmt->execute([$first_player_id]);
// Redirection vers la page de jeu
header("Location: game.php?game_id=$game_id");
session_start();
$_SESSION['game_id'] = $game_id; // Stocker l'ID de la partie dans la session pour y accéder plus tard
exit();
?>
+62 -62
View File
@@ -1,63 +1,63 @@
<?php
require_once 'db.php';
session_start();
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Vérifier que la partie existe
$stmt = $db->prepare("SELECT id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
if (!$stmt->fetch()) {
throw new Exception("La partie n'existe pas.");
}
// 2. Faire en sorte que le dealer de la partie soit le joueur suivant l'actuel dealer
$stmt = $db->prepare("SELECT id FROM players WHERE is_dealer = 1 AND game_id = ?");
$stmt->execute([$game_id]);
$current_dealer = $stmt->fetch();
if ($current_dealer) {
$current_dealer_id = $current_dealer['id'];
// On remet à 0 le dealer actuel
$stmt = $db->prepare("UPDATE players SET is_dealer = 0 WHERE id = ?");
$stmt->execute([$current_dealer_id]);
// On cherche le prochain dealer
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_dealer_id]);
$next_dealer = $stmt->fetch();
if (!$next_dealer) { // Si on est au dernier, on revient au premier
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next_dealer = $stmt->fetch();
}
$next_dealer_id = $next_dealer['id'];
// On met à jour le nouveau dealer
$stmt = $db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
$stmt->execute([$next_dealer_id]);
} else {
// Si aucun dealer n'est défini, on choisit le premier joueur comme dealer
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$first_player = $stmt->fetch();
if ($first_player) {
$first_player_id = $first_player['id'];
$stmt = $db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
$stmt->execute([$first_player_id]);
} else {
throw new Exception("Aucun joueur dans la partie pour devenir dealer.");
}
}
// 3. On réveille les joueurs endormis
$stmt = $db->prepare("UPDATE players SET is_folded = 0 WHERE game_id = ?");
$stmt->execute([$game_id]);
echo json_encode(['success' => true, 'message' => "Nouvelle partie commencée, dealer mis à jour."]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php';
session_start();
header('Content-Type: application/json');
$game_id = intval($_POST['game_id']);
try {
// 1. Vérifier que la partie existe
$stmt = $db->prepare("SELECT id FROM games WHERE id = ?");
$stmt->execute([$game_id]);
if (!$stmt->fetch()) {
throw new Exception("La partie n'existe pas.");
}
// 2. Faire en sorte que le dealer de la partie soit le joueur suivant l'actuel dealer
$stmt = $db->prepare("SELECT id FROM players WHERE is_dealer = 1 AND game_id = ?");
$stmt->execute([$game_id]);
$current_dealer = $stmt->fetch();
if ($current_dealer) {
$current_dealer_id = $current_dealer['id'];
// On remet à 0 le dealer actuel
$stmt = $db->prepare("UPDATE players SET is_dealer = 0 WHERE id = ?");
$stmt->execute([$current_dealer_id]);
// On cherche le prochain dealer
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? AND id > ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id, $current_dealer_id]);
$next_dealer = $stmt->fetch();
if (!$next_dealer) { // Si on est au dernier, on revient au premier
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$next_dealer = $stmt->fetch();
}
$next_dealer_id = $next_dealer['id'];
// On met à jour le nouveau dealer
$stmt = $db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
$stmt->execute([$next_dealer_id]);
} else {
// Si aucun dealer n'est défini, on choisit le premier joueur comme dealer
$stmt = $db->prepare("SELECT id FROM players WHERE game_id = ? ORDER BY id ASC LIMIT 1");
$stmt->execute([$game_id]);
$first_player = $stmt->fetch();
if ($first_player) {
$first_player_id = $first_player['id'];
$stmt = $db->prepare("UPDATE players SET is_dealer = 1 WHERE id = ?");
$stmt->execute([$first_player_id]);
} else {
throw new Exception("Aucun joueur dans la partie pour devenir dealer.");
}
}
// 3. On réveille les joueurs endormis
$stmt = $db->prepare("UPDATE players SET is_folded = 0 WHERE game_id = ?");
$stmt->execute([$game_id]);
echo json_encode(['success' => true, 'message' => "Nouvelle partie commencée, dealer mis à jour."]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+25 -25
View File
@@ -1,26 +1,26 @@
<?php
require_once 'db.php'; // On n'appelle plus config.php qui pollue avec son HTML
header('Content-Type: application/json');
try {
if (!isset($_POST['player_id'], $_POST['amount'])) {
echo json_encode(['success' => false, 'message' => 'Données manquantes']);
exit;
}
$player_id = intval($_POST['player_id']);
$amount = intval($_POST['amount']);
// On met à jour
$stmt = $db->prepare("UPDATE players SET money = money + :amount WHERE id = :id");
$stmt->execute([
':amount' => $amount,
':id' => $player_id
]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
<?php
require_once 'db.php'; // On n'appelle plus config.php qui pollue avec son HTML
header('Content-Type: application/json');
try {
if (!isset($_POST['player_id'], $_POST['amount'])) {
echo json_encode(['success' => false, 'message' => 'Données manquantes']);
exit;
}
$player_id = intval($_POST['player_id']);
$amount = intval($_POST['amount']);
// On met à jour
$stmt = $db->prepare("UPDATE players SET money = money + :amount WHERE id = :id");
$stmt->execute([
':amount' => $amount,
':id' => $player_id
]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
+59 -59
View File
@@ -1,60 +1,60 @@
<?php
session_start();
$game_id = isset($_GET['game_id']) ? $_GET['game_id'] :null;
$host = 'localhost';
$db = 'poker_paf';
$user = 'root';
$pass = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
// charger la BDD
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass, $options);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
die(json_encode(['error' => 'Connexion échouée']));
}
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
$stmt->execute([$game_id]);
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT name FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game_name = $stmt->fetchColumn();
// Récupération du game_id depuis les paramètres GET
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Choix du joueur - PokerPaf</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='css/playerSelector.css'>
</head>
<body>
<div class="container">
<button class="back-btn" onclick="window.location.href='index.html'">◀️ Retour à l'accueil</button>
<h1>Rejoindre la partie <?php echo htmlspecialchars($game_name); ?></h1>
<br>
<h2>Choix du joueur</h2>
<p>Veuillez cliquer sur le nom du joueur pour rejoindre la partie :</p>
<div class="player-selection">
<?php foreach ($players as $player): ?>
<button class="join-player-btn" onclick="window.location.href='game.html?game_id=<?php echo $game_id; ?>&player_id=<?php echo $player['id']; ?>'">
<?php echo htmlspecialchars($player['name']); ?>
</button>
<?php endforeach; ?>
</div>
</div>
</body>
<?php
session_start();
$game_id = isset($_GET['game_id']) ? $_GET['game_id'] :null;
$host = 'localhost';
$db = 'poker_paf';
$user = 'root';
$pass = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
// charger la BDD
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass, $options);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
die(json_encode(['error' => 'Connexion échouée']));
}
$stmt = $pdo->prepare("SELECT * FROM players WHERE game_id = ?");
$stmt->execute([$game_id]);
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("SELECT name FROM games WHERE id = ?");
$stmt->execute([$game_id]);
$game_name = $stmt->fetchColumn();
// Récupération du game_id depuis les paramètres GET
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Choix du joueur - PokerPaf</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' type='text/css' media='screen' href='css/playerSelector.css'>
</head>
<body>
<div class="container">
<button class="back-btn" onclick="window.location.href='index.html'">◀️ Retour à l'accueil</button>
<h1>Rejoindre la partie <?php echo htmlspecialchars($game_name); ?></h1>
<br>
<h2>Choix du joueur</h2>
<p>Veuillez cliquer sur le nom du joueur pour rejoindre la partie :</p>
<div class="player-selection">
<?php foreach ($players as $player): ?>
<button class="join-player-btn" onclick="window.location.href='game.html?game_id=<?php echo $game_id; ?>&player_id=<?php echo $player['id']; ?>'">
<?php echo htmlspecialchars($player['name']); ?>
</button>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
+52 -52
View File
@@ -1,53 +1,53 @@
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
$host = 'localhost'; $db = 'poker_paf'; $user = 'root'; $pass = '';
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
$game_id = $_GET['game_id'] ?? 0;
$last_state_hash = "";
while (true) {
// 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->execute([$game_id]);
$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->execute([$game_id]);
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 3. Typage propre AVANT de mettre dans le full_state
foreach ($players as &$player) {
$player['id'] = (int)$player['id'];
$player['money'] = (int)$player['money'];
$player['current_bet'] = (int)$player['current_bet'];
$player['is_dealer'] = (int)$player['is_dealer'];
$player['is_folded'] = (int)$player['is_folded'];
}
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));
if ($current_hash !== $last_state_hash) {
echo "data: " . json_encode($full_state) . "\n\n";
$last_state_hash = $current_hash;
// On force l'envoi
ob_flush();
flush();
}
// 6. Pause raisonnable (500ms) pour ne pas tuer le CPU/Base de données
sleep(0.01);
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
$host = 'localhost'; $db = 'poker_paf'; $user = 'root'; $pass = '';
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
$game_id = $_GET['game_id'] ?? 0;
$last_state_hash = "";
while (true) {
// 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->execute([$game_id]);
$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->execute([$game_id]);
$players = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 3. Typage propre AVANT de mettre dans le full_state
foreach ($players as &$player) {
$player['id'] = (int)$player['id'];
$player['money'] = (int)$player['money'];
$player['current_bet'] = (int)$player['current_bet'];
$player['is_dealer'] = (int)$player['is_dealer'];
$player['is_folded'] = (int)$player['is_folded'];
}
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));
if ($current_hash !== $last_state_hash) {
echo "data: " . json_encode($full_state) . "\n\n";
$last_state_hash = $current_hash;
// On force l'envoi
ob_flush();
flush();
}
// 6. Pause raisonnable (500ms) pour ne pas tuer le CPU/Base de données
sleep(0.01);
}
+167 -167
View File
@@ -1,167 +1,167 @@
[05-03-2026 - 06:45:46] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 06:45:46] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 06:45:46] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 06:45:46] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 06:45:46] [INFO]: logging in using static token
[05-03-2026 - 06:45:47] [INFO]: Shard ID None has connected to Gateway (Session ID: 3fcbaff82be1089a65ee9e39167873f0).
[05-03-2026 - 06:46:06] [DEBUG]: Re-initializing context...
[05-03-2026 - 06:46:06] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 06:46:06] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 06:46:06] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 06:46:06] [DEBUG]: Using HTTP scheme
[05-03-2026 - 06:46:06] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 06:46:06] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 06:46:06] [DEBUG]: Login successful
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 6
[05-03-2026 - 06:46:37] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 06:46:37] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 883
[05-03-2026 - 06:46:37] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 852
[05-03-2026 - 06:46:37] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 06:48:14] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 06:48:14] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 06:48:14] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 06:48:14] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 06:48:14] [INFO]: logging in using static token
[05-03-2026 - 06:48:15] [INFO]: Shard ID None has connected to Gateway (Session ID: 14436ec2092d5493b710dec84eeb3758).
[05-03-2026 - 06:48:22] [DEBUG]: Re-initializing context...
[05-03-2026 - 06:48:22] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 06:48:22] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 06:48:22] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 06:48:22] [DEBUG]: Using HTTP scheme
[05-03-2026 - 06:48:22] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 06:48:22] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 06:48:22] [DEBUG]: Login successful
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 6
[05-03-2026 - 06:48:52] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 06:48:52] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 06:48:52] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 852
[05-03-2026 - 06:48:52] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 06:49:12] [DEBUG]: Re-initializing context...
[05-03-2026 - 06:49:12] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 06:49:12] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 06:49:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 06:49:12] [DEBUG]: Using HTTP scheme
[05-03-2026 - 06:49:12] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 06:49:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 06:49:12] [DEBUG]: Login successful
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 06:49:42] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 06:49:42] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 06:49:42] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 854
[05-03-2026 - 06:49:42] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 07:01:15] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 07:01:15] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 07:01:15] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 07:01:15] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 07:01:15] [INFO]: logging in using static token
[05-03-2026 - 07:01:16] [INFO]: Shard ID None has connected to Gateway (Session ID: 863bc7befbdd673b5f817795a609eab0).
[05-03-2026 - 07:01:36] [DEBUG]: Re-initializing context...
[05-03-2026 - 07:01:36] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 07:01:36] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 07:01:36] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 07:01:36] [DEBUG]: Using HTTP scheme
[05-03-2026 - 07:01:36] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 07:01:36] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 07:01:36] [DEBUG]: Login successful
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 07:02:06] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 07:02:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 07:02:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 850
[05-03-2026 - 07:02:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 07:04:32] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 07:04:32] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 07:04:32] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 07:04:32] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 07:04:32] [INFO]: logging in using static token
[05-03-2026 - 07:04:33] [INFO]: Shard ID None has connected to Gateway (Session ID: 288eb0eab730ce742b2f27870ed9c3fb).
[05-03-2026 - 07:04:38] [DEBUG]: Re-initializing context...
[05-03-2026 - 07:04:38] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 07:04:38] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 07:04:38] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 07:04:38] [DEBUG]: Using HTTP scheme
[05-03-2026 - 07:04:38] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 07:04:38] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 07:04:38] [DEBUG]: Login successful
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 07:05:08] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 07:05:08] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 07:05:08] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 851
[05-03-2026 - 07:05:08] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 07:06:09] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 07:06:09] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 07:06:09] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 07:06:09] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 07:06:09] [INFO]: logging in using static token
[05-03-2026 - 07:06:10] [INFO]: Shard ID None has connected to Gateway (Session ID: 348f55012127dd658ddab46f89d29019).
[05-03-2026 - 07:06:12] [DEBUG]: Re-initializing context...
[05-03-2026 - 07:06:12] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 07:06:12] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 07:06:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 07:06:12] [DEBUG]: Using HTTP scheme
[05-03-2026 - 07:06:12] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 07:06:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 07:06:12] [DEBUG]: Login successful
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 07:06:42] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 07:06:43] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 885
[05-03-2026 - 07:06:43] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 820
[05-03-2026 - 07:06:43] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 08:20:45] [DEBUG]: Re-initializing context...
[05-03-2026 - 08:20:45] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 08:20:45] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 08:20:45] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 08:20:45] [DEBUG]: Using HTTP scheme
[05-03-2026 - 08:20:45] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 08:20:45] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 08:20:45] [DEBUG]: Login successful
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 08:21:15] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 08:21:15] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 08:21:15] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 949
[05-03-2026 - 08:21:15] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 231
[05-03-2026 - 08:23:34] [DEBUG]: Re-initializing context...
[05-03-2026 - 08:23:34] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 08:23:34] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 08:23:34] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 08:23:34] [DEBUG]: Using HTTP scheme
[05-03-2026 - 08:23:34] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 08:23:34] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 08:23:34] [DEBUG]: Login successful
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 08:24:04] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 08:24:04] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 887
[05-03-2026 - 08:24:04] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 895
[05-03-2026 - 08:24:04] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 454
[05-03-2026 - 08:49:03] [INFO]: Shard ID None has successfully RESUMED session 348f55012127dd658ddab46f89d29019.
[05-03-2026 - 06:45:46] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 06:45:46] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 06:45:46] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 06:45:46] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 06:45:46] [INFO]: logging in using static token
[05-03-2026 - 06:45:47] [INFO]: Shard ID None has connected to Gateway (Session ID: 3fcbaff82be1089a65ee9e39167873f0).
[05-03-2026 - 06:46:06] [DEBUG]: Re-initializing context...
[05-03-2026 - 06:46:06] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 06:46:06] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 06:46:06] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 06:46:06] [DEBUG]: Using HTTP scheme
[05-03-2026 - 06:46:06] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 06:46:06] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 06:46:06] [DEBUG]: Login successful
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 06:46:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 6
[05-03-2026 - 06:46:37] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 06:46:37] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 883
[05-03-2026 - 06:46:37] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 852
[05-03-2026 - 06:46:37] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 06:48:14] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 06:48:14] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 06:48:14] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 06:48:14] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 06:48:14] [INFO]: logging in using static token
[05-03-2026 - 06:48:15] [INFO]: Shard ID None has connected to Gateway (Session ID: 14436ec2092d5493b710dec84eeb3758).
[05-03-2026 - 06:48:22] [DEBUG]: Re-initializing context...
[05-03-2026 - 06:48:22] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 06:48:22] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 06:48:22] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 06:48:22] [DEBUG]: Using HTTP scheme
[05-03-2026 - 06:48:22] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 06:48:22] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 06:48:22] [DEBUG]: Login successful
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 06:48:22] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 6
[05-03-2026 - 06:48:52] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 06:48:52] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 06:48:52] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 852
[05-03-2026 - 06:48:52] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 06:49:12] [DEBUG]: Re-initializing context...
[05-03-2026 - 06:49:12] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 06:49:12] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 06:49:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 06:49:12] [DEBUG]: Using HTTP scheme
[05-03-2026 - 06:49:12] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 06:49:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 06:49:12] [DEBUG]: Login successful
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 06:49:12] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 06:49:42] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 06:49:42] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 06:49:42] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 854
[05-03-2026 - 06:49:42] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 07:01:15] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 07:01:15] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 07:01:15] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 07:01:15] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 07:01:15] [INFO]: logging in using static token
[05-03-2026 - 07:01:16] [INFO]: Shard ID None has connected to Gateway (Session ID: 863bc7befbdd673b5f817795a609eab0).
[05-03-2026 - 07:01:36] [DEBUG]: Re-initializing context...
[05-03-2026 - 07:01:36] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 07:01:36] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 07:01:36] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 07:01:36] [DEBUG]: Using HTTP scheme
[05-03-2026 - 07:01:36] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 07:01:36] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 07:01:36] [DEBUG]: Login successful
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 07:01:36] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 07:02:06] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 07:02:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 07:02:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 850
[05-03-2026 - 07:02:06] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 07:04:32] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 07:04:32] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 07:04:32] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 07:04:32] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 07:04:32] [INFO]: logging in using static token
[05-03-2026 - 07:04:33] [INFO]: Shard ID None has connected to Gateway (Session ID: 288eb0eab730ce742b2f27870ed9c3fb).
[05-03-2026 - 07:04:38] [DEBUG]: Re-initializing context...
[05-03-2026 - 07:04:38] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 07:04:38] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 07:04:38] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 07:04:38] [DEBUG]: Using HTTP scheme
[05-03-2026 - 07:04:38] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 07:04:38] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 07:04:38] [DEBUG]: Login successful
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 07:04:38] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 07:05:08] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 07:05:08] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 07:05:08] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 851
[05-03-2026 - 07:05:08] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 07:06:09] [WARNING]: PyNaCl is not installed, voice will NOT be supported
[05-03-2026 - 07:06:09] [DEBUG]: on_ready has successfully been registered as an event
[05-03-2026 - 07:06:09] [DEBUG]: on_message has successfully been registered as an event
[05-03-2026 - 07:06:09] [DEBUG]: Using proactor: IocpProactor
[05-03-2026 - 07:06:09] [INFO]: logging in using static token
[05-03-2026 - 07:06:10] [INFO]: Shard ID None has connected to Gateway (Session ID: 348f55012127dd658ddab46f89d29019).
[05-03-2026 - 07:06:12] [DEBUG]: Re-initializing context...
[05-03-2026 - 07:06:12] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 07:06:12] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 07:06:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 07:06:12] [DEBUG]: Using HTTP scheme
[05-03-2026 - 07:06:12] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 07:06:12] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 07:06:12] [DEBUG]: Login successful
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 07:06:12] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 07:06:42] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 07:06:43] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 885
[05-03-2026 - 07:06:43] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 820
[05-03-2026 - 07:06:43] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 2
[05-03-2026 - 08:20:45] [DEBUG]: Re-initializing context...
[05-03-2026 - 08:20:45] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 08:20:45] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 08:20:45] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 08:20:45] [DEBUG]: Using HTTP scheme
[05-03-2026 - 08:20:45] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 08:20:45] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 08:20:45] [DEBUG]: Login successful
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 08:20:45] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 08:21:15] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 08:21:15] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 884
[05-03-2026 - 08:21:15] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 949
[05-03-2026 - 08:21:15] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 231
[05-03-2026 - 08:23:34] [DEBUG]: Re-initializing context...
[05-03-2026 - 08:23:34] [DEBUG]: Parsed user URL: ParseResult(scheme='', netloc='localhost:8081', path='', params='', query='', fragment='')
[05-03-2026 - 08:23:34] [DEBUG]: Detecting scheme for URL...
[05-03-2026 - 08:23:34] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "HEAD / HTTP/11" 200 0
[05-03-2026 - 08:23:34] [DEBUG]: Using HTTP scheme
[05-03-2026 - 08:23:34] [DEBUG]: Base URL: http://localhost:8081/
[05-03-2026 - 08:23:34] [DEBUG]: Starting new HTTP connection (1): localhost:8081
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "POST /api/v2/auth/login HTTP/11" 200 3
[05-03-2026 - 08:23:34] [DEBUG]: Login successful
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "GET /api/v2/app/version HTTP/11" 200 6
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "GET /api/v2/app/webapiVersion HTTP/11" 200 6
[05-03-2026 - 08:23:34] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/add HTTP/11" 200 3
[05-03-2026 - 08:24:04] [DEBUG]: Resetting dropped connection: localhost
[05-03-2026 - 08:24:04] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/info HTTP/11" 200 887
[05-03-2026 - 08:24:04] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/properties HTTP/11" 200 895
[05-03-2026 - 08:24:04] [DEBUG]: http://localhost:8081 "POST /api/v2/torrents/files HTTP/11" 200 454
[05-03-2026 - 08:49:03] [INFO]: Shard ID None has successfully RESUMED session 348f55012127dd658ddab46f89d29019.
+48 -48
View File
@@ -1,49 +1,49 @@
<html>
<head>
<title>Ruty - L'outil multifonction</title>
<link rel="stylesheet" href="styles/style.css">
<link rel="icon" href="img/logo.png">
</head>
<body>
<header>
<img src="img/logo.png">
<h1 class="Welcome">Bienvenue sur Ruty [BETA]</h1>
</header>
<div class="login">
<h2 class="type1">Accéder à son compte Ruty</h2>
<svg xmlns="http://www.w3.org/2000/svg" height="200px" width="200px" viewBox="0 0 200 200" class="pencil">
<defs>
<clipPath id="pencil-eraser">
<rect height="30" width="30" ry="5" rx="5"></rect>
</clipPath>
</defs>
<circle transform="rotate(-113,100,100)" stroke-linecap="round" stroke-dashoffset="439.82" stroke-dasharray="439.82 439.82" stroke-width="2" stroke="currentColor" fill="none" r="70" class="pencil__stroke"></circle>
<g transform="translate(100,100)" class="pencil__rotate">
<g fill="none">
<circle transform="rotate(-90)" stroke-dashoffset="402" stroke-dasharray="402.12 402.12" stroke-width="30" stroke="hsl(8, 90%, 50%)" r="64" class="pencil__body1"></circle>
<circle transform="rotate(-90)" stroke-dashoffset="465" stroke-dasharray="464.96 464.96" stroke-width="10" stroke="hsl(8, 90%, 60%)" r="74" class="pencil__body2"></circle>
<circle transform="rotate(-90)" stroke-dashoffset="339" stroke-dasharray="339.29 339.29" stroke-width="10" stroke="hsl(9, 90%, 44%)" r="54" class="pencil__body3"></circle>
</g>
<g transform="rotate(-90) translate(49,0)" class="pencil__eraser">
<g class="pencil__eraser-skew">
<rect height="30" width="30" ry="5" rx="5" fill="hsl(223,90%,70%)"></rect>
<rect clip-path="url(#pencil-eraser)" height="30" width="5" fill="hsl(223,90%,60%)"></rect>
<rect height="20" width="30" fill="hsl(223,10%,90%)"></rect>
<rect height="20" width="15" fill="hsl(223,10%,70%)"></rect>
<rect height="20" width="5" fill="hsl(223,10%,80%)"></rect>
<rect height="2" width="30" y="6" fill="hsla(223,10%,10%,0.2)"></rect>
<rect height="2" width="30" y="13" fill="hsla(223,10%,10%,0.2)"></rect>
</g>
</g>
<g transform="rotate(-90) translate(49,-30)" class="pencil__point">
<polygon points="15 0,30 30,0 30" fill="hsl(33,90%,70%)"></polygon>
<polygon points="15 0,6 30,0 30" fill="hsl(33,90%,50%)"></polygon>
<polygon points="15 0,20 10,10 10" fill="hsl(223,10%,10%)"></polygon>
</g>
</g>
</svg>
<a class="login_button" href="home.php" >Se connecter</a>
</div>
</body>
<html>
<head>
<title>Ruty - L'outil multifonction</title>
<link rel="stylesheet" href="styles/style.css">
<link rel="icon" href="img/logo.png">
</head>
<body>
<header>
<img src="img/logo.png">
<h1 class="Welcome">Bienvenue sur Ruty [BETA]</h1>
</header>
<div class="login">
<h2 class="type1">Accéder à son compte Ruty</h2>
<svg xmlns="http://www.w3.org/2000/svg" height="200px" width="200px" viewBox="0 0 200 200" class="pencil">
<defs>
<clipPath id="pencil-eraser">
<rect height="30" width="30" ry="5" rx="5"></rect>
</clipPath>
</defs>
<circle transform="rotate(-113,100,100)" stroke-linecap="round" stroke-dashoffset="439.82" stroke-dasharray="439.82 439.82" stroke-width="2" stroke="currentColor" fill="none" r="70" class="pencil__stroke"></circle>
<g transform="translate(100,100)" class="pencil__rotate">
<g fill="none">
<circle transform="rotate(-90)" stroke-dashoffset="402" stroke-dasharray="402.12 402.12" stroke-width="30" stroke="hsl(8, 90%, 50%)" r="64" class="pencil__body1"></circle>
<circle transform="rotate(-90)" stroke-dashoffset="465" stroke-dasharray="464.96 464.96" stroke-width="10" stroke="hsl(8, 90%, 60%)" r="74" class="pencil__body2"></circle>
<circle transform="rotate(-90)" stroke-dashoffset="339" stroke-dasharray="339.29 339.29" stroke-width="10" stroke="hsl(9, 90%, 44%)" r="54" class="pencil__body3"></circle>
</g>
<g transform="rotate(-90) translate(49,0)" class="pencil__eraser">
<g class="pencil__eraser-skew">
<rect height="30" width="30" ry="5" rx="5" fill="hsl(223,90%,70%)"></rect>
<rect clip-path="url(#pencil-eraser)" height="30" width="5" fill="hsl(223,90%,60%)"></rect>
<rect height="20" width="30" fill="hsl(223,10%,90%)"></rect>
<rect height="20" width="15" fill="hsl(223,10%,70%)"></rect>
<rect height="20" width="5" fill="hsl(223,10%,80%)"></rect>
<rect height="2" width="30" y="6" fill="hsla(223,10%,10%,0.2)"></rect>
<rect height="2" width="30" y="13" fill="hsla(223,10%,10%,0.2)"></rect>
</g>
</g>
<g transform="rotate(-90) translate(49,-30)" class="pencil__point">
<polygon points="15 0,30 30,0 30" fill="hsl(33,90%,70%)"></polygon>
<polygon points="15 0,6 30,0 30" fill="hsl(33,90%,50%)"></polygon>
<polygon points="15 0,20 10,10 10" fill="hsl(223,10%,10%)"></polygon>
</g>
</g>
</svg>
<a class="login_button" href="home.php" >Se connecter</a>
</div>
</body>
</html>
+16 -16
View File
@@ -1,17 +1,17 @@
// Ouverture menu nav
const menuTrigger = document.getElementById("menu-trigger");
const menu = document.getElementById("menu");
const overlay = document.getElementById("overlay")
menuTrigger.addEventListener("click", () => {
menu.classList.toggle("hidden");
if (!menu.classList.contains("hidden")) {
menu.classList.remove("hidden");
menu.style.left = "-300px";
overlay.style.display = "none";
} else {
menu.classList.add("hidden");
menu.style.left = "0px";
overlay.style.display = "block";
}
// Ouverture menu nav
const menuTrigger = document.getElementById("menu-trigger");
const menu = document.getElementById("menu");
const overlay = document.getElementById("overlay")
menuTrigger.addEventListener("click", () => {
menu.classList.toggle("hidden");
if (!menu.classList.contains("hidden")) {
menu.classList.remove("hidden");
menu.style.left = "-300px";
overlay.style.display = "none";
} else {
menu.classList.add("hidden");
menu.style.left = "0px";
overlay.style.display = "block";
}
});
+14 -14
View File
@@ -1,14 +1,14 @@
[02-Oct-2023 18:04:08 +0000]: <13n3u2rh> DB Error: SQLSTATE[HY000] [1045] Accès refusé pour l'utilisateur: 'roundcube'@'@localhost' (mot de passe: NON) in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[02-Oct-2023 18:24:21 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:24:41 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh@gmail.com against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:33:55 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:44:41 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:45:00 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:45:14 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:45:41 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:48:29 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh@gmail.com against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 19:02:57 +0000]: <13n3u2rh> IMAP Error: Login failed for root against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 19:11:53 +0000]: <13n3u2rh> IMAP Error: Login failed for whykorp@gmail.com against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[25-Mar-2026 20:07:03 +0000]: <n856jth9> DB Error: SQLSTATE[HY000] [1049] Base 'roundcubemail' inconnue in C:\wamp\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[25-Mar-2026 20:07:14 +0000]: <n856jth9> DB Error: SQLSTATE[HY000] [1049] Base 'roundcubemail' inconnue in C:\wamp\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[25-Mar-2026 20:07:17 +0000]: <n856jth9> DB Error: SQLSTATE[HY000] [1049] Base 'roundcubemail' inconnue in C:\wamp\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[02-Oct-2023 18:04:08 +0000]: <13n3u2rh> DB Error: SQLSTATE[HY000] [1045] Accès refusé pour l'utilisateur: 'roundcube'@'@localhost' (mot de passe: NON) in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[02-Oct-2023 18:24:21 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:24:41 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh@gmail.com against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:33:55 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:44:41 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:45:00 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:45:14 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:45:41 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 18:48:29 +0000]: <13n3u2rh> IMAP Error: Login failed for whykioh@gmail.com against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 19:02:57 +0000]: <13n3u2rh> IMAP Error: Login failed for root against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[02-Oct-2023 19:11:53 +0000]: <13n3u2rh> IMAP Error: Login failed for whykorp@gmail.com against localhost from 192.168.0.254. Could not connect to localhost:143: Aucune connexion na pu être établie car lordinateur cible la expressément refusée in C:\wamp64\www\ruty\mails\program\lib\Roundcube\rcube_imap.php on line 211 (POST /ruty/mails/?_task=login&_action=login)
[25-Mar-2026 20:07:03 +0000]: <n856jth9> DB Error: SQLSTATE[HY000] [1049] Base 'roundcubemail' inconnue in C:\wamp\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[25-Mar-2026 20:07:14 +0000]: <n856jth9> DB Error: SQLSTATE[HY000] [1049] Base 'roundcubemail' inconnue in C:\wamp\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)
[25-Mar-2026 20:07:17 +0000]: <n856jth9> DB Error: SQLSTATE[HY000] [1049] Base 'roundcubemail' inconnue in C:\wamp\www\ruty\mails\program\lib\Roundcube\rcube_db.php on line 201 (GET /ruty/mails/)

Some files were not shown because too many files have changed in this diff Show More