fix(game): 修复房间信息请求和定缺响应处理逻辑

- 将 pendingRoomInfoRequest 重命名为 needsInitialRoomInfo 以更准确表达含义
- 移除 waiting 阶段的限制条件,仅在结算阶段返回 false
- 当手牌为空时才返回空状态,避免误判
- 新增 handlePlayerDingQueResponse 函数处理玩家定缺响应
- 优化 onMounted 中的房间信息请求逻辑,确保连接状态下才发送请求
- 在消息处理器中添加对定缺响应的处理支持
This commit is contained in:
2026-03-27 17:26:33 +08:00
parent d1220cc45d
commit d60a505226

View File

@@ -83,7 +83,7 @@ const startGamePending = ref(false)
const dingQuePending = ref(false) const dingQuePending = ref(false)
let clockTimer: number | null = null let clockTimer: number | null = null
let unsubscribe: (() => void) | null = null let unsubscribe: (() => void) | null = null
let pendingRoomInfoRequest = false let needsInitialRoomInfo = false
const menuOpen = ref(false) const menuOpen = ref(false)
const isTrustMode = ref(false) const isTrustMode = ref(false)
@@ -352,7 +352,7 @@ const showDingQueChooser = computed(() => {
return false return false
} }
if (gameStore.phase === 'waiting' || gameStore.phase === 'settlement') { if (gameStore.phase === 'settlement') {
return false return false
} }
@@ -568,18 +568,14 @@ function requestRoomInfo(): void {
const routeRoomId = typeof route.params.roomId === 'string' ? route.params.roomId : '' const routeRoomId = typeof route.params.roomId === 'string' ? route.params.roomId : ''
const roomId = routeRoomId || gameStore.roomId || activeRoom.value?.roomId || '' const roomId = routeRoomId || gameStore.roomId || activeRoom.value?.roomId || ''
if (!roomId) { if (!roomId) {
pendingRoomInfoRequest = true
wsMessages.value.push('[client] get_room_info pending: missing roomId')
return return
} }
if (wsStatus.value !== 'connected') { if (wsStatus.value !== 'connected') {
pendingRoomInfoRequest = true
wsMessages.value.push(`[client] get_room_info pending: ws=${wsStatus.value}`)
return return
} }
pendingRoomInfoRequest = false needsInitialRoomInfo = false
wsMessages.value.push(`[client] get_room_info ${roomId}`) wsMessages.value.push(`[client] get_room_info ${roomId}`)
sendWsMessage({ sendWsMessage({
type: 'get_room_info', type: 'get_room_info',
@@ -920,7 +916,7 @@ const wallSeats = computed<Record<SeatKey, WallSeatState>>(() => {
left: emptyWallSeat(), left: emptyWallSeat(),
} }
if (gameStore.phase === 'waiting') { if (gameStore.phase === 'waiting' && myHandTiles.value.length === 0) {
return emptyState return emptyState
} }
@@ -1249,6 +1245,59 @@ function handleReadyStateResponse(message: unknown): void {
} }
} }
function handlePlayerDingQueResponse(message: unknown): void {
if (!message || typeof message !== 'object') {
return
}
const source = message as Record<string, unknown>
if (typeof source.type !== 'string') {
return
}
if (normalizeWsType(source.type) !== 'PLAYER_DING_QUE') {
return
}
const payload = asRecord(source.payload)
if (!payload) {
return
}
const roomId =
readString(payload, 'room_id', 'roomId') ||
readString(source, 'roomId')
if (roomId && roomId !== gameStore.roomId) {
return
}
const userId =
readString(payload, 'user_id', 'userId', 'player_id', 'playerId') ||
readString(source, 'target')
const suit = readString(payload, 'suit', 'Suit')
if (!userId || !suit) {
return
}
const player = gameStore.players[userId]
if (player) {
player.missingSuit = suit
}
const room = activeRoom.value
if (room && room.roomId === (roomId || gameStore.roomId)) {
const roomPlayer = room.players.find((item) => item.playerId === userId)
if (roomPlayer) {
roomPlayer.missingSuit = suit
}
}
if (userId === loggedInUserId.value) {
dingQuePending.value = false
}
}
function logoutToLogin(): void { function logoutToLogin(): void {
clearAuth() clearAuth()
auth.value = null auth.value = null
@@ -1558,18 +1607,20 @@ function hydrateFromActiveRoom(routeRoomId: string): void {
onMounted(() => { onMounted(() => {
const routeRoomId = typeof route.params.roomId === 'string' ? route.params.roomId : '' const routeRoomId = typeof route.params.roomId === 'string' ? route.params.roomId : ''
pendingRoomInfoRequest = true needsInitialRoomInfo = true
void ensureCurrentUserLoaded().finally(() => { void ensureCurrentUserLoaded().finally(() => {
hydrateFromActiveRoom(routeRoomId) hydrateFromActiveRoom(routeRoomId)
if (routeRoomId) { if (routeRoomId) {
gameStore.roomId = routeRoomId gameStore.roomId = routeRoomId
} }
requestRoomInfo() if (wsStatus.value === 'connected' && needsInitialRoomInfo) {
requestRoomInfo()
}
}) })
const handler = (status: WsStatus) => { const handler = (status: WsStatus) => {
wsStatus.value = status wsStatus.value = status
if (status === 'connected' && pendingRoomInfoRequest) { if (status === 'connected' && needsInitialRoomInfo) {
requestRoomInfo() requestRoomInfo()
} }
} }
@@ -1580,6 +1631,7 @@ onMounted(() => {
handleRoomInfoResponse(msg) handleRoomInfoResponse(msg)
handlePlayerHandResponse(msg) handlePlayerHandResponse(msg)
handleReadyStateResponse(msg) handleReadyStateResponse(msg)
handlePlayerDingQueResponse(msg)
const gameAction = toGameAction(msg) const gameAction = toGameAction(msg)
if (gameAction) { if (gameAction) {
dispatchGameAction(gameAction) dispatchGameAction(gameAction)