refactor(multiplayer): reuse code & sync settings to database
This commit is contained in:
@@ -336,12 +336,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
async def ChangeBeatmapAvailability(
|
||||
self, client: Client, beatmap_availability: BeatmapAvailability
|
||||
):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -353,12 +348,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def AddPlaylistItem(self, client: Client, item: PlaylistItem):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
@@ -374,12 +364,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def EditPlaylistItem(self, client: Client, item: PlaylistItem):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
@@ -396,12 +381,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def RemovePlaylistItem(self, client: Client, item_id: int):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
@@ -417,7 +397,25 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
user,
|
||||
)
|
||||
|
||||
async def change_db_settings(self, room: ServerMultiplayerRoom):
|
||||
async with AsyncSession(engine) as session:
|
||||
await session.execute(
|
||||
update(Room)
|
||||
.where(col(Room.id) == room.room.room_id)
|
||||
.values(
|
||||
name=room.room.settings.name,
|
||||
type=room.room.settings.match_type,
|
||||
queue_mode=room.room.settings.queue_mode,
|
||||
auto_skip=room.room.settings.auto_skip,
|
||||
auto_start_duration=int(
|
||||
room.room.settings.auto_start_duration.total_seconds()
|
||||
),
|
||||
host_id=room.room.host.user_id,
|
||||
)
|
||||
)
|
||||
|
||||
async def setting_changed(self, room: ServerMultiplayerRoom, beatmap_changed: bool):
|
||||
await self.change_db_settings(room)
|
||||
await self.validate_styles(room)
|
||||
await self.unready_all_users(room, beatmap_changed)
|
||||
await self.broadcast_group_call(
|
||||
@@ -455,12 +453,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
async def ChangeUserStyle(
|
||||
self, client: Client, beatmap_id: int | None, ruleset_id: int | None
|
||||
):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -583,12 +576,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def ChangeUserMods(self, client: Client, new_mods: list[APIMod]):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -645,7 +633,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
"Cannot ready up while all items have been played."
|
||||
)
|
||||
case MultiplayerUserState.WAITING_FOR_LOAD:
|
||||
raise InvokeException("Cannot change state from {old} to {new}")
|
||||
raise InvokeException(f"Cannot change state from {old} to {new}")
|
||||
case MultiplayerUserState.LOADED:
|
||||
if old != MultiplayerUserState.WAITING_FOR_LOAD:
|
||||
raise InvokeException(f"Cannot change state from {old} to {new}")
|
||||
@@ -658,18 +646,13 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
if old != MultiplayerUserState.PLAYING:
|
||||
raise InvokeException(f"Cannot change state from {old} to {new}")
|
||||
case MultiplayerUserState.RESULTS:
|
||||
raise InvokeException("Cannot change state from {old} to {new}")
|
||||
raise InvokeException(f"Cannot change state from {old} to {new}")
|
||||
case MultiplayerUserState.SPECTATING:
|
||||
if old not in (MultiplayerUserState.IDLE, MultiplayerUserState.READY):
|
||||
raise InvokeException(f"Cannot change state from {old} to {new}")
|
||||
|
||||
async def ChangeState(self, client: Client, state: MultiplayerUserState):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -795,18 +778,12 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def StartMatch(self, client: Client):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
raise InvokeException("You are not in this room")
|
||||
if room.host is None or room.host.user_id != client.user_id:
|
||||
raise InvokeException("You are not the host of this room")
|
||||
self._ensure_host(client, server_room)
|
||||
|
||||
# Check host state - host must be ready or spectating
|
||||
if room.host.state not in (
|
||||
@@ -998,9 +975,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
return
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -1014,16 +989,9 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
logger.info(f"[MultiplayerHub] {client.user_id} left room {room.room_id}")
|
||||
|
||||
async def KickUser(self, client: Client, user_id: int):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
|
||||
if room.host is None or room.host.user_id != client.user_id:
|
||||
raise InvokeException("You are not the host of this room")
|
||||
self._ensure_host(client, server_room)
|
||||
|
||||
if user_id == client.user_id:
|
||||
raise InvokeException("Can't kick self")
|
||||
@@ -1047,6 +1015,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
|
||||
async def set_host(self, room: ServerMultiplayerRoom, user: MultiplayerRoomUser):
|
||||
room.room.host = user
|
||||
await self.change_db_settings(room)
|
||||
await self.broadcast_group_call(
|
||||
self.group_id(room.room.room_id),
|
||||
"HostChanged",
|
||||
@@ -1054,16 +1023,9 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def TransferHost(self, client: Client, user_id: int):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
|
||||
if room.host is None or room.host.user_id != client.user_id:
|
||||
raise InvokeException("You are not the host of this room")
|
||||
self._ensure_host(client, server_room)
|
||||
|
||||
new_host = next((u for u in room.users if u.user_id == user_id), None)
|
||||
if new_host is None:
|
||||
@@ -1079,12 +1041,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
)
|
||||
|
||||
async def AbortGameplay(self, client: Client):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -1101,16 +1058,9 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
await self.update_room_state(server_room)
|
||||
|
||||
async def AbortMatch(self, client: Client):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
|
||||
if room.host is None or room.host.user_id != client.user_id:
|
||||
raise InvokeException("You are not the host of this room")
|
||||
self._ensure_host(client, server_room)
|
||||
|
||||
if (
|
||||
room.state != MultiplayerRoomState.PLAYING
|
||||
@@ -1175,12 +1125,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
await self.update_room_state(server_room)
|
||||
|
||||
async def SendMatchRequest(self, client: Client, request: MatchRequest):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
@@ -1190,7 +1135,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
if room.host and room.host.user_id != user.user_id:
|
||||
raise InvokeException("You are not the host of this room")
|
||||
if room.state != MultiplayerRoomState.OPEN:
|
||||
raise InvokeException("Cannot start a countdown during ongoing play")
|
||||
raise InvokeException("Cannot start match countdown when not open")
|
||||
await server_room.start_countdown(
|
||||
MatchStartCountdown(time_remaining=request.duration),
|
||||
self.start_match,
|
||||
@@ -1215,12 +1160,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
|
||||
await server_room.match_type_handler.handle_request(user, request)
|
||||
|
||||
async def InvitePlayer(self, client: Client, user_id: int):
|
||||
store = self.get_or_create_state(client)
|
||||
if store.room_id == 0:
|
||||
raise InvokeException("You are not in a room")
|
||||
if store.room_id not in self.rooms:
|
||||
raise InvokeException("Room does not exist")
|
||||
server_room = self.rooms[store.room_id]
|
||||
server_room = self._ensure_in_room(client)
|
||||
room = server_room.room
|
||||
user = next((u for u in room.users if u.user_id == client.user_id), None)
|
||||
if user is None:
|
||||
|
||||
Reference in New Issue
Block a user