Server not replying to query

Started by EK.IceFlake, Apr 22, 2017, 12:16 PM

Previous topic - Next topic

EK.IceFlake

I requested some information from a server:
<?php

const cloudwards_servers = ["178.32.116.43"];

const 
masterlist "http&#58;//master.vc-mp.org/servers/";

class 
Server
{
    public 
$ip             "0.0.0.0";
    public 
$port           0;

    public 
$version        "Unknown";
    public 
$passworded     false;
    public 
$players        0;
    public 
$max_players    0;

    public 
$success        false;


    public function 
__construct($ip$port)
    {
        
//Create stream

        
$ip_array explode("."$ip);
        
array_map("intval"$ip_array);

        
$client stream_socket_client("udp&#58;//{$ip}:{$port}");

        
stream_set_timeout($client1);

        
//Send request

        
if ($client === false) return;

        
$message    "";

        
$message   .= "MP04";                  //Magic

        
$message   .= chr($ip_array[0]);       //IP byte 0
        
$message   .= chr($ip_array[1]);       //IP byte 1
        
$message   .= chr($ip_array[2]);       //IP byte 2
        
$message   .= chr($ip_array[3]);       //IP byte 3
        
        
$message   .= chr($port 0xFF);       //Port byte 0
        
$message   .= chr($port >> 0xFF);  //Port byte 1
        
        
$message   .= "i";                     //Opcode information

        
fwrite($client$message);

        
//Receive information

        
$header fread($client42);
        
        if (
strlen($header) < 42) return;

        
$magic    substr($header04);       //Magic

        
$ip       "";                          //IP
        
$ip      .= ord(substr($header41));  //IP byte 0
        
$ip      .= ".";                         //IP byte seperator
        
$ip      .= ord(substr($header51));  //IP byte 1
        
$ip      .= ".";                         //IP byte seperator
        
$ip      .= ord(substr($header61));  //IP byte 2
        
$ip      .= ".";                         //IP byte seperator
        
$ip      .= ord(substr($header71));  //IP byte 3

        
$port_1   ord(substr($header81));  //Port byte 0
        
$port_2   ord(substr($header91));  //Port byte 1
        
        
$opcode   substr(101);
    }
}

$server = new Server("46.105.184.128""8194");
And it doesn't feel like replying for some reason, since strlen($header) returns 0.

What am I doing wrong here?

EK.IceFlake

Solved by changing the magic from 'MP04' to 'VCMP'.

EK.IceFlake

Okay, new problem.
I can't convert some lengths into integers.
This works fine:
<?php //for syntax highlighting, not present in actual code
        
$_max_players     fread($client2);
        if (
strlen($_max_players) < 2) return;

        
$max_players    0;
        
$max_players   += ord(substr($_max_players01));
        
$max_players   += ord(substr($_max_players11)) << 8;
However, this, which uses the same logic, doesn't:
<?php //for syntax highlighting, not present in actual code
        
$_name_len        fread($client4);
        if (
strlen($_name_len) < 4) return;

        
$name_len    0;
        
$name_len   += ord(substr($_name_len01));
        
$name_len   += ord(substr($_name_len11)) << 8;
        
$name_len   += ord(substr($_name_len21)) << 16;
        
$name_len   += ord(substr($_name_len31)) << 24;
How should I deal with this?

KAKAN

Its so good that I had added to my fav list in Github:
https://github.com/Rhytz/LU-WebSDK
Use an existing library. That will make your work easier. You can view the code and see how it does those things :)
oh no

EK.IceFlake

Quote from: KAKAN on Apr 22, 2017, 04:32 PMIts so good that I had added to my fav list in Github:
https://github.com/Rhytz/LU-WebSDK
Use an existing library. That will make your work easier. You can view the code and see how it does those things :)
This uses a custom SDK which doesn't have to deal with those things and instead passes data directly as a JSON string.
However, I can't force a script into every server to query it.

EK.IceFlake

Solved, I forgot to read the player count.

EK.IceFlake

#6
Here is the class if anyone wants to experiment with it:
<?php
class Server
{
    public 
$ip             "0.0.0.0";
    public 
$port           0;

    public 
$name           "Unknown";
    public 
$version        "Unknown";
    public 
$passworded     false;
    public 
$players        0;
    public 
$max_players    0;
    public 
$map            "Unknown";

    public 
$success        false;


    public function 
__construct($ip$port)
    {
        
//Set IP and port

        
$this->ip $ip;
        
$this->port $port;

        
//Load

        
$this->Refresh();
    }

    public function 
Refresh()
    {
        
$this->success false;

        
//Create stream

        
$ip_array explode("."$this->ip);
        
array_map("intval"$ip_array);

        
$client stream_socket_client("udp&#58;//{$this->ip}:{$this->port}");

        
stream_set_timeout($client1);

        
//Send request

        
if ($client === false) return;

        
$message    "";

        
$message   .= "VCMP";                        //Magic

        
$message   .= chr($ip_array[0]);             //IP byte 0
        
$message   .= chr($ip_array[1]);             //IP byte 1
        
$message   .= chr($ip_array[2]);             //IP byte 2
        
$message   .= chr($ip_array[3]);             //IP byte 3
        
        
$message   .= chr($this->port 0xFF);       //Port byte 0
        
$message   .= chr($this->port >> 0xFF);  //Port byte 1
        
        
$message   .= "i";                           //Opcode 'information'

        
fwrite($client$message);

        
//Receive information

        //Header

        
$header fread($client11);
        if (
strlen($header) < 11) return;

        
$magic            substr($header04);           //Magic

        
$server_ip      "";                                //IP
        
$server_ip     .= ord(substr($header41));        //IP byte 0
        
$server_ip     .= ".";                               //IP byte seperator
        
$server_ip     .= ord(substr($header51));        //IP byte 1
        
$server_ip     .= ".";                               //IP byte seperator
        
$server_ip     .= ord(substr($header61));        //IP byte 2
        
$server_ip     .= ".";                               //IP byte seperator
        
$server_ip     .= ord(substr($header71));        //IP byte 3

        
$server_port    0;
        
$server_port    += ord(substr($header81));       //Port byte 0
        
$server_port    += ord(substr($header91)) << 8;  //Port byte 1
        
        
$opcode         substr($header101);

        
//Authencity checks

        
if ($magic != "MP04") return;
        if (
$server_ip != $this->ip) return;
        if (
$server_port != $this->port) return;
        if (
$opcode != "i") return;

        
//Version

        
$_version         fread($client12);
        if (
strlen($_version) < 12) return;

        
$version str_replace("\0"""$_version);

        
//Password

        
$_passworded        fread($client1);
        if (
strlen($_passworded) < 1) return;
        
        
$passworded ord($_passworded) == 1;

        
//Players

        
$_players     fread($client2);
        if (
strlen($_players) < 2) return;

        
$players    0;
        
$players   += ord(substr($_players01));
        
$players   += ord(substr($_players11)) << 8;

        
//Max players

        
$_max_players     fread($client2);
        if (
strlen($_max_players) < 2) return;

        
$max_players    0;
        
$max_players   += ord(substr($_max_players01));
        
$max_players   += ord(substr($_max_players11)) << 8;
        
        
//Server name

        
$_name_len        fread($client4);
        if (
strlen($_name_len) < 4) return;

        
$name_len    0;
        
$name_len   += ord(substr($_name_len01));
        
$name_len   += ord(substr($_name_len11)) << 8;
        
$name_len   += ord(substr($_name_len21)) << 16;
        
$name_len   += ord(substr($_name_len31)) << 24;
        
        
$name             fread($client$name_len);
        if (
strlen($name) < $name_len) return;

        
//Gamemode

        
$_gamemode_len    fread($client4);
        if (
strlen($_gamemode_len) < 4) return;

        
$gamemode_len    0;
        
$gamemode_len   += ord(substr($_gamemode_len01));
        
$gamemode_len   += ord(substr($_gamemode_len11)) << 8;
        
$gamemode_len   += ord(substr($_gamemode_len21)) << 16;
        
$gamemode_len   += ord(substr($_gamemode_len31)) << 24;

        
$gamemode         fread($client$gamemode_len);
        if (
strlen($gamemode) < $gamemode_len) return;

        
//Map namespace

        
$_map_len         fread($client4);
        if (
strlen($_map_len) < 4) return;

        
$map_len          0;
        
$map_len   += ord(substr($_map_len01));
        
$map_len   += ord(substr($_map_len11)) << 8;
        
$map_len   += ord(substr($_map_len21)) << 16;
        
$map_len   += ord(substr($_map_len31)) << 24;

        
$map              fread($client$map_len);
        if (
strlen($map) < $map_len) return;

        
//We know everything now

        
fclose($client);

        
//Load it

        
$this->name          $name;
        
$this->version       $version;
        
$this->passworded    $passworded;
        
$this->players       $players;
        
$this->max_players   $max_players;
        
$this->map           $map;
    
        
$this->success       true;
    }
}

Usage:
<?php
$server 
= new Server("127.0.0.1"8192);

KAKAN

#7
http://pastie.org/9501000
??
:edit: That website seems off. So, this: https://pastebin.com/jkj8RWZL
oh no

EK.IceFlake

Quote from: KAKAN on Apr 23, 2017, 05:05 AMThat website seems off.
One of the reasons I had to write my own...

KAKAN

Quote from: EK.IceFlake on Apr 23, 2017, 05:34 AMOne of the reasons I had to write my own...
https://pastebin.com/jkj8RWZL
https://pastebin.com/jkj8RWZL
https://pastebin.com/jkj8RWZL
https://pastebin.com/jkj8RWZL
Couldn't you see that? I've never seen pastebin go off someday. IIRC, I've seen another VCMP Query'ng PHP script.

Instead of wasting 2 days on your PHP script, you could've just searched. 2 days work done in 1 minute :)
oh no

EK.IceFlake

Quote from: KAKAN on Apr 23, 2017, 07:18 AM
Quote from: EK.IceFlake on Apr 23, 2017, 05:34 AMOne of the reasons I had to write my own...
https://pastebin.com/jkj8RWZL
https://pastebin.com/jkj8RWZL
https://pastebin.com/jkj8RWZL
https://pastebin.com/jkj8RWZL
Couldn't you see that? I've never seen pastebin go off someday. IIRC, I've seen another VCMP Query'ng PHP script.

Instead of wasting 2 days on your PHP script, you could've just searched. 2 days work done in 1 minute :)
I searched for it and couldn't find it...