Skip to content

Instantly share code, notes, and snippets.

@jkcgs
Last active December 18, 2015 19:19
Show Gist options
  • Save jkcgs/5832305 to your computer and use it in GitHub Desktop.
Save jkcgs/5832305 to your computer and use it in GitHub Desktop.
Retrieve info from Minecraft query port
<?php
/*
returns: Array
(
[hostip] => <ip>
[hostport] => <puerto>
[error] => <error info>
[is_online] => <true/false>
[hostname] => <motd>
[gametype] => SMP
[game_id] => MINECRAFT
[version] => <version>
[plugins] => Array
(
[API] => CB version
[list] => Of plugins, if apply
)
[map] => <main world name>
[numplayers] => <online players>
[maxplayers] => <max players>
[players] => Array
(
[0] => player1
[1] => player2
[...]
)
)
*/
function getMCQueryInfo($host = "127.0.0.1", $port = "25565"){
// parse the host if the port is there
if(preg_match('/:\d+$/',$host)){
if( preg_match('/:\/\//', $host) ) {
list($p, $host, $port) = explode(':', str_replace('//', '', $host));
} else list($host, $port) = explode(':', $host);
}
if(is_numeric($port)) $port = intval($port);
$info = array();
$info["hostip"] = $host;
$info["hostport"] = $port;
$info["error"] = "";
$info["is_online"] = false;
// connect!
if(@!$socket = stream_socket_client(sprintf('udp://%s:%u', $host, $port), $errno, $errstr, 1)){
$info["error"] = "Could not create connection: " . $errstr;
return $info;
}
// get the token
fwrite($socket, "\xFE\xFD\x09\x00\x00\x00\x01");
$data = fread($socket, 1024);
if(empty($data)){ // failed?
$info["error"] = "Failed to get token";
return $info;
}
// make the host send the info
$token = pack('N', substr($data, 5, -1));
$cmd = "\xFE\xFD\x00\x00\x00\x00\x01";
$cmd .= $token . "\x00\x00\x00\x00";
fwrite($socket, $cmd);
$data = fread($socket, 4096);
// first split of data
$kv_del = strpos($data, "splitnum") + 11; // K, V section
$pl_del = strpos($data, "player_") + 9; // players section
// take the data to array
$info_raw = explode("\x00", substr($data, $kv_del, $pl_del - strlen($data) - 12));
for($i = 0; $i < count($info_raw)/2; $i++)
$info[$info_raw[$i*2]] = $info_raw[$i*2+1];
// split plugins info
$info["plugins"] = explode(": ", $info["plugins"]);
$info["plugins"] = array(
"API" => $info["plugins"][0],
"list" => (count($info["plugins"])==1) ? array() : explode("; ",$info["plugins"][1])
);
// split players
$players = explode("\x00", substr($data, $pl_del, -2));
$info["players"] = ($players[0] == "") ? array() : $players;
$info["is_online"] = true;
return $info;
}
$msg = "";
$status = array();
$ok = false;
if(isset($_POST["host"]) && isset($_POST["pass"])){
if(md5(md5(md5($_POST["pass"]))) != "fa1c798431ade1bef7dea94da4bfd1eb")
$msg = "Contrase&ntilde;a incorrecta o inv&aacute;lida";
elseif(empty($_POST["host"]))
$msg = "Host incorrecto";
else{
$status = getMCQueryInfo($_POST["host"]);
if(!$status["is_online"])
$msg = "Servidor offline o incorrecto";
else
$ok = true;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Hola que hace</title>
<meta charset="utf-8" />
</head>
<body>
<form method="post" action="?">
<label>Host: <input type="text" name="host" value="127.0.0.1" /> </label>
<br />
<label>Pass: <input type="password" name="pass" maxlength="25" /></label>
<br />
<input type="submit" value="Obtener info" />
</form>
<?php
if(!empty($msg)) { ?>
<strong><?=$msg?></strong>
<?php
}
if($ok){ ?>
<pre>
<?php
print_r($status); ?>
</pre>
<?php
} ?>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment