diff --git a/assets/rooms/room_office.json b/assets/rooms/room_office.json index f94e3ec..b79f272 100644 --- a/assets/rooms/room_office.json +++ b/assets/rooms/room_office.json @@ -338,6 +338,17 @@ "width": 48, "x": 340, "y": 144 + }, + { + "height": 48, + "id": 17, + "name": "lockpick", + "rotation": 0, + "type": "", + "visible": true, + "width": 48, + "x": 330, + "y": 144 } @@ -349,7 +360,7 @@ "y":0 }], "nextlayerid":12, - "nextobjectid":16, + "nextobjectid":18, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.11.0", diff --git a/assets/rooms/room_reception.json b/assets/rooms/room_reception.json index eb88f44..265cd2b 100644 --- a/assets/rooms/room_reception.json +++ b/assets/rooms/room_reception.json @@ -244,6 +244,17 @@ "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, @@ -253,7 +264,7 @@ "y":0 }], "nextlayerid":12, - "nextobjectid":11, + "nextobjectid":14, "orientation":"orthogonal", "renderorder":"right-down", "tiledversion":"1.11.0", diff --git a/assets/scenarios/ceo_exfil.json b/assets/scenarios/ceo_exfil.json index d91af48..2a77d16 100644 --- a/assets/scenarios/ceo_exfil.json +++ b/assets/scenarios/ceo_exfil.json @@ -45,7 +45,14 @@ "name": "Bluetooth Scanner", "takeable": true, "observations": "A device for detecting nearby Bluetooth signals", - "canScanBluetooth": true, + "canScanBluetooth": true + }, + { + "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" } ] @@ -141,6 +148,12 @@ "readable": true, "text": "Large data transfers detected to unknown external IPs - All originating from CEO's office", "observations": "Suspicious network activity logs" + }, + { + "type": "lockpick", + "name": "Lock Pick Kit", + "takeable": true, + "observations": "A professional lock picking kit with various picks and tension wrenches" } ] }, @@ -153,6 +166,7 @@ "locked": true, "lockType": "key", "requires": "ceo_office_key", + "difficulty": "easy", "objects": [ { "type": "pc", @@ -167,6 +181,7 @@ "locked": true, "lockType": "key", "requires": "briefcase_key", + "difficulty": "medium", "observations": "An expensive leather briefcase with a sturdy lock", "contents": [ { @@ -212,6 +227,7 @@ "locked": true, "lockType": "key", "requires": "safe_key", + "difficulty": "hard", "observations": "A well-hidden wall safe behind a painting", "contents": [ { diff --git a/assets/sounds/lockpick_binding.mp3 b/assets/sounds/lockpick_binding.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_binding.mp3 differ diff --git a/assets/sounds/lockpick_click.mp3 b/assets/sounds/lockpick_click.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_click.mp3 differ diff --git a/assets/sounds/lockpick_overtension.mp3 b/assets/sounds/lockpick_overtension.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_overtension.mp3 differ diff --git a/assets/sounds/lockpick_reset.mp3 b/assets/sounds/lockpick_reset.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_reset.mp3 differ diff --git a/assets/sounds/lockpick_set.mp3 b/assets/sounds/lockpick_set.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_set.mp3 differ diff --git a/assets/sounds/lockpick_success.mp3 b/assets/sounds/lockpick_success.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_success.mp3 differ diff --git a/assets/sounds/lockpick_tension.mp3 b/assets/sounds/lockpick_tension.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_tension.mp3 differ diff --git a/assets/sounds/lockpick_wrong.mp3 b/assets/sounds/lockpick_wrong.mp3 new file mode 100644 index 0000000..bdf479b Binary files /dev/null and b/assets/sounds/lockpick_wrong.mp3 differ diff --git a/index.html b/index.html index 606f074..252a6d8 100644 --- a/index.html +++ b/index.html @@ -27,6 +27,284 @@ display: none; } + /* Notification System */ + #notification-container { + position: fixed; + top: 20px; + right: 20px; + width: 300px; + max-width: 80%; + z-index: 2000; + font-family: Arial, sans-serif; + pointer-events: none; + } + + .notification { + background-color: rgba(0, 0, 0, 0.8); + color: white; + padding: 15px 20px; + margin-bottom: 10px; + border-radius: 5px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + transition: all 0.3s ease; + opacity: 0; + transform: translateY(-20px); + pointer-events: auto; + position: relative; + overflow: hidden; + } + + .notification.show { + opacity: 1; + transform: translateY(0); + } + + .notification.info { + border-left: 4px solid #3498db; + } + + .notification.success { + border-left: 4px solid #2ecc71; + } + + .notification.warning { + border-left: 4px solid #f39c12; + } + + .notification.error { + border-left: 4px solid #e74c3c; + } + + .notification-title { + font-weight: bold; + margin-bottom: 5px; + font-size: 16px; + } + + .notification-message { + font-size: 14px; + line-height: 1.4; + } + + .notification-close { + position: absolute; + top: 10px; + right: 10px; + cursor: pointer; + font-size: 16px; + color: #aaa; + } + + .notification-close:hover { + color: white; + } + + .notification-progress { + position: absolute; + bottom: 0; + left: 0; + height: 3px; + background-color: rgba(255, 255, 255, 0.5); + width: 100%; + } + + /* Notes Panel */ + #notes-panel { + position: fixed; + bottom: 80px; + right: 20px; + width: 350px; + max-height: 500px; + background-color: rgba(0, 0, 0, 0.9); + color: white; + border-radius: 5px; + box-shadow: 0 2px 15px rgba(0, 0, 0, 0.5); + z-index: 1999; + font-family: Arial, sans-serif; + display: none; + overflow: hidden; + transition: all 0.3s ease; + border: 1px solid #444; + } + + #notes-header { + background-color: #222; + padding: 12px 15px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #444; + } + + #notes-title { + font-weight: bold; + font-size: 18px; + color: #3498db; + } + + #notes-close { + cursor: pointer; + font-size: 18px; + color: #aaa; + transition: color 0.2s; + } + + #notes-close:hover { + color: white; + } + + #notes-search-container { + padding: 10px 15px; + background-color: #333; + border-bottom: 1px solid #444; + } + + #notes-search { + width: 100%; + padding: 8px 10px; + border: none; + border-radius: 3px; + background-color: #222; + color: white; + font-size: 14px; + } + + #notes-search:focus { + outline: none; + box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.5); + } + + #notes-categories { + display: flex; + padding: 5px 15px; + background-color: #2c2c2c; + border-bottom: 1px solid #444; + } + + .notes-category { + padding: 5px 10px; + margin-right: 5px; + cursor: pointer; + border-radius: 3px; + font-size: 12px; + transition: all 0.2s; + } + + .notes-category.active { + background-color: #3498db; + color: white; + } + + .notes-category:hover:not(.active) { + background-color: #444; + } + + #notes-content { + padding: 15px; + overflow-y: auto; + max-height: 350px; + } + + .note-item { + margin-bottom: 15px; + padding-bottom: 15px; + border-bottom: 1px solid #444; + cursor: pointer; + transition: background-color 0.2s; + padding: 10px; + border-radius: 3px; + } + + .note-item:hover { + background-color: #333; + } + + .note-item:last-child { + margin-bottom: 0; + padding-bottom: 0; + border-bottom: none; + } + + .note-title { + font-weight: bold; + margin-bottom: 5px; + font-size: 14px; + color: #3498db; + display: flex; + justify-content: space-between; + align-items: center; + } + + .note-icons { + display: flex; + gap: 5px; + } + + .note-icon { + font-size: 12px; + color: #aaa; + } + + .note-text { + font-size: 13px; + line-height: 1.4; + white-space: pre-wrap; + max-height: 80px; + overflow: hidden; + transition: max-height 0.3s; + } + + .note-item.expanded .note-text { + max-height: 1000px; + } + + .note-timestamp { + font-size: 11px; + color: #888; + margin-top: 5px; + text-align: right; + } + + #notes-toggle { + position: fixed; + bottom: 20px; + right: 20px; + width: 60px; + height: 60px; + background-color: #3498db; + color: white; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + z-index: 1998; + font-size: 28px; + transition: all 0.3s ease; + } + + #notes-toggle:hover { + background-color: #2980b9; + transform: scale(1.1); + } + + #notes-count { + position: absolute; + top: -5px; + right: -5px; + background-color: #e74c3c; + color: white; + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 14px; + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; + } + #laptop-popup { display: none; position: fixed; @@ -112,6 +390,297 @@ background: rgba(0, 0, 0, 0.5); z-index: 999; } + + /* Bluetooth Scanner Panel */ + #bluetooth-panel { + position: fixed; + bottom: 80px; + right: 90px; + width: 350px; + max-height: 500px; + background-color: rgba(0, 0, 0, 0.9); + color: white; + border-radius: 5px; + box-shadow: 0 2px 15px rgba(0, 0, 0, 0.5); + z-index: 1999; + font-family: Arial, sans-serif; + display: none; + overflow: hidden; + transition: all 0.3s ease; + border: 1px solid #444; + } + + #bluetooth-header { + background-color: #222; + padding: 12px 15px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #444; + } + + #bluetooth-title { + font-weight: bold; + font-size: 18px; + color: #9b59b6; + } + + #bluetooth-close { + cursor: pointer; + font-size: 18px; + color: #aaa; + transition: color 0.2s; + } + + #bluetooth-close:hover { + color: white; + } + + #bluetooth-search-container { + padding: 10px 15px; + background-color: #333; + border-bottom: 1px solid #444; + } + + #bluetooth-search { + width: 100%; + padding: 8px 10px; + border: none; + border-radius: 3px; + background-color: #222; + color: white; + font-size: 14px; + } + + #bluetooth-search:focus { + outline: none; + box-shadow: 0 0 0 2px rgba(155, 89, 182, 0.5); + } + + #bluetooth-categories { + display: flex; + padding: 5px 15px; + background-color: #2c2c2c; + border-bottom: 1px solid #444; + } + + .bluetooth-category { + padding: 5px 10px; + margin-right: 5px; + cursor: pointer; + border-radius: 3px; + font-size: 12px; + transition: all 0.2s; + } + + .bluetooth-category.active { + background-color: #9b59b6; + color: white; + } + + .bluetooth-category:hover:not(.active) { + background-color: #444; + } + + #bluetooth-content { + padding: 15px; + overflow-y: auto; + max-height: 350px; + } + + .bluetooth-device { + margin-bottom: 15px; + padding-bottom: 15px; + border-bottom: 1px solid #444; + cursor: pointer; + transition: background-color 0.2s; + padding: 10px; + border-radius: 3px; + } + + .bluetooth-device:hover { + background-color: #333; + } + + .bluetooth-device:last-child { + margin-bottom: 0; + padding-bottom: 0; + border-bottom: none; + } + + .bluetooth-device-name { + font-weight: bold; + margin-bottom: 5px; + font-size: 14px; + color: #9b59b6; + display: flex; + justify-content: space-between; + align-items: center; + } + + .bluetooth-device-icons { + display: flex; + gap: 5px; + } + + .bluetooth-device-icon { + font-size: 12px; + color: #aaa; + } + + .bluetooth-device-details { + font-size: 13px; + line-height: 1.4; + white-space: pre-wrap; + max-height: 80px; + overflow: hidden; + transition: max-height 0.3s; + } + + .bluetooth-device.expanded .bluetooth-device-details { + max-height: 1000px; + } + + .bluetooth-device-timestamp { + font-size: 11px; + color: #888; + margin-top: 5px; + text-align: right; + } + + /* Bluetooth Signal Strength Bar */ + .bluetooth-signal-bar-container { + margin: 0; + display: flex; + align-items: flex-end; + height: 16px; + } + + .bluetooth-signal-bars { + display: flex; + align-items: flex-end; + height: 16px; + gap: 1px; + } + + .bluetooth-signal-bar { + width: 3px; + background-color: #444; + border-radius: 1px; + transition: background-color 0.3s ease; + } + + .bluetooth-signal-bar.active { + background-color: currentColor; + } + + .bluetooth-signal-bar:nth-child(1) { height: 3px; } + .bluetooth-signal-bar:nth-child(2) { height: 6px; } + .bluetooth-signal-bar:nth-child(3) { height: 9px; } + .bluetooth-signal-bar:nth-child(4) { height: 12px; } + .bluetooth-signal-bar:nth-child(5) { height: 16px; } + + .bluetooth-signal-text { + display: none; + } + + #bluetooth-toggle { + position: fixed; + bottom: 20px; + right: 90px; + width: 60px; + height: 60px; + background-color: #9b59b6; + color: white; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); + z-index: 1998; + font-size: 28px; + transition: all 0.3s ease; + } + + #bluetooth-toggle:hover { + background-color: #8e44ad; + transform: scale(1.1); + } + + #bluetooth-count { + position: absolute; + top: -5px; + right: -5px; + background-color: #e74c3c; + color: white; + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 14px; + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; + 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; + margin-top: 8px; + padding: 5px 10px; + background-color: #2980b9; + color: white; + border: none; + border-radius: 3px; + font-size: 12px; + cursor: pointer; + transition: background-color 0.2s; + } + + .bluetooth-unlock-button:hover { + background-color: #3498db; + } + + /* Add a class to preserve hover state during updates */ + .bluetooth-device.hover-preserved { + background-color: #333; + } + + /* Add a more specific rule to prevent hover state from being lost when hovering over child elements */ + .bluetooth-device:hover .bluetooth-device-name, + .bluetooth-device:hover .bluetooth-device-details, + .bluetooth-device:hover .bluetooth-device-timestamp, + .bluetooth-device:hover .bluetooth-pair-button { + pointer-events: auto; + } @@ -121,6 +690,51 @@
Loading...
+ +
+ + +
+
+
Notes & Information
+
×
+
+
+ +
+
+
All
+
Important
+
Unread
+
+
+
+
+ 📝 +
0
+
+ + +
+
+
Bluetooth Scanner
+
×
+
+
+ +
+
+
All
+
Nearby
+
Saved
+
+
+
+ + \ No newline at end of file