完善联调标准化与诊断链路

This commit is contained in:
2026-04-03 17:01:04 +08:00
parent 114c524044
commit b09c21c814
35 changed files with 2677 additions and 175 deletions

View File

@@ -3,6 +3,7 @@ import { getEventPlay, launchEvent, type BackendCourseVariantSummary, type Backe
import { adaptBackendLaunchResultToEnvelope } from '../../utils/backendLaunchAdapter'
import { formatBackendPlayActionText, formatBackendPlayStatusText } from '../../utils/backendPlayCopy'
import { prepareMapPageUrlForLaunch } from '../../utils/gameLaunch'
import { reportBackendClientLog } from '../../utils/backendClientLogs'
import { HeartRateController } from '../../engine/sensor/heartRateController'
const PREFERRED_HEART_RATE_DEVICE_STORAGE_KEY = 'cmr.preferredHeartRateDevice'
@@ -290,12 +291,32 @@ Page({
result.play.assignmentMode,
result.play.courseVariants,
)
const assignmentMode = result.play.assignmentMode ? result.play.assignmentMode : null
const logVariantId = assignmentMode === 'manual' && selectedVariantId ? selectedVariantId : null
const selectableVariants = buildSelectableVariants(
selectedVariantId,
result.play.assignmentMode,
result.play.courseVariants,
)
const selectedVariant = selectableVariants.find((item) => item.id === selectedVariantId) || null
reportBackendClientLog({
level: 'info',
category: 'event-prepare',
message: 'prepare play loaded',
eventId: result.event.id || this.data.eventId || '',
releaseId: result.resolvedRelease && result.resolvedRelease.releaseId
? result.resolvedRelease.releaseId
: '',
manifestUrl: result.resolvedRelease && result.resolvedRelease.manifestUrl
? result.resolvedRelease.manifestUrl
: '',
details: {
pageEventId: this.data.eventId || '',
resultEventId: result.event.id || '',
selectedVariantId: logVariantId,
assignmentMode,
},
})
this.setData({
loading: false,
titleText: `${result.event.displayName} / 开始前准备`,
@@ -586,6 +607,22 @@ Page({
})
try {
const assignmentMode = this.data.assignmentMode ? this.data.assignmentMode : null
const selectedVariantId = assignmentMode === 'manual' && this.data.selectedVariantId
? this.data.selectedVariantId
: null
reportBackendClientLog({
level: 'info',
category: 'event-prepare',
message: 'launch requested',
eventId: this.data.eventId || '',
details: {
pageEventId: this.data.eventId || '',
selectedVariantId,
assignmentMode,
phase: 'launch-requested',
},
})
const app = getApp<IAppOption>()
if (app.globalData) {
const pendingDeviceName = prepareHeartRateController && prepareHeartRateController.currentDeviceName
@@ -608,6 +645,32 @@ Page({
clientType: 'wechat',
deviceKey: 'mini-dev-device-001',
})
reportBackendClientLog({
level: 'info',
category: 'event-prepare',
message: 'launch response received',
eventId: result.launch.business && result.launch.business.eventId ? result.launch.business.eventId : this.data.eventId || '',
releaseId: result.launch.config && result.launch.config.releaseId ? result.launch.config.releaseId : '',
sessionId: result.launch.business && result.launch.business.sessionId ? result.launch.business.sessionId : '',
manifestUrl: result.launch.resolvedRelease && result.launch.resolvedRelease.manifestUrl
? result.launch.resolvedRelease.manifestUrl
: '',
details: {
pageEventId: this.data.eventId || '',
launchEventId: result.launch.business && result.launch.business.eventId ? result.launch.business.eventId : '',
launchSessionId: result.launch.business && result.launch.business.sessionId ? result.launch.business.sessionId : '',
configUrl: result.launch.config && result.launch.config.configUrl ? result.launch.config.configUrl : '',
releaseId: result.launch.config && result.launch.config.releaseId ? result.launch.config.releaseId : '',
resolvedReleaseId: result.launch.resolvedRelease && result.launch.resolvedRelease.releaseId
? result.launch.resolvedRelease.releaseId
: '',
resolvedManifestUrl: result.launch.resolvedRelease && result.launch.resolvedRelease.manifestUrl
? result.launch.resolvedRelease.manifestUrl
: '',
launchVariantId: result.launch.variant && result.launch.variant.id ? result.launch.variant.id : null,
phase: 'launch-response',
},
})
const envelope = adaptBackendLaunchResultToEnvelope(result)
wx.navigateTo({
url: prepareMapPageUrlForLaunch(envelope),

View File

@@ -1,6 +1,7 @@
import { loadBackendAuthTokens, loadBackendBaseUrl } from '../../utils/backendAuth'
import { getEventPlay, type BackendEventPlayResult } from '../../utils/backendApi'
import { formatBackendPlayActionText, formatBackendPlayStatusText } from '../../utils/backendPlayCopy'
import { reportBackendClientLog } from '../../utils/backendClientLogs'
type EventPageData = {
eventId: string
@@ -130,6 +131,26 @@ Page({
},
applyEventPlay(result: BackendEventPlayResult) {
const assignmentMode = result.play.assignmentMode ? result.play.assignmentMode : null
reportBackendClientLog({
level: 'info',
category: 'event-play',
message: 'event play loaded',
eventId: result.event.id || this.data.eventId || '',
releaseId: result.resolvedRelease && result.resolvedRelease.releaseId
? result.resolvedRelease.releaseId
: '',
manifestUrl: result.resolvedRelease && result.resolvedRelease.manifestUrl
? result.resolvedRelease.manifestUrl
: '',
details: {
pageEventId: this.data.eventId || '',
resultEventId: result.event.id || '',
primaryAction: result.play.primaryAction || '',
assignmentMode,
variantCount: result.play.courseVariants ? result.play.courseVariants.length : 0,
},
})
this.setData({
loading: false,
titleText: result.event.displayName,

View File

@@ -1,5 +1,7 @@
import { clearBackendAuthTokens, loadBackendAuthTokens, loadBackendBaseUrl } from '../../utils/backendAuth'
import { getEntryHome, type BackendCardResult, type BackendEntryHomeResult } from '../../utils/backendApi'
import { reportBackendClientLog } from '../../utils/backendClientLogs'
import { setGlobalMockDebugBridgeEnabled } from '../../utils/globalMockDebugBridge'
const DEFAULT_CHANNEL_CODE = 'mini-demo'
const DEFAULT_CHANNEL_TYPE = 'wechat_mini'
@@ -100,6 +102,18 @@ Page({
},
applyEntryHomeResult(result: BackendEntryHomeResult) {
reportBackendClientLog({
level: 'info',
category: 'entry-home',
message: 'entry home loaded',
details: {
ongoingSessionId: result.ongoingSession && result.ongoingSession.id ? result.ongoingSession.id : '',
ongoingEventId: result.ongoingSession && result.ongoingSession.eventId ? result.ongoingSession.eventId : '',
recentSessionId: result.recentSession && result.recentSession.id ? result.recentSession.id : '',
recentEventId: result.recentSession && result.recentSession.eventId ? result.recentSession.eventId : '',
cardEventIds: (result.cards || []).map((item) => (item.event && item.event.id ? item.event.id : '')),
},
})
this.setData({
loading: false,
statusText: '首页加载完成',
@@ -141,6 +155,7 @@ Page({
handleLogout() {
clearBackendAuthTokens()
setGlobalMockDebugBridgeEnabled(false)
const app = getApp<IAppOption>()
if (app.globalData) {
app.globalData.backendAuthTokens = null

View File

@@ -1,5 +1,6 @@
import { clearBackendAuthTokens, saveBackendAuthTokens, saveBackendBaseUrl } from '../../utils/backendAuth'
import { loginWechatMini } from '../../utils/backendApi'
import { setGlobalMockDebugBridgeEnabled } from '../../utils/globalMockDebugBridge'
const DEFAULT_BACKEND_BASE_URL = 'https://api.gotomars.xyz'
const DEFAULT_DEVICE_KEY = 'mini-dev-device-001'
@@ -116,6 +117,7 @@ Page({
handleClearLoginState() {
clearBackendAuthTokens()
setGlobalMockDebugBridgeEnabled(false)
const app = getApp<IAppOption>()
if (app.globalData) {
app.globalData.backendAuthTokens = null

View File

@@ -16,6 +16,13 @@ import {
import { finishSession, startSession, type BackendSessionFinishSummaryPayload } from '../../utils/backendApi'
import { loadBackendBaseUrl } from '../../utils/backendAuth'
import { loadRemoteMapConfig, type RemoteMapConfig } from '../../utils/remoteMapConfig'
import {
persistStoredMockDebugLogBridgeUrl,
setGlobalMockDebugBridgeChannelId,
setGlobalMockDebugBridgeEnabled,
setGlobalMockDebugBridgeUrl,
} from '../../utils/globalMockDebugBridge'
import { reportBackendClientLog } from '../../utils/backendClientLogs'
import { type H5ExperienceFallbackPayload, type H5ExperienceRequest } from '../../game/experience/h5Experience'
import { type TrackColorPreset } from '../../game/presentation/trackStyleConfig'
import { type GpsMarkerColorPreset } from '../../game/presentation/gpsMarkerStyleConfig'
@@ -146,6 +153,7 @@ type MapPageData = MapEngineViewState & {
showLeftButtonGroup: boolean
showRightButtonGroups: boolean
showBottomDebugButton: boolean
showStartEntryButton: boolean
}
function getGlobalTelemetryProfile(): PlayerTelemetryProfile | null {
@@ -184,6 +192,7 @@ let systemSettingsLockLifetimeActive = false
let syncedBackendSessionStartId = ''
let syncedBackendSessionFinishId = ''
let shouldAutoRestoreRecoverySnapshot = false
let shouldAutoStartSessionOnEnter = false
let redirectedToResultPage = false
let pendingHeartRateSwitchDeviceName: string | null = null
const DEBUG_MOCK_CHANNEL_ID_STORAGE_KEY = 'cmr.debug.mockChannelId.v1'
@@ -828,6 +837,52 @@ function buildRuntimeSummaryRows(envelope: GameLaunchEnvelope): MapEngineGameInf
return rows
}
function buildLaunchConfigSummaryRows(envelope: GameLaunchEnvelope): MapEngineGameInfoRow[] {
const rows: MapEngineGameInfoRow[] = []
rows.push({ label: '配置标签', value: envelope.config.configLabel || '--' })
rows.push({ label: '配置URL', value: envelope.config.configUrl || '--' })
rows.push({ label: '配置Release', value: envelope.config.releaseId || '--' })
rows.push({
label: 'Launch Event',
value: envelope.business && envelope.business.eventId
? envelope.business.eventId
: '--',
})
rows.push({
label: 'Resolved Manifest',
value: envelope.resolvedRelease && envelope.resolvedRelease.manifestUrl
? envelope.resolvedRelease.manifestUrl
: '--',
})
rows.push({
label: 'Resolved Release',
value: envelope.resolvedRelease && envelope.resolvedRelease.releaseId
? envelope.resolvedRelease.releaseId
: '--',
})
return rows
}
function emitSimulatorLaunchDiagnostic(
stage: string,
payload: Record<string, unknown>,
) {
reportBackendClientLog({
level: 'info',
category: 'launch-diagnostic',
message: stage,
eventId: typeof payload.launchEventId === 'string' ? payload.launchEventId : '',
releaseId: typeof payload.configReleaseId === 'string'
? payload.configReleaseId
: (typeof payload.resolvedReleaseId === 'string' ? payload.resolvedReleaseId : ''),
sessionId: typeof payload.launchSessionId === 'string' ? payload.launchSessionId : '',
manifestUrl: typeof payload.resolvedManifestUrl === 'string'
? payload.resolvedManifestUrl
: (typeof payload.configUrl === 'string' ? payload.configUrl : ''),
details: payload,
})
}
Page({
data: {
showDebugPanel: false,
@@ -967,6 +1022,7 @@ Page({
centerScaleRulerMajorMarks: [],
compassTicks: buildCompassTicks(),
compassLabels: buildCompassLabels(),
showStartEntryButton: true,
...buildSideButtonVisibility('shown'),
...buildSideButtonState({
sideButtonMode: 'shown',
@@ -989,10 +1045,15 @@ Page({
syncedBackendSessionFinishId = ''
redirectedToResultPage = false
shouldAutoRestoreRecoverySnapshot = options && options.recoverSession === '1'
currentGameLaunchEnvelope = resolveGameLaunchEnvelope(options)
if (!hasExplicitLaunchOptions(options)) {
const recoverySnapshot = loadSessionRecoverySnapshot()
if (recoverySnapshot) {
shouldAutoStartSessionOnEnter = !!(options && options.autoStartOnEnter === '1')
const recoverySnapshot = loadSessionRecoverySnapshot()
if (shouldAutoRestoreRecoverySnapshot && recoverySnapshot) {
// Recovery should trust the persisted session envelope first so it can
// survive launchId stash misses and still reconstruct the original round.
currentGameLaunchEnvelope = recoverySnapshot.launchEnvelope
} else {
currentGameLaunchEnvelope = resolveGameLaunchEnvelope(options)
if (!hasExplicitLaunchOptions(options) && recoverySnapshot) {
currentGameLaunchEnvelope = recoverySnapshot.launchEnvelope
}
}
@@ -1005,6 +1066,9 @@ Page({
const statusBarHeight = systemInfo.statusBarHeight || 0
const menuButtonRect = wx.getMenuButtonBoundingClientRect()
const menuButtonBottom = menuButtonRect && typeof menuButtonRect.bottom === 'number' ? menuButtonRect.bottom : statusBarHeight
this.setData({
showStartEntryButton: !shouldAutoStartSessionOnEnter,
})
if (mapEngine) {
mapEngine.destroy()
@@ -1514,11 +1578,27 @@ Page({
systemSettingsLockLifetimeActive = false
currentGameLaunchEnvelope = getDemoGameLaunchEnvelope()
shouldAutoRestoreRecoverySnapshot = false
shouldAutoStartSessionOnEnter = false
redirectedToResultPage = false
stageCanvasAttached = false
},
loadGameLaunchEnvelope(envelope: GameLaunchEnvelope) {
emitSimulatorLaunchDiagnostic('loadGameLaunchEnvelope', {
launchEventId: envelope.business && envelope.business.eventId ? envelope.business.eventId : '',
launchSessionId: envelope.business && envelope.business.sessionId ? envelope.business.sessionId : '',
configUrl: envelope.config.configUrl || '',
configReleaseId: envelope.config.releaseId || '',
resolvedManifestUrl: envelope.resolvedRelease && envelope.resolvedRelease.manifestUrl
? envelope.resolvedRelease.manifestUrl
: '',
resolvedReleaseId: envelope.resolvedRelease && envelope.resolvedRelease.releaseId
? envelope.resolvedRelease.releaseId
: '',
launchVariantId: envelope.variant && envelope.variant.variantId ? envelope.variant.variantId : null,
launchVariantRouteCode: envelope.variant && envelope.variant.routeCode ? envelope.variant.routeCode : null,
runtimeCourseVariantId: envelope.runtime && envelope.runtime.courseVariantId ? envelope.runtime.courseVariantId : null,
})
this.loadMapConfigFromRemote(
envelope.config.configUrl,
envelope.config.configLabel,
@@ -1621,10 +1701,49 @@ Page({
reportAbandonedRecoverySnapshot(snapshot: SessionRecoverySnapshot) {
const sessionContext = getBackendSessionContextFromLaunchEnvelope(snapshot.launchEnvelope)
if (!sessionContext) {
reportBackendClientLog({
level: 'warn',
category: 'session-recovery',
message: 'abandon recovery without valid session context',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'abandon-no-session',
},
})
clearSessionRecoverySnapshot()
return
}
reportBackendClientLog({
level: 'info',
category: 'session-recovery',
message: 'abandon recovery requested',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: sessionContext.sessionId,
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'abandon-requested',
},
})
finishSession({
baseUrl: getCurrentBackendBaseUrl(),
sessionId: sessionContext.sessionId,
@@ -1634,6 +1753,26 @@ Page({
})
.then(() => {
syncedBackendSessionFinishId = sessionContext.sessionId
reportBackendClientLog({
level: 'info',
category: 'session-recovery',
message: 'abandon recovery synced as cancelled',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: sessionContext.sessionId,
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'abandon-finished',
},
})
clearSessionRecoverySnapshot()
wx.showToast({
title: '已放弃上次对局',
@@ -1642,6 +1781,27 @@ Page({
})
})
.catch((error) => {
reportBackendClientLog({
level: 'warn',
category: 'session-recovery',
message: 'abandon recovery finish(cancelled) failed',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: sessionContext.sessionId,
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'abandon-failed',
message: error && error.message ? error.message : '未知错误',
},
})
clearSessionRecoverySnapshot()
const message = error && error.message ? error.message : '未知错误'
this.setData({
@@ -1712,6 +1872,28 @@ Page({
this.applyRuntimeSystemSettings(true)
const restored = mapEngine ? mapEngine.restoreSessionRecoveryRuntimeSnapshot(snapshot.runtime) : false
if (!restored) {
reportBackendClientLog({
level: 'warn',
category: 'session-recovery',
message: 'recovery restore failed',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.sessionId
? snapshot.launchEnvelope.business.sessionId
: '',
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'restore-failed',
},
})
clearSessionRecoverySnapshot()
wx.showToast({
title: '恢复失败,已回到初始状态',
@@ -1726,11 +1908,34 @@ Page({
showDebugPanel: false,
showGameInfoPanel: false,
showSystemSettingsPanel: false,
showStartEntryButton: false,
})
const sessionContext = getCurrentBackendSessionContext()
if (sessionContext) {
syncedBackendSessionStartId = sessionContext.sessionId
}
reportBackendClientLog({
level: 'info',
category: 'session-recovery',
message: 'recovery restored',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.sessionId
? snapshot.launchEnvelope.business.sessionId
: '',
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'restored',
},
})
this.syncSessionRecoveryLifecycle('running')
return true
},
@@ -1752,24 +1957,77 @@ Page({
maybePromptSessionRecoveryRestore(config: RemoteMapConfig) {
const snapshot = loadSessionRecoverySnapshot()
if (!snapshot || !mapEngine) {
return
return false
}
if (
snapshot.launchEnvelope.config.configUrl !== currentGameLaunchEnvelope.config.configUrl
|| snapshot.configAppId !== config.configAppId
|| snapshot.configVersion !== config.configVersion
) {
reportBackendClientLog({
level: 'warn',
category: 'session-recovery',
message: 'recovery snapshot dropped due to config mismatch',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.sessionId
? snapshot.launchEnvelope.business.sessionId
: '',
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'config-mismatch',
currentConfigUrl: currentGameLaunchEnvelope.config.configUrl,
snapshotConfigUrl: snapshot.launchEnvelope.config.configUrl,
currentConfigAppId: config.configAppId,
snapshotConfigAppId: snapshot.configAppId,
},
})
clearSessionRecoverySnapshot()
return
this.setData({
statusText: '检测到旧局恢复记录,但当前配置源已变化,已回到初始状态',
})
return false
}
if (shouldAutoRestoreRecoverySnapshot) {
shouldAutoRestoreRecoverySnapshot = false
reportBackendClientLog({
level: 'info',
category: 'session-recovery',
message: 'auto recovery requested',
eventId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.eventId
? snapshot.launchEnvelope.business.eventId
: '',
releaseId: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.releaseId
? snapshot.launchEnvelope.config.releaseId
: '',
sessionId: snapshot.launchEnvelope.business && snapshot.launchEnvelope.business.sessionId
? snapshot.launchEnvelope.business.sessionId
: '',
manifestUrl: snapshot.launchEnvelope.resolvedRelease && snapshot.launchEnvelope.resolvedRelease.manifestUrl
? snapshot.launchEnvelope.resolvedRelease.manifestUrl
: snapshot.launchEnvelope.config && snapshot.launchEnvelope.config.configUrl
? snapshot.launchEnvelope.config.configUrl
: '',
details: {
phase: 'auto-restore',
},
})
this.restoreRecoverySnapshot(snapshot)
return
return true
}
this.setData({
showStartEntryButton: true,
})
wx.showModal({
title: '恢复对局',
content: '检测到上次有未正常结束的对局,是否继续恢复?',
@@ -1784,6 +2042,21 @@ Page({
this.restoreRecoverySnapshot(snapshot)
},
})
return true
},
maybeAutoStartSessionOnEnter() {
if (!shouldAutoStartSessionOnEnter || !mapEngine) {
return
}
shouldAutoStartSessionOnEnter = false
systemSettingsLockLifetimeActive = true
this.applyRuntimeSystemSettings(true)
this.setData({
showStartEntryButton: false,
})
mapEngine.handleStartGame()
},
compileCurrentRuntimeProfile(lockLifetimeActive = isSystemSettingsLockLifetimeActive()) {
@@ -1913,20 +2186,76 @@ Page({
return
}
emitSimulatorLaunchDiagnostic('loadRemoteMapConfig:resolved', {
launchEventId: currentGameLaunchEnvelope.business && currentGameLaunchEnvelope.business.eventId
? currentGameLaunchEnvelope.business.eventId
: '',
configUrl,
configVersion: config.configVersion || '',
schemaVersion: config.configSchemaVersion || '',
playfieldKind: config.playfieldKind || '',
gameMode: config.gameMode || '',
configTitle: config.configTitle || '',
})
currentEngine.applyRemoteMapConfig(config)
this.applyConfiguredSystemSettings(config)
this.applyCompiledRuntimeProfiles(true, {
const compiledProfile = this.applyCompiledRuntimeProfiles(true, {
includeMap: true,
includeGame: true,
includePresentation: true,
})
this.maybePromptSessionRecoveryRestore(config)
if (compiledProfile) {
reportBackendClientLog({
level: 'info',
category: 'runtime-compiler',
message: 'compiled runtime profile applied',
eventId: currentGameLaunchEnvelope.business && currentGameLaunchEnvelope.business.eventId
? currentGameLaunchEnvelope.business.eventId
: '',
releaseId: currentGameLaunchEnvelope.config && currentGameLaunchEnvelope.config.releaseId
? currentGameLaunchEnvelope.config.releaseId
: '',
sessionId: currentGameLaunchEnvelope.business && currentGameLaunchEnvelope.business.sessionId
? currentGameLaunchEnvelope.business.sessionId
: '',
manifestUrl: currentGameLaunchEnvelope.resolvedRelease && currentGameLaunchEnvelope.resolvedRelease.manifestUrl
? currentGameLaunchEnvelope.resolvedRelease.manifestUrl
: currentGameLaunchEnvelope.config && currentGameLaunchEnvelope.config.configUrl
? currentGameLaunchEnvelope.config.configUrl
: '',
details: {
phase: 'compiled-runtime-applied',
schemaVersion: config.configSchemaVersion || '',
playfield: {
kind: config.playfieldKind || '',
},
game: {
mode: config.gameMode || '',
},
},
})
}
const recoveryHandled = this.maybePromptSessionRecoveryRestore(config)
if (!recoveryHandled) {
this.maybeAutoStartSessionOnEnter()
} else {
shouldAutoStartSessionOnEnter = false
}
})
.catch((error) => {
if (mapEngine !== currentEngine) {
return
}
emitSimulatorLaunchDiagnostic('loadRemoteMapConfig:error', {
launchEventId: currentGameLaunchEnvelope.business && currentGameLaunchEnvelope.business.eventId
? currentGameLaunchEnvelope.business.eventId
: '',
configUrl,
message: error && error.message ? error.message : '未知错误',
})
const rawErrorMessage = error && error.message ? error.message : '未知错误'
const errorMessage = rawErrorMessage.indexOf('404') >= 0
? `release manifest 不存在或未发布 (${configLabel})`
@@ -2115,6 +2444,10 @@ Page({
})
persistMockChannelId(channelId)
persistMockAutoConnectEnabled(true)
setGlobalMockDebugBridgeChannelId(channelId)
setGlobalMockDebugBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
persistStoredMockDebugLogBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
setGlobalMockDebugBridgeEnabled(true)
mapEngine.handleSetMockChannelId(channelId)
mapEngine.handleSetMockLocationBridgeUrl(this.data.mockBridgeUrlDraft)
mapEngine.handleSetMockHeartRateBridgeUrl(this.data.mockHeartRateBridgeUrlDraft)
@@ -2144,6 +2477,7 @@ Page({
mockChannelIdDraft: channelId,
})
persistMockChannelId(channelId)
setGlobalMockDebugBridgeChannelId(channelId)
if (mapEngine) {
mapEngine.handleSetMockChannelId(channelId)
}
@@ -2199,12 +2533,17 @@ Page({
},
handleSaveMockDebugLogBridgeUrl() {
persistStoredMockDebugLogBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
setGlobalMockDebugBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
if (mapEngine) {
mapEngine.handleSetMockDebugLogBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
}
},
handleConnectMockDebugLogBridge() {
setGlobalMockDebugBridgeChannelId((this.data.mockChannelIdDraft || '').trim() || 'default')
setGlobalMockDebugBridgeUrl(this.data.mockDebugLogBridgeUrlDraft)
setGlobalMockDebugBridgeEnabled(true)
if (mapEngine) {
mapEngine.handleConnectMockDebugLogBridge()
}
@@ -2212,6 +2551,7 @@ Page({
handleDisconnectMockDebugLogBridge() {
persistMockAutoConnectEnabled(false)
setGlobalMockDebugBridgeEnabled(false)
if (mapEngine) {
mapEngine.handleDisconnectMockDebugLogBridge()
}
@@ -2358,8 +2698,12 @@ Page({
handleStartGame() {
if (mapEngine) {
shouldAutoStartSessionOnEnter = false
systemSettingsLockLifetimeActive = true
this.applyRuntimeSystemSettings(true)
this.setData({
showStartEntryButton: false,
})
mapEngine.handleStartGame()
}
},
@@ -2443,6 +2787,7 @@ Page({
const snapshot = mapEngine.getGameInfoSnapshot()
const localRows = snapshot.localRows.concat([
...buildRuntimeSummaryRows(currentGameLaunchEnvelope),
...buildLaunchConfigSummaryRows(currentGameLaunchEnvelope),
{ label: '比例尺开关', value: this.data.showCenterScaleRuler ? '开启' : '关闭' },
{ label: '比例尺锚点', value: this.data.centerScaleRulerAnchorMode === 'compass-center' ? '指北针圆心' : '屏幕中心' },
{ label: '按钮习惯', value: this.data.sideButtonPlacement === 'right' ? '右手' : '左手' },
@@ -2471,7 +2816,9 @@ Page({
resultSceneSubtitle: snapshot.subtitle,
resultSceneHeroLabel: snapshot.heroLabel,
resultSceneHeroValue: snapshot.heroValue,
resultSceneRows: snapshot.rows.concat(buildRuntimeSummaryRows(currentGameLaunchEnvelope)),
resultSceneRows: snapshot.rows
.concat(buildRuntimeSummaryRows(currentGameLaunchEnvelope))
.concat(buildLaunchConfigSummaryRows(currentGameLaunchEnvelope)),
})
},

View File

@@ -158,7 +158,7 @@
<cover-view class="map-content-entry__text">{{pendingContentEntryText}}</cover-view>
</cover-view>
<cover-view class="screen-button-layer screen-button-layer--start-left" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showResultScene && !showSystemSettingsPanel && showBottomDebugButton && gameSessionStatus !== 'running'}}" bindtap="handleStartGame">
<cover-view class="screen-button-layer screen-button-layer--start-left" wx:if="{{!showDebugPanel && !showGameInfoPanel && !showResultScene && !showSystemSettingsPanel && showBottomDebugButton && showStartEntryButton && gameSessionStatus !== 'running'}}" bindtap="handleStartGame">
<cover-view class="screen-button-layer__text screen-button-layer__text--start">开始</cover-view>
</cover-view>