Lines 41.37% 12 / 29
Functions and Methods 0.00% 0 / 3
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
Login 41.37% 12 / 29 0.00% 0 / 3 25.32 0.00% 0 / 1
 enter 0.00% 0 / 13 0.00% 0 / 1 12
 enterOn 81.81% 9 / 11 0.00% 0 / 1 4.10
 leave 60.00% 3 / 5 0.00% 0 / 1 2.26
1<?php
2
3declare(strict_types=1);
4
5namespace Lorekeeper\Client\Login;
6
7use Lorekeeper\Client\Bot\Credentials;
8use Lorekeeper\Client\Character;
9use Lorekeeper\Client\Client;
10use Lorekeeper\Client\ClientVersion;
11use Lorekeeper\Client\Command\Session\LogoutCommand;
12use Lorekeeper\Client\Connection;
13use Lorekeeper\Client\Exception\PeerClosedException;
14use Lorekeeper\Client\Script\Disconnected;
15use Lorekeeper\Client\Script\Game\EnterGameScript;
16use Lorekeeper\Client\Script\Game\InGame;
17use Lorekeeper\Client\Script\Outcome;
18use Lorekeeper\Client\Script\Stopped;
19use Lorekeeper\Core\Player\PlayerName;
20use Psl\Async\CancellationTokenInterface;
21use Psl\Async\NullCancellationToken;
22use SensitiveParameter;
23use Throwable;
24
25final readonly class Login
26{
27    public static function enter(
28        Credentials $credentials,
29        CancellationTokenInterface $stop = new NullCancellationToken(),
30        LoginClient $logins = new LoginClient(),
31        ClientVersion $version = new ClientVersion('5.1'),
32    ): Client|Ending {
33        try {
34            $login = $logins->login($credentials->player, $credentials->password);
35
36            $server = ServerChoice::pick($login->servers, $credentials->server);
37            if ($server->isNone()) {
38                return new Ending(EndingStatus::Failed, 'no open server');
39            }
40
41            return self::enterOn(
42                Connection::open($server->unwrap()),
43                $credentials->player,
44                $login->token,
45                $stop,
46                $version,
47            );
48        } catch (Throwable $failure) {
49            return new Ending(EndingStatus::Failed, $failure->getMessage());
50        }
51    }
52
53    public static function enterOn(
54        Connection $connection,
55        PlayerName $player,
56        #[SensitiveParameter]
57        string $token,
58        CancellationTokenInterface $stop = new NullCancellationToken(),
59        ClientVersion $version = new ClientVersion('5.1'),
60    ): Client|Ending {
61        $client = new Client($connection, new Character($player));
62
63        $entered = $client->run(new EnterGameScript(new GameLogin($player, $token, $version)), $stop);
64        if ($entered instanceof Disconnected) {
65            return new Ending(EndingStatus::Disconnected, $entered->reason);
66        }
67
68        if (!$entered instanceof InGame) {
69            $client->close();
70
71            return $entered instanceof Stopped
72                ? new Ending(EndingStatus::Stopped)
73                : new Ending(EndingStatus::Failed, Outcome::of($entered)->summary);
74        }
75
76        $client->character()->entered($entered);
77
78        return $client;
79    }
80
81    public static function leave(Client $client): bool
82    {
83        try {
84            $client->send(new LogoutCommand());
85
86            return true;
87        } catch (PeerClosedException) {
88            return false;
89        } finally {
90            $client->close();
91        }
92    }
93}