fix(multiplayer): try to fix cannot spectate by changing state one by one

This commit is contained in:
MingxuanGame
2025-08-18 14:02:33 +00:00
parent 68f47c5a24
commit 13803c7054
2 changed files with 13 additions and 12 deletions

View File

@@ -660,10 +660,6 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
if user.state == state: if user.state == state:
return return
logger.info(
f"[MultiplayerHub] {user.user_id}'s state "
f"changed from {user.state} to {state}"
)
match state: match state:
case MultiplayerUserState.IDLE: case MultiplayerUserState.IDLE:
if user.state.is_playing: if user.state.is_playing:
@@ -691,6 +687,10 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
user: MultiplayerRoomUser, user: MultiplayerRoomUser,
state: MultiplayerUserState, state: MultiplayerUserState,
): ):
logger.info(
f"[MultiplayerHub] {user.user_id}'s state "
f"changed from {user.state} to {state}"
)
user.state = state user.state = state
await self.broadcast_group_call( await self.broadcast_group_call(
self.group_id(room.room.room_id), self.group_id(room.room.room_id),
@@ -796,7 +796,6 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
if all(u.state != MultiplayerUserState.READY for u in room.users): if all(u.state != MultiplayerUserState.READY for u in room.users):
raise InvokeException("Can't start match when no users are ready.") raise InvokeException("Can't start match when no users are ready.")
logger.info(f"[MultiplayerHub] Room {room.room_id} match started")
await self.start_match(server_room) await self.start_match(server_room)
async def start_match(self, room: ServerMultiplayerRoom): async def start_match(self, room: ServerMultiplayerRoom):
@@ -804,6 +803,12 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
raise InvokeException("Can't start match when already in a running state.") raise InvokeException("Can't start match when already in a running state.")
if room.queue.current_item.expired: if room.queue.current_item.expired:
raise InvokeException("Current playlist item is expired") raise InvokeException("Current playlist item is expired")
if all(u.state != MultiplayerUserState.READY for u in room.room.users):
await room.queue.finish_current_item()
logger.info(f"[MultiplayerHub] Room {room.room.room_id} match started")
ready_users = [ ready_users = [
u u
for u in room.room.users for u in room.room.users
@@ -813,12 +818,8 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
or u.state == MultiplayerUserState.IDLE or u.state == MultiplayerUserState.IDLE
) )
] ]
await asyncio.gather( for u in ready_users:
*[ await self.change_user_state(room, u, MultiplayerUserState.WAITING_FOR_LOAD)
self.change_user_state(room, u, MultiplayerUserState.WAITING_FOR_LOAD)
for u in ready_users
]
)
await self.change_room_state( await self.change_room_state(
room, room,
MultiplayerRoomState.WAITING_FOR_LOAD, MultiplayerRoomState.WAITING_FOR_LOAD,

View File

@@ -6,7 +6,6 @@ import lzma
import struct import struct
import time import time
from typing import override from typing import override
from venv import logger
from app.calculator import clamp from app.calculator import clamp
from app.config import settings from app.config import settings
@@ -19,6 +18,7 @@ from app.dependencies.database import engine, get_redis
from app.dependencies.fetcher import get_fetcher from app.dependencies.fetcher import get_fetcher
from app.dependencies.storage import get_storage_service from app.dependencies.storage import get_storage_service
from app.exception import InvokeException from app.exception import InvokeException
from app.log import logger
from app.models.mods import APIMod, mods_to_int from app.models.mods import APIMod, mods_to_int
from app.models.score import GameMode, LegacyReplaySoloScoreInfo, ScoreStatistics from app.models.score import GameMode, LegacyReplaySoloScoreInfo, ScoreStatistics
from app.models.spectator_hub import ( from app.models.spectator_hub import (