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):
|
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
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user