update flow 2.1

This commit is contained in:
2026-06-04 05:15:04 +00:00
parent 04a045b59d
commit d2122d267d
202 changed files with 287 additions and 26 deletions
+6
View File
@@ -2787,6 +2787,12 @@ code {
border: 1px solid rgba(124, 154, 255, 0.18);
}
.cm-pick select { width: 100%; }
.cm-section-title {
margin: 1.25rem 0 0.5rem;
font-size: 1.05rem;
font-weight: 800;
color: #a8b8ff;
}
.ev-suspect-block {
border: 1px solid rgba(124, 154, 255, 0.25);
+33 -2
View File
@@ -4207,8 +4207,11 @@
if (caseMediaImages == null) {
fetch(CASE_MEDIA_IMAGES_API + '?_=' + Date.now(), { credentials: 'include', cache: 'no-store' })
.then(function (r) { return r.json(); })
.then(function (j) { caseMediaImages = (j && j.images) || { case: [], cutscene: [] }; renderCaseMedia(caseMediaCurrent); })
.catch(function () { caseMediaImages = { case: [], cutscene: [] }; });
.then(function (j) {
caseMediaImages = (j && j.images) || { case: [], cutscene: [], 'suspect-pick': [], 'culprit-prison': [] };
renderCaseMedia(caseMediaCurrent);
})
.catch(function () { caseMediaImages = { case: [], cutscene: [], 'suspect-pick': [], 'culprit-prison': [] }; });
}
fetch(CASE_MEDIA_API + '?_=' + Date.now(), { credentials: 'include', cache: 'no-store' })
.then(function (r) { return r.json(); })
@@ -4235,6 +4238,12 @@
if (!Array.isArray(c.story)) c.story = [];
if (typeof c.story[0] !== 'string') c.story[0] = '/Main-Lobby/IMAGE/cutscene/case-' + n + '-story-1.png';
if (typeof c.story[1] !== 'string') c.story[1] = '/Main-Lobby/IMAGE/cutscene/case-' + n + '-story-2.png';
if (!Array.isArray(c.suspects) || c.suspects.length < 3) {
c.suspects = [1, 2, 3].map(function (s) { return '/Main-Lobby/IMAGE/suspect-pick/case-' + n + '-suspect-' + s + '.png'; });
}
if (!Array.isArray(c.culprits) || c.culprits.length < 3) {
c.culprits = [1, 2, 3].map(function (s) { return '/Main-Lobby/IMAGE/culprit-prison/case-' + n + '-suspect-' + s + '.png'; });
}
return c;
}
@@ -4284,6 +4293,28 @@
grid.appendChild(caseMediaImagePicker('Cutscene รูปที่ 1', 'cutscene', c.story[0], function (v) { c.story[0] = v; }));
grid.appendChild(caseMediaImagePicker('Cutscene รูปที่ 2', 'cutscene', c.story[1], function (v) { c.story[1] = v; }));
root.appendChild(grid);
var susHead = document.createElement('h3');
susHead.className = 'cm-section-title';
susHead.textContent = 'เลือกผู้ต้องสงสัย (3 คน) — LobbyB';
root.appendChild(susHead);
var susGrid = document.createElement('div');
susGrid.className = 'cm-grid';
[0, 1, 2].forEach(function (si) {
susGrid.appendChild(caseMediaImagePicker('ผู้ต้องสงสัย ' + (si + 1), 'suspect-pick', c.suspects[si], function (v) { c.suspects[si] = v; }));
});
root.appendChild(susGrid);
var culHead = document.createElement('h3');
culHead.className = 'cm-section-title';
culHead.textContent = 'ส่งผู้ร้ายเข้าคุก (3 คน) — หน้าผลพิจารณาคดี';
root.appendChild(culHead);
var culGrid = document.createElement('div');
culGrid.className = 'cm-grid';
[0, 1, 2].forEach(function (si) {
culGrid.appendChild(caseMediaImagePicker('คนร้ายในคุก ' + (si + 1), 'culprit-prison', c.culprits[si], function (v) { c.culprits[si] = v; }));
});
root.appendChild(culGrid);
}
function saveCaseMediaPanel() {
+2 -2
View File
@@ -335,7 +335,7 @@
<section id="tab-panel-case-media" class="tab-panel card" hidden role="tabpanel" aria-labelledby="tab-case-media">
<h2 class="sq-title">รูปคดี &amp; Cutscene — LobbyA → LobbyB</h2>
<p class="muted">มี <strong>15 คดี</strong> · แต่ละคดีตั้งได้: <strong>ชื่อคดี</strong>, <strong>รูปการ์ดเลือกคดี</strong>, <strong>รูปรายละเอียดคดี</strong>, และ <strong>Cutscene 2 รูป</strong> (โชว์ก่อนเข้า LobbyB · ต้องกด «ไปต่อ») · เลือกรูปจากที่อัปโหลดไว้ใน <code>/Main-Lobby/IMAGE/case</code> และ <code>/Main-Lobby/IMAGE/cutscene</code> · เก็บที่ <code>/Game/data/case-media.json</code></p>
<p class="muted">มี <strong>15 คดี</strong> · แต่ละคดีตั้งได้: <strong>ชื่อคดี</strong>, <strong>รูปการ์ดเลือกคดี</strong>, <strong>รูปรายละเอียด</strong>, <strong>Cutscene 2 รูป</strong>, <strong>ผู้ต้องสงสัย 3 คน</strong> (หน้าเลือกผู้ต้องสงสัย/โหวต), <strong>ส่งผู้ร้ายเข้าคุก 3 คน</strong> (หน้าผลพิจารณาคดีเมื่อชี้ถูก) · โฟลเดอร์รูป: <code>case</code>, <code>cutscene</code>, <code>suspect-pick</code>, <code>culprit-prison</code> · เก็บที่ <code>/Game/data/case-media.json</code></p>
<fieldset class="sq-fieldset sq-pick">
<legend>เลือกคดีที่จะแก้</legend>
@@ -1059,6 +1059,6 @@
</div>
</main>
</div>
<script src="admin.js?v=78"></script>
<script src="admin.js?v=79"></script>
</body>
</html>
+150
View File
@@ -7,6 +7,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-1-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-1-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-1-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-1-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-1-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-1-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-1-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-1-suspect-3.png"
]
},
"2": {
@@ -16,6 +26,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-2-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-2-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-2-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-2-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-2-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-2-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-2-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-2-suspect-3.png"
]
},
"3": {
@@ -25,6 +45,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-3-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-3-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-3-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-3-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-3-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-3-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-3-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-3-suspect-3.png"
]
},
"4": {
@@ -34,6 +64,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-4-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-4-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-4-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-4-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-4-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-4-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-4-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-4-suspect-3.png"
]
},
"5": {
@@ -43,6 +83,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-5-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-5-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-5-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-5-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-5-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-5-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-5-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-5-suspect-3.png"
]
},
"6": {
@@ -52,6 +102,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-6-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-6-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-6-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-6-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-6-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-6-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-6-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-6-suspect-3.png"
]
},
"7": {
@@ -61,6 +121,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-7-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-7-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-7-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-7-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-7-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-7-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-7-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-7-suspect-3.png"
]
},
"8": {
@@ -70,6 +140,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-8-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-8-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-8-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-8-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-8-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-8-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-8-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-8-suspect-3.png"
]
},
"9": {
@@ -79,6 +159,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-9-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-9-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-9-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-9-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-9-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-9-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-9-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-9-suspect-3.png"
]
},
"10": {
@@ -88,6 +178,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-10-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-10-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-10-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-10-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-10-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-10-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-10-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-10-suspect-3.png"
]
},
"11": {
@@ -97,6 +197,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-11-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-11-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-11-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-11-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-11-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-11-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-11-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-11-suspect-3.png"
]
},
"12": {
@@ -106,6 +216,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-12-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-12-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-12-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-12-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-12-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-12-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-12-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-12-suspect-3.png"
]
},
"13": {
@@ -115,6 +235,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-13-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-13-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-13-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-13-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-13-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-13-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-13-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-13-suspect-3.png"
]
},
"14": {
@@ -124,6 +254,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-14-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-14-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-14-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-14-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-14-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-14-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-14-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-14-suspect-3.png"
]
},
"15": {
@@ -133,6 +273,16 @@
"story": [
"/Main-Lobby/IMAGE/cutscene/case-15-story-1.png",
"/Main-Lobby/IMAGE/cutscene/case-15-story-2.png"
],
"suspects": [
"/Main-Lobby/IMAGE/suspect-pick/case-15-suspect-1.png",
"/Main-Lobby/IMAGE/suspect-pick/case-15-suspect-2.png",
"/Main-Lobby/IMAGE/suspect-pick/case-15-suspect-3.png"
],
"culprits": [
"/Main-Lobby/IMAGE/culprit-prison/case-15-suspect-1.png",
"/Main-Lobby/IMAGE/culprit-prison/case-15-suspect-2.png",
"/Main-Lobby/IMAGE/culprit-prison/case-15-suspect-3.png"
]
}
}
+77 -19
View File
@@ -1781,6 +1781,7 @@
function openLobbyPreplayWizard() {
if (!getPreplayEls()) return;
initLobbyPreplayWizard();
ensureCaseMediaLoaded();
preplaySelectedLevel = null;
delete preplayOverlay.dataset.preplayLevel;
preplayOverlay.querySelectorAll('.lobby-level-card.is-selected').forEach(function (el) { el.classList.remove('is-selected'); });
@@ -1819,25 +1820,74 @@
.catch(function () { caseMediaFetchPromise = null; return { cases: {} }; });
return caseMediaFetchPromise;
}
function getDetectiveCaseId() {
try {
var m = window.__detectiveLobbyMeta;
var cid = m && m.caseId != null ? parseInt(m.caseId, 10) : 1;
if (cid >= 1 && cid <= 15) return cid;
} catch (e) { /* ignore */ }
return 1;
}
function getCaseMedia(cid) {
var n = parseInt(cid, 10);
if (!(n >= 1)) n = 1;
if (!(n >= 1 && n <= 15)) n = 1;
var defSuspects = [1, 2, 3].map(function (s) {
return '/Main-Lobby/IMAGE/suspect-pick/case-' + n + '-suspect-' + s + '.png';
});
var defCulprits = [1, 2, 3].map(function (s) {
return '/Main-Lobby/IMAGE/culprit-prison/case-' + n + '-suspect-' + s + '.png';
});
var def = {
name: 'คดีที่ ' + n,
art: '/Main-Lobby/IMAGE/case/case-' + n + '.png',
detail: '/Main-Lobby/IMAGE/case/case-detail-' + n + '.png',
story: ['/Main-Lobby/IMAGE/cutscene/case-' + n + '-story-1.png', '/Main-Lobby/IMAGE/cutscene/case-' + n + '-story-2.png'],
suspects: defSuspects,
culprits: defCulprits,
};
var c = (caseMediaData && caseMediaData.cases) ? (caseMediaData.cases[n] || caseMediaData.cases[String(n)]) : null;
if (!c) return def;
var suspects = (Array.isArray(c.suspects) && c.suspects.length >= 3) ? c.suspects.slice(0, 3) : def.suspects;
var culprits = (Array.isArray(c.culprits) && c.culprits.length >= 3) ? c.culprits.slice(0, 3) : def.culprits;
return {
name: c.name || def.name,
art: c.art || def.art,
detail: c.detail || def.detail,
story: (Array.isArray(c.story) && c.story.length) ? c.story : def.story,
suspects: suspects,
culprits: culprits,
};
}
function getSuspectPickImageUrl(suspectIndex) {
var i = Math.max(0, Math.min(2, Math.floor(Number(suspectIndex)) || 0));
var m = getCaseMedia(getDetectiveCaseId());
return (m.suspects && m.suspects[i]) || ('/Main-Lobby/IMAGE/Choose%20a%20suspect/suspect-' + (i + 1) + '.png');
}
function getCulpritPrisonImageUrl(suspectIndex) {
var i = Math.max(0, Math.min(2, Math.floor(Number(suspectIndex)) || 0));
var m = getCaseMedia(getDetectiveCaseId());
return (m.culprits && m.culprits[i]) || ('/Main-Lobby/IMAGE/Choose%20a%20suspect/suspect-' + (i + 1) + '.png');
}
/** อัปเดตรูปผู้ต้องสงสัย 3 ใบตามคดีปัจจุบัน (เลือกผู้ต้องสงสัย + โหวตพิจารณาคดี) */
function applySuspectPickImages() {
var cards = document.querySelectorAll('#suspect-cards-row .suspect-card');
if (!cards.length) return;
function paint() {
cards.forEach(function (card) {
var idx = parseInt(card.getAttribute('data-index'), 10);
if (Number.isNaN(idx) || idx < 0 || idx > 2) return;
var img = card.querySelector(':scope > img');
if (img) img.src = getSuspectPickImageUrl(idx);
});
}
if (caseMediaData) paint();
else ensureCaseMediaLoaded().then(paint);
}
/** สร้างการ์ดเลือกคดีตามระดับที่เลือก — 5 ระดับ × 3 คดี (L1=1-3, L2=4-6 … L5=13-15) */
function renderPreplayCaseCards() {
var row = preplayOverlay ? preplayOverlay.querySelector('.lobby-preplay-case-row') : null;
@@ -2927,6 +2977,18 @@
if (ROOM_CZ_SPOT) appendLobbySystemChat('— เดินไปช่องเขียว แล้วกด F เพื่อเปิดห้องแต่งตัว');
if (ROOM_HC_SPOT && hostId === socket.id) appendLobbySystemChat('— เดินไปจุดโฮสต์ (ไอคอนชมพู) แล้วกด F เพื่อเปิด Host Console');
clientLobbyMapId = res.mapId != null ? res.mapId : null;
if (res.detectiveLobbyCaseId != null) {
try {
window.__detectiveLobbyMeta = {
level: res.detectiveLobbyLevel != null ? res.detectiveLobbyLevel : null,
caseId: res.detectiveLobbyCaseId,
};
} catch (eMeta) { /* ignore */ }
ensureCaseMediaLoaded().then(function () {
applySuspectPickImages();
refreshSuspectCaseLabel();
});
}
hostId = res.hostId || null;
spaceName = (res.spaceName || '').trim() || spaceId;
(res.peers || []).forEach(p => { peers.set(p.id, normalizeLobbyPeerFromServer(p, mapData)); });
@@ -4272,13 +4334,9 @@
function getLobbyRankCaseTitle() {
try {
const meta = window.__detectiveLobbyMeta;
const cid = meta && meta.caseId != null ? String(meta.caseId).trim() : '';
if (cid === '2') return 'คดีปล้นร้านอัญมณี';
if (cid === '3') return 'คดีฆาตกรรมปริศนา';
return 'คดีโจรกรรมไซเบอร์';
return getCaseMedia(getDetectiveCaseId()).name || 'คดี';
} catch (e) {
return 'คดีโจรกรรมไซเบอร์';
return 'คดี';
}
}
@@ -4488,12 +4546,7 @@
function refreshSuspectCaseLabel() {
const el = document.getElementById('suspect-case-label');
if (!el) return;
let meta = null;
try { meta = window.__detectiveLobbyMeta; } catch (e) { meta = null; }
const cid = meta && meta.caseId != null ? String(meta.caseId).trim() : '';
if (cid === '2') el.textContent = 'คดีปล้นร้านอัญมณี';
else if (cid === '3') el.textContent = 'คดีฆาตกรรมปริศนา';
else el.textContent = 'คดีโจรกรรมไซเบอร์';
el.textContent = getCaseMedia(getDetectiveCaseId()).name || 'คดี';
}
function setSuspectCardMinigames(cards) {
@@ -4748,6 +4801,7 @@
injectTrialStyle();
var ov = document.getElementById('suspect-pick-overlay');
if (!ov) return;
applySuspectPickImages();
bindSuspectPickScaleListeners();
suspectPickOverlayOpen = true;
serverSuspectPhaseActive = false;
@@ -4871,7 +4925,6 @@
function showFinalResult(correct, culprit) {
injectFinalResultStyle();
var R = '/Main-Lobby/IMAGE/Result/';
var CS = '/Main-Lobby/IMAGE/Choose%20a%20suspect/';
var ov = document.getElementById('trial-final');
if (!ov) {
ov = document.createElement('div');
@@ -4886,7 +4939,11 @@
var txtEl = ov.querySelector('#trial-final-txt');
if (correct) {
ov.style.backgroundImage = 'url(' + R + 'cyber-prison.png)';
if (culpEl) { culpEl.src = CS + 'suspect-' + (((typeof culprit === 'number' ? culprit : 0)) + 1) + '.png'; culpEl.style.display = 'block'; }
var culpIdx = (typeof culprit === 'number') ? culprit : 0;
if (culpEl) {
culpEl.src = getCulpritPrisonImageUrl(culpIdx);
culpEl.style.display = 'block';
}
if (txtEl) txtEl.style.display = 'none';
} else {
ov.style.backgroundImage = 'url(' + R + 'lose-bg.png)';
@@ -5409,11 +5466,10 @@
/* ต้องเลือกหลักฐาน = min(2, จำนวนที่เก็บได้) — ถ้าได้ 1 ใบ ส่ง 1 ใบพอ */
tmState.requiredPicks = Math.max(1, Math.min(2, tmState.ownedSlots.length));
var SC = '/Main-Lobby/IMAGE/Showcard/';
var CS = '/Main-Lobby/IMAGE/Choose%20a%20suspect/';
var sd = tmSuspectData(tmState.round);
document.getElementById('es3-title').textContent = 'การไต่สวน : ปากคำที่ ' + (tmState.round + 1) + ' - ' + (sd.linkName || ('ผู้ต้องสงสัย ' + (tmState.round + 1)));
var susImg = document.getElementById('es3-sus-img');
if (susImg) susImg.src = CS + 'suspect-' + (tmState.round + 1) + '.png';
if (susImg) susImg.src = getSuspectPickImageUrl(tmState.round);
var susName = document.getElementById('es3-sus-name'); if (susName) susName.textContent = sd.linkName || '';
var stage = ov.querySelector('.es3-stage');
if (stage) stage.classList.remove('es3-stage--reveal');
@@ -5480,7 +5536,6 @@
if (data && typeof data.round === 'number') tmState.round = data.round;
if (data && Array.isArray(data.members)) tmState.members = data.members;
var SC = '/Main-Lobby/IMAGE/Showcard/';
var CS = '/Main-Lobby/IMAGE/Choose%20a%20suspect/';
var sd = tmSuspectData(tmState.round);
var stage = ov.querySelector('.es3-stage');
if (stage) stage.classList.add('es3-stage--reveal');
@@ -5489,7 +5544,7 @@
var titleEl = document.getElementById('es-popup-title');
if (titleEl) titleEl.textContent = 'การไต่สวน : ปากคำที่ ' + (tmState.round + 1) + ' - ' + (sd.linkName || ('ผู้ต้องสงสัย ' + (tmState.round + 1)));
var susImg = document.getElementById('es-popup-sus-img');
if (susImg) susImg.src = CS + 'suspect-' + (tmState.round + 1) + '.png';
if (susImg) susImg.src = getSuspectPickImageUrl(tmState.round);
var susName = document.getElementById('es-popup-sus-name');
if (susName) susName.textContent = sd.linkName || '';
var rd = document.getElementById('esBtnReady');
@@ -5795,6 +5850,7 @@
if (!ov) return;
bindSuspectPickScaleListeners();
refreshSuspectCaseLabel();
applySuspectPickImages();
suspectPickOverlayOpen = true;
ov.classList.remove('is-hidden');
ov.setAttribute('aria-hidden', 'false');
@@ -6238,6 +6294,8 @@
caseId: data.caseId || null
};
} catch (e) { /* ignore */ }
applySuspectPickImages();
refreshSuspectCaseLabel();
troublesomeEligibleSent = false;
resizeAndDraw();
updateHostStartGameButton();
+1 -1
View File
@@ -1613,7 +1613,7 @@
<script src="js/display-name.js?v=2"></script>
<script src="js/version.js?v=0.0122"></script>
<script src="js/customize-popup.js?v=31" data-customize-triggers="" data-customize-asset-base="img/03-5-Customize"></script>
<script src="js/room-lobby.js?v=0.0267"></script>
<script src="js/room-lobby.js?v=0.0268"></script>
<div class="version-tag">v —</div>
</body>
</html>
+18 -2
View File
@@ -1206,6 +1206,8 @@ const CASE_MEDIA_COUNT = 15;
const MAIN_LOBBY_IMAGE_ROOT = path.join(__dirname, '..', 'Main-Lobby', 'IMAGE');
function caseMediaDefault(n) {
const suspects = [1, 2, 3].map((s) => '/Main-Lobby/IMAGE/suspect-pick/case-' + n + '-suspect-' + s + '.png');
const culprits = [1, 2, 3].map((s) => '/Main-Lobby/IMAGE/culprit-prison/case-' + n + '-suspect-' + s + '.png');
return {
name: 'คดีที่ ' + n,
art: '/Main-Lobby/IMAGE/case/case-' + n + '.png',
@@ -1214,9 +1216,17 @@ function caseMediaDefault(n) {
'/Main-Lobby/IMAGE/cutscene/case-' + n + '-story-1.png',
'/Main-Lobby/IMAGE/cutscene/case-' + n + '-story-2.png',
],
suspects,
culprits,
};
}
function sanitizeCaseMediaUrlList(arr, fallbackArr) {
const fb = Array.isArray(fallbackArr) ? fallbackArr : [];
const src = Array.isArray(arr) ? arr : [];
return [0, 1, 2].map((i) => sanitizeCaseMediaUrl(src[i], fb[i] || fb[0] || ''));
}
/** อนุญาตเฉพาะ path รูปภายในเว็บ (กัน URL ภายนอก/สคริปต์) — ไม่ผ่าน → คืนค่า fallback */
function sanitizeCaseMediaUrl(v, fallback) {
if (typeof v !== 'string') return fallback;
@@ -1238,6 +1248,8 @@ function sanitizeCaseMedia(obj) {
art: sanitizeCaseMediaUrl(c.art, d.art),
detail: sanitizeCaseMediaUrl(c.detail, d.detail),
story: [sanitizeCaseMediaUrl(story[0], d.story[0]), sanitizeCaseMediaUrl(story[1], d.story[1])],
suspects: sanitizeCaseMediaUrlList(c.suspects, d.suspects),
culprits: sanitizeCaseMediaUrlList(c.culprits, d.culprits),
};
}
return { cases };
@@ -1267,8 +1279,8 @@ function saveCaseMedia(d) {
/** รายการรูปที่มีจริงในโฟลเดอร์ case / cutscene (ไว้ให้ Admin เลือก) */
function listCaseMediaImages() {
const out = { case: [], cutscene: [] };
['case', 'cutscene'].forEach((sub) => {
const out = { case: [], cutscene: [], 'suspect-pick': [], 'culprit-prison': [] };
['case', 'cutscene', 'suspect-pick', 'culprit-prison'].forEach((sub) => {
try {
const p = path.join(MAIN_LOBBY_IMAGE_ROOT, sub);
out[sub] = fs.readdirSync(p)
@@ -5984,6 +5996,10 @@ io.on('connection', (socket) => {
lobbyBotThemes: syncLobbyBotThemeSlots(space),
joinLocked: !!space.joinLocked,
};
if (serverMapIsPostCaseLobbyB(space)) {
joinCb.detectiveLobbyLevel = space.detectiveLobbyLevel != null ? space.detectiveLobbyLevel : null;
joinCb.detectiveLobbyCaseId = space.detectiveLobbyCaseId != null ? space.detectiveLobbyCaseId : null;
}
if (mdJoin.gameType === 'quiz_carry' || spaceAllowsQuizCarryLobbyRelaxed(space)) {
try {
const qs = loadQuizSettings();
Binary file not shown.

After

Width:  |  Height:  |  Size: 652 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Some files were not shown because too many files have changed in this diff Show More