diff --git a/cli/ratchet/game.php b/cli/ratchet/game.php index df6003a7..6bdbb05e 100644 --- a/cli/ratchet/game.php +++ b/cli/ratchet/game.php @@ -2,7 +2,6 @@ namespace ChessServer\Cli\Ratchet; -use ChessServer\Db; use ChessServer\Command\Parser; use ChessServer\Command\Game\Cli; use ChessServer\Socket\Ratchet\ClientStorage; @@ -13,7 +12,6 @@ use Ratchet\Http\HttpServer; use Ratchet\Server\IoServer; use Ratchet\WebSocket\WsServer; -use React\EventLoop\Factory; use React\Socket\LimitingServer; use React\Socket\Server; use React\Socket\SecureServer; @@ -26,20 +24,12 @@ $pool = Pool::create(); -$db = new Db([ - 'driver' => $_ENV['DB_DRIVER'], - 'host' => $_ENV['DB_HOST'], - 'database' => $_ENV['DB_DATABASE'], - 'username' => $_ENV['DB_USERNAME'], - 'password' => $_ENV['DB_PASSWORD'], -]); - $logger = new Logger('log'); $logger->pushHandler(new StreamHandler(__DIR__.'/../../storage' . '/game.log', Logger::INFO)); -$clientStorage = new ClientStorage($logger); +$parser = new Parser(new Cli($pool)); -$parser = new Parser(new Cli($pool, $db)); +$clientStorage = new ClientStorage($logger); $webSocket = (new GameWebSocket($parser))->init($clientStorage); diff --git a/cli/ratchet/ws_game.php b/cli/ratchet/ws_game.php index 7caa06f6..5dfa5b7b 100644 --- a/cli/ratchet/ws_game.php +++ b/cli/ratchet/ws_game.php @@ -2,7 +2,6 @@ namespace ChessServer\Cli\Ratchet; -use ChessServer\Db; use ChessServer\Command\Parser; use ChessServer\Command\Game\Cli; use ChessServer\Socket\Ratchet\ClientStorage; @@ -23,20 +22,12 @@ $pool = Pool::create(); -$db = new Db([ - 'driver' => $_ENV['DB_DRIVER'], - 'host' => $_ENV['DB_HOST'], - 'database' => $_ENV['DB_DATABASE'], - 'username' => $_ENV['DB_USERNAME'], - 'password' => $_ENV['DB_PASSWORD'], -]); - $logger = new Logger('log'); $logger->pushHandler(new StreamHandler(__DIR__.'/../../storage' . '/game.log', Logger::INFO)); -$clientStorage = new ClientStorage($logger); +$parser = new Parser(new Cli($pool)); -$parser = new Parser(new Cli($pool, $db)); +$clientStorage = new ClientStorage($logger); $webSocket = (new GameWebSocket($parser))->init($clientStorage); diff --git a/cli/workerman/game.php b/cli/workerman/game.php index 9e74a670..7c175755 100644 --- a/cli/workerman/game.php +++ b/cli/workerman/game.php @@ -2,7 +2,6 @@ namespace ChessServer\Cli\Workerman; -use ChessServer\Db; use ChessServer\Command\Parser; use ChessServer\Command\Game\Cli; use ChessServer\Socket\Workerman\ClientStorage; @@ -19,18 +18,10 @@ $pool = Pool::create(); -$db = new Db([ - 'driver' => $_ENV['DB_DRIVER'], - 'host' => $_ENV['DB_HOST'], - 'database' => $_ENV['DB_DATABASE'], - 'username' => $_ENV['DB_USERNAME'], - 'password' => $_ENV['DB_PASSWORD'], -]); - $logger = new Logger('game'); $logger->pushHandler(new StreamHandler(GameWebSocket::STORAGE_FOLDER . '/game.log', Logger::INFO)); -$parser = new Parser(new Cli($pool, $db)); +$parser = new Parser(new Cli($pool)); $clientStorage = new ClientStorage($logger); diff --git a/src/Command/Game/Cli.php b/src/Command/Game/Cli.php index b62a67df..52592d80 100644 --- a/src/Command/Game/Cli.php +++ b/src/Command/Game/Cli.php @@ -10,11 +10,10 @@ class Cli extends AbstractCli { private Db $db; - public function __construct(Pool $pool, Db $db) + public function __construct(Pool $pool) { parent::__construct(); - $this->db = $db; // text-based commands $this->commands->attach(new EvalNamesCommand()); $this->commands->attach(new OnlineGamesCommand()); @@ -26,14 +25,14 @@ public function __construct(Pool $pool, Db $db) // param-based commands $this->commands->attach(new AcceptPlayRequestCommand()); $this->commands->attach((new HeuristicCommand())->setPool($pool)); - $this->commands->attach(new LeaveCommand($db)); + $this->commands->attach((new LeaveCommand())->setPool($pool)); $this->commands->attach(new LegalCommand()); $this->commands->attach(new PlayLanCommand()); $this->commands->attach((new PlayRavCommand())->setPool($pool)); $this->commands->attach(new RandomizerCommand()); - $this->commands->attach(new ResignCommand($db)); - $this->commands->attach(new RestartCommand($db)); - $this->commands->attach(new StartCommand($db)); + $this->commands->attach((new ResignCommand())->setPool($pool)); + $this->commands->attach((new RestartCommand())->setPool($pool)); + $this->commands->attach((new StartCommand())->setPool($pool)); $this->commands->attach((new StockfishCommand())->setPool($pool)); $this->commands->attach(new TutorFenCommand()); } diff --git a/src/Command/Game/LeaveCommand.php b/src/Command/Game/LeaveCommand.php index 96b8705d..0d9c0414 100644 --- a/src/Command/Game/LeaveCommand.php +++ b/src/Command/Game/LeaveCommand.php @@ -2,17 +2,14 @@ namespace ChessServer\Command\Game; -use ChessServer\Db; use ChessServer\Command\AbstractCommand; use ChessServer\Repository\UserRepository; use ChessServer\Socket\AbstractSocket; class LeaveCommand extends AbstractCommand { - public function __construct(Db $db) + public function __construct() { - parent::__construct($db); - $this->name = '/leave'; $this->description = 'Leaves a game.'; $this->params = [ @@ -31,7 +28,7 @@ public function run(AbstractSocket $socket, array $argv, int $id) if ($gameMode = $socket->getGameModeStorage()->getById($id)) { $gameMode->getGame()->setAbandoned($params['color']); - (new UserRepository($this->db))->updateElo( + (new UserRepository())->updateElo( $gameMode->getGame()->state()->end['result'], $gameMode->getJwtDecoded() ); diff --git a/src/Command/Game/Mode/PlayMode.php b/src/Command/Game/Mode/PlayMode.php index 2001fdc4..7b771a1f 100644 --- a/src/Command/Game/Mode/PlayMode.php +++ b/src/Command/Game/Mode/PlayMode.php @@ -3,7 +3,6 @@ namespace ChessServer\Command\Game\Mode; use Chess\Variant\Classical\PGN\AN\Color; -use ChessServer\Db; use ChessServer\Command\Game\Game; use ChessServer\Command\Game\PlayLanCommand; use ChessServer\Repository\UserRepository; @@ -18,8 +17,6 @@ class PlayMode extends AbstractMode const SUBMODE_FRIEND = 'friend'; const SUBMODE_ONLINE = 'online'; - protected Db $db; - protected string $status; protected int $startedAt; @@ -28,11 +25,10 @@ class PlayMode extends AbstractMode protected array $timer; - public function __construct(Game $game, array $resourceIds, string $jwt, Db $db) + public function __construct(Game $game, array $resourceIds, string $jwt) { parent::__construct($game, $resourceIds, $jwt); - $this->db = $db; $this->status = self::STATUS_PENDING; } @@ -106,7 +102,7 @@ public function res($params, $cmd) $isValid = $this->game->playLan($params['color'], $params['lan']); if ($isValid) { if (isset($this->game->state()->end)) { - (new UserRepository($this->db))->updateElo( + (new UserRepository())->updateElo( $this->game->state()->end['result'], $this->getJwtDecoded() ); diff --git a/src/Command/Game/ResignCommand.php b/src/Command/Game/ResignCommand.php index af03dbc6..58955062 100644 --- a/src/Command/Game/ResignCommand.php +++ b/src/Command/Game/ResignCommand.php @@ -2,17 +2,14 @@ namespace ChessServer\Command\Game; -use ChessServer\Db; use ChessServer\Command\AbstractCommand; use ChessServer\Repository\UserRepository; use ChessServer\Socket\AbstractSocket; class ResignCommand extends AbstractCommand { - public function __construct(Db $db) + public function __construct() { - parent::__construct($db); - $this->name = '/resign'; $this->description = 'Resigns a game.'; $this->params = [ @@ -30,7 +27,7 @@ public function run(AbstractSocket $socket, array $argv, int $id) $params = json_decode(stripslashes($argv[1]), true); $gameMode = $socket->getGameModeStorage()->getById($id); $gameMode->getGame()->setResignation($params['color']); - (new UserRepository($this->db))->updateElo( + (new UserRepository())->updateElo( $gameMode->getGame()->state()->end['result'], $gameMode->getJwtDecoded() ); diff --git a/src/Command/Game/RestartCommand.php b/src/Command/Game/RestartCommand.php index df228803..eaab6152 100644 --- a/src/Command/Game/RestartCommand.php +++ b/src/Command/Game/RestartCommand.php @@ -4,7 +4,6 @@ use Chess\Variant\Chess960\FEN\StrToBoard as Chess960FenStrToBoard; use Chess\Variant\Classical\PGN\AN\Color; -use ChessServer\Db; use ChessServer\Command\AbstractCommand; use ChessServer\Command\Game\Game; use ChessServer\Command\Game\Mode\PlayMode; @@ -13,10 +12,8 @@ class RestartCommand extends AbstractCommand { - public function __construct(Db $db) + public function __construct() { - parent::__construct($db); - $this->name = '/restart'; $this->description = 'Restarts an existing game.'; $this->params = [ @@ -47,8 +44,7 @@ public function run(AbstractSocket $socket, array $argv, int $id) $newGameMode = (new PlayMode( $game, $gameMode->getResourceIds(), - JWT::encode((array) $decoded, $_ENV['JWT_SECRET'], 'HS256'), - $this->db + JWT::encode((array) $decoded, $_ENV['JWT_SECRET'], 'HS256') ))->setStatus(PlayMode::STATUS_ACCEPTED) ->setStartedAt(time()) ->setUpdatedAt(time()) diff --git a/src/Command/Game/StartCommand.php b/src/Command/Game/StartCommand.php index 05787405..3bb9410d 100644 --- a/src/Command/Game/StartCommand.php +++ b/src/Command/Game/StartCommand.php @@ -12,7 +12,6 @@ use Chess\Variant\Dunsany\Board as DunsanyBoard; use Chess\Variant\Losing\Board as LosingBoard; use Chess\Variant\RacingKings\Board as RacingKingsBoard; -use ChessServer\Db; use ChessServer\Command\AbstractCommand; use ChessServer\Command\Game\Mode\AnalysisMode; use ChessServer\Command\Game\Mode\PlayMode; @@ -22,10 +21,8 @@ class StartCommand extends AbstractCommand { - public function __construct(Db $db) + public function __construct() { - parent::__construct($db); - $this->name = '/start'; $this->description = 'Starts a new game.'; $this->params = [ @@ -162,8 +159,7 @@ public function run(AbstractSocket $socket, array $argv, int $id) $gameMode = new PlayMode( $game, [$id], - JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256'), - $this->db + JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256') ); $socket->getGameModeStorage()->set($gameMode); if ($params['settings']['submode'] === PlayMode::SUBMODE_ONLINE) { diff --git a/src/Repository/UpdateEloAsyncTask.php b/src/Repository/UpdateEloAsyncTask.php new file mode 100644 index 00000000..dc2f39ec --- /dev/null +++ b/src/Repository/UpdateEloAsyncTask.php @@ -0,0 +1,46 @@ +params = $params; + $this->env = $env; + } + + public function configure() + { + $this->db = new Db($this->env['db']); + } + + public function run() + { + $sql = "UPDATE users SET elo = :elo WHERE username = :username"; + + $values= [ + [ + 'param' => ":username", + 'value' => $this->params['username'], + 'type' => \PDO::PARAM_STR, + ], + [ + 'param' => ":elo", + 'value' => $this->params['elo'], + 'type' => \PDO::PARAM_INT, + ], + ]; + + return $this->db->query($sql, $values); + } +} diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index 875bbd5d..f47d2936 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -7,17 +7,9 @@ use Chess\Elo\Player; use Chess\Variant\Classical\PGN\AN\Color; use Chess\Variant\Classical\PGN\AN\Termination; -use ChessServer\Db; class UserRepository { - private Db $db; - - public function __construct(Db $db) - { - $this->db = $db; - } - public function updateElo(string $result, stdClass $decoded): void { if ($decoded->elo->{Color::W} && $decoded->elo->{Color::B}) { @@ -26,8 +18,26 @@ public function updateElo(string $result, stdClass $decoded): void $decoded->elo->{Color::W}, $decoded->elo->{Color::B} ); - $this->updateEloQuery($decoded->username->{Color::W}, $eloRating[Color::W]); - $this->updateEloQuery($decoded->username->{Color::B}, $eloRating[Color::B]); + + $env = [ + 'db' => [ + 'driver' => $_ENV['DB_DRIVER'], + 'host' => $_ENV['DB_HOST'], + 'database' => $_ENV['DB_DATABASE'], + 'username' => $_ENV['DB_USERNAME'], + 'password' => $_ENV['DB_PASSWORD'], + ], + ]; + + $this->pool->add(new UpdateEloAsyncTask([ + 'username' => $decoded->username->{Color::W}, + 'elo' => $eloRating[Color::W], + ], $env)); + + $this->pool->add(new UpdateEloAsyncTask([ + 'username' => $decoded->username->{Color::B}, + 'elo' => $eloRating[Color::B], + ], $env)); } } @@ -36,6 +46,7 @@ protected function eloRating(string $result, int $i, int $j): array $w = new Player($i); $b = new Player($j); $g = (new Game($w, $b))->setK(32); + if ($result === Termination::WHITE_WINS) { $g->setScore(1, 0)->count(); } elseif ($result === Termination::DRAW) { @@ -49,23 +60,4 @@ protected function eloRating(string $result, int $i, int $j): array Color::B => $b->getRating(), ]; } - - protected function updateEloQuery(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); - } } diff --git a/src/Socket/DbReconnectTrait.php b/src/Socket/DbReconnectTrait.php deleted file mode 100644 index 087665f0..00000000 --- a/src/Socket/DbReconnectTrait.php +++ /dev/null @@ -1,30 +0,0 @@ -parser->cli->getDb()->getPdo()->getAttribute(\PDO::ATTR_SERVER_INFO); - } catch(\PDOException $e) { - try { - $db = new Db([ - 'driver' => $_ENV['DB_DRIVER'], - 'host' => $_ENV['DB_HOST'], - 'database' => $_ENV['DB_DATABASE'], - 'username' => $_ENV['DB_USERNAME'], - 'password' => $_ENV['DB_PASSWORD'], - ]); - $this->setParser(new Parser(new Cli($db))); - $this->getClientStorage()->getLogger()->info('Successfully reconnected to Chess Data'); - } catch(\PDOException $e) { - } - } - } -} diff --git a/src/Socket/Ratchet/GameWebSocket.php b/src/Socket/Ratchet/GameWebSocket.php index 73c98029..ccab6d68 100644 --- a/src/Socket/Ratchet/GameWebSocket.php +++ b/src/Socket/Ratchet/GameWebSocket.php @@ -4,21 +4,14 @@ use ChessServer\Command\Parser; use ChessServer\Command\Game\GameModeStorage; -use ChessServer\Socket\DbReconnectTrait; use Ratchet\ConnectionInterface; class GameWebSocket extends AbstractWebSocket { - use DbReconnectTrait; - public function __construct(Parser $parser) { parent::__construct($parser); - $this->loop->addPeriodicTimer($this->timeInterval, function() { - $this->reconnect(); - }); - $this->gameModeStorage = new GameModeStorage(); } diff --git a/src/Socket/Workerman/GameWebSocket.php b/src/Socket/Workerman/GameWebSocket.php index ae7e4407..d5802f6d 100644 --- a/src/Socket/Workerman/GameWebSocket.php +++ b/src/Socket/Workerman/GameWebSocket.php @@ -4,13 +4,10 @@ use ChessServer\Command\Parser; use ChessServer\Command\Game\GameModeStorage; -use ChessServer\Socket\DbReconnectTrait; use Workerman\Timer; class GameWebSocket extends AbstractWebSocket { - use DbReconnectTrait; - private GrandmasterMove $gmMove; private GameModeStorage $gameModeStorage; @@ -19,12 +16,6 @@ public function __construct(string $socketName, array $context, Parser $parser) { parent::__construct($socketName, $context, $parser); - $this->worker->onWorkerStart = function() { - Timer::add($this->timeInterval, function() { - $this->reconnect(); - }); - }; - $this->gameModeStorage = new GameModeStorage(); $this->connect()->message()->error()->close();