Randomize decoy usernames and which rapports carry coded messages
Decoy names in /var/home and verifyCodes.txt were a hardcoded 4-name list (Luke, Charles, William, Peter), so a real player registering under one of those names would collide with it. Now each session picks 6 decoys from a pool of 10, excluding any name already taken by a real player, and stores the pick as a session setting. Likewise the 3 "special report" rapports that get coded messages were always Doyle, Vega and Lennox. Each session now randomly assigns 3 of the 20 rapports to that role, and the win screen / mainframe-help message reference whichever agents were actually picked instead of the hardcoded names. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,37 @@ final class GameDashboardService
|
||||
private const LOBBY_MESSAGE_MAX_LENGTH = 500;
|
||||
private const LOBBY_CHAT_GRACE_PERIOD_SECONDS = 3600;
|
||||
|
||||
private const DECOY_USERNAME_POOL = [
|
||||
'Luke', 'Charles', 'William', 'Peter', 'Simon',
|
||||
'Oliver', 'Daniel', 'Thomas', 'Edward', 'George',
|
||||
];
|
||||
private const DECOY_USERNAME_COUNT = 6;
|
||||
|
||||
// File => cover-identity agent name, mirrors assets/game1/filesystem/var/rapports/index.txt
|
||||
private const RAPPORT_AGENTS = [
|
||||
'/var/rapports/095_07-14.txt' => 'Mason',
|
||||
'/var/rapports/007_19-52.txt' => 'Harper',
|
||||
'/var/rapports/083_25-39.txt' => 'Doyle',
|
||||
'/var/rapports/019_31-11.txt' => 'Vega',
|
||||
'/var/rapports/075_46-77.txt' => 'Ellis',
|
||||
'/var/rapports/031_53-28.txt' => 'Navarro',
|
||||
'/var/rapports/072_61-05.txt' => 'Carter',
|
||||
'/var/rapports/064_72-90.txt' => 'Quinn',
|
||||
'/var/rapports/091_81-33.txt' => 'Raines',
|
||||
'/var/rapports/079_89-47.txt' => 'Dalton',
|
||||
'/var/rapports/098_92-14.txt' => 'Langston',
|
||||
'/var/rapports/012_94-31.txt' => 'Donovan',
|
||||
'/var/rapports/016_98-07.txt' => 'Fletcher',
|
||||
'/var/rapports/087_102-45.txt' => 'Sanders',
|
||||
'/var/rapports/094_110-19.txt' => 'Mitchell',
|
||||
'/var/rapports/063_117-56.txt' => 'O’Connor',
|
||||
'/var/rapports/017_123-88.txt' => 'Holloway',
|
||||
'/var/rapports/011_130-62.txt' => 'Lennox',
|
||||
'/var/rapports/093_138-24.txt' => 'Bennett',
|
||||
'/var/rapports/001_145-93.txt' => 'Carver',
|
||||
];
|
||||
private const SPECIAL_REPORT_COUNT = 3;
|
||||
|
||||
public function __construct(
|
||||
private readonly GameRepository $gameRepository,
|
||||
private readonly SessionRepository $sessionRepository,
|
||||
@@ -257,6 +288,50 @@ final class GameDashboardService
|
||||
}
|
||||
}
|
||||
|
||||
// Picks decoy usernames for /var/home and verifyCodes.txt, excluding any name
|
||||
// already taken by a real player in this session so they can never collide.
|
||||
private function initializeDecoyUsernames(Session $session): void
|
||||
{
|
||||
$realUsernames = array_map(
|
||||
static fn (Player $p) => $p->getUser()->getUsername(),
|
||||
$session->getPlayers()->toArray()
|
||||
);
|
||||
|
||||
$availableDecoys = array_values(array_diff(self::DECOY_USERNAME_POOL, $realUsernames));
|
||||
shuffle($availableDecoys);
|
||||
$selected = array_slice($availableDecoys, 0, self::DECOY_USERNAME_COUNT);
|
||||
|
||||
$setting = new SessionSetting();
|
||||
$setting->setSession($session);
|
||||
$setting->setName(SessionSettingType::DECOY_USERNAMES);
|
||||
$setting->setValue(json_encode($selected));
|
||||
$this->entityManager->persist($setting);
|
||||
}
|
||||
|
||||
// Picks which 3 rapports carry the coded messages this session, so it isn't
|
||||
// always the same Doyle/Vega/Lennox trio.
|
||||
private function initializeSpecialReportAssignments(Session $session): void
|
||||
{
|
||||
$files = array_keys(self::RAPPORT_AGENTS);
|
||||
shuffle($files);
|
||||
$chosen = array_slice($files, 0, self::SPECIAL_REPORT_COUNT);
|
||||
|
||||
$assignments = [];
|
||||
foreach ($chosen as $index => $file) {
|
||||
$assignments[] = [
|
||||
'file' => $file,
|
||||
'agent' => self::RAPPORT_AGENTS[$file],
|
||||
'digit' => $index + 1,
|
||||
];
|
||||
}
|
||||
|
||||
$setting = new SessionSetting();
|
||||
$setting->setSession($session);
|
||||
$setting->setName(SessionSettingType::SPECIAL_REPORT_ASSIGNMENTS);
|
||||
$setting->setValue(json_encode($assignments));
|
||||
$this->entityManager->persist($setting);
|
||||
}
|
||||
|
||||
public function startSession(Session $session): bool
|
||||
{
|
||||
if ($session->getStatus() !== SessionStatus::CREATED) {
|
||||
@@ -286,6 +361,9 @@ final class GameDashboardService
|
||||
$this->entityManager->persist($player);
|
||||
}
|
||||
|
||||
$this->initializeDecoyUsernames($session);
|
||||
$this->initializeSpecialReportAssignments($session);
|
||||
|
||||
$session->setStatus(SessionStatus::READY);
|
||||
$this->entityManager->persist($session);
|
||||
$this->entityManager->flush();
|
||||
|
||||
Reference in New Issue
Block a user