ilch Forum » Allgemein » HTML, PHP, SQL,... » Fehller im Script minecraftserverping

Geschlossen
  1. #1
    User Pic
    MonkeyOnKeyboard Moderator
    Registriert seit
    10.02.2014
    Beiträge
    438
    Beitragswertungen
    20 Beitragspunkte
    Hallöchen, ich baue gerade für jemanden an einem Minecraftserver query Modul für ilch.
    Bis jetzt läuft fast alles bis auf ein Script, welches mit bei Server offline in Fehler geht.

    <?php
    
    namespace xPaw;
    
    class MinecraftPing
    {
    	/*
    	 * Queries Minecraft server
    	 * Returns array on success, false on failure.
    	 *
    	 * WARNING: This method was added in snapshot 13w41a (Minecraft 1.7)
    	 *
    	 * Written by xPaw
    	 *
    	 * Website: http://xpaw.me
    	 * GitHub: https://github.com/xPaw/PHP-Minecraft-Query
    	 *
    	 * ---------
    	 *
    	 * This method can be used to get server-icon.png too.
    	 * Something like this:
    	 *
    	 * $Server = new MinecraftPing( 'localhost' );
    	 * $Info = $Server->Query();
    	 * echo '<img width="64" height="64" src="' . Str_Replace( "\n", "", $Info[ 'favicon' ] ) . '">';
    	 *
    	 */
    
    	private $Socket;
    	private $ServerAddress;
    	private $ServerPort;
    	private $Timeout;
    
    	public function __construct( $Address, $Port = 25565, $Timeout = 2, $ResolveSRV = true )
    	{
    		$this->ServerAddress = $Address;
    		$this->ServerPort = (int)$Port;
    		$this->Timeout = (int)$Timeout;
    
    		if( $ResolveSRV )
    		{
    			$this->ResolveSRV();
    		}
    
    		$this->Connect( );
    	}
    
    	public function __destruct( )
    	{
    		$this->Close( );
    	}
    
    	public function Close( )
    	{
    		if( $this->Socket !== null )
    		{
    			\fclose( $this->Socket );
    
    			$this->Socket = null;
    		}
    	}
    
    	public function Connect( )
    	{
    		$this->Socket = @\fsockopen( $this->ServerAddress, $this->ServerPort, $errno, $errstr, (float)$this->Timeout );
    
    		if( !$this->Socket )
    		{
    			$this->Socket = null;
    
    			throw new MinecraftPingException( "Failed to connect or create a socket: $errno ($errstr)" );
    		}
    
    		// Set Read/Write timeout
    		\stream_set_timeout( $this->Socket, $this->Timeout );
    	}
    
    	public function Query( )
    	{
    		$TimeStart = \microtime( true ); // for read timeout purposes
    
    		// See http://wiki.vg/Protocol (Status Ping)
    		$Data = "\x00"; // packet ID = 0 (varint)
    
    		$Data .= "\x04"; // Protocol version (varint)
    		$Data .= \pack( 'c', \strlen( $this->ServerAddress ) ) . $this->ServerAddress; // Server (varint len + UTF-8 addr)
    		$Data .= \pack( 'n', $this->ServerPort ); // Server port (unsigned short)
    		$Data .= "\x01"; // Next state: status (varint)
    
    		$Data = \pack( 'c', \strlen( $Data ) ) . $Data; // prepend length of packet ID + data
    
    		fwrite( $this->Socket, $Data . "\x01\x00" ); // handshake followed by status ping
    
    		$Length = $this->ReadVarInt( ); // full packet length
    
    		if( $Length < 10 )
    		{
    			return FALSE;
    		}
    
    		$this->ReadVarInt( ); // packet type, in server ping it's 0
    
    		$Length = $this->ReadVarInt( ); // string length
    
    		$Data = "";
    		while( \strlen( $Data ) < $Length )
    		{
    			if( \microtime( true ) - $TimeStart > $this->Timeout )
    			{
    				throw new MinecraftPingException( 'Server read timed out' );
    			}
    
    			$Remainder = $Length - \strlen( $Data );
    			$block = \fread( $this->Socket, $Remainder ); // and finally the json string
    			// abort if there is no progress
    			if( !$block )
    			{
    				throw new MinecraftPingException( 'Server returned too few data' );
    			}
    
    			$Data .= $block;
    		}
    
    		$Data = \json_decode( $Data, true );
    
    		if( \json_last_error( ) !== JSON_ERROR_NONE )
    		{
    			throw new MinecraftPingException( 'JSON parsing failed: ' . \json_last_error_msg( ) );
    		}
    
    		return $Data;
    	}
    
    	public function QueryOldPre17( )
    	{
    		\fwrite( $this->Socket, "\xFE\x01" );
    		$Data = \fread( $this->Socket, 512 );
    		$Len = \strlen( $Data );
    
    		if( $Len < 4 || $Data[ 0 ] !== "\xFF" )
    		{
    			return FALSE;
    		}
    
    		$Data = \substr( $Data, 3 ); // Strip packet header (kick message packet and short length)
    		$Data = \iconv( 'UTF-16BE', 'UTF-8', $Data );
    
    		// Are we dealing with Minecraft 1.4+ server?
    		if( $Data[ 1 ] === "\xA7" && $Data[ 2 ] === "\x31" )
    		{
    			$Data = \explode( "\x00", $Data );
    
    			return Array(
    				'HostName'   => $Data[ 3 ],
    				'Players'    => (int)$Data[ 4 ],
    				'MaxPlayers' => (int)$Data[ 5 ],
    				'Protocol'   => (int)$Data[ 1 ],
    				'Version'    => $Data[ 2 ]
    			);
    		}
    
    		$Data = \explode( "\xA7", $Data );
    
    		return Array(
    			'HostName'   => \substr( $Data[ 0 ], 0, -1 ),
    			'Players'    => isset( $Data[ 1 ] ) ? (int)$Data[ 1 ] : 0,
    			'MaxPlayers' => isset( $Data[ 2 ] ) ? (int)$Data[ 2 ] : 0,
    			'Protocol'   => 0,
    			'Version'    => '1.3'
    		);
    	}
    
    	private function ReadVarInt( )
    	{
    		$i = 0;
    		$j = 0;
    
    		while( true )
    		{
    			$k = @\fgetc( $this->Socket );
    
    			if( $k === FALSE )
    			{
    				return 0;
    			}
    
    			$k = \ord( $k );
    
    			$i |= ( $k & 0x7F ) << $j++ * 7;
    
    			if( $j > 5 )
    			{
    				throw new MinecraftPingException( 'VarInt too big' );
    			}
    
    			if( ( $k & 0x80 ) != 128 )
    			{
    				break;
    			}
    		}
    
    		return $i;
    	}
    
    	private function ResolveSRV()
    	{
    		if( \ip2long( $this->ServerAddress ) !== false )
    		{
    			return;
    		}
    
    		$Record = @\dns_get_record( '_minecraft._tcp.' . $this->ServerAddress, DNS_SRV );
    
    		if( empty( $Record ) )
    		{
    			return;
    		}
    
    		if( isset( $Record[ 0 ][ 'target' ] ) )
    		{
    			$this->ServerAddress = $Record[ 0 ][ 'target' ];
    		}
    
    		if( isset( $Record[ 0 ][ 'port' ] ) )
    		{
    			$this->ServerPort = $Record[ 0 ][ 'port' ];
    		}
    	}
    }


    Und zwar lese ich mit hilfe dieses Scriptes als LIB ein Queryarray aus. Das funktioniert auch soweit. solange der server nicht offline ist oder die query im minecraftserver enabled ist.

    Ich packs nicht das Script anzupassen.


    verwendete ilch Version: 2.1.x

    betroffene Homepage: localhost
    0 Mitglieder finden den Beitrag gut.
  2. #2
    User Pic
    RTX2070 Hall Of Fame
    Registriert seit
    14.06.2019
    Beiträge
    277
    Beitragswertungen
    46 Beitragspunkte
    Solange der Server nicht offline ist sagst du läuft es....wenn Offline läuft nicht??

    Versuche doch mal einen try()-Catch() Block mit exception.

    0 Mitglieder finden den Beitrag gut.
  3. #3
    User Pic
    MonkeyOnKeyboard Moderator
    Registriert seit
    10.02.2014
    Beiträge
    438
    Beitragswertungen
    20 Beitragspunkte
    Moin, an welcher stelle?

    Hast du dir mal die Datei angeschaut?
    Sorry aber ich hab keine ahnung wo an welcher stelle ich das mit try und catch machen soll
    0 Mitglieder finden den Beitrag gut.
  4. #4
    User Pic
    blackcoder Entwickler
    Registriert seit
    22.05.2014
    Beiträge
    2.310
    Beitragswertungen
    361 Beitragspunkte
    Moin,

    du rufst doch in irgendeinem Script die "Connect" und "Query"-Funktion aus der Klasse auf.

    Die "Connect" kann die Exception "MinecraftPingException("Failed to connect or create a socket: $errno ($errstr)")" werfen.
    Die "Query" kann die folgenden Exceptions werfen:
    • MinecraftPingException('Server read timed out')
    • MinecraftPingException('Server returned too few data')
    • MinecraftPingException('JSON parsing failed: ' . json_last_error_msg())


    Die "Query" kann außerdem noch deine Daten als Array oder False zurückgeben, wenn die Antwort kürzer als 10 Zeichen ist.
    "QueryOldPre17" entweder False oder deine Daten als Array.

    Also packt du deine Funktionsaufrufe in ein Try-Catch:
    try {
        // Aufruf von Connect() und Rückgabewerte auswerten.
        // Aufruf von Query() und Rückgabewerte auswerten
    } catch (MinecraftPingException $e) {
        // Auf die verschiedenen Exceptions reagieren.
        // Die verschiedenen MinecraftPingExceptions kannst du durch die "Message" oder andere Eigenschaften unterscheiden.
        echo 'Exception abgefangen: ',  $e->getMessage(), "\n";
    } finally {
        // Verbindung trennen, aufräumen, ...
    }


    Hier paar Links zur PHP-Dokumentation:
    www.php.net/manual/de/function.json-decode.php
    www.php.net/manual/de/language.exceptions.php
    www.php.net/manual/de/language.exceptions.extending.php


    Zuletzt modifiziert von blackcoder am 28.08.2023 - 17:28:24
    0 Mitglieder finden den Beitrag gut.
  5. #5
    User Pic
    MonkeyOnKeyboard Moderator
    Registriert seit
    10.02.2014
    Beiträge
    438
    Beitragswertungen
    20 Beitragspunkte
    Danke habs dann auch gefunden und super Informationen. Supi danke nochmal scheint nun zu laufen
    0 Mitglieder finden den Beitrag gut.
Geschlossen

Zurück zu HTML, PHP, SQL,...

Optionen: Bei einer Antwort zu diesem Thema eine eMail erhalten