diff --git a/src/views/chengdu/socket/handlers/roomInfoHandlers.ts b/src/views/chengdu/socket/handlers/roomInfoHandlers.ts index 7d004c4..13c2740 100644 --- a/src/views/chengdu/socket/handlers/roomInfoHandlers.ts +++ b/src/views/chengdu/socket/handlers/roomInfoHandlers.ts @@ -3,9 +3,11 @@ import { parseRoomInfoSnapshot } from '../parsers/roomInfoSnapshot' import { clearRoomAndRedirect, syncActiveRoomFromRoomInfo } from '../room/roomSnapshotSync' import { clearClaimAndTurnPending, + clearRoomCountdown, clearDingQuePending, clearSelfTurnAllowActions, clearTurnPending, + setRoomCountdown, setSettlementDeadline, syncCurrentUserId, } from '../session/sessionStateAdapter' @@ -69,6 +71,11 @@ export function createRoomInfoHandlers(context: SocketHandlerContext) { } else { clearTurnPending(context.session) } + if (snapshot.actionTimer) { + setRoomCountdown(context.session, snapshot.actionTimer) + } else { + clearRoomCountdown(context.session) + } if (typeof snapshot.settlementDeadlineMs === 'number' && snapshot.settlementDeadlineMs > 0) { setSettlementDeadline(context.session, snapshot.settlementDeadlineMs) } diff --git a/src/views/chengdu/socket/handlers/roomStateHandlers.ts b/src/views/chengdu/socket/handlers/roomStateHandlers.ts index 1ce6f08..64980af 100644 --- a/src/views/chengdu/socket/handlers/roomStateHandlers.ts +++ b/src/views/chengdu/socket/handlers/roomStateHandlers.ts @@ -8,11 +8,13 @@ import { parseRoomStateSnapshot } from '../parsers/roomStateSnapshot' import { syncActiveRoomFromRoomState } from '../room/roomSnapshotSync' import { clearClaimAndTurnPending, + clearRoomCountdown, clearSelfTurnAllowActions, clearStartGamePending, clearTurnPending, completeDiscard, resetSettlementOverlayState, + setRoomCountdown, setSettlementDeadline, } from '../session/sessionStateAdapter' import { applyRoomSnapshot } from '../store/gameStoreAdapter' @@ -61,6 +63,11 @@ export function createRoomStateHandlers(context: SocketHandlerContext) { } else if (snapshot.phase !== 'settlement') { setSettlementDeadline(context.session, null) } + if (snapshot.actionTimer) { + setRoomCountdown(context.session, snapshot.actionTimer) + } else { + clearRoomCountdown(context.session) + } if (!snapshot.pendingClaim) { clearClaimAndTurnPending(context.session) diff --git a/src/views/chengdu/socket/parsers/actionTimerSnapshot.ts b/src/views/chengdu/socket/parsers/actionTimerSnapshot.ts new file mode 100644 index 0000000..1f9b612 --- /dev/null +++ b/src/views/chengdu/socket/parsers/actionTimerSnapshot.ts @@ -0,0 +1,27 @@ +import { asRecord, readNumber, readString, readStringArray } from '../../../../game/chengdu/messageNormalizers' +import type { PlayerActionTimer } from '../../types' + +export function parseActionTimerSnapshot(source: unknown): PlayerActionTimer | null { + const timer = asRecord(source) + if (!timer) { + return null + } + + const playerIds = readStringArray(timer, 'player_ids', 'playerIds', 'PlayerIDs') + const countdownSeconds = readNumber(timer, 'countdown_seconds', 'countdownSeconds', 'CountdownSeconds') ?? 0 + const duration = readNumber(timer, 'duration', 'Duration') ?? countdownSeconds + const remaining = readNumber(timer, 'remaining', 'Remaining') ?? countdownSeconds + const actionDeadlineAt = readString(timer, 'action_deadline_at', 'actionDeadlineAt', 'ActionDeadlineAt') || null + + if (playerIds.length === 0 && countdownSeconds <= 0 && remaining <= 0 && !actionDeadlineAt) { + return null + } + + return { + playerIds, + actionDeadlineAt, + countdownSeconds, + duration, + remaining, + } +} diff --git a/src/views/chengdu/socket/parsers/roomInfoSnapshot.ts b/src/views/chengdu/socket/parsers/roomInfoSnapshot.ts index b335cf0..2500aad 100644 --- a/src/views/chengdu/socket/parsers/roomInfoSnapshot.ts +++ b/src/views/chengdu/socket/parsers/roomInfoSnapshot.ts @@ -13,6 +13,8 @@ import { } from '../../../../game/chengdu/messageNormalizers' import type { RoomMetaSnapshotState } from '../../../../store/state' import type { PendingClaimState, PlayerState } from '../../../../types/state' +import type { PlayerActionTimer } from '../../types' +import { parseActionTimerSnapshot } from './actionTimerSnapshot' interface RoomInfoSnapshotPlayerPair { roomPlayer: RoomMetaSnapshotState['players'][number] @@ -39,6 +41,7 @@ export interface ParsedRoomInfoSnapshot { currentRound: number | null totalRounds: number | null settlementDeadlineMs: number | null + actionTimer: PlayerActionTimer | null } interface ParseRoomInfoSnapshotOptions { @@ -273,5 +276,6 @@ export function parseRoomInfoSnapshot( currentRound: readNumber(gameState ?? {}, 'current_round', 'currentRound'), totalRounds: readNumber(gameState ?? {}, 'total_rounds', 'totalRounds'), settlementDeadlineMs: readNumber(gameState ?? {}, 'settlement_deadline_ms', 'settlementDeadlineMs'), + actionTimer: parseActionTimerSnapshot(gameState?.action_timer ?? gameState?.actionTimer), } } diff --git a/src/views/chengdu/socket/parsers/roomStateSnapshot.ts b/src/views/chengdu/socket/parsers/roomStateSnapshot.ts index df178a8..7ae52d3 100644 --- a/src/views/chengdu/socket/parsers/roomStateSnapshot.ts +++ b/src/views/chengdu/socket/parsers/roomStateSnapshot.ts @@ -10,6 +10,8 @@ import { readStringArray, } from '../../../../game/chengdu/messageNormalizers' import type { PendingClaimState, PlayerState } from '../../../../types/state' +import type { PlayerActionTimer } from '../../types' +import { parseActionTimerSnapshot } from './actionTimerSnapshot' export interface ParsedRoomStateSnapshot { roomId: string @@ -25,6 +27,7 @@ export interface ParsedRoomStateSnapshot { currentRound: number | null totalRounds: number | null settlementDeadlineMs: number | null + actionTimer: PlayerActionTimer | null } interface ParseRoomStateSnapshotOptions { @@ -108,5 +111,6 @@ export function parseRoomStateSnapshot( currentRound: readNumber(payload, 'current_round', 'currentRound'), totalRounds: readNumber(payload, 'total_rounds', 'totalRounds'), settlementDeadlineMs: readNumber(payload, 'settlement_deadline_ms', 'settlementDeadlineMs'), + actionTimer: parseActionTimerSnapshot(payload.action_timer ?? payload.actionTimer), } } diff --git a/src/ws/client.ts b/src/ws/client.ts index 6e70c76..dcc819e 100644 --- a/src/ws/client.ts +++ b/src/ws/client.ts @@ -134,6 +134,7 @@ class WsClient { // 订阅状态变化 onStatusChange(handler: StatusHandler) { this.statusHandlers.push(handler) + handler(this.status) return () => { this.statusHandlers = this.statusHandlers.filter(fn => fn !== handler) }