Trying to add waiting pages
This commit is contained in:
@@ -15,6 +15,9 @@ use App\Game\Repository\SessionRepository;
|
||||
use App\Tech\Entity\User;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Mercure\HubInterface;
|
||||
use Symfony\Component\Mercure\Update;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
final class GameDashboardService
|
||||
{
|
||||
@@ -22,6 +25,9 @@ final class GameDashboardService
|
||||
private readonly GameRepository $gameRepository,
|
||||
private readonly SessionRepository $sessionRepository,
|
||||
private readonly EntityManagerInterface $entityManager,
|
||||
private readonly HubInterface $hub,
|
||||
#[Autowire('%env(MERCURE_TOPIC_BASE)%')]
|
||||
private readonly string $mercureTopicBase,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -66,13 +72,17 @@ final class GameDashboardService
|
||||
|
||||
$player = new Player();
|
||||
$player->setUser($user);
|
||||
$player->setSession($session);
|
||||
$session->addPlayer($player);
|
||||
|
||||
$this->entityManager->persist($session);
|
||||
$this->entityManager->persist($player);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
if (count($session->getPlayers()) === $session->getGame()->getNumberOfPlayers()) {
|
||||
$this->startSession($session);
|
||||
}
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
@@ -107,12 +117,16 @@ final class GameDashboardService
|
||||
|
||||
$player = new Player();
|
||||
$player->setUser($user);
|
||||
$player->setSession($session);
|
||||
$session->addPlayer($player);
|
||||
|
||||
$this->entityManager->persist($player);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
if (count($session->getPlayers()) === $session->getGame()->getNumberOfPlayers()) {
|
||||
$this->startSession($session);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,7 +136,7 @@ final class GameDashboardService
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($session->getStatus() !== SessionStatus::CREATED || $session->getTimer() > 0) {
|
||||
if (!in_array($session->getStatus(), [SessionStatus::CREATED, SessionStatus::READY]) || $session->getTimer() > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -138,6 +152,14 @@ final class GameDashboardService
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($session->getStatus() === SessionStatus::READY) {
|
||||
$session->setStatus(SessionStatus::CREATED);
|
||||
// Clear assignments for all remaining players since the game needs to be "started" again
|
||||
foreach ($session->getPlayers() as $player) {
|
||||
$player->setScreen(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove player specific settings (like rights)
|
||||
foreach ($session->getSettings() as $setting) {
|
||||
if ($setting->getPlayer() === $playerToDelete) {
|
||||
@@ -240,6 +262,14 @@ final class GameDashboardService
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clean up any existing assignments (e.g. if we reverted from READY to CREATED)
|
||||
foreach ($session->getSettings() as $setting) {
|
||||
if ($setting->getPlayer() !== null) {
|
||||
$session->removeSetting($setting);
|
||||
$this->entityManager->remove($setting);
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle players to assign random screens
|
||||
shuffle($players);
|
||||
|
||||
@@ -257,6 +287,113 @@ final class GameDashboardService
|
||||
return true;
|
||||
}
|
||||
|
||||
public function toggleReady(Session $session, User $user): bool
|
||||
{
|
||||
if ($session->getStatus() !== SessionStatus::READY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$player = null;
|
||||
foreach ($session->getPlayers() as $p) {
|
||||
if ($p->getUser() === $user) {
|
||||
$player = $p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$settingName = SessionSettingType::tryFrom('ReadyAtForPlayer' . $player->getScreen());
|
||||
if (!$settingName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var \App\Game\Repository\SessionSettingRepository $settingRepo */
|
||||
$settingRepo = $this->entityManager->getRepository(SessionSetting::class);
|
||||
$setting = $settingRepo->getSetting($session, $settingName, $player);
|
||||
|
||||
if ($setting) {
|
||||
$session->removeSetting($setting);
|
||||
$this->entityManager->remove($setting);
|
||||
} else {
|
||||
$setting = new SessionSetting();
|
||||
$setting->setSession($session);
|
||||
$setting->setPlayer($player);
|
||||
$setting->setName($settingName);
|
||||
$setting->setValue((string)(new \DateTime())->getTimestamp());
|
||||
$this->entityManager->persist($setting);
|
||||
}
|
||||
|
||||
$this->checkAllPlayersReady($session);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$topic = $this->mercureTopicBase . '/game/hub-' . $session->getId();
|
||||
$this->hub->publish(new Update($topic, json_encode(['type' => 'player_ready', 'player' => $player->getScreen(), 'ready' => !$setting])));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function checkAllPlayersReady(Session $session): void
|
||||
{
|
||||
if ($session->getStatus() !== SessionStatus::READY) {
|
||||
return;
|
||||
}
|
||||
|
||||
$players = $session->getPlayers();
|
||||
$numPlayers = $session->getGame()->getNumberOfPlayers();
|
||||
|
||||
if (count($players) < $numPlayers) {
|
||||
return;
|
||||
}
|
||||
|
||||
$readyPlayersCount = 0;
|
||||
$now = new \DateTime();
|
||||
|
||||
/** @var \App\Game\Repository\SessionSettingRepository $settingRepo */
|
||||
$settingRepo = $this->entityManager->getRepository(SessionSetting::class);
|
||||
|
||||
foreach ($players as $player) {
|
||||
$settingName = SessionSettingType::tryFrom('ReadyAtForPlayer' . $player->getScreen());
|
||||
if (!$settingName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$setting = $settingRepo->getSetting($session, $settingName, $player);
|
||||
if ($setting) {
|
||||
$readyAtTimestamp = (int)$setting->getValue();
|
||||
// Check timeout: 1 minute = 60 seconds
|
||||
if (($now->getTimestamp() - $readyAtTimestamp) > 60) {
|
||||
$session->removeSetting($setting);
|
||||
$this->entityManager->remove($setting);
|
||||
} else {
|
||||
$readyPlayersCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($readyPlayersCount === $numPlayers) {
|
||||
$session->setStatus(SessionStatus::PLAYING);
|
||||
$this->entityManager->persist($session);
|
||||
|
||||
// Clean up ready settings
|
||||
foreach ($players as $player) {
|
||||
$settingName = SessionSettingType::tryFrom('ReadyAtForPlayer' . $player->getScreen());
|
||||
if ($settingName) {
|
||||
$setting = $settingRepo->getSetting($session, $settingName, $player);
|
||||
if ($setting) {
|
||||
$session->removeSetting($setting);
|
||||
$this->entityManager->remove($setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$topic = $this->mercureTopicBase . '/game/hub-' . $session->getId();
|
||||
$this->hub->publish(new Update($topic, json_encode(['type' => 'all_ready'])));
|
||||
}
|
||||
}
|
||||
|
||||
public function generateInviteCode(Session $session, UserInterface $user, bool $isAdmin): ?string
|
||||
{
|
||||
// Security check: is user part of this session?
|
||||
|
||||
Reference in New Issue
Block a user