mirror of
https://github.com/xPaw/PHP-Source-Query.git
synced 2026-06-08 01:46:00 +02:00
Improve socket mocking
This commit is contained in:
@@ -35,4 +35,93 @@
|
|||||||
abstract public function Open( $Ip, $Port, $Timeout, $Engine );
|
abstract public function Open( $Ip, $Port, $Timeout, $Engine );
|
||||||
abstract public function Write( $Header, $String = '' );
|
abstract public function Write( $Header, $String = '' );
|
||||||
abstract public function Read( $Length = 1400 );
|
abstract public function Read( $Length = 1400 );
|
||||||
|
|
||||||
|
protected function ReadInternal( $Buffer, $SherlockFunction )
|
||||||
|
{
|
||||||
|
if( $Buffer->Remaining( ) === 0 )
|
||||||
|
{
|
||||||
|
throw new InvalidPacketException( 'Failed to read any data from socket', InvalidPacketException::BUFFER_EMPTY );
|
||||||
|
}
|
||||||
|
|
||||||
|
$Header = $Buffer->GetLong( );
|
||||||
|
|
||||||
|
if( $Header === -1 ) // Single packet
|
||||||
|
{
|
||||||
|
// We don't have to do anything
|
||||||
|
}
|
||||||
|
else if( $Header === -2 ) // Split packet
|
||||||
|
{
|
||||||
|
$Packets = [];
|
||||||
|
$IsCompressed = false;
|
||||||
|
$ReadMore = false;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$RequestID = $Buffer->GetLong( );
|
||||||
|
|
||||||
|
switch( $this->Engine )
|
||||||
|
{
|
||||||
|
case SourceQuery::GOLDSOURCE:
|
||||||
|
{
|
||||||
|
$PacketCountAndNumber = $Buffer->GetByte( );
|
||||||
|
$PacketCount = $PacketCountAndNumber & 0xF;
|
||||||
|
$PacketNumber = $PacketCountAndNumber >> 4;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SourceQuery::SOURCE:
|
||||||
|
{
|
||||||
|
$IsCompressed = ( $RequestID & 0x80000000 ) !== 0;
|
||||||
|
$PacketCount = $Buffer->GetByte( );
|
||||||
|
$PacketNumber = $Buffer->GetByte( ) + 1;
|
||||||
|
|
||||||
|
if( $IsCompressed )
|
||||||
|
{
|
||||||
|
$Buffer->GetLong( ); // Split size
|
||||||
|
|
||||||
|
$PacketChecksum = $Buffer->GetUnsignedLong( );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$Buffer->GetShort( ); // Split size
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$Packets[ $PacketNumber ] = $Buffer->Get( );
|
||||||
|
|
||||||
|
$ReadMore = $PacketCount > sizeof( $Packets );
|
||||||
|
}
|
||||||
|
while( $ReadMore && $SherlockFunction( $Buffer, $Length ) );
|
||||||
|
|
||||||
|
$Data = Implode( $Packets );
|
||||||
|
|
||||||
|
// TODO: Test this
|
||||||
|
if( $IsCompressed )
|
||||||
|
{
|
||||||
|
// Let's make sure this function exists, it's not included in PHP by default
|
||||||
|
if( !Function_Exists( 'bzdecompress' ) )
|
||||||
|
{
|
||||||
|
throw new \RuntimeException( 'Received compressed packet, PHP doesn\'t have Bzip2 library installed, can\'t decompress.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$Data = bzdecompress( $Data );
|
||||||
|
|
||||||
|
if( CRC32( $Data ) !== $PacketChecksum )
|
||||||
|
{
|
||||||
|
throw new InvalidPacketException( 'CRC32 checksum mismatch of uncompressed packet data.', InvalidPacketException::CHECKSUM_MISMATCH );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$Buffer->Set( SubStr( $Data, 4 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidPacketException( 'Socket read: Raw packet header mismatch. (0x' . DecHex( $Header ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-83
@@ -73,89 +73,7 @@
|
|||||||
$Buffer = new Buffer( );
|
$Buffer = new Buffer( );
|
||||||
$Buffer->Set( FRead( $this->Socket, $Length ) );
|
$Buffer->Set( FRead( $this->Socket, $Length ) );
|
||||||
|
|
||||||
if( $Buffer->Remaining( ) === 0 )
|
$this->ReadInternal( $Buffer, $this->Sherlock );
|
||||||
{
|
|
||||||
throw new InvalidPacketException( 'Failed to read any data from socket', InvalidPacketException::BUFFER_EMPTY );
|
|
||||||
}
|
|
||||||
|
|
||||||
$Header = $Buffer->GetLong( );
|
|
||||||
|
|
||||||
if( $Header === -1 ) // Single packet
|
|
||||||
{
|
|
||||||
// We don't have to do anything
|
|
||||||
}
|
|
||||||
else if( $Header === -2 ) // Split packet
|
|
||||||
{
|
|
||||||
$Packets = [];
|
|
||||||
$IsCompressed = false;
|
|
||||||
$ReadMore = false;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
$RequestID = $Buffer->GetLong( );
|
|
||||||
|
|
||||||
switch( $this->Engine )
|
|
||||||
{
|
|
||||||
case SourceQuery::GOLDSOURCE:
|
|
||||||
{
|
|
||||||
$PacketCountAndNumber = $Buffer->GetByte( );
|
|
||||||
$PacketCount = $PacketCountAndNumber & 0xF;
|
|
||||||
$PacketNumber = $PacketCountAndNumber >> 4;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SourceQuery::SOURCE:
|
|
||||||
{
|
|
||||||
$IsCompressed = ( $RequestID & 0x80000000 ) !== 0;
|
|
||||||
$PacketCount = $Buffer->GetByte( );
|
|
||||||
$PacketNumber = $Buffer->GetByte( ) + 1;
|
|
||||||
|
|
||||||
if( $IsCompressed )
|
|
||||||
{
|
|
||||||
$Buffer->GetLong( ); // Split size
|
|
||||||
|
|
||||||
$PacketChecksum = $Buffer->GetUnsignedLong( );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$Buffer->GetShort( ); // Split size
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$Packets[ $PacketNumber ] = $Buffer->Get( );
|
|
||||||
|
|
||||||
$ReadMore = $PacketCount > sizeof( $Packets );
|
|
||||||
}
|
|
||||||
while( $ReadMore && $this->Sherlock( $Buffer, $Length ) );
|
|
||||||
|
|
||||||
$Data = Implode( $Packets );
|
|
||||||
|
|
||||||
// TODO: Test this
|
|
||||||
if( $IsCompressed )
|
|
||||||
{
|
|
||||||
// Let's make sure this function exists, it's not included in PHP by default
|
|
||||||
if( !Function_Exists( 'bzdecompress' ) )
|
|
||||||
{
|
|
||||||
throw new \RuntimeException( 'Received compressed packet, PHP doesn\'t have Bzip2 library installed, can\'t decompress.' );
|
|
||||||
}
|
|
||||||
|
|
||||||
$Data = bzdecompress( $Data );
|
|
||||||
|
|
||||||
if( CRC32( $Data ) !== $PacketChecksum )
|
|
||||||
{
|
|
||||||
throw new InvalidPacketException( 'CRC32 checksum mismatch of uncompressed packet data.', InvalidPacketException::CHECKSUM_MISMATCH );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$Buffer->Set( SubStr( $Data, 4 ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidPacketException( 'Socket read: Raw packet header mismatch. (0x' . DecHex( $Header ) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $Buffer;
|
return $Buffer;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user