From 24d0a3a34c453d6990637ab7ed3c5fe21d6e2ab5 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 10:34:41 +0200 Subject: [PATCH 01/13] Added ELO to the game JWT token --- src/Command/Game/AcceptPlayRequestCommand.php | 4 +++- src/Command/Game/StartCommand.php | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Command/Game/AcceptPlayRequestCommand.php b/src/Command/Game/AcceptPlayRequestCommand.php index d909a324..389ab87a 100644 --- a/src/Command/Game/AcceptPlayRequestCommand.php +++ b/src/Command/Game/AcceptPlayRequestCommand.php @@ -40,7 +40,9 @@ public function run(AbstractSocket $socket, array $argv, int $id) if ($gameMode->getStatus() === PlayMode::STATUS_PENDING) { $decoded = $gameMode->getJwtDecoded(); - $decoded->username->{(new Color)->opp($decoded->color)} = $params['username'] ?? self::ANONYMOUS_USER; + $color = (new Color())->opp($decoded->color); + $decoded->username->{$color} = $params['username'] ?? self::ANONYMOUS_USER; + $decoded->elo->{$color} = $params['elo']; $ids = [...$gameMode->getResourceIds(), $id]; $gameMode->setJwt((array) $decoded) ->setResourceIds($ids) diff --git a/src/Command/Game/StartCommand.php b/src/Command/Game/StartCommand.php index c1027285..136102f8 100644 --- a/src/Command/Game/StartCommand.php +++ b/src/Command/Game/StartCommand.php @@ -25,7 +25,7 @@ class StartCommand extends AbstractCommand public function __construct(Db $db) { parent::__construct($db); - + $this->name = '/start'; $this->description = 'Starts a new game.'; $this->params = [ @@ -138,6 +138,14 @@ public function run(AbstractSocket $socket, array $argv, int $id) ? $params['settings']['username'] : self::ANONYMOUS_USER, ], + 'elo' => [ + Color::W => $params['settings']['color'] === Color::W && $params['settings']['elo'] + ? $params['settings']['elo'] + : null, + Color::B => $params['settings']['color'] === Color::B && $params['settings']['elo'] + ? $params['settings']['elo'] + : null, + ], 'submode' => $params['settings']['submode'], 'color' => $params['settings']['color'], 'min' => $params['settings']['min'], From c88427c641e0b69884fa7c121f4614389041a1c6 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 10:57:20 +0200 Subject: [PATCH 02/13] Inject the database connection into PlayMode --- src/Command/Game/Cli.php | 2 +- src/Command/Game/Mode/PlayMode.php | 8 ++++++-- src/Command/Game/RestartCommand.php | 6 +++++- src/Command/Game/StartCommand.php | 7 ++++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Command/Game/Cli.php b/src/Command/Game/Cli.php index 1ceac156..a0e82159 100644 --- a/src/Command/Game/Cli.php +++ b/src/Command/Game/Cli.php @@ -25,7 +25,7 @@ public function __construct(Db $db) $this->commands->attach(new PlayLanCommand()); $this->commands->attach(new PlayRavCommand()); $this->commands->attach(new RandomizerCommand()); - $this->commands->attach(new RestartCommand()); + $this->commands->attach(new RestartCommand($db)); $this->commands->attach(new StartCommand($db)); $this->commands->attach(new StockfishCommand()); $this->commands->attach(new TutorFenCommand()); diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index b2a36a2f..4ab94618 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -3,6 +3,7 @@ namespace ChessServer\Command\Game\Mode; use Chess\Variant\Classical\PGN\AN\Color; +use ChessServer\Command\Db; use ChessServer\Command\Game\Game; use ChessServer\Command\Game\PlayLanCommand; use Firebase\JWT\JWT; @@ -20,7 +21,9 @@ class PlayMode extends AbstractMode const SUBMODE_ONLINE = 'online'; - protected $jwt; + protected string $jwt; + + protected Db $db; protected string $status; @@ -30,11 +33,12 @@ class PlayMode extends AbstractMode protected array $timer; - public function __construct(Game $game, array $resourceIds, string $jwt) + public function __construct(Game $game, array $resourceIds, string $jwt, Db $db) { parent::__construct($game, $resourceIds); $this->jwt = $jwt; + $this->db = $db; $this->hash = hash('adler32', $jwt); $this->status = self::STATUS_PENDING; } diff --git a/src/Command/Game/RestartCommand.php b/src/Command/Game/RestartCommand.php index a3479afa..550cd20d 100644 --- a/src/Command/Game/RestartCommand.php +++ b/src/Command/Game/RestartCommand.php @@ -5,6 +5,7 @@ use Chess\Variant\Chess960\FEN\StrToBoard as Chess960FenStrToBoard; use Chess\Variant\Classical\PGN\AN\Color; use ChessServer\Command\AbstractCommand; +use ChessServer\Command\Db; use ChessServer\Command\Game\Game; use ChessServer\Command\Game\Mode\PlayMode; use ChessServer\Socket\AbstractSocket; @@ -12,8 +13,10 @@ class RestartCommand extends AbstractCommand { - public function __construct() + public function __construct(Db $db) { + parent::__construct($db); + $this->name = '/restart'; $this->description = 'Restarts a game.'; $this->params = [ @@ -45,6 +48,7 @@ public function run(AbstractSocket $socket, array $argv, int $id) $game, $gameMode->getResourceIds(), JWT::encode((array) $decoded, $_ENV['JWT_SECRET'], 'HS256'), + $this->db ); $newGameMode->setStatus(PlayMode::STATUS_ACCEPTED) ->setStartedAt(time()) diff --git a/src/Command/Game/StartCommand.php b/src/Command/Game/StartCommand.php index 136102f8..bf5377aa 100644 --- a/src/Command/Game/StartCommand.php +++ b/src/Command/Game/StartCommand.php @@ -160,7 +160,12 @@ public function run(AbstractSocket $socket, array $argv, int $id) : [] ), ]; - $gameMode = new PlayMode($game, [$id], JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256')); + $gameMode = new PlayMode( + $game, + [$id], + JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256'), + $this->db + ); $socket->getGameModeStorage()->set($gameMode); if ($params['settings']['submode'] === PlayMode::SUBMODE_ONLINE) { $socket->getClientStorage()->sendToAll([ From 529817ab8b4b029a9b9ffec75e5f22ad22d3ba07 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 13:17:12 +0200 Subject: [PATCH 03/13] Update the ELO of the players --- composer.lock | 176 ++++++++++++++--------------- src/Command/Game/Mode/PlayMode.php | 78 ++++++++++++- 2 files changed, 160 insertions(+), 94 deletions(-) diff --git a/composer.lock b/composer.lock index 6b0fca28..10184f5c 100644 --- a/composer.lock +++ b/composer.lock @@ -621,11 +621,11 @@ }, { "name": "chesslablab/php-chess", - "version": "1.4.58", + "version": "1.4.59", "source": { "type": "git", "url": "https://github.com/chesslablab/php-chess.git", - "reference": "ffd53c593b97ee37a5e6a67b8e0de45d1f42979a" + "reference": "34a8fddc1c615bedf79fda0fda750b8030af7c91" }, "require": { "imagine/imagine": "^1.2", @@ -682,7 +682,7 @@ "validate", "validator" ], - "time": "2024-08-28T21:47:36+00:00" + "time": "2024-09-06T16:18:41+00:00" }, { "name": "evenement/evenement", @@ -1496,16 +1496,16 @@ }, { "name": "psr/log", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "79dff0b268932c640297f5208d6298f71855c03e" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", - "reference": "79dff0b268932c640297f5208d6298f71855c03e", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -1540,9 +1540,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.1" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2024-08-21T13:31:24+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "ralouphie/getallheaders", @@ -2173,16 +2173,16 @@ }, { "name": "rubix/ml", - "version": "2.5.0", + "version": "2.5.1", "source": { "type": "git", "url": "https://github.com/RubixML/ML.git", - "reference": "d43a5f2cd714277c10f74096cc5776ce4c828354" + "reference": "85d7d4be9f3f75ec4fea24a4213442e5c14d3853" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/RubixML/ML/zipball/d43a5f2cd714277c10f74096cc5776ce4c828354", - "reference": "d43a5f2cd714277c10f74096cc5776ce4c828354", + "url": "https://api.github.com/repos/RubixML/ML/zipball/85d7d4be9f3f75ec4fea24a4213442e5c14d3853", + "reference": "85d7d4be9f3f75ec4fea24a4213442e5c14d3853", "shasum": "" }, "require": { @@ -2330,7 +2330,7 @@ "type": "github" } ], - "time": "2024-05-23T17:44:44+00:00" + "time": "2024-08-31T22:53:34+00:00" }, { "name": "rubix/tensor", @@ -2663,20 +2663,20 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", - "reference": "0424dff1c58f028c451efff2045f5d92410bd540", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -2722,7 +2722,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -2738,24 +2738,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "c027e6a3c6aee334663ec21f5852e89738abc805" + "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c027e6a3c6aee334663ec21f5852e89738abc805", - "reference": "c027e6a3c6aee334663ec21f5852e89738abc805", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/48becf00c920479ca2e910c22a5a39e5d47ca956", + "reference": "48becf00c920479ca2e910c22a5a39e5d47ca956", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-iconv": "*" @@ -2802,7 +2802,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.31.0" }, "funding": [ { @@ -2818,24 +2818,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", - "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -2880,7 +2880,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -2896,24 +2896,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", - "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -2961,7 +2961,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -2977,24 +2977,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", - "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -3041,7 +3041,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -3057,40 +3057,32 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "10112722600777e02d2745716b70c5db4ca70442" + "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442", - "reference": "10112722600777e02d2745716b70c5db4ca70442", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", + "reference": "fa2ae56c44f03bed91a39bfc9822e31e7c5c38ce", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, - "type": "library", + "type": "metapackage", "extra": { "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" } }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" @@ -3114,7 +3106,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.31.0" }, "funding": [ { @@ -3130,24 +3122,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", - "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -3194,7 +3186,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -3210,24 +3202,24 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php82", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php82.git", - "reference": "77ff49780f56906788a88974867ed68bc49fae5b" + "reference": "5d2ed36f7734637dacc025f179698031951b1692" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/77ff49780f56906788a88974867ed68bc49fae5b", - "reference": "77ff49780f56906788a88974867ed68bc49fae5b", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/5d2ed36f7734637dacc025f179698031951b1692", + "reference": "5d2ed36f7734637dacc025f179698031951b1692", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -3270,7 +3262,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php82/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php82/tree/v1.31.0" }, "funding": [ { @@ -3286,24 +3278,24 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:30:46+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.30.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9" + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", - "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { @@ -3346,7 +3338,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" }, "funding": [ { @@ -3362,20 +3354,20 @@ "type": "tidelift" } ], - "time": "2024-06-19T12:35:24+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/routing", - "version": "v6.4.10", + "version": "v6.4.11", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "aad19fe10753ba842f0d653a8db819c4b3affa87" + "reference": "8ee0c24c1bf61c263a26f1b9b6d19e83b1121f2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/aad19fe10753ba842f0d653a8db819c4b3affa87", - "reference": "aad19fe10753ba842f0d653a8db819c4b3affa87", + "url": "https://api.github.com/repos/symfony/routing/zipball/8ee0c24c1bf61c263a26f1b9b6d19e83b1121f2a", + "reference": "8ee0c24c1bf61c263a26f1b9b6d19e83b1121f2a", "shasum": "" }, "require": { @@ -3429,7 +3421,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.10" + "source": "https://github.com/symfony/routing/tree/v6.4.11" }, "funding": [ { @@ -3445,7 +3437,7 @@ "type": "tidelift" } ], - "time": "2024-07-15T09:26:24+00:00" + "time": "2024-08-29T08:15:38+00:00" }, { "name": "vlucas/phpdotenv", diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index 4ab94618..14f19bc0 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -2,7 +2,10 @@ namespace ChessServer\Command\Game\Mode; +use Chess\Elo\Game as EloGame; +use Chess\Elo\Player as EloPlayer; use Chess\Variant\Classical\PGN\AN\Color; +use Chess\Variant\Classical\PGN\AN\Termination; use ChessServer\Command\Db; use ChessServer\Command\Game\Game; use ChessServer\Command\Game\PlayLanCommand; @@ -124,19 +127,90 @@ protected function updateTimer(string $color) $this->updatedAt = $now; } + protected function elo(string $result, int $i, int $j): array + { + $w = new EloPlayer($i); + $b = new EloPlayer($j); + $game = (new EloGame($w, $b))->setK(32); + if ($result === Termination::WHITE_WINS) { + $game->setScore(1, 0); + } elseif ($result === Termination::DRAW) { + $game->setScore(0, 0); + } elseif ($result === Termination::BLACK_WINS) { + $game->setScore(0, 1); + } + $game->count(); + + return [ + Color::W => $w->getRating(), + Color::B => $b->getRating(), + ]; + } + + protected function eloQuery(string $username, int $elo): void + { + $sql = "UPDATE users SET elo = :elo WHERE username = :username"; + $values= [ + [ + 'param' => ":username", + 'value' => $username, + 'type' => \PDO::PARAM_STR, + ], + [ + 'param' => ":elo", + 'value' => $elo, + 'type' => \PDO::PARAM_INT, + ], + ]; + + $this->db->query($sql, $values); + } + + protected function rating(): array + { + if ($this->game->state()->end) { + $decoded = $this->getJwtDecoded(); + if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { + $elo = $this->elo( + $this->game->state()->end['result'], + $decoded->elo->{Color::W}, + $decoded->elo->{Color::B} + ); + $this->eloQuery($decoded->username->{Color::W}, $elo[Color::W]); + $this->eloQuery($decoded->username->{Color::B}, $elo[Color::B]); + return [ + 'username' => [ + Color::W => $decoded->username->{Color::W}, + Color::B => $decoded->username->{Color::B}, + ], + 'elo' => [ + Color::W => $elo[Color::W], + Color::B => $elo[Color::B], + ], + ]; + } + } + + return []; + } + public function res($params, $cmd) { switch (get_class($cmd)) { case PlayLanCommand::class: $isValid = $this->game->playLan($params['color'], $params['lan']); $this->updateTimer($params['color']); + $rating = $this->rating(); return [ $cmd->name => [ - ... (array) $this->game->state(), + ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), - // play mode information 'timer' => $this->timer, 'isValid' => $isValid, + ...($rating + ? ['rating' => $rating] + : [] + ), ], ]; From f2a67d0572a726cadfdc0f4676d242dcef06e663 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 13:20:54 +0200 Subject: [PATCH 04/13] Updated PlayMode --- src/Command/Game/Mode/PlayMode.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index 14f19bc0..de7a2644 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -200,17 +200,13 @@ public function res($params, $cmd) case PlayLanCommand::class: $isValid = $this->game->playLan($params['color'], $params['lan']); $this->updateTimer($params['color']); - $rating = $this->rating(); return [ $cmd->name => [ ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), 'timer' => $this->timer, 'isValid' => $isValid, - ...($rating - ? ['rating' => $rating] - : [] - ), + 'rating' => $this->rating(), ], ]; From 6b07e9087eae80f0a3b6431f15585c56096882a6 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 15:33:46 +0200 Subject: [PATCH 05/13] Conditionally add associative element to array --- src/Command/Game/Game.php | 11 ++++++++--- src/Command/Game/Mode/PlayMode.php | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Command/Game/Game.php b/src/Command/Game/Game.php index 8b5f3d89..36f60056 100644 --- a/src/Command/Game/Game.php +++ b/src/Command/Game/Game.php @@ -82,11 +82,16 @@ public function setBoard(AbstractBoard $board): Game public function state(): object { + $end = $this->end(); + return (object) [ 'turn' => $this->board->turn, 'movetext' => $this->board->movetext(), 'fen' => $this->board->toFen(), - 'end' => $this->end(), + ...($end + ? ['end' => $end] + : [] + ), ]; } @@ -123,7 +128,7 @@ public function playLan(string $color, string $lan): bool return $this->board->playLan($color, $lan); } - protected function end(): array + protected function end(): ?array { if ($this->board->doesWin()) { // TODO ... @@ -167,6 +172,6 @@ protected function end(): array ]; } - return []; + return null; } } diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index de7a2644..b4a387f0 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -168,7 +168,7 @@ protected function eloQuery(string $username, int $elo): void protected function rating(): array { - if ($this->game->state()->end) { + if (isset($this->game->state()->end)) { $decoded = $this->getJwtDecoded(); if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { $elo = $this->elo( From 693db439e7cc9a46b1f16a490824a947c945c0bd Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 15:35:15 +0200 Subject: [PATCH 06/13] Coding convention --- src/Command/Game/Mode/AbstractMode.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Command/Game/Mode/AbstractMode.php b/src/Command/Game/Mode/AbstractMode.php index 26d7b033..ab446412 100644 --- a/src/Command/Game/Mode/AbstractMode.php +++ b/src/Command/Game/Mode/AbstractMode.php @@ -63,14 +63,14 @@ public function res($params, $cmd) $isValid = $this->game->playLan($params['color'], $params['lan']); return [ $cmd->name => [ - ... (array) $this->game->state(), + ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), 'isValid' => $isValid, ], ]; case StockfishCommand::class: - if (!$this->game->state()->end) { + if (!$this->game->state()->end) { $computer = $this->game->computer($params['options'], $params['params']); if ($computer['pgn']) { $this->game->play($this->game->state()->turn, $computer['pgn']); @@ -78,7 +78,7 @@ public function res($params, $cmd) } return [ $cmd->name => [ - ... (array) $this->game->state(), + ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), ], ]; @@ -88,7 +88,7 @@ public function res($params, $cmd) $this->game->setBoard($board); return [ $cmd->name => [ - ... (array) $this->game->state(), + ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), ], ]; From b78b0836f0e0d417ce8d379c4ed5c49d98f28e28 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 15:42:47 +0200 Subject: [PATCH 07/13] Conditionally add associative element to array --- src/Command/Game/Mode/PlayMode.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index b4a387f0..fc34af87 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -166,7 +166,7 @@ protected function eloQuery(string $username, int $elo): void $this->db->query($sql, $values); } - protected function rating(): array + protected function rating(): ?array { if (isset($this->game->state()->end)) { $decoded = $this->getJwtDecoded(); @@ -191,7 +191,7 @@ protected function rating(): array } } - return []; + return null; } public function res($params, $cmd) @@ -200,13 +200,17 @@ public function res($params, $cmd) case PlayLanCommand::class: $isValid = $this->game->playLan($params['color'], $params['lan']); $this->updateTimer($params['color']); + $rating = $this->rating(); return [ $cmd->name => [ ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), 'timer' => $this->timer, 'isValid' => $isValid, - 'rating' => $this->rating(), + ...($rating + ? ['rating' => $rating] + : [] + ), ], ]; From f7a1005288f6963c4f3da81921a09e665efb07c5 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 16:00:15 +0200 Subject: [PATCH 08/13] Implemented TotpRefreshCommand --- src/Command/Data/Cli.php | 1 + src/Command/Data/TotpRefreshCommand.php | 56 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 src/Command/Data/TotpRefreshCommand.php diff --git a/src/Command/Data/Cli.php b/src/Command/Data/Cli.php index 42aa0d98..07e4b092 100644 --- a/src/Command/Data/Cli.php +++ b/src/Command/Data/Cli.php @@ -22,6 +22,7 @@ public function __construct(Db $db) $this->commands->attach(new ResultPlayerCommand($db)); $this->commands->attach(new ResultCommand($db)); $this->commands->attach(new SearchCommand($db)); + $this->commands->attach(new TotpRefreshCommand($db)); $this->commands->attach(new TotpSignInCommand($db)); $this->commands->attach(new TotpSignUpCommand($db)); } diff --git a/src/Command/Data/TotpRefreshCommand.php b/src/Command/Data/TotpRefreshCommand.php new file mode 100644 index 00000000..ec88ba8e --- /dev/null +++ b/src/Command/Data/TotpRefreshCommand.php @@ -0,0 +1,56 @@ +name = '/totp_refresh'; + $this->description = 'Refresh the TOTP access token.'; + $this->params = [ + 'params' => '', + ]; + } + + public function validate(array $argv) + { + return count($argv) - 1 === count($this->params); + } + + public function run(AbstractSocket $socket, array $argv, int $id) + { + $params = json_decode(stripslashes($argv[1]), true); + + $decoded = JWT::decode($params['access_token'], new Key($_ENV['JWT_SECRET'], 'HS256')); + + $sql = "SELECT * FROM users WHERE username = :username"; + $values[] = [ + 'param' => ":username", + 'value' => $decoded->username, + 'type' => \PDO::PARAM_STR, + ]; + $arr = $this->db->query($sql, $values)->fetch(\PDO::FETCH_ASSOC); + + $payload = [ + 'iss' => $_ENV['JWT_ISS'], + 'iat' => time(), + 'exp' => time() + 3600, // one hour by default + 'username' => $arr['username'], + 'elo' => $arr['elo'], + ]; + + return $socket->getClientStorage()->sendToOne($id, [ + $this->name => [ + 'access_token' => JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256'), + ], + ]); + } +} From d8cfbb44caba2a6f14f9eeb54e9b09b3b9418282 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 16:15:51 +0200 Subject: [PATCH 09/13] Refactored PlayMode --- src/Command/Game/Mode/PlayMode.php | 48 +++++++++--------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index fc34af87..8b1d99aa 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -166,51 +166,31 @@ protected function eloQuery(string $username, int $elo): void $this->db->query($sql, $values); } - protected function rating(): ?array - { - if (isset($this->game->state()->end)) { - $decoded = $this->getJwtDecoded(); - if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { - $elo = $this->elo( - $this->game->state()->end['result'], - $decoded->elo->{Color::W}, - $decoded->elo->{Color::B} - ); - $this->eloQuery($decoded->username->{Color::W}, $elo[Color::W]); - $this->eloQuery($decoded->username->{Color::B}, $elo[Color::B]); - return [ - 'username' => [ - Color::W => $decoded->username->{Color::W}, - Color::B => $decoded->username->{Color::B}, - ], - 'elo' => [ - Color::W => $elo[Color::W], - Color::B => $elo[Color::B], - ], - ]; - } - } - - return null; - } - public function res($params, $cmd) { switch (get_class($cmd)) { case PlayLanCommand::class: $isValid = $this->game->playLan($params['color'], $params['lan']); - $this->updateTimer($params['color']); - $rating = $this->rating(); + if (isset($this->game->state()->end)) { + $decoded = $this->getJwtDecoded(); + if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { + $elo = $this->elo( + $this->game->state()->end['result'], + $decoded->elo->{Color::W}, + $decoded->elo->{Color::B} + ); + $this->eloQuery($decoded->username->{Color::W}, $elo[Color::W]); + $this->eloQuery($decoded->username->{Color::B}, $elo[Color::B]); + } + } else { + $this->updateTimer($params['color']); + } return [ $cmd->name => [ ...(array) $this->game->state(), 'variant' => $this->game->getVariant(), 'timer' => $this->timer, 'isValid' => $isValid, - ...($rating - ? ['rating' => $rating] - : [] - ), ], ]; From 99268569d8af27aed838bf3614379ab7dd7e2d86 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 16:58:44 +0200 Subject: [PATCH 10/13] Refactored PlayMode --- src/Command/Game/Mode/PlayMode.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index 8b1d99aa..b088cc43 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -171,19 +171,21 @@ public function res($params, $cmd) switch (get_class($cmd)) { case PlayLanCommand::class: $isValid = $this->game->playLan($params['color'], $params['lan']); - if (isset($this->game->state()->end)) { - $decoded = $this->getJwtDecoded(); - if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { - $elo = $this->elo( - $this->game->state()->end['result'], - $decoded->elo->{Color::W}, - $decoded->elo->{Color::B} - ); - $this->eloQuery($decoded->username->{Color::W}, $elo[Color::W]); - $this->eloQuery($decoded->username->{Color::B}, $elo[Color::B]); + if ($isValid) { + if (isset($this->game->state()->end)) { + $decoded = $this->getJwtDecoded(); + if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { + $elo = $this->elo( + $this->game->state()->end['result'], + $decoded->elo->{Color::W}, + $decoded->elo->{Color::B} + ); + $this->eloQuery($decoded->username->{Color::W}, $elo[Color::W]); + $this->eloQuery($decoded->username->{Color::B}, $elo[Color::B]); + } + } else { + $this->updateTimer($params['color']); } - } else { - $this->updateTimer($params['color']); } return [ $cmd->name => [ From 84a87e6b877d37b75fd5ba1e5bc8cd42f3109306 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 17:22:50 +0200 Subject: [PATCH 11/13] Fixed TotpRefreshCommand --- src/Command/Data/TotpRefreshCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Command/Data/TotpRefreshCommand.php b/src/Command/Data/TotpRefreshCommand.php index ec88ba8e..a7d2f164 100644 --- a/src/Command/Data/TotpRefreshCommand.php +++ b/src/Command/Data/TotpRefreshCommand.php @@ -6,6 +6,7 @@ use ChessServer\Command\Db; use ChessServer\Socket\AbstractSocket; use Firebase\JWT\JWT; +use Firebase\JWT\Key; class TotpRefreshCommand extends AbstractCommand { From b5c88516e44df8159b7e5c5c23c6b39708592c03 Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 17:37:50 +0200 Subject: [PATCH 12/13] Return null if no access token is provided --- src/Command/Data/TotpRefreshCommand.php | 43 +++++++++++++------------ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/Command/Data/TotpRefreshCommand.php b/src/Command/Data/TotpRefreshCommand.php index a7d2f164..3366affa 100644 --- a/src/Command/Data/TotpRefreshCommand.php +++ b/src/Command/Data/TotpRefreshCommand.php @@ -30,28 +30,31 @@ public function run(AbstractSocket $socket, array $argv, int $id) { $params = json_decode(stripslashes($argv[1]), true); - $decoded = JWT::decode($params['access_token'], new Key($_ENV['JWT_SECRET'], 'HS256')); - - $sql = "SELECT * FROM users WHERE username = :username"; - $values[] = [ - 'param' => ":username", - 'value' => $decoded->username, - 'type' => \PDO::PARAM_STR, - ]; - $arr = $this->db->query($sql, $values)->fetch(\PDO::FETCH_ASSOC); - - $payload = [ - 'iss' => $_ENV['JWT_ISS'], - 'iat' => time(), - 'exp' => time() + 3600, // one hour by default - 'username' => $arr['username'], - 'elo' => $arr['elo'], - ]; + if ($params['access_token']) { + $decoded = JWT::decode($params['access_token'], new Key($_ENV['JWT_SECRET'], 'HS256')); + $sql = "SELECT * FROM users WHERE username = :username"; + $values[] = [ + 'param' => ":username", + 'value' => $decoded->username, + 'type' => \PDO::PARAM_STR, + ]; + $arr = $this->db->query($sql, $values)->fetch(\PDO::FETCH_ASSOC); + $payload = [ + 'iss' => $_ENV['JWT_ISS'], + 'iat' => time(), + 'exp' => time() + 3600, // one hour by default + 'username' => $arr['username'], + 'elo' => $arr['elo'], + ]; + return $socket->getClientStorage()->sendToOne($id, [ + $this->name => [ + 'access_token' => JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256'), + ], + ]); + } return $socket->getClientStorage()->sendToOne($id, [ - $this->name => [ - 'access_token' => JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256'), - ], + $this->name => null, ]); } } From 52dde4937ff7f03492ec81e429757d13331047bd Mon Sep 17 00:00:00 2001 From: programarivm Date: Thu, 12 Sep 2024 17:39:52 +0200 Subject: [PATCH 13/13] Fixed PHP Warning: Undefined array key 'access_token' --- src/Command/Data/TotpRefreshCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Command/Data/TotpRefreshCommand.php b/src/Command/Data/TotpRefreshCommand.php index 3366affa..3ea3a2a7 100644 --- a/src/Command/Data/TotpRefreshCommand.php +++ b/src/Command/Data/TotpRefreshCommand.php @@ -30,7 +30,7 @@ public function run(AbstractSocket $socket, array $argv, int $id) { $params = json_decode(stripslashes($argv[1]), true); - if ($params['access_token']) { + if (isset($params['access_token'])) { $decoded = JWT::decode($params['access_token'], new Key($_ENV['JWT_SECRET'], 'HS256')); $sql = "SELECT * FROM users WHERE username = :username"; $values[] = [