sessionRepository->findBy(['status' => SessionStatus::PLAYING]); $hintsSent = 0; foreach ($sessions as $session) { if ($this->checkContactHint($session)) { $hintsSent++; } } $output->writeln(sprintf('Checked %d running session(s), sent %d hint(s).', count($sessions), $hintsSent)); return Command::SUCCESS; } /** * "Get in touch" hint: if 5 minutes into the game the players haven't messaged * everyone (a private message to each other player, plus one broadcast), nudge them. * Repeats every run of this command for as long as the condition still holds. */ private function checkContactHint(Session $session): bool { $elapsed = $this->getElapsedPlayingSeconds($session); if ($elapsed === null || $elapsed < 300) { return false; } if ($this->allPlayersHaveContactedEveryone($session)) { return false; } $this->publishHint($session, 'Get in contact with your fellow agents to work together on defeating this AI virus.'); return true; } private function getElapsedPlayingSeconds(Session $session): ?int { $timer = $session->getTimer(); if ($timer === null) { return null; } $totalTimeSetting = $this->gameSettingRepository->getSetting($session->getGame(), GameSettingType::TOTAL_TIME); $totalTime = $totalTimeSetting ? (int)$totalTimeSetting->getValue() : self::DEFAULT_TOTAL_TIME; $startedAt = $timer - $totalTime; return time() - $startedAt; } private function allPlayersHaveContactedEveryone(Session $session): bool { $players = $session->getPlayers(); $screens = []; foreach ($players as $player) { if ($player->getScreen() === null) { return false; } $screens[] = $player->getScreen(); } foreach ($players as $player) { $screen = $player->getScreen(); $trackingSettingName = SessionSettingType::tryFrom('ChatTrackingForPlayer' . $screen); if (!$trackingSettingName) { return false; } $setting = $this->sessionSettingRepository->getSetting($session, $trackingSettingName, $player); $tracking = $setting ? (json_decode($setting->getValue() ?? '[]', true) ?? []) : []; if (!in_array(0, $tracking)) { return false; } foreach ($screens as $otherScreen) { if ($otherScreen !== $screen && !in_array($otherScreen, $tracking)) { return false; } } } return true; } private function publishHint(Session $session, string $message): void { $topic = '/game/hub/' . $session->getId(); try { $this->hub->publish(new Update($topic, json_encode([0, $message, 'hint']))); } catch (\Exception $e) { // Mercure might be down } } }