feat(multiplayer,playlist): complete the filter for /rooms

This commit is contained in:
MingxuanGame
2025-08-09 06:28:37 +00:00
parent 99f2b3db2a
commit e236c06f0f
4 changed files with 50 additions and 19 deletions

View File

@@ -76,7 +76,7 @@ class Room(AsyncAttrs, RoomBase, table=True):
class RoomResp(RoomBase): class RoomResp(RoomBase):
id: int id: int
password: str | None = None has_password: bool = False
host: UserResp | None = None host: UserResp | None = None
playlist: list[PlaylistResp] = [] playlist: list[PlaylistResp] = []
playlist_item_stats: RoomPlaylistItemStats | None = None playlist_item_stats: RoomPlaylistItemStats | None = None

View File

@@ -10,6 +10,7 @@ class RoomCategory(str, Enum):
SPOTLIGHT = "spotlight" SPOTLIGHT = "spotlight"
FEATURED_ARTIST = "featured_artist" FEATURED_ARTIST = "featured_artist"
DAILY_CHALLENGE = "daily_challenge" DAILY_CHALLENGE = "daily_challenge"
REALTIME = "realtime"
class MatchType(str, Enum): class MatchType(str, Enum):

View File

@@ -13,10 +13,8 @@ from app.database.room import Room, RoomBase, RoomResp
from app.database.room_participated_user import RoomParticipatedUser from app.database.room_participated_user import RoomParticipatedUser
from app.database.score import Score from app.database.score import Score
from app.dependencies.database import get_db, get_redis 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.dependencies.user import get_current_user
from app.fetcher import Fetcher from app.models.room import RoomCategory, RoomStatus
from app.models.room import RoomStatus
from app.signalr.hub import MultiplayerHubs from app.signalr.hub import MultiplayerHubs
from .api_router import router from .api_router import router
@@ -24,7 +22,7 @@ from .api_router import router
from fastapi import Depends, HTTPException, Query from fastapi import Depends, HTTPException, Query
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from redis.asyncio import Redis from redis.asyncio import Redis
from sqlmodel import col, select from sqlmodel import col, exists, select
from sqlmodel.ext.asyncio.session import AsyncSession from sqlmodel.ext.asyncio.session import AsyncSession
@@ -32,26 +30,57 @@ from sqlmodel.ext.asyncio.session import AsyncSession
async def get_all_rooms( async def get_all_rooms(
mode: Literal["open", "ended", "participated", "owned", None] = Query( mode: Literal["open", "ended", "participated", "owned", None] = Query(
default="open" default="open"
), # TODO: 对房间根据状态进行筛选 ),
category: str | None = Query(None), # TODO category: RoomCategory = Query(RoomCategory.NORMAL),
status: RoomStatus | None = Query(None), status: RoomStatus | None = Query(None),
db: AsyncSession = Depends(get_db), db: AsyncSession = Depends(get_db),
fetcher: Fetcher = Depends(get_fetcher),
redis: Redis = Depends(get_redis),
current_user: User = Depends(get_current_user), current_user: User = Depends(get_current_user),
): ):
resp_list: list[RoomResp] = [] resp_list: list[RoomResp] = []
db_rooms = (await db.exec(select(Room).where(True))).unique().all() db_rooms = (await db.exec(select(Room).where(True))).unique().all()
now = datetime.now(UTC)
for room in db_rooms: for room in db_rooms:
if category == "realtime": if category == RoomCategory.REALTIME and room.id not in MultiplayerHubs.rooms:
if room.id in MultiplayerHubs.rooms: continue
resp_list.append(await RoomResp.from_db(room, db)) elif category != RoomCategory.REALTIME and category != room.category:
elif category is not None: continue
if category == room.category:
resp_list.append(await RoomResp.from_db(room, db)) if status is not None and room.status != status:
else: continue
if room.id not in MultiplayerHubs.rooms:
resp_list.append(await RoomResp.from_db(room, db)) 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 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.commit()
await db.refresh(db_room) await db.refresh(db_room)
resp = await RoomResp.from_db(db_room, db) resp = await RoomResp.from_db(db_room, db)
return resp return resp
else: else:
raise HTTPException(404, "room not found0") raise HTTPException(404, "room not found0")

View File

@@ -181,7 +181,7 @@ class MultiplayerHub(Hub[MultiplayerClientState]):
async with session: async with session:
db_room = Room( db_room = Room(
name=room.settings.name, name=room.settings.name,
category=RoomCategory.NORMAL, category=RoomCategory.REALTIME,
type=room.settings.match_type, type=room.settings.match_type,
queue_mode=room.settings.queue_mode, queue_mode=room.settings.queue_mode,
auto_skip=room.settings.auto_skip, auto_skip=room.settings.auto_skip,