Advertisement
Lordkire

m2mpquery.php

Jun 13th, 2012
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.96 KB | None | 0 0
  1. <?php
  2.  
  3. /*------------------------------------------------------------
  4. | M2MP Query Script
  5. |------------------------------------------------------------
  6. | This class enables you to connect to a M2MP server
  7. | and get info about it.
  8. |------------------------------------------------------------
  9. | Author: Lordkire
  10. ------------------------------------------------------------*/
  11.  
  12. class M2MPServer {
  13.    
  14.     private $ip, $port, $timeout, $retries, $maxretries, $socket, $connected;
  15.    
  16.     public function __construct($ip, $port = 27016, $timeout = 2, $retries = 1) {
  17.         $this->ip = $ip;
  18.         $this->port = $port;
  19.         $this->timeout = $timeout;
  20.         $this->retries = 0;
  21.         $this->maxretries = $retries;
  22.        
  23.         $this->socket = @fsockopen('udp://' . $this->ip, $this->port, $errno, $errstr, $this->timeout);
  24.         socket_set_timeout($this->socket, $this->timeout);
  25.        
  26.         if (!$this->socket) {
  27.             $this->connected = false;
  28.             return;
  29.         }
  30.        
  31.         if ($this->sendPacket('p')) {
  32.             $this->connected = true;
  33.             return;
  34.         }
  35.         else {
  36.             $this->connected = false;
  37.         }
  38.     }
  39.    
  40.     private function sendPacket($opcode) {
  41.         fwrite($this->socket, 'M2MP' . $opcode);
  42.         $packet = fread($this->socket, 1024);
  43.         if (!$packet) {
  44.             if ($this->retries < $this->maxretries) {
  45.                 $this->retries += 1;
  46.                 return $this->sendPacket($opcode);
  47.             }
  48.             else {
  49.                 $this->retries = 0;
  50.                 return false;
  51.             }
  52.         }
  53.         else {
  54.             $this->retries = 0;
  55.             $packet = rtrim($packet, "\x00");
  56.             return $packet;
  57.         }
  58.     }
  59.    
  60.     // This function is used to get the IP address and (query) port number of the server.
  61.     // Returns an array with:
  62.     // - index 0: IP addres (str)
  63.     // - index 1: Query port (int)
  64.     public function getAddress() {
  65.         return array($this->ip, $this->port);
  66.     }
  67.    
  68.     // This function is used to check if the script is connected to the server.
  69.     // It is best to check this first before using the other functions (saves time-out time).
  70.     // Returns true if connected, false if not connected.
  71.     public function isConnected() {
  72.         return $this->connected;
  73.     }
  74.    
  75.     // This function is used to get the ping from the webserver that runs the script to the M2MP server.
  76.     // Returns the ping (int) if the query succeeded, and false if it failed.
  77.     public function getPing() {
  78.         $startTime = microtime();
  79.         fwrite($this->socket, 'M2MPp');
  80.         $packet = fread($this->socket, 1024);
  81.         $stopTime = microtime();
  82.         if (!$packet) {
  83.             if ($this->retries < $this->maxretries) {
  84.                 $this->retries += 1;
  85.                 return $this->getPing();
  86.             }
  87.             else {
  88.                 $this->retries = 0;
  89.                 return false;
  90.             }
  91.         }
  92.         else {
  93.             $this->retries = 0;
  94.             return ceil(($stopTime - $startTime) * 1000);
  95.         }
  96.     }
  97.    
  98.     // This function is used to get basic info about the server.
  99.     // The function returns an array with the following keys if the query succeeded:
  100.     // - 'hostname': name of the server (str)
  101.     // - 'players': number of players in the server (int)
  102.     // - 'maxplayers': maximum number of players (int)
  103.     // - 'gamemode': name of the gamemode (str)
  104.     // - 'passworded': wether the server requires a password (bool)
  105.     // - 'mapname': name of the map (str)
  106.     // - 'version': server version (str)
  107.     // - 'weburl': web URL as specified in the server's config (str)
  108.     // - 'httpport' : httpport as specified in the server's config (str)
  109.     // Or it returns false in case the query failed.
  110.     public function getInfo() {
  111.         $packet = $this->sendPacket('i');
  112.         if ($packet) {
  113.             $packet = explode('<info>', $packet);
  114.             $info = array(
  115.                 'hostname' => $packet[1],
  116.                 'players' => (int)$packet[2],
  117.                 'maxplayers' => (int)$packet[3],
  118.                 'gamemode' => $packet[4],
  119.                 'passworded' => (bool)$packet[5],
  120.                 'mapname' => $packet[6],
  121.                 'version' => $packet[7],
  122.                 'weburl' => $packet[8],
  123.                 'httpport' => $packet[9]);
  124.             return $info;
  125.         }
  126.         else {
  127.             return false;
  128.         }
  129.     }
  130.    
  131.     // This function is used to get the playerlist of the server.
  132.     // It returns an array with players arrays if the query succeeded, or false if the query failed.
  133.     // The player arrays have the following keys:
  134.     // - 'id': the playerid (int)
  135.     // - 'name': the player's nickname (str)
  136.     // - 'score': the player's score (int)
  137.     public function getPlayers() {
  138.         $packet = $this->sendPacket('l');
  139.         if ($packet) {
  140.             $packet = explode('<info>', $packet);
  141.             if ($packet[1] > 0) {
  142.                 $packet = explode('<player>', $packet[2]);
  143.                 foreach ($packet as $player) {
  144.                     $player = explode('<data>', $player);
  145.                     $players[] = array(
  146.                         'id' => (int)$player[0],
  147.                         'name' => $player[1],
  148.                         'score' => (int)$player[2]);
  149.                 }
  150.                 return $players;
  151.             }
  152.             else {
  153.                 return false;
  154.             }
  155.         }
  156.         else {
  157.             return false;
  158.         }
  159.     }
  160.    
  161.     // This function checks if a player with name == $name is on the server.
  162.     // It returns true if there is, and false if there isn't, or if the query failed.
  163.     public function isPlayerOnline($name) {
  164.         if ($players = $this->getPlayers()) {
  165.             foreach ($players as $player) {
  166.                 if ($player['name'] == $name) {
  167.                     return true;
  168.                 }
  169.             }
  170.             return false;
  171.         }
  172.         else {
  173.             return false;
  174.         }
  175.     }
  176.    
  177.     // This static function returns an array of M2MPServer objects based on the master list.
  178.     // If the master list could not be found, it returns false.
  179.     public static function getMasterList($url = 'http://www.m2-multiplayer.com/master/list.php') {
  180.         $data = file_get_contents($url);
  181.         if ($data) {
  182.             $data = explode('<br />', $data);
  183.             unset($data[count($data) - 1]);
  184.             foreach ($data as $server) {
  185.                 $server = explode(':', $server);
  186.                 $servers[] = new M2MPServer($server[0], $server[1] + 1);
  187.             }
  188.             return $servers;
  189.         }
  190.         else {
  191.             return false;
  192.         }
  193.     }
  194.    
  195.     // This static function returns an array with info about the master list, with the following keys:
  196.     // - 'players': the total number of players online (int)
  197.     // - 'maxplayers': the total number of player slots (int)
  198.     // - 'servers': the nummber of servers online (int)
  199.     // Or it returns false in case the master list could not be found.
  200.     public static function getMasterInfo($url = 'http://www.m2-multiplayer.com/master/list.php') {
  201.         if ($servers = self::getMasterList($url)) {
  202.             $masterInfo = array(
  203.                 'players' => 0,
  204.                 'maxplayers' => 0,
  205.                 'servers' => 0);
  206.             foreach ($servers as $server) {
  207.                 if ($server->isConnected() && ($info = $server->getInfo())) {
  208.                     $masterInfo['players'] += $info['players'];
  209.                     $masterInfo['maxplayers'] += $info['maxplayers'];
  210.                     $masterInfo['servers'] += 1;
  211.                 }
  212.             }
  213.             return $masterInfo;
  214.         }
  215.         else {
  216.             return false;
  217.         }
  218.     }
  219.    
  220.     public function __destruct() {
  221.         @fclose($this->socket);
  222.     }
  223.    
  224. }
  225.    
  226. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement