Last active
June 2, 2019 21:44
-
-
Save BEcraft/80f291ecda6d747949c8e7dfc667425f to your computer and use it in GitHub Desktop.
Consulta un servidor de Minecraft Bedrock | Query a Minecraft Bedrock server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//Mas información: https://wiki.vg/Query | |
$direccion = gethostbyname("127.0.0.1"); | |
$puerto = 19132; | |
$socket = fsockopen("udp://" . $direccion, $puerto, $error_id, $error, 30); //Pueden usar un socket creado por la extención de Sockets sin ningún problema. | |
//Veríficación del socket. | |
if (is_resource($socket) === false) { | |
die("No se ha podido crear la conexión, el servidor no está en línea o no existe"); | |
} | |
//Tiempo límite de respuesta. | |
stream_set_timeout($socket, 3); | |
//Datos importantes. | |
define("ENCABEZADO", "\xFE\xFD"); //"Magia" | |
define("SESION", pack("N", mt_rand(1, 999999))); //Identificador del la sesión. | |
//Primera solicitud hacia el servidor. | |
$handshake = function(string $datos, string $accion) { | |
switch ($accion) { | |
//Decodifica el token que será necesario para obtener los datos del servidor. | |
//Ambos métodos funcionan. | |
case "decodificar": | |
if (true) { | |
$handshake = substr($datos, 5, strlen($datos)); | |
} else { | |
$handshake = substr(preg_replace("{[^0-9\-]}si", "", $datos), 1); //Opción #2 | |
$handshake = ($handshake >> 24) . ($handshake >> 16) . ($handshake >> 8) . ($handshake >> 0); | |
} | |
break; | |
//Códifica la solicitud para recibir el token. | |
case "codificar": | |
$handshake = ENCABEZADO; | |
$handshake .= "\x09"; | |
$handshake .= SESION; | |
$handshake .= ""; //vacío | |
break; | |
} | |
return ($handshake ?? ""); | |
}; | |
//Segunda solicitud hacia el servidor. | |
$statistics = function (string $datos, string $accion, bool $longQuery = true) { | |
switch ($accion) { | |
case "decodificar": | |
// $datos = preg_replace("{}") | |
$informacion = array( | |
"hostname" => null, | |
"gametype" => null, | |
"map" => null, //Datos para información simple. | |
"numplayers" => null, | |
"maxplayers" => null, | |
); | |
$larga = strpos($datos, chr(128)); //Verífica si la informacion es de tipo "long query". | |
if ($larga !== false) { | |
$partes = explode("\x00\x01player_\x00\x00", $datos); | |
if (count($partes) > 1) { | |
$informacion["players"] = array_filter(explode("\x00", array_pop($partes)), function ($usuario) { | |
return $usuario !== ""; | |
}); | |
} | |
} | |
if ($larga !== false) { | |
$partes = array_chunk(explode("\x00", substr($partes[0], (strpos($partes[0], chr(128)) + 2), strlen($partes[0]))), 2); | |
} else { | |
$partes = explode("\x00", substr($partes, 5, strlen($partes))); | |
} | |
$llaves = array_keys($informacion); array_pop($partes); | |
foreach ($partes as $llave => $valor) { | |
if ($larga !== false) { | |
if ($valor[0] === "plugins") { | |
$valor[1] = array_filter(explode("; ", str_replace(":", ";", $relleno)), function ($componente) { | |
return $componente !== ""; | |
}); | |
} | |
$informacion[$valor[0]] = $valor[1]; | |
} else { | |
if (isset($llaves[$llave]) === true) { | |
$informacion[$llaves[$llave]] = $valor; | |
} | |
} | |
} | |
$informacion["raw"] = $datos; | |
break; | |
case "codificar": | |
$statistics = ENCABEZADO; | |
$statistics .= "\x00"; | |
$statistics .= SESION; | |
$statistics .= pack("N", $datos); | |
$statistics .= ($longQuery === true) ? str_repeat("\x01", 4) : ""; //En caso de no recibir información usar false. | |
break; | |
} | |
return (($statistics ?? $informacion) ?? ""); | |
}; | |
//En caso de que no funcione el primer método, intenta con un unconnected_ping. | |
$unconnected_ping = function () { | |
return ("\x01" . SESION . "\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x12\x34\x56\x78"); | |
}; | |
//Ennvío de solicitud al servidor. | |
$solicitud = $handshake("", "codificar"); | |
if (@fwrite($socket, $solicitud) === false) { | |
die("#01"); | |
} | |
//Consigue la respuesta del servidor, en caso de no recibir intentará con un unconneted_ping. | |
$respuesta = (string) @fread($socket, 65535); | |
if ($respuesta === "") { | |
if (@fwrite($socket, $unconnected_ping())) { | |
$informacion = $statistics((string) @fread($socket, 65535), "decodificar"); | |
} | |
} | |
//Verífica si aún no hay información y prosigue. | |
if (isset($informacion) === false) { | |
if (@fwrite($socket, $statistics($handshake($respuesta, "decodificar"), "codificar")) === false) { | |
die("#02"); | |
} | |
$informacion = $statistics((string) @fread($socket, 65535), "decodificar"); | |
} | |
var_dump($informacion); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment