За последние 24 часа нас посетили 103726 программистов и 5636 роботов. Сейчас ищут 2866 программистов ...

получение информации.

Тема в разделе "PHP для новичков", создана пользователем 715kg, 29 июл 2013.

  1. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    Здравствуйте, получаю информацию с такой функции.

    Код (Text):
    1. <?php
    2. class MinecraftQueryException extends Exception
    3. {
    4.    // Exception thrown by MinecraftQuery class
    5. }
    6.  
    7. class MinecraftQuery
    8. {
    9.    /*
    10.     * Class written by xPaw
    11.     *
    12.     * Website: http://xpaw.ru
    13.     * GitHub: https://github.com/xPaw/PHP-Minecraft-Query
    14.     */
    15.  
    16.    const STATISTIC = 0x00;
    17.    const HANDSHAKE = 0x09;
    18.  
    19.    private $Socket;
    20.    private $Players;
    21.    private $Info;
    22.  
    23.    public function Connect( $Ip, $Port = 25565, $Timeout = 3 )
    24.    {
    25.       if( !is_int( $Timeout ) || $Timeout < 0 )
    26.       {
    27.          throw new InvalidArgumentException( 'Timeout must be an integer.' );
    28.       }
    29.  
    30.       $this->Socket = @FSockOpen( 'udp://' . $Ip, (int)$Port, $ErrNo, $ErrStr, $Timeout );
    31.  
    32.       if( $ErrNo || $this->Socket === false )
    33.       {
    34.          throw new MinecraftQueryException( 'Could not create socket: ' . $ErrStr );
    35.       }
    36.  
    37.       Stream_Set_Timeout( $this->Socket, $Timeout );
    38.       Stream_Set_Blocking( $this->Socket, true );
    39.  
    40.       try
    41.       {
    42.          $Challenge = $this->GetChallenge( );
    43.  
    44.          $this->GetStatus( $Challenge );
    45.       }
    46.       // We catch this because we want to close the socket, not very elegant
    47.       catch( MinecraftQueryException $e )
    48.       {
    49.          FClose( $this->Socket );
    50.  
    51.          throw new MinecraftQueryException( $e->getMessage( ) );
    52.       }
    53.  
    54.       FClose( $this->Socket );
    55.    }
    56.  
    57.    public function GetInfo( )
    58.    {
    59.       return isset( $this->Info ) ? $this->Info : false;
    60.    }
    61.  
    62.    public function GetPlayers( )
    63.    {
    64.       return isset( $this->Players ) ? $this->Players : false;
    65.    }
    66.  
    67.    private function GetChallenge( )
    68.    {
    69.       $Data = $this->WriteData( self :: HANDSHAKE );
    70.  
    71.       if( $Data === false )
    72.       {
    73.          throw new MinecraftQueryException( "Failed to receive challenge." );
    74.       }
    75.  
    76.       return Pack( 'N', $Data );
    77.    }
    78.  
    79.    private function GetStatus( $Challenge )
    80.    {
    81.       $Data = $this->WriteData( self :: STATISTIC, $Challenge . Pack( 'c*', 0x00, 0x00, 0x00, 0x00 ) );
    82.  
    83.       if( !$Data )
    84.       {
    85.          throw new MinecraftQueryException( "Failed to receive status." );
    86.       }
    87.  
    88.       $Last = "";
    89.       $Info = Array( );
    90.  
    91.       $Data    = SubStr( $Data, 11 ); // splitnum + 2 int
    92.       $Data    = Explode( "\x00\x00\x01player_\x00\x00", $Data );
    93.       $Players = SubStr( $Data[ 1 ], 0, -2 );
    94.       $Data    = Explode( "\x00", $Data[ 0 ] );
    95.  
    96.       // Array with known keys in order to validate the result
    97.       // It can happen that server sends custom strings containing bad things (who can know!)
    98.       $Keys = Array(
    99.          'hostname'   => 'HostName',
    100.          'gametype'   => 'GameType',
    101.          'version'    => 'Version',
    102.          'plugins'    => 'Plugins',
    103.          'map'        => 'Map',
    104.          'numplayers' => 'Players',
    105.          'maxplayers' => 'MaxPlayers',
    106.          'hostport'   => 'HostPort',
    107.          'hostip'     => 'HostIp'
    108.       );
    109.  
    110.       foreach( $Data as $Key => $Value )
    111.       {
    112.          if( ~$Key & 1 )
    113.          {
    114.             if( !Array_Key_Exists( $Value, $Keys ) )
    115.             {
    116.                $Last = false;
    117.                continue;
    118.             }
    119.  
    120.             $Last = $Keys[ $Value ];
    121.             $Info[ $Last ] = "";
    122.          }
    123.          else if( $Last != false )
    124.          {
    125.             $Info[ $Last ] = $Value;
    126.          }
    127.       }
    128.  
    129.       // Ints
    130.       $Info[ 'Players' ]    = IntVal( $Info[ 'Players' ] );
    131.       $Info[ 'MaxPlayers' ] = IntVal( $Info[ 'MaxPlayers' ] );
    132.       $Info[ 'HostPort' ]   = IntVal( $Info[ 'HostPort' ] );
    133.  
    134.       // Parse "plugins", if any
    135.       if( $Info[ 'Plugins' ] )
    136.       {
    137.          $Data = Explode( ": ", $Info[ 'Plugins' ], 2 );
    138.  
    139.          $Info[ 'RawPlugins' ] = $Info[ 'Plugins' ];
    140.          $Info[ 'Software' ]   = $Data[ 0 ];
    141.  
    142.          if( Count( $Data ) == 2 )
    143.          {
    144.             $Info[ 'Plugins' ] = Explode( "; ", $Data[ 1 ] );
    145.          }
    146.       }
    147.       else
    148.       {
    149.          $Info[ 'Software' ] = 'Vanilla';
    150.       }
    151.  
    152.       $this->Info = $Info;
    153.  
    154.       if( $Players )
    155.       {
    156.          $this->Players = Explode( "\x00", $Players );
    157.       }
    158.    }
    159.  
    160.    private function WriteData( $Command, $Append = "" )
    161.    {
    162.       $Command = Pack( 'c*', 0xFE, 0xFD, $Command, 0x01, 0x02, 0x03, 0x04 ) . $Append;
    163.       $Length  = StrLen( $Command );
    164.  
    165.       if( $Length !== FWrite( $this->Socket, $Command, $Length ) )
    166.       {
    167.          throw new MinecraftQueryException( "Failed to write on socket." );
    168.       }
    169.  
    170.       $Data = FRead( $this->Socket, 2048 );
    171.  
    172.       if( $Data === false )
    173.       {
    174.          throw new MinecraftQueryException( "Failed to read from socket." );
    175.       }
    176.  
    177.       if( StrLen( $Data ) < 5 || $Data[ 0 ] != $Command[ 2 ] )
    178.       {
    179.          return false;
    180.       }
    181.  
    182.       return SubStr( $Data, 5 );
    183.    }
    184. }
    185.  
    186.  
    187.  
    188.  
    189.  
    190. $obj = new MinecraftQuery();
    191. $obj->Connect('78.46.36.98',25700, 1);
    192. $serv = $obj->GetInfo('78.46.36.98',25700, 1);
    193. $serv_players = $obj->GetPlayers('78.46.36.98',25700, 1);
    194.  
    195.  
    196. $new = htmlspecialchars($serv['HostName']);
    197. echo $new.'<br>';
    198. echo $serv['Version'].'<br>';
    199. echo $serv['Plugins'].'<br>';
    200. echo $serv['GameType'].'<br>';
    201.  
    202.  
    203. $spisok = '';  
    204.  
    205.         foreach ($serv_players as $value) {                  
    206.                    $spisok .= $value.'<br>';              
    207. }  
    208. echo $spisok;
    209.  
    210.  
    211.  
    212. ?>
    Если сервер доступен, информация выводится. Если сервер недоступен,
    то вот такая вот ошибка

    Fatal error: Uncaught exception 'MinecraftQueryException' with message 'Failed to receive challenge.' in C:\CMS\www\localhost\index.php:51 Stack trace: #0 C:\CMS\www\localhost\index.php(191): MinecraftQuery->Connect('78.46.36.98', 25700, 1) #1 {main} thrown in C:\CMS\www\localhost\index.php on line 51

    Как это можно исправить? чтобы если сервер недоступен, просто бы был чистый лист. Без ошибок.

    Видимо на этой строке что то нужно сделать $obj->Connect('78.46.36.98',25700, 1);
     
  2. kosinus2012

    kosinus2012 Активный пользователь

    С нами с:
    16 июл 2012
    Сообщения:
    137
    Симпатии:
    0
    Для начала вам сюда:
    Код (Text):
    1. GitHub: https://github.com/xPaw/PHP-Minecraft-Query
    Затем, посмотрите предлагаемые примеры, вот примерно:
    Код (Text):
    1.     $obj = new MinecraftQuery();
    2.  
    3.     try
    4.     {
    5.         $obj->Connect( '78.46.36.98',25700 );
    6.  
    7.         print_r( $obj->GetInfo( ) );
    8.         print_r( $obj->GetPlayers( ) );
    9.     }
    10.     catch( MinecraftQueryException $e )
    11.     {
    12.         echo $e->getMessage( );
    13.     }
     
  3. shelestov

    shelestov Активный пользователь

    С нами с:
    25 авг 2011
    Сообщения:
    148
    Симпатии:
    0
    Адрес:
    Россия, Арзамас
  4. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    Как бы раздел для новичков, не совсем понял((
     
  5. shelestov

    shelestov Активный пользователь

    С нами с:
    25 авг 2011
    Сообщения:
    148
    Симпатии:
    0
    Адрес:
    Россия, Арзамас
    Код (Text):
    1. catch( MinecraftQueryException $e )
    2.     {
    3.         echo "НЕТ КОННЕКТА!"
    4.     }
    Отлавливает отсутствие соединения.
     
  6. 715kg

    715kg Активный пользователь

    С нами с:
    2 мар 2013
    Сообщения:
    147
    Симпатии:
    0
    То есть я так понимаю как то так.

    Код (Text):
    1.  
    2. try {
    3. $obj = new MinecraftQuery();
    4. $obj->Connect('78.46.36.98',2570, 1);
    5. $serv = $obj->GetInfo('78.46.36.98',25700, 1);
    6. } catch( MinecraftQueryException $e )
    7.     {
    8.       echo "Нет коннетка";
    9.     }