false, 'players' => 0, 'max_players' => 0, 'version' => '', 'motd' => '', 'latency' => null, ]; $start = microtime(true); $socket = @fsockopen($host, $port, $errno, $errstr, $timeout); if (!$socket) { return $result; } stream_set_timeout($socket, $timeout); // ---- Handshake packet (0x00) ---- $hostBytes = $host; $hostLen = strlen($hostBytes); $handshakeData = "\x00"; // Packet ID 0x00 $handshakeData .= varInt(47); // Protocol version (47 = 1.8, -1 non-spécifique) $handshakeData .= varInt($hostLen) . $hostBytes; // Server address $handshakeData .= pack('n', $port); // Port (unsigned short big-endian) $handshakeData .= varInt(1); // Next state: 1 = status fwrite($socket, varInt(strlen($handshakeData)) . $handshakeData); // ---- Status Request (0x00, longueur 1) ---- fwrite($socket, "\x01\x00"); // ---- Lire la réponse ---- $packetLen = readVarInt($socket); if ($packetLen <= 0) { fclose($socket); return $result; } // Lire l'ID du paquet (doit être 0x00) readVarInt($socket); // Lire la longueur de la chaîne JSON $strLen = readVarInt($socket); if ($strLen <= 0) { fclose($socket); return $result; } // Lire le JSON $json = ''; $remaining = $strLen; while ($remaining > 0 && !feof($socket)) { $chunk = fread($socket, min($remaining, 4096)); if ($chunk === false || $chunk === '') break; $json .= $chunk; $remaining -= strlen($chunk); } fclose($socket); $latency = (int) round((microtime(true) - $start) * 1000); $data = @json_decode($json, true); if (!$data) { return $result; } // ---- Extraire le MOTD ---- $motd = ''; if (isset($data['description'])) { if (is_string($data['description'])) { $motd = $data['description']; } elseif (is_array($data['description'])) { $motd = $data['description']['text'] ?? ''; // Concatener les extras if (!empty($data['description']['extra']) && is_array($data['description']['extra'])) { foreach ($data['description']['extra'] as $extra) { $motd .= $extra['text'] ?? ''; } } } } // Supprimer les codes couleur §X $motd = preg_replace('/§[0-9a-fk-orA-FK-OR]/u', '', $motd); $motd = trim(preg_replace('/\s+/', ' ', $motd)); $result['online'] = true; $result['players'] = (int) ($data['players']['online'] ?? 0); $result['max_players'] = (int) ($data['players']['max'] ?? 0); $result['version'] = $data['version']['name'] ?? ''; $result['motd'] = $motd; $result['latency'] = $latency; return $result; } /** * Encode un entier en VarInt Minecraft */ function varInt(int $value): string { $out = ''; do { $byte = $value & 0x7F; $value = ($value >> 7) & PHP_INT_MAX; // shift sans signe if ($value !== 0) $byte |= 0x80; $out .= chr($byte); } while ($value !== 0); return $out; } /** * Lit un VarInt depuis un socket */ function readVarInt($socket): int { $value = 0; $shift = 0; do { $raw = fgetc($socket); if ($raw === false) return 0; $byte = ord($raw); $value |= ($byte & 0x7F) << $shift; $shift += 7; if ($shift > 35) break; // sécurité anti-boucle infinie } while ($byte & 0x80); return $value; } // ====================================================== // Configuration des serveurs à pinger // ====================================================== $servers = [ [ 'name' => 'Serveur MC #1', 'host' => 'nix.roulaise.net', 'port' => 9191, ], [ 'name' => 'Serveur MC #2', 'host' => 'nix.roulaise.net', 'port' => 9292, ], ]; // ====================================================== // Ping tous les serveurs et retourner le résultat JSON // ====================================================== $results = []; foreach ($servers as $srv) { $ping = pingMinecraftServer($srv['host'], $srv['port']); $results[] = array_merge([ 'name' => $srv['name'], 'host' => $srv['host'], 'port' => $srv['port'], ], $ping); } echo json_encode([ 'success' => true, 'servers' => $results, 'timestamp' => time(), ], JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK); ?>