105 lines
3.3 KiB
Python
105 lines
3.3 KiB
Python
from __future__ import annotations
|
||
|
||
from datetime import UTC, datetime
|
||
from time import timezone
|
||
from typing import Literal
|
||
|
||
from app.database.lazer_user import User
|
||
from app.database.playlists import Playlist
|
||
from app.database.room import Room, RoomBase, RoomResp
|
||
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.multiplayer_hub import MultiplayerRoom, ServerMultiplayerRoom
|
||
from app.models.room import RoomStatus
|
||
from app.signalr.hub import MultiplayerHubs
|
||
|
||
from .api_router import router
|
||
|
||
from fastapi import Depends, Query
|
||
from redis.asyncio import Redis
|
||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||
|
||
|
||
@router.get("/rooms", tags=["rooms"], response_model=list[RoomResp])
|
||
async def get_all_rooms(
|
||
mode: Literal["open", "ended", "participated", "owned", None] = Query(
|
||
default="open"
|
||
), # TODO: 对房间根据状态进行筛选
|
||
category: str = Query(default="realtime"), # TODO
|
||
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),
|
||
):
|
||
rooms = MultiplayerHubs.rooms.values()
|
||
resp_list: list[RoomResp] = []
|
||
for room in rooms:
|
||
if category == "realtime" and room.category != "normal":
|
||
continue
|
||
elif category != room.category:
|
||
continue
|
||
resp_list.append(await RoomResp.from_hub(room))
|
||
return resp_list
|
||
|
||
|
||
class APICreatedRoom(RoomResp):
|
||
error: str = ""
|
||
|
||
|
||
class APIUploadedRoom(RoomBase):
|
||
def to_room(self) -> Room:
|
||
"""
|
||
将 APIUploadedRoom 转换为 Room 对象,playlist 字段需单独处理。
|
||
"""
|
||
room_dict = self.model_dump()
|
||
room_dict.pop("playlist", None)
|
||
# host_id 已在字段中
|
||
return Room(**room_dict)
|
||
|
||
id: int | None
|
||
host_id: int | None = None
|
||
playlist: list[Playlist]
|
||
|
||
|
||
@router.post("/rooms", tags=["room"], response_model=APICreatedRoom)
|
||
async def create_room(
|
||
room: APIUploadedRoom,
|
||
db: AsyncSession = Depends(get_db),
|
||
current_user: User = Depends(get_current_user),
|
||
):
|
||
# db_room = Room.from_resp(room)
|
||
await db.refresh(current_user)
|
||
user_id = current_user.id
|
||
db_room = room.to_room()
|
||
db_room.host_id = current_user.id if current_user.id else 1
|
||
db.add(db_room)
|
||
await db.commit()
|
||
await db.refresh(db_room)
|
||
|
||
playlist: list[Playlist] = []
|
||
# 处理 APIUploadedRoom 里的 playlist 字段
|
||
for item in room.playlist:
|
||
# 确保 room_id 正确赋值
|
||
item.id = await Playlist.get_next_id_for_room(db_room.id, db)
|
||
item.room_id = db_room.id
|
||
item.owner_id = user_id if user_id else 1
|
||
db.add(item)
|
||
await db.commit()
|
||
await db.refresh(item)
|
||
playlist.append(item)
|
||
await db.refresh(db_room)
|
||
db_room.playlist = playlist
|
||
server_room = ServerMultiplayerRoom(
|
||
room=MultiplayerRoom.from_db(db_room),
|
||
category=db_room.category,
|
||
start_at=datetime.now(UTC),
|
||
hub=MultiplayerHubs,
|
||
)
|
||
MultiplayerHubs.rooms[db_room.id] = server_room
|
||
created_room = APICreatedRoom.model_validate(db_room)
|
||
created_room.error = ""
|
||
return created_room
|