diff --git a/index-en.php b/index-en.php index 45f9587..35484cd 100644 --- a/index-en.php +++ b/index-en.php @@ -1,5 +1,73 @@ 'scan-rarity-L', + 'E' => 'scan-rarity-E', + 'R' => 'scan-rarity-R', + 'U' => 'scan-rarity-U', + 'C' => 'scan-rarity-C', + default => 'scan-rarity-none', + }; +} + +function index_scan_rarity_label(?string $rarity): string +{ + return match (index_scan_normalize_rarity($rarity)) { + 'L' => 'Légendaire', + 'E' => 'Épique', + 'R' => 'Rare', + 'U' => 'Peu commun', + 'C' => 'Commun', + default => 'Non définie', + }; +} + +function index_itemcustom_display_value($value): string +{ + if ($value === null || $value === '') { + return '0'; + } + + if (is_numeric($value)) { + $formatted = number_format((float) $value, 2, '.', ''); + $formatted = rtrim(rtrim($formatted, '0'), '.'); + return $formatted === '' ? '0' : $formatted; + } + + return trim((string) $value) !== '' ? trim((string) $value) : '0'; +} + +function index_itemcustom_stat_preview(?string $sign, $value, ?string $unit): string +{ + $prefix = $sign === '-' ? '-' : ($sign === '+' ? '+' : ''); + $displayValue = index_itemcustom_display_value($value); + $displayUnit = trim((string) ($unit ?? '')); + + return trim($prefix . $displayValue . ($displayUnit !== '' ? ' ' . $displayUnit : '')); +} + +function index_vanilla_description_html(?string $description): string +{ + $description = trim((string) $description); + if ($description === '') { + return 'Aucune description.'; + } + + if ($description !== strip_tags($description)) { + return $description; + } + + return nl2br(htmlspecialchars($description, ENT_QUOTES, 'UTF-8')); +} auth_start_session(); auth_bootstrap(); @@ -8,6 +76,314 @@ $session_cl_auth_user = isset($_SESSION['user']) ? (string) $_SESSION['user'] : $session_cl_auth_right = isset($_SESSION['role']) ? (string) $_SESSION['role'] : ''; $is_authenticated = $session_cl_auth_user !== ''; $has_member_access = $is_authenticated && in_array($session_cl_auth_right, ['member', 'admin'], true); +$has_vanilla_db_access = $is_authenticated && in_array($session_cl_auth_right, ['member', 'moderator', 'admin'], true); + +$scan_reference_rows = []; +$scan_reference_max_occurrence = 0; +$scan_reference_error = null; +$ship_preset_rows = []; +$ship_preset_manufacturers = []; +$ship_preset_error = null; +$item_custom_public_rows = []; +$item_custom_public_types = []; +$item_custom_public_error = null; +$vanilla_db_rows = []; +$vanilla_db_error = null; +$vanilla_db_search = ''; +$vanilla_db_per_page = 10; +$vanilla_db_total_rows = 0; +$vanilla_db_total_pages = 1; +$vanilla_db_current_page = 1; +$vanilla_db_result_start = 0; +$vanilla_db_result_end = 0; +$vanilla_db_base_query = ['open_modal' => 'vanilla-db']; +$vanilla_db_reset_url = 'index.php?open_modal=vanilla-db'; +$should_open_vanilla_db_modal = false; + +try { + $db = db(); + $stmt_scan_reference = $db->query( + "SELECT o.cl_scobjs_id, o.cl_scobjs_name, o.cl_scobjs_rarity, m.cl_scmining_scan_value, m.cl_scmining_max_occurrence, + m.cl_scmining_can_manual, m.cl_scmining_can_land, m.cl_scmining_can_space + FROM tbl_scmining m + INNER JOIN tbl_scobjs o ON o.cl_scobjs_id = m.cl_scmining_obj_id + ORDER BY + CASE UPPER(COALESCE(o.cl_scobjs_rarity, '')) + WHEN 'L' THEN 1 + WHEN 'E' THEN 2 + WHEN 'R' THEN 3 + WHEN 'U' THEN 4 + WHEN 'C' THEN 5 + ELSE 6 + END, + o.cl_scobjs_name ASC" + ); + + foreach ($stmt_scan_reference->fetchAll() as $row) { + $occurrence_count = max(1, (int) ($row['cl_scmining_max_occurrence'] ?? 1)); + $scan_value = (int) ($row['cl_scmining_scan_value'] ?? 0); + $recovery_modes = []; + + if (!empty($row['cl_scmining_can_manual'])) { + $recovery_modes[] = 'Manuel'; + } + if (!empty($row['cl_scmining_can_land'])) { + $recovery_modes[] = 'Terrestre'; + } + if (!empty($row['cl_scmining_can_space'])) { + $recovery_modes[] = 'Spatial'; + } + + $scan_steps = []; + for ($i = 1; $i <= $occurrence_count; $i++) { + $scan_steps[] = $scan_value * $i; + } + + $scan_reference_rows[] = [ + 'id' => (string) ($row['cl_scobjs_id'] ?? ''), + 'name' => (string) ($row['cl_scobjs_name'] ?? ''), + 'rarity' => index_scan_normalize_rarity($row['cl_scobjs_rarity'] ?? ''), + 'rarity_label' => index_scan_rarity_label($row['cl_scobjs_rarity'] ?? ''), + 'rarity_class' => index_scan_rarity_class($row['cl_scobjs_rarity'] ?? ''), + 'recovery_modes' => $recovery_modes, + 'scan_steps' => $scan_steps, + 'max_occurrence' => $occurrence_count, + ]; + + $scan_reference_max_occurrence = max($scan_reference_max_occurrence, $occurrence_count); + } +} catch (Throwable $e) { + $scan_reference_error = 'Impossible de charger le tableau des signatures de scan pour le moment.'; +} + +if ($has_member_access) { + try { + if (!isset($db) || !($db instanceof PDO)) { + $db = db(); + } + + $stmt_ship_presets = $db->query( + "SELECT cl_scpreset_id, cl_scpreset_name, cl_scpreset_manufacturer, cl_scpreset_description, cl_scpreset_link, cl_scpreset_creator + FROM tbl_scpreset + ORDER BY cl_scpreset_manufacturer ASC, cl_scpreset_name ASC" + ); + + foreach ($stmt_ship_presets->fetchAll() as $row) { + $ship_name = trim((string) ($row['cl_scpreset_name'] ?? '')) ?: 'Vaisseau inconnu'; + $manufacturer = trim((string) ($row['cl_scpreset_manufacturer'] ?? '')) ?: 'Manufacture inconnue'; + $manufacturer_key = function_exists('mb_strtolower') + ? mb_strtolower($manufacturer, 'UTF-8') + : strtolower($manufacturer); + + $ship_preset_manufacturers[$manufacturer_key] = $manufacturer; + + $ship_preset_rows[] = [ + 'id' => (string) ($row['cl_scpreset_id'] ?? ''), + 'name' => $ship_name, + 'manufacturer' => $manufacturer, + 'creator' => trim((string) ($row['cl_scpreset_creator'] ?? '')) ?: 'Inconnu', + 'description' => trim((string) ($row['cl_scpreset_description'] ?? '')) ?: 'Aucune description disponible pour ce preset.', + 'link' => trim((string) ($row['cl_scpreset_link'] ?? '')), + ]; + } + + natcasesort($ship_preset_manufacturers); + $ship_preset_manufacturers = array_values($ship_preset_manufacturers); + } catch (Throwable $e) { + $ship_preset_error = 'Impossible de charger les presets de vaisseaux pour le moment.'; + } +} + +if ($has_member_access) { + try { + if (!isset($db) || !($db instanceof PDO)) { + $db = db(); + } + + $stmt_item_custom_public = $db->query( + "SELECT + c.cl_scitemcustom_id, + o.cl_scobjs_name, + o.cl_scobjs_uuid, + o.cl_scobjs_type, + o.cl_scobjs_subtype, + COALESCE(NULLIF(TRIM(a.cl_auth_user), ''), 'Inconnu') AS creator_name, + cs.cl_scitemcustomstat_id, + cs.cl_scitemcustomstat_sign, + cs.cl_scitemcustomstat_value, + st.cl_scstatsitem_name, + st.cl_scstatsitem_unit + FROM tbl_scitemcustom c + INNER JOIN tbl_scobjs o ON o.cl_scobjs_id = c.cl_scitemcustom_obj_id + LEFT JOIN tbl_auth a ON a.cl_auth_id = c.cl_scitemcustom_owner_auth_id + LEFT JOIN tbl_scitemcustomstat cs ON cs.cl_scitemcustomstat_itemcustom_id = c.cl_scitemcustom_id + LEFT JOIN tbl_scstatsitem st ON st.cl_scstatsitem_id = cs.cl_scitemcustomstat_stat_id + WHERE c.cl_scitemcustom_owner_auth_id IS NOT NULL + ORDER BY o.cl_scobjs_name ASC, creator_name ASC, c.cl_scitemcustom_id ASC, st.cl_scstatsitem_name ASC, cs.cl_scitemcustomstat_id ASC" + ); + + $grouped_item_custom_public = []; + + foreach ($stmt_item_custom_public->fetchAll() as $row) { + $item_id = (int) ($row['cl_scitemcustom_id'] ?? 0); + if ($item_id <= 0) { + continue; + } + + if (!isset($grouped_item_custom_public[$item_id])) { + $name = trim((string) ($row['cl_scobjs_name'] ?? '')) ?: 'Objet inconnu'; + $creator = trim((string) ($row['creator_name'] ?? '')) ?: 'Inconnu'; + $type = trim((string) ($row['cl_scobjs_type'] ?? '')); + $subtype = trim((string) ($row['cl_scobjs_subtype'] ?? '')); + $uuid = trim((string) ($row['cl_scobjs_uuid'] ?? '')); + + $grouped_item_custom_public[$item_id] = [ + 'id' => $item_id, + 'name' => $name, + 'creator' => $creator, + 'type' => $type, + 'subtype' => $subtype, + 'uuid' => $uuid, + 'stats' => [], + 'search_parts' => [$name, $creator, $type, $subtype, $uuid], + ]; + } + + if (!empty($row['cl_scitemcustomstat_id'])) { + $stat_name = trim((string) ($row['cl_scstatsitem_name'] ?? '')) ?: 'Stat inconnue'; + $stat_sign = trim((string) ($row['cl_scitemcustomstat_sign'] ?? '')); + $stat_value_raw = $row['cl_scitemcustomstat_value'] ?? 0; + $stat_unit = trim((string) ($row['cl_scstatsitem_unit'] ?? '')); + $stat_preview = index_itemcustom_stat_preview($stat_sign, $stat_value_raw, $stat_unit); + + $grouped_item_custom_public[$item_id]['stats'][] = [ + 'name' => $stat_name, + 'preview' => $stat_preview, + ]; + + $grouped_item_custom_public[$item_id]['search_parts'][] = $stat_name; + $grouped_item_custom_public[$item_id]['search_parts'][] = $stat_preview; + } + } + + $item_custom_public_types_lookup = []; + + foreach ($grouped_item_custom_public as $item_custom_public_row) { + $item_custom_public_row['search'] = trim(implode(' ', array_filter($item_custom_public_row['search_parts'], static function ($value) { + return trim((string) $value) !== ''; + }))); + unset($item_custom_public_row['search_parts']); + $item_custom_public_rows[] = $item_custom_public_row; + + $item_custom_public_type_label = $item_custom_public_row['type'] !== '' ? $item_custom_public_row['type'] : 'Type inconnu'; + $item_custom_public_type_key = strtolower($item_custom_public_type_label); + if (!isset($item_custom_public_types_lookup[$item_custom_public_type_key])) { + $item_custom_public_types_lookup[$item_custom_public_type_key] = $item_custom_public_type_label; + } + } + + natcasesort($item_custom_public_types_lookup); + $item_custom_public_types = array_values($item_custom_public_types_lookup); + } catch (Throwable $e) { + $item_custom_public_error = 'Impossible de charger les objets Item Custom pour le moment.'; + } +} + +if ($has_vanilla_db_access) { + $vanilla_db_search = trim((string) ($_GET['vanilla_search'] ?? '')); + $vanilla_db_current_page = max(1, (int) ($_GET['vanilla_page'] ?? 1)); + $should_open_vanilla_db_modal = ( + (isset($_GET['open_modal']) && (string) $_GET['open_modal'] === 'vanilla-db') + || $vanilla_db_search !== '' + || isset($_GET['vanilla_page']) + ); + + $vanilla_db_base_query = ['open_modal' => 'vanilla-db']; + if ($vanilla_db_search !== '') { + $vanilla_db_base_query['vanilla_search'] = $vanilla_db_search; + } + $vanilla_db_reset_url = 'index.php?' . http_build_query(['open_modal' => 'vanilla-db']); + + try { + if (!isset($db) || !($db instanceof PDO)) { + $db = db(); + } + + $vanilla_db_where_sql = ''; + $vanilla_db_bindings = []; + + if ($vanilla_db_search !== '') { + $vanilla_db_where_sql = " + WHERE ( + cl_scobjs_name LIKE :vanilla_search + OR cl_scobjs_type LIKE :vanilla_search + OR cl_scobjs_subtype LIKE :vanilla_search + OR cl_scobjs_uuid LIKE :vanilla_search + OR cl_scobjs_rarity LIKE :vanilla_search + OR cl_scobjs_description LIKE :vanilla_search + )"; + $vanilla_db_bindings[':vanilla_search'] = '%' . $vanilla_db_search . '%'; + } + + $stmt_vanilla_db_count = $db->prepare( + "SELECT COUNT(*) + FROM tbl_scobjs" . $vanilla_db_where_sql + ); + + foreach ($vanilla_db_bindings as $bindingName => $bindingValue) { + $stmt_vanilla_db_count->bindValue($bindingName, $bindingValue, PDO::PARAM_STR); + } + + $stmt_vanilla_db_count->execute(); + $vanilla_db_total_rows = (int) $stmt_vanilla_db_count->fetchColumn(); + $vanilla_db_total_pages = max(1, (int) ceil($vanilla_db_total_rows / $vanilla_db_per_page)); + $vanilla_db_current_page = min($vanilla_db_current_page, $vanilla_db_total_pages); + $vanilla_db_offset = ($vanilla_db_current_page - 1) * $vanilla_db_per_page; + + $stmt_vanilla_db = $db->prepare( + "SELECT cl_scobjs_id, cl_scobjs_name, cl_scobjs_type, cl_scobjs_subtype, cl_scobjs_uuid, cl_scobjs_rarity, cl_scobjs_description + FROM tbl_scobjs" . $vanilla_db_where_sql . " + ORDER BY cl_scobjs_name ASC, cl_scobjs_type ASC, cl_scobjs_subtype ASC, cl_scobjs_id ASC + LIMIT :vanilla_limit OFFSET :vanilla_offset" + ); + + foreach ($vanilla_db_bindings as $bindingName => $bindingValue) { + $stmt_vanilla_db->bindValue($bindingName, $bindingValue, PDO::PARAM_STR); + } + $stmt_vanilla_db->bindValue(':vanilla_limit', $vanilla_db_per_page, PDO::PARAM_INT); + $stmt_vanilla_db->bindValue(':vanilla_offset', $vanilla_db_offset, PDO::PARAM_INT); + $stmt_vanilla_db->execute(); + + foreach ($stmt_vanilla_db->fetchAll() as $row) { + $name = trim((string) ($row['cl_scobjs_name'] ?? '')) ?: 'Objet inconnu'; + $type = trim((string) ($row['cl_scobjs_type'] ?? '')) ?: '—'; + $subtype = trim((string) ($row['cl_scobjs_subtype'] ?? '')) ?: '—'; + $uuid = trim((string) ($row['cl_scobjs_uuid'] ?? '')) ?: '—'; + $rarity = index_scan_normalize_rarity($row['cl_scobjs_rarity'] ?? ''); + $description = trim((string) ($row['cl_scobjs_description'] ?? '')); + + $vanilla_db_rows[] = [ + 'id' => (int) ($row['cl_scobjs_id'] ?? 0), + 'name' => $name, + 'type' => $type, + 'subtype' => $subtype, + 'uuid' => $uuid, + 'image_url' => $uuid !== '—' ? 'https://cstone.space/uifimages/' . rawurlencode($uuid) . '.png' : null, + 'rarity' => $rarity !== '' ? $rarity : '—', + 'rarity_label' => $rarity !== '' ? index_scan_rarity_label($rarity) : 'Non définie', + 'rarity_class' => index_scan_rarity_class($rarity), + 'description_html' => index_vanilla_description_html($description), + ]; + } + + if ($vanilla_db_total_rows > 0) { + $vanilla_db_result_start = $vanilla_db_offset + 1; + $vanilla_db_result_end = $vanilla_db_offset + count($vanilla_db_rows); + } + } catch (Throwable $e) { + $vanilla_db_error = 'Impossible de charger la base des objets pour le moment.'; + } +} ?> @@ -25,21 +401,1354 @@ $has_member_access = $is_authenticated && in_array($session_cl_auth_right, ['mem +
+ - + + +Aucun preset de vaisseau n'est enregistré pour le moment.
+ + +