Proposal for better Exceptions

pull/40/head
Michael Yoo 10 years ago
parent 6d3355f01f
commit cfcd43111c
No known key found for this signature in database
GPG Key ID: 409DBB63E3750CCD

@ -1,12 +0,0 @@
<?php
/**
* Class written by xPaw
*
* Website: http://xpaw.me
* GitHub: https://github.com/xPaw/PHP-Source-Query-Class
*/
class SourceQueryException extends Exception
{
// Exception thrown by SourceQuery class
}

@ -0,0 +1,43 @@
<?php
/**
* Class written by xPaw
*
* Website: http://xpaw.me
* GitHub: https://github.com/xPaw/PHP-Source-Query-Class
*/
namespace xPaw\SourceQuery\Exception;
abstract class SourceQueryException extends \Exception
{
}
class InvalidArgumentException extends SourceQueryException
{
const TIMEOUT_NOT_INTEGER = 1;
}
class TimeoutException extends SourceQueryException
{
const TIMEOUT_CONNECT = 1;
}
class InvalidPacketException extends SourceQueryException
{
const PACKET_HEADER_MISMATCH = 1;
const BUFFER_NOT_EMPTY = 2;
const CHECKSUM_MISMATCH = 3;
}
class AuthenticationException extends SourceQueryException
{
const BAD_PASSWORD = 1;
const BANNED = 2;
}
class SocketException extends SourceQueryException
{
const COULD_NOT_CREATE_SOCKET = 1;
}

@ -5,6 +5,8 @@
* Website: http://xpaw.me * Website: http://xpaw.me
* GitHub: https://github.com/xPaw/PHP-Source-Query-Class * GitHub: https://github.com/xPaw/PHP-Source-Query-Class
*/ */
use xPaw\SourceQuery\Exception\AuthenticationException;
class SourceQueryGoldSourceRcon class SourceQueryGoldSourceRcon
{ {
@ -51,7 +53,11 @@
return $Length === FWrite( $this->Socket->Socket, $Command, $Length ); return $Length === FWrite( $this->Socket->Socket, $Command, $Length );
} }
/**
* @param int $Length
* @throws AuthenticationException
*/
public function Read( $Length = 1400 ) public function Read( $Length = 1400 )
{ {
// GoldSource RCON has same structure as Query // GoldSource RCON has same structure as Query
@ -65,10 +71,13 @@
$Buffer = $this->Buffer->Get( ); $Buffer = $this->Buffer->Get( );
$Trimmed = Trim( $Buffer ); $Trimmed = Trim( $Buffer );
if( $Trimmed === 'Bad rcon_password.' if($Trimmed === 'Bad rcon_password.')
|| $Trimmed === 'You have been banned from this server.' ) {
throw new AuthenticationException($Trimmed, AuthenticationException::BAD_PASSWORD);
}
else if($Trimmed === 'You have been banned from this server.')
{ {
throw new SourceQueryException( $Trimmed ); throw new AuthenticationException($Trimmed, AuthenticationException::BANNED);
} }
$ReadMore = false; $ReadMore = false;

@ -1,5 +1,8 @@
<?php <?php
/** use xPaw\SourceQuery\Exception\InvalidPacketException;
use xPaw\SourceQuery\Exception\SocketException;
/**
* Class written by xPaw * Class written by xPaw
* *
* Website: http://xpaw.me * Website: http://xpaw.me
@ -48,7 +51,7 @@
if( $ErrNo || $this->Socket === false ) if( $ErrNo || $this->Socket === false )
{ {
throw new Exception( 'Could not create socket: ' . $ErrStr ); throw new SocketException( 'Could not create socket: ' . $ErrStr, SocketException::COULD_NOT_CREATE_SOCKET);
} }
Stream_Set_Timeout( $this->Socket, $Timeout ); Stream_Set_Timeout( $this->Socket, $Timeout );
@ -143,7 +146,7 @@
if( CRC32( $Buffer ) !== $PacketChecksum ) if( CRC32( $Buffer ) !== $PacketChecksum )
{ {
throw new SourceQueryException( 'CRC32 checksum mismatch of uncompressed packet data.' ); throw new InvalidPacketException( 'CRC32 checksum mismatch of uncompressed packet data.', InvalidPacketException::CHECKSUM_MISMATCH);
} }
} }
@ -151,7 +154,7 @@
} }
else else
{ {
throw new SourceQueryException( 'Socket read: Raw packet header mismatch. (0x' . DecHex( $Header ) . ')' ); throw new InvalidPacketException( 'Socket read: Raw packet header mismatch. (0x' . DecHex( $Header ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH);
} }
} }

@ -14,12 +14,16 @@
define( '__DIR__', dirname( __FILE__ ) ); define( '__DIR__', dirname( __FILE__ ) );
} }
require __DIR__ . '/Exception.class.php'; require __DIR__ . '/Exceptions.class.php';
require __DIR__ . '/Buffer.class.php'; require __DIR__ . '/Buffer.class.php';
require __DIR__ . '/Socket.class.php'; require __DIR__ . '/Socket.class.php';
require __DIR__ . '/SourceRcon.class.php'; require __DIR__ . '/SourceRcon.class.php';
require __DIR__ . '/GoldSourceRcon.class.php'; require __DIR__ . '/GoldSourceRcon.class.php';
use xPaw\SourceQuery\Exception\InvalidArgumentException;
use xPaw\SourceQuery\Exception\TimeoutException;
use xPaw\SourceQuery\Exception\InvalidPacketException;
class SourceQuery class SourceQuery
{ {
/** /**
@ -121,7 +125,7 @@
{ {
$this->Disconnect( ); $this->Disconnect( );
} }
/** /**
* Opens connection to server * Opens connection to server
* *
@ -130,8 +134,8 @@
* @param int $Timeout Timeout period * @param int $Timeout Timeout period
* @param int $Engine Engine the server runs on (goldsource, source) * @param int $Engine Engine the server runs on (goldsource, source)
* *
* @throws SourceQueryException * @throws InvalidArgumentException
* @throws InvalidArgumentException If timeout is not an integer * @throws TimeoutException
*/ */
public function Connect( $Ip, $Port, $Timeout = 3, $Engine = self :: SOURCE ) public function Connect( $Ip, $Port, $Timeout = 3, $Engine = self :: SOURCE )
{ {
@ -139,12 +143,12 @@
if( !is_int( $Timeout ) || $Timeout < 0 ) if( !is_int( $Timeout ) || $Timeout < 0 )
{ {
throw new InvalidArgumentException( 'Timeout must be an integer.' ); throw new InvalidArgumentException("Timeout must be an integer.", InvalidArgumentException::TIMEOUT_NOT_INTEGER);
} }
if( !$this->Socket->Open( $Ip, (int)$Port, $Timeout, (int)$Engine ) ) if( !$this->Socket->Open( $Ip, (int)$Port, $Timeout, (int)$Engine ) )
{ {
throw new SourceQueryException( 'Can\'t connect to the server.' ); throw new TimeoutException("Could not connect to server.", TimeoutException::TIMEOUT_CONNECT);
} }
$this->Connected = true; $this->Connected = true;
@ -208,7 +212,7 @@
/** /**
* Get server information * Get server information
* *
* @throws SourceQueryException * @throws InvalidPacketException
* *
* @return bool|array Returns array with information on success, false on failure * @return bool|array Returns array with information on success, false on failure
*/ */
@ -275,7 +279,7 @@
if( $Type !== self :: S2A_INFO ) if( $Type !== self :: S2A_INFO )
{ {
throw new SourceQueryException( 'GetInfo: Packet header mismatch. (0x' . DecHex( $Type ) . ')' ); throw new InvalidPacketException("GetInfo: Packet header mismatch. (0x' . DecHex( $Type ) . ')", InvalidPacketException::PACKET_HEADER_MISMATCH);
} }
$Server[ 'Protocol' ] = $this->Buffer->GetByte( ); $Server[ 'Protocol' ] = $this->Buffer->GetByte( );
@ -340,7 +344,8 @@
if( $this->Buffer->Remaining( ) > 0 ) if( $this->Buffer->Remaining( ) > 0 )
{ {
throw new SourceQueryException( 'GetInfo: unread data? ' . $this->Buffer->Remaining( ) . ' bytes remaining in the buffer. Please report it to the library developer.' ); throw new InvalidPacketException("GetInfo: unread data? " . $this->Buffer->Remaining( ) . " bytes remaining in the buffer. Please report it to the library developer.",
InvalidPacketException::BUFFER_NOT_EMPTY);
} }
} }
@ -350,7 +355,7 @@
/** /**
* Get players on the server * Get players on the server
* *
* @throws SourceQueryException * @throws InvalidPacketException
* *
* @return bool|array Returns array with players on success, false on failure * @return bool|array Returns array with players on success, false on failure
*/ */
@ -381,7 +386,7 @@
} }
else if( $Type !== self :: S2A_PLAYER ) else if( $Type !== self :: S2A_PLAYER )
{ {
throw new SourceQueryException( 'GetPlayers: Packet header mismatch. (0x' . DecHex( $Type ) . ')' ); throw new InvalidPacketException( 'GetPlayers: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH);
} }
break; break;
@ -408,7 +413,7 @@
/** /**
* Get rules (cvars) from the server * Get rules (cvars) from the server
* *
* @throws SourceQueryException * @throws InvalidPacketException
* *
* @return bool|array Returns array with rules on success, false on failure * @return bool|array Returns array with rules on success, false on failure
*/ */
@ -438,7 +443,7 @@
} }
else if( $Type !== self :: S2A_RULES ) else if( $Type !== self :: S2A_RULES )
{ {
throw new SourceQueryException( 'GetRules: Packet header mismatch. (0x' . DecHex( $Type ) . ')' ); throw new InvalidPacketException( 'GetRules: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH);
} }
break; break;
@ -461,10 +466,13 @@
return $Rules; return $Rules;
} }
/** /**
* Get challenge (used for players/rules packets) * Get challenge (used for players/rules packets)
* *
* @param $Header
* @param $ExpectedResult
* @throws InvalidPacketException
* @return bool True if all went well, false if server uses old GoldSource protocol, and it already contains answer * @return bool True if all went well, false if server uses old GoldSource protocol, and it already contains answer
*/ */
private function GetChallenge( $Header, $ExpectedResult ) private function GetChallenge( $Header, $ExpectedResult )
@ -504,7 +512,7 @@
} }
default: default:
{ {
throw new SourceQueryException( 'GetChallenge: Packet header mismatch. (0x' . DecHex( $Type ) . ')' ); throw new InvalidPacketException( 'GetChallenge: Packet header mismatch. (0x' . DecHex( $Type ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH);
} }
} }
} }

@ -1,5 +1,8 @@
<?php <?php
/** use xPaw\SourceQuery\Exception\AuthenticationException;
use xPaw\SourceQuery\Exception\TimeoutException;
/**
* Class written by xPaw * Class written by xPaw
* *
* Website: http://xpaw.me * Website: http://xpaw.me
@ -51,7 +54,7 @@
if( $ErrNo || !$this->RconSocket ) if( $ErrNo || !$this->RconSocket )
{ {
throw new SourceQueryException( 'Can\'t connect to RCON server: ' . $ErrStr ); throw new TimeoutException( 'Can\'t connect to RCON server: ' . $ErrStr, TimeoutException::TIMEOUT_CONNECT);
} }
Stream_Set_Timeout( $this->RconSocket, $this->Socket->Timeout ); Stream_Set_Timeout( $this->RconSocket, $this->Socket->Timeout );
@ -103,7 +106,7 @@
if( $Type === SourceQuery :: SERVERDATA_AUTH_RESPONSE ) if( $Type === SourceQuery :: SERVERDATA_AUTH_RESPONSE )
{ {
throw new SourceQueryException( 'Bad rcon_password.' ); throw new AuthenticationException( 'Bad rcon_password.', AuthenticationException::BAD_PASSWORD);
} }
else if( $Type !== SourceQuery :: SERVERDATA_RESPONSE_VALUE ) else if( $Type !== SourceQuery :: SERVERDATA_RESPONSE_VALUE )
{ {
@ -160,7 +163,7 @@
if( $RequestID === -1 || $Type !== SourceQuery :: SERVERDATA_AUTH_RESPONSE ) if( $RequestID === -1 || $Type !== SourceQuery :: SERVERDATA_AUTH_RESPONSE )
{ {
throw new SourceQueryException( 'RCON authorization failed.' ); throw new AuthenticationException( 'RCON authorization failed.', AuthenticationException::BAD_PASSWORD);
} }
return true; return true;

Loading…
Cancel
Save