refactor(multiplayer): 简化数据模型,只使用跟lazer源码中类似的Room模型
This commit is contained in:
@@ -1,124 +1,101 @@
|
|||||||
# mp 房间相关模型
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
from app.database.user import User
|
||||||
from app.models.mods import APIMod
|
from app.models.mods import APIMod
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from sqlmodel import Double
|
|
||||||
|
|
||||||
# 数据结构定义来自osu/osu.Game/Online/Multiplayer*.cs
|
|
||||||
|
|
||||||
|
|
||||||
class MultiplayerRoomState(int, Enum):
|
class RoomCategory(str, Enum):
|
||||||
Open = 0
|
NORMAL = "normal"
|
||||||
WaitingForLoad = 1
|
SPOTLIGHT = "spotlight"
|
||||||
Playing = 2
|
FEATURED_ARTIST = "featured_artist"
|
||||||
Closed = 3
|
DAILY_CHALLENGE = "daily_challenge"
|
||||||
|
|
||||||
|
|
||||||
class MatchType(int, Enum):
|
class MatchType(str, Enum):
|
||||||
Playlists = 0
|
PLAYLISTS = "playlists"
|
||||||
HeadToHead = 1
|
HEAD_TO_HEAD = "head_to_head"
|
||||||
TeamVersus = 2
|
TEAM_VERSUS = "team_versus"
|
||||||
|
|
||||||
|
|
||||||
class QueueMode(int, Enum):
|
class QueueMode(str, Enum):
|
||||||
HostOnly = 0
|
HOST_ONLY = "host_only"
|
||||||
Allplayers = 1
|
ALL_PLAYERS = "all_players"
|
||||||
AllplayersRoundRobin = 2
|
ALL_PLAYERS_ROUND_ROBIN = "all_players_round_robin"
|
||||||
|
|
||||||
|
|
||||||
class MultiPlayerRoomSettings(BaseModel):
|
class RoomAvailability(str, Enum):
|
||||||
name: str = "Unnamed room" # 来自osu/osu.Game/Online/MultiplayerRoomSettings.cs:15
|
PUBLIC = "public"
|
||||||
playlist_item_id: int
|
FRIENDS_ONLY = "friends_only"
|
||||||
password: str
|
INVITE_ONLY = "invite_only"
|
||||||
match_type: MatchType
|
|
||||||
queue_mode: QueueMode
|
|
||||||
auto_start_duration: timedelta
|
|
||||||
auto_skip: bool
|
|
||||||
|
|
||||||
|
|
||||||
class MultiPlayerUserState(int, Enum):
|
class RoomStatus(str, Enum):
|
||||||
Idle = 0
|
IDLE = "idle"
|
||||||
Ready = 1
|
PLAYING = "playing"
|
||||||
WaitingForLoad = 2
|
|
||||||
Loaded = 3
|
|
||||||
ReadyForGameplay = 4
|
|
||||||
Playing = 5
|
|
||||||
FinishedPlay = 6
|
|
||||||
Results = 7
|
|
||||||
Spectating = 8
|
|
||||||
|
|
||||||
|
|
||||||
class DownloadeState(int, Enum):
|
class PlaylistItem(BaseModel):
|
||||||
Unkown = 0
|
id: int | None
|
||||||
NotDownloaded = 1
|
|
||||||
Downloading = 2
|
|
||||||
Importing = 3
|
|
||||||
LocallyAvailable = 4
|
|
||||||
|
|
||||||
|
|
||||||
class BeatmapAvailability(BaseModel):
|
|
||||||
state: DownloadeState
|
|
||||||
download_progress: float
|
|
||||||
|
|
||||||
|
|
||||||
class MatchUserState(BaseModel):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MatchRoomState(BaseModel):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class MultiPlayerRoomUser(BaseModel):
|
|
||||||
user_id: int
|
|
||||||
state: MultiPlayerUserState = MultiPlayerUserState.Idle
|
|
||||||
mods: APIMod = APIMod(acronym="", settings={})
|
|
||||||
match_state: MatchUserState | None
|
|
||||||
rule_set_id: int | None # 非空则用户本地有自定义模式
|
|
||||||
beatmap_id: int | None # 非空则用户本地自定义谱面
|
|
||||||
|
|
||||||
|
|
||||||
class MultiplayerPlaylistItem(BaseModel):
|
|
||||||
id: int
|
|
||||||
owner_id: int
|
owner_id: int
|
||||||
beatmap_id: int
|
|
||||||
beatmap_checksum: str = ""
|
|
||||||
ruleset_id: int
|
ruleset_id: int
|
||||||
requierd_mods: list[APIMod] = []
|
expired: bool
|
||||||
allowed_mods: list[APIMod] = []
|
playlist_order: int | None
|
||||||
play_list_order: int
|
|
||||||
played_at: datetime | None
|
played_at: datetime | None
|
||||||
star_rating: Double
|
allowed_mods: list[APIMod] = []
|
||||||
free_style: bool
|
required_mods: list[APIMod] = []
|
||||||
OwnerID: int
|
beatmap_id: int
|
||||||
BeatmapID: int
|
freestyle: bool
|
||||||
BeatmapChecksum: str = ""
|
|
||||||
RulesetID: int
|
|
||||||
RequierdMods: list[APIMod] = []
|
|
||||||
AllowedMods: list[APIMod] = []
|
|
||||||
PlayListOrder: int
|
|
||||||
PlayedAt: datetime | None
|
|
||||||
StarRating: Double
|
|
||||||
FreeStyle: bool
|
|
||||||
|
|
||||||
|
|
||||||
class MultiplayerCountdown(BaseModel):
|
class RoomPlaylistItemStats(BaseModel):
|
||||||
|
count_active: int
|
||||||
|
count_total: int
|
||||||
|
ruleset_ids: list[int] = []
|
||||||
|
|
||||||
|
|
||||||
|
class RoomDifficultyRange(BaseModel):
|
||||||
|
min: float
|
||||||
|
max: float
|
||||||
|
|
||||||
|
|
||||||
|
class ItemAttemptsCount(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
time_raming: timedelta
|
attempts: int
|
||||||
|
passed: bool
|
||||||
|
|
||||||
|
|
||||||
class MultiplayerRoom(BaseModel):
|
class PlaylistAggregateScore(BaseModel):
|
||||||
room_id: int
|
playlist_item_attempts: list[ItemAttemptsCount]
|
||||||
state: MultiplayerRoomState
|
|
||||||
settings: MultiPlayerRoomSettings
|
|
||||||
users: list[MultiPlayerRoomUser]
|
class Room(BaseModel):
|
||||||
host: MultiPlayerRoomUser | None
|
id: int | None
|
||||||
match_state: MatchUserState
|
name: str = ""
|
||||||
playlist: list[MultiplayerPlaylistItem]
|
password: str | None
|
||||||
active_conutdowns: list[MultiplayerCountdown]
|
has_password: bool = False
|
||||||
channel_id: int
|
host: User | None
|
||||||
|
category: RoomCategory = RoomCategory.NORMAL
|
||||||
|
duration: int | None
|
||||||
|
starts_at: datetime | None
|
||||||
|
ends_at: datetime | None
|
||||||
|
participant_count: int = 0
|
||||||
|
recent_participants: list[User] = []
|
||||||
|
max_attempts: int | None
|
||||||
|
playlist: list[PlaylistItem] = []
|
||||||
|
playlist_item_stats: RoomPlaylistItemStats | None
|
||||||
|
difficulty_range: RoomDifficultyRange | None
|
||||||
|
type: MatchType = MatchType.PLAYLISTS
|
||||||
|
queue_mode: QueueMode = QueueMode.HOST_ONLY
|
||||||
|
auto_skip: bool = False
|
||||||
|
auto_start_duration: int = 0
|
||||||
|
current_user_score: PlaylistAggregateScore | None
|
||||||
|
current_playlist_item: PlaylistItem | None
|
||||||
|
channel_id: int = 0
|
||||||
|
status: RoomStatus = RoomStatus.IDLE
|
||||||
|
# availability 字段在当前序列化中未包含,但可能在某些场景下需要
|
||||||
|
availability: RoomAvailability | None
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from app.database.beatmap import Beatmap
|
|
||||||
from app.database.user import User
|
|
||||||
from app.models.mods import APIMod
|
|
||||||
from app.models.multiplayer import MatchType, QueueMode
|
|
||||||
|
|
||||||
from pydantic import BaseModel
|
|
||||||
|
|
||||||
|
|
||||||
class RoomCategory(int, Enum):
|
|
||||||
Normal = 0
|
|
||||||
Spotlight = 1
|
|
||||||
FeaturedArtist = 2
|
|
||||||
DailyChallenge = 3
|
|
||||||
|
|
||||||
|
|
||||||
class RespPlaylistItem(BaseModel):
|
|
||||||
id: int | None
|
|
||||||
owner_id: int
|
|
||||||
ruleset_id: int
|
|
||||||
expired: bool
|
|
||||||
playlist_order: int | None
|
|
||||||
played_at: datetime | None
|
|
||||||
allowed_mods: list[APIMod] = []
|
|
||||||
required_mods: list[APIMod] = []
|
|
||||||
beatmap_id: int
|
|
||||||
freestyle: bool
|
|
||||||
beatmap: Beatmap | None
|
|
||||||
|
|
||||||
|
|
||||||
class RoomPlaylistItemStats(BaseModel):
|
|
||||||
count_active: int
|
|
||||||
count_total: int
|
|
||||||
ruleset_ids: list[int]
|
|
||||||
|
|
||||||
|
|
||||||
class RoomDifficulityRange(BaseModel):
|
|
||||||
min: float
|
|
||||||
max: float
|
|
||||||
|
|
||||||
|
|
||||||
class ItemAttempsCount(BaseModel):
|
|
||||||
playlist_item_id: int
|
|
||||||
attemps: int
|
|
||||||
passed: bool
|
|
||||||
|
|
||||||
|
|
||||||
class PlaylistAggregateScore(BaseModel):
|
|
||||||
playlist_item_attempts: list[ItemAttempsCount]
|
|
||||||
|
|
||||||
|
|
||||||
class RoomStatus(int, Enum):
|
|
||||||
Idle = 0
|
|
||||||
Playing = 1
|
|
||||||
|
|
||||||
|
|
||||||
class RoomAvilability(int, Enum):
|
|
||||||
Public = 0
|
|
||||||
FriendsOnly = 1
|
|
||||||
InviteOnly = 2
|
|
||||||
|
|
||||||
|
|
||||||
class RoomResp(BaseModel):
|
|
||||||
room_id: int
|
|
||||||
name: str = ""
|
|
||||||
password: str | None
|
|
||||||
has_password: bool
|
|
||||||
host: User | None
|
|
||||||
category: RoomCategory
|
|
||||||
duration: timedelta | None
|
|
||||||
start_date: datetime | None
|
|
||||||
end_date: datetime | None
|
|
||||||
max_participants: int | None
|
|
||||||
participant_count: int
|
|
||||||
recent_participants: list[User] = []
|
|
||||||
type: MatchType
|
|
||||||
max_attemps: int | None
|
|
||||||
playlist: list[RespPlaylistItem]
|
|
||||||
playlist_item_status: RoomPlaylistItemStats
|
|
||||||
difficulity_range: RoomDifficulityRange
|
|
||||||
queue_mode: QueueMode
|
|
||||||
auto_skip: bool
|
|
||||||
auto_start_duration: timedelta
|
|
||||||
user_score: (
|
|
||||||
PlaylistAggregateScore | None
|
|
||||||
) # osu.Game/Online/Rooms/Room.cs:221 原文如此,不知道为什么
|
|
||||||
current_playlist_item: RespPlaylistItem
|
|
||||||
channel_id: int
|
|
||||||
status: RoomStatus
|
|
||||||
availabiliity: RoomAvilability
|
|
||||||
Reference in New Issue
Block a user