MAPG-203 prepare GameController for multiplayer

This commit is contained in:
Bence Pőcze 2021-03-19 23:13:35 +01:00
parent 573440868e
commit 2f665381c3
Signed by: bence
GPG Key ID: AA52B11A3269D1C1

View File

@ -1,20 +1,37 @@
<?php namespace MapGuesser\Controller; <?php namespace MapGuesser\Controller;
use DateTime;
use Faker\Factory;
use MapGuesser\Interfaces\Request\IRequest; use MapGuesser\Interfaces\Request\IRequest;
use MapGuesser\Response\HtmlContent; use MapGuesser\Response\HtmlContent;
use MapGuesser\Response\JsonContent; use MapGuesser\Response\JsonContent;
use MapGuesser\Interfaces\Response\IContent; use MapGuesser\Interfaces\Response\IContent;
use MapGuesser\Interfaces\Response\IRedirect;
use MapGuesser\Multi\MultiConnector;
use MapGuesser\PersistentData\Model\MultiRoom;
use MapGuesser\PersistentData\PersistentDataManager;
use MapGuesser\Repository\MapRepository; use MapGuesser\Repository\MapRepository;
use MapGuesser\Repository\MultiRoomRepository;
use MapGuesser\Response\Redirect;
class GameController class GameController
{ {
private IRequest $request; private IRequest $request;
private PersistentDataManager $pdm;
private MultiConnector $multiConnector;
private MultiRoomRepository $multiRoomRepository;
private MapRepository $mapRepository; private MapRepository $mapRepository;
public function __construct(IRequest $request) public function __construct(IRequest $request)
{ {
$this->request = $request; $this->request = $request;
$this->pdm = new PersistentDataManager();
$this->multiConnector = new MultiConnector();
$this->multiRoomRepository = new MultiRoomRepository();
$this->mapRepository = new MapRepository(); $this->mapRepository = new MapRepository();
} }
@ -22,18 +39,49 @@ class GameController
{ {
$mapId = (int) $this->request->query('mapId'); $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'); $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); $map = $this->mapRepository->getById($mapId);
$session = $this->request->session(); $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;
} }
} }