update before change

This commit is contained in:
2026-07-08 03:44:48 +00:00
parent 5f3ad2d6ec
commit 29ea63ac30
11 changed files with 12762 additions and 41 deletions
+12
View File
@@ -4674,6 +4674,8 @@
var embedPanels = [
{ tab: 'map-editor', panel: 'tab-panel-map-editor', fsBtn: 'btn-map-editor-fullscreen' },
{ tab: 'characters', panel: 'tab-panel-characters', fsBtn: 'btn-character-fullscreen' },
{ tab: 'qb-map-editor', panel: 'tab-panel-qb-map-editor', fsBtn: 'btn-qb-map-editor-fullscreen' },
{ tab: 'ai-admin', panel: 'tab-panel-ai-admin', fsBtn: 'btn-ai-admin-fullscreen' },
];
embedPanels.forEach(function (ep) {
if (name === ep.tab) return;
@@ -4704,6 +4706,14 @@
if (name === 'troublesome') loadTroublesomePanel();
if (name === 'test-mode') { loadForcedMinigamePanel(); loadSpecialCardByMapPanel(); loadTroublesomeForcePanel(); }
if (name === 'sound') loadSoundPanel();
if (name === 'qb-map-editor') ensureEmbedFrameSrc('admin-qb-map-editor-frame');
if (name === 'ai-admin') ensureEmbedFrameSrc('admin-ai-admin-frame');
}
/* ฝัง iframe editor แบบ lazy — ตั้ง src จาก data-src ครั้งแรกที่เปิด tab (ไม่โหลดตอนเปิดหน้า Admin) */
function ensureEmbedFrameSrc(id) {
var f = el(id);
if (f && !f.getAttribute('src') && f.getAttribute('data-src')) f.setAttribute('src', f.getAttribute('data-src'));
}
function boot() {
@@ -4894,6 +4904,8 @@
}
bindEmbedPanelFullscreen('btn-map-editor-fullscreen', 'tab-panel-map-editor');
bindEmbedPanelFullscreen('btn-character-fullscreen', 'tab-panel-characters');
bindEmbedPanelFullscreen('btn-qb-map-editor-fullscreen', 'tab-panel-qb-map-editor');
bindEmbedPanelFullscreen('btn-ai-admin-fullscreen', 'tab-panel-ai-admin');
/* Test Mode toggle — เก็บใน localStorage (share ระหว่าง Admin กับ Game ภายใต้ origin เดียวกัน) */
var TEST_MODE_KEY = 'justiceTestMode';
File diff suppressed because it is too large Load Diff
+25 -1
View File
@@ -102,6 +102,8 @@
<div class="admin-tab-sep" aria-hidden="true"><span>ทั่วไป &amp; ฉาก</span></div>
<button type="button" class="tab is-active" data-tab="oauth" role="tab" id="tab-oauth" aria-selected="true" aria-controls="tab-panel-oauth"><span class="tab-label">OAuth</span><span class="tab-desc">Facebook / Google</span></button>
<button type="button" class="tab" data-tab="map-editor" role="tab" id="tab-map-editor" aria-controls="tab-panel-map-editor"><span class="tab-label">Editor ฉาก</span><span class="tab-desc">แผนที่ฉาก / โซนเกม</span></button>
<button type="button" class="tab" data-tab="qb-map-editor" role="tab" id="tab-qb-map-editor" aria-controls="tab-panel-qb-map-editor"><span class="tab-label">Editor แผนที่ Quiz Battle</span><span class="tab-desc">เส้นทาง · โดม · จุดเกิด (10 ห้อง)</span></button>
<button type="button" class="tab" data-tab="ai-admin" role="tab" id="tab-ai-admin" aria-controls="tab-panel-ai-admin"><span class="tab-label">ตั้งค่า AI แชท</span><span class="tab-desc">ผู้ช่วย AI ในเกม · ล็อกอินแยก</span></button>
<button type="button" class="tab" data-tab="change-password" role="tab" id="tab-change-password" aria-selected="false" aria-controls="tab-panel-change-password"><span class="tab-label">รหัสผ่าน</span><span class="tab-desc tab-desc--wide">เปลี่ยนรหัสของคุณ · กดซ้ำเพื่อปิด</span></button>
<div class="admin-tab-sep" aria-hidden="true"><span>มินิเกม</span></div>
@@ -195,6 +197,28 @@
<iframe class="admin-editor-iframe" id="admin-map-editor-frame" title="Editor ฉาก" src="/Game/editor.html?embed=1"></iframe>
</section>
<section id="tab-panel-qb-map-editor" class="tab-panel card admin-editor-panel" hidden role="tabpanel" aria-labelledby="tab-qb-map-editor">
<div class="admin-editor-panel-head">
<div class="admin-editor-panel-intro">
<h2>Editor แผนที่ Quiz Battle</h2>
<p class="muted">แก้แผนที่ห้อง Quiz Battle (qbroom 110) — เลือกห้องจากเมนูในตัว editor · วาดเส้นทาง / โดม / จุดเกิด · คลิกซ้ายวาด คลิกขวาลบ</p>
</div>
<button type="button" class="btn btn-ghost btn-editor-fs" id="btn-qb-map-editor-fullscreen" aria-pressed="false" title="ขยายเต็มหน้าจอ (Esc ออก)">เต็มจอ</button>
</div>
<iframe class="admin-editor-iframe" id="admin-qb-map-editor-frame" title="Editor แผนที่ Quiz Battle" data-src="/Game/qb-editor.html"></iframe>
</section>
<section id="tab-panel-ai-admin" class="tab-panel card admin-editor-panel" hidden role="tabpanel" aria-labelledby="tab-ai-admin">
<div class="admin-editor-panel-head">
<div class="admin-editor-panel-intro">
<h2>ตั้งค่า AI แชท (Admin)</h2>
<p class="muted">ตั้งค่าผู้ช่วย AI ในเกม — หน้านี้มีการล็อกอินแยกของตัวเอง (ไม่ใช่ session Admin นี้)</p>
</div>
<button type="button" class="btn btn-ghost btn-editor-fs" id="btn-ai-admin-fullscreen" aria-pressed="false" title="ขยายเต็มหน้าจอ (Esc ออก)">เต็มจอ</button>
</div>
<iframe class="admin-editor-iframe" id="admin-ai-admin-frame" title="ตั้งค่า AI แชท" data-src="/Game/ai-admin.html"></iframe>
</section>
<section id="tab-panel-quiz" class="tab-panel card" hidden role="tabpanel" aria-labelledby="tab-quiz">
<h2>คำถามเกม (ถูก / ผิด)</h2>
<p class="muted">ใช้กับฉากประเภท <strong>เกมตอบคำถาม</strong> ใน Editor — จำนวนข้อที่สุ่มต่อรอบตั้งได้ด้านล่าง (สูงสุด 50, ค่าเริ่ม 10) · เวลาเป็นวินาที (เก็บที่เซิร์ฟเวอร์เกม <code>/Game/data/quiz-settings.json</code>) · <em>English:</em> True/false quiz draws up to N shuffled questions per game session.</p>
@@ -1333,7 +1357,7 @@
</div>
</main>
</div>
<script src="admin.js?v=93"></script>
<script src="admin.js?v=94"></script>
<script>
/* toggle: เปิด/ปิด HUD โหลด LobbyA (Iron Man) ให้ "ผู้เล่นทั่วไป" เห็น (เก็บใน game-timing.json: lobbyDebugHud)
— dev เปิดเครื่องตัวเองได้เสมอด้วย ?dbg=1 หรือ localStorage.lobbyDbg='1' โดยไม่ต้องใช้ปุ่มนี้ */
File diff suppressed because it is too large Load Diff
+129 -30
View File
@@ -250,9 +250,9 @@
"providerUserId": "p_1780400804441_lsc3lqqvs0i",
"notes": "auto: player-coins",
"blocked": false,
"coins": 224,
"coins": 274,
"createdAt": "2026-06-02T11:46:46+00:00",
"updatedAt": "2026-07-03T12:00:58+00:00",
"updatedAt": "2026-07-06T12:55:43+00:00",
"daily": {
"anchorMs": 1781802000000,
"claimedDays": [
@@ -264,27 +264,44 @@
false,
false
],
"lockUntilMs": 1783098000000
"lockUntilMs": 0
},
"score": 154,
"score": 204,
"scoreByCase": {
"1": 10,
"1": 30,
"7": 2,
"10": 52,
"6": 24,
"13": 32,
"5": 6,
"12": 10,
"3": 18
"3": 18,
"2": 30
},
"lbName": "Pear",
"achievements": {
"d1_minigame_solver": 20,
"a1_first_deduction": 1,
"a5_truth_hunter": 3
"a5_truth_hunter": 4,
"b4_data_miner": 6,
"b1_evidence_collector": 3,
"b5_deep_scanner": 2,
"a2_sharp_eye": 3,
"d3_the_backbone": 3,
"c3_quick_draw": 1,
"d2_silent_guardian": 1,
"b2_relentless_investigator": 1,
"e1_the_observer": 1,
"d4_flawless_diver": 1,
"a6_unbreakable_logic": 1
},
"lobbyColorThemeIndex": 8,
"lobbySkinToneIndex": 3
"lobbySkinToneIndex": 3,
"achvStreak": {
"e1_the_observer": 1,
"d4_flawless_diver": 1,
"a6_unbreakable_logic": 1
}
},
{
"id": "9404ea306bffed187b43a490",
@@ -732,39 +749,52 @@
"providerUserId": "p_1782122326943_7p2fnvivscm",
"notes": "auto: player-coins",
"blocked": false,
"coins": 264,
"coins": 309,
"createdAt": "2026-06-22T09:58:46+00:00",
"updatedAt": "2026-07-04T13:20:26+00:00",
"lobbyColorThemeIndex": 3,
"lobbySkinToneIndex": 1,
"score": 254,
"updatedAt": "2026-07-06T11:31:06+00:00",
"lobbyColorThemeIndex": 7,
"lobbySkinToneIndex": 2,
"score": 284,
"scoreByCase": {
"10": 34,
"10": 44,
"12": 142,
"3": 54,
"13": 10,
"13": 30,
"8": 14
},
"lbName": "MONE",
"lbName": "Q",
"achievements": {
"d1_minigame_solver": 20,
"e2_the_impostor": 1,
"e4_agent_of_chaos": 1,
"e3_master_of_doubt": 1,
"e5_slippery_eel": 1
"e5_slippery_eel": 1,
"b4_data_miner": 5,
"a2_sharp_eye": 2,
"b1_evidence_collector": 2,
"b3_hidden_fragment": 1,
"d3_the_backbone": 3,
"a3_mind_architect": 1,
"d2_silent_guardian": 1,
"a6_unbreakable_logic": 0,
"d4_flawless_diver": 0
},
"daily": {
"anchorMs": 1782147600000,
"claimedDays": [
true,
false,
true,
false,
false,
false,
false,
false
],
"lockUntilMs": 0
"lockUntilMs": 1783357200000
},
"achvStreak": {
"a6_unbreakable_logic": 0,
"d4_flawless_diver": 0
}
},
{
@@ -823,18 +853,32 @@
"providerUserId": "p_1778097234255_htbbepc8x3m",
"notes": "auto: player-coins",
"blocked": false,
"coins": 58,
"coins": 98,
"createdAt": "2026-06-22T13:52:23+00:00",
"updatedAt": "2026-06-23T09:46:51+00:00",
"score": 58,
"updatedAt": "2026-07-06T07:04:13+00:00",
"score": 98,
"scoreByCase": {
"12": 20,
"12": 40,
"13": 30,
"8": 8
"8": 8,
"10": 20
},
"lbName": "ผู้เล่น",
"achievements": {
"d1_minigame_solver": 6
"d1_minigame_solver": 10,
"b4_data_miner": 4,
"b1_evidence_collector": 3,
"d3_the_backbone": 6,
"b2_relentless_investigator": 1,
"d2_silent_guardian": 2,
"e1_the_observer": 1,
"a2_sharp_eye": 2,
"b5_deep_scanner": 1
},
"lobbyColorThemeIndex": 2,
"lobbySkinToneIndex": 2,
"achvStreak": {
"e1_the_observer": 1
}
},
{
@@ -1129,15 +1173,15 @@
"providerUserId": "p_1782802776912_g9ua6h1w5dj",
"notes": "auto: achievements",
"blocked": false,
"coins": 66,
"coins": 96,
"achievements": {
"d1_minigame_solver": 7
"d1_minigame_solver": 12
},
"createdAt": "2026-07-01T06:43:44+00:00",
"updatedAt": "2026-07-02T09:02:56+00:00",
"score": 66,
"updatedAt": "2026-07-07T06:44:54+00:00",
"score": 96,
"scoreByCase": {
"1": 66
"1": 96
},
"lbName": "DevTester"
},
@@ -1302,6 +1346,61 @@
"a1_first_deduction": 1,
"a5_truth_hunter": 1
}
},
{
"id": "da66a220ae68773617cbdef0",
"email": "",
"displayName": "TOY Studio",
"loginType": "guest",
"providerUserId": "g_103253816568665853265",
"notes": "auto: game-award",
"blocked": false,
"coins": 30,
"score": 30,
"scoreByCase": {
"1": 30
},
"lbName": "TOY Studio",
"createdAt": "2026-07-07T07:06:32+00:00",
"updatedAt": "2026-07-07T07:21:02+00:00",
"achievements": {
"d1_minigame_solver": 1
}
},
{
"id": "ad188698a36b8b26690cb40c",
"email": "",
"displayName": "ผู้เล่น",
"loginType": "guest",
"providerUserId": "p_1783423451842_11irmcfil84",
"notes": "auto: player-coins",
"blocked": false,
"coins": 10,
"createdAt": "2026-07-07T11:24:11+00:00",
"updatedAt": "2026-07-07T13:10:37+00:00",
"score": 10,
"scoreByCase": {
"2": 10
},
"lbName": "ผู้เล่น",
"achievements": {
"d1_minigame_solver": 1,
"b4_data_miner": 3,
"b1_evidence_collector": 1,
"a2_sharp_eye": 2
}
},
{
"id": "056ac410650650b51ad4f969",
"email": "",
"displayName": "Guest",
"loginType": "guest",
"providerUserId": "p_1783430078857_8zuv4132wnn",
"notes": "auto: player-coins",
"blocked": false,
"coins": 0,
"createdAt": "2026-07-07T13:14:37+00:00",
"updatedAt": "2026-07-07T13:14:37+00:00"
}
]
}
+8 -8
View File
@@ -20,7 +20,7 @@
"stackBlockWidthTiles": 3.2,
"stackTowerMissionTimeSec": 90,
"stackTeamMissesMax": 3,
"stackTowerProgressBlocks": 50,
"stackTowerProgressBlocks": 60,
"stackBlockNormalImageUrls": [
"/Game/img/TowerBlock/Block-Code-1-red.png",
"/Game/img/TowerBlock/Block-Code-2-orange.png",
@@ -28,8 +28,8 @@
"/Game/img/TowerBlock/Block-Code-4-Green.png",
"/Game/img/TowerBlock/Block-Code-5-Blue.png",
"/Game/img/TowerBlock/Block-Code-6-Navy.png",
"",
""
"/Game/img/TowerBlock/Block-Code-7-Violet.png",
"/Game/img/TowerBlock/Block-Code-8-Pink.png"
],
"stackBlockHeavyImageUrls": [
"/Game/img/TowerBlock/Block-Code-1-red-2.png",
@@ -38,8 +38,8 @@
"/Game/img/TowerBlock/Block-Code-4-Green-2.png",
"/Game/img/TowerBlock/Block-Code-5-Blue-2.png",
"/Game/img/TowerBlock/Block-Code-6-Navy-2.png",
"",
""
"/Game/img/TowerBlock/Block-Code-7-Violet-2.png",
"/Game/img/TowerBlock/Block-Code-8-Pink-2.png"
],
"stackHeavyBlockPercent": 35,
"jumpSurviveJumpHeightMult": 1.7,
@@ -97,9 +97,9 @@
"balloonBossPlayerBalloonFallbackUrl": "/Game/img/MegaVirus/Artboard%209.png",
"balloonBossBalloonsPerPlayer": 3,
"forcedMinigameKeys": [
"quiz",
"gauntlet",
"space_shooter"
"quiz_carry",
"jump_survive",
"balloon_boss"
],
"testSpecialCardByMap": {},
"troublesomeForceOffer": false,
-1
View File
@@ -1565,7 +1565,6 @@
<input id="ai-chat-input" placeholder="Type a here..." autocomplete="off">
<button type="submit" class="chat-send-btn" title="ส่ง"><img src="img/chat-btn-send.png" alt="ส่ง"></button>
</form>
<p class="ai-chat-admin-link"><a href="ai-admin.html">ตั้งค่า AI (Admin)</a></p>
</div>
<!-- READY / ไมค์ อยู่นอก overlay — กดได้ทุกจำนวนคนในห้อง ไม่โดนบังจากแผงรายชื่อยาว -->
<div class="room-lobby-ready-fixed">
File diff suppressed because it is too large Load Diff
-1
View File
@@ -208,7 +208,6 @@
<img src="../Game/img/chat-btn-send.png" alt="" decoding="async">
</button>
</form>
<p class="lobby-ai-chat-admin-link"><a href="../Game/ai-admin.html" target="_blank" rel="noopener noreferrer">ตั้งค่า AI (Admin)</a></p>
</div>
<div id="lobby-howto-overlay" class="lobby-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="lobby-howto-title">
@@ -0,0 +1,245 @@
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Main Lobby — JD JUSTICE DIVERS</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Kanit:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css?v=0.0190">
<link rel="stylesheet" href="daily-popup.css?v=8">
<link rel="stylesheet" href="../Game/css/customize-popup.css?v=43">
<link rel="stylesheet" href="../Game/css/profile-popup.css?v=7">
</head>
<body class="lobby-page">
<div class="lobby-bg" role="img" aria-label="พื้นหลัง">
<img src="IMAGE/BG-Main-Lobby.png" alt="" class="lobby-bg-img" role="presentation" decoding="async">
</div>
<div class="lobby-vignette" aria-hidden="true"></div>
<div class="lobby-ui">
<header class="lobby-header">
<div class="lobby-profile-panel">
<img src="IMAGE/profile-bg.png" alt="" class="lobby-profile-bg" role="presentation" decoding="async">
<div class="lobby-profile-inner">
<div class="lobby-avatar-wrap">
<img src="" alt="" class="lobby-avatar-mask" id="lobby-profile-avatar" width="50" height="50" decoding="async">
</div>
<div class="lobby-profile-info">
<p class="lobby-profile-name" id="lobby-profile-name">MONE</p>
<p class="lobby-profile-meta">AGENT ID : <span id="lobby-profile-agent-id">001998</span></p>
<p class="lobby-profile-coins">
<img src="IMAGE/coin-JD.png" alt="" class="lobby-coin-icon" role="presentation" width="18" height="18" decoding="async">
COINS : <span id="lobby-profile-coins">0</span>
</p>
</div>
</div>
</div>
<div class="lobby-news-wrap">
<img src="IMAGE/news-banner-bg.png" alt="" class="lobby-news-bg" role="presentation" decoding="async">
<img src="IMAGE/news.png" alt="ข่าวสารศูนย์บัญชาการ" class="lobby-news-img" role="presentation" decoding="async">
</div>
<div class="lobby-header-row2-left">
<button type="button" class="lobby-btn-tutorial" id="btn-tutorial" title="วิธีเล่น" aria-label="วิธีเล่น">
<img src="IMAGE/btn-tutorial.png" alt="" class="lobby-btn-tutorial-img" role="presentation" decoding="async">
</button>
</div>
<button type="button" class="lobby-btn-daily" id="btn-daily" aria-label="รางวัลประจำวัน">
<img src="IMAGE/daily-rewards.png" alt="" class="lobby-daily-img" role="presentation" decoding="async">
<span class="lobby-daily-dot" aria-hidden="true"></span>
</button>
</header>
<div class="lobby-character-area">
<div class="lobby-center-left">
<button type="button" class="lobby-btn-cloth" id="btn-cloth" aria-label="ห้องแต่งตัว">
<img src="IMAGE/btn-cloth.png" alt="" class="lobby-btn-cloth-img" role="presentation" decoding="async">
</button>
</div>
<div class="lobby-character-center" id="lobby-character-center" aria-hidden="true">
<img id="lobby-character-img" src="" alt="" class="lobby-character-img" width="256" height="256" decoding="async">
</div>
</div>
<aside class="lobby-leaderboard" aria-label="กระดานผู้นำ">
<img src="IMAGE/leaderboard-bg.png" alt="" class="lobby-leaderboard-bg" role="presentation" decoding="async">
<div class="lobby-leaderboard-mask">
<div class="lobby-leaderboard-inner">
<div class="lobby-leaderboard-scroll">
<ul class="lobby-leaderboard-list">
<li>
<img src="IMAGE/leaderboard-1.png" alt="" class="lobby-rank-icon" role="presentation" decoding="async">
<div class="lobby-rank-info">
<span class="lobby-rank-name">Mixie Kim</span>
<span class="lobby-rank-case">(คดี : มหาเศรษฐีนามปลอม)</span>
</div>
<span class="lobby-rank-score">9999</span>
</li>
<li>
<img src="IMAGE/leaderboard-2.png" alt="" class="lobby-rank-icon" role="presentation" decoding="async">
<div class="lobby-rank-info">
<span class="lobby-rank-name">Golden L.</span>
<span class="lobby-rank-case">(คดี : โจรกรรมไซเบอร์)</span>
</div>
<span class="lobby-rank-score">9951</span>
</li>
<li>
<img src="IMAGE/leaderboard-3.png" alt="" class="lobby-rank-icon" role="presentation" decoding="async">
<div class="lobby-rank-info">
<span class="lobby-rank-name">Lilly 991</span>
<span class="lobby-rank-case">(คดี : ปั่นแอพพลวงเกม)</span>
</div>
<span class="lobby-rank-score">9552</span>
</li>
<li>
<span class="lobby-rank-num">4</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Nova Byte</span>
<span class="lobby-rank-case">(คดี : ฟิชชิงองค์กร)</span>
</div>
<span class="lobby-rank-score">9410</span>
</li>
<li>
<span class="lobby-rank-num">5</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Aster R.</span>
<span class="lobby-rank-case">(คดี : แก๊งค์หลอกลงทุน)</span>
</div>
<span class="lobby-rank-score">9280</span>
</li>
<li>
<span class="lobby-rank-num">6</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Hexa One</span>
<span class="lobby-rank-case">(คดี : เจาะระบบธนาคาร)</span>
</div>
<span class="lobby-rank-score">9145</span>
</li>
<li>
<span class="lobby-rank-num">7</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Mint C.</span>
<span class="lobby-rank-case">(คดี : ปลอมเพจขายสินค้า)</span>
</div>
<span class="lobby-rank-score">9032</span>
</li>
<li>
<span class="lobby-rank-num">8</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Q-Logic</span>
<span class="lobby-rank-case">(คดี : หลอกโอนผ่านแชท)</span>
</div>
<span class="lobby-rank-score">8918</span>
</li>
<li>
<span class="lobby-rank-num">9</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Rin 47</span>
<span class="lobby-rank-case">(คดี : ลักข้อมูลส่วนบุคคล)</span>
</div>
<span class="lobby-rank-score">8804</span>
</li>
<li>
<span class="lobby-rank-num">10</span>
<div class="lobby-rank-info">
<span class="lobby-rank-name">Skyline X</span>
<span class="lobby-rank-case">(คดี : ฟอกเงินคริปโต)</span>
</div>
<span class="lobby-rank-score">8690</span>
</li>
</ul>
</div>
<div class="lobby-leaderboard-scroll-track" id="lobby-leaderboard-scroll-track" aria-hidden="true"></div>
<div class="lobby-leaderboard-scroll-thumb" id="lobby-leaderboard-scroll-thumb" aria-hidden="true"></div>
</div>
</div>
</aside>
<footer class="lobby-footer">
<div class="lobby-footer-left">
<button type="button" class="lobby-btn-ai-chat" id="btn-ai-chat" aria-label="เทพความรู้">
<img src="IMAGE/BTN-AI-ChatBOT.png" alt="" class="lobby-btn-ai-chat-img" role="presentation" decoding="async">
</button>
</div>
<div class="lobby-footer-center">
<button type="button" class="lobby-btn-start" id="btn-start-mission" aria-label="ไปเมนูหลัก" data-href="../Main-Menu/">
<img src="IMAGE/btn-start-mission.png" alt="" class="lobby-btn-start-img" role="presentation" decoding="async">
</button>
<button type="button" class="lobby-btn-quiz" id="btn-quiz-battle" aria-label="ห้องเกมตอบคำถาม" data-href="../Quiz-Battle/">
<img src="IMAGE/btn-quix%20battle.png" alt="" class="lobby-btn-quiz-img" role="presentation" decoding="async">
</button>
</div>
<div class="lobby-footer-right">
<button type="button" class="lobby-btn-profile" id="btn-myprofile" aria-label="โปรไฟล์ของฉัน">
<img src="IMAGE/btn-myprofile.png" alt="" class="lobby-btn-profile-img" role="presentation" decoding="async">
</button>
</div>
</footer>
<div id="lobby-guide-dim" class="lobby-guide-dim hidden" aria-hidden="true"></div>
<div id="lobby-guide-focus" class="lobby-guide-focus hidden" aria-hidden="true"></div>
<div class="lobby-guide-bar hidden" id="lobby-guide-bar" role="dialog" aria-modal="true" aria-labelledby="guide-img-label">
<span id="guide-img-label" class="sr-only">คำแนะนำทีละขั้น</span>
<div class="lobby-guide-frame">
<img src="IMAGE/guide/guide-01.png" alt="คำแนะนำ" class="lobby-guide-img" id="guide-img" decoding="async">
<button type="button" class="lobby-guide-next" id="btn-guide-next" aria-label="ถัดไป">
<img src="IMAGE/guide/btn-next.png" alt="" decoding="async">
</button>
</div>
</div>
</div>
<!-- แชท AI — API เดียวกับ room-lobby -->
<div id="lobby-ai-chat-panel" class="lobby-ai-chat-panel lobby-ai-chat-hidden" role="dialog" aria-label="เทพความรู้">
<div class="lobby-ai-chat-header">
<span class="lobby-ai-chat-title">
<img src="../Game/img/ai-chat-header.png" alt="คุยกับ AI" decoding="async">
<img src="../Game/img/ai-chat-title-label.png" alt="เทพความรู้" class="lobby-ai-chat-title-label" decoding="async">
</span>
<button type="button" class="lobby-ai-chat-close" id="lobby-ai-chat-close-btn" title="ปิดแชท AI" aria-label="ปิดแชท AI">
<img src="../Game/img/chat-close-btn.png" alt="ปิด" id="lobby-ai-chat-toggle-img" width="50" height="50" decoding="async">
</button>
</div>
<div id="lobby-ai-chat-messages" class="lobby-ai-chat-messages"></div>
<form id="lobby-ai-chat-form" class="lobby-ai-chat-form">
<input id="lobby-ai-chat-input" type="text" placeholder="Type a here..." autocomplete="off" aria-label="ข้อความถึง AI">
<button type="submit" class="lobby-ai-chat-send" title="ส่ง" aria-label="ส่ง">
<img src="../Game/img/chat-btn-send.png" alt="" decoding="async">
</button>
</form>
<p class="lobby-ai-chat-admin-link"><a href="../Game/ai-admin.html" target="_blank" rel="noopener noreferrer">ตั้งค่า AI (Admin)</a></p>
</div>
<div id="lobby-howto-overlay" class="lobby-overlay hidden" role="dialog" aria-modal="true" aria-labelledby="lobby-howto-title">
<div class="lobby-howto-inner">
<h2 id="lobby-howto-title" class="sr-only">วิธีเล่น</h2>
<img src="IMAGE/Howto/howtoplay.png" alt="วิธีเล่น" decoding="async">
<div class="lobby-howto-close">
<button type="button" class="lobby-icon-btn" id="btn-howto-got-it" aria-label="เข้าใจแล้ว">
<img src="IMAGE/Howto/btn-got-it.png" alt="" decoding="async" onerror="this.style.display='none'; this.parentElement.textContent='ปิด';">
</button>
</div>
</div>
</div>
<div id="lobby-toast" class="lobby-toast" role="status" aria-live="polite"></div>
<script src="../app-base.js?v=2"></script>
<script src="../Game/js/display-name.js?v=2"></script>
<script src="daily-popup.js?v=26" data-daily-trigger="#btn-daily" data-daily-asset-base="IMAGE/Daily" data-daily-test-reset-seconds="0"></script>
<script src="../Game/js/customize-popup.js?v=38" data-customize-triggers="#btn-cloth" data-customize-asset-base="/Game/img/03-5-Customize"></script>
<script src="../Game/js/achievements.js?v=0.002" data-asset-base="/Game/img/03-6-Profile"></script>
<script src="../Game/js/sound.js?v=1"></script>
<script src="../Game/js/profile-popup.js?v=9" data-profile-trigger="#btn-myprofile" data-profile-asset-base="/Game/img/03-6-Profile"></script>
<script src="lobby.js?v=0.0194"></script>
<script>
/* เสียงคลิกปุ่มใน Main-Lobby (เฉพาะปุ่มจริง) */
document.addEventListener('click', function (e) {
if (!window.jdSound) return;
var t = (e.target && e.target.closest) ? e.target.closest('button, .btn, [role="button"], [class*="btn-"]') : null;
if (t) { try { window.jdSound.playSfx('button', 'lobby'); } catch (err) { /* ignore */ } }
}, true);
</script>
</body>
</html>
File diff suppressed because it is too large Load Diff