feat(multiplayer): support multiplayer events

This commit is contained in:
MingxuanGame
2025-08-07 16:18:54 +00:00
parent bc2961de10
commit 7a2c8c1fb4
8 changed files with 341 additions and 9 deletions

View File

@@ -15,6 +15,7 @@ from .lazer_user import (
User,
UserResp,
)
from .multiplayer_event import MultiplayerEvent, MultiplayerEventResp
from .playlist_attempts import ItemAttemptsCount, ItemAttemptsResp
from .playlist_best_score import PlaylistBestScore
from .playlists import Playlist, PlaylistResp
@@ -51,6 +52,8 @@ __all__ = [
"FavouriteBeatmapset",
"ItemAttemptsCount",
"ItemAttemptsResp",
"MultiplayerEvent",
"MultiplayerEventResp",
"MultiplayerScores",
"OAuthToken",
"PPBestScore",

View File

@@ -0,0 +1,53 @@
from datetime import UTC, datetime
from typing import Any
from app.models.model import UTCBaseModel
from sqlmodel import (
JSON,
BigInteger,
Column,
DateTime,
Field,
ForeignKey,
SQLModel,
)
class MultiplayerEventBase(SQLModel, UTCBaseModel):
playlist_item_id: int | None = None
user_id: int | None = Field(
default=None,
sa_column=Column(BigInteger, ForeignKey("lazer_users.id"), index=True),
)
created_at: datetime = Field(
sa_column=Column(
DateTime(timezone=True),
),
default=datetime.now(UTC),
)
event_type: str = Field(index=True)
class MultiplayerEvent(MultiplayerEventBase, table=True):
__tablename__ = "multiplayer_events" # pyright: ignore[reportAssignmentType]
id: int | None = Field(default=None, primary_key=True)
room_id: int = Field(foreign_key="rooms.id", index=True)
updated_at: datetime = Field(
sa_column=Column(
DateTime(timezone=True),
),
default=datetime.now(UTC),
)
event_detail: dict[str, Any] | None = Field(
sa_column=Column(JSON),
default_factory=dict,
)
class MultiplayerEventResp(MultiplayerEventBase):
id: int
@classmethod
def from_db(cls, event: MultiplayerEvent) -> "MultiplayerEventResp":
return cls.model_validate(event)

View File

@@ -29,9 +29,7 @@ class ItemAttemptsCountBase(SQLModel):
class ItemAttemptsCount(ItemAttemptsCountBase, table=True):
__tablename__ = "item_attempts_count" # pyright: ignore[reportAssignmentType]
id: int | None = Field(
default=None, foreign_key="room_playlists.db_id", primary_key=True
)
id: int | None = Field(default=None, primary_key=True)
user: User = Relationship()

View File

@@ -133,8 +133,11 @@ class PlaylistResp(PlaylistBase):
beatmap: BeatmapResp | None = None
@classmethod
async def from_db(cls, playlist: Playlist) -> "PlaylistResp":
async def from_db(
cls, playlist: Playlist, include: list[str] = []
) -> "PlaylistResp":
data = playlist.model_dump()
data["beatmap"] = await BeatmapResp.from_db(playlist.beatmap, from_set=True)
if "beatmap" in include:
data["beatmap"] = await BeatmapResp.from_db(playlist.beatmap, from_set=True)
resp = cls.model_validate(data)
return resp

View File

@@ -98,7 +98,7 @@ class RoomResp(RoomBase):
difficulty_range.max = max(
difficulty_range.max, playlist.beatmap.difficulty_rating
)
resp.playlist.append(await PlaylistResp.from_db(playlist))
resp.playlist.append(await PlaylistResp.from_db(playlist, ["beatmap"]))
stats.ruleset_ids = list(rulesets)
resp.playlist_item_stats = stats
resp.difficulty_range = difficulty_range