From e236c06f0f6c9bd0d2cf03d35e639555949f2393 Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Sat, 9 Aug 2025 06:28:37 +0000 Subject: [PATCH] feat(multiplayer,playlist): complete the filter for `/rooms` --- app/database/room.py | 2 +- app/models/room.py | 1 + app/router/room.py | 64 +++++++++++++++++++++++++--------- app/signalr/hub/multiplayer.py | 2 +- 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/app/database/room.py b/app/database/room.py index f0234e8..3b59ab0 100644 --- a/app/database/room.py +++ b/app/database/room.py @@ -76,7 +76,7 @@ class Room(AsyncAttrs, RoomBase, table=True): class RoomResp(RoomBase): id: int - password: str | None = None + has_password: bool = False host: UserResp | None = None playlist: list[PlaylistResp] = [] playlist_item_stats: RoomPlaylistItemStats | None = None diff --git a/app/models/room.py b/app/models/room.py index 392562a..cc257c2 100644 --- a/app/models/room.py +++ b/app/models/room.py @@ -10,6 +10,7 @@ class RoomCategory(str, Enum): SPOTLIGHT = "spotlight" FEATURED_ARTIST = "featured_artist" DAILY_CHALLENGE = "daily_challenge" + REALTIME = "realtime" class MatchType(str, Enum): diff --git a/app/router/room.py b/app/router/room.py index c3d4aee..c13574b 100644 --- a/app/router/room.py +++ b/app/router/room.py @@ -13,10 +13,8 @@ from app.database.room import Room, RoomBase, RoomResp from app.database.room_participated_user import RoomParticipatedUser from app.database.score import Score from app.dependencies.database import get_db, get_redis -from app.dependencies.fetcher import get_fetcher from app.dependencies.user import get_current_user -from app.fetcher import Fetcher -from app.models.room import RoomStatus +from app.models.room import RoomCategory, RoomStatus from app.signalr.hub import MultiplayerHubs from .api_router import router @@ -24,7 +22,7 @@ from .api_router import router from fastapi import Depends, HTTPException, Query from pydantic import BaseModel, Field from redis.asyncio import Redis -from sqlmodel import col, select +from sqlmodel import col, exists, select from sqlmodel.ext.asyncio.session import AsyncSession @@ -32,26 +30,57 @@ from sqlmodel.ext.asyncio.session import AsyncSession async def get_all_rooms( mode: Literal["open", "ended", "participated", "owned", None] = Query( default="open" - ), # TODO: 对房间根据状态进行筛选 - category: str | None = Query(None), # TODO + ), + category: RoomCategory = Query(RoomCategory.NORMAL), status: RoomStatus | None = Query(None), db: AsyncSession = Depends(get_db), - fetcher: Fetcher = Depends(get_fetcher), - redis: Redis = Depends(get_redis), current_user: User = Depends(get_current_user), ): resp_list: list[RoomResp] = [] db_rooms = (await db.exec(select(Room).where(True))).unique().all() + now = datetime.now(UTC) for room in db_rooms: - if category == "realtime": - if room.id in MultiplayerHubs.rooms: - resp_list.append(await RoomResp.from_db(room, db)) - elif category is not None: - if category == room.category: - resp_list.append(await RoomResp.from_db(room, db)) - else: - if room.id not in MultiplayerHubs.rooms: - resp_list.append(await RoomResp.from_db(room, db)) + if category == RoomCategory.REALTIME and room.id not in MultiplayerHubs.rooms: + continue + elif category != RoomCategory.REALTIME and category != room.category: + continue + + if status is not None and room.status != status: + continue + + if ( + mode == "open" + and room.ends_at is not None + and room.ends_at.replace(tzinfo=UTC) < now + ): + continue + if ( + mode == "participated" + and not ( + await db.exec( + select(exists()).where( + RoomParticipatedUser.room_id == room.id, + RoomParticipatedUser.user_id == current_user.id, + ) + ) + ).first() + ): + continue + if mode == "owned" and room.host_id != current_user.id: + continue + if mode == "ended" and ( + room.ends_at is None + or room.ends_at.replace(tzinfo=UTC) < (now - timedelta(days=30)) + ): + continue + + resp = await RoomResp.from_db(room, db) + if category == RoomCategory.REALTIME: + resp.has_password = bool( + MultiplayerHubs.rooms[room.id].room.settings.password.strip() + ) + resp_list.append(resp) + return resp_list @@ -167,6 +196,7 @@ async def add_user_to_room(room: int, user: int, db: AsyncSession = Depends(get_ await db.commit() await db.refresh(db_room) resp = await RoomResp.from_db(db_room, db) + return resp else: raise HTTPException(404, "room not found0") diff --git a/app/signalr/hub/multiplayer.py b/app/signalr/hub/multiplayer.py index f7763df..46f24d9 100644 --- a/app/signalr/hub/multiplayer.py +++ b/app/signalr/hub/multiplayer.py @@ -181,7 +181,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]): async with session: db_room = Room( name=room.settings.name, - category=RoomCategory.NORMAL, + category=RoomCategory.REALTIME, type=room.settings.match_type, queue_mode=room.settings.queue_mode, auto_skip=room.settings.auto_skip,