feat(signalr): support json & msgpack protocol for all hubs

This commit is contained in:
MingxuanGame
2025-08-03 09:45:04 +00:00
parent 0f1a57afba
commit 9f7ab81213
13 changed files with 432 additions and 307 deletions

View File

@@ -5,14 +5,14 @@ from enum import IntEnum
from typing import Any
from app.models.beatmap import BeatmapRankStatus
from app.models.mods import APIMod
from .score import (
ScoreStatisticsInt,
ScoreStatistics,
)
from .signalr import MessagePackArrayModel, UserState
from .signalr import SignalRMeta, UserState
from msgpack_lazer_api import APIMod
from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic import BaseModel, Field, field_validator
class SpectatedUserState(IntEnum):
@@ -24,14 +24,12 @@ class SpectatedUserState(IntEnum):
Quit = 5
class SpectatorState(MessagePackArrayModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
class SpectatorState(BaseModel):
beatmap_id: int | None = None
ruleset_id: int | None = None # 0,1,2,3
mods: list[APIMod] = Field(default_factory=list)
state: SpectatedUserState
maximum_statistics: ScoreStatisticsInt = Field(default_factory=dict)
maximum_statistics: ScoreStatistics = Field(default_factory=dict)
def __eq__(self, other: object) -> bool:
if not isinstance(other, SpectatorState):
@@ -44,22 +42,20 @@ class SpectatorState(MessagePackArrayModel):
)
class ScoreProcessorStatistics(MessagePackArrayModel):
base_score: int
maximum_base_score: int
class ScoreProcessorStatistics(BaseModel):
base_score: float
maximum_base_score: float
accuracy_judgement_count: int
combo_portion: float
bouns_portion: float
bonus_portion: float
class FrameHeader(MessagePackArrayModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
class FrameHeader(BaseModel):
total_score: int
acc: float
accuracy: float
combo: int
max_combo: int
statistics: ScoreStatisticsInt = Field(default_factory=dict)
statistics: ScoreStatistics = Field(default_factory=dict)
score_processor_statistics: ScoreProcessorStatistics
received_time: datetime.datetime
mods: list[APIMod] = Field(default_factory=list)
@@ -87,14 +83,18 @@ class FrameHeader(MessagePackArrayModel):
# SMOKE = 16
class LegacyReplayFrame(MessagePackArrayModel):
class LegacyReplayFrame(BaseModel):
time: float # from ReplayFrame,the parent of LegacyReplayFrame
x: float | None = None
y: float | None = None
mouse_x: float | None = None
mouse_y: float | None = None
button_state: int
header: FrameHeader | None = Field(
default=None, metadata=[SignalRMeta(member_ignore=True)]
)
class FrameDataBundle(MessagePackArrayModel):
class FrameDataBundle(BaseModel):
header: FrameHeader
frames: list[LegacyReplayFrame]
@@ -106,18 +106,16 @@ class APIUser(BaseModel):
class ScoreInfo(BaseModel):
model_config = ConfigDict(arbitrary_types_allowed=True)
mods: list[APIMod]
user: APIUser
ruleset: int
maximum_statistics: ScoreStatisticsInt
maximum_statistics: ScoreStatistics
id: int | None = None
total_score: int | None = None
acc: float | None = None
accuracy: float | None = None
max_combo: int | None = None
combo: int | None = None
statistics: ScoreStatisticsInt = Field(default_factory=dict)
statistics: ScoreStatistics = Field(default_factory=dict)
class StoreScore(BaseModel):