[WEB] [PHP] Simple to use minecraft server status query!

Discussion in 'Bukkit Tools' started by FunnyItsElmo, Apr 29, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Coolechriz

    I'm have the same errors:

    Code:
    Warning: socket_connect() [function.socket-connect]: unable to connect [110]: Connection timed out in /home/***/domains/***/public_html/index_test.php on line 136
     
    Warning: socket_send() [function.socket-send]: unable to write to socket [32]: Broken pipe in /home/***/domains/***/public_html/index_test.php on line 44
     
    Warning: socket_send() [function.socket-send]: unable to write to socket [32]: Broken pipe in /home/***/domains/***/public_html/index_test.php on line 45
     
    Warning: socket_read() [function.socket-read]: unable to read from socket [107]: Transport endpoint is not connected in /home/***/domains/***/public_html/index_test.php on line 46
     
    Warning: socket_read() [function.socket-read]: unable to read from socket [107]: Transport endpoint is not connected in /home/***/domains/***/public_html/index_test.php on line 150
    Do someting
     
  2. Offline

    mmuziek

    i really like to see a querry script like this showing a list of players online.
    without the need of querry enabled in the config ?

    is that possible?
     
  3. Offline

    john01dav

    No, unfortunately.
     
  4. Offline

    Zlimon

    When i updated my website with the update for mc 1.7, it didnt work anymore.
    It just says my server is offline, and i KNOW that query is enabled on my server. It worked perfect before with mc 1.6 until the 1.7 came and messed up the query. I can use it on other servers, but it doesnt work on mine. Im sure i have written the right ip and port.

    My website is running on a raspberry pi with linux debian, and the server is running on another computer with linux debian, and they are both on the same network. Im not sure if thats the problem :oops:
     
  5. Offline

    MartyRot

    Maybe someone can help me? I only get a blank page when I test this script on my website. I have tried several servers but ill get a blank page anyway. I think it indicates that I have done something wrong with the scrips. What is wrong?

    This is "example.php"
    PHP:
    <html>
    <head>
    <title>Minecraft server</title>
    </head>
    <body>
    <?php
     
        
    include_once 'status.class.php'//include the class
        
    $status = new MinecraftServerStatus(); // call the class
        
    $response $status-> getStatus('37.59.252.113'25889); // when you dont have the default port
    if(!$response) {
        echo
    "The Server is offline!";
    } else {
        echo
    "<img width=\"64\" height=\"64\" src=\"".$response['favicon']."\" /> <br>
        The Server "
    .$response['hostname']." is running on ".$response['version']." and is online,
        currently are "
    .$response['players']." players online
        of a maximum of "
    .$response['maxplayers'].". The motd of the server is '".$response['motd']."'.
        The server has a ping of "
    .$response['ping']." milliseconds.";
    }
     
    ?>
    </body>
    </html>
    And i didn't change anything in "status.class.php"
    PHP:
    <?php
     
        
    /**
        * Minecraft Server Status Query
        * @author Julian Spravil <julian.spr@t-online.de> https://github.com/FunnyItsElmo
        * @license Free to use but dont remove the author, license and copyright
        * [USER=90879835]Copyright[/USER] © 2013 Julian Spravil
        */
        
    class MinecraftServerStatus {
     
            private 
    $timeout;
     
            public function 
    __construct($timeout 2) {
                
    $this->timeout $timeout;
            }
     
            public function 
    getStatus($host '127.0.0.1'$version '1.7.*' $port 25565) {
     
                if (
    substr_count($host '.') != 4$host gethostbyname($host);
     
                
    $serverdata = array();
                
    $serverdata['hostname'] = $host;
                
    $serverdata['version'] = false;
                
    $serverdata['protocol'] = false;
                
    $serverdata['players'] = false;
                
    $serverdata['maxplayers'] = false;
                
    $serverdata['motd'] = false;
                
    $serverdata['motd_raw'] = false;
                
    $serverdata['favicon'] = false;
                
    $serverdata['ping'] = false;
     
                
    $socket $this->connect($host$port);
     
                if(!
    $socket) {
                    return 
    false;
                }
     
                if(
    preg_match('/1.7|1.8/',$version)) {
     
                    
    $start microtime(true);
     
                    
    $handshake pack('cccca*'hexdec(strlen($host)), 00x04strlen($host), $host).pack('nc'$port0x01);
     
                    
    socket_send($socket$handshakestrlen($handshake), 0); //give the server a high five
                    
    socket_send($socket"\x01\x00"20);
                    
    socket_read$socket);
     
                    
    $ping round((microtime(true)-$start)*1000); //calculate the high five duration
     
                    
    $packetlength $this->read_packet_length($socket);
     
                    if(
    $packetlength 10) {
                        return 
    false;
                    }
     
                    
    socket_read($socket1);
     
                    
    $packetlength $this->read_packet_length($socket);
     
                    
    $data socket_read($socket$packetlengthPHP_NORMAL_READ);
     
                    if(!
    $data) {
                        return 
    false;
                    }
     
                    
    $data json_decode($data);
     
                    
    $serverdata['version'] = $data->version->name;
                    
    $serverdata['protocol'] = $data->version->protocol;
                    
    $serverdata['players'] = $data->players->online;
                    
    $serverdata['maxplayers'] = $data->players->max;
     
                    
    $motd $data->description;
                    
    $motd preg_replace("/(§.)/""",$motd);
                    
    $motd preg_replace("/[^[:alnum:][:punct:] ]/"""$motd);
     
                    
    $serverdata['motd'] = $motd;
                    
    $serverdata['motd_raw'] = $data->description;
                    
    $serverdata['favicon'] = $data->favicon;
                    
    $serverdata['ping'] = $ping;
     
                } else {
     
                    
    $start microtime(true);
     
                    
    socket_send($socket"\xFE\x01"20);
                    
    $length socket_recv($socket$data5120);
     
                    
    $ping round((microtime(true)-$start)*1000);//calculate the high five duration
                   
                    
    if($length || $data[0] != "\xFF") {
                        return 
    false;
                    }
     
                    
    $motd "";
                    
    $motdraw "";
     
                    
    //Evaluate the received data
                    
    if (substr((String)$data35) == "\x00\xa7\x00\x31\x00"){
     
                        
    $result explode("\x00"mb_convert_encoding(substr((String)$data15), 'UTF-8''UCS-2'));
                        
    $motd $result[1];
                        
    $motdraw $motd;
     
                    } else {
     
                        
    $result explode('§'mb_convert_encoding(substr((String)$data3), 'UTF-8''UCS-2'));
                            foreach (
    $result as $key => $string) {
                                if(
    $key != sizeof($result)-&& $key != sizeof($result)-&& $key != 0) {
                                    
    $motd .= '§'.$string;
                                }
                            }
                            
    $motdraw $motd;
                        }
     
                        
    $motd preg_replace("/(§.)/"""$motd);
                        
    $motd preg_replace("/[^[:alnum:][:punct:] ]/"""$motd); //Remove all special characters from a string
     
                        
    $serverdata['version'] = $result[0];
                        
    $serverdata['players'] = $result[sizeof($result)-2];
                        
    $serverdata['maxplayers'] = $result[sizeof($result)-1];
                        
    $serverdata['motd'] = $motd;
                        
    $serverdata['motd_raw'] = $motdraw;
                        
    $serverdata['ping'] = $ping;
     
                }
     
                
    $this->disconnect($socket);
     
                return 
    $serverdata;
     
            }
     
            private function 
    connect($host$port) {
                
    $socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
                
    socket_connect($socket$host$port);
                return 
    $socket;
            }
     
            private function 
    disconnect($socket) {
                if(
    $socket != null) {
                    
    socket_close($socket);
                }
            }
     
            private function 
    read_packet_length($socket) {
                
    $a 0;
                
    $b 0;
                while(
    true) {
                    
    $c socket_read($socket1);
                    if(!
    $c) {
                        return 
    0;
                    }
                    
    $c Ord($c);
                    
    $a |= ($c 0x7F) << $b++ * 7;
                    if( 
    $b ) {
                        return 
    false;
                    }
                    if((
    $c 0x80) != 128) {
                        break;
                    }
                }
                return 
    $a;
            }
     
        }
    The files on the Web server is as follows:
    [-] webpage
    -example.php
    -status.class.php
    -index.php

    Is there something I'm missing? I do not see anything that the script requires jquery, but only that the query is true in the "server.properties" and it is. Is the query's ip in the "server.properties" important?

    Thanks for your help!
     
  6. Offline

    Zlimon

    I have tried to include status.class.php, but it did not work for me, I did also got a blank page. But when I include the code from status.class.php into example.php it works.

    This is probably the correct code for you in the example.php I guess:
    HTML:
    <html>
    <head>
    <title>Minecraft server</title>
    </head>
    <body>
     
    <?php
     
        include_once 'status.class.php'; //include the class
        $status = new MinecraftServerStatus(); // call the class
        $response = $status-> getStatus('37.59.252.113', 25889); // when you dont have the default port
    if(!$response) {
        echo"The Server is offline!";
    } else {
        echo"<img width=\"64\" height=\"64\" src=\"".$response['favicon']."\" /> <br>
        The Server ".$response['hostname']." is running on ".$response['version']." and is online,
        currently are ".$response['players']." players online
        of a maximum of ".$response['maxplayers'].". The motd of the server is '".$response['motd']."'.
        The server has a ping of ".$response['ping']." milliseconds.";
    }
     
    ?>
     
    <?php
     
        /**
        * Minecraft Server Status Query
        * @author Julian Spravil <julian.spr@t-online.de> https://github.com/FunnyItsElmo
        * @license Free to use but dont remove the author, license and copyright
        * [USER=90879835]Copyright[/USER] © 2013 Julian Spravil
        */
        class MinecraftServerStatus {
     
            private $timeout;
     
            public function __construct($timeout = 2) {
                $this->timeout = $timeout;
            }
     
            public function getStatus($host = '127.0.0.1', $version = '1.7.*' , $port = 25565) {
     
                if (substr_count($host , '.') != 4) $host = gethostbyname($host);
     
                $serverdata = array();
                $serverdata['hostname'] = $host;
                $serverdata['version'] = false;
                $serverdata['protocol'] = false;
                $serverdata['players'] = false;
                $serverdata['maxplayers'] = false;
                $serverdata['motd'] = false;
                $serverdata['motd_raw'] = false;
                $serverdata['favicon'] = false;
                $serverdata['ping'] = false;
     
                $socket = $this->connect($host, $port);
     
                if(!$socket) {
                    return false;
                }
     
                if(preg_match('/1.7|1.8/',$version)) {
     
                    $start = microtime(true);
     
                    $handshake = pack('cccca*', hexdec(strlen($host)), 0, 0x04, strlen($host), $host).pack('nc', $port, 0x01);
     
                    socket_send($socket, $handshake, strlen($handshake), 0); //give the server a high five
                    socket_send($socket, "\x01\x00", 2, 0);
                    socket_read( $socket, 1 );
     
                    $ping = round((microtime(true)-$start)*1000); //calculate the high five duration
     
                    $packetlength = $this->read_packet_length($socket);
     
                    if($packetlength < 10) {
                        return false;
                    }
     
                    socket_read($socket, 1);
     
                    $packetlength = $this->read_packet_length($socket);
     
                    $data = socket_read($socket, $packetlength, PHP_NORMAL_READ);
     
                    if(!$data) {
                        return false;
                    }
     
                    $data = json_decode($data);
     
                    $serverdata['version'] = $data->version->name;
                    $serverdata['protocol'] = $data->version->protocol;
                    $serverdata['players'] = $data->players->online;
                    $serverdata['maxplayers'] = $data->players->max;
     
                    $motd = $data->description;
                    $motd = preg_replace("/(§.)/", "",$motd);
                    $motd = preg_replace("/[^[:alnum:][:punct:] ]/", "", $motd);
     
                    $serverdata['motd'] = $motd;
                    $serverdata['motd_raw'] = $data->description;
                    $serverdata['favicon'] = $data->favicon;
                    $serverdata['ping'] = $ping;
     
                } else {
     
                    $start = microtime(true);
     
                    socket_send($socket, "\xFE\x01", 2, 0);
                    $length = socket_recv($socket, $data, 512, 0);
     
                    $ping = round((microtime(true)-$start)*1000);//calculate the high five duration
             
                    if($length < 4 || $data[0] != "\xFF") {
                        return false;
                    }
     
                    $motd = "";
                    $motdraw = "";
     
                    //Evaluate the received data
                    if (substr((String)$data, 3, 5) == "\x00\xa7\x00\x31\x00"){
     
                        $result = explode("\x00", mb_convert_encoding(substr((String)$data, 15), 'UTF-8', 'UCS-2'));
                        $motd = $result[1];
                        $motdraw = $motd;
     
                    } else {
     
                        $result = explode('§', mb_convert_encoding(substr((String)$data, 3), 'UTF-8', 'UCS-2'));
                            foreach ($result as $key => $string) {
                                if($key != sizeof($result)-1 && $key != sizeof($result)-2 && $key != 0) {
                                    $motd .= '§'.$string;
                                }
                            }
                            $motdraw = $motd;
                        }
     
                        $motd = preg_replace("/(§.)/", "", $motd);
                        $motd = preg_replace("/[^[:alnum:][:punct:] ]/", "", $motd); //Remove all special characters from a string
     
                        $serverdata['version'] = $result[0];
                        $serverdata['players'] = $result[sizeof($result)-2];
                        $serverdata['maxplayers'] = $result[sizeof($result)-1];
                        $serverdata['motd'] = $motd;
                        $serverdata['motd_raw'] = $motdraw;
                        $serverdata['ping'] = $ping;
     
                }
     
                $this->disconnect($socket);
     
                return $serverdata;
     
            }
     
            private function connect($host, $port) {
                $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                socket_connect($socket, $host, $port);
                return $socket;
            }
     
            private function disconnect($socket) {
                if($socket != null) {
                    socket_close($socket);
                }
            }
     
            private function read_packet_length($socket) {
                $a = 0;
                $b = 0;
                while(true) {
                    $c = socket_read($socket, 1);
                    if(!$c) {
                        return 0;
                    }
                    $c = Ord($c);
                    $a |= ($c & 0x7F) << $b++ * 7;
                    if( $b > 5 ) {
                        return false;
                    }
                    if(($c & 0x80) != 128) {
                        break;
                    }
                }
                return $a;
            }
     
        }
    ?>
    </body>
    </html>
    Solved my problem :) For some reason I had to write my port (25565) with the IP...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Dec 19, 2015
  7. Offline

    MartyRot

    Zlimon
    Tried the code you put together, and tried to move it so that status.class came on top but still I get blank page. Wonder if "include_once" must be replaced with something else to read the class files? Also attempted change the ip by typing the port behind the ip (100.10.1.2:12345) but still blank page :/
     
  8. Offline

    trianmarc

  9. Offline

    Zlimon

    Nice :)
    Maybe Joomla has something to do with it...
    I could not find any solution to this, but I found another query that I use on my website.
     
  10. Offline

    metrakit



    Hi,

    I answer a bit late but I have solved the small problem of the socket error.

    So you can see my fork here : https://github.com/Metrakit/PHP-Min...master/MinecraftServerStatus/status.class.php

    We should check if the connexion is okay before continue the script...


    Cordially, Metrakit.
     
  11. Offline

    DefaultSyntax

    I know nothing about this, but how would install this onto your website?
     
  12. Offline

    SPGEARClub

    Awesome work FunnyItsElmo!
    But does anyone know how to adjust the general ping timeout? I'm not a pro in PHP, and I saw
    PHP:
    public function __construct($timeout 2) {
                
    $this->timeout $timeout;
            }
    ...but changing the value gives no luck. Any ideas? Any help appreciated!


    I found a somewhat cheap fix for anyone else who wants to know. I simply used fsockopen in an if statement, setting the timeout manually:

    PHP:
    <?php
    $server 
    "minecraft.example.com"//The server ip
    $port 25565//The port (only adjects the fsockopen port, not the actual server data ping)
    $waitTimeoutInSeconds 1//Self-explanitory, the timeout in seconds. Just don't set it to 0
    if($fp = @fsockopen($server,$port,$errCode,$errStr,$waitTimeoutInSeconds)){
        
    //Where the familiar code begins
        
    include_once 'MinecraftServerStatus/status.class.php'//Or whatever your relative directory is
        
    $status = new MinecraftServerStatus();
        
    $response $status->getStatus($server);
        if(!
    $response) {
            echo 
    "The Server is offline!";
        } else {
            echo 
    "<b>Icon:</b> <img width=\"64\" height=\"64\" src=\"".$response['favicon']."\" /> <br>
            <b>Server:</b> "
    .$server."<br>
            <b>Server IP:</b> "
    .$response['hostname']."<br>
            <b>Version:</b> "
    .$response['version']."<br>
            <b>Online</b> @"
    .$response['players']."/".$response['maxplayers']."<br>
            <b>MOTD:</b> "
    .$response['motd']."<br>
            <b>Ping:</b> "
    .$response['ping']." milliseconds <br>
            "
    //My variables were set up a little different
        
    }
    }else{
        echo 
    "The Server is offline!";
    }
    @
    fclose($fp);
    ?>
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Dec 19, 2015
  13. Offline

    HamsterLV

    getting theese errors..
    [​IMG]
    it is not a free web host and the server is online +query port is correct.
    [​IMG]

    SOLVED!! if you use version '1.6.*' it works with 1.7 and you dont need to put query port, but server port
     
  14. Offline

    Phumix

    While using this, I figured it needs an update. Simply, when this script can't ping your server. It will either show up an error or load slow.
    Here is the error it gave me,
    Code:
    PHP Warning:  socket_connect(): unable to connect [110]: Connection timed out in /home/flachoc1/public_html/api/MinecraftServerStatus/status.class.php on line 136
    PHP Warning:  socket_send(): unable to write to socket [32]: Broken pipe in /home/flachoc1/public_html/api/MinecraftServerStatus/status.class.php on line 86
    PHP Warning:  socket_recv(): unable to read from socket [107]: Transport endpoint is not connected in /home/flachoc1/public_html/api/MinecraftServerStatus/status.class.php on line 87
    It was working when it was possible to ping my server, but when my host was doing maintenace. They shut down their network and it started showing up the error. It was saying offline when I turned the server off manually. But as I said, it's not working when it cannot ping the server (I assume). I guess it needs some fixes?
     
  15. Offline

    Gletschernadel

    Hi, thank you for this script. :)

    But one question:
    Is it possible to get the map currently played on with the query?
     
  16. Offline

    JWhy

    The new query protocol isn't sending the default map anymore
     
  17. Offline

    Gletschernadel

    Oh, ok.
    Thank you.
     
  18. Offline

    manuelgu

    Does not work for me :( If I want to open the example.php I get this error: [​IMG]I hope someone can help me, I didnt change anything in the status.class.php
     
  19. Offline

    JWhy

    You'll have to enable the PHP sockets extension in your webserver configuration. If you don't host the web server yourself you might have to consult your hoster.
     
  20. Offline

    drax98

    How to use this class for more than 1 server on 1 ip. I have different ports but it doesn't work
     
  21. Offline

    mona

    I have an issue with minecraft server connection. I have minecraft server installed on local machin. and sending a vote through the php code from server live website , but I can't receive vote. also if I do that on local website its working very well. what should I do? please help me
     
  22. Offline

    JWhy

    mona: Your hosting environment may disallow socket_create(), check that.
     
  23. Offline

    peleus

    Is disallow socket_create() set to yes upon installation?
     
  24. Offline

    ThLoser

    Hello people, im using this script to get some information from a minecraft server.. I added some code to show playernames aswell.. But i only get 12 names even if its more than 20 on the server i always only get 12.

    This is the code im at right now:
    PHP:
    print_r($data->players);
    If you use this code and look for sample, you see an array with 12 slots in it.

    How come this is happening? What am i doing wrong?
     
  25. Offline

    weirdGuy

    Does anyone added this to packagist? Good code, but with composer and namespaces will be much better :D
     
  26. Offline

    bernivic135

    How can I integrate this in html?
     
  27. Offline

    FunnyItsElmo

    Check out the latest update :)
     
Thread Status:
Not open for further replies.

Share This Page