Add multiplayer room event model and channel ID allocation
Introduces the MultiplayerRealtimeRoomEvent SQLModel for tracking real-time room events. Adds an async helper to allocate unique channel IDs for rooms, and updates room creation logic to use this helper for assigning channel IDs automatically.
This commit is contained in:
39
app/database/multiplayer_realtime_room_event.py
Normal file
39
app/database/multiplayer_realtime_room_event.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional, ClassVar
|
||||
|
||||
from sqlalchemy import Text
|
||||
from sqlalchemy.ext.asyncio import AsyncAttrs
|
||||
from sqlmodel import SQLModel, Field, Column, DateTime, BigInteger, ForeignKey
|
||||
|
||||
from app.models.model import UTCBaseModel
|
||||
from app.utils import utcnow
|
||||
|
||||
|
||||
class MultiplayerRealtimeRoomEventBase(SQLModel, UTCBaseModel):
|
||||
event_type: str = Field(index=True)
|
||||
event_detail: Optional[str] = Field(default=None, sa_column=Column(Text))
|
||||
|
||||
|
||||
class MultiplayerRealtimeRoomEvent(AsyncAttrs, MultiplayerRealtimeRoomEventBase, table=True):
|
||||
__tablename__: ClassVar[str] = "multiplayer_realtime_room_event"
|
||||
|
||||
id: int | None = Field(default=None, primary_key=True, index=True)
|
||||
|
||||
room_id: int = Field(
|
||||
sa_column=Column(ForeignKey("rooms.id"), index=True, nullable=False)
|
||||
)
|
||||
playlist_item_id: int | None = Field(
|
||||
default=None,
|
||||
sa_column=Column(ForeignKey("playlists.id"), index=True, nullable=True),
|
||||
)
|
||||
user_id: int | None = Field(
|
||||
default=None,
|
||||
sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True, nullable=True),
|
||||
)
|
||||
|
||||
created_at: datetime = Field(
|
||||
sa_column=Column(DateTime(timezone=True)), default_factory=utcnow
|
||||
)
|
||||
updated_at: datetime = Field(
|
||||
sa_column=Column(DateTime(timezone=True)), default_factory=utcnow
|
||||
)
|
||||
@@ -7,7 +7,7 @@ from typing import Any, Dict, List
|
||||
from fastapi import APIRouter, HTTPException, Request, status, Query, Depends
|
||||
from pydantic import BaseModel
|
||||
from sqlmodel import col, select, desc
|
||||
from sqlalchemy import update
|
||||
from sqlalchemy import update, func
|
||||
from redis.asyncio import Redis
|
||||
|
||||
from app.database.lazer_user import User
|
||||
@@ -24,6 +24,15 @@ from app.utils import utcnow
|
||||
router = APIRouter(prefix="/_lio", tags=["LIO"])
|
||||
|
||||
|
||||
|
||||
async def _alloc_channel_id(db: Database) -> int:
|
||||
"""
|
||||
自动分配一个 >100 的 channel_id。
|
||||
策略:取当前 rooms.channel_id 的最大值(没有时从100开始)+1。
|
||||
"""
|
||||
result = await db.execute(select(func.max(Room.channel_id)))
|
||||
current_max = result.scalar() or 100
|
||||
return int(current_max) + 1
|
||||
class RoomCreateRequest(BaseModel):
|
||||
"""Request model for creating a multiplayer room."""
|
||||
name: str
|
||||
@@ -140,7 +149,6 @@ def _validate_playlist_items(items: List[Dict[str, Any]]) -> None:
|
||||
|
||||
|
||||
async def _create_room(db: Database, room_data: Dict[str, Any]) -> tuple[Room, int]:
|
||||
"""Create a new multiplayer room."""
|
||||
host_user_id = room_data.get("user_id")
|
||||
room_name = room_data.get("name", "Unnamed Room")
|
||||
password = room_data.get("password")
|
||||
@@ -148,18 +156,16 @@ async def _create_room(db: Database, room_data: Dict[str, Any]) -> tuple[Room, i
|
||||
queue_mode = room_data.get("queue_mode", "HostOnly")
|
||||
|
||||
if not host_user_id or not isinstance(host_user_id, int):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Missing or invalid user_id"
|
||||
)
|
||||
raise HTTPException(status_code=400, detail="Missing or invalid user_id")
|
||||
|
||||
# Validate host user exists
|
||||
await _validate_user_exists(db, host_user_id)
|
||||
|
||||
# Parse room type enums
|
||||
|
||||
match_type_enum, queue_mode_enum = _parse_room_enums(match_type, queue_mode)
|
||||
|
||||
# Create room
|
||||
# 自动分配一个 channel_id (>100)
|
||||
channel_id = await _alloc_channel_id(db)
|
||||
|
||||
# 创建房间
|
||||
room = Room(
|
||||
name=room_name,
|
||||
host_id=host_user_id,
|
||||
@@ -170,12 +176,13 @@ async def _create_room(db: Database, room_data: Dict[str, Any]) -> tuple[Room, i
|
||||
participant_count=1,
|
||||
auto_skip=False,
|
||||
auto_start_duration=0,
|
||||
channel_id=channel_id,
|
||||
)
|
||||
|
||||
|
||||
db.add(room)
|
||||
await db.commit()
|
||||
await db.refresh(room)
|
||||
|
||||
|
||||
return room, host_user_id
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user