feat: Emberwake, Crucible phases, Linux agent, musical dashboard, e2e
Emberwake spread/waterhole UI, campaign DB, spread handler, spread-kit web publisher, and SPREAD_TECHNIQUES doc. Crucible Phase A-C: expanded ops, port-forward matrix, remote dir browser, crucible help/tests. Linux agent hardening: credential vault, persistence audit, firewall/defender deploy, SMB spread status, CPU stats, screenshots/crypt/file-ops split. Docker compose and agent/server images with e2e validation script and docs. Musical dashboard: ambient music player, hover SFX, SoundContext/AmbientMusicContext, steampunk polish. Public builds API, dropper handler updates, SessionGate and fleet UX. README and PROBLEMS.md refresh.
This commit is contained in:
@@ -19,6 +19,8 @@ import NeonCard from '../components/NeonCard/NeonCard';
|
||||
import FleetTasksPanel from '../components/Fleet/FleetTasksPanel';
|
||||
import { AuditLogStrip } from '../components/Fleet/FleetOpsWidgets';
|
||||
import { useSound } from '../context/SoundContext';
|
||||
import { useAmbientMusic } from '../context/AmbientMusicContext';
|
||||
import { AMBIENT_MUSIC_SRC } from '../audio/ambientMusic';
|
||||
import { useVisualEffects } from '../context/VisualEffectsContext';
|
||||
import './Pages.css';
|
||||
|
||||
@@ -46,7 +48,19 @@ export function deepMerge<T extends object>(base: T, override: Partial<T>): T {
|
||||
}
|
||||
|
||||
export default function SettingsPage() {
|
||||
const { enabled: sfxEnabled, volume: sfxVolume, setEnabled: setSfxEnabled, setVolume: setSfxVolume, preview: previewSfx } = useSound();
|
||||
const {
|
||||
enabled: sfxEnabled,
|
||||
volume: sfxVolume,
|
||||
hoverEnabled,
|
||||
hoverVolume,
|
||||
setEnabled: setSfxEnabled,
|
||||
setVolume: setSfxVolume,
|
||||
setHoverEnabled,
|
||||
setHoverVolume,
|
||||
preview: previewSfx,
|
||||
previewHover,
|
||||
} = useSound();
|
||||
const { enabled: bgmEnabled, volume: bgmVolume, setEnabled: setBgmEnabled, setVolume: setBgmVolume } = useAmbientMusic();
|
||||
const { glowParticles, setGlowParticles } = useVisualEffects();
|
||||
const [config, setConfig] = useState<ServerConfig | null>(null);
|
||||
const [serverInfo, setServerInfo] = useState<{ suggested_url: string; local_ips: string[] } | null>(null);
|
||||
@@ -490,6 +504,82 @@ export default function SettingsPage() {
|
||||
Preview share
|
||||
</button>
|
||||
</div>
|
||||
<hr style={{ border: 'none', borderTop: '1px solid var(--border-dim)', margin: '1.25rem 0' }} />
|
||||
<h3 className="font-tech" style={{ fontSize: '0.85rem', marginBottom: '0.35rem' }}>Hover highlight sounds</h3>
|
||||
<p className="section-desc" style={{ marginBottom: '0.75rem' }}>
|
||||
Subtle dubstep-style blips when hovering buttons, cards, nav links, and fleet rows. Debounced so rapid
|
||||
mouse movement stays quiet. Muted when click sounds are off.
|
||||
</p>
|
||||
<div className="form-group checkbox-group">
|
||||
<label className="checkbox-label">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="checkbox"
|
||||
checked={hoverEnabled}
|
||||
disabled={!sfxEnabled}
|
||||
onChange={(e) => setHoverEnabled(e.target.checked)}
|
||||
/>
|
||||
<span>Enable hover highlight sounds</span>
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="cfg-hover-volume" className="label">
|
||||
Hover volume ({Math.round(hoverVolume * 100)}%)
|
||||
</label>
|
||||
<input
|
||||
id="cfg-hover-volume"
|
||||
type="range"
|
||||
className="input"
|
||||
min={0}
|
||||
max={100}
|
||||
step={5}
|
||||
value={Math.round(hoverVolume * 100)}
|
||||
disabled={!sfxEnabled || !hoverEnabled}
|
||||
onChange={(e) => setHoverVolume(parseInt(e.target.value, 10) / 100)}
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline btn-sm"
|
||||
disabled={!sfxEnabled || !hoverEnabled}
|
||||
onClick={previewHover}
|
||||
>
|
||||
Preview hover
|
||||
</button>
|
||||
<hr style={{ border: 'none', borderTop: '1px solid var(--border-dim)', margin: '1.25rem 0' }} />
|
||||
<h3 className="font-tech" style={{ fontSize: '0.85rem', marginBottom: '0.35rem' }}>Background music</h3>
|
||||
<p className="section-desc" style={{ marginBottom: '0.75rem' }}>
|
||||
Optional looping ambient track served from <code className="mono-sm">{AMBIENT_MUSIC_SRC}</code>. Use the
|
||||
mini player in the bottom-right corner on any page, or enable here. Defaults off — browsers block autoplay
|
||||
until you press play or toggle this on.
|
||||
</p>
|
||||
<div className="form-group checkbox-group">
|
||||
<label className="checkbox-label">
|
||||
<input
|
||||
type="checkbox"
|
||||
className="checkbox"
|
||||
checked={bgmEnabled}
|
||||
onChange={(e) => setBgmEnabled(e.target.checked)}
|
||||
/>
|
||||
<span>Enable background music</span>
|
||||
</label>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label htmlFor="cfg-bgm-volume" className="label">
|
||||
Music volume ({Math.round(bgmVolume * 100)}%)
|
||||
</label>
|
||||
<input
|
||||
id="cfg-bgm-volume"
|
||||
type="range"
|
||||
className="input"
|
||||
min={0}
|
||||
max={100}
|
||||
step={5}
|
||||
value={Math.round(bgmVolume * 100)}
|
||||
disabled={!bgmEnabled}
|
||||
onChange={(e) => setBgmVolume(parseInt(e.target.value, 10) / 100)}
|
||||
/>
|
||||
</div>
|
||||
</NeonCard>
|
||||
|
||||
<NeonCard accent="brass" className="settings-section">
|
||||
|
||||
Reference in New Issue
Block a user