feat(multiplayer,playlist): complete the filter for /rooms
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -10,6 +10,7 @@ class RoomCategory(str, Enum):
|
||||
SPOTLIGHT = "spotlight"
|
||||
FEATURED_ARTIST = "featured_artist"
|
||||
DAILY_CHALLENGE = "daily_challenge"
|
||||
REALTIME = "realtime"
|
||||
|
||||
|
||||
class MatchType(str, Enum):
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user