From 2f665381c3a48732a4cfd333ea58f2c7944d9f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=91cze=20Bence?= Date: Fri, 19 Mar 2021 23:13:35 +0100 Subject: [PATCH] MAPG-203 prepare GameController for multiplayer --- src/Controller/GameController.php | 125 ++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/src/Controller/GameController.php b/src/Controller/GameController.php index 8149d7c..bd9a281 100644 --- a/src/Controller/GameController.php +++ b/src/Controller/GameController.php @@ -1,20 +1,37 @@ request = $request; + $this->pdm = new PersistentDataManager(); + $this->multiConnector = new MultiConnector(); + $this->multiRoomRepository = new MultiRoomRepository(); $this->mapRepository = new MapRepository(); } @@ -22,18 +39,49 @@ class GameController { $mapId = (int) $this->request->query('mapId'); - return new HtmlContent('game', $this->prepareGame($mapId)); + return new HtmlContent('game', ['mapId' => $mapId]); } - public function getGameJson(): IContent + public function getNewMultiGame(): IRedirect { $mapId = (int) $this->request->query('mapId'); + $map = $this->mapRepository->getById($mapId); + $roomId = bin2hex(random_bytes(3)); + $token = $this->getMultiToken($roomId); - return new JsonContent($this->prepareGame($mapId)); + $room = new MultiRoom(); + $room->setRoomId($roomId); + $room->setStateArray([ + 'mapId' => $mapId, + 'area' => $map->getArea(), + 'rounds' => [], + 'currentRound' => -1 + ]); + $room->setMembersArray(['owner' => $token, 'all' => []]); + $room->setUpdatedDate(new DateTime()); + + $this->pdm->saveToDb($room); + + $this->multiConnector->sendMessage('create_room', ['roomId' => $roomId]); + + return new Redirect( + \Container::$routeCollection + ->getRoute('multiGame') + ->generateLink(['roomId' => $roomId]), + IRedirect::TEMPORARY + ); } - private function prepareGame(int $mapId): array + public function getMultiGame() { + $roomId = $this->request->query('roomId'); + + return new HtmlContent('game', ['roomId' => $roomId]); + } + + public function prepareGame(int $mapId): IContent + { + $mapId = (int) $this->request->query('mapId'); $map = $this->mapRepository->getById($mapId); $session = $this->request->session(); @@ -46,6 +94,73 @@ class GameController ]); } - return ['mapId' => $mapId, 'mapName' => $map->getName(), 'bounds' => $map->getBounds()->toArray()]; + return new JsonContent([ + 'mapId' => $mapId, + 'mapName' => $map->getName(), + 'bounds' => $map->getBounds()->toArray() + ]); + } + + public function prepareMultiGame(): IContent + { + $roomId = $this->request->query('roomId'); + $userName = $this->request->post('userName'); + if (empty($userName)) { + $faker = Factory::create(); + $userName = $faker->userName; + } + + $room = $this->multiRoomRepository->getByRoomId($roomId); + $state = $room->getStateArray(); + $map = $this->mapRepository->getById($state['mapId']); + $token = $this->getMultiToken($roomId); + + $members = $room->getMembersArray(); + + if (!in_array($token, $members['all'])) { + if ($state['currentRound'] >= 0) { + return new JsonContent(['error' => 'game_already_started']); + } + + $members['all'][] = $token; + } + + $room->setMembersArray($members); + $room->setUpdatedDate(new DateTime()); + + $this->pdm->saveToDb($room); + + $this->multiConnector->sendMessage('join_room', [ + 'roomId' => $roomId, + 'token' => $token, + 'userName' => $userName + ]); + + return new JsonContent([ + 'roomId' => $roomId, + 'token' => $token, + 'owner' => $members['owner'] == $token, + 'mapId' => $state['mapId'], + 'mapName' => $map->getName(), + 'bounds' => $map->getBounds()->toArray() + ]); + } + + private function getMultiToken(string $roomId, bool $forceNew = false) + { + $session = $this->request->session(); + + if (!($multiState = $session->get('multiState')) || $multiState['roomId'] !== $roomId) { + $token = bin2hex(random_bytes(16)); + + $session->set('multiState', [ + 'roomId' => $roomId, + 'token' => $token + ]); + } else { + $token = $multiState['token']; + } + + return $token; } }