fix(multiplayer): move playlists rooms to database

This commit is contained in:
jimmy-sketch
2025-08-08 13:07:29 +00:00
parent 28f7888294
commit 0710ccecbe
2 changed files with 21 additions and 27 deletions

View File

@@ -1,5 +1,6 @@
from datetime import UTC, datetime from datetime import UTC, datetime
from app.models.model import UTCBaseModel
from app.models.multiplayer_hub import ServerMultiplayerRoom from app.models.multiplayer_hub import ServerMultiplayerRoom
from app.models.room import ( from app.models.room import (
MatchType, MatchType,
@@ -24,7 +25,7 @@ from sqlmodel import (
) )
class RoomBase(SQLModel): class RoomBase(SQLModel, UTCBaseModel):
name: str = Field(index=True) name: str = Field(index=True)
category: RoomCategory = Field(default=RoomCategory.NORMAL, index=True) category: RoomCategory = Field(default=RoomCategory.NORMAL, index=True)
duration: int | None = Field(default=None) # minutes duration: int | None = Field(default=None) # minutes

View File

@@ -15,11 +15,6 @@ from app.dependencies.database import get_db, get_redis
from app.dependencies.fetcher import get_fetcher 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.fetcher import Fetcher
from app.models.multiplayer_hub import (
MultiplayerRoom,
MultiplayerRoomUser,
ServerMultiplayerRoom,
)
from app.models.room import RoomStatus from app.models.room import RoomStatus
from app.signalr.hub import MultiplayerHubs from app.signalr.hub import MultiplayerHubs
@@ -44,14 +39,11 @@ async def get_all_rooms(
redis: Redis = Depends(get_redis), redis: Redis = Depends(get_redis),
current_user: User = Depends(get_current_user), current_user: User = Depends(get_current_user),
): ):
rooms = MultiplayerHubs.rooms.values()
resp_list: list[RoomResp] = [] resp_list: list[RoomResp] = []
for room in rooms: db_rooms = (await db.exec(select(Room).where(True))).unique().all()
# if category == "realtime" and room.category != "normal": for room in db_rooms:
# continue if room.ended_at is not None and room.ended_at > datetime.now(UTC):
# elif category != room.category and category != "": resp_list.append(await RoomResp.from_db(room))
# continue
resp_list.append(await RoomResp.from_hub(room))
return resp_list return resp_list
@@ -85,6 +77,10 @@ async def create_room(
user_id = current_user.id user_id = current_user.id
db_room = room.to_room() db_room = room.to_room()
db_room.host_id = current_user.id if current_user.id else 1 db_room.host_id = current_user.id if current_user.id else 1
db_room.starts_at = datetime.now(UTC)
# db_room.ended_at = db_room.starts_at + timedelta(
# minutes=db_room.duration if db_room.duration is not None else 0
# )
db.add(db_room) db.add(db_room)
await db.commit() await db.commit()
await db.refresh(db_room) await db.refresh(db_room)
@@ -102,13 +98,7 @@ async def create_room(
playlist.append(item) playlist.append(item)
await db.refresh(db_room) await db.refresh(db_room)
db_room.playlist = playlist db_room.playlist = playlist
server_room = ServerMultiplayerRoom( await db.refresh(db_room)
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(await RoomResp.from_db(db_room)) created_room = APICreatedRoom.model_validate(await RoomResp.from_db(db_room))
created_room.error = "" created_room.error = ""
return created_room return created_room
@@ -117,10 +107,15 @@ async def create_room(
@router.get("/rooms/{room}", tags=["room"], response_model=RoomResp) @router.get("/rooms/{room}", tags=["room"], response_model=RoomResp)
async def get_room( async def get_room(
room: int, room: int,
category: str = Query(default=""),
db: AsyncSession = Depends(get_db), db: AsyncSession = Depends(get_db),
redis: Redis = Depends(get_redis),
): ):
server_room = MultiplayerHubs.rooms[room] # 直接从db获取信息毕竟都一样
return await RoomResp.from_hub(server_room) db_room = (await db.exec(select(Room).where(Room.id == room))).first()
if db_room is None:
raise HTTPException(404, "Room not found")
return await RoomResp.from_db(db_room)
@router.delete("/rooms/{room}", tags=["room"]) @router.delete("/rooms/{room}", tags=["room"])
@@ -135,13 +130,11 @@ async def delete_room(room: int, db: AsyncSession = Depends(get_db)):
@router.put("/rooms/{room}/users/{user}", tags=["room"]) @router.put("/rooms/{room}/users/{user}", tags=["room"])
async def add_user_to_room(room: int, user: int, db: AsyncSession = Depends(get_db)): async def add_user_to_room(room: int, user: int, db: AsyncSession = Depends(get_db)):
server_room = MultiplayerHubs.rooms[room]
server_room.room.users.append(MultiplayerRoomUser(user_id=user))
db_room = (await db.exec(select(Room).where(Room.id == room))).first() db_room = (await db.exec(select(Room).where(Room.id == room))).first()
if db_room is not None: if db_room is not None:
db_room.participant_count += 1 db_room.participant_count += 1
await db.commit() await db.commit()
resp = await RoomResp.from_hub(server_room) resp = await RoomResp.from_db(db_room)
await db.refresh(db_room) await db.refresh(db_room)
for item in db_room.playlist: for item in db_room.playlist:
resp.playlist.append(await PlaylistResp.from_db(item, ["beatmap"])) resp.playlist.append(await PlaylistResp.from_db(item, ["beatmap"]))
@@ -161,8 +154,8 @@ async def get_room_leaderboard(
db: AsyncSession = Depends(get_db), db: AsyncSession = Depends(get_db),
current_user: User = Depends(get_current_user), current_user: User = Depends(get_current_user),
): ):
server_room = MultiplayerHubs.rooms[room] db_room = (await db.exec(select(Room).where(Room.id == room))).first()
if not server_room: if db_room is None:
raise HTTPException(404, "Room not found") raise HTTPException(404, "Room not found")
aggs = await db.exec( aggs = await db.exec(