From 658c1a4d17669f3fb779ff4f9ec4bce3790c8acb Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Sat, 16 Aug 2025 16:48:09 +0000 Subject: [PATCH] fix(score): fix cannot calculate pp when mod setting is enum --- app/calculator.py | 9 ++++++--- app/models/mods.py | 21 +++++++++++++++++++++ app/router/v2/score.py | 3 ++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/calculator.py b/app/calculator.py index e06b8cb..2c3c699 100644 --- a/app/calculator.py +++ b/app/calculator.py @@ -1,5 +1,6 @@ from __future__ import annotations +from copy import deepcopy from enum import Enum import math from typing import TYPE_CHECKING @@ -7,7 +8,7 @@ from typing import TYPE_CHECKING from app.config import settings from app.log import logger from app.models.beatmap import BeatmapAttributes -from app.models.mods import APIMod +from app.models.mods import APIMod, parse_enum_to_str from app.models.score import GameMode from osupyparser import HitObject, OsuFile @@ -81,9 +82,11 @@ async def calculate_pp(score: "Score", beatmap: str, session: AsyncSession) -> f return 0 map = rosu.Beatmap(content=beatmap) - map.convert(score.gamemode.to_rosu(), score.mods) # pyright: ignore[reportArgumentType] + mods = deepcopy(score.mods.copy()) + parse_enum_to_str(int(score.gamemode), mods) + map.convert(score.gamemode.to_rosu(), mods) # pyright: ignore[reportArgumentType] perf = rosu.Performance( - mods=score.mods, + mods=mods, lazer=True, accuracy=clamp(score.accuracy * 100, 0, 100), combo=score.max_combo, diff --git a/app/models/mods.py b/app/models/mods.py index e92ab89..5be2b2c 100644 --- a/app/models/mods.py +++ b/app/models/mods.py @@ -180,3 +180,24 @@ def mods_can_get_pp(ruleset_id: int, mods: list[APIMod]) -> bool: if expected_value != NO_CHECK and value != expected_value: return False return True + + +ENUM_TO_STR = { + 0: { + "MR": {"reflection"}, + "AC": {"accuracy_judge_mode"}, + "BR": {"direction"}, + "AD": {"style"}, + }, + 1: {"AC": {"accuracy_judge_mode"}}, + 2: {"AC": {"accuracy_judge_mode"}}, + 3: {"AC": {"accuracy_judge_mode"}}, +} + + +def parse_enum_to_str(ruleset_id: int, mods: list[APIMod]): + for mod in mods: + if mod["acronym"] in ENUM_TO_STR.get(ruleset_id, {}): + for setting in mod.get("settings", {}): + if setting in ENUM_TO_STR[ruleset_id][mod["acronym"]]: + mod["settings"][setting] = str(mod["settings"][setting]) # pyright: ignore[reportTypedDictNotRequiredAccess] diff --git a/app/router/v2/score.py b/app/router/v2/score.py index b9a45aa..9c2ffe0 100644 --- a/app/router/v2/score.py +++ b/app/router/v2/score.py @@ -49,7 +49,7 @@ from app.storage.local import LocalStorageService from .router import router -from fastapi import Body, Depends, Form, HTTPException, Path, Query, Security +from fastapi import Body, Depends, Form, HTTPException, Path, Query, Request, Security from fastapi.responses import FileResponse, RedirectResponse from httpx import HTTPError from pydantic import BaseModel @@ -316,6 +316,7 @@ async def create_solo_score( description="**客户端专属**\n使用令牌提交单曲成绩。", ) async def submit_solo_score( + req: Request, beatmap_id: int = Path(description="谱面 ID"), token: int = Path(description="成绩令牌 ID"), info: SoloScoreSubmissionInfo = Body(description="成绩提交信息"),