Suppression easteregg + fix captcha
This commit is contained in:
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
// Sert la photo de profil d'un joueur "Presse-Citron", stockée en base
|
||||
// (voir migration Juillet 2026 (8)). Public : pas besoin d'être connecté pour voir
|
||||
// les avatars affichés dans le classement.
|
||||
|
||||
require_once('../functions/databaseConnection.php');
|
||||
|
||||
$playerId = $_GET['player_id'] ?? '';
|
||||
|
||||
if (!is_numeric($playerId)) {
|
||||
http_response_code(404);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('SELECT avatar_data, avatar_mime FROM lemon_avatars WHERE player_id = :id');
|
||||
$stmt->bindValue(':id', (int) $playerId, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(404);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$row) {
|
||||
http_response_code(404);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: ' . $row['avatar_mime']);
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('Content-Length: ' . strlen($row['avatar_data']));
|
||||
header('Content-Disposition: inline');
|
||||
// Les avatars changent rarement : cache navigateur d'une heure, comme les PDF (voir viewPdf.php)
|
||||
header('Cache-Control: public, max-age=3600');
|
||||
echo $row['avatar_data'];
|
||||
exit;
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
// Suppression de la photo de profil du joueur "Presse-Citron" connecté (retour à
|
||||
// l'avatar par défaut : cercle avec l'initiale du pseudo).
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
require_once('../functions/databaseConnection.php');
|
||||
require_once('../functions/lemonSession.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Méthode non autorisée.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
requireLemonAuth();
|
||||
requireCsrfToken();
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('DELETE FROM lemon_avatars WHERE player_id = :id');
|
||||
$stmt->bindValue(':id', (int) $_SESSION['lemon_player_id'], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
echo json_encode(['ok' => true]);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Erreur serveur.']);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
// Upload / remplacement de la photo de profil du joueur "Presse-Citron" connecté.
|
||||
// Le fichier est déjà redimensionné et compressé côté navigateur (voir pages/citron.php),
|
||||
// mais la validation ici ne fait aucune confiance à ça : elle revérifie tout elle-même.
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
require_once('../functions/databaseConnection.php');
|
||||
require_once('../functions/lemonSession.php');
|
||||
require_once('../functions/avatarUpload.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Méthode non autorisée.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
requireLemonAuth();
|
||||
requireCsrfToken();
|
||||
|
||||
$resultat = lireUploadAvatar('avatar');
|
||||
|
||||
if ($resultat === null) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Aucune image envoyée.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (is_string($resultat)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => $resultat]);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('
|
||||
INSERT INTO lemon_avatars (player_id, avatar_data, avatar_mime, updated_at)
|
||||
VALUES (:id, :data, :mime, NOW())
|
||||
ON DUPLICATE KEY UPDATE avatar_data = VALUES(avatar_data), avatar_mime = VALUES(avatar_mime), updated_at = NOW()
|
||||
');
|
||||
$stmt->bindValue(':id', (int) $_SESSION['lemon_player_id'], PDO::PARAM_INT);
|
||||
$stmt->bindValue(':data', $resultat['data'], PDO::PARAM_LOB);
|
||||
$stmt->bindValue(':mime', $resultat['mime'], PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
|
||||
echo json_encode(['ok' => true]);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Erreur serveur.']);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
// Classement public du jeu "Presse-Citron" (les 15 meilleurs scores cumulés), avec un
|
||||
// peu plus de détail que le simple score : nombre de bâtiments possédés (calculé depuis
|
||||
// game_state), niveau de prestige, date de dernière partie. Lecture seule, sans connexion.
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
require_once('../functions/databaseConnection.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('
|
||||
SELECT id, username, score, lifetime_score, prestige_level, prestige_bonus, game_state, last_played, created_at
|
||||
FROM lemon_players
|
||||
ORDER BY lifetime_score DESC
|
||||
LIMIT 15
|
||||
');
|
||||
$stmt->execute();
|
||||
$lignes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
$lignes = [];
|
||||
}
|
||||
|
||||
// On calcule le nombre total de bâtiments possédés à partir du game_state (stocké en JSON) :
|
||||
// une info que le classement n'affichait pas jusqu'ici, et qui donne un vrai aperçu de
|
||||
// l'avancée d'un joueur au-delà du seul score
|
||||
$classement = array_map(function ($ligne) {
|
||||
$totalBatiments = 0;
|
||||
if (!empty($ligne['game_state'])) {
|
||||
$etat = json_decode($ligne['game_state'], true);
|
||||
if (is_array($etat) && !empty($etat['buildings']) && is_array($etat['buildings'])) {
|
||||
foreach ($etat['buildings'] as $possedes) {
|
||||
$totalBatiments += (int) $possedes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => (int) $ligne['id'],
|
||||
'username' => $ligne['username'],
|
||||
'score' => (float) $ligne['score'],
|
||||
'lifetime_score' => (float) $ligne['lifetime_score'],
|
||||
'prestige_level' => (int) $ligne['prestige_level'],
|
||||
'prestige_bonus' => (float) $ligne['prestige_bonus'],
|
||||
'total_buildings' => $totalBatiments,
|
||||
'last_played' => $ligne['last_played'],
|
||||
'created_at' => $ligne['created_at'],
|
||||
];
|
||||
}, $lignes);
|
||||
|
||||
echo json_encode($classement);
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
// Connexion au jeu "Presse-Citron" (easter egg). Comptes totalement séparés
|
||||
// des comptes admin du portfolio (table lemon_players).
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
require_once('../functions/databaseConnection.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Méthode non autorisée.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
requireCsrfToken();
|
||||
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('
|
||||
SELECT id, username, password, score, lifetime_score, prestige_level, prestige_bonus, game_state
|
||||
FROM lemon_players WHERE username = :username LIMIT 1
|
||||
');
|
||||
$stmt->execute([':username' => $username]);
|
||||
$player = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Erreur serveur.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$player || !password_verify($password, $player['password'])) {
|
||||
http_response_code(401);
|
||||
echo json_encode(['error' => 'Nom de pressier ou mot de passe incorrect.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Régénère l'ID de session à la connexion : évite la fixation de session
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['lemon_player_id'] = (int) $player['id'];
|
||||
$_SESSION['lemon_username'] = $player['username'];
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('UPDATE lemon_players SET last_played = NOW() WHERE id = :id');
|
||||
$stmt->execute([':id' => $player['id']]);
|
||||
} catch (PDOException $e) {
|
||||
// Pas bloquant : la connexion reste valable même si cette mise à jour échoue
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'ok' => true,
|
||||
'id' => (int) $player['id'],
|
||||
'username' => $player['username'],
|
||||
'score' => (float) $player['score'],
|
||||
'lifetime_score' => (float) $player['lifetime_score'],
|
||||
'prestige_level' => (int) $player['prestige_level'],
|
||||
'prestige_bonus' => (float) $player['prestige_bonus'],
|
||||
'game_state' => $player['game_state'],
|
||||
]);
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
// Déconnexion du jeu "Presse-Citron" uniquement : ne touche jamais à une éventuelle
|
||||
// session admin du portfolio (clés de session complètement séparées)
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
unset($_SESSION['lemon_player_id'], $_SESSION['lemon_username']);
|
||||
|
||||
echo json_encode(['ok' => true]);
|
||||
@@ -1,68 +0,0 @@
|
||||
<?php
|
||||
// Création d'un compte pour le jeu "Presse-Citron" (easter egg).
|
||||
// Comptes totalement séparés des comptes admin du portfolio (table lemon_players).
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
require_once('../functions/databaseConnection.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Méthode non autorisée.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
requireCsrfToken();
|
||||
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if ($username === '' || mb_strlen($username) > 50) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => "Nom de pressier invalide (1 à 50 caractères)."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (mb_strlen($password) < 4) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Le mot de passe doit faire au moins 4 caractères.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// On vérifie que le nom n'est pas déjà pris
|
||||
$stmt = $dbh->prepare('SELECT id FROM lemon_players WHERE username = :username LIMIT 1');
|
||||
$stmt->execute([':username' => $username]);
|
||||
if ($stmt->fetch()) {
|
||||
http_response_code(409);
|
||||
echo json_encode(['error' => 'Ce nom de pressier est déjà pris.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$hash = password_hash($password, PASSWORD_DEFAULT);
|
||||
$stmt = $dbh->prepare('INSERT INTO lemon_players (username, password, created_at) VALUES (:username, :password, NOW())');
|
||||
$stmt->execute([':username' => $username, ':password' => $hash]);
|
||||
|
||||
$playerId = (int) $dbh->lastInsertId();
|
||||
|
||||
// Régénère l'ID de session à la création de compte (même logique que checkLogin.php
|
||||
// pour le portfolio : évite la fixation de session)
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['lemon_player_id'] = $playerId;
|
||||
$_SESSION['lemon_username'] = $username;
|
||||
|
||||
echo json_encode([
|
||||
'ok' => true,
|
||||
'id' => $playerId,
|
||||
'username' => $username,
|
||||
'score' => 0,
|
||||
'lifetime_score' => 0,
|
||||
'prestige_level' => 0,
|
||||
'prestige_bonus' => 0,
|
||||
'game_state' => null,
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Erreur serveur.']);
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
// Sauvegarde de la partie en cours pour le joueur "Presse-Citron" connecté.
|
||||
// Toute la logique du jeu vit côté JS : ce script se contente de valider
|
||||
// grossièrement les données reçues (nombres positifs, JSON de taille raisonnable)
|
||||
// et de les enregistrer telles quelles pour le joueur de la session en cours.
|
||||
|
||||
require_once(__DIR__ . '/../functions/security.php');
|
||||
require_once('../functions/databaseConnection.php');
|
||||
require_once('../functions/lemonSession.php');
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Méthode non autorisée.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
requireLemonAuth();
|
||||
requireCsrfToken();
|
||||
|
||||
$score = $_POST['score'] ?? null;
|
||||
$lifetimeScore = $_POST['lifetime_score'] ?? null;
|
||||
$prestigeLevel = $_POST['prestige_level'] ?? null;
|
||||
$prestigeBonus = $_POST['prestige_bonus'] ?? null;
|
||||
$gameState = $_POST['game_state'] ?? null;
|
||||
|
||||
// Validation basique : évite qu'une requête forgée n'enregistre n'importe quoi
|
||||
if (
|
||||
!is_numeric($score) || $score < 0 ||
|
||||
!is_numeric($lifetimeScore) || $lifetimeScore < 0 ||
|
||||
!is_numeric($prestigeLevel) || $prestigeLevel < 0 ||
|
||||
!is_numeric($prestigeBonus) || $prestigeBonus < 0
|
||||
) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'Données de sauvegarde invalides.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// game_state : JSON de taille raisonnable (20 Ko largement suffisant pour la liste
|
||||
// des bâtiments/améliorations possédés), sinon on refuse plutôt que de tronquer
|
||||
if ($gameState !== null && (strlen($gameState) > 20000 || json_decode($gameState) === null)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'État de jeu invalide.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $dbh->prepare('
|
||||
UPDATE lemon_players
|
||||
SET score = :score, lifetime_score = :lifetime_score, prestige_level = :prestige_level,
|
||||
prestige_bonus = :prestige_bonus, game_state = :game_state, last_played = NOW()
|
||||
WHERE id = :id
|
||||
');
|
||||
$stmt->bindValue(':score', (float) $score);
|
||||
$stmt->bindValue(':lifetime_score', (float) $lifetimeScore);
|
||||
$stmt->bindValue(':prestige_level', (int) $prestigeLevel, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':prestige_bonus', (float) $prestigeBonus);
|
||||
$stmt->bindValue(':game_state', $gameState, $gameState === null ? PDO::PARAM_NULL : PDO::PARAM_STR);
|
||||
$stmt->bindValue(':id', (int) $_SESSION['lemon_player_id'], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
echo json_encode(['ok' => true]);
|
||||
} catch (PDOException $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => 'Erreur serveur.']);
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
<?php
|
||||
|
||||
if (!isset($_SESSION['captcha_valid']) || $_SESSION['captcha_valid'] !== true) {
|
||||
require_once(__DIR__ . '/../functions/listSettings.php');
|
||||
|
||||
// Le captcha peut être désactivé depuis le panel Admin (section Sécurité)
|
||||
$captchaEnabled = recupererSetting('captcha_enabled') ?? '1';
|
||||
|
||||
if ($captchaEnabled === '1' && (!isset($_SESSION['captcha_valid']) || $_SESSION['captcha_valid'] !== true)) {
|
||||
header('Location: ../captcha.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,21 @@ if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
|
||||
// On récupère les données pour les mettres en variables locales
|
||||
// La checkbox n'est envoyée que si elle est cochée
|
||||
$reglages = [
|
||||
'site_notice_title' => trim($_POST['notice_title'] ?? ''),
|
||||
'site_notice_text' => trim($_POST['notice_text'] ?? ''),
|
||||
'site_notice_enabled' => isset($_POST['notice_enabled']) ? '1' : '0'
|
||||
];
|
||||
// settings_group : évite qu'un formulaire écrase les réglages d'un autre (ex : la case
|
||||
// "notice_enabled" non cochée ne doit pas désactiver le captcha, et inversement)
|
||||
$groupeReglages = $_POST['settings_group'] ?? 'notice';
|
||||
|
||||
if ($groupeReglages === 'captcha') {
|
||||
$reglages = [
|
||||
'captcha_enabled' => isset($_POST['captcha_enabled']) ? '1' : '0'
|
||||
];
|
||||
} else {
|
||||
$reglages = [
|
||||
'site_notice_title' => trim($_POST['notice_title'] ?? ''),
|
||||
'site_notice_text' => trim($_POST['notice_text'] ?? ''),
|
||||
'site_notice_enabled' => isset($_POST['notice_enabled']) ? '1' : '0'
|
||||
];
|
||||
}
|
||||
|
||||
try { // On essaie d'executer une requête qui est préparée pour chaque réglage
|
||||
// ON DUPLICATE KEY UPDATE : crée le réglage s'il n'existe pas encore, le met à jour sinon
|
||||
|
||||
Reference in New Issue
Block a user