use enumeration types

This commit is contained in:
yggverse 2026-03-05 01:08:13 +02:00
parent a101a55715
commit 795f304789

View file

@ -4,6 +4,21 @@ declare(strict_types=1);
namespace Yggverse\Hl\Xash3D; namespace Yggverse\Hl\Xash3D;
enum Family: int {
case IPv4 = 4;
case IPv6 = 16;
}
enum Region: string {
case Europe = "\x03";
case US_East = "\x00";
case World = "\xFF";
}
enum Game: string {
case Valve = "valve";
}
class Master class Master
{ {
private string $_host; private string $_host;
@ -14,7 +29,7 @@ class Master
public function __construct( public function __construct(
string $host, string $host,
int $port, int $port = 27010,
int $timeout = 5 int $timeout = 5
) )
{ {
@ -37,14 +52,16 @@ class Master
// Legacy protocol implementation does not support mixed address families // Legacy protocol implementation does not support mixed address families
// in the binary master socket response, use separated method for IPv4 servers. // in the binary master socket response, use separated method for IPv4 servers.
public function getServersIPv6( public function getServers(
int $limit = 100, int $limit = 100,
string $host = "[::]", string $host = "0.0.0.0",
int $port = 0, int $port = 0,
string $gamedir = "valve", Game $game = Game::Valve,
string $region = "\xFF" Region $region = Region::World
): ?array ): ?array
{ {
$family = filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ? Family::IPv4 : Family::IPv6;
// Init connection // Init connection
$socket = fsockopen( $socket = fsockopen(
"udp://{$this->_host}", "udp://{$this->_host}",
@ -80,7 +97,7 @@ class Master
} }
// Filter query // Filter query
if (false === fwrite($socket, "1{$region}{$host}:{$port}\0\\gamedir\\{$gamedir}\0")) if (false === fwrite($socket, "1{$region->value}{$host}:{$port}\0\\gamedir\\{$game->value}\0"))
{ {
$this->_errors[] = _("Could not send socket query for $master"); $this->_errors[] = _("Could not send socket query for $master");
@ -109,20 +126,20 @@ class Master
for ($i = 0; $i < $limit; $i++) for ($i = 0; $i < $limit; $i++)
{ {
// Get host bytes // Get host bytes
if (false === $h = fread($socket, 16)) if (false === $host = fread($socket, $family->value))
{ {
$this->_errors[] = _("Invalid `host` fragment in packet at $i for $master"); $this->_errors[] = _("Invalid `host` fragment in packet at $i for $master");
break; break;
} }
// End of packet // End of packet
if (true === str_ends_with(bin2hex($h), bin2hex("\0\0\0\0\0\0"))) if (true === str_ends_with(bin2hex($host), bin2hex("\0\0\0\0\0\0")))
{ {
break; break;
} }
// Get host string // Get host string
if (false === $h = inet_ntop($h)) if (false === $host = inet_ntop($host))
{ {
$this->_errors[] = _("Invalid `host` value in packet at $i for $master"); $this->_errors[] = _("Invalid `host` value in packet at $i for $master");
break; break;
@ -143,15 +160,16 @@ class Master
} }
// Validate result // Validate result
if (false === filter_var($h, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || empty($p['port'])) if (false === filter_var($host, FILTER_VALIDATE_IP, $family == Family::IPv6 ? FILTER_FLAG_IPV6
: FILTER_FLAG_IPV4) || empty($p['port']))
{ {
$this->_errors[] = _("Invalid socket address in packet at $i for $master"); $this->_errors[] = _("Invalid socket address in packet at $i for $master");
continue; continue;
} }
$servers["{$h}{$p['port']}"] = // keep unique $servers["{$host}{$p['port']}"] = // keep unique
[ [
'host' => $h, 'host' => $host,
'port' => $p['port'] 'port' => $p['port']
]; ];
} }