3 Commits
Author SHA1 Message Date
FrankandClaude Sonnet 5 7f389fbbc2 Reword two confusing mainframe hints
- DecodeMessage::PLAYER_3 ("locked up bash files should be removed to
  lock it up") was awkward and unclear about what it meant.
- The private-communication hint said "contact each other privately",
  which read as any one private message rather than the actual
  requirement of messaging every other agent privately.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 20:15:13 +02:00
FrankandClaude Sonnet 5 ffa2b12786 Fix rm not accepting absolute paths
rm always glued its argument onto the player's current directory, so
typing an absolute path (e.g. sudo rm /var/arrest/handle.sh) built a
garbage path that matched no file and was rejected as "not allowed" -
even with full rm/sudo rights. cd already special-cased a leading '/'
as absolute; rm now does the same.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 20:15:05 +02:00
FrankandClaude Sonnet 5 51c542c7bb Explain the win condition on the ready-up screen
Players had no in-game indication of what actually ends the game
before reaching the terminal itself.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 20:14:55 +02:00
4 changed files with 7 additions and 3 deletions
+1 -1
View File
@@ -132,7 +132,7 @@ final class SendMainframeHintsCommand extends Command
if (!$hasBroadcast || !$hasContactedEveryonePrivately) { if (!$hasBroadcast || !$hasContactedEveryonePrivately) {
if ($elapsed >= self::PRIVATE_CHAT_THRESHOLD_SECONDS) { if ($elapsed >= self::PRIVATE_CHAT_THRESHOLD_SECONDS) {
$this->publishHint($session, 'The AI virus can see all communication if you are using open communication channels. Contact each other privately as well.', $player); $this->publishHint($session, 'The AI virus can see all communication if you are using open communication channels. Make sure you send private messages to all other agents as well, so I know you can.', $player);
return true; return true;
} }
if (!$hasBroadcast && $elapsed >= self::BROADCAST_CHAT_THRESHOLD_SECONDS) { if (!$hasBroadcast && $elapsed >= self::BROADCAST_CHAT_THRESHOLD_SECONDS) {
+1 -1
View File
@@ -6,5 +6,5 @@ enum DecodeMessage: string
{ {
case PLAYER_1 = 'Sudo is now available'; case PLAYER_1 = 'Sudo is now available';
case PLAYER_2 = 'AI virus protects its own files by replacing them'; case PLAYER_2 = 'AI virus protects its own files by replacing them';
case PLAYER_3 = 'The locked up bash files should be removed to lock it up'; case PLAYER_3 = 'The AI virus is having a lock on certain files. Remove these to disable it.';
} }
+3 -1
View File
@@ -240,7 +240,9 @@ class GameResponseService
} }
$filename = $messagePart[1]; $filename = $messagePart[1];
$fullPath = ($pwd === '/' ? '' : $pwd) . '/' . $filename; $fullPath = str_starts_with($filename, '/')
? $filename
: ($pwd === '/' ? '' : $pwd) . '/' . $filename;
if(!$this->isAllowedToRemove($fullPath, $player, $sudo)) if(!$this->isAllowedToRemove($fullPath, $player, $sudo))
return ['result' => ['You are not allowed to remove this file.']]; return ['result' => ['You are not allowed to remove this file.']];
+2
View File
@@ -13,6 +13,8 @@
<h4>{{ session.game.name }}</h4> <h4>{{ session.game.name }}</h4>
<p>Welcome to the game! Please wait for all players to join and signal they are ready to start.</p> <p>Welcome to the game! Please wait for all players to join and signal they are ready to start.</p>
<p>This game will end when you disable the virus by having its source files deleted from the server.</p>
<div class="game-info"> <div class="game-info">
Please keep the following things in mind: Please keep the following things in mind:
<ul> <ul>