Skip to content

Instantly share code, notes, and snippets.

@BEcraft
Last active June 2, 2019 21:44
Show Gist options
  • Save BEcraft/80f291ecda6d747949c8e7dfc667425f to your computer and use it in GitHub Desktop.
Save BEcraft/80f291ecda6d747949c8e7dfc667425f to your computer and use it in GitHub Desktop.
Consulta un servidor de Minecraft Bedrock | Query a Minecraft Bedrock server
<?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