prepare("SELECT role FROM users WHERE id = ?"); $stmt->execute([$user_id]); $user = $stmt->fetch(); if (!$user) return null; $role = $user['role']; $level = 0; try { $stmt_lvl = $pdo->prepare("SELECT level FROM users WHERE id = ?"); $stmt_lvl->execute([$user_id]); $level = (int)$stmt_lvl->fetchColumn(); } catch (Exception $e) { // level column might not exist } if ($role === 'admin') { $stmt = $pdo->prepare("SELECT * FROM grades WHERE user_type = 'admin' LIMIT 1"); $stmt->execute(); return $stmt->fetch(); } elseif ($role === 'gm') { $stmt = $pdo->prepare("SELECT * FROM grades WHERE user_type = 'GM' LIMIT 1"); $stmt->execute(); return $stmt->fetch(); } else { $stmt = $pdo->prepare("SELECT * FROM grades WHERE user_type = 'utilisateur' AND ? BETWEEN min_level AND max_level LIMIT 1"); $stmt->execute([$level]); return $stmt->fetch(); } } require_once 'db/config.php'; session_start(); $db = db(); // Auth Check: Must be logged in and be admin if (!isset($_SESSION['user_id'])) { header("Location: auth.php?page=login"); exit; } $user_id = $_SESSION['user_id']; $user_stmt = $db->prepare("SELECT role FROM users WHERE id = ?"); $user_stmt->execute([$user_id]); $current_user = $user_stmt->fetch(); if (!$current_user || $current_user['role'] !== 'admin') { die("Accès refusé. Cette console est réservée aux Administrateurs."); } // Default tab is now users as before, but let's see if we should change it to project_logs $tab = isset($_GET['tab']) ? $_GET['tab'] : 'project_logs'; // --- HANDLERS --- // Handle User Role Update if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update_user_role') { $target_user_id = (int)$_POST['target_user_id']; $new_role = $_POST['new_role']; if (in_array($new_role, ['user', 'gm', 'admin'])) { $stmt = $db->prepare("UPDATE users SET role = ? WHERE id = ?"); $stmt->execute([$new_role, $target_user_id]); } header("Location: admin.php?tab=users&success=1"); exit; } // Handle Celestial Object Type CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_object_type') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $icon = $_POST['icon']; $description = $_POST['description']; $status_profile_id = !empty($_POST['status_profile_id']) ? (int)$_POST['status_profile_id'] : null; $modifier_ids = isset($_POST['modifiers']) ? $_POST['modifiers'] : []; $image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM celestial_object_types WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); } if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']["name"], PATHINFO_EXTENSION); $filename = $slug . "_" . time() . "." . $ext; $target = "assets/images/celestial/" . $filename; if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) { $image_url = $target; } } $orbital_enabled = isset($_POST["orbital_control_enabled"]) ? 1 : 0; $terrestrial_enabled = isset($_POST["terrestrial_control_enabled"]) ? 1 : 0; if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_types SET name = ?, slug = ?, icon = ?, description = ?, image_url = ?, orbital_control_enabled = ?, terrestrial_control_enabled = ?, status_profile_id = ? WHERE id = ?"); $stmt->execute([$name, $slug, $icon, $description, $image_url, $orbital_enabled, $terrestrial_enabled, $status_profile_id, $id]); } else { $stmt = $db->prepare("INSERT INTO celestial_object_types (name, slug, icon, description, image_url, orbital_control_enabled, terrestrial_control_enabled, status_profile_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $icon, $description, $image_url, $orbital_enabled, $terrestrial_enabled, $status_profile_id]); $id = $db->lastInsertId(); } // Sync modifiers $db->prepare("DELETE FROM celestial_object_type_modifiers WHERE celestial_object_type_id = ?")->execute([$id]); if (!empty($modifier_ids)) { $ins = $db->prepare("INSERT INTO celestial_object_type_modifiers (celestial_object_type_id, modifier_id) VALUES (?, ?)"); foreach ($modifier_ids as $mid) { $ins->execute([$id, (int)$mid]); } } header("Location: admin.php?tab=objects&success=1"); exit; } if (isset($_GET['delete_object'])) { $id = (int)$_GET['delete_object']; $db->prepare("DELETE FROM celestial_object_types WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=objects&success=1"); exit; } // Handle Title CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_title') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $color = $_POST["color"] ?? "#ffffff"; $allowed_user_type = $_POST['allowed_user_type']; $required_level = (int)$_POST['required_level']; if ($id > 0) { $stmt = $db->prepare("UPDATE titles SET name = ?, slug = ?, allowed_user_type = ?, required_level = ?, color = ? WHERE id = ?"); $stmt->execute([$name, $slug, $allowed_user_type, $required_level, $color, $id]); } else { $stmt = $db->prepare("INSERT INTO titles (name, slug, allowed_user_type, required_level, color) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $allowed_user_type, $required_level, $color]); } header("Location: admin.php?tab=badges&success=1"); exit; } // Handle Badge CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_badge') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $allowed_user_type = $_POST['allowed_user_type']; $required_level = (int)$_POST['required_level']; $image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM badges WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); } if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']["name"], PATHINFO_EXTENSION); $filename = "badge_" . $slug . "_" . time() . "." . $ext; $target = "assets/images/badges/" . $filename; if (!is_dir("assets/images/badges/")) mkdir("assets/images/badges/", 0775, true); if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) { $image_url = $target; } } if ($id > 0) { $stmt = $db->prepare("UPDATE badges SET name = ?, slug = ?, allowed_user_type = ?, required_level = ?, image_url = ? WHERE id = ?"); $stmt->execute([$name, $slug, $allowed_user_type, $required_level, $image_url, $id]); } else { $stmt = $db->prepare("INSERT INTO badges (name, slug, allowed_user_type, required_level, image_url) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $allowed_user_type, $required_level, $image_url]); } header("Location: admin.php?tab=badges&success=1"); exit; } // Handle Title/Badge Deletion if (isset($_GET['delete_title'])) { $id = (int)$_GET['delete_title']; $db->prepare("DELETE FROM titles WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=badges&success=deleted"); exit; } if (isset($_GET['delete_badge'])) { $id = (int)$_GET['delete_badge']; $db->prepare("DELETE FROM badges WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=badges&success=deleted"); exit; } // Handle Status CRUD if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_status") { $id = (int)$_POST["id"]; $name = $_POST["name"]; $slug = $_POST["slug"]; $color = $_POST["color"]; $description = $_POST["description"]; // Gérer le clignotement if (isset($_POST["is_blinking"]) && $_POST["is_blinking"] === "on") { if (strpos($color, ";blink") === false) { $color .= ";blink"; } } else { $color = str_replace(";blink", "", $color); } if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_statuses SET name = ?, slug = ?, color = ?, description = ? WHERE id = ?"); $stmt->execute([$name, $slug, $color, $description, $id]); } else { $stmt = $db->prepare("INSERT INTO celestial_object_statuses (name, slug, color, description) VALUES (?, ?, ?, ?)"); $stmt->execute([$name, $slug, $color, $description]); } header("Location: admin.php?tab=statuses&success=1"); exit; } if (isset($_GET['delete_status'])) { $id = (int)$_GET['delete_status']; $db->prepare("DELETE FROM celestial_object_statuses WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=statuses&success=1"); exit; } // Handle Status Profile CRUD if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_status_profile") { $id = (int)$_POST["id"]; $name = $_POST["name"]; $slug = $_POST["slug"]; if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_status_profiles SET name = ?, slug = ? WHERE id = ?"); $stmt->execute([$name, $slug, $id]); } else { $stmt = $db->prepare("INSERT INTO celestial_object_status_profiles (name, slug) VALUES (?, ?)"); $stmt->execute([$name, $slug]); } header("Location: admin.php?tab=statuses&success=1"); exit; } if (isset($_GET["delete_status_profile"])) { $id = (int)$_GET["delete_status_profile"]; // Check if it is used $count = $db->query("SELECT COUNT(*) FROM celestial_object_status_rules WHERE profile_id = $id")->fetchColumn(); $count2 = $db->query("SELECT COUNT(*) FROM celestial_object_types WHERE status_profile_id = $id")->fetchColumn(); if ($count == 0 && $count2 == 0) { $db->prepare("DELETE FROM celestial_object_status_profiles WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=statuses&success=1"); } else { header("Location: admin.php?tab=statuses&error=profile_in_use"); } exit; } // Handle Status Rule CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_status_rule') { $id = (int)$_POST['id']; $name = $_POST["name"]; $status_id = (int)$_POST['status_id']; $profile_id = (int)$_POST['profile_id']; $priority = (int)$_POST['priority']; $orbital_count_op = $_POST['orbital_count_op'] ?: null; $orbital_count_val = $_POST['orbital_count_val'] !== '' ? (int)$_POST['orbital_count_val'] : null; $terrestrial_count_op = $_POST['terrestrial_count_op'] ?: null; $terrestrial_count_val = $_POST['terrestrial_count_val'] !== '' ? (int)$_POST['terrestrial_count_val'] : null; $orbital_dominance = isset($_POST['orbital_dominance']) ? implode(',', (array)$_POST['orbital_dominance']) : null; $terrestrial_dominance = isset($_POST['terrestrial_dominance']) ? implode(',', (array)$_POST['terrestrial_dominance']) : null; $is_empty_case = isset($_POST['is_empty_case']) ? 1 : 0; $combine_mode = $_POST['combine_mode'] ?? 'OR'; if ($id > 0) { $stmt = $db->prepare("UPDATE celestial_object_status_rules SET name = ?, status_id = ?, profile_id = ?, priority = ?, orbital_count_op = ?, orbital_count_val = ?, terrestrial_count_op = ?, terrestrial_count_val = ?, orbital_dominance = ?, terrestrial_dominance = ?, is_empty_case = ?, combine_mode = ? WHERE id = ?"); $stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominance, $terrestrial_dominance, $is_empty_case, $combine_mode, $id]); } else { $stmt = $db->prepare("INSERT INTO celestial_object_status_rules (name, status_id, profile_id, priority, orbital_count_op, orbital_count_val, terrestrial_count_op, terrestrial_count_val, orbital_dominance, terrestrial_dominance, is_empty_case, combine_mode) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $status_id, $profile_id, $priority, $orbital_count_op, $orbital_count_val, $terrestrial_count_op, $terrestrial_count_val, $orbital_dominance, $terrestrial_dominance, $is_empty_case, $combine_mode]); } header("Location: admin.php?tab=statuses&success=1"); exit; } if (isset($_GET['delete_status_rule'])) { $id = (int)$_GET['delete_status_rule']; $db->prepare("DELETE FROM celestial_object_status_rules WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=statuses&success=1"); exit; } // Handle Settlement Type CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_settlement_type') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $description = $_POST['description']; if ($id > 0) { $stmt = $db->prepare("UPDATE settlement_types SET name = ?, slug = ?, description = ? WHERE id = ?"); $stmt->execute([$name, $slug, $description, $id]); } else { $stmt = $db->prepare("INSERT INTO settlement_types (name, slug, description) VALUES (?, ?, ?)"); $stmt->execute([$name, $slug, $description]); } header("Location: admin.php?tab=settlement_types&success=1"); exit; } if (isset($_GET['delete_settlement_type'])) { $id = (int)$_GET['delete_settlement_type']; $db->prepare("DELETE FROM settlement_types WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=settlement_types&success=1"); exit; } // Handle Modifiers CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_modifier') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $type = $_POST['type']; $description = $_POST['description']; if ($id > 0) { $stmt = $db->prepare("UPDATE modifiers SET name = ?, slug = ?, type = ?, description = ? WHERE id = ?"); $stmt->execute([$name, $slug, $type, $description, $id]); } else { $stmt = $db->prepare("INSERT INTO modifiers (name, slug, type, description) VALUES (?, ?, ?, ?)"); $stmt->execute([$name, $slug, $type, $description]); } header("Location: admin.php?tab=modifiers&success=1"); exit; } if (isset($_GET['delete_modifier'])) { $id = (int)$_GET['delete_modifier']; $db->prepare("DELETE FROM modifiers WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=modifiers&success=1"); exit; } // Handle Faction CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_faction') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $fa_icon = $_POST['fa_icon']; $color = $_POST['color']; $image_url = null; $alliance_ids = isset($_POST['alliances']) ? $_POST['alliances'] : []; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM factions WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); } if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']["name"], PATHINFO_EXTENSION); $filename = "faction_" . time() . "." . $ext; $target = "assets/images/factions/" . $filename; if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) { $image_url = $target; } } if ($id > 0) { $stmt = $db->prepare("UPDATE factions SET name = ?, slug = ?, image_url = ?, fa_icon = ?, color = ? WHERE id = ?"); $stmt->execute([$name, $slug, $image_url, $fa_icon, $color, $id]); } else { $stmt = $db->prepare("INSERT INTO factions (name, slug, image_url, fa_icon, color) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $image_url, $fa_icon, $color]); $id = $db->lastInsertId(); } // Handle Alliances (Reciprocal) $db->prepare("DELETE FROM faction_alliances WHERE faction_id_1 = ? OR faction_id_2 = ?")->execute([$id, $id]); foreach ($alliance_ids as $ally_id) { $f1 = min((int)$id, (int)$ally_id); $f2 = max((int)$id, (int)$ally_id); if ($f1 === $f2) continue; $db->prepare("INSERT IGNORE INTO faction_alliances (faction_id_1, faction_id_2) VALUES (?, ?)")->execute([$f1, $f2]); } header("Location: admin.php?tab=factions&success=1"); exit; } if (isset($_GET['delete_faction'])) { $id = (int)$_GET['delete_faction']; $db->prepare("DELETE FROM factions WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=factions&success=1"); exit; } // Handle Levels CRUD if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_level") { $id = (int)$_POST["id"]; $name = $_POST["name"]; $slug = $_POST["slug"]; $resource_id = (int)$_POST["resource_id"]; $required_quantity = (int)$_POST["required_quantity"]; if ($required_quantity <= 0) { header("Location: admin.php?tab=levels&error=invalid_amount"); exit; } if ($id > 0) { $stmt = $db->prepare("UPDATE levels SET name = ?, slug = ?, resource_id = ?, required_quantity = ? WHERE id = ?"); $stmt->execute([$name, $slug, $resource_id, $required_quantity, $id]); } else { $stmt = $db->prepare("INSERT INTO levels (name, slug, resource_id, required_quantity) VALUES (?, ?, ?, ?)"); $stmt->execute([$name, $slug, $resource_id, $required_quantity]); } header("Location: admin.php?tab=levels&success=1"); exit; } if (isset($_GET["delete_level"])) { $id = (int)$_GET["delete_level"]; $db->prepare("DELETE FROM levels WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=levels&success=1"); exit; } // Handle Resource CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_resource') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $icon = $_POST['icon']; $description = $_POST['description']; $show_in_header = isset($_POST["show_in_header"]) ? 1 : 0; $image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM game_resources WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); } if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['image']["name"], PATHINFO_EXTENSION); $filename = "res_" . $slug . "_" . time() . "." . $ext; if (!is_dir("assets/images/resources")) { mkdir("assets/images/resources", 0775, true); } $target = "assets/images/resources/" . $filename; if (move_uploaded_file($_FILES['image']['tmp_name'], $target)) { $image_url = $target; } } if ($id > 0) { $stmt = $db->prepare("UPDATE game_resources SET name = ?, slug = ?, icon = ?, description = ?, image_url = ?, show_in_header = ? WHERE id = ?"); $stmt->execute([$name, $slug, $icon, $description, $image_url, $show_in_header, $id]); } else { $stmt = $db->prepare("INSERT INTO game_resources (name, slug, icon, description, image_url, show_in_header) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $icon, $description, $image_url, $show_in_header]); } header("Location: admin.php?tab=resources&success=1"); exit; } if (isset($_GET['delete_resource'])) { $id = (int)$_GET['delete_resource']; $db->prepare("DELETE FROM game_resources WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=resources&success=1"); exit; } // Handle Guild System Config error_log(print_r($_POST, true)); if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "update_guild_requirements") { $db->exec("DELETE FROM guild_creation_requirements"); $stmt = $db->prepare("INSERT INTO guild_creation_requirements (resource_id, amount) VALUES (?, ?)"); foreach ($_POST as $key => $value) { if (strpos($key, "res_") === 0 && (int)$value >= 0) { $res_id = (int)str_replace("res_", "", $key); $stmt->execute([$res_id, (int)$value]); } } if (isset($_POST['guild_member_limit'])) { $stmt = $db->prepare("UPDATE guild_restrictions SET value = ? WHERE restriction_key = 'member_limit'"); $stmt->execute([(int)$_POST['guild_member_limit']]); } header("Location: admin.php?tab=guilds&success=1"); exit; } // Handle Lootbox CRUD if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_grade') { $id = (int)$_POST['id']; $name = trim($_POST["name"]); $slug = trim($_POST['slug']); $user_type = $_POST['user_type']; $min_level = ($user_type === 'utilisateur') ? (int)$_POST['min_level'] : null; $max_level = ($user_type === 'utilisateur') ? (int)$_POST['max_level'] : null; if ($user_type === 'utilisateur' && $min_level > $max_level) { header('Location: ?tab=ranks&error=invalid_range'); exit; } // Check for overlap if user_type is 'utilisateur' if ($user_type === 'utilisateur') { $check = db()->prepare("SELECT id FROM grades WHERE user_type = 'utilisateur' AND id != ? AND NOT (max_level < ? OR min_level > ?)"); $check->execute([$id, $min_level, $max_level]); if ($check->fetch()) { header('Location: ?tab=ranks&error=overlap_levels'); exit; } } try { $image_url = null; if (!empty($_FILES["image"]["name"])) { $ext = pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION); $filename = "grade_" . time() . "_" . uniqid() . "." . $ext; if (!is_dir("assets/images/grades/")) mkdir("assets/images/grades/", 0775, true); move_uploaded_file($_FILES["image"]["tmp_name"], "assets/images/grades/" . $filename); $image_url = "assets/images/grades/" . $filename; } if ($id > 0) { $stmt = db()->prepare("UPDATE grades SET name = ?, slug = ?, user_type = ?, min_level = ?, max_level = ?, image_url = COALESCE(?, image_url) WHERE id = ?"); $stmt->execute([$name, $slug, $user_type, $min_level, $max_level, $image_url, $id]); } else { $stmt = db()->prepare("INSERT INTO grades (name, slug, user_type, min_level, max_level, image_url) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $user_type, $min_level, $max_level, $image_url]); } header('Location: ?tab=ranks&success=1'); exit; } catch (PDOException $e) { header('Location: ?tab=ranks&error=db'); exit; } } if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'upsert_lootbox') { $id = (int)$_POST['id']; $name = $_POST["name"]; $slug = $_POST['slug']; $description = $_POST['description']; if ($id > 0) { $stmt = $db->prepare("UPDATE lootboxes SET name = ?, slug = ?, description = ? WHERE id = ?"); $stmt->execute([$name, $slug, $description, $id]); } else { $stmt = $db->prepare("INSERT INTO lootboxes (name, slug, description) VALUES (?, ?, ?)"); $stmt->execute([$name, $slug, $description]); $id = $db->lastInsertId(); } // Handle Rolls $db->prepare("DELETE FROM lootbox_rolls WHERE lootbox_id = ?")->execute([$id]); if (isset($_POST['rolls_count']) && is_array($_POST['rolls_count'])) { $ins_roll = $db->prepare("INSERT INTO lootbox_rolls (lootbox_id, roll_count, probability) VALUES (?, ?, ?)"); foreach ($_POST['rolls_count'] as $idx => $rc) { $prob = (float)$_POST['rolls_prob'][$idx]; if ($prob > 0) { $ins_roll->execute([$id, (int)$rc, $prob]); } } } // Handle Items $db->prepare("DELETE FROM lootbox_items WHERE lootbox_id = ?")->execute([$id]); if (isset($_POST['item_slug']) && is_array($_POST['item_slug'])) { $ins_item = $db->prepare("INSERT INTO lootbox_items (lootbox_id, resource_slug, probability, quantity_min, quantity_max, is_guaranteed) VALUES (?, ?, ?, ?, ?, ?)"); foreach ($_POST['item_slug'] as $idx => $islug) { $is_guaranteed = isset($_POST['item_is_guaranteed'][$idx]) ? (int)$_POST['item_is_guaranteed'][$idx] : 0; $iprob = $is_guaranteed ? 100.00 : (float)$_POST['item_prob'][$idx]; if ($is_guaranteed || $iprob > 0) { $qmin = (int)$_POST['item_qmin'][$idx]; $qmax = (int)$_POST['item_qmax'][$idx]; $ins_item->execute([$id, $islug ?: null, $iprob, $qmin, $qmax, $is_guaranteed]); } } } header("Location: admin.php?tab=lootboxes&success=1"); exit; } if (isset($_GET['delete_lootbox'])) { $id = (int)$_GET['delete_lootbox']; $db->prepare("DELETE FROM lootboxes WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=lootboxes&success=1"); exit; } // Handle Project Log CRUD if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_project_log") { $id = (int)$_POST["id"]; $version = $_POST["version"]; $title = $_POST["title"]; $content_log = $_POST["content"]; if ($id > 0) { $stmt = $db->prepare("UPDATE project_logs SET version = ?, title = ?, content = ? WHERE id = ?"); $stmt->execute([$version, $title, $content_log, $id]); } else { $stmt = $db->prepare("INSERT INTO project_logs (version, title, content) VALUES (?, ?, ?)"); $stmt->execute([$version, $title, $content_log]); } header("Location: admin.php?tab=project_logs&success=1"); exit; } if (isset($_GET['delete_grade'])) { $id = (int)$_GET['delete_grade']; $stmt = db()->prepare("DELETE FROM grades WHERE id = ?"); $stmt->execute([$id]); header('Location: ?tab=ranks&success=deleted'); exit; } if (isset($_GET["delete_project_log"])) { $id = (int)$_GET["delete_project_log"]; $db->prepare("DELETE FROM project_logs WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=project_logs&success=1"); exit; } // Handle Unit CRUD if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["action"]) && $_POST["action"] === "upsert_unit") { $id = (int)$_POST["id"]; $name = $_POST["name"]; $slug = $_POST["slug"]; $faction_id = !empty($_POST["faction_id"]) ? (int)$_POST["faction_id"] : null; $can_be_destroyed = isset($_POST["can_be_destroyed"]) ? 1 : 0; $can_be_captured = isset($_POST["can_be_captured"]) ? 1 : 0; $points_per_hit = (int)$_POST["points_per_hit"]; $bonus_destruction = (int)$_POST["bonus_destruction"]; $bonus_capture = (int)$_POST["bonus_capture"]; $grid_data = $_POST["grid_data"]; $image_url = null; if ($id > 0) { $stmt_img = $db->prepare("SELECT image_url FROM units WHERE id = ?"); $stmt_img->execute([$id]); $image_url = $stmt_img->fetchColumn(); } if (isset($_FILES["image"]) && $_FILES["image"]["error"] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION); $filename = "unit_" . $slug . "_" . time() . "." . $ext; $target = "assets/images/units/" . $filename; if (!is_dir("assets/images/units/")) mkdir("assets/images/units/", 0775, true); if (move_uploaded_file($_FILES["image"]["tmp_name"], $target)) { $image_url = $target; } } if ($id > 0) { $stmt = $db->prepare("UPDATE units SET name = ?, slug = ?, faction_id = ?, can_be_destroyed = ?, can_be_captured = ?, points_per_hit = ?, bonus_destruction = ?, bonus_capture = ?, grid_data = ?, image_url = ? WHERE id = ?"); $stmt->execute([$name, $slug, $faction_id, $can_be_destroyed, $can_be_captured, $points_per_hit, $bonus_destruction, $bonus_capture, $grid_data, $image_url, $id]); } else { $stmt = $db->prepare("INSERT INTO units (name, slug, faction_id, can_be_destroyed, can_be_captured, points_per_hit, bonus_destruction, bonus_capture, grid_data, image_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$name, $slug, $faction_id, $can_be_destroyed, $can_be_captured, $points_per_hit, $bonus_destruction, $bonus_capture, $grid_data, $image_url]); $id = $db->lastInsertId(); } // Handle Rewards $db->prepare("DELETE FROM unit_rewards WHERE unit_id = ?")->execute([$id]); if (isset($_POST["reward_action"]) && is_array($_POST["reward_action"])) { $ins_rw = $db->prepare("INSERT INTO unit_rewards (unit_id, action_type, resource_id, amount) VALUES (?, ?, ?, ?)"); foreach ($_POST["reward_action"] as $idx => $action) { $res_id = (int)$_POST["reward_resource_id"][$idx]; $amount = (int)$_POST["reward_amount"][$idx]; if ($amount > 0) { $ins_rw->execute([$id, $action, $res_id, $amount]); } } } header("Location: admin.php?tab=units&success=1"); exit; } if (isset($_GET["delete_unit"])) { $id = (int)$_GET["delete_unit"]; $db->prepare("DELETE FROM units WHERE id = ?")->execute([$id]); header("Location: admin.php?tab=units&success=1"); exit; } // --- DATA FETCHING --- $users_list = []; $objects_list = []; $statuses_list = []; $status_rules_list = []; $status_profiles_list = []; $settlement_types_list = []; $modifiers_list = []; $factions_list = []; $resources_list = []; $lootboxes_list = []; $project_logs_list = []; $units_list = []; $titles_list = []; $badges_list = []; $levels_list = []; $ranks_list = []; $guild_requirements = []; $guild_member_limit = 50; if ($tab === 'users') { $users_list = $db->query("SELECT id, username, email, role FROM users ORDER BY username ASC")->fetchAll(); } elseif ($tab === 'objects') { $objects_list = $db->query("SELECT * FROM celestial_object_types ORDER BY name ASC")->fetchAll(); foreach ($objects_list as &$obj) { $stmt = $db->prepare("SELECT modifier_id FROM celestial_object_type_modifiers WHERE celestial_object_type_id = ?"); $stmt->execute([$obj['id']]); $obj['modifier_ids'] = $stmt->fetchAll(PDO::FETCH_COLUMN); } unset($obj); $modifiers_list = $db->query("SELECT * FROM modifiers ORDER BY type, name ASC")->fetchAll(); $status_profiles_list = $db->query("SELECT * FROM celestial_object_status_profiles ORDER BY name ASC")->fetchAll(); } elseif ($tab === 'statuses') { $statuses_list = $db->query("SELECT * FROM celestial_object_statuses ORDER BY name ASC")->fetchAll(); $status_rules_list = $db->query("SELECT r.*, s.name as status_name, p.name as profile_name FROM celestial_object_status_rules r JOIN celestial_object_statuses s ON r.status_id = s.id LEFT JOIN celestial_object_status_profiles p ON r.profile_id = p.id ORDER BY r.profile_id, r.priority DESC, r.name ASC")->fetchAll(); $status_profiles_list = $db->query("SELECT * FROM celestial_object_status_profiles ORDER BY name ASC")->fetchAll(); $factions_list = $db->query("SELECT * FROM factions ORDER BY name ASC")->fetchAll(); } elseif ($tab === 'settlement_types') { $settlement_types_list = $db->query("SELECT * FROM settlement_types ORDER BY name ASC")->fetchAll(); } elseif ($tab === 'modifiers') { $modifiers_list = $db->query("SELECT * FROM modifiers ORDER BY type, name ASC")->fetchAll(); } elseif ($tab === 'factions') { $factions_list = $db->query("SELECT * FROM factions ORDER BY name ASC")->fetchAll(); foreach ($factions_list as &$f) { $stmt = $db->prepare("SELECT faction_id_1 as ally_id FROM faction_alliances WHERE faction_id_2 = ? UNION SELECT faction_id_2 as ally_id FROM faction_alliances WHERE faction_id_1 = ?"); $stmt->execute([$f['id'], $f['id']]); $f['alliance_ids'] = $stmt->fetchAll(PDO::FETCH_COLUMN); } unset($f); } elseif ($tab === 'levels') { $levels_list = $db->query("SELECT l.*, r.name as resource_name FROM levels l JOIN game_resources r ON l.resource_id = r.id ORDER BY l.required_quantity ASC")->fetchAll(); $resources_list = $db->query("SELECT id, name FROM game_resources ORDER BY name ASC")->fetchAll(); } elseif ($tab === 'resources') { $resources_list = $db->query("SELECT * FROM game_resources ORDER BY name ASC")->fetchAll(); } elseif ($tab === 'project_logs') { $project_logs_list = $db->query("SELECT * FROM project_logs ORDER BY created_at DESC")->fetchAll(); } elseif ($tab === 'badges') { $titles_list = $db->query("SELECT * FROM titles ORDER BY name ASC")->fetchAll(); $badges_list = $db->query("SELECT * FROM badges ORDER BY name ASC")->fetchAll(); } elseif ($tab === 'ranks') { $ranks_list = $db->query("SELECT * FROM grades ORDER BY user_type DESC, min_level ASC")->fetchAll(); } elseif ($tab === 'lootboxes') { $lootboxes_list = $db->query("SELECT * FROM lootboxes ORDER BY name ASC")->fetchAll(); $resources_list = $db->query("SELECT name, slug FROM game_resources ORDER BY name ASC")->fetchAll(); foreach ($lootboxes_list as &$lb) { $stmt_r = $db->prepare("SELECT * FROM lootbox_rolls WHERE lootbox_id = ?"); $stmt_r->execute([$lb['id']]); $lb['rolls'] = $stmt_r->fetchAll(); $stmt_i = $db->prepare("SELECT * FROM lootbox_items WHERE lootbox_id = ?"); $stmt_i->execute([$lb['id']]); $lb['items'] = $stmt_i->fetchAll(); } unset($lb); } elseif ($tab === 'guilds') { $guild_requirements = $db->query("SELECT r.id, r.name, r.icon, gr.amount FROM game_resources r LEFT JOIN guild_creation_requirements gr ON r.id = gr.resource_id")->fetchAll(); $stmt = $db->query("SELECT value FROM guild_restrictions WHERE restriction_key = 'member_limit'"); $guild_member_limit = $stmt->fetchColumn() ?: 50; } elseif ($tab === "units") { $units_list = $db->query("SELECT u.*, f.name as faction_name FROM units u LEFT JOIN factions f ON u.faction_id = f.id ORDER BY u.name ASC")->fetchAll(); foreach ($units_list as &$unit) { $stmt_rw = $db->prepare("SELECT action_type, resource_id, amount FROM unit_rewards WHERE unit_id = ?"); $stmt_rw->execute([$unit["id"]]); $unit["rewards"] = $stmt_rw->fetchAll(); } unset($unit); $factions_list = $db->query("SELECT id, name FROM factions ORDER BY name ASC")->fetchAll(); $resources_list = $db->query("SELECT id, name FROM game_resources ORDER BY name ASC")->fetchAll(); } ?> Console Admin - Nexus

CONSOLE ADMIN

Erreur : La quantité doit être un nombre strictement positif.
Opération effectuée avec succès.
"> Journal de Bord Utilisateurs Niveaux Grades Titres & Badges "> Gestion de guilde
Objets Célestes Bonus & Malus Statuts / États Lieux et points d’intérêt Factions Ressources Lootboxes Unité

Gestion des Rôles

UtilisateurEmailRôle ActuelNouveau Rôle

Gestion des Unités

Ajouter / Modifier une Unité

Cliquez sur les cases pour définir la forme de l'unité (6x6).
Action
Ressource
Quantité
Image Nom / Slug Faction Propriétés Récompenses Actions
Aucune unité configurée.

Pts/Coup:
● Destructible
● Capturable
0): ?>Destr: + pts
0): ?>Capt: + pts
: +
Supprimer

Gestion des Niveaux

Ajouter / Modifier un Niveau

Nom Slug Ressource requise Quantité requise Actions
Aucun niveau configuré.
Supprimer

Gestion des Grades

Erreur : Les intervalles de niveaux pour les grades utilisateurs ne doivent pas se chevaucher.
Erreur : Le niveau maximum doit être supérieur ou égal au niveau minimum.

Ajouter / Modifier un Grade

Visuel Nom Slug Type Intervalle Niveau Actions
Aucun grade configuré.
" style="width:40px;"> - N/A Supprimer

Gestion des Guildes

Paramètres globaux des Guildes

Coût de création

RessourceQuantité requise
" value="">

Titres & Badges

Gestion des Titres

Titre Slug Niveau Couleur Actions
X

Gestion des Badges

Visuel Badge Slug Niveau Actions
X

Objets Célestes

Ajouter / Modifier un Objet

VisuelNomContrôlesRèglesBonus/MalusActions
?v=" style="max-width: 40px; max-height: 40px; display: block; margin: 0 auto;">
ORBITAL TERRESTRE
Fixe"; foreach($status_profiles_list as $p) if($p['id'] == $o['status_profile_id']) $p_name = htmlspecialchars($p["name"]); echo $p_name; ?> prepare("SELECT m.name, m.type FROM modifiers m JOIN celestial_object_type_modifiers cotm ON m.id = cotm.modifier_id WHERE cotm.celestial_object_type_id = ?"); $stmt->execute([$o['id']]); $m_list = $stmt->fetchAll(); foreach ($m_list as $ml): ?> Supprimer

Gestion des Bonus & Malus

Ajouter / Modifier un Modificateur

TypeNomDescriptionSlugActions
Supprimer

Statuts / États

Ajouter / Modifier un Statut

CouleurNomSlugActions
Supprimer

PROFILS / GROUPES DE RÈGLES

()

CONFIGURATION DES RÈGLES

EN ORBITE
Toutes / Peu importe
(Orbital) [?] (Sol)
AU SOL
Toutes / Peu importe
ProfilePrioritéNom / ConditionStatutActions

Toujours vrai'; ?>
Supprimer

Lieux et points d’intérêt

Ajouter / Modifier un Lieu et point d’intérêt

NomSlugDescriptionActions
Supprimer

Gestion des Factions

Ajouter / Modifier une Faction

CouleurVisuelNomSlugAlliancesActions
?v=" style="max-width: 40px; max-height: 40px;"> prepare("SELECT f.name FROM factions f JOIN faction_alliances fa ON (f.id = fa.faction_id_1 OR f.id = fa.faction_id_2) WHERE (fa.faction_id_1 = ? OR fa.faction_id_2 = ?) AND f.id != ?"); $stmt->execute([$f['id'], $f['id'], $f['id']]); $allies = $stmt->fetchAll(PDO::FETCH_COLUMN); if(empty($allies)) echo 'Aucune'; foreach($allies as $ally) echo '' . htmlspecialchars($ally) . ''; ?> Supprimer

Gestion des Ressources

Ajouter / Modifier une Ressource

VisuelHeaderNomSlugActions
?v=" style="max-width: 30px; max-height: 30px;"> Supprimer

Système de Lootboxes

Ajouter / Modifier une Lootbox

Nombre de tirages (Probabilités)
Nb Tirages
Probabilité (%)
Objets possibles dans la box
Ressource (Slug)
Probabilité (%)
Quantité (Min/Max)
Garanti ?
NomSlugTirages PossiblesNombre d'itemsActions
Supprimer

Journal de Bord du Projet

Nouvelle Entrée

Supprimer