update server

This commit is contained in:
bridge
2025-11-22 14:05:56 +08:00
parent dfba5fda28
commit 460984e5ab
2 changed files with 47 additions and 14 deletions

View File

@@ -32,7 +32,7 @@ import random
game_instance = {
"world": None,
"sim": None,
"is_paused": False # 新增暂停标记
"is_paused": True # 默认启动为暂停状态,等待前端连接唤醒
}
# 简易的命令行参数检查 (不使用 argparse 以避免冲突和时序问题)
@@ -45,9 +45,24 @@ class ConnectionManager:
async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)
# 当第一个客户端连接时,自动恢复游戏
if len(self.active_connections) == 1:
self._set_pause_state(False, "检测到客户端连接,自动恢复游戏运行。")
def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)
if websocket in self.active_connections:
self.active_connections.remove(websocket)
# 当最后一个客户端断开时,自动暂停游戏
if len(self.active_connections) == 0:
self._set_pause_state(True, "所有客户端已断开,自动暂停游戏以节省资源。")
def _set_pause_state(self, should_pause: bool, log_msg: str):
"""辅助方法:切换暂停状态并打印日志"""
if game_instance.get("is_paused") != should_pause:
game_instance["is_paused"] = should_pause
print(f"[Auto-Control] {log_msg}")
async def broadcast(self, message: dict):
import json

View File

@@ -68,6 +68,14 @@ export const useGameStore = defineStore('game', () => {
if (Array.isArray(payload.avatars)) {
mergeAvatars(payload.avatars)
}
// Tick means time passed, so cache is stale
hoverCache.clear()
// If panel is open, silently refresh content to show latest status
if (selectedTarget.value) {
fetchHoverInfo(selectedTarget.value, { force: true, silent: true })
}
}
function mergeAvatars(list: Avatar[]) {
@@ -117,23 +125,29 @@ export const useGameStore = defineStore('game', () => {
}
}
async function fetchHoverInfo(target: HoverTarget, forceRefresh = false) {
async function fetchHoverInfo(target: HoverTarget, options: { force?: boolean, silent?: boolean } = {}) {
const { force = false, silent = false } = options
const key = cacheKey(target)
if (!forceRefresh) {
if (!force) {
const cached = hoverCache.get(key)
if (cached) {
if (selectedTarget.value && cacheKey(selectedTarget.value) === key) {
hoverInfo.value = cached
}
infoLoading.value = false
infoError.value = null
if (!silent) {
infoLoading.value = false
infoError.value = null
}
return
}
}
infoLoading.value = true
infoError.value = null
if (!forceRefresh) hoverInfo.value = []
if (!silent) {
infoLoading.value = true
infoError.value = null
if (!force) hoverInfo.value = []
}
try {
const data = await gameApi.getHoverInfo(target)
@@ -144,12 +158,16 @@ export const useGameStore = defineStore('game', () => {
}
} catch (error) {
if (selectedTarget.value && cacheKey(selectedTarget.value) === key) {
infoError.value = error instanceof Error ? error.message : String(error)
hoverInfo.value = []
if (!silent) {
infoError.value = error instanceof Error ? error.message : String(error)
hoverInfo.value = []
}
}
} finally {
if (selectedTarget.value && cacheKey(selectedTarget.value) === key) {
infoLoading.value = false
if (!silent) {
infoLoading.value = false
}
}
}
}
@@ -158,7 +176,7 @@ export const useGameStore = defineStore('game', () => {
await gameApi.setLongTermObjective(avatarId, content)
// 成功后刷新 info panel
if (selectedTarget.value && selectedTarget.value.id === avatarId && selectedTarget.value.type === 'avatar') {
await fetchHoverInfo(selectedTarget.value, true)
await fetchHoverInfo(selectedTarget.value, { force: true })
}
}
@@ -166,7 +184,7 @@ export const useGameStore = defineStore('game', () => {
await gameApi.clearLongTermObjective(avatarId)
// 成功后刷新 info panel
if (selectedTarget.value && selectedTarget.value.id === avatarId && selectedTarget.value.type === 'avatar') {
await fetchHoverInfo(selectedTarget.value, true)
await fetchHoverInfo(selectedTarget.value, { force: true })
}
}