From ae58cdad8211c2969ab632add3ced5ca71b793c4 Mon Sep 17 00:00:00 2001 From: ll <48448919+llsccm@users.noreply.github.com> Date: Mon, 14 Sep 2026 01:10:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(handler):=20=E5=8E=BB=E9=87=8D=E5=AF=B9?= =?UTF-8?q?=E5=B1=80=E6=B6=88=E6=81=AF=E5=B9=B6=E7=AE=80=E5=8C=96=E7=BB=93?= =?UTF-8?q?=E7=AE=97=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/handler/MsgGameOver.js | 55 +++++++++++++++++++------------------- src/handler/StartGame.js | 2 ++ src/logic.js | 14 ++++++++-- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/handler/MsgGameOver.js b/src/handler/MsgGameOver.js index 6b590ad..3f3e70e 100644 --- a/src/handler/MsgGameOver.js +++ b/src/handler/MsgGameOver.js @@ -6,63 +6,64 @@ import { destroyPeiXiuMapWindow } from '@/ui/PeiXiuMapWindow' import { wait } from '@/utils' let closeGameOverWindowsTimer = null -let isPveRoguelike = false +let gameOverTask = null -// 应该存在一个更好的方法 -function scheduleCloseGameOverWindows() { +export function cancelGameOverTask() { if (closeGameOverWindowsTimer !== null) { clearTimeout(closeGameOverWindowsTimer) closeGameOverWindowsTimer = null } + gameOverTask = null +} + +function isCurrentGameOverTask(task) { + if (gameOverTask !== task) return false + const room = tracker.getTrackerRoom() + return room === null || room === task.room +} +function scheduleCloseGameOverWindows(task) { if (!globalConfig.blockMvpSettlementSwitch) { - cleanupGame() + cleanupGame(task.room) return } closeGameOverWindowsTimer = setTimeout(async () => { closeGameOverWindowsTimer = null + if (!isCurrentGameOverTask(task)) return const getWindow = (name) => { const win = laya.GetWindow(name) return win && win.visible ? win : null } - // 此时关闭战绩 山河图结算数据还不存在导致窗口空白 - const resultWin = await wait(() => getWindow('GameResultWindow')) - if (!resultWin) { - cleanupGame() - return - } - - // 等山河图结算窗口初始化 - // if (isPveRoguelike) await wait(() => getWindow('RogueZhanJiWindow')) - // if (zhanJiWin) return - resultWin.laterClose?.() + for (const windowName of task.windowNames) { + const win = await wait(() => !isCurrentGameOverTask(task) || getWindow(windowName)) + if (!isCurrentGameOverTask(task)) return + if (!win) break - // 山河图没有mvp窗口 - // mvp窗口在战绩后出现 - if (!isPveRoguelike) { - const mvpWin = await wait(() => getWindow('GameMvpWindow')) - if (mvpWin) { - mvpWin.laterClose?.() - } + win.laterClose?.() } - cleanupGame() - }, 1000) + if (isCurrentGameOverTask(task)) cleanupGame(task.room) + }, 500) } export function handleGameOver() { - isPveRoguelike = Game.isShanHeTu - scheduleCloseGameOverWindows() + cancelGameOverTask() + gameOverTask = { + room: tracker.getTrackerRoom(), + windowNames: Game.isShanHeTu ? ['GameResultWindow'] : ['GameResultWindow', 'GameMvpWindow'] + } + scheduleCloseGameOverWindows(gameOverTask) } export function handleLeaveTable() { cleanupGame() } -function cleanupGame() { +function cleanupGame(room = tracker.getTrackerRoom()) { + if (tracker.getTrackerRoom() !== room) return // document.querySelectorAll('.mizhu').forEach((e) => (e.style.display = 'none')) Game.isPassed = null laya.zhanfaMap.clear() diff --git a/src/handler/StartGame.js b/src/handler/StartGame.js index c386a82..5300048 100644 --- a/src/handler/StartGame.js +++ b/src/handler/StartGame.js @@ -3,8 +3,10 @@ import { user } from '@/tracker' import { tracker } from '@/tracker/runtime/browser' import { addTooltip } from '@/utils/notification' import { hideOrderContainer, resetOrderContainer } from '@/ui/seatOverlay' +import { cancelGameOverTask } from './MsgGameOver' function registerGamePlayers(infos) { + cancelGameOverTask() resetSeatUIs() tracker.initTrackerRoom() tracker.registerTrackerPlayers(infos, user.userID) diff --git a/src/logic.js b/src/logic.js index 5c19daf..ba6360e 100644 --- a/src/logic.js +++ b/src/logic.js @@ -42,6 +42,7 @@ const ALLOWED_CLASSES = new Set([ // ]) const ShanHeTu_regex = /\[\d+\]$/ +let lastClassName = null export function logic(msg) { try { @@ -50,6 +51,15 @@ export function logic(msg) { if (msg.className === undefined && msg.ClassName === undefined) return const className = msg.ClassName || msg.className || msg.toString() + // 宿主会连续重复发送这两类消息,只处理连续消息中的第一条。 + if ( + className === lastClassName && + (className === 'decodeGameRecordInitInfo' || className === 'MsgGameOver') + ) { + return + } + lastClassName = className + const { ProtoObj, SeatID } = msg // 录制器有独立的记牌协议规则,需先于功能白名单执行,以保留路由遗漏现场。 @@ -137,7 +147,7 @@ export function logic(msg) { // }) break - // 用于判断模式 此消息会触发两次 + // 用于判断模式 case 'decodeGameRecordInitInfo': if (import.meta.env.DEV) console.info(msg) Game.init() @@ -240,7 +250,7 @@ export function logic(msg) { break case 'MsgGameOver': - // 此消息会触发两次 + if (import.meta.env.DEV) console.info(msg) handleGameOver() break