Vice City: Multiplayer

VC:MP Discussion => General Discussion => Topic started by: EK.IceFlake on Apr 22, 2017, 12:16 PM

Title: Server not replying to query
Post by: EK.IceFlake on Apr 22, 2017, 12:16 PM
I requested some information from a server:
<?phpconst 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($client, 1);        //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 >> 8 & 0xFF);  //Port byte 1                $message   .= "i";                     //Opcode information        fwrite($client, $message);        //Receive information        $header = fread($client, 42);                if (strlen($header) < 42) return;        $magic    = substr($header, 0, 4);       //Magic        $ip       = "";                          //IP        $ip      .= ord(substr($header, 4, 1));  //IP byte 0        $ip      .= ".";                         //IP byte seperator        $ip      .= ord(substr($header, 5, 1));  //IP byte 1        $ip      .= ".";                         //IP byte seperator        $ip      .= ord(substr($header, 6, 1));  //IP byte 2        $ip      .= ".";                         //IP byte seperator        $ip      .= ord(substr($header, 7, 1));  //IP byte 3        $port_1   = ord(substr($header, 8, 1));  //Port byte 0        $port_2   = ord(substr($header, 9, 1));  //Port byte 1                $opcode   = substr(10, 1);    }}$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?
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 22, 2017, 12:47 PM
Solved by changing the magic from 'MP04' to 'VCMP'.
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 22, 2017, 04:04 PM
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($client, 2);        if (strlen($_max_players) < 2) return;        $max_players    = 0;        $max_players   += ord(substr($_max_players, 0, 1));        $max_players   += ord(substr($_max_players, 1, 1)) << 8;
However, this, which uses the same logic, doesn't:
<?php //for syntax highlighting, not present in actual code        $_name_len        = fread($client, 4);        if (strlen($_name_len) < 4) return;        $name_len    = 0;        $name_len   += ord(substr($_name_len, 0, 1));        $name_len   += ord(substr($_name_len, 1, 1)) << 8;        $name_len   += ord(substr($_name_len, 2, 1)) << 16;        $name_len   += ord(substr($_name_len, 3, 1)) << 24;
How should I deal with this?
Title: Re: Server not replying to query
Post by: KAKAN on Apr 22, 2017, 04:32 PM
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 :)
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 22, 2017, 05:47 PM
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.
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 22, 2017, 05:57 PM
Solved, I forgot to read the player count.
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 22, 2017, 06:01 PM
Here is the class if anyone wants to experiment with it:
<?phpclass 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($client, 1);        //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 >> 8 & 0xFF);  //Port byte 1                $message   .= "i";                           //Opcode 'information'        fwrite($client, $message);        //Receive information        //Header        $header = fread($client, 11);        if (strlen($header) < 11) return;        $magic            = substr($header, 0, 4);           //Magic        $server_ip      = "";                                //IP        $server_ip     .= ord(substr($header, 4, 1));        //IP byte 0        $server_ip     .= ".";                               //IP byte seperator        $server_ip     .= ord(substr($header, 5, 1));        //IP byte 1        $server_ip     .= ".";                               //IP byte seperator        $server_ip     .= ord(substr($header, 6, 1));        //IP byte 2        $server_ip     .= ".";                               //IP byte seperator        $server_ip     .= ord(substr($header, 7, 1));        //IP byte 3        $server_port    = 0;        $server_port    += ord(substr($header, 8, 1));       //Port byte 0        $server_port    += ord(substr($header, 9, 1)) << 8;  //Port byte 1                $opcode         = substr($header, 10, 1);        //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($client, 12);        if (strlen($_version) < 12) return;        $version = str_replace("\0", "", $_version);        //Password        $_passworded        = fread($client, 1);        if (strlen($_passworded) < 1) return;                $passworded = ord($_passworded) == 1;        //Players        $_players     = fread($client, 2);        if (strlen($_players) < 2) return;        $players    = 0;        $players   += ord(substr($_players, 0, 1));        $players   += ord(substr($_players, 1, 1)) << 8;        //Max players        $_max_players     = fread($client, 2);        if (strlen($_max_players) < 2) return;        $max_players    = 0;        $max_players   += ord(substr($_max_players, 0, 1));        $max_players   += ord(substr($_max_players, 1, 1)) << 8;                //Server name        $_name_len        = fread($client, 4);        if (strlen($_name_len) < 4) return;        $name_len    = 0;        $name_len   += ord(substr($_name_len, 0, 1));        $name_len   += ord(substr($_name_len, 1, 1)) << 8;        $name_len   += ord(substr($_name_len, 2, 1)) << 16;        $name_len   += ord(substr($_name_len, 3, 1)) << 24;                $name             = fread($client, $name_len);        if (strlen($name) < $name_len) return;        //Gamemode        $_gamemode_len    = fread($client, 4);        if (strlen($_gamemode_len) < 4) return;        $gamemode_len    = 0;        $gamemode_len   += ord(substr($_gamemode_len, 0, 1));        $gamemode_len   += ord(substr($_gamemode_len, 1, 1)) << 8;        $gamemode_len   += ord(substr($_gamemode_len, 2, 1)) << 16;        $gamemode_len   += ord(substr($_gamemode_len, 3, 1)) << 24;        $gamemode         = fread($client, $gamemode_len);        if (strlen($gamemode) < $gamemode_len) return;        //Map namespace        $_map_len         = fread($client, 4);        if (strlen($_map_len) < 4) return;        $map_len          = 0;        $map_len   += ord(substr($_map_len, 0, 1));        $map_len   += ord(substr($_map_len, 1, 1)) << 8;        $map_len   += ord(substr($_map_len, 2, 1)) << 16;        $map_len   += ord(substr($_map_len, 3, 1)) << 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);
Title: Re: Server not replying to query
Post by: KAKAN on Apr 23, 2017, 05:05 AM
http://pastie.org/9501000
??
:edit: That website seems off. So, this: https://pastebin.com/jkj8RWZL
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 23, 2017, 05:34 AM
Quote from: KAKAN on Apr 23, 2017, 05:05 AMThat website seems off.
One of the reasons I had to write my own...
Title: Re: Server not replying to query
Post by: 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 :)
Title: Re: Server not replying to query
Post by: EK.IceFlake on Apr 23, 2017, 07:51 AM
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...