diff --git a/public/app.js b/public/app.js index 2c2bf20..c5ea535 100644 --- a/public/app.js +++ b/public/app.js @@ -27,7 +27,8 @@ function connectWS() { renderRootme(msg.ranking); } else if (msg.type === 'rootme_flag') { renderRootme(rootmeCache); - showNotif(`FLAG ! ${msg.login} +${msg.gained} PTS — TOTAL : ${msg.newScore} PTS`); + showNotif(`FLAG ! ${msg.login} +${msg.gained} PTS — TOTAL : ${msg.newScore} PTS`, null); + playKillstreak(msg.streak || 1); } else if (msg.type === 'geo_news') { showGeoBanner(msg.title, msg.link); } else if (msg.type === 'anssi_news') { @@ -65,6 +66,24 @@ const alertIconEl = document.getElementById('alert-icon'); const alertImageEl = document.getElementById('alert-image'); const infoAlert = document.getElementById('info-alert'); +// ── Killstreak sounds ───────────────────────────────────────────────────────── + +const killstreakSounds = [ + null, // index 0 inutilisé + [new Audio('/sound_effects/first-blood-1.mp3'), new Audio('/sound_effects/first-blood-2.mp3')], + [new Audio('/sound_effects/double-kill-1.mp3'), new Audio('/sound_effects/double-kill-2.mp3')], + [new Audio('/sound_effects/triple-kill-1.mp3'), new Audio('/sound_effects/triple-kill-2.mp3')], + [new Audio('/sound_effects/monsterkill.mp3')], +]; +const godlikeAudio = new Audio('/sound_effects/godlike.mp3'); + +function playKillstreak(streak) { + const pool = streak >= 5 ? [godlikeAudio] : (killstreakSounds[streak] || killstreakSounds[1]); + const snd = pool[Math.floor(Math.random() * pool.length)]; + snd.currentTime = 0; + snd.play().catch(err => console.error('killstreak audio:', err)); +} + // ── Notification (ANSSI / geo) ──────────────────────────────────────────────── const notifOverlay = document.getElementById('notif-overlay'); diff --git a/server.js b/server.js index 715dc10..2a8262d 100644 --- a/server.js +++ b/server.js @@ -13,6 +13,7 @@ const PORT = process.env.DASHBOARD_PORT || 3000; const app = express(); app.use(express.json({ limit: '10mb' })); app.use(express.static(path.join(__dirname, 'public'))); +app.use('/sound_effects', express.static(path.resolve('sound_effects'))); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); @@ -263,6 +264,20 @@ let rootmeCache = null; let rootmePrevScores = {}; // login → last known score const rootmePlayerCache = {}; // id → { login, score, rank } +// Killstreak : streak par joueur, réinitialisée quand un autre joueur flag +let killstreakLastFlagger = null; +const killstreakCounts = {}; // login → streak actuel + +function recordFlag(login) { + if (killstreakLastFlagger !== login) { + killstreakCounts[login] = 1; + } else { + killstreakCounts[login] = (killstreakCounts[login] || 0) + 1; + } + killstreakLastFlagger = login; + return killstreakCounts[login]; +} + function parseRootmeUser(profile, id) { const profileRaw = Array.isArray(profile) ? profile[0] : profile; const user = profileRaw?.['0'] ?? profileRaw; @@ -305,8 +320,9 @@ function startRootmePoller() { const prev = rootmePrevScores[entry.login]; if (prev !== undefined && entry.score > prev) { const gained = entry.score - prev; - console.log(`[rootme] FLAG ! ${entry.login} +${gained} pts (${prev} → ${entry.score})`); - broadcast({ type: 'rootme_flag', login: entry.login, gained, newScore: entry.score }); + const streak = recordFlag(entry.login); + console.log(`[rootme] FLAG ! ${entry.login} +${gained} pts (${prev} → ${entry.score}) streak=${streak}`); + broadcast({ type: 'rootme_flag', login: entry.login, gained, newScore: entry.score, streak }); } rootmePrevScores[entry.login] = entry.score; diff --git a/sound_effects/double-kill-1.mp3 b/sound_effects/double-kill-1.mp3 new file mode 100644 index 0000000..ac4a97b Binary files /dev/null and b/sound_effects/double-kill-1.mp3 differ diff --git a/sound_effects/double-kill-2.mp3 b/sound_effects/double-kill-2.mp3 new file mode 100644 index 0000000..4fe8c42 Binary files /dev/null and b/sound_effects/double-kill-2.mp3 differ diff --git a/sound_effects/first-blood-1.mp3 b/sound_effects/first-blood-1.mp3 new file mode 100644 index 0000000..c0e49be Binary files /dev/null and b/sound_effects/first-blood-1.mp3 differ diff --git a/sound_effects/first-blood-2.mp3 b/sound_effects/first-blood-2.mp3 new file mode 100644 index 0000000..1799a6c Binary files /dev/null and b/sound_effects/first-blood-2.mp3 differ diff --git a/sound_effects/godlike.mp3 b/sound_effects/godlike.mp3 new file mode 100644 index 0000000..ee9fcd7 Binary files /dev/null and b/sound_effects/godlike.mp3 differ diff --git a/sound_effects/monsterkill.mp3 b/sound_effects/monsterkill.mp3 new file mode 100644 index 0000000..c11f1bf Binary files /dev/null and b/sound_effects/monsterkill.mp3 differ diff --git a/sound_effects/triple-kill-1.mp3 b/sound_effects/triple-kill-1.mp3 new file mode 100644 index 0000000..dac6607 Binary files /dev/null and b/sound_effects/triple-kill-1.mp3 differ diff --git a/sound_effects/triple-kill-2.mp3 b/sound_effects/triple-kill-2.mp3 new file mode 100644 index 0000000..a23b61f Binary files /dev/null and b/sound_effects/triple-kill-2.mp3 differ