Lines
100.00%
31 / 31
Functions and Methods
100.00%
2 / 2
Classes and Traits
100.00%
1 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ServerListClient | 100.00% | 31 / 31 | 100.00% | 2 / 2 | 4 | 100.00% | 1 / 1 | |||
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| fetch | 100.00% | 30 / 30 | 100.00% | 1 / 1 | 3 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace Lorekeeper\Client\Login; | |
| 6 | ||
| 7 | use Lorekeeper\Client\Exception\ServerListUnavailableException; | |
| 8 | use Lorekeeper\Server\Server; | |
| 9 | use Psl\Network\Address; | |
| 10 | use Psl\Type; | |
| 11 | use Psl\Type\Exception\CoercionException; | |
| 12 | ||
| 13 | final readonly class ServerListClient | |
| 14 | { | |
| 15 | /** @param non-empty-string $url */ | |
| 16 | public function __construct( | |
| 17 | private string $url = 'https://game.aq.com/game/api/data/servers', | |
| 18 | ) {} | |
| 19 | ||
| 20 | /** | |
| 21 | * @throws ServerListUnavailableException | |
| 22 | * | |
| 23 | * @return list<Server> | |
| 24 | */ | |
| 25 | public function fetch(): array | |
| 26 | { | |
| 27 | $curl = curl_init($this->url); | |
| 28 | curl_setopt_array($curl, [ | |
| 29 | CURLOPT_RETURNTRANSFER => true, | |
| 30 | CURLOPT_FOLLOWLOCATION => true, | |
| 31 | CURLOPT_TIMEOUT => 10, | |
| 32 | CURLOPT_CONNECTTIMEOUT => 5, | |
| 33 | CURLOPT_USERAGENT => 'Mozilla/5.0', | |
| 34 | ]); | |
| 35 | ||
| 36 | $response = curl_exec($curl); | |
| 37 | if (!is_string($response)) { | |
| 38 | throw new ServerListUnavailableException('Could not reach the server list API: ' . curl_error($curl)); | |
| 39 | } | |
| 40 | ||
| 41 | try { | |
| 42 | $servers = Type\json_decoded(Type\vec(Type\shape([ | |
| 43 | 'sName' => Type\non_empty_string(), | |
| 44 | 'sIP' => Type\non_empty_string(), | |
| 45 | 'iPort' => Type\int_range(min: 1, max: 65_535), | |
| 46 | 'bOnline' => Type\int(), | |
| 47 | 'bUpg' => Type\int(), | |
| 48 | ], allowUnknownFields: true))) | |
| 49 | ->coerce($response); | |
| 50 | } catch (CoercionException $exception) { | |
| 51 | throw new ServerListUnavailableException('Unexpected server list response.', previous: $exception); | |
| 52 | } | |
| 53 | ||
| 54 | return array_map( | |
| 55 | static fn(array $server): Server => new Server( | |
| 56 | $server['sName'], | |
| 57 | Address::tcp($server['sIP'], $server['iPort']), | |
| 58 | $server['bOnline'] === 1, | |
| 59 | $server['bUpg'] === 1, | |
| 60 | ), | |
| 61 | $servers, | |
| 62 | ); | |
| 63 | } | |
| 64 | } |