feat(score): support osu-rx & osu-ap & all beatmap leaderboard like osu.ppy.sb
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from app.config import settings
|
||||
from app.models.beatmap import BeatmapRankStatus
|
||||
from app.models.score import MODE_TO_INT, GameMode
|
||||
|
||||
@@ -62,10 +63,6 @@ class Beatmap(BeatmapBase, table=True):
|
||||
back_populates="beatmaps", sa_relationship_kwargs={"lazy": "joined"}
|
||||
)
|
||||
|
||||
@property
|
||||
def can_ranked(self) -> bool:
|
||||
return self.beatmap_status > BeatmapRankStatus.PENDING
|
||||
|
||||
@classmethod
|
||||
async def from_resp(cls, session: AsyncSession, resp: "BeatmapResp") -> "Beatmap":
|
||||
d = resp.model_dump()
|
||||
@@ -160,12 +157,20 @@ class BeatmapResp(BeatmapBase):
|
||||
) -> "BeatmapResp":
|
||||
from .score import Score
|
||||
|
||||
beatmap_status = beatmap.beatmap_status
|
||||
beatmap_ = beatmap.model_dump()
|
||||
if query_mode is not None and beatmap.mode != query_mode:
|
||||
beatmap_["convert"] = True
|
||||
beatmap_["is_scoreable"] = beatmap.beatmap_status > BeatmapRankStatus.PENDING
|
||||
beatmap_["status"] = beatmap.beatmap_status.name.lower()
|
||||
beatmap_["ranked"] = beatmap.beatmap_status.value
|
||||
beatmap_["is_scoreable"] = beatmap_status.has_leaderboard()
|
||||
if (
|
||||
settings.enable_all_beatmap_leaderboard
|
||||
and not beatmap_status.has_leaderboard()
|
||||
):
|
||||
beatmap_["ranked"] = BeatmapRankStatus.APPROVED.value
|
||||
beatmap_["status"] = BeatmapRankStatus.APPROVED.name.lower()
|
||||
else:
|
||||
beatmap_["status"] = beatmap_status.name.lower()
|
||||
beatmap_["ranked"] = beatmap_status.value
|
||||
beatmap_["mode_int"] = MODE_TO_INT[beatmap.mode]
|
||||
if not from_set:
|
||||
beatmap_["beatmapset"] = await BeatmapsetResp.from_db(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, NotRequired, TypedDict
|
||||
|
||||
from app.config import settings
|
||||
from app.models.beatmap import BeatmapRankStatus, Genre, Language
|
||||
from app.models.score import GameMode
|
||||
|
||||
@@ -228,11 +229,21 @@ class BeatmapsetResp(BeatmapsetBase):
|
||||
required=beatmapset.nominations_required,
|
||||
current=beatmapset.nominations_current,
|
||||
),
|
||||
"status": beatmapset.beatmap_status.name.lower(),
|
||||
"ranked": beatmapset.beatmap_status.value,
|
||||
"is_scoreable": beatmapset.beatmap_status > BeatmapRankStatus.PENDING,
|
||||
"is_scoreable": beatmapset.beatmap_status.has_leaderboard(),
|
||||
**beatmapset.model_dump(),
|
||||
}
|
||||
|
||||
beatmap_status = beatmapset.beatmap_status
|
||||
if (
|
||||
settings.enable_all_beatmap_leaderboard
|
||||
and not beatmap_status.has_leaderboard()
|
||||
):
|
||||
update["status"] = BeatmapRankStatus.APPROVED.name.lower()
|
||||
update["ranked"] = BeatmapRankStatus.APPROVED.value
|
||||
else:
|
||||
update["status"] = beatmap_status.name.lower()
|
||||
update["ranked"] = beatmap_status.value
|
||||
|
||||
if session and user:
|
||||
existing_favourite = (
|
||||
await session.exec(
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.calculator import (
|
||||
calculate_weighted_pp,
|
||||
clamp,
|
||||
)
|
||||
from app.config import settings
|
||||
from app.database.team import TeamMember
|
||||
from app.models.model import RespWithCursor, UTCBaseModel
|
||||
from app.models.mods import APIMod, mods_can_get_pp
|
||||
@@ -324,6 +325,13 @@ async def get_leaderboard(
|
||||
user: User | None = None,
|
||||
limit: int = 50,
|
||||
) -> tuple[list[Score], Score | None]:
|
||||
is_rx = "RX" in (mods or [])
|
||||
is_ap = "AP" in (mods or [])
|
||||
if settings.enable_osu_rx and is_rx:
|
||||
mode = GameMode.OSURX
|
||||
elif settings.enable_osu_ap and is_ap:
|
||||
mode = GameMode.OSUAP
|
||||
|
||||
wheres = await _score_where(type, beatmap, mode, mods, user)
|
||||
if wheres is None:
|
||||
return [], None
|
||||
@@ -637,6 +645,14 @@ async def process_score(
|
||||
) -> Score:
|
||||
assert user.id
|
||||
can_get_pp = info.passed and ranked and mods_can_get_pp(info.ruleset_id, info.mods)
|
||||
acronyms = [mod["acronym"] for mod in info.mods]
|
||||
is_rx = "RX" in acronyms
|
||||
is_ap = "AP" in acronyms
|
||||
gamemode = INT_TO_MODE[info.ruleset_id]
|
||||
if settings.enable_osu_rx and is_rx and gamemode == GameMode.OSU:
|
||||
gamemode = GameMode.OSURX
|
||||
elif settings.enable_osu_ap and is_ap and gamemode == GameMode.OSU:
|
||||
gamemode = GameMode.OSUAP
|
||||
score = Score(
|
||||
accuracy=info.accuracy,
|
||||
max_combo=info.max_combo,
|
||||
@@ -648,7 +664,7 @@ async def process_score(
|
||||
total_score_without_mods=info.total_score_without_mods,
|
||||
beatmap_id=beatmap_id,
|
||||
ended_at=datetime.now(UTC),
|
||||
gamemode=INT_TO_MODE[info.ruleset_id],
|
||||
gamemode=gamemode,
|
||||
started_at=score_token.created_at,
|
||||
user_id=user.id,
|
||||
preserve=info.passed,
|
||||
|
||||
Reference in New Issue
Block a user