updatee game 5and flow and loading
This commit is contained in:
@@ -51,9 +51,9 @@
|
||||
"providerUserId": "p_1775109142385_wq7wfy1p32j",
|
||||
"notes": "auto: player-coins",
|
||||
"blocked": false,
|
||||
"coins": 2072,
|
||||
"coins": 2140,
|
||||
"createdAt": "2026-04-02T05:52:21+00:00",
|
||||
"updatedAt": "2026-06-26T07:58:33+00:00",
|
||||
"updatedAt": "2026-06-26T10:25:41+00:00",
|
||||
"daily": {
|
||||
"anchorMs": 1781197200000,
|
||||
"claimedDays": [
|
||||
@@ -67,13 +67,13 @@
|
||||
],
|
||||
"lockUntilMs": 0
|
||||
},
|
||||
"score": 18,
|
||||
"score": 86,
|
||||
"scoreByCase": {
|
||||
"1": 16,
|
||||
"10": 514,
|
||||
"10": 562,
|
||||
"8": 296,
|
||||
"11": 20,
|
||||
"13": 224,
|
||||
"13": 234,
|
||||
"14": 30,
|
||||
"9": 40,
|
||||
"12": 408,
|
||||
@@ -83,7 +83,7 @@
|
||||
"7": 6,
|
||||
"3": 142,
|
||||
"6": 44,
|
||||
"2": 80
|
||||
"2": 90
|
||||
},
|
||||
"lbName": "Q",
|
||||
"achievements": {
|
||||
@@ -651,19 +651,20 @@
|
||||
"providerUserId": "p_1782016990238_0u37bv7pxlxs",
|
||||
"notes": "auto: player-coins",
|
||||
"blocked": false,
|
||||
"coins": 288,
|
||||
"coins": 368,
|
||||
"createdAt": "2026-06-21T04:43:11+00:00",
|
||||
"updatedAt": "2026-06-26T08:07:51+00:00",
|
||||
"updatedAt": "2026-06-26T09:44:40+00:00",
|
||||
"lobbyColorThemeIndex": 8,
|
||||
"lobbySkinToneIndex": 1,
|
||||
"score": 258,
|
||||
"score": 338,
|
||||
"scoreByCase": {
|
||||
"13": 82,
|
||||
"10": 120,
|
||||
"10": 172,
|
||||
"6": 8,
|
||||
"8": 20,
|
||||
"2": 18,
|
||||
"3": 10
|
||||
"2": 36,
|
||||
"3": 10,
|
||||
"7": 10
|
||||
},
|
||||
"lbName": "MONE",
|
||||
"achievements": {
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"/Game/img/ViolentCrime/Meteo-3.png"
|
||||
],
|
||||
"spaceShooterAsteroidExplodeFrameMs": 60,
|
||||
"spaceShooterAsteroidIntervalMs": 300,
|
||||
"spaceShooterAsteroidIntervalMs": 200,
|
||||
"spaceShooterShipDamageOverlayUrls": [
|
||||
"/Game/img/ViolentCrime/Rocket-broke-1.png",
|
||||
"/Game/img/ViolentCrime/Rocket-broke-2.png",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"betweenMs": 3000,
|
||||
"carryReadMs": 3000,
|
||||
"carryAnswerMs": 15000,
|
||||
"carrySessionLength": 2,
|
||||
"carrySessionLength": 10,
|
||||
"carryMapPanelTheme": {
|
||||
"panelBg": "rgba(255, 0, 0, 0)",
|
||||
"panelBorder": "rgba(255, 255, 255, 0)",
|
||||
|
||||
+106
-11
@@ -106,7 +106,20 @@
|
||||
ov.innerHTML = '<div class="plo-spin"></div><div class="plo-text">กำลังโหลดเกม…</div>';
|
||||
document.body.insertBefore(ov, document.body.firstChild);
|
||||
}
|
||||
setTimeout(hidePlayLoadingOverlay, 8000); /* safety: กันค้างถ้าโหลดนาน/ติด */
|
||||
/* safety กันค้าง — แต่ "อย่าซ่อนถ้าเกมยังไม่ render" (เน็ตช้า join นาน → ถ้าซ่อน 8 วิ = จอดำเปล่า ไม่รู้สถานะ)
|
||||
เช็คทุก 1.5 วิ: เกมเริ่มวาดแล้ว (playLoadingHideScheduled) → ปล่อย path ปกติซ่อน · ยังไม่วาด+ช้า → โชว์ "เน็ตช้า (N วิ)" คง spinner · เกิน 30 วิ ค่อยซ่อนกันค้างถาวร */
|
||||
const _ploT0 = Date.now();
|
||||
const _ploCheck = function () {
|
||||
if (playLoadingHidden || playLoadingHideScheduled) return; /* ซ่อนแล้ว/เกมเริ่มวาดแล้ว */
|
||||
const waited = Date.now() - _ploT0;
|
||||
if (waited > 30000) { hidePlayLoadingOverlay(); return; } /* hard limit กันค้างถาวร */
|
||||
if (waited > 5000) {
|
||||
const txt = document.querySelector('#play-loading-overlay .plo-text');
|
||||
if (txt) txt.textContent = 'เน็ตช้า… กำลังโหลด (' + Math.floor(waited / 1000) + ' วิ)';
|
||||
}
|
||||
setTimeout(_ploCheck, 1500);
|
||||
};
|
||||
setTimeout(_ploCheck, 1500);
|
||||
} catch (_e) { playLoadingHidden = true; }
|
||||
})();
|
||||
const playMapIdFromQuery = (params.get('map') || '').trim();
|
||||
@@ -730,7 +743,9 @@
|
||||
socket.emit('stack-state', {
|
||||
idx: stackPreviewTurnIndex,
|
||||
/* theme ต่อที่นั่ง (host เป็นเจ้าของ) → ทุกจอลงสี block ตรงกัน (เดิม non-host คำนวณสีเองจาก playTint → ไม่ตรง 2 จอ) */
|
||||
order: stackPreviewTurnOrder.map((e) => ({ kind: e.kind, seat: e.seat, id: e.id, botId: e.botId || null, theme: stackSeatColorThemePlay(e.seat) || null })),
|
||||
order: stackPreviewTurnOrder.map((e) => ({ kind: e.kind, seat: e.seat, id: e.id, botId: e.botId || null, theme: stackSeatThemeForBroadcastPlay(e.seat) })),
|
||||
/* สีของ block ที่ "วางแล้ว" ทั้งหอ (host authoritative) → client sync เขียนทับ layer ที่เพี้ยนค้าง (จากจังหวะ dual-host ต้นเกม) */
|
||||
lthemes: (stackMini && Array.isArray(stackMini.layers)) ? stackMini.layers.map(function (l) { return (l && l.theme >= 1 && l.theme <= 8) ? l.theme : 0; }) : [],
|
||||
});
|
||||
logStackSeatColors('host-bcast');
|
||||
} catch (e) { /* ignore */ }
|
||||
@@ -740,6 +755,29 @@
|
||||
function stackTurnOrderReadyPlay() {
|
||||
return !!(stackPreviewTurnOrder && stackPreviewTurnOrder.length >= 1);
|
||||
}
|
||||
/** (host) คิวตาตรงกับผู้เล่น/บอทปัจจุบันไหม — ใช้ auto-heal late-join (client เข้าทีหลังต้องได้ seat ไม่งั้น "เล่นไม่ได้" + ไม่มีสี)
|
||||
เทียบรายชื่อคน (me + others ที่ไม่ใช่บอท/ไม่ถูกแบน) + บอท กับ entry ในคิว; ต่างเมื่อไหร่ = ต้อง rebuild */
|
||||
let _stackHumansSig = '';
|
||||
function stackOrderNeedsRebuildPlay() {
|
||||
if (!stackTurnOrderReadyPlay() || !Array.isArray(stackPreviewTurnOrder)) return true;
|
||||
/* เช็คเฉพาะ "คน" (humans ≤ maxPlayers จึงลงคิวครบเสมอ ไม่โดน cap ตัด) — บอทจัดการใน rebuild เอง */
|
||||
const cur = [];
|
||||
if (myId != null && !playBannedSpectator) cur.push(String(myId));
|
||||
others.forEach((o, id) => {
|
||||
if (isPreviewBotId(id)) return;
|
||||
if (o && o.bannedSpectator) return;
|
||||
cur.push(String(id));
|
||||
});
|
||||
cur.sort();
|
||||
const sig = cur.join('|');
|
||||
if (sig === _stackHumansSig) return false; /* คนไม่เปลี่ยน → ไม่ต้องเช็ค (กัน rebuild ถี่) */
|
||||
const ord = [];
|
||||
stackPreviewTurnOrder.forEach((e) => { if (e && e.kind !== 'bot' && !e.botId && e.id != null) ord.push(String(e.id)); });
|
||||
ord.sort();
|
||||
const need = (sig !== ord.join('|'));
|
||||
if (!need) _stackHumansSig = sig; /* ตรงแล้ว → cache กันเช็คซ้ำทุกเฟรม */
|
||||
return need;
|
||||
}
|
||||
function stackCurrentTurnEntryPlay() {
|
||||
if (!stackTurnOrderReadyPlay()) return null;
|
||||
return stackPreviewTurnOrder[stackPreviewTurnIndex % stackPreviewTurnOrder.length] || null;
|
||||
@@ -766,8 +804,8 @@
|
||||
pts: hit.pts || 0, progressDelta: hit.progressDelta || 0, landOffsetTiles: hit.landOffsetTiles || 0,
|
||||
overlap: hit.overlap, supportRatio: hit.supportRatio, delta: hit.delta || 0,
|
||||
seat: seat || 1, heavy: !!heavy, actorId: actorId != null ? String(actorId) : '', isBot: !!isBot,
|
||||
/* สี (theme) ที่ host/เจ้าของตา resolve ตอนวาง → ส่งไปด้วย ให้บล็อกที่วางบนทุกจอใช้สีเดียวกัน (กัน host/client คนละสี) */
|
||||
theme: stackSeatColorThemePlay(seat) || null,
|
||||
/* สี (theme) ที่ host/เจ้าของตา resolve ตอนวาง → ส่งไปด้วย ให้บล็อกที่วางบนทุกจอใช้สีเดียวกัน (กัน host/client คนละสี) — never-null */
|
||||
theme: stackSeatThemeForBroadcastPlay(seat),
|
||||
});
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
@@ -843,6 +881,15 @@
|
||||
return ent ? playLobbyThemeIndexForEntityPlay(ent) : null;
|
||||
}
|
||||
|
||||
/** สีที่ host จะ broadcast — "ไม่มีทาง null": resolve ปกติ ไม่ได้ค่อย default ตาม seat
|
||||
→ client (broadcast-first) ยึดค่า host ได้เสมอ ไม่ตกไปคำนวณเอง = สีตรง host ทุกจอแน่นอน */
|
||||
function stackSeatThemeForBroadcastPlay(seat) {
|
||||
const t = stackSeatColorThemePlay(seat);
|
||||
if (t >= 1 && t <= 8) return t;
|
||||
const s = Math.floor(Number(seat)) || 1;
|
||||
return ((s - 1) % 8) + 1;
|
||||
}
|
||||
|
||||
/** ส่ง log ไป /gamelog (ดูรวมที่หน้าเว็บ) */
|
||||
function gamelogPost(cat, ev, detail, who) {
|
||||
try {
|
||||
@@ -855,6 +902,7 @@
|
||||
/** วินิจฉัยสี block MG3 ต่อ seat — เทียบ "สี avatar (playTint)" vs "สี block (resolved)"; ถ้าไม่ตรง → ส่งเข้า /gamelog
|
||||
เรียกเอง: window.__mg3ColorLog() หรือ auto throttle */
|
||||
let _mg3ColorLogAt = 0;
|
||||
let _mg3SnapAt = 0;
|
||||
let _mg3LastMismatchKey = '';
|
||||
function logStackSeatColors(tag, force) {
|
||||
try {
|
||||
@@ -872,13 +920,34 @@
|
||||
return { seat: e.seat, kind: e.kind, nick: (ent && ent.nickname) || String(e.id || e.botId || '').slice(0, 6), avatarIdx: avatarIdx, blockIdx: blockIdx, srv: (ent && ent.lobbyThemeIndexSrv) || null, bc: e.theme || null, ok: (avatarIdx && blockIdx) ? (avatarIdx === blockIdx) : null };
|
||||
});
|
||||
console.log('[mg3-color/' + (tag || '') + '] host=' + isMePlayHost(), JSON.stringify(rows));
|
||||
/* ส่งเฉพาะกรณีพบ mismatch (avatar≠block) → เห็นใน /gamelog (MG3) ทันที ไม่ต้องเปิด console */
|
||||
const role = isMePlayHost() ? 'host' : 'client';
|
||||
/* (A) snapshot ทุก ~5 วิ จาก "ทั้ง host และ client" → เทียบใน /gamelog ได้: block(=สีที่วาด) av(=สี avatar) srv bc */
|
||||
if (now - _mg3SnapAt > 5000) {
|
||||
_mg3SnapAt = now;
|
||||
/* รายชื่อ "คน" ใน others (เทียบกับคิว) — หา root "client หายจากคิว" */
|
||||
const othH = [];
|
||||
if (myId != null) othH.push((me && me.nickname ? me.nickname : 'me') + '(self' + (playBannedSpectator ? ',BAN' : '') + ')');
|
||||
others.forEach(function (o, id) {
|
||||
if (isPreviewBotId(id)) return;
|
||||
othH.push((o && o.nickname ? o.nickname : String(id).slice(0, 5)) + (o && o.bannedSpectator ? '(BAN)' : ''));
|
||||
});
|
||||
const ordSeats = rows.length;
|
||||
/* block ที่ "วางแล้ว" (frozen layer.theme) — ตัวที่ user เห็นเพี้ยน; เทียบ host vs client ทีละ layer (seat:theme) */
|
||||
let lyr = '';
|
||||
if (stackMini && Array.isArray(stackMini.layers)) {
|
||||
const L = stackMini.layers;
|
||||
lyr = ' || layers(' + L.length + ')=[' + L.slice(-12).map(function (l) { return (l && l.seat != null ? l.seat : '?') + ':' + (l && l.theme != null ? l.theme : 'null'); }).join(',') + ']';
|
||||
}
|
||||
const summary = 'order=' + ordSeats + 'seat othHumans=[' + othH.join(',') + '] :: '
|
||||
+ rows.map(function (r) { return 's' + r.seat + ':' + (r.nick || '?').slice(0, 5) + ' blk=' + r.blockIdx + ' av=' + r.avatarIdx; }).join(' | ') + lyr;
|
||||
gamelogPost('MG3', 'color-snap', summary, role);
|
||||
}
|
||||
/* (B) mismatch (avatar≠block บนจอเดียวกัน) → ส่งทันที (เปลี่ยนค่อยส่งซ้ำ) */
|
||||
const bad = rows.filter(function (r) { return r.ok === false; });
|
||||
if (bad.length) {
|
||||
const key = (isMePlayHost() ? 'H' : 'C') + '|' + bad.map(function (r) { return r.seat + ':' + r.avatarIdx + '!=' + r.blockIdx; }).join(',');
|
||||
const key = role + '|' + bad.map(function (r) { return r.seat + ':' + r.avatarIdx + '!=' + r.blockIdx; }).join(',');
|
||||
if (key !== _mg3LastMismatchKey) {
|
||||
_mg3LastMismatchKey = key;
|
||||
const role = isMePlayHost() ? 'host' : 'client';
|
||||
const detail = bad.map(function (r) { return r.nick + ' seat' + r.seat + ' avatar#' + r.avatarIdx + ' แต่ block#' + r.blockIdx + ' (srv' + r.srv + '/bc' + r.bc + ')'; }).join(' | ');
|
||||
gamelogPost('MG3', 'color-mismatch', detail, role);
|
||||
}
|
||||
@@ -12325,7 +12394,8 @@
|
||||
lastStackTickMs = now;
|
||||
/* เล่นจริง: host ส่งลำดับตา+index เป็นระยะ → non-host adopt (ครอบ late-join: client โหลดช้า host จะรวมเข้า order ให้) */
|
||||
if (detectiveCaseFillBots && isMePlayHost()) {
|
||||
if (!stackTurnOrderReadyPlay()) rebuildStackPreviewTurnOrder();
|
||||
/* rebuild เมื่อ (ก) ยังไม่มีคิว หรือ (ข) คน/บอท เปลี่ยน (เช่น client เข้าทีหลัง = late-join) → ให้ทุกคนได้ seat + สี */
|
||||
if (!stackTurnOrderReadyPlay() || stackOrderNeedsRebuildPlay()) rebuildStackPreviewTurnOrder();
|
||||
const ts = Date.now();
|
||||
if (ts - stackLastStateEmit > 300) { stackLastStateEmit = ts; broadcastStackStatePlay(); }
|
||||
}
|
||||
@@ -12602,11 +12672,13 @@
|
||||
? stackFall.actorSeat
|
||||
: (m.pendingDropSeat != null ? m.pendingDropSeat : getStackDropActorSeat());
|
||||
const heavyDraw = stackFall ? !!stackFall.actorHeavy : !!m.pendingDropHeavy;
|
||||
/* remote drop → ใช้สีจาก host (actorTheme/pendingDropTheme) เหมือน block ที่วาง → block ห้อย/ตก สีตรง host */
|
||||
const themeOverrideDraw = stackFall ? (stackFall.actorTheme || null) : (m.pendingDropTheme || null);
|
||||
const hueHint = (m.layers.length * 47) % 360;
|
||||
ctx.save();
|
||||
ctx.translate(bcx, bcy);
|
||||
ctx.rotate(fallTiltRad + swingTiltRad);
|
||||
drawStackBlockSpriteOrHue(ctx, -twWorld * zoom / 2, 0, twWorld * zoom, drawStripPx, seatDraw, heavyDraw, hueHint, { missTint: !!hitMissTint, missOverlay: !!hitMissTint });
|
||||
drawStackBlockSpriteOrHue(ctx, -twWorld * zoom / 2, 0, twWorld * zoom, drawStripPx, seatDraw, heavyDraw, hueHint, { missTint: !!hitMissTint, missOverlay: !!hitMissTint, themeOverride: themeOverrideDraw });
|
||||
ctx.lineWidth = 1;
|
||||
ctx.restore();
|
||||
}
|
||||
@@ -20399,7 +20471,13 @@
|
||||
|
||||
/* MG3 stack — non-host รับลำดับตา+index จาก host (single source of truth) → เลิกแยกตึก/ตาเหลื่อม */
|
||||
socket.on('stack-state', (d) => {
|
||||
if (!d || !mapData || !isStack() || !detectiveCaseFillBots || isMePlayHost()) return;
|
||||
if (!d || !mapData || !isStack() || !detectiveCaseFillBots) return;
|
||||
/* ได้รับ stack-state = server relay จาก "host จริง" (socket.to ไม่ส่งกลับผู้ส่ง) → เรา "ไม่ใช่ host"
|
||||
แก้ playHostId ที่ผิด (dual-host: เข้าใจผิดว่าเป็น host แล้ว sim เอง = ลำดับ/สี block หลุดกับ host) */
|
||||
if (d.hostId != null && myId != null && String(d.hostId) !== String(myId)) {
|
||||
if (String(playHostId) !== String(d.hostId)) playHostId = d.hostId;
|
||||
}
|
||||
if (isMePlayHost()) return;
|
||||
if (Array.isArray(d.order)) {
|
||||
stackPreviewTurnOrder = d.order.map((e) => ({
|
||||
kind: e.kind, seat: e.seat,
|
||||
@@ -20410,7 +20488,24 @@
|
||||
}
|
||||
if (stackPreviewTurnOrder && stackPreviewTurnOrder.length && Number.isFinite(Number(d.idx))) {
|
||||
const n = stackPreviewTurnOrder.length;
|
||||
stackPreviewTurnIndex = ((Math.floor(Number(d.idx)) % n) + n) % n;
|
||||
const newIdx = ((Math.floor(Number(d.idx)) % n) + n) % n;
|
||||
if (newIdx !== stackPreviewTurnIndex) {
|
||||
stackPreviewTurnIndex = newIdx;
|
||||
/* ตาเปลี่ยน → refresh "block ที่ห้อย" (pendingDropSeat/สี) ให้ตรงตาปัจจุบัน
|
||||
เดิมไม่ mark dirty → block ห้อยค้างโชว์สีของตาที่แล้ว = ก่อนปล่อยสีไม่ตรง */
|
||||
markStackNextDropVisualDirty();
|
||||
}
|
||||
}
|
||||
/* sync สี block ที่ "วางแล้ว" จาก host → เขียนทับ layer ที่เพี้ยนค้าง (จากจังหวะ dual-host ต้นเกม)
|
||||
sync เฉพาะเมื่อจำนวนชั้นตรงกัน (aligned) — กันเขียนผิดตำแหน่งช่วง drop คาบเกี่ยว */
|
||||
if (Array.isArray(d.lthemes) && stackMini && Array.isArray(stackMini.layers)
|
||||
&& d.lthemes.length === stackMini.layers.length) {
|
||||
for (let i = 0; i < stackMini.layers.length; i++) {
|
||||
const ht = Math.floor(Number(d.lthemes[i]));
|
||||
if (ht >= 1 && ht <= 8 && stackMini.layers[i] && stackMini.layers[i].theme !== ht) {
|
||||
stackMini.layers[i].theme = ht;
|
||||
}
|
||||
}
|
||||
}
|
||||
logStackSeatColors('client-recv');
|
||||
});
|
||||
|
||||
@@ -10,6 +10,21 @@
|
||||
const nick = (params.get('nick') || '').trim() || 'ผู้เล่น';
|
||||
const DISPLAY_NAME_STORAGE_KEY = 'roomLobbyDisplayName';
|
||||
let profileDisplayName = nick;
|
||||
/* ===== log LobbyA/B → /gamelog (จับ timeline init: connect/join/preload/loading-hide หาเหตุ "กดไม่ได้ต้องรอ") ===== */
|
||||
const _lobbyT0 = Date.now();
|
||||
function lobbyLogCat() {
|
||||
try { if (clientLobbyMapId === POST_CASE_LOBBY_SPACE_ID || serverSuspectPhaseActive) return 'LobbyB'; } catch (e) { /* ignore */ }
|
||||
return 'LobbyA';
|
||||
}
|
||||
function lobbyLog(ev, detail) {
|
||||
try {
|
||||
fetch('/gamelog/log.php', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' }, keepalive: true,
|
||||
body: JSON.stringify({ cat: lobbyLogCat(), room: (typeof spaceId === 'string' ? spaceId : ''), who: (function () { try { return getProfileDisplayName(); } catch (e) { return nick; } })(), ev: ev || '', detail: (detail || '') + ' [+' + (Date.now() - _lobbyT0) + 'ms]', src: 'client' }),
|
||||
}).catch(function () {});
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
lobbyLog('lobby-open', 'space=' + spaceId);
|
||||
const DESIGN_MENU = typeof designMainMenuHref === 'function' ? designMainMenuHref() : '/Main-Menu/';
|
||||
if (!spaceId) { location.href = DESIGN_MENU; return; }
|
||||
const roomIdValueEl = document.getElementById('room-id-value');
|
||||
@@ -510,6 +525,7 @@
|
||||
var elapsed = Date.now() - roomLoadingShownAt;
|
||||
if (elapsed < ROOM_LOADING_MIN_MS) { setTimeout(hideRoomLoading, ROOM_LOADING_MIN_MS - elapsed); return; }
|
||||
roomLoadingHidden = true;
|
||||
try { lobbyLog('loading-hide', 'เริ่มเล่นได้'); } catch (e) { /* ignore */ }
|
||||
var ov = document.getElementById('room-loading-overlay');
|
||||
if (ov) { ov.classList.add('is-hidden'); setTimeout(function () { if (ov.parentNode) ov.parentNode.removeChild(ov); }, 600); }
|
||||
}
|
||||
@@ -3215,6 +3231,7 @@
|
||||
socket.on('peer-display-name', applyPeerDisplayNameUpdate);
|
||||
|
||||
socket.on('connect', () => {
|
||||
lobbyLog('socket-connect', '');
|
||||
/* ส่งค่าสีที่เลือกใน Main-Lobby ติดไปด้วย — server จะใช้ค่านี้ถ้ายังว่าง (กันโชว์สีแดง default ตอนเข้าใหม่) */
|
||||
var savedThemeIdx = null;
|
||||
var savedSkinIdx = null;
|
||||
@@ -3245,6 +3262,8 @@
|
||||
}
|
||||
mapData = res.mapData;
|
||||
roomJoinReady = true;
|
||||
clientLobbyMapId = res.mapId != null ? res.mapId : null;
|
||||
lobbyLog('join-ok', 'peers=' + (res.peers || []).length + ' host=' + (res.hostId === socket.id ? 'me' : 'other') + ' map=' + res.mapId + ' bots=' + (res.botSlotCount != null ? res.botSlotCount : '?'));
|
||||
/* ไอคอนกุญแจ 🔒 โชว์เฉพาะห้อง private (จาก res.isPrivate) — public ไม่โชว์ */
|
||||
try {
|
||||
const lockEl = document.getElementById('room-id-lock');
|
||||
@@ -7585,14 +7604,22 @@
|
||||
setTimeout(resizeAndDraw, 100);
|
||||
updateLobbyProfileAvatar();
|
||||
setupRoomCustomize();
|
||||
lobbyLog('preload-start', '');
|
||||
rlEnsureManifest(function () {
|
||||
lobbyLog('manifest-done', '');
|
||||
rlResolveMyColors(function () {
|
||||
lobbyLog('colors-resolved', '');
|
||||
updateRoomProfileAvatarTinted();
|
||||
preloadMyTintedCharacter(function () {
|
||||
lobbyLog('mychar-tinted', 'roomJoinReady=' + roomJoinReady);
|
||||
/* พอ tint "ตัวเรา" เสร็จ → เปิดให้เล่นได้เลย (ไม่รอ tint คนอื่นครบ = เดิมกิน ~12 วิ คอขวด)
|
||||
tint คนอื่นโหลด background → avatar คนอื่นโผล่สีตามทีหลังนิดหน่อย (ยอมรับได้) */
|
||||
roomPreloadReady = true;
|
||||
setRoomLoadingPct(100);
|
||||
lobbyLog('preload-ready(mychar)', '');
|
||||
maybeHideRoomLoading();
|
||||
preloadAllLobbyTintedOccupants(function () {
|
||||
roomPreloadReady = true;
|
||||
setRoomLoadingPct(100);
|
||||
maybeHideRoomLoading();
|
||||
lobbyLog('preload-occupants-done(bg)', '');
|
||||
}, function (d, t) {
|
||||
setRoomLoadingPct(t ? (d / t) * 100 : 100);
|
||||
});
|
||||
|
||||
@@ -5412,7 +5412,7 @@
|
||||
<script src="/app-base.js?v=2"></script>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0306"></script>
|
||||
<script src="js/play.js?v=0.006260111"></script>
|
||||
<script src="js/play.js?v=0.006260120"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
<style id="qc-howto-mg2-fix">
|
||||
/* HOW TO PLAY ของ quiz_carry (Minigame-4) -> ให้เหมือน Minigame-2 (gch-mg2-mock)
|
||||
|
||||
@@ -1648,7 +1648,7 @@
|
||||
<script src="js/version.js?v=0.0122"></script>
|
||||
<script src="js/customize-popup.js?v=40" data-customize-triggers="" data-customize-asset-base="img/03-5-Customize"></script>
|
||||
<script src="js/achievements.js?v=0.002" data-asset-base="img/03-6-Profile"></script>
|
||||
<script src="js/room-lobby.js?v=0.0324"></script>
|
||||
<script src="js/room-lobby.js?v=0.0326"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+10
-1
@@ -8215,6 +8215,7 @@ io.on('connection', (socket) => {
|
||||
const space = sid ? spaces.get(sid) : null;
|
||||
if (!space || !data) return;
|
||||
const num = (v) => (typeof v === 'number' && Number.isFinite(v)) ? v : 0;
|
||||
const themeOf = (v) => { const n = Math.floor(Number(v)); return (n >= 1 && n <= 8) ? n : null; };
|
||||
socket.to(sid).emit('stack-drop', {
|
||||
placedCx: num(data.placedCx), placedW: num(data.placedW),
|
||||
miss: !!data.miss, perfect: !!data.perfect,
|
||||
@@ -8223,6 +8224,7 @@ io.on('connection', (socket) => {
|
||||
supportRatio: (data.supportRatio == null ? null : num(data.supportRatio)),
|
||||
delta: num(data.delta),
|
||||
seat: Math.max(1, Math.min(8, Math.floor(num(data.seat)) || 1)), heavy: !!data.heavy,
|
||||
theme: themeOf(data.theme), /* สี block ที่วาง (host เป็นเจ้าของ) — เดิมถูกตัดทิ้ง → client freeze สีตัวเอง = เพี้ยน */
|
||||
actorId: data.actorId != null ? String(data.actorId).slice(0, 64) : '', isBot: !!data.isBot,
|
||||
});
|
||||
});
|
||||
@@ -8251,16 +8253,23 @@ io.on('connection', (socket) => {
|
||||
const sid = socket.data.spaceId;
|
||||
const space = sid ? spaces.get(sid) : null;
|
||||
if (!space || space.hostId !== socket.id || !data) return; /* host เท่านั้น */
|
||||
const themeOf = (v) => { const n = Math.floor(Number(v)); return (n >= 1 && n <= 8) ? n : null; };
|
||||
const order = Array.isArray(data.order)
|
||||
? data.order.filter((e) => e && (e.kind === 'human' || e.kind === 'bot')).slice(0, 8).map((e) => ({
|
||||
kind: e.kind === 'bot' ? 'bot' : 'human',
|
||||
seat: Math.max(1, Math.min(8, Math.floor(Number(e.seat)) || 1)),
|
||||
id: e.id != null ? String(e.id).slice(0, 64) : null,
|
||||
botId: e.botId != null ? String(e.botId).slice(0, 64) : null,
|
||||
theme: themeOf(e.theme), /* สีต่อ seat (host เป็นเจ้าของ) — เดิมถูกตัดทิ้ง → client คำนวณเอง = เพี้ยน */
|
||||
}))
|
||||
: [];
|
||||
const idx = Math.max(0, Math.floor(Number(data.idx)) || 0);
|
||||
socket.to(sid).emit('stack-state', { order, idx });
|
||||
/* สีของ block ที่วางทั้งหอ (host authoritative) — ต้อง relay ด้วย ไม่งั้นถูก allowlist ตัดทิ้ง */
|
||||
const lthemes = Array.isArray(data.lthemes)
|
||||
? data.lthemes.slice(0, 200).map((v) => { const n = Math.floor(Number(v)); return (n >= 1 && n <= 8) ? n : 0; })
|
||||
: [];
|
||||
/* hostId (= host จริงที่ server ยืนยัน) → client ที่เข้าใจผิดว่าตัวเองเป็น host (dual-host) แก้ playHostId แล้วหยุด sim เอง */
|
||||
socket.to(sid).emit('stack-state', { order, idx, hostId: socket.id, lthemes });
|
||||
});
|
||||
|
||||
/* MG3 stack — host ตัดสินจบรอบ relay ให้ทุกคนจบพร้อมกัน */
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
{"t":1782460590560,"cat":"MG3","room":"hhh","who":"","ev":"game-start","detail":"เริ่มมินิเกม: Minigame-3 Tower block (การ์ด 1)","src":"server"}
|
||||
{"t":1782460590711,"cat":"MG3","room":"hhh","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782460590711,"cat":"MG3","room":"hhh","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782460591013,"cat":"MG3","room":"hhh","who":"MONE","ev":"join","detail":"สี#8 · คน 1 + บอท 3","src":"server"}
|
||||
{"t":1782460591315,"cat":"MG3","room":"hhh","who":"Q","ev":"join","detail":"สี#7 · คน 2 + บอท 3","src":"server"}
|
||||
{"t":1782460717354,"cat":"LobbyB","room":"hhh","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782460717354,"cat":"LobbyB","room":"hhh","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782460718032,"cat":"LobbyB","room":"hhh","who":"Q","ev":"join","detail":"สี#7 · คน 2 + บอท 3","src":"server"}
|
||||
{"t":1782460719931,"cat":"LobbyB","room":"hhh","who":"MONE","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782460720509,"cat":"LobbyB","room":"hhh","who":"MONE","ev":"join","detail":"สี#8 · คน 2 + บอท 3","src":"server"}
|
||||
{"t":1782461143015,"cat":"MG3","room":"hhh","who":"","ev":"game-start","detail":"เริ่มมินิเกม: Minigame-3 Tower block (การ์ด 1)","src":"server"}
|
||||
{"t":1782461143223,"cat":"MG3","room":"hhh","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782461143223,"cat":"MG3","room":"hhh","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782461143637,"cat":"MG3","room":"hhh","who":"Q","ev":"join","detail":"สี#7 · คน 1 + บอท 3","src":"server"}
|
||||
{"t":1782461143920,"cat":"MG3","room":"hhh","who":"MONE","ev":"join","detail":"สี#8 · คน 2 + บอท 3","src":"server"}
|
||||
{"t":1782461213243,"cat":"MG3","room":"hhh","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782461213243,"cat":"MG3","room":"hhh","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782461223245,"cat":"MG3","room":"hhh","who":"Q","ev":"bot-takeover","detail":"หลุดเกิน 10วิ → บอทแทน (สีตามคนออก)","src":"server"}
|
||||
{"t":1782461274423,"cat":"LobbyB","room":"hhh","who":"MONE","ev":"join","detail":"สี#8 · คน 1 + บอท 4","src":"server"}
|
||||
{"t":1782461327954,"cat":"LobbyA","room":"aaa","who":"Q","ev":"join","detail":"สี#7 · คน 1 + บอท 3","src":"server"}
|
||||
{"t":1782461351978,"cat":"LobbyA","room":"aaa","who":"Q","ev":"join","detail":"สี#7 · คน 1 + บอท 4","src":"server"}
|
||||
{"t":1782461363786,"cat":"LobbyA","room":"aaa","who":"MONE","ev":"join","detail":"สี#8 · คน 2 + บอท 4","src":"server"}
|
||||
{"t":1782461415359,"cat":"LobbyB","room":"aaa","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782461415359,"cat":"LobbyB","room":"aaa","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782461425362,"cat":"LobbyB","room":"aaa","who":"Q","ev":"bot-takeover","detail":"หลุดเกิน 10วิ → บอทแทน (สีตามคนออก)","src":"server"}
|
||||
{"t":1782461428827,"cat":"LobbyA","room":"aaa","who":"Q","ev":"join","detail":"สี#7 · คน 1 + บอท 3","src":"server"}
|
||||
{"t":1782461438053,"cat":"LobbyA","room":"aaa","who":"MONE","ev":"join","detail":"สี#8 · คน 2 + บอท 3","src":"server"}
|
||||
{"t":1782461466584,"cat":"MG3","room":"aaa","who":"","ev":"game-start","detail":"เริ่มมินิเกม: Minigame-3 Tower block (การ์ด 1)","src":"server"}
|
||||
{"t":1782461466705,"cat":"MG3","room":"aaa","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782461466705,"cat":"MG3","room":"aaa","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782461467047,"cat":"MG3","room":"aaa","who":"MONE","ev":"join","detail":"สี#8 · คน 1 + บอท 3","src":"server"}
|
||||
{"t":1782461467352,"cat":"MG3","room":"aaa","who":"Q","ev":"join","detail":"สี#7 · คน 2 + บอท 3","src":"server"}
|
||||
{"t":1782461544478,"cat":"MG3","room":"aaa","who":"Q","ev":"host-change","detail":"host ใหม่ → MONE","src":"server"}
|
||||
{"t":1782461544479,"cat":"MG3","room":"aaa","who":"Q","ev":"leave","detail":"ออกจากห้อง · เหลือคน 1","src":"server"}
|
||||
{"t":1782461554486,"cat":"MG3","room":"aaa","who":"Q","ev":"bot-takeover","detail":"หลุดเกิน 10วิ → บอทแทน (สีตามคนออก)","src":"server"}
|
||||
|
||||
+710
-740
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user