diff --git a/assets/rooms/room_reception.json b/assets/rooms/room_reception.json index 265cd2b..32f41d0 100644 --- a/assets/rooms/room_reception.json +++ b/assets/rooms/room_reception.json @@ -244,17 +244,6 @@ "width":48, "x":380, "y":166 - }, - { - "height":48, - "id":13, - "name":"bluetooth_spoofer", - "rotation":0, - "type":"", - "visible":true, - "width":48, - "x":320, - "y":166 } ], "opacity":1, @@ -264,7 +253,7 @@ "y":0 }], "nextlayerid":12, - "nextobjectid":14, + "nextobjectid":13, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.11.0", diff --git a/assets/scenarios/ceo_exfil.json b/assets/scenarios/ceo_exfil.json index af9b60f..ea4b4ba 100644 --- a/assets/scenarios/ceo_exfil.json +++ b/assets/scenarios/ceo_exfil.json @@ -53,14 +53,6 @@ "takeable": true, "inInventory": true, "observations": "A powerful workstation for cryptographic analysis" - }, - { - "type": "bluetooth_spoofer", - "name": "Bluetooth Spoofer", - "takeable": true, - "observations": "A specialized device that can mimic Bluetooth signals from other devices", - "canSpoofBluetooth": true, - "mac": "00:11:22:33:44:55" } ] }, diff --git a/index.html b/index.html index b04c5f1..c7dfd2c 100644 --- a/index.html +++ b/index.html @@ -623,32 +623,6 @@ display: none; } - /* Bluetooth Pairing Button */ - .bluetooth-pair-button { - display: inline-block; - margin-top: 8px; - padding: 5px 10px; - background-color: #9b59b6; - color: white; - border: none; - border-radius: 3px; - font-size: 12px; - cursor: pointer; - transition: background-color 0.2s; - } - - .bluetooth-pair-button:hover { - background-color: #8e44ad; - } - - .bluetooth-pair-button.paired { - background-color: #27ae60; - } - - .bluetooth-pair-button.paired:hover { - background-color: #219653; - } - /* Bluetooth Unlock Button */ .bluetooth-unlock-button { display: inline-block; @@ -676,7 +650,7 @@ .bluetooth-device:hover .bluetooth-device-name, .bluetooth-device:hover .bluetooth-device-details, .bluetooth-device:hover .bluetooth-device-timestamp, - .bluetooth-device:hover .bluetooth-pair-button { + .bluetooth-device:hover { pointer-events: auto; } @@ -1528,7 +1502,6 @@ this.load.image('book', 'assets/objects/book.png'); this.load.image('workstation', 'assets/objects/workstation.png'); this.load.image('bluetooth_scanner', 'assets/objects/bluetooth_scanner.png'); - this.load.image('bluetooth_spoofer', 'assets/objects/bluetooth_spoofer.png'); this.load.image('tablet', 'assets/objects/tablet.png'); this.load.image('fingerprint_kit', 'assets/objects/fingerprint_kit.png'); this.load.image('lockpick', 'assets/objects/lockpick.png'); @@ -3401,14 +3374,6 @@ case 'bluetooth': if (lockable.scenarioData?.locked) { - // Try to spoof the Bluetooth device - const spoofResult = spoofBluetoothDevice(lockable); - - if (spoofResult) { - // If spoofing was successful, unlock the target - unlockTarget(lockable, type, lockable.layer); - } - // Allow the item to be picked up even if locked if (type === 'item' && lockable.scenarioData?.takeable) { // Check if the item is already in the inventory before adding it @@ -3746,102 +3711,6 @@ } } - function spoofBluetoothDevice(target) { - // Find spoofer in inventory - const spoofer = inventory.items.find(item => - item.scenarioData?.type === "bluetooth_spoofer" - ); - - if (!spoofer) { - gameAlert("You need a Bluetooth spoofer to unlock this device.", 'warning', 'Bluetooth Spoofer Required', 4000); - return false; - } - - // Check if target is in inventory or in the environment - const isInventoryItem = inventory.items.includes(target); - - // If it's an environment object, check distance - if (!isInventoryItem) { - // Calculate distance between player and target device - const distance = Phaser.Math.Distance.Between( - player.x, player.y, - target.x, target.y - ); - - debugLog('BLUETOOTH SPOOF ATTEMPT', { - deviceName: target.scenarioData?.name, - deviceMac: target.scenarioData?.mac, - spooferMac: spoofer.scenarioData?.macPaired, - distance: Math.round(distance), - isInventoryItem: false - }, 2); - - // Check if player is within range - if (distance > BLUETOOTH_SCAN_RANGE) { - gameAlert("Too far from device to establish Bluetooth connection.", 'error', 'Connection Failed', 3000); - return false; - } - } else { - // Log attempt for inventory item - debugLog('BLUETOOTH SPOOF ATTEMPT', { - deviceName: target.scenarioData?.name, - deviceMac: target.scenarioData?.mac, - spooferMac: spoofer.scenarioData?.macPaired, - isInventoryItem: true, - distance: 0 // Inventory items are always at distance 0 - }, 2); - } - - // Normalize MAC addresses for comparison - const targetMac = target.scenarioData?.mac?.toLowerCase() || ""; - const spooferMac = spoofer.scenarioData?.macPaired?.toLowerCase() || ""; - - // Check if the spoofer has the correct MAC address - if (spooferMac && targetMac && spooferMac === targetMac) { - debugLog('BLUETOOTH SPOOF SUCCESS', { - deviceName: target.scenarioData?.name, - mac: target.scenarioData?.mac, - isInventoryItem: isInventoryItem - }, 1); - - // Unlock the device - target.scenarioData.locked = false; - - // If it's an inventory item, update its appearance if needed - if (isInventoryItem) { - // Update the item's texture if it has an unlocked version - if (target.scenarioData?.unlockedTexture) { - target.setTexture(target.scenarioData.unlockedTexture); - } - - // If the item has contents, allow them to be collected - if (target.scenarioData?.contents) { - target.scenarioData.isUnlockedButNotCollected = true; - collectContainerContents(target); - - // Remove the device from the bluetoothDevices array - const deviceIndex = bluetoothDevices.findIndex(device => - device.mac.toLowerCase() === targetMac && device.inInventory - ); - - if (deviceIndex !== -1) { - bluetoothDevices.splice(deviceIndex, 1); - } - } - } - - gameAlert("Bluetooth connection spoofed. Device unlocked.", 'success', 'Spoofing Successful', 4000); - - // Update the Bluetooth panel to reflect the unlocked state - updateBluetoothPanel(); - - return true; - } else { - gameAlert("Bluetooth spoofer MAC address doesn't match the target device.", 'error', 'Spoofing Failed', 4000); - return false; - } - } - // Add helper function to generate fingerprint data function generateFingerprintData(item) { // For original samples from items, we use the item's data @@ -6047,34 +5916,7 @@ deviceContent += ``; deviceContent += `
MAC: ${device.mac}\n${device.details}
`; - // Add pairing button only if device is nearby and player has a Bluetooth spoofer - if (device.nearby) { - // Check if player has a Bluetooth spoofer in inventory - const spoofer = inventory.items.find(item => - item.scenarioData?.type === "bluetooth_spoofer" - ); - - if (spoofer) { - // Check if this device is already paired with (MAC address programmed to spoofer) - const isPaired = spoofer.scenarioData?.macPaired === device.mac; - const buttonClass = isPaired ? 'bluetooth-pair-button paired' : 'bluetooth-pair-button'; - const buttonText = isPaired ? 'MAC Address Paired' : 'Pair MAC Address'; - - deviceContent += ``; - - // If device is paired, add a hint about using it to unlock - if (isPaired) { - deviceContent += `
- You can now use this MAC address to unlock matching Bluetooth locks -
`; - - // If this is an inventory item, add an unlock button - if (device.inInventory) { - deviceContent += ``; - } - } - } - } + deviceContent += `
Last seen: ${formattedDate} ${formattedTime}
`; @@ -6082,11 +5924,6 @@ // Toggle expanded state when clicked deviceElement.addEventListener('click', (event) => { - // Don't toggle if clicking on the pair button - if (event.target.classList.contains('bluetooth-pair-button') || - event.target.closest('.bluetooth-pair-button')) { - return; - } deviceElement.classList.toggle('expanded'); @@ -6146,49 +5983,6 @@ updateBluetoothPanel(); }); }); - - // Set up global event delegation for the pairing buttons - document.addEventListener('click', function(event) { - if (event.target.classList.contains('bluetooth-pair-button')) { - const mac = event.target.dataset.mac; - console.log('Attempting to pair with device MAC:', mac); - - // Find the device in our list - const device = bluetoothDevices.find(device => device.mac === mac); - console.log('Found device:', device); - - if (device) { - attemptPairingWithDevice(mac); - } else { - gameAlert("Device not found in Bluetooth devices list.", 'error', 'Pairing Failed', 3000); - } - - event.stopPropagation(); // Prevent device expanding/collapsing when clicking the button - } - - // Handle unlock button clicks - if (event.target.classList.contains('bluetooth-unlock-button')) { - const mac = event.target.dataset.mac; - console.log('Attempting to unlock device MAC:', mac); - - // Find the inventory item with this MAC address - const item = inventory.items.find(item => - item.scenarioData?.mac === mac && - item.scenarioData?.lockType === "bluetooth" && - item.scenarioData?.locked - ); - console.log('Found inventory item:', item); - - if (item) { - unlockInventoryDeviceByMac(mac); - } else { - gameAlert("Device not found in inventory.", 'error', 'Unlock Failed', 3000); - } - - event.stopPropagation(); // Prevent device expanding/collapsing when clicking the button - } - }); - // Initialize Bluetooth count updateBluetoothCount(); } @@ -6214,323 +6008,6 @@ } console.log('Found inventory item to unlock:', item); - - // Attempt to spoof the device - const success = spoofBluetoothDevice(item); - - // If successful, remove the device from the bluetoothDevices array - if (success) { - // Find the device in the bluetoothDevices array - const deviceIndex = bluetoothDevices.findIndex(device => - device.mac.toLowerCase() === normalizedMac && device.inInventory - ); - - // Remove it if found - if (deviceIndex !== -1) { - console.log('Removing unlocked device from bluetoothDevices array'); - bluetoothDevices.splice(deviceIndex, 1); - - // Update the Bluetooth panel to reflect the changes - updateBluetoothPanel(); - } - } - } - - // Function to handle pairing attempts with Bluetooth devices - function attemptPairingWithDevice(mac) { - console.log('Attempting to pair with MAC:', mac); - console.log('All Bluetooth devices:', bluetoothDevices); - - // Find the device in our list (case-insensitive comparison) - const normalizedMac = mac.toLowerCase(); - const device = bluetoothDevices.find(device => device.mac.toLowerCase() === normalizedMac); - - if (!device) { - console.error('Device not found with MAC:', mac); - gameAlert("Device not found.", 'error', 'Pairing Failed', 3000); - return; - } - - console.log('Found device for pairing:', device); - - // Find spoofer in inventory - const spoofer = inventory.items.find(item => - item.scenarioData?.type === "bluetooth_spoofer" - ); - - if (!spoofer) { - gameAlert("You need a Bluetooth spoofer to pair with this device.", 'warning', 'Spoofer Required', 3000); - return; - } - - // Check if player is close enough to the device (using the proximity from real-time scanning) - // Skip proximity check for inventory items - if (!device.nearby && !device.inInventory) { - gameAlert("You need to be closer to the device to pair with it.", 'warning', 'Too Far', 3000); - return; - } - - // Check if this device is already paired with - if (spoofer.scenarioData?.macPaired && spoofer.scenarioData.macPaired.toLowerCase() === normalizedMac) { - gameAlert(`This device's MAC address (${mac}) is already programmed into your spoofer.`, 'info', 'Already Paired', 3000); - return; - } - - // Launch the MAC address pairing minigame - startBluetoothPairingMinigame(device); - } - - // Bluetooth MAC Address Pairing Minigame - function startBluetoothPairingMinigame(device) { - // Create minigame container - const minigameContainer = document.createElement('div'); - minigameContainer.style.cssText = ` - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - width: 60%; - height: 60%; - background: rgba(0, 0, 0, 0.9); - border: 1px solid #444; - z-index: 1000; - padding: 20px; - border-radius: 5px; - display: flex; - flex-direction: column; - align-items: center; - `; - - // Add instructions - const instructions = document.createElement('div'); - instructions.innerHTML = ` -

MAC Address Spoofing

-

- Align the signal frequencies to match the target device's MAC address pattern.
- Drag the sliders to adjust each frequency band until all segments turn green.
- When all segments are aligned, the MAC address will be successfully paired. -

- `; - instructions.style.cssText = ` - position: absolute; - top: 10px; - left: 50%; - transform: translateX(-50%); - width: 90%; - `; - - // Create device info display - const deviceInfo = document.createElement('div'); - deviceInfo.innerHTML = ` -
Target Device: ${device.name}
-
MAC Address: ${device.mac}
- `; - deviceInfo.style.cssText = ` - margin-top: 70px; - text-align: center; - width: 100%; - `; - - // Create signal visualization - const signalVisualization = document.createElement('div'); - signalVisualization.style.cssText = ` - width: 90%; - height: 120px; - background: #111; - border: 1px solid #333; - margin: 20px 0; - position: relative; - overflow: hidden; - `; - - // Create frequency bands (6 for MAC address octets) - const frequencyBands = document.createElement('div'); - frequencyBands.style.cssText = ` - display: flex; - width: 90%; - justify-content: space-between; - margin-bottom: 30px; - `; - - // Create sliders for each frequency band - const sliders = []; - const targetValues = []; - const currentValues = []; - const segments = []; - - // Parse MAC address to generate target values - const macParts = device.mac.split(':'); - - for (let i = 0; i < 6; i++) { - // Convert hex to decimal for target value (0-100 range) - const hexValue = macParts[i] || '00'; - const decimalValue = parseInt(hexValue, 16); - const targetValue = Math.round((decimalValue / 255) * 100); - targetValues.push(targetValue); - - // Start with random values - const initialValue = Math.floor(Math.random() * 100); - currentValues.push(initialValue); - - // Create slider container - const sliderContainer = document.createElement('div'); - sliderContainer.style.cssText = ` - display: flex; - flex-direction: column; - align-items: center; - width: 40px; - `; - - // Create slider - const slider = document.createElement('input'); - slider.type = 'range'; - slider.min = 0; - slider.max = 100; - slider.value = initialValue; - slider.style.cssText = ` - width: 120px; - transform: rotate(-90deg); - margin: 50px 0; - `; - - // Create segment in visualization - const segment = document.createElement('div'); - segment.style.cssText = ` - position: absolute; - bottom: 0; - left: ${i * (100/6)}%; - width: ${100/6}%; - height: ${initialValue}%; - background: #cc5500; - transition: height 0.2s, background-color 0.3s; - `; - segments.push(segment); - signalVisualization.appendChild(segment); - - // Create label - const label = document.createElement('div'); - label.textContent = hexValue.toUpperCase(); - label.style.cssText = ` - color: #aaa; - font-size: 12px; - margin-top: 10px; - `; - - // Add event listener to slider - slider.addEventListener('input', (e) => { - const value = parseInt(e.target.value); - currentValues[i] = value; - segment.style.height = `${value}%`; - - // Check if this segment is aligned correctly - const isAligned = Math.abs(value - targetValues[i]) <= 5; - segment.style.backgroundColor = isAligned ? '#00cc00' : '#cc5500'; - - // Check if all segments are aligned - checkCompletion(); - }); - - sliders.push(slider); - sliderContainer.appendChild(slider); - sliderContainer.appendChild(label); - frequencyBands.appendChild(sliderContainer); - } - - // Create status message - const statusMessage = document.createElement('div'); - statusMessage.style.cssText = ` - color: #aaa; - font-size: 14px; - margin-top: 15px; - text-align: center; - `; - statusMessage.textContent = 'Align all frequency bands...'; - - // Create cancel button - const cancelButton = document.createElement('button'); - cancelButton.textContent = 'Cancel'; - cancelButton.style.cssText = ` - background-color: #555; - color: white; - border: none; - border-radius: 3px; - padding: 8px 15px; - margin-top: 20px; - cursor: pointer; - font-size: 14px; - `; - cancelButton.addEventListener('click', () => { - endMinigame(false); - }); - - // Add all elements to container - minigameContainer.appendChild(instructions); - minigameContainer.appendChild(deviceInfo); - minigameContainer.appendChild(signalVisualization); - minigameContainer.appendChild(frequencyBands); - minigameContainer.appendChild(statusMessage); - minigameContainer.appendChild(cancelButton); - - // Add container to document - document.body.appendChild(minigameContainer); - - // Function to check if all segments are aligned - function checkCompletion() { - const allAligned = currentValues.every((value, index) => - Math.abs(value - targetValues[index]) <= 5 - ); - - if (allAligned) { - statusMessage.textContent = 'MAC Address pattern matched!'; - statusMessage.style.color = '#00cc00'; - - // Add success animation - segments.forEach(segment => { - segment.style.backgroundColor = '#00cc00'; - }); - - // End minigame with success after a short delay - setTimeout(() => { - endMinigame(true); - }, 1500); - } - } - - // Function to end minigame - function endMinigame(success) { - // Remove minigame container - document.body.removeChild(minigameContainer); - - // Call callback with result - if (success) { - // Find spoofer in inventory - const spoofer = inventory.items.find(item => - item.scenarioData?.type === "bluetooth_spoofer" - ); - - if (spoofer) { - console.log('Programming spoofer with MAC address:', device.mac); - - // Program the spoofer with the target MAC address - spoofer.scenarioData.macPaired = device.mac; - - // Show success message - gameAlert(`Successfully programmed spoofer with MAC address: ${device.mac}`, 'success', 'Pairing Complete', 4000); - debugLog('BLUETOOTH SPOOFER PROGRAMMED', { - deviceName: device.name, - deviceMac: device.mac - }, 1); - - // Update the UI to show the pairing was successful - device.paired = true; - - // Update the Bluetooth panel to reflect the pairing - updateBluetoothPanel(); - } - } else { - gameAlert('Pairing canceled.', 'info', 'Pairing Canceled', 3000); - } - } } // Biometrics Panel System