From a67fe4e408638f79d9c44325f1ff02d36a334187 Mon Sep 17 00:00:00 2001 From: giteaadmin Date: Wed, 24 Jun 2026 08:58:51 +0000 Subject: [PATCH] fixgame 1 and 2 but 2 not finish --- www/html/Admin/private/store.json | 48 +++---- www/html/Game/data/game-timing.json | 6 +- www/html/Game/public/js/play.js | 172 +++++++++++++++++++++----- www/html/Game/public/js/room-lobby.js | 10 +- www/html/Game/public/play.html | 2 +- www/html/Game/public/room-lobby.html | 2 +- www/html/Game/server.js | 41 ++++-- 7 files changed, 214 insertions(+), 67 deletions(-) diff --git a/www/html/Admin/private/store.json b/www/html/Admin/private/store.json index 62d3151..7aba89d 100644 --- a/www/html/Admin/private/store.json +++ b/www/html/Admin/private/store.json @@ -51,37 +51,38 @@ "providerUserId": "p_1775109142385_wq7wfy1p32j", "notes": "auto: player-coins", "blocked": false, - "coins": 1233, + "coins": 1358, "createdAt": "2026-04-02T05:52:21+00:00", - "updatedAt": "2026-06-23T15:32:42+00:00", + "updatedAt": "2026-06-24T08:45:00+00:00", "daily": { "anchorMs": 1781197200000, "claimedDays": [ true, true, true, - false, + true, false, false, false ], - "lockUntilMs": 0 + "lockUntilMs": 1782320400000 }, - "score": 1118, + "score": 1208, "scoreByCase": { "1": 16, - "10": 340, - "8": 230, + "10": 358, + "8": 238, "11": 20, "13": 96, "14": 20, "9": 40, - "12": 246, + "12": 272, "15": 20, "4": 10, "5": 20, "7": 6, - "3": 54 + "3": 72, + "6": 20 }, "lbName": "Q", "achievements": { @@ -415,9 +416,9 @@ "providerUserId": "p_1781851275186_szcmp5pu3s", "notes": "auto: player-coins", "blocked": false, - "coins": 158, + "coins": 212, "createdAt": "2026-06-19T06:41:15+00:00", - "updatedAt": "2026-06-21T17:18:58+00:00", + "updatedAt": "2026-06-24T05:16:27+00:00", "daily": { "anchorMs": 1781802000000, "claimedDays": [ @@ -431,16 +432,17 @@ ], "lockUntilMs": 0 }, - "score": 138, + "score": 192, "scoreByCase": { - "10": 20, + "10": 28, "13": 36, - "12": 54, - "4": 28 + "12": 82, + "4": 28, + "3": 18 }, "lbName": "MONE", "achievements": { - "d1_minigame_solver": 13, + "d1_minigame_solver": 19, "a1_first_deduction": 1, "a5_truth_hunter": 1 } @@ -617,19 +619,21 @@ "providerUserId": "p_1782016990238_0u37bv7pxlxs", "notes": "auto: player-coins", "blocked": false, - "coins": 20, + "coins": 58, "createdAt": "2026-06-21T04:43:11+00:00", - "updatedAt": "2026-06-21T05:01:35+00:00", + "updatedAt": "2026-06-24T08:45:00+00:00", "lobbyColorThemeIndex": 8, "lobbySkinToneIndex": 1, - "score": 20, + "score": 48, "scoreByCase": { "13": 10, - "10": 10 + "10": 20, + "6": 8, + "8": 10 }, - "lbName": "ผู้เล่น", + "lbName": "MONE", "achievements": { - "d1_minigame_solver": 2 + "d1_minigame_solver": 4 } }, { diff --git a/www/html/Game/data/game-timing.json b/www/html/Game/data/game-timing.json index 6094cb8..036d01c 100644 --- a/www/html/Game/data/game-timing.json +++ b/www/html/Game/data/game-timing.json @@ -89,9 +89,9 @@ "balloonBossPlayerBalloonFallbackUrl": "/Game/img/MegaVirus/Artboard%209.png", "balloonBossBalloonsPerPlayer": 3, "forcedMinigameKeys": [ - "balloon_boss", - "jump_survive", - "space_shooter" + "quiz", + "gauntlet", + "stack" ], "testSpecialCardByMap": {}, "troublesomeForceOffer": false, diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js index 55656f3..2b7776a 100644 --- a/www/html/Game/public/js/play.js +++ b/www/html/Game/public/js/play.js @@ -1704,7 +1704,10 @@ clearTimeout(gauntletCrownCountdownTimer); gauntletCrownCountdownTimer = null; } - showGauntletCrownMissionOverlay(gauntletCrownHeistBuildLocalCrownMissionPlay()); + /* ตามกฎใหม่: เข้าเส้นชัย/รอด ≥1 คน (ไม่ถูกดันตกขอบ) = result-complete · ตายหมด = result-gameover (ไม่มี timeup) */ + const mg2LocalMission = gauntletCrownHeistBuildLocalCrownMissionPlay(); + const mg2LocalWin = missionSurvivorsPlay(mg2LocalMission) >= 1 || missionAnyScorePlay(mg2LocalMission); + beginSimpleResultFlashThenGcmPlay(mg2LocalMission, mg2LocalWin ? 'result-complete.png' : 'result-gameover.png'); } catch (_e) { /* ignore */ } try { draw(); @@ -6767,8 +6770,56 @@ } } + /** กันภาพผลโชว์ "ซ้ำ" — บางเกมจบ 2 path (เช่น MG2 local finish + server gauntlet-ended) ยิง flash 2 รอบผลต่างกัน + → ตัวที่ 2 ถูกบล็อก (เก็บตัวแรกไว้). reset เมื่อเริ่มมินิเกมรอบใหม่ (resetMissionResultFlashGuardPlay) */ + let _missionResultFlashAt = 0; + function missionResultFlashGuardPlay() { + const now = Date.now(); + if (now - _missionResultFlashAt < 9500) return false; /* เพิ่งโชว์ไป → บล็อกตัวซ้ำ */ + _missionResultFlashAt = now; + return true; + } + function resetMissionResultFlashGuardPlay() { _missionResultFlashAt = 0; } + + /** มีใครได้คะแนน ≥1 ไหม (จาก mission.ranked) — ตัดสิน complete/gameover (MG1 quiz / MG4 quiz_carry) */ + function missionAnyScorePlay(mission) { + const r = (mission && Array.isArray(mission.ranked)) ? mission.ranked : []; + return r.some(function (x) { return x && (Number(x.baseScore) || Number(x.finalScore) || Number(x.score) || 0) > 0; }); + } + /** จำนวนผู้รอด (ไม่ eliminated) — ตัดสิน complete/gameover (MG2 เข้าเส้นชัย / MG5 / MG6) */ + function missionSurvivorsPlay(mission) { + if (mission && typeof mission.survivorCount === 'number') return mission.survivorCount; + const r = (mission && Array.isArray(mission.ranked)) ? mission.ranked : []; + return r.filter(function (x) { return x && !x.eliminated; }).length; + } + /** จำนวนผู้เข้าร่วมทั้งหมด (คน+บอท) */ + function missionParticipantsPlay(mission) { + if (mission && typeof mission.participantCount === 'number' && mission.participantCount > 0) return mission.participantCount; + return (mission && Array.isArray(mission.ranked)) ? mission.ranked.length : 0; + } + /** "รอดทั้งหมด" — ทุกคนรอด ไม่มีใคร eliminated (MG5/MG6) */ + function missionAllSurvivedPlay(mission) { + const total = missionParticipantsPlay(mission); + return total > 0 && missionSurvivorsPlay(mission) >= total; + } + /** แฟลชรูปผลรูปเดียว (5s) แล้วเปิด GCM — เกมที่เดิมไม่มีแฟลช (MG1/MG2). asset ตาม skin ผ่าน gcmMissionMockAssetUrl */ + function beginSimpleResultFlashThenGcmPlay(mission, file) { + if (!missionResultFlashGuardPlay()) return; /* กันโชว์ซ้ำ (MG2: local finish + server gauntlet-ended ยิงทั้งคู่) */ + hideStackTowerResultFlashDomOnlyPlay(); + const ov = document.getElementById('stack-tower-result-flash'); + const imgEl = document.getElementById('stack-tower-result-flash-img'); + if (!mission || !ov || !imgEl) { showGauntletCrownMissionOverlay(mission); return; } + const finishToGcm = function () { hideStackTowerResultFlashDomOnlyPlay(); showGauntletCrownMissionOverlay(mission); }; + imgEl.onerror = function () { imgEl.onerror = null; finishToGcm(); }; + imgEl.src = gcmMissionMockAssetUrl(mission, file); + ov.classList.remove('is-hidden'); + ov.setAttribute('aria-hidden', 'false'); + stackTowerResultFlashTimer = setTimeout(function () { stackTowerResultFlashTimer = null; finishToGcm(); }, STACK_TOWER_RESULT_FLASH_MS); + } + /** โชว์รูปผล Tower จาก TowerBlock 5 วิ แล้วเปิด GCM สรุปเดิม */ function beginStackTowerResultFlashThenGcm(mission) { + if (!missionResultFlashGuardPlay()) return; /* กันโชว์ผลซ้ำ */ if (!mission || mission.uiSkin !== 'stack_tower') { showGauntletCrownMissionOverlay(mission); return; @@ -6802,11 +6853,10 @@ }, STACK_TOWER_RESULT_FLASH_MS); } - /** Jumper mnptfts2: เกรด F = ภาพ gameover · อื่น = complete (ก่อนแผงสรุปผล) */ + /** Jumper mnptfts2: มีคนรอด ≥1 = complete · ไม่รอดเลย = gameover (เกรดไม่เกี่ยว — ตามกฎใหม่) */ function jumpSurviveMissionOutcomeImageFile(mission) { - const g = mission && String(mission.grade || '').toUpperCase(); - if (g === 'F') return 'result-gameover.png'; - return 'result-complete.png'; + /* รอดทั้งหมด = complete · มีคนตาย/ตายหมด = gameover (ตามกฎใหม่) */ + return missionAllSurvivedPlay(mission) ? 'result-complete.png' : 'result-gameover.png'; } /** @@ -6814,6 +6864,7 @@ * all_dead = ข้าม timeup แล้ว outcome อย่างเดียว แล้วค่อย GCM */ function beginJumpSurviveMissionResultFlashSequenceThenGcm(mission, endKind) { + if (!missionResultFlashGuardPlay()) return; /* กันโชว์ผลซ้ำ */ if (!mission || mission.uiSkin !== 'jumper') { showGauntletCrownMissionOverlay(mission); return; @@ -6858,6 +6909,7 @@ * ทุกคนตาย = แฟลช result-gameover อย่างเดียวแล้ว GCM */ function beginSpaceShooterMissionResultFlashSequenceThenGcm(mission, endKind) { + if (!missionResultFlashGuardPlay()) return; /* กันโชว์ผลซ้ำ */ if (!mission || mission.uiSkin !== 'violent_crime') { showGauntletCrownMissionOverlay(mission); return; @@ -6889,10 +6941,11 @@ if (endKind === 'time_up') { showOneFlash('result-timeup.png', function () { hideStackTowerResultFlashDomOnlyPlay(); - showOneFlash('result-gameover.png', finishToGcm); + /* หมดเวลา: รอดทั้งหมด = complete · มีคนตาย = gameover (ตามกฎใหม่) */ + showOneFlash(missionAllSurvivedPlay(mission) ? 'result-complete.png' : 'result-gameover.png', finishToGcm); }); } else { - showOneFlash('result-gameover.png', finishToGcm); + showOneFlash('result-gameover.png', finishToGcm); /* all_dead */ } } @@ -6902,6 +6955,7 @@ * — ชนะ = end-victory-2.png ใน MegaVirus */ function beginBalloonBossMegaVirusResultFlashSequenceThenGcm(mission, endReason) { + if (!missionResultFlashGuardPlay()) return; /* กันโชว์ผลซ้ำ */ if (!mission || mission.uiSkin !== 'mega_virus') { showGauntletCrownMissionOverlay(mission); return; @@ -6913,23 +6967,30 @@ showGauntletCrownMissionOverlay(mission); return; } - const lose = endReason === 'all_dead' || endReason === 'time'; - const flashSrc = lose ? stackTowerAssetUrl('result-gameover.png') : megaVirusAssetUrl('end-victory-2.png'); const finishToGcm = function () { hideStackTowerResultFlashDomOnlyPlay(); showGauntletCrownMissionOverlay(mission); }; - imgEl.onerror = function () { - imgEl.onerror = null; - finishToGcm(); + const showOneFlash = function (url, onDone) { + imgEl.onerror = function () { imgEl.onerror = null; onDone(); }; + imgEl.src = url; + ov.classList.remove('is-hidden'); + ov.setAttribute('aria-hidden', 'false'); + stackTowerResultFlashTimer = setTimeout(function () { stackTowerResultFlashTimer = null; onDone(); }, STACK_TOWER_RESULT_FLASH_MS); }; - imgEl.src = flashSrc; - ov.classList.remove('is-hidden'); - ov.setAttribute('aria-hidden', 'false'); - stackTowerResultFlashTimer = setTimeout(function () { - stackTowerResultFlashTimer = null; - finishToGcm(); - }, STACK_TOWER_RESULT_FLASH_MS); + if (endReason === 'victory') { + /* ฆ่าบอส HP=0 → end-victory-2.png (MegaVirus) */ + showOneFlash(megaVirusAssetUrl('end-victory-2.png'), finishToGcm); + } else if (endReason === 'time') { + /* หมดเวลา บอสยังไม่ตาย → result-timeup → result-gameover (MegaVirus ไม่มี timeup ใช้ TowerBlock) */ + showOneFlash(stackTowerAssetUrl('result-timeup.png'), function () { + hideStackTowerResultFlashDomOnlyPlay(); + showOneFlash(stackTowerAssetUrl('result-gameover.png'), finishToGcm); + }); + } else { + /* ตายหมด → result-gameover */ + showOneFlash(stackTowerAssetUrl('result-gameover.png'), finishToGcm); + } } function stackTowerMissionTimeLimitSecPlay() { @@ -8434,7 +8495,10 @@ const n = ranked.length || 1; const averageScore = Math.floor(totalSum / n); let grade = averageScore >= 80 ? 'A' : averageScore >= 60 ? 'B' : 'C'; - if (totalSum <= 0 && rows.length) grade = 'F'; + /* เกรด F (= โชว์ Lose stamp) เฉพาะ "ไม่มีใครได้คะแนนเลย" — ดูจาก playLiveQuizScores เต็ม (ครบทุกคน) + ไม่ใช่ totalSum ของ ranked (me+others) ที่อาจหายคนตอบถูกที่ไม่อยู่ใน others → ขัดกับ flash complete */ + const mg1FullScoreSum = Object.keys(playLiveQuizScores).reduce(function (s, k) { return s + Math.max(0, playLiveQuizScores[k] | 0); }, 0); + if (mg1FullScoreSum <= 0 && rows.length) grade = 'F'; const rewardCard = grade === 'F' ? null : gauntletCrownRollRewardCardLocal(grade); return { ranked: ranked, @@ -10286,7 +10350,8 @@ const splashN = splashRanks.length; const splashAvg = splashN ? Math.min(100, Math.max(0, Math.round(splashTotal / splashN))) : 0; const splashGrade = summaryOpts.forceGradeF ? 'F' : quizCarryGradeFromTeamAverage(splashAvg); - const useCompleteSplash = splashGrade !== 'F'; + /* ตามกฎใหม่: มีใครได้คะแนน ≥1 = result-complete · ไม่มีใครได้เลย = result-gameover (ไม่อิงเกรด/timeup) */ + const useCompleteSplash = splashParts.some(function (s) { return s > 0; }); showQuizCarryResultEndLayer(useCompleteSplash); quizCarrySessionCompleteResultToSummaryT = setTimeout(function () { quizCarrySessionCompleteResultToSummaryT = null; @@ -16970,7 +17035,7 @@ if (e.ref && !e.ref.balloonBossEliminated) { e.ref.balloonBossBalloons = 0; e.ref.balloonBossEliminated = true; } }); try { if (socket && myId != null) socket.emit('move', { x: me.x, y: me.y, direction: me.direction, balloonBossBalloons: 0, balloonBossEliminated: true }); } catch (eT) { /* ignore */ } - triggerBalloonBossOverPlay('all_dead'); + triggerBalloonBossOverPlay('time'); /* หมดเวลา บอสยังไม่ตาย → timeup→gameover (แยกจาก all_dead = gameover) */ return; } if (teamBossDmg >= maxHp) { @@ -19537,8 +19602,13 @@ const o = others.get(oid); if (!o) return; if (hostHumans.has(String(oid))) { o._notInHostRoster = 0; return; } + /* peer ที่ server ยืนยันสดๆ (อยู่ใน gauntlet-sync = space.peers จริง) ห้ามลบ — + server-authoritative ชนะ host roster ที่อาจตกหล่นชั่วคราว = กัน MG2 ผู้เล่นหาย/วูบ */ + if (o._serverConfirmedAt && (Date.now() - o._serverConfirmedAt) < 3000) { o._notInHostRoster = 0; return; } o._notInHostRoster = (o._notInHostRoster || 0) + 1; - if (o._notInHostRoster >= 3) others.delete(oid); + /* ลบเฉพาะผีที่ "หายจาก roster ของ host นานจริง" (~1.3s = 16 broadcast) — กัน blip สั้นทำให้ peer ดีหลุด + แล้ว gauntlet-sync ไม่ re-create → ต้องรอ snapshot re-add ที่ตำแหน่งเก่า = MG2 ผู้เล่นมารวมเลนบน */ + if (o._notInHostRoster >= 16) others.delete(oid); }); } /* เกมที่ render อ่านตำแหน่งจาก x/y หรือ Cx/Cy ตรงๆ (ไม่ผ่าน lerp ของ main tick) → สแนปตำแหน่งเลย */ @@ -19685,7 +19755,7 @@ /* MG7 — รับสัญญาณจบเกมจาก host → จบพร้อมกันทุกเครื่อง + ใช้คะแนนสุดท้ายของ host (อันดับตรงกัน) */ socket.on('balloon-boss-over', (d) => { if (!mapData || mapData.gameType !== 'balloon_boss' || balloonBossGameEnded) return; - const reason = (d && d.reason === 'victory') ? 'victory' : 'all_dead'; + const reason = (d && (d.reason === 'victory' || d.reason === 'time')) ? d.reason : 'all_dead'; if (d && Array.isArray(d.scores)) { d.scores.forEach((s) => { if (!s || s.id == null) return; @@ -20269,8 +20339,16 @@ checkMg1AllDeadAndEnd(); }); - socket.on('quiz-ended', () => { + socket.on('quiz-ended', (data) => { if (previewMode && isQuiz()) return; + /* merge คะแนนสุดท้าย authoritative จาก server ก่อนสร้าง mission → ผล complete/gameover + อันดับ ตรงกันทุกจอ + (กัน quiz-result ข้อสุดท้ายมาไม่ทันบางจอ → totalSum/anyScore ต่าง = ผล 2 จอไม่เหมือนกัน) */ + if (data && data.scores && typeof data.scores === 'object') { + Object.keys(data.scores).forEach((pid) => { + const sv = Math.max(0, Number(data.scores[pid]) || 0); + if (playLiveQuizScores[pid] == null || sv > (playLiveQuizScores[pid] | 0)) playLiveQuizScores[pid] = sv; + }); + } let questionMissionEnd = null; if (isQuizQuestionMissionUiMapPlay()) { questionMissionEnd = quizQuestionMissionBuildPayload(); @@ -20296,7 +20374,11 @@ quizQuestionMissionPhase = 'ended'; quizQuestionMissionDeferredPhase = null; applyQuizQuestionMissionPanelImages(); - showGauntletCrownMissionOverlay(questionMissionEnd); + /* ตามกฎใหม่: มีใครตอบถูก ≥1 = result-complete · ไม่มีใครได้เลย = result-gameover (ไม่มี timeup) + ตัดสินจาก playLiveQuizScores ตรงๆ (มีครบทุกคน + merge authoritative แล้ว) — ไม่ใช่ ranked + (ranked สร้างจาก me+others เท่านั้น → ถ้าคนตอบถูกไม่อยู่ใน others ของจอนี้ คะแนนหาย = ผลเพี้ยน/2 จอไม่ตรง) */ + const mg1AnyScore = Object.keys(playLiveQuizScores).some(function (k) { return (playLiveQuizScores[k] | 0) > 0; }); + beginSimpleResultFlashThenGcmPlay(questionMissionEnd, mg1AnyScore ? 'result-complete.png' : 'result-gameover.png'); } }); @@ -20376,15 +20458,41 @@ } me.gauntletEliminated = !!p.gauntletEliminated; clampGauntletCrownHeistEntityXInPlacePlay(me); - } else { - const o = others.get(p.id) ?? others.get(pid); + } else if (!isPreviewBotId(p.id)) { + let o = others.get(p.id) ?? others.get(pid); + const px = Number(p.x); + const py = Number(p.y); + if (!o && Number.isFinite(px) && Number.isFinite(py)) { + /* peer อยู่ใน gauntlet-sync (server-authoritative = space.peers) แต่หายจาก others + (เช่นถูก fill-bot-state human-roster force-remove ผิด หรือ user-joined/snapshot มาไม่ครบ) + → re-create ที่ "ตำแหน่ง sync" ทันที ไม่ต้องรอ snapshot re-add ที่จุดเกิด + = แก้ MG2 ผู้เล่นมาไม่ครบ + มารวมเลนบน (เพราะ snapshot เก่า re-add ที่ spawn) */ + o = { + x: px, y: py, tx: px, ty: py, + direction: p.direction || 'down', + nickname: p.nickname || 'ผู้เล่น', + characterId: p.characterId ?? null, + spawnJoinOrder: 0, + playTint: playTintForPreviewBotId(p.id) || resolvePlayTintForPeer(p.id, p), + gauntletJumpTicks: 0, gauntletJumpVis: 0, gauntletScore: 0, + gauntletEliminated: !!p.gauntletEliminated, + jumpSurviveEliminated: false, + spaceShooterScore: 0, balloonBossScore: 0, balloonBossBossDmg: 0, + balloonBossBalloons: balloonBossBalloonsStartPlay(), balloonBossEliminated: false, + quizCarryHeld: null, bannedSpectator: false, + _notInHostRoster: 0, + }; + others.set(p.id, o); + if (o.characterId) { try { preloadPlayTintForAvatar(o.characterId, o.playTint); } catch (_e) { /* ignore */ } } + } if (o) { + o._serverConfirmedAt = Date.now(); + o._notInHostRoster = 0; const prevSc = Math.max(0, Number(o.gauntletScore) || 0); - const px = Number(p.x); - const py = Number(p.y); if (Number.isFinite(px)) o.tx = px; if (Number.isFinite(py)) o.ty = py; if (p.direction) o.direction = p.direction; + if (o.characterId == null && p.characterId != null) o.characterId = p.characterId; const jt = Number(p.gauntletJumpTicks); o.gauntletJumpTicks = Number.isFinite(jt) ? jt : 0; if (o.gauntletJumpVis == null) o.gauntletJumpVis = o.gauntletJumpTicks; @@ -20463,7 +20571,9 @@ if (hto) hto.classList.add('is-hidden'); gauntletCrownHowtoVisible = false; if (data && data.crownMission) { - showGauntletCrownMissionOverlay(data.crownMission); + /* ตามกฎใหม่: เข้าเส้นชัย/รอด ≥1 คน = result-complete · ตายหมด = result-gameover (ไม่มี timeup) */ + const mg2SrvWin = missionSurvivorsPlay(data.crownMission) >= 1 || missionAnyScorePlay(data.crownMission); + beginSimpleResultFlashThenGcmPlay(data.crownMission, mg2SrvWin ? 'result-complete.png' : 'result-gameover.png'); return; } const ov = document.getElementById('gauntlet-ended-overlay'); diff --git a/www/html/Game/public/js/room-lobby.js b/www/html/Game/public/js/room-lobby.js index 4ed51f7..fe2324d 100644 --- a/www/html/Game/public/js/room-lobby.js +++ b/www/html/Game/public/js/room-lobby.js @@ -27,6 +27,12 @@ } const CREATE_ROOM_URL = typeof appPath === 'function' ? appPath('/Create%20Room/') : '/Create%20Room/'; + const JOIN_ROOM_URL = typeof appPath === 'function' ? appPath('/Join%20Room/') : '/Join%20Room/'; + /** กดออกจากห้อง (LobbyA/LobbyB): host → Create Room · client → Join Room */ + function leaveRoomDest() { + try { if (hostId != null && socket && hostId === socket.id) return CREATE_ROOM_URL; } catch (e) { /* ignore */ } + return JOIN_ROOM_URL; + } function wasPageReload() { try { @@ -4704,7 +4710,7 @@ openRoomCustomize(); }); document.getElementById('room-lobby-profile-logout')?.addEventListener('click', () => { - window.location.href = CREATE_ROOM_URL; + window.location.href = leaveRoomDest(); /* host→Create Room · client→Join Room */ }); document.getElementById('lobby-rank-backdrop')?.addEventListener('click', () => { closeLobbyRankModal(); @@ -7329,7 +7335,7 @@ const btnLeaveLobby = document.getElementById('btn-leave-lobby'); if (btnLeaveLobby) { btnLeaveLobby.addEventListener('click', () => { - window.location.href = CREATE_ROOM_URL; + window.location.href = leaveRoomDest(); /* host→Create Room · client→Join Room */ }); } diff --git a/www/html/Game/public/play.html b/www/html/Game/public/play.html index 6816660..f8bc839 100644 --- a/www/html/Game/public/play.html +++ b/www/html/Game/public/play.html @@ -5371,7 +5371,7 @@ - +
v —