request = $request; $this->pdm = new PersistentDataManager(); $this->multiConnector = new MultiConnector(); $this->multiRoomRepository = new MultiRoomRepository(); $this->mapRepository = new MapRepository(); } public function getGame(): IContent { $mapId = (int) $this->request->query('mapId'); return new HtmlContent('game', ['mapId' => $mapId]); } public function getNewMultiGame(): IRedirect { $mapId = (int) $this->request->query('mapId'); $map = $this->mapRepository->getById($mapId); $roomId = bin2hex(random_bytes(3)); $token = $this->getMultiToken($roomId); $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 ); } 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(); if (!($state = $session->get('state')) || $state['mapId'] !== $mapId) { $session->set('state', [ 'mapId' => $mapId, 'area' => $map->getArea(), 'rounds' => [], 'currentRound' => -1 ]); } 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; } }