mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
Refactor Container Minigame: Enhance item handling to properly manage takeable items and delegate interactions to the main game handler. Update inventory management to prevent duplicate pickups and streamline object interactions.
Add new scenario: Introduce "CyBOK Heist" with detailed room and object interactions, including clues and challenges related to cybersecurity concepts.
This commit is contained in:
@@ -285,6 +285,13 @@ export class ContainerMinigame extends MinigameScene {
|
||||
handleInteractiveItem(item, itemElement) {
|
||||
console.log('Handling interactive item from container:', item);
|
||||
|
||||
// For takeable items, use takeItem to properly remove from container
|
||||
if (item.takeable) {
|
||||
console.log('Item is takeable, using takeItem method');
|
||||
this.takeItem(item, itemElement);
|
||||
return;
|
||||
}
|
||||
|
||||
// Store container state for return after minigame
|
||||
const containerState = {
|
||||
containerItem: this.containerItem,
|
||||
@@ -298,123 +305,22 @@ export class ContainerMinigame extends MinigameScene {
|
||||
// Close the container minigame first
|
||||
this.complete(false);
|
||||
|
||||
// Route to appropriate minigame based on item type
|
||||
if (item.type === 'notes' && item.readable && item.text) {
|
||||
this.handleNotesItem(item);
|
||||
} else if (item.type === 'text_file' && item.text) {
|
||||
this.handleTextFileItem(item);
|
||||
} else if (item.type === 'phone' && (item.text || item.voice)) {
|
||||
this.handlePhoneItem(item);
|
||||
} else if (item.type === 'workstation') {
|
||||
this.handleWorkstationItem(item);
|
||||
// Create a temporary sprite-like object for the main game handler
|
||||
const tempSprite = {
|
||||
scenarioData: item,
|
||||
name: item.type,
|
||||
objectId: `temp_${Date.now()}`
|
||||
};
|
||||
|
||||
// Delegate to main game's handler for viewing/reading items (notes, phone, files, etc.)
|
||||
if (window.handleObjectInteraction) {
|
||||
window.handleObjectInteraction(tempSprite);
|
||||
} else {
|
||||
console.warn('Unknown interactive item type:', item.type);
|
||||
this.showMessage(`Unknown item type: ${item.type}`, 'error');
|
||||
console.error('handleObjectInteraction not available');
|
||||
window.gameAlert('Could not handle item interaction', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
handleNotesItem(item) {
|
||||
console.log('Handling notes item from container:', item);
|
||||
|
||||
// Start the notes minigame
|
||||
if (window.startNotesMinigame) {
|
||||
// Create a temporary sprite-like object for the notes minigame
|
||||
const tempSprite = {
|
||||
scenarioData: item,
|
||||
name: item.type,
|
||||
objectId: `temp_${Date.now()}`
|
||||
};
|
||||
|
||||
// Start notes minigame with the item's text
|
||||
window.startNotesMinigame(tempSprite, item.text, item.observations);
|
||||
} else {
|
||||
console.error('Notes minigame not available');
|
||||
window.gameAlert('Notes minigame not available', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
handleTextFileItem(item) {
|
||||
console.log('Handling text file item from container:', item);
|
||||
|
||||
// Start the text file minigame
|
||||
if (window.MinigameFramework) {
|
||||
const minigameParams = {
|
||||
title: `Text File - ${item.name || 'Unknown File'}`,
|
||||
fileName: item.name || 'Unknown File',
|
||||
fileContent: item.text,
|
||||
fileType: item.fileType || 'text',
|
||||
observations: item.observations,
|
||||
source: item.source || 'Container',
|
||||
onComplete: (success, result) => {
|
||||
console.log('Text file minigame completed:', success, result);
|
||||
}
|
||||
};
|
||||
|
||||
window.MinigameFramework.startMinigame('text-file', null, minigameParams);
|
||||
} else {
|
||||
console.error('MinigameFramework not available');
|
||||
window.gameAlert('Text file minigame not available', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
handlePhoneItem(item) {
|
||||
console.log('Handling phone item from container:', item);
|
||||
|
||||
// Start the phone messages minigame
|
||||
if (window.MinigameFramework) {
|
||||
const messages = [];
|
||||
|
||||
// Add text message if available
|
||||
if (item.text) {
|
||||
messages.push({
|
||||
type: 'text',
|
||||
sender: item.sender || 'Unknown',
|
||||
text: item.text,
|
||||
timestamp: item.timestamp || 'Unknown time',
|
||||
read: false
|
||||
});
|
||||
}
|
||||
|
||||
// Add voice message if available
|
||||
if (item.voice) {
|
||||
messages.push({
|
||||
type: 'voice',
|
||||
sender: item.sender || 'Unknown',
|
||||
text: item.text || null,
|
||||
voice: item.voice,
|
||||
timestamp: item.timestamp || 'Unknown time',
|
||||
read: false
|
||||
});
|
||||
}
|
||||
|
||||
const minigameParams = {
|
||||
title: item.name || 'Phone Messages',
|
||||
messages: messages,
|
||||
observations: item.observations,
|
||||
onComplete: (success, result) => {
|
||||
console.log('Phone messages minigame completed:', success, result);
|
||||
}
|
||||
};
|
||||
|
||||
window.MinigameFramework.startMinigame('phone-messages', null, minigameParams);
|
||||
} else {
|
||||
console.error('MinigameFramework not available');
|
||||
window.gameAlert('Phone minigame not available', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
handleWorkstationItem(item) {
|
||||
console.log('Handling workstation item from container:', item);
|
||||
|
||||
// Open the crypto workstation
|
||||
if (window.openCryptoWorkstation) {
|
||||
window.openCryptoWorkstation();
|
||||
} else {
|
||||
console.error('Crypto workstation not available');
|
||||
window.gameAlert('Crypto workstation not available', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
addPostitToNotebook() {
|
||||
console.log('Adding postit note to notebook:', this.containerItem.scenarioData.postitNote);
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ export { DustingMinigame } from './dusting/dusting-game.js';
|
||||
export { NotesMinigame, startNotesMinigame, showMissionBrief } from './notes/notes-minigame.js';
|
||||
export { BluetoothScannerMinigame, startBluetoothScannerMinigame } from './bluetooth/bluetooth-scanner-minigame.js';
|
||||
export { BiometricsMinigame, startBiometricsMinigame } from './biometrics/biometrics-minigame.js';
|
||||
export { LockpickSetMinigame, startLockpickSetMinigame } from './lockpick/lockpick-set-minigame.js';
|
||||
export { ContainerMinigame, startContainerMinigame, returnToContainerAfterNotes } from './container/container-minigame.js';
|
||||
export { PhoneMessagesMinigame, returnToPhoneAfterNotes } from './phone/phone-messages-minigame.js';
|
||||
export { PinMinigame, startPinMinigame } from './pin/pin-minigame.js';
|
||||
@@ -51,9 +50,6 @@ import { BluetoothScannerMinigame, startBluetoothScannerMinigame } from './bluet
|
||||
// Import the biometrics minigame
|
||||
import { BiometricsMinigame, startBiometricsMinigame } from './biometrics/biometrics-minigame.js';
|
||||
|
||||
// Import the lockpick set minigame
|
||||
import { LockpickSetMinigame, startLockpickSetMinigame } from './lockpick/lockpick-set-minigame.js';
|
||||
|
||||
// Import the container minigame
|
||||
import { ContainerMinigame, startContainerMinigame, returnToContainerAfterNotes } from './container/container-minigame.js';
|
||||
|
||||
@@ -76,7 +72,6 @@ MinigameFramework.registerScene('dusting', DustingMinigame);
|
||||
MinigameFramework.registerScene('notes', NotesMinigame);
|
||||
MinigameFramework.registerScene('bluetooth-scanner', BluetoothScannerMinigame);
|
||||
MinigameFramework.registerScene('biometrics', BiometricsMinigame);
|
||||
MinigameFramework.registerScene('lockpick-set', LockpickSetMinigame);
|
||||
MinigameFramework.registerScene('container', ContainerMinigame);
|
||||
MinigameFramework.registerScene('phone-messages', PhoneMessagesMinigame);
|
||||
MinigameFramework.registerScene('pin', PinMinigame);
|
||||
@@ -88,7 +83,6 @@ window.startNotesMinigame = startNotesMinigame;
|
||||
window.showMissionBrief = showMissionBrief;
|
||||
window.startBluetoothScannerMinigame = startBluetoothScannerMinigame;
|
||||
window.startBiometricsMinigame = startBiometricsMinigame;
|
||||
window.startLockpickSetMinigame = startLockpickSetMinigame;
|
||||
window.startContainerMinigame = startContainerMinigame;
|
||||
window.returnToContainerAfterNotes = returnToContainerAfterNotes;
|
||||
window.returnToPhoneAfterNotes = returnToPhoneAfterNotes;
|
||||
|
||||
@@ -202,9 +202,10 @@ function getInteractionSpriteKey(obj) {
|
||||
return 'keyway';
|
||||
}
|
||||
|
||||
// Check for containers with contents (even if not locked yet)
|
||||
// Unlocked containers don't need an overlay
|
||||
// (they'll be opened via the container minigame when interacted with)
|
||||
if (data.contents) {
|
||||
return 'keyway';
|
||||
return null; // No overlay for unlocked containers
|
||||
}
|
||||
|
||||
// Check for fingerprint collection
|
||||
@@ -266,9 +267,23 @@ export function handleObjectInteraction(sprite) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle the Crypto Workstation
|
||||
// Handle the Crypto Workstation - pick it up if takeable, or use it if in inventory
|
||||
if (sprite.scenarioData.type === "workstation") {
|
||||
window.openCryptoWorkstation();
|
||||
// If it's in inventory (marked as non-takeable), open it
|
||||
if (!sprite.scenarioData.takeable) {
|
||||
console.log('OPENING WORKSTATION FROM INVENTORY');
|
||||
if (window.openCryptoWorkstation) {
|
||||
window.openCryptoWorkstation();
|
||||
} else {
|
||||
window.gameAlert('Crypto workstation not available', 'error', 'Error', 3000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, try to pick it up and add to inventory
|
||||
console.log('WORKSTATION ADDED TO INVENTORY');
|
||||
addToInventory(sprite);
|
||||
window.gameAlert(`${sprite.scenarioData.name} added to inventory. You can now use it for cryptographic analysis.`, 'success', 'Item Acquired', 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -325,17 +340,20 @@ export function handleObjectInteraction(sprite) {
|
||||
// If it's not in inventory, let it fall through to the takeable logic below
|
||||
}
|
||||
|
||||
// Handle the Lockpick Set - only open minigame if it's already in inventory
|
||||
// Handle the Lockpick Set - pick it up if takeable, or use it if in inventory
|
||||
if (sprite.scenarioData.type === "lockpick" || sprite.scenarioData.type === "lockpickset") {
|
||||
// Check if this is an inventory item (clicked from inventory)
|
||||
const isInventoryItem = sprite.objectId && sprite.objectId.startsWith('inventory_');
|
||||
|
||||
if (isInventoryItem && window.startLockpickSetMinigame) {
|
||||
console.log('Starting lockpick set minigame from inventory');
|
||||
window.startLockpickSetMinigame(sprite);
|
||||
// If it's in inventory (marked as non-takeable), just acknowledge it
|
||||
if (!sprite.scenarioData.takeable) {
|
||||
console.log('LOCKPICK ALREADY IN INVENTORY');
|
||||
window.gameAlert(`${sprite.scenarioData.name} is already in inventory.`, 'info', 'Already Have Item', 3000);
|
||||
return;
|
||||
}
|
||||
// If it's not in inventory, let it fall through to the takeable logic below
|
||||
|
||||
// Otherwise, try to pick it up and add to inventory
|
||||
console.log('LOCKPICK SET ADDED TO INVENTORY');
|
||||
addToInventory(sprite);
|
||||
window.gameAlert(`${sprite.scenarioData.name} added to inventory. You can now use it to pick locks.`, 'success', 'Item Acquired', 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle biometric scanner interaction
|
||||
@@ -387,27 +405,27 @@ export function handleObjectInteraction(sprite) {
|
||||
|
||||
const data = sprite.scenarioData;
|
||||
|
||||
// Check if item is locked
|
||||
if (data.locked === true) {
|
||||
console.log('ITEM LOCKED', data);
|
||||
handleUnlock(sprite, 'item');
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle container items (suitcase, briefcase, etc.)
|
||||
if (data.type === 'suitcase' || data.type === 'briefcase' || data.contents) {
|
||||
// Handle container items (suitcase, briefcase, bags, bins, etc.) - check BEFORE lock check
|
||||
if (data.type === 'suitcase' || data.type === 'briefcase' || data.type === 'bag1' || data.type === 'bin1' || data.contents) {
|
||||
console.log('CONTAINER ITEM INTERACTION', data);
|
||||
|
||||
// Check if container was unlocked but not yet collected
|
||||
if (data.isUnlockedButNotCollected) {
|
||||
console.log('CONTAINER UNLOCKED - LAUNCHING MINIGAME', data);
|
||||
handleContainerInteraction(sprite);
|
||||
// Check if container is locked
|
||||
if (data.locked === true) {
|
||||
console.log('CONTAINER LOCKED - UNLOCK SYSTEM WILL HANDLE', data);
|
||||
handleUnlock(sprite, 'item');
|
||||
return;
|
||||
}
|
||||
|
||||
// If container is still locked, the unlock system will handle it
|
||||
// and set isUnlockedButNotCollected flag
|
||||
console.log('CONTAINER LOCKED - UNLOCK SYSTEM WILL HANDLE', data);
|
||||
// Container is unlocked (or has no lock) - launch the container minigame
|
||||
console.log('CONTAINER UNLOCKED/OPEN - LAUNCHING MINIGAME', data);
|
||||
handleContainerInteraction(sprite);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if item is locked (non-container items)
|
||||
if (data.locked === true) {
|
||||
console.log('ITEM LOCKED', data);
|
||||
handleUnlock(sprite, 'item');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,13 +115,18 @@ export function addToInventory(sprite) {
|
||||
if (window.currentPlayerRoom && rooms[window.currentPlayerRoom] && rooms[window.currentPlayerRoom].objects) {
|
||||
if (rooms[window.currentPlayerRoom].objects[sprite.objectId]) {
|
||||
const roomObj = rooms[window.currentPlayerRoom].objects[sprite.objectId];
|
||||
roomObj.setVisible(false);
|
||||
if (roomObj.setVisible) {
|
||||
roomObj.setVisible(false);
|
||||
}
|
||||
roomObj.active = false;
|
||||
console.log(`Removed object ${sprite.objectId} from room`);
|
||||
}
|
||||
}
|
||||
|
||||
sprite.setVisible(false);
|
||||
// Only call setVisible if it's a Phaser sprite with that method
|
||||
if (sprite.setVisible && typeof sprite.setVisible === 'function') {
|
||||
sprite.setVisible(false);
|
||||
}
|
||||
|
||||
// Special handling for keys - group them together
|
||||
if (sprite.scenarioData.type === 'key') {
|
||||
@@ -156,6 +161,9 @@ export function addToInventory(sprite) {
|
||||
itemImg.name = sprite.name;
|
||||
itemImg.objectId = 'inventory_' + sprite.objectId;
|
||||
|
||||
// Mark as non-takeable once in inventory (so it won't try to be picked up again)
|
||||
itemImg.scenarioData.takeable = false;
|
||||
|
||||
// Add click handler
|
||||
itemImg.addEventListener('click', function() {
|
||||
if (window.handleObjectInteraction) {
|
||||
@@ -186,23 +194,6 @@ export function addToInventory(sprite) {
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// If this is the Fingerprint Kit, automatically open the minigame after adding to inventory
|
||||
if (sprite.scenarioData.type === "fingerprint_kit" && window.startBiometricsMinigame) {
|
||||
// Small delay to ensure the item is fully added to inventory
|
||||
setTimeout(() => {
|
||||
console.log('Auto-opening biometrics minigame after adding to inventory');
|
||||
window.startBiometricsMinigame(itemImg);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// If this is the Lockpick Set, automatically open the minigame after adding to inventory
|
||||
if ((sprite.scenarioData.type === "lockpick" || sprite.scenarioData.type === "lockpickset") && window.startLockpickSetMinigame) {
|
||||
// Small delay to ensure the item is fully added to inventory
|
||||
setTimeout(() => {
|
||||
console.log('Auto-opening lockpick set minigame after adding to inventory');
|
||||
window.startLockpickSetMinigame(itemImg);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// Fingerprint kit is now handled as a minigame when clicked from inventory
|
||||
|
||||
|
||||
@@ -256,6 +256,22 @@
|
||||
{ "ka": "F", "topic": "Definitions and Conceptual Models", "keywords": ["forensic science", "digital (forensic) trace", "conceptual models"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cybok_heist",
|
||||
"title": "CyBOK Heist: Recover the LaTeX Files",
|
||||
"description": "You are a cybersecurity student tasked with recovering the Professor's backup of the CyBOK LaTeX source files for the CyBOK 1.1 release. Time to put your physical security skills to the test!",
|
||||
"difficulty": "beginner",
|
||||
"file": "scenarios/cybok_heist.json",
|
||||
"cybok": [
|
||||
{ "ka": "AC", "topic": "Cryptography", "keywords": ["Base64 encoding", "Password security"] },
|
||||
{ "ka": "AAA", "topic": "Access Control", "keywords": ["Physical locks", "Key-based access", "PIN-based access"] },
|
||||
{ "ka": "WAM", "topic": "Fundamental Concepts", "keywords": ["Knowledge Areas", "CyBOK Framework"] }
|
||||
],
|
||||
"cybok_themes": [
|
||||
{ "ka": "F", "topic": "Artifact Analysis", "keywords": ["Physical security", "Security through obscurity"] },
|
||||
{ "ka": "LR", "topic": "Ethical and Legal", "keywords": ["Educational security testing"] }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "asymmetric_encryption",
|
||||
title: "Asymmetric Encryption with RSA",
|
||||
|
||||
229
scenarios/cybok_heist.json
Normal file
229
scenarios/cybok_heist.json
Normal file
@@ -0,0 +1,229 @@
|
||||
{
|
||||
"scenario_brief": "You are a cyber security student tasked with recovering the Professor's backup of the CyBOK LaTeX source files for the CyBOK 1.1 release. According to legend, the HDD is stored in a safe in the Professor's office. Follow the clues scattered around the department to find the safe code. Time to put your physical security skills to the test! Good luck, and try not to get caught... or expelled.",
|
||||
"endGoal": "Recover the CyBOK LaTeX source HDD",
|
||||
"startRoom": "reception",
|
||||
"rooms": {
|
||||
"reception": {
|
||||
"type": "room_reception",
|
||||
"connections": {
|
||||
"north": "admin_office"
|
||||
},
|
||||
"objects": [
|
||||
{
|
||||
"type": "phone",
|
||||
"name": "Reception Phone",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"voice": "Welcome to the Computer Science Department! The CyBOK backup is in the Professor's safe. The door through to the offices is also locked, so I guess it's safe for now.",
|
||||
"sender": "Receptionist",
|
||||
"timestamp": "Now",
|
||||
"observations": "The reception phone plays back a voicemail message"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Lockpicking Hint Notice",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "DEPARTMENT NOTICE:\n\nMany doors use pin tumbler locks.\n\nTip: Apply tension to the lock while manipulating the pins with a pick.\n\nDo NOT attempt this in front of colleagues.",
|
||||
"observations": "A cautionary notice about lockpicking techniques"
|
||||
},
|
||||
{
|
||||
"type": "pc",
|
||||
"name": "Reception Computer",
|
||||
"takeable": false,
|
||||
"lockType": "password",
|
||||
"requires": "visitor123",
|
||||
"showKeyboard": true,
|
||||
"maxAttempts": 3,
|
||||
"locked": true,
|
||||
"postitNote": "Password: visitor123",
|
||||
"showPostit": true,
|
||||
"observations": "The receptionist's computer with a visible sticky note",
|
||||
"contents": [
|
||||
{
|
||||
"type": "text_file",
|
||||
"name": "Building Directory",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "Reminder: Leaving passwords on sticky notes is a bad security practice. Always use a password manager!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "bag",
|
||||
"name": "Lockpicking Backpack",
|
||||
"contents": [
|
||||
{
|
||||
"type": "lockpick",
|
||||
"name": "Lock Pick Kit",
|
||||
"takeable": true
|
||||
},
|
||||
{
|
||||
"type": "workstation",
|
||||
"name": "Crypto Analysis Station",
|
||||
"takeable": true,
|
||||
"inInventory": true,
|
||||
"observations": "A powerful workstation for cryptographic analysis"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"admin_office": {
|
||||
"type": "room_office",
|
||||
"locked": true,
|
||||
"lockType": "key",
|
||||
"requires": "admin_office_key:25,30,35,40",
|
||||
"difficulty": "medium",
|
||||
"door_sign": "Admin Office - Authorized Personnel Only",
|
||||
"connections": {
|
||||
"north": "professors_office",
|
||||
"south": "reception"
|
||||
},
|
||||
"objects": [
|
||||
{
|
||||
"type": "bin1",
|
||||
"locked": false,
|
||||
|
||||
"name": "Overflowing Trash Bin",
|
||||
"takeable": false,
|
||||
"observations": "A messy trash bin overflowing with papers and debris",
|
||||
"contents": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Crumpled Meeting Notes",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "OVERHEARD CONVERSATION:\n\nAdmin: 'The Professor keeps losing his keys!'\nIT Director: 'Why not put a key backup somewhere secure?'\nAdmin: 'I threw the office key in this bin. He always finds it eventually...'\n\n(Obviously this was a bad plan)",
|
||||
"observations": "Coffee-stained notes recovered from trash"
|
||||
},
|
||||
{
|
||||
"type": "key",
|
||||
"name": "Admin Office Key",
|
||||
"takeable": true,
|
||||
"key_id": "admin_office_key:25,30,35,40",
|
||||
"observations": "A dusty key marked 'ADMIN' - retrieved from garbage. Gross."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "bag1",
|
||||
"name": "Old Messenger Bag",
|
||||
"takeable": false,
|
||||
"observations": "A worn messenger bag sitting in the corner, partially open",
|
||||
"contents": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Safe Code Hint - CyBOK Reference",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "SAFE CODE CLUE #1:\n\nCyBOK 1.1 defines several key domains:\n\n🔐 Security Fundamentals\n🔐 Software Security\n🔐 System Architecture\n🔐 Cryptography\n🔐 Systems Security\n🔐 Network Security\n🔐 Cyber-Physical Systems\n🔐 Cloud Security\n🔐 Distributed Systems\n🔐 Security Operations\n🔐 Organizational & Human Aspects\n\nCount them all...",
|
||||
"observations": "A reference card with CyBOK domains listed"
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Post-It: Professor's Password Hint",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "PASSWORD HINT:\n\nThe Professor's laptop password is:\n'cybok' + (current year)\n\nExample password: cybok2024\nBase64 encoded: Y3lib2syMDI0\n\n(He uses this same password everywhere. Very secure.)",
|
||||
"observations": "A helpful post-it note about password patterns"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "pc",
|
||||
"name": "Admin Computer",
|
||||
"takeable": false,
|
||||
"lockType": "password",
|
||||
"requires": "admin2024",
|
||||
"showKeyboard": true,
|
||||
"maxAttempts": 3,
|
||||
"locked": true,
|
||||
"postitNote": "Password: admin2024",
|
||||
"showPostit": true,
|
||||
"observations": "The admin office computer with a visible sticky note password",
|
||||
"contents": [
|
||||
{
|
||||
"type": "text_file",
|
||||
"name": "Safe Configuration Log",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "SAFE ACCESS LOG:\n\n- Safe Owner: Professor\n- Safe Location: Professor's Office, North wall\n- Lock Type: Digital PIN\n- Code: Based on educational reference\n- Code Hint: 'Think about how many major topics I teach'\n\nThe code is mathematical - count something important to CyBOK."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"professors_office": {
|
||||
"type": "room_ceo",
|
||||
"connections": {
|
||||
"south": "admin_office"
|
||||
},
|
||||
"locked": true,
|
||||
"lockType": "key",
|
||||
"requires": "admin_office_key:25,30,35,40",
|
||||
"difficulty": "medium",
|
||||
"door_sign": "Professor's Office - Do Not Disturb!",
|
||||
"objects": [
|
||||
{
|
||||
"type": "pc",
|
||||
"name": "Professor's Laptop",
|
||||
"takeable": false,
|
||||
"lockType": "password",
|
||||
"requires": "cybok2024",
|
||||
"showKeyboard": true,
|
||||
"maxAttempts": 3,
|
||||
"locked": true,
|
||||
"postitNote": "Y3lib2syMDI0",
|
||||
"showPostit": true,
|
||||
"observations": "The Professor's laptop with a Base64-encoded password on a sticky note. This is a cryptography challenge!",
|
||||
"contents": [
|
||||
{
|
||||
"type": "text_file",
|
||||
"name": "Safe Code Hint - DECODED",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "SAFE CODE DECODED:\n\nI've written the safe code down after forgetting it twice.\n\nThe code represents: How many Knowledge Areas does CyBOK 1.1 have?\n\nQuick count from my syllabus:\n- Foundational Concepts\n- Software Development\n- System Design\n- Cryptography\n- Systems Security\n- Network Security\n- Cyber-Physical\n- Cloud Security\n- Distributed Systems\n- Security Operations\n- Human & Organizational\n\nThat's... 11 areas!\n\nSafe Code: 11"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "CyBOK 1.1 Syllabus",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "CYBOK 1.1 COURSE SYLLABUS\n\nModule Schedule:\n\n1️⃣ Security and Privacy Risks\n2️⃣ Secure Software Development\n3️⃣ System Architecture\n4️⃣ Cryptography Fundamentals\n5️⃣ Systems Security\n6️⃣ Network Security\n7️⃣ Cyber-Physical Systems\n8️⃣ Cloud Security\n9️⃣ Distributed Systems Security\n🔟 Security Operations\n1️⃣1️⃣ Human, Organisational & Regulatory\n\nTotal Coverage: 11 Major Knowledge Areas",
|
||||
"observations": "The Professor's CyBOK course syllabus with all 11 knowledge areas clearly listed"
|
||||
},
|
||||
{
|
||||
"type": "safe",
|
||||
"name": "Wall Safe",
|
||||
"takeable": false,
|
||||
"locked": true,
|
||||
"lockType": "pin",
|
||||
"requires": "11",
|
||||
"difficulty": "hard",
|
||||
"observations": "A secure wall safe with a digital PIN lock",
|
||||
"contents": [
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "CyBOK LaTeX Source HDD",
|
||||
"takeable": true,
|
||||
"readable": true,
|
||||
"text": "🎉 SUCCESS! 🎉\n\nYou have successfully recovered the CyBOK 1.1 LaTeX source files!\n\nContained on this HDD:\n✅ 11 Knowledge Area modules\n✅ 350+ pages of security goodness\n✅ Comprehensive CyBOK framework documentation\n✅ 47 diagrams (the Professor spent way too long on these)\n✅ One very grumpy Professor's entire weekend\n\n🚩 flag{cybok_heist_success}\n\nMission accomplished! Now get out before anyone notices!",
|
||||
"observations": "The legendary CyBOK LaTeX source HDD - your ticket to freedom!"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "notes",
|
||||
"name": "Professor's Desk Calendar",
|
||||
"takeable": false,
|
||||
"readable": true,
|
||||
"text": "PROFESSOR'S CALENDAR:\n\nMonday: CyBOK lecture prep\nTuesday: More CyBOK prep\nWednesday: Even more CyBOK prep\nThursday: Did I mention CyBOK?\nFriday: Coffee and crying about LaTeX formatting\n\nP.S. - Finally got all 11 knowledge areas in the curriculum!",
|
||||
"observations": "A desk calendar showing the Professor's obsession with CyBOK"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user