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:
咕谷酱
2025-08-24 05:01:10 +08:00
committed by MingxuanGame
parent fabc1e9e88
commit 56d6911589
2 changed files with 58 additions and 12 deletions

View 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
)

View File

@@ -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