Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Rust
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 2
90
0.00% covered (danger)
0.00%
0 / 1
 query_server
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 parse_rust_player_counts
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Clansuite Server Query
7 *
8 * SPDX-FileCopyrightText: 2003-2025 Jens A. Koch
9 * SPDX-License-Identifier: MIT
10 *
11 * For the full copyright and license information, please view
12 * the LICENSE file that was distributed with this source code.
13 */
14
15namespace Clansuite\ServerQuery\ServerProtocols;
16
17use function is_string;
18use function preg_match_all;
19use Override;
20
21/**
22 * Rust protocol implementation.
23 *
24 * Based on Steam/Source protocol with Rust-specific parsing for player counts from keywords.
25 */
26class Rust extends Steam
27{
28    /**
29     * Protocol name.
30     */
31    public string $name = 'Rust';
32
33    /**
34     * List of supported games.
35     *
36     * @var array<string>
37     */
38    public array $supportedGames = ['Rust'];
39
40    /**
41     * Protocol identifier.
42     */
43    public string $protocol = 'A2S';
44
45    /**
46     * Query server - override to handle Rust specific player count parsing.
47     */
48    #[Override]
49    public function query_server(bool $getPlayers = true, bool $getRules = true): bool
50    {
51        // Call parent query_server
52        $result = parent::query_server($getPlayers, $getRules);
53
54        if (!$result) {
55            return false;
56        }
57
58        // Parse Rust-specific player counts from keywords
59        if (isset($this->rules['keywords']) && is_string($this->rules['keywords'])) {
60            $this->parse_rust_player_counts($this->rules['keywords']);
61        }
62
63        return true;
64    }
65
66    /**
67     * Parse player counts from Rust keywords
68     * mp{maxplayers} and cp{currentplayers} format.
69     */
70    private function parse_rust_player_counts(string $keywords): void
71    {
72        // Match mp{number} and cp{number} patterns
73        if (preg_match_all('/(mp|cp)(\d+)/', $keywords, $matches) !== false) {
74            foreach ($matches[1] as $index => $type) {
75                if (!isset($matches[2][$index])) {
76                    continue;
77                }
78                $value = (int) $matches[2][$index];
79
80                if ($type === 'mp') {
81                    $this->maxplayers = $value;
82                } else {
83                    $this->numplayers = $value;
84                }
85            }
86        }
87    }
88}