diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..54d86a2 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,27 @@ +<?php + +declare(strict_types=1); + +return (new PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@PSR1' => true, + '@PSR12' => true, + '@PSR12:risky' => true, + '@PSR2' => true, + '@PhpCsFixer' => true, + '@PhpCsFixer:risky' => true, + '@Symfony' => true, + '@Symfony:risky' => true, + 'concat_space' => false, + 'native_constant_invocation' => false, + 'native_function_invocation' => false, + 'php_unit_fqcn_annotation' => false, + ]) + ->setFinder(PhpCsFixer\Finder::create() + ->exclude('vendor') + ->in('Examples') + ->in('SourceQuery') + ->in('Tests') + ) +; diff --git a/Examples/Example.php b/Examples/Example.php index 9ad9b85..1ce622e 100644 --- a/Examples/Example.php +++ b/Examples/Example.php @@ -4,8 +4,8 @@ declare(strict_types=1); require __DIR__ . '/../vendor/autoload.php'; -use xPaw\SourceQuery\SourceQuery; use xPaw\SourceQuery\Socket\SourceSocket; +use xPaw\SourceQuery\SourceQuery; // For the sake of this example header('Content-Type: text/plain'); diff --git a/Examples/RconExample.php b/Examples/RconExample.php index f367bbc..c07bf27 100644 --- a/Examples/RconExample.php +++ b/Examples/RconExample.php @@ -4,8 +4,8 @@ declare(strict_types=1); require __DIR__ . '/../vendor/autoload.php'; -use xPaw\SourceQuery\SourceQuery; use xPaw\SourceQuery\Socket\SourceSocket; +use xPaw\SourceQuery\SourceQuery; // For the sake of this example header('Content-Type: text/plain'); diff --git a/Examples/View.php b/Examples/View.php index bcccc40..b0f4287 100644 --- a/Examples/View.php +++ b/Examples/View.php @@ -4,8 +4,8 @@ declare(strict_types=1); require __DIR__ . '/../vendor/autoload.php'; -use xPaw\SourceQuery\SourceQuery; use xPaw\SourceQuery\Socket\SourceSocket; +use xPaw\SourceQuery\SourceQuery; $timer = microtime(true); @@ -37,28 +37,28 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); <head> <meta charset="utf-8"> <title>Source Query PHP Library</title> - + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <style> .table { table-layout: fixed; border-top-color: #428BCA; } - + .table td { overflow-x: auto; } - + .table thead th { background-color: #428BCA; border-color: #428BCA !important; color: #FFF; } - + .info-column { width: 120px; } - + .frags-column { width: 80px; } @@ -69,9 +69,9 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); <div class="jumbotron"> <div class="container"> <h1>Source Query PHP Library</h1> - + <p class="lead">This library was created to query game server which use the Source (Steamworks) query protocol.</p> - + <p> <a class="btn btn-large btn-primary" href="https://xpaw.me">Made by xPaw</a> <a class="btn btn-large btn-primary" href="https://github.com/xPaw/PHP-Source-Query">View on GitHub</a> @@ -79,13 +79,13 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); </p> </div> </div> - + <div class="container"> -<?php if ($exception !== null): ?> +<?php if (null !== $exception) { ?> <div class="panel panel-error"> <pre class="panel-body"><?php echo htmlspecialchars($exception->__toString()); ?></pre> </div> -<?php endif; ?> +<?php } ?> <div class="row"> <div class="col-sm-6"> <table class="table table-bordered table-striped"> @@ -96,18 +96,18 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); </tr> </thead> <tbody> -<?php if (!empty($info)): ?> -<?php foreach ($info as $infoKey => $infoValue): ?> +<?php if (!empty($info)) { ?> +<?php foreach ($info as $infoKey => $infoValue) { ?> <tr> <td><?php echo htmlspecialchars($infoKey); ?></td> <td><?php if (is_array($infoValue)) { - echo "<pre>"; + echo '<pre>'; print_r($infoValue); - echo "</pre>"; - } elseif ($infoValue === true) { + echo '</pre>'; + } elseif (true === $infoValue) { echo 'true'; - } elseif ($infoValue === false) { + } elseif (false === $infoValue) { echo 'false'; } elseif (is_int($infoValue)) { echo $infoValue; @@ -116,12 +116,12 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); } ?></td> </tr> -<?php endforeach; ?> -<?php else: ?> +<?php } ?> +<?php } else { ?> <tr> <td colspan="2">No information received</td> </tr> -<?php endif; ?> +<?php } ?> </tbody> </table> </div> @@ -135,19 +135,19 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); </tr> </thead> <tbody> -<?php if (!empty($players)): ?> -<?php foreach ($players as $player): ?> +<?php if (!empty($players)) { ?> +<?php foreach ($players as $player) { ?> <tr> - <td><?php echo htmlspecialchars($player[ 'Name' ]); ?></td> - <td><?php echo $player[ 'Frags' ]; ?></td> - <td><?php echo $player[ 'TimeF' ]; ?></td> + <td><?php echo htmlspecialchars($player['Name']); ?></td> + <td><?php echo $player['Frags']; ?></td> + <td><?php echo $player['TimeF']; ?></td> </tr> -<?php endforeach; ?> -<?php else: ?> +<?php } ?> +<?php } else { ?> <tr> <td colspan="3">No players received</td> </tr> -<?php endif; ?> +<?php } ?> </tbody> </table> </div> @@ -161,18 +161,18 @@ $timer = number_format(microtime(true) - $timer, 4, '.', ''); </tr> </thead> <tbody> -<?php if (!empty($rules)): ?> -<?php foreach ($rules as $ruleKey => $ruleValue): ?> +<?php if (!empty($rules)) { ?> +<?php foreach ($rules as $ruleKey => $ruleValue) { ?> <tr> <td><?php echo htmlspecialchars($ruleKey); ?></td> <td><?php echo htmlspecialchars($ruleValue); ?></td> </tr> -<?php endforeach; ?> -<?php else: ?> +<?php } ?> +<?php } else { ?> <tr> <td colspan="2">No rules received</td> </tr> -<?php endif; ?> +<?php } ?> </tbody> </table> </div> diff --git a/SourceQuery/Buffer.php b/SourceQuery/Buffer.php index a7f9744..d4a038b 100644 --- a/SourceQuery/Buffer.php +++ b/SourceQuery/Buffer.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -20,24 +20,22 @@ use xPaw\SourceQuery\Exception\InvalidPacketException; final class Buffer { /** - * Buffer + * Buffer. */ private string $buffer = ''; /** - * Buffer length + * Buffer length. */ private int $length = 0; /** - * Current position in buffer + * Current position in buffer. */ private int $position = 0; /** - * Sets buffer - * - * @param string $buffer + * Sets buffer. */ public function set(string $buffer): void { @@ -47,7 +45,7 @@ final class Buffer } /** - * Get remaining bytes + * Get remaining bytes. * * @return int Remaining bytes in buffer */ @@ -56,30 +54,25 @@ final class Buffer return $this->length - $this->position; } - /** - * @return bool - */ public function isEmpty(): bool { return $this->remaining() <= 0; } /** - * Gets data from buffer + * Gets data from buffer. * * @param int $length Bytes to read - * - * @return string */ public function get(int $length = -1): string { - if ($length === 0) { + if (0 === $length) { return ''; } $remaining = $this->remaining(); - if ($length === -1) { + if (-1 === $length) { $length = $remaining; } elseif ($length > $remaining) { return ''; @@ -93,7 +86,7 @@ final class Buffer } /** - * Get byte from buffer + * Get byte from buffer. */ public function getByte(): int { @@ -101,7 +94,7 @@ final class Buffer } /** - * Get short from buffer + * Get short from buffer. * * @throws InvalidPacketException */ @@ -121,7 +114,7 @@ final class Buffer } /** - * Get long from buffer + * Get long from buffer. * * @throws InvalidPacketException */ @@ -141,7 +134,7 @@ final class Buffer } /** - * Get float from buffer + * Get float from buffer. * * @throws InvalidPacketException */ @@ -161,7 +154,7 @@ final class Buffer } /** - * Get unsigned long from buffer + * Get unsigned long from buffer. * * @throws InvalidPacketException */ @@ -181,19 +174,19 @@ final class Buffer } /** - * Read one string from buffer ending with null byte + * Read one string from buffer ending with null byte. */ public function getString(): string { $zeroBytePosition = strpos($this->buffer, "\0", $this->position); - if ($zeroBytePosition === false) { + if (false === $zeroBytePosition) { return ''; } $string = $this->get($zeroBytePosition - $this->position); - $this->position++; + ++$this->position; return $string; } diff --git a/SourceQuery/Exception/AuthenticationException.php b/SourceQuery/Exception/AuthenticationException.php index 2dd78c9..4bb0160 100644 --- a/SourceQuery/Exception/AuthenticationException.php +++ b/SourceQuery/Exception/AuthenticationException.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * diff --git a/SourceQuery/Exception/InvalidArgumentException.php b/SourceQuery/Exception/InvalidArgumentException.php index 269b602..82642d0 100644 --- a/SourceQuery/Exception/InvalidArgumentException.php +++ b/SourceQuery/Exception/InvalidArgumentException.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * diff --git a/SourceQuery/Exception/InvalidPacketException.php b/SourceQuery/Exception/InvalidPacketException.php index 142f158..947e360 100644 --- a/SourceQuery/Exception/InvalidPacketException.php +++ b/SourceQuery/Exception/InvalidPacketException.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * diff --git a/SourceQuery/Exception/SocketException.php b/SourceQuery/Exception/SocketException.php index 99a65de..c5ab485 100644 --- a/SourceQuery/Exception/SocketException.php +++ b/SourceQuery/Exception/SocketException.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * diff --git a/SourceQuery/Exception/SourceQueryException.php b/SourceQuery/Exception/SourceQueryException.php index b936393..4ff7cab 100644 --- a/SourceQuery/Exception/SourceQueryException.php +++ b/SourceQuery/Exception/SourceQueryException.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * diff --git a/SourceQuery/Rcon/AbstractRcon.php b/SourceQuery/Rcon/AbstractRcon.php index 50367f8..8736f22 100644 --- a/SourceQuery/Rcon/AbstractRcon.php +++ b/SourceQuery/Rcon/AbstractRcon.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -24,16 +24,8 @@ abstract class AbstractRcon implements RconInterface /** * @throws AuthenticationException * @throws InvalidPacketException - * - * @return Buffer */ abstract protected function read(): Buffer; - /** - * @param int|null $header - * @param string $string - * - * @return bool - */ abstract protected function write(?int $header, string $string = ''): bool; } diff --git a/SourceQuery/Rcon/GoldSourceRcon.php b/SourceQuery/Rcon/GoldSourceRcon.php index 851fec4..b8c3bf3 100644 --- a/SourceQuery/Rcon/GoldSourceRcon.php +++ b/SourceQuery/Rcon/GoldSourceRcon.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -24,49 +24,36 @@ use xPaw\SourceQuery\SourceQuery; final class GoldSourceRcon extends AbstractRcon { /** - * Points to socket class - * - * @var SocketInterface + * Points to socket class. */ private SocketInterface $socket; - /** - * @var string - */ private string $rconPassword = ''; - /** - * @var string - */ private string $rconChallenge = ''; - /** - * @param SocketInterface $socket - */ public function __construct(SocketInterface $socket) { $this->socket = $socket; } /** - * Open + * Open. */ public function open(): void { } /** - * Close + * Close. */ public function close(): void { $this->rconChallenge = ''; - $this->rconPassword = ''; + $this->rconPassword = ''; } /** - * @param string $password - * * @throws AuthenticationException */ public function authorize(string $password): void @@ -76,7 +63,7 @@ final class GoldSourceRcon extends AbstractRcon $this->write(null, 'challenge rcon'); $buffer = $this->socket->read(); - if ($buffer->get(14) !== 'challenge rcon') { + if ('challenge rcon' !== $buffer->get(14)) { throw new AuthenticationException('Failed to get RCON challenge.', AuthenticationException::BAD_PASSWORD); } @@ -84,10 +71,6 @@ final class GoldSourceRcon extends AbstractRcon } /** - * @param string $command - * - * @return string - * * @throws AuthenticationException * @throws InvalidPacketException */ @@ -106,8 +89,6 @@ final class GoldSourceRcon extends AbstractRcon /** * @throws AuthenticationException * @throws InvalidPacketException - * - * @return Buffer */ protected function read(): Buffer { @@ -121,7 +102,7 @@ final class GoldSourceRcon extends AbstractRcon $readMore = !$buffer->isEmpty(); if ($readMore) { - if ($buffer->getByte() !== SourceQuery::S2A_RCON) { + if (SourceQuery::S2A_RCON !== $buffer->getByte()) { throw new InvalidPacketException('Invalid rcon response.', InvalidPacketException::PACKET_HEADER_MISMATCH); } @@ -140,9 +121,10 @@ final class GoldSourceRcon extends AbstractRcon $trimmed = trim($stringBuffer); - if ($trimmed === 'Bad rcon_password.') { + if ('Bad rcon_password.' === $trimmed) { throw new AuthenticationException($trimmed, AuthenticationException::BAD_PASSWORD); - } elseif ($trimmed === 'You have been banned from this server.') { + } + if ('You have been banned from this server.' === $trimmed) { throw new AuthenticationException($trimmed, AuthenticationException::BANNED); } @@ -151,12 +133,6 @@ final class GoldSourceRcon extends AbstractRcon return $buffer; } - /** - * @param int|null $header - * @param string $string - * - * @return bool - */ protected function write(?int $header, string $string = ''): bool { $command = pack('cccca*', 0xFF, 0xFF, 0xFF, 0xFF, $string); diff --git a/SourceQuery/Rcon/RconInterface.php b/SourceQuery/Rcon/RconInterface.php index 045e440..b1ccc9f 100644 --- a/SourceQuery/Rcon/RconInterface.php +++ b/SourceQuery/Rcon/RconInterface.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -21,33 +21,24 @@ use xPaw\SourceQuery\Socket\SocketInterface; interface RconInterface { - /** - * @param SocketInterface $socket - */ public function __construct(SocketInterface $socket); /** - * Open + * Open. */ public function open(): void; /** - * Close + * Close. */ public function close(): void; /** - * @param string $password - * * @throws AuthenticationException */ public function authorize(string $password): void; /** - * @param string $command - * - * @return string - * * @throws AuthenticationException * @throws InvalidPacketException */ diff --git a/SourceQuery/Rcon/SourceRcon.php b/SourceQuery/Rcon/SourceRcon.php index c2ea251..04e5444 100644 --- a/SourceQuery/Rcon/SourceRcon.php +++ b/SourceQuery/Rcon/SourceRcon.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -25,7 +25,7 @@ use xPaw\SourceQuery\SourceQuery; final class SourceRcon extends AbstractRcon { /** - * Points to socket class + * Points to socket class. */ private SocketInterface $socket; @@ -36,14 +36,8 @@ final class SourceRcon extends AbstractRcon */ private $rconSocket; - /** - * @var int - */ private int $rconRequestId = 0; - /** - * @param SocketInterface $socket - */ public function __construct(SocketInterface $socket) { $this->socket = $socket; @@ -74,7 +68,7 @@ final class SourceRcon extends AbstractRcon } /** - * Close + * Close. */ public function close(): void { @@ -88,8 +82,6 @@ final class SourceRcon extends AbstractRcon } /** - * @param string $password - * * @throws AuthenticationException * @throws InvalidPacketException */ @@ -104,23 +96,19 @@ final class SourceRcon extends AbstractRcon // If we receive SERVERDATA_RESPONSE_VALUE, then we need to read again. // More info: https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Additional_Comments - if ($type === SourceQuery::SERVERDATA_RESPONSE_VALUE) { + if (SourceQuery::SERVERDATA_RESPONSE_VALUE === $type) { $buffer = $this->read(); $requestId = $buffer->getLong(); $type = $buffer->getLong(); } - if ($requestId === -1 || $type !== SourceQuery::SERVERDATA_AUTH_RESPONSE) { + if (-1 === $requestId || SourceQuery::SERVERDATA_AUTH_RESPONSE !== $type) { throw new AuthenticationException('RCON authorization failed.', AuthenticationException::BAD_PASSWORD); } } /** - * @param string $command - * - * @return string - * * @throws AuthenticationException * @throws InvalidPacketException */ @@ -133,9 +121,10 @@ final class SourceRcon extends AbstractRcon $type = $buffer->getLong(); - if ($type === SourceQuery::SERVERDATA_AUTH_RESPONSE) { + if (SourceQuery::SERVERDATA_AUTH_RESPONSE === $type) { throw new AuthenticationException('Bad rcon_password.', AuthenticationException::BAD_PASSWORD); - } elseif ($type !== SourceQuery::SERVERDATA_RESPONSE_VALUE) { + } + if (SourceQuery::SERVERDATA_RESPONSE_VALUE !== $type) { throw new InvalidPacketException('Invalid rcon response.', InvalidPacketException::PACKET_HEADER_MISMATCH); } @@ -151,13 +140,13 @@ final class SourceRcon extends AbstractRcon $buffer->getLong(); // RequestID. - if ($buffer->getLong() !== SourceQuery::SERVERDATA_RESPONSE_VALUE) { + if (SourceQuery::SERVERDATA_RESPONSE_VALUE !== $buffer->getLong()) { break; } $data2 = $buffer->get(); - if ($data2 === "\x00\x01\x00\x00\x00\x00") { + if ("\x00\x01\x00\x00\x00\x00" === $data2) { break; } @@ -169,8 +158,6 @@ final class SourceRcon extends AbstractRcon } /** - * @return Buffer - * * @throws InvalidPacketException */ protected function read(): Buffer @@ -229,11 +216,6 @@ final class SourceRcon extends AbstractRcon } /** - * @param int|null $header - * @param string $string - * - * @return bool - * * @throws InvalidPacketException */ protected function write(?int $header, string $string = ''): bool @@ -247,7 +229,7 @@ final class SourceRcon extends AbstractRcon // Prepend packet length. $command = pack('V', strlen($command)) . $command; - $length = strlen($command); + $length = strlen($command); return $length === fwrite($this->rconSocket, $command, $length); } diff --git a/SourceQuery/Socket/AbstractSocket.php b/SourceQuery/Socket/AbstractSocket.php index 32cacca..8489ed1 100644 --- a/SourceQuery/Socket/AbstractSocket.php +++ b/SourceQuery/Socket/AbstractSocket.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -22,14 +22,8 @@ use xPaw\SourceQuery\Exception\SocketException; abstract class AbstractSocket implements SocketInterface { - /** - * @var string $address - */ public string $address = ''; - /** - * @var int $port - */ public int $port = 0; /** @@ -39,39 +33,30 @@ abstract class AbstractSocket implements SocketInterface */ public $socket; - /** - * @var int $timeout - */ public int $timeout = 0; /** - * Destructor + * Destructor. */ public function __destruct() { $this->close(); } - /** - * @return string - */ public function getAddress(): string { return $this->address; } - /** - * @return int - */ public function getPort(): int { return $this->port; } /** - * @return resource - * * @throws InvalidArgumentException + * + * @return resource */ public function getSocket() { @@ -82,30 +67,23 @@ abstract class AbstractSocket implements SocketInterface return $this->socket; } - /** - * @return int - */ public function getTimeout(): int { return $this->timeout; } /** - * @param string $address - * @param int $port - * @param int $timeout - * * @throws SocketException */ public function open(string $address, int $port, int $timeout): void { $this->timeout = $timeout; - $this->port = $port; + $this->port = $port; $this->address = $address; $socket = @fsockopen('udp://' . $address, $port, $errNo, $errStr, $timeout); - if ($errNo || $socket === false) { + if ($errNo || false === $socket) { throw new SocketException('Could not create socket: ' . $errStr, SocketException::COULD_NOT_CREATE_SOCKET); } @@ -115,7 +93,7 @@ abstract class AbstractSocket implements SocketInterface } /** - * Close + * Close. */ public function close(): void { @@ -129,13 +107,10 @@ abstract class AbstractSocket implements SocketInterface /** * Reads from socket and returns Buffer. * - * @param int $length - * - * @return Buffer Buffer - * * @throws InvalidPacketException * @throws SocketException * + * @return Buffer Buffer */ public function read(int $length = 1400): Buffer { @@ -152,17 +127,12 @@ abstract class AbstractSocket implements SocketInterface $buffer->set($data); - $this->readInternal($buffer, $length, [ $this, 'sherlock' ]); + $this->readInternal($buffer, $length, [$this, 'sherlock']); return $buffer; } /** - * @param int $header - * @param string $string - * - * @return bool - * * @throws InvalidPacketException */ public function write(int $header, string $string = ''): bool @@ -172,17 +142,12 @@ abstract class AbstractSocket implements SocketInterface } $command = pack('ccccca*', 0xFF, 0xFF, 0xFF, 0xFF, $header, $string); - $length = strlen($command); + $length = strlen($command); return $length === fwrite($this->socket, $command, $length); } /** - * @param Buffer $buffer - * @param int $length - * - * @return bool - * * @throws InvalidPacketException */ public function sherlock(Buffer $buffer, int $length): bool @@ -203,18 +168,11 @@ abstract class AbstractSocket implements SocketInterface $buffer->set($data); - return $buffer->getLong() === -2; + return -2 === $buffer->getLong(); } /** - * * Get packet data (count, number, checksum) from the buffer. Different for goldsrc/src. - * - * @param Buffer $buffer - * @param int $count - * @param int $number - * @param bool $isCompressed - * @param int|null $checksum */ abstract protected function readInternalPacketData( Buffer $buffer, @@ -225,12 +183,6 @@ abstract class AbstractSocket implements SocketInterface ): void; /** - * @param Buffer $buffer - * @param int $length - * @param callable $sherlockFunction - * - * @return Buffer - * * @throws InvalidPacketException */ protected function readInternal(Buffer $buffer, int $length, callable $sherlockFunction): Buffer @@ -242,11 +194,11 @@ abstract class AbstractSocket implements SocketInterface $header = $buffer->getLong(); // Single packet, do nothing. - if ($header === -1) { + if (-1 === $header) { return $buffer; } - if ($header === -2) { // Split packet + if (-2 === $header) { // Split packet $packets = []; $packetCount = 0; $packetNumber = 0; @@ -269,7 +221,7 @@ abstract class AbstractSocket implements SocketInterface $readMore = $packetCount > count($packets); } while ($readMore && $sherlockFunction($buffer, $length)); - $data = implode($packets); + $data = implode('', $packets); // TODO: Test this if ($isCompressed) { diff --git a/SourceQuery/Socket/GoldSourceSocket.php b/SourceQuery/Socket/GoldSourceSocket.php index 370dba7..b5475ba 100644 --- a/SourceQuery/Socket/GoldSourceSocket.php +++ b/SourceQuery/Socket/GoldSourceSocket.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -19,21 +19,11 @@ use xPaw\SourceQuery\Buffer; final class GoldSourceSocket extends AbstractSocket { - /** - * @return int - */ public function getType(): int { return SocketType::GOLDSOURCE; } - /** - * @param Buffer $buffer - * @param int $count - * @param int $number - * @param bool $isCompressed - * @param int|null $checksum - */ protected function readInternalPacketData( Buffer $buffer, int &$count, diff --git a/SourceQuery/Socket/SocketInterface.php b/SourceQuery/Socket/SocketInterface.php index 76c2406..8f1fca9 100644 --- a/SourceQuery/Socket/SocketInterface.php +++ b/SourceQuery/Socket/SocketInterface.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -18,20 +18,12 @@ namespace xPaw\SourceQuery\Socket; use xPaw\SourceQuery\Buffer; /** - * Base socket interface - * - * @package xPaw\SourceQuery\Socket + * Base socket interface. */ interface SocketInterface { - /** - * @return string - */ public function getAddress(): string; - /** - * @return int - */ public function getPort(): int; /** @@ -39,9 +31,6 @@ interface SocketInterface */ public function getSocket(); - /** - * @return int - */ public function getTimeout(): int; /** @@ -49,30 +38,14 @@ interface SocketInterface */ public function getType(): int; - /** - * @param string $address - * @param int $port - * @param int $timeout - */ public function open(string $address, int $port, int $timeout): void; /** - * Close + * Close. */ public function close(): void; - /** - * @param int $length - * - * @return Buffer - */ public function read(int $length = 1400): Buffer; - /** - * @param int $header - * @param string $string - * - * @return bool - */ public function write(int $header, string $string = ''): bool; } diff --git a/SourceQuery/Socket/SocketType.php b/SourceQuery/Socket/SocketType.php index 4e342d1..58c3bce 100644 --- a/SourceQuery/Socket/SocketType.php +++ b/SourceQuery/Socket/SocketType.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * diff --git a/SourceQuery/Socket/SourceSocket.php b/SourceQuery/Socket/SourceSocket.php index e22fa25..38824ce 100644 --- a/SourceQuery/Socket/SourceSocket.php +++ b/SourceQuery/Socket/SourceSocket.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -20,21 +20,12 @@ use xPaw\SourceQuery\Exception\InvalidPacketException; final class SourceSocket extends AbstractSocket { - /** - * @return int - */ public function getType(): int { return SocketType::SOURCE; } /** - * @param Buffer $buffer - * @param int $count - * @param int $number - * @param bool $isCompressed - * @param int|null $checksum - * * @throws InvalidPacketException */ protected function readInternalPacketData( diff --git a/SourceQuery/Socket/TestableSocket.php b/SourceQuery/Socket/TestableSocket.php index 5a9b2df..d0cc2fd 100644 --- a/SourceQuery/Socket/TestableSocket.php +++ b/SourceQuery/Socket/TestableSocket.php @@ -5,8 +5,8 @@ declare(strict_types=1); /** * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 * @@ -25,15 +25,10 @@ final class TestableSocket extends AbstractSocket */ private array $packetQueue; - /** - * @var int - */ private int $type; /** * TestableSocket constructor. - * - * @param int $type */ public function __construct(int $type) { @@ -41,31 +36,20 @@ final class TestableSocket extends AbstractSocket $this->type = $type; } - /** - * @return int - */ public function getType(): int { return $this->type; } - /** - * @param string $data - */ public function queue(string $data): void { $this->packetQueue[] = $data; } - /** - * @param string $address - * @param int $port - * @param int $timeout - */ public function open(string $address, int $port, int $timeout): void { $this->timeout = $timeout; - $this->port = $port; + $this->port = $port; $this->address = $address; } @@ -77,10 +61,6 @@ final class TestableSocket extends AbstractSocket } /** - * @param int $length - * - * @return Buffer - * * @throws InvalidPacketException */ public function read(int $length = 1400): Buffer @@ -95,48 +75,31 @@ final class TestableSocket extends AbstractSocket $buffer->set($packet); - $this->readInternal($buffer, $length, [ $this, 'sherlock' ]); + $this->readInternal($buffer, $length, [$this, 'sherlock']); return $buffer; } - /** - * @param int $header - * @param string $string - * - * @return bool - */ public function write(int $header, string $string = ''): bool { return true; } /** - * @param Buffer $buffer - * @param int $length - * - * @return bool - * * @throws InvalidPacketException */ public function sherlock(Buffer $buffer, int $length): bool { - if (count($this->packetQueue) === 0) { + if (0 === count($this->packetQueue)) { return false; } $buffer->set(array_shift($this->packetQueue)); - return $buffer->getLong() === -2; + return -2 === $buffer->getLong(); } /** - * @param Buffer $buffer - * @param int $count - * @param int $number - * @param bool $isCompressed - * @param int|null $checksum - * * @throws InvalidPacketException */ protected function readInternalPacketData( @@ -172,12 +135,6 @@ final class TestableSocket extends AbstractSocket /** * Same as GoldSourceSocket::readInternalPacketData. - * - * @param Buffer $buffer - * @param int $count - * @param int $number - * @param bool $isCompressed - * @param int|null $checksum */ private function readInternalPacketDataGoldSource( Buffer $buffer, @@ -195,12 +152,6 @@ final class TestableSocket extends AbstractSocket /** * Same as SourceSocket::readInternalPacketData. * - * @param Buffer $buffer - * @param int $count - * @param int $number - * @param bool $isCompressed - * @param int|null $checksum - * * @throws InvalidPacketException */ private function readInternalPacketDataSource( diff --git a/SourceQuery/SourceQuery.php b/SourceQuery/SourceQuery.php index 3a9120b..6a8d5c5 100644 --- a/SourceQuery/SourceQuery.php +++ b/SourceQuery/SourceQuery.php @@ -7,8 +7,8 @@ declare(strict_types=1); * * @author Pavel Djundik * - * @link https://xpaw.me - * @link https://github.com/xPaw/PHP-Source-Query + * @see https://xpaw.me + * @see https://github.com/xPaw/PHP-Source-Query * * @license GNU Lesser General Public License, version 2.1 */ @@ -29,68 +29,63 @@ use xPaw\SourceQuery\Socket\SocketType; final class SourceQuery { /** - * Packets sent + * Packets sent. */ - private const A2A_PING = 0x69; - private const A2S_INFO = 0x54; - private const A2S_PLAYER = 0x55; - private const A2S_RULES = 0x56; + private const A2A_PING = 0x69; + private const A2S_INFO = 0x54; + private const A2S_PLAYER = 0x55; + private const A2S_RULES = 0x56; private const A2S_SERVERQUERY_GETCHALLENGE = 0x57; /** - * Packets received + * Packets received. */ - private const A2A_ACK = 0x6A; + private const A2A_ACK = 0x6A; private const S2C_CHALLENGE = 0x41; - private const S2A_INFO_SRC = 0x49; - private const S2A_INFO_OLD = 0x6D; // Old GoldSource, HLTV uses it (actually called S2A_INFO_DETAILED). - private const S2A_PLAYER = 0x44; - private const S2A_RULES = 0x45; - public const S2A_RCON = 0x6C; + private const S2A_INFO_SRC = 0x49; + private const S2A_INFO_OLD = 0x6D; // Old GoldSource, HLTV uses it (actually called S2A_INFO_DETAILED). + private const S2A_PLAYER = 0x44; + private const S2A_RULES = 0x45; + public const S2A_RCON = 0x6C; /** - * Source rcon sent + * Source rcon sent. */ - public const SERVERDATA_REQUESTVALUE = 0; - public const SERVERDATA_EXECCOMMAND = 2; - public const SERVERDATA_AUTH = 3; + public const SERVERDATA_REQUESTVALUE = 0; + public const SERVERDATA_EXECCOMMAND = 2; + public const SERVERDATA_AUTH = 3; /** - * Source rcon received + * Source rcon received. */ public const SERVERDATA_RESPONSE_VALUE = 0; - public const SERVERDATA_AUTH_RESPONSE = 2; + public const SERVERDATA_AUTH_RESPONSE = 2; /** - * Points to rcon class - * - * @var RconInterface|null + * Points to rcon class. */ private ?RconInterface $rcon; /** - * Points to socket class + * Points to socket class. */ private SocketInterface $socket; /** - * True if connection is open, false if not + * True if connection is open, false if not. */ private bool $connected = false; /** - * Contains challenge + * Contains challenge. */ private string $challenge = ''; /** - * Use old method for getting challenge number + * Use old method for getting challenge number. */ private bool $useOldGetChallengeMethod = false; - /** - * @param SocketInterface $socket - */ public function __construct(SocketInterface $socket) { $this->socket = $socket; @@ -98,7 +93,7 @@ final class SourceQuery } /** - * Destructor + * Destructor. */ public function __destruct() { @@ -106,11 +101,11 @@ final class SourceQuery } /** - * Opens connection to server + * Opens connection to server. * * @param string $address Server ip - * @param int $port Server port - * @param int $timeout Timeout period + * @param int $port Server port + * @param int $timeout Timeout period * * @throws InvalidArgumentException */ @@ -128,7 +123,7 @@ final class SourceQuery } /** - * Closes all open connections + * Closes all open connections. */ public function disconnect(): void { @@ -145,7 +140,7 @@ final class SourceQuery } /** - * Forces GetChallenge to use old method for challenge retrieval because some games use outdated protocol (e.g Starbound) + * Forces GetChallenge to use old method for challenge retrieval because some games use outdated protocol (e.g Starbound). * * @param bool $value Set to true to force old method * @@ -155,14 +150,14 @@ final class SourceQuery { $previous = $this->useOldGetChallengeMethod; - $this->useOldGetChallengeMethod = $value === true; + $this->useOldGetChallengeMethod = true === $value; return $previous; } /** * Sends ping packet to the server - * NOTE: This may not work on some games (TF2 for example) + * NOTE: This may not work on some games (TF2 for example). * * @throws SocketException * @@ -177,11 +172,11 @@ final class SourceQuery $this->socket->write(self::A2A_PING); $buffer = $this->socket->read(); - return $buffer->getByte() === self::A2A_ACK; + return self::A2A_ACK === $buffer->getByte(); } /** - * Get server information + * Get server information. * * @throws InvalidPacketException * @throws SocketException @@ -204,7 +199,7 @@ final class SourceQuery $type = $buffer->getByte(); $server = []; - if ($type === self::S2C_CHALLENGE) { + if (self::S2C_CHALLENGE === $type) { $this->challenge = $buffer->get(4); $this->socket->write(self::A2S_INFO, "Source Engine Query\0" . $this->challenge); @@ -213,78 +208,78 @@ final class SourceQuery } // Old GoldSource protocol, HLTV still uses it. - if ($type === self::S2A_INFO_OLD && $this->socket->getType() === SocketType::GOLDSOURCE) { - /** + if (self::S2A_INFO_OLD === $type && SocketType::GOLDSOURCE === $this->socket->getType()) { + /* * If we try to read data again, and we get the result with type S2A_INFO (0x49) * That means this server is running dproto, * Because it sends answer for both protocols */ - $server[ 'Address' ] = $buffer->getString(); - $server[ 'HostName' ] = $buffer->getString(); - $server[ 'Map' ] = $buffer->getString(); - $server[ 'ModDir' ] = $buffer->getString(); - $server[ 'ModDesc' ] = $buffer->getString(); - $server[ 'Players' ] = $buffer->getByte(); - $server[ 'MaxPlayers' ] = $buffer->getByte(); - $server[ 'Protocol' ] = $buffer->getByte(); - $server[ 'Dedicated' ] = chr($buffer->getByte()); - $server[ 'Os' ] = chr($buffer->getByte()); - $server[ 'Password' ] = $buffer->getByte() === 1; - $server[ 'IsMod' ] = $buffer->getByte() === 1; - - if ($server[ 'IsMod' ]) { + $server['Address'] = $buffer->getString(); + $server['HostName'] = $buffer->getString(); + $server['Map'] = $buffer->getString(); + $server['ModDir'] = $buffer->getString(); + $server['ModDesc'] = $buffer->getString(); + $server['Players'] = $buffer->getByte(); + $server['MaxPlayers'] = $buffer->getByte(); + $server['Protocol'] = $buffer->getByte(); + $server['Dedicated'] = chr($buffer->getByte()); + $server['Os'] = chr($buffer->getByte()); + $server['Password'] = 1 === $buffer->getByte(); + $server['IsMod'] = 1 === $buffer->getByte(); + + if ($server['IsMod']) { $Mod = []; - $Mod[ 'Url' ] = $buffer->getString(); - $Mod[ 'Download' ] = $buffer->getString(); + $Mod['Url'] = $buffer->getString(); + $Mod['Download'] = $buffer->getString(); $buffer->get(1); // NULL byte - $Mod[ 'Version' ] = $buffer->getLong(); - $Mod[ 'Size' ] = $buffer->getLong(); - $Mod[ 'ServerSide' ] = $buffer->getByte() === 1; - $Mod[ 'CustomDLL' ] = $buffer->getByte() === 1; - $server[ 'Mod' ] = $Mod; + $Mod['Version'] = $buffer->getLong(); + $Mod['Size'] = $buffer->getLong(); + $Mod['ServerSide'] = 1 === $buffer->getByte(); + $Mod['CustomDLL'] = 1 === $buffer->getByte(); + $server['Mod'] = $Mod; } - $server[ 'Secure' ] = $buffer->getByte() === 1; - $server[ 'Bots' ] = $buffer->getByte(); + $server['Secure'] = 1 === $buffer->getByte(); + $server['Bots'] = $buffer->getByte(); return $server; } - if ($type !== self::S2A_INFO_SRC) { + if (self::S2A_INFO_SRC !== $type) { throw new InvalidPacketException('GetInfo: Packet header mismatch. (0x' . dechex($type) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH); } - $server[ 'Protocol' ] = $buffer->getByte(); - $server[ 'HostName' ] = $buffer->getString(); - $server[ 'Map' ] = $buffer->getString(); - $server[ 'ModDir' ] = $buffer->getString(); - $server[ 'ModDesc' ] = $buffer->getString(); - $server[ 'AppID' ] = $buffer->getShort(); - $server[ 'Players' ] = $buffer->getByte(); - $server[ 'MaxPlayers' ] = $buffer->getByte(); - $server[ 'Bots' ] = $buffer->getByte(); - $server[ 'Dedicated' ] = chr($buffer->getByte()); - $server[ 'Os' ] = chr($buffer->getByte()); - $server[ 'Password' ] = $buffer->getByte() === 1; - $server[ 'Secure' ] = $buffer->getByte() === 1; + $server['Protocol'] = $buffer->getByte(); + $server['HostName'] = $buffer->getString(); + $server['Map'] = $buffer->getString(); + $server['ModDir'] = $buffer->getString(); + $server['ModDesc'] = $buffer->getString(); + $server['AppID'] = $buffer->getShort(); + $server['Players'] = $buffer->getByte(); + $server['MaxPlayers'] = $buffer->getByte(); + $server['Bots'] = $buffer->getByte(); + $server['Dedicated'] = chr($buffer->getByte()); + $server['Os'] = chr($buffer->getByte()); + $server['Password'] = 1 === $buffer->getByte(); + $server['Secure'] = 1 === $buffer->getByte(); // The Ship (they violate query protocol spec by modifying the response) - if ($server[ 'AppID' ] === 2400) { - $server[ 'GameMode' ] = $buffer->getByte(); - $server[ 'WitnessCount' ] = $buffer->getByte(); - $server[ 'WitnessTime' ] = $buffer->getByte(); + if (2400 === $server['AppID']) { + $server['GameMode'] = $buffer->getByte(); + $server['WitnessCount'] = $buffer->getByte(); + $server['WitnessTime'] = $buffer->getByte(); } - $server[ 'Version' ] = $buffer->getString(); + $server['Version'] = $buffer->getString(); // Extra Data Flags. if ($buffer->remaining() > 0) { - $server[ 'ExtraDataFlags' ] = $Flags = $buffer->getByte(); + $server['ExtraDataFlags'] = $Flags = $buffer->getByte(); // S2A_EXTRA_DATA_HAS_GAME_PORT - Next 2 bytes include the game port. if ($Flags & 0x80) { - $server[ 'GamePort' ] = $buffer->getShort(); + $server['GamePort'] = $buffer->getShort(); } // S2A_EXTRA_DATA_HAS_STEAMID - Next 8 bytes are the steamID. @@ -306,32 +301,29 @@ final class SourceQuery $steamId = $steamIdLower | ($steamIdInstance << 32); } - $server[ 'SteamID' ] = $steamId; + $server['SteamID'] = $steamId; unset($steamIdLower, $steamIdInstance, $steamId); } // S2A_EXTRA_DATA_HAS_SPECTATOR_DATA - Next 2 bytes include the spectator port, then the spectator server name. if ($Flags & 0x40) { - $server[ 'SpecPort' ] = $buffer->getShort(); - $server[ 'SpecName' ] = $buffer->getString(); + $server['SpecPort'] = $buffer->getShort(); + $server['SpecName'] = $buffer->getString(); } // S2A_EXTRA_DATA_HAS_GAMETAG_DATA - Next bytes are the game tag string. if ($Flags & 0x20) { - $server[ 'GameTags' ] = $buffer->getString(); + $server['GameTags'] = $buffer->getString(); } // S2A_EXTRA_DATA_GAMEID - Next 8 bytes are the gameID of the server. if ($Flags & 0x01) { - $server[ 'GameID' ] = $buffer->getUnsignedLong() | ($buffer->getUnsignedLong() << 32); + $server['GameID'] = $buffer->getUnsignedLong() | ($buffer->getUnsignedLong() << 32); } if (!$buffer->isEmpty()) { - throw new InvalidPacketException( - 'GetInfo: unread data? ' . $buffer->remaining() . ' bytes remaining in the buffer. Please report it to the library developer.', - InvalidPacketException::BUFFER_NOT_EMPTY - ); + throw new InvalidPacketException('GetInfo: unread data? ' . $buffer->remaining() . ' bytes remaining in the buffer. Please report it to the library developer.', InvalidPacketException::BUFFER_NOT_EMPTY); } } @@ -339,7 +331,7 @@ final class SourceQuery } /** - * Get players on the server + * Get players on the server. * * @throws InvalidPacketException * @throws SocketException @@ -360,7 +352,7 @@ final class SourceQuery $type = $buffer->getByte(); - if ($type !== self::S2A_PLAYER) { + if (self::S2A_PLAYER !== $type) { throw new InvalidPacketException('GetPlayers: Packet header mismatch. (0x' . dechex($type) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH); } @@ -369,11 +361,11 @@ final class SourceQuery while ($count-- > 0 && !$buffer->isEmpty()) { $player = []; - $player[ 'Id' ] = $buffer->getByte(); // PlayerID, is it just always 0? - $player[ 'Name' ] = $buffer->getString(); - $player[ 'Frags' ] = $buffer->getLong(); - $player[ 'Time' ] = (int)$buffer->getFloat(); - $player[ 'TimeF' ] = gmdate(($player[ 'Time' ] > 3600 ? 'H:i:s' : 'i:s'), $player[ 'Time' ]); + $player['Id'] = $buffer->getByte(); // PlayerID, is it just always 0? + $player['Name'] = $buffer->getString(); + $player['Frags'] = $buffer->getLong(); + $player['Time'] = (int) $buffer->getFloat(); + $player['TimeF'] = gmdate(($player['Time'] > 3600 ? 'H:i:s' : 'i:s'), $player['Time']); $players[] = $player; } @@ -382,7 +374,7 @@ final class SourceQuery } /** - * Get rules (cvars) from the server + * Get rules (cvars) from the server. * * @throws InvalidPacketException * @throws SocketException @@ -402,7 +394,7 @@ final class SourceQuery $type = $buffer->getByte(); - if ($type !== self::S2A_RULES) { + if (self::S2A_RULES !== $type) { throw new InvalidPacketException('GetRules: Packet header mismatch. (0x' . dechex($type) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH); } @@ -422,7 +414,7 @@ final class SourceQuery } /** - * Sets rcon password, for future use in Rcon() + * Sets rcon password, for future use in Rcon(). * * @param string $password Rcon Password * @@ -438,21 +430,17 @@ final class SourceQuery switch ($this->socket->getType()) { case SocketType::GOLDSOURCE: - { $this->rcon = new GoldSourceRcon($this->socket); break; - } + case SocketType::SOURCE: - { $this->rcon = new SourceRcon($this->socket); break; - } + default: - { throw new SocketException('Unknown engine.', SocketException::INVALID_ENGINE); - } } $this->rcon->open(); @@ -464,11 +452,11 @@ final class SourceQuery * * @param string $command Command to execute * - * @return string Answer from server in string * @throws InvalidPacketException * @throws SocketException - * * @throws AuthenticationException + * + * @return string Answer from server in string */ public function rcon(string $command): string { @@ -476,7 +464,7 @@ final class SourceQuery throw new SocketException('Not connected.', SocketException::NOT_CONNECTED); } - if ($this->rcon === null) { + if (null === $this->rcon) { throw new SocketException('You must set a RCON password before trying to execute a RCON command.', SocketException::NOT_CONNECTED); } @@ -484,10 +472,7 @@ final class SourceQuery } /** - * Get challenge (used for players/rules packets) - * - * @param int $header - * @param int $expectedResult + * Get challenge (used for players/rules packets). * * @throws InvalidPacketException */ @@ -508,24 +493,18 @@ final class SourceQuery switch ($type) { case self::S2C_CHALLENGE: - { $this->challenge = $buffer->get(4); return; - } + case $expectedResult: - { // Goldsource (HLTV). return; - } + case 0: - { throw new InvalidPacketException('GetChallenge: Failed to get challenge.'); - } default: - { throw new InvalidPacketException('GetChallenge: Packet header mismatch. (0x' . dechex($type) . ')', InvalidPacketException::PACKET_HEADER_MISMATCH); - } } } } diff --git a/Tests/Tests.php b/Tests/Tests.php index ed444cc..3d414fc 100644 --- a/Tests/Tests.php +++ b/Tests/Tests.php @@ -3,30 +3,28 @@ declare(strict_types=1); use PHPUnit\Framework\TestCase; -use xPaw\SourceQuery\SourceQuery; use xPaw\SourceQuery\Exception\AuthenticationException; use xPaw\SourceQuery\Exception\InvalidArgumentException; use xPaw\SourceQuery\Exception\InvalidPacketException; use xPaw\SourceQuery\Exception\SocketException; use xPaw\SourceQuery\Socket\SocketType; use xPaw\SourceQuery\Socket\TestableSocket; +use xPaw\SourceQuery\SourceQuery; +/** + * @internal + * @coversNothing + */ final class Tests extends TestCase { - /** - * @var TestableSocket - */ private TestableSocket $socket; - /** - * @var SourceQuery - */ private SourceQuery $sourceQuery; /** * @throws InvalidArgumentException */ - public function setUp(): void + protected function setUp(): void { $this->socket = new TestableSocket(SocketType::SOURCE); $this->sourceQuery = new SourceQuery($this->socket); @@ -34,13 +32,14 @@ final class Tests extends TestCase } /** - * tearDown + * tearDown. */ - public function tearDown(): void + protected function tearDown(): void { $this->sourceQuery->disconnect(); - unset($this->socket, $this->sourceQuery); + $this->socket = null; + $this->sourceQuery = null; } /** @@ -132,9 +131,6 @@ final class Tests extends TestCase } /** - * @param string $rawInput - * @param array $expectedOutput - * * @throws InvalidArgumentException * @throws InvalidPacketException * @throws SocketException @@ -143,7 +139,7 @@ final class Tests extends TestCase */ public function testGetInfo(string $rawInput, array $expectedOutput): void { - if (isset($expectedOutput[ 'IsMod' ])) { + if (isset($expectedOutput['IsMod'])) { $this->socket = new TestableSocket(SocketType::GOLDSOURCE); $this->sourceQuery = new SourceQuery($this->socket); $this->sourceQuery->connect('', 2); @@ -153,12 +149,10 @@ final class Tests extends TestCase $realOutput = $this->sourceQuery->getInfo(); - self::assertEquals($expectedOutput, $realOutput); + static::assertSame($expectedOutput, $realOutput); } /** - * @return array - * * @throws JsonException */ public function infoProvider(): array @@ -167,8 +161,6 @@ final class Tests extends TestCase } /** - * @param string $data - * * @throws InvalidPacketException * @throws SocketException * @@ -183,8 +175,6 @@ final class Tests extends TestCase } /** - * @param string $data - * * @throws InvalidPacketException * @throws SocketException * @@ -199,8 +189,6 @@ final class Tests extends TestCase } /** - * @param string $data - * * @throws InvalidPacketException * @throws SocketException * @@ -216,8 +204,6 @@ final class Tests extends TestCase } /** - * @param string $data - * * @throws InvalidPacketException * @throws SocketException * @@ -239,13 +225,13 @@ final class Tests extends TestCase { return [ - [ '' ], - [ "\xff\xff\xff\xff" ], // No type. - [ "\xff\xff\xff\xff\x49" ], // Correct type, but no data after. - [ "\xff\xff\xff\xff\x6D" ], // Old info packet, but tests are done for source. - [ "\xff\xff\xff\xff\x11" ], // Wrong type. - [ "\x11\x11\x11\x11" ], // Wrong header. - [ "\xff" ], // Should be 4 bytes, but it's 1. + [''], + ["\xff\xff\xff\xff"], // No type. + ["\xff\xff\xff\xff\x49"], // Correct type, but no data after. + ["\xff\xff\xff\xff\x6D"], // Old info packet, but tests are done for source. + ["\xff\xff\xff\xff\x11"], // Wrong type. + ["\x11\x11\x11\x11"], // Wrong header. + ["\xff"], // Should be 4 bytes, but it's 1. ]; } @@ -257,15 +243,14 @@ final class Tests extends TestCase { $this->socket->queue("\xFF\xFF\xFF\xFF\x41\x11\x11\x11\x11"); $this->socket->queue("\xFF\xFF\xFF\xFF\x45\x01\x00ayy\x00lmao\x00"); - self::assertEquals([ 'ayy' => 'lmao' ], $this->sourceQuery->getRules()); + static::assertSame(['ayy' => 'lmao'], $this->sourceQuery->getRules()); $this->socket->queue("\xFF\xFF\xFF\xFF\x45\x01\x00wow\x00much\x00"); - self::assertEquals([ 'wow' => 'much' ], $this->sourceQuery->getRules()); + static::assertSame(['wow' => 'much'], $this->sourceQuery->getRules()); } /** * @param string[] $rawInput - * @param array $expectedOutput * * @throws InvalidPacketException * @throws SocketException @@ -294,12 +279,10 @@ final class Tests extends TestCase $realOutput = $this->sourceQuery->getRules(); - self::assertEquals($expectedOutput, $realOutput); + static::assertSame($expectedOutput, $realOutput); } /** - * @return array - * * @throws JsonException */ public function rulesProvider(): array @@ -309,7 +292,6 @@ final class Tests extends TestCase /** * @param string[] $rawInput - * @param array $expectedOutput * * @throws InvalidPacketException * @throws SocketException @@ -338,12 +320,10 @@ final class Tests extends TestCase $realOutput = $this->sourceQuery->getPlayers(); - self::assertEquals($expectedOutput, $realOutput); + static::assertSame($expectedOutput, $realOutput); } /** - * @return array - * * @throws JsonException */ public function playersProvider(): array @@ -357,18 +337,13 @@ final class Tests extends TestCase public function testPing(): void { $this->socket->queue("\xFF\xFF\xFF\xFF\x6A\x00"); - self::assertTrue($this->sourceQuery->ping()); + static::assertTrue($this->sourceQuery->ping()); $this->socket->queue("\xFF\xFF\xFF\xFF\xEE"); - self::assertFalse($this->sourceQuery->ping()); + static::assertFalse($this->sourceQuery->ping()); } /** - * @param string $path - * @param bool $hexToBin - * - * @return array - * * @throws JsonException */ private function getData(string $path, bool $hexToBin = false): array @@ -410,7 +385,7 @@ final class Tests extends TestCase true, 512, JSON_THROW_ON_ERROR - ) + ), ]; } diff --git a/composer.json b/composer.json index 3f8d3ec..7b280d5 100644 --- a/composer.json +++ b/composer.json @@ -36,5 +36,11 @@ { "xPaw\\SourceQuery\\": "SourceQuery/" } + }, + "scripts": { + "psalm": "psalm", + "phpstan": "phpstan", + "phpunit": "phpunit Tests/Tests.php", + "php-cs-fixer": "php-cs-fixer fix --config=.php-cs-fixer.php" } }