fix(score): fix cannot calculate pp when mod setting is enum

This commit is contained in:
MingxuanGame
2025-08-16 16:48:09 +00:00
parent 9c7eb2ac87
commit 658c1a4d17
3 changed files with 29 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
from copy import deepcopy
from enum import Enum from enum import Enum
import math import math
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@@ -7,7 +8,7 @@ from typing import TYPE_CHECKING
from app.config import settings from app.config import settings
from app.log import logger from app.log import logger
from app.models.beatmap import BeatmapAttributes 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 app.models.score import GameMode
from osupyparser import HitObject, OsuFile from osupyparser import HitObject, OsuFile
@@ -81,9 +82,11 @@ async def calculate_pp(score: "Score", beatmap: str, session: AsyncSession) -> f
return 0 return 0
map = rosu.Beatmap(content=beatmap) 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( perf = rosu.Performance(
mods=score.mods, mods=mods,
lazer=True, lazer=True,
accuracy=clamp(score.accuracy * 100, 0, 100), accuracy=clamp(score.accuracy * 100, 0, 100),
combo=score.max_combo, combo=score.max_combo,

View File

@@ -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: if expected_value != NO_CHECK and value != expected_value:
return False return False
return True 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]

View File

@@ -49,7 +49,7 @@ from app.storage.local import LocalStorageService
from .router import router 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 fastapi.responses import FileResponse, RedirectResponse
from httpx import HTTPError from httpx import HTTPError
from pydantic import BaseModel from pydantic import BaseModel
@@ -316,6 +316,7 @@ async def create_solo_score(
description="**客户端专属**\n使用令牌提交单曲成绩。", description="**客户端专属**\n使用令牌提交单曲成绩。",
) )
async def submit_solo_score( async def submit_solo_score(
req: Request,
beatmap_id: int = Path(description="谱面 ID"), beatmap_id: int = Path(description="谱面 ID"),
token: int = Path(description="成绩令牌 ID"), token: int = Path(description="成绩令牌 ID"),
info: SoloScoreSubmissionInfo = Body(description="成绩提交信息"), info: SoloScoreSubmissionInfo = Body(description="成绩提交信息"),