From 900fa9b121e0d09d798e9bb85dd73ac9702c0c38 Mon Sep 17 00:00:00 2001 From: MingxuanGame Date: Mon, 25 Aug 2025 13:23:33 +0000 Subject: [PATCH] fix(score): fix incorrect best_id --- app/database/score.py | 20 +++++--------------- app/router/notification/banchobot.py | 2 +- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/app/database/score.py b/app/database/score.py index c331865..273ba1a 100644 --- a/app/database/score.py +++ b/app/database/score.py @@ -48,9 +48,9 @@ from .score_token import ScoreToken from pydantic import field_serializer, field_validator from redis.asyncio import Redis -from sqlalchemy import Boolean, Column, ColumnExpressionArgument, DateTime, TextClause +from sqlalchemy import Boolean, Column, DateTime, TextClause from sqlalchemy.ext.asyncio import AsyncAttrs -from sqlalchemy.orm import Mapped, aliased +from sqlalchemy.orm import Mapped from sqlalchemy.sql.elements import ColumnElement from sqlmodel import ( JSON, @@ -66,7 +66,6 @@ from sqlmodel import ( true, ) from sqlmodel.ext.asyncio.session import AsyncSession -from sqlmodel.sql._expression_select_cls import SelectOfScalar if TYPE_CHECKING: from app.fetcher import Fetcher @@ -194,17 +193,6 @@ class Score(ScoreBase, table=True): def is_perfect_combo(self) -> bool: return self.max_combo == self.beatmap.max_combo - @staticmethod - def select_clause_unique( - *where_clauses: ColumnExpressionArgument[bool] | bool, - ) -> SelectOfScalar["Score"]: - rownum = ( - func.row_number().over(partition_by=col(Score.user_id), order_by=col(Score.total_score).desc()).label("rn") - ) - subq = select(Score, rownum).where(*where_clauses).subquery() - best = aliased(Score, subq, adapt_on_names=True) - return select(best).where(subq.c.rn == 1) - class ScoreResp(ScoreBase): id: int @@ -357,7 +345,9 @@ class ScoreAround(SQLModel): async def get_best_id(session: AsyncSession, score_id: int) -> int | None: rownum = ( - func.row_number().over(partition_by=col(PPBestScore.user_id), order_by=col(PPBestScore.pp).desc()).label("rn") + func.row_number() + .over(partition_by=(col(PPBestScore.user_id), col(PPBestScore.gamemode)), order_by=col(PPBestScore.pp).desc()) + .label("rn") ) subq = select(PPBestScore, rownum).subquery() stmt = select(subq.c.rn).where(subq.c.score_id == score_id) diff --git a/app/router/notification/banchobot.py b/app/router/notification/banchobot.py index 2f32696..5b1a7ed 100644 --- a/app/router/notification/banchobot.py +++ b/app/router/notification/banchobot.py @@ -580,7 +580,7 @@ async def _score( best_id = await get_best_id(session, score.id) bp_pp = "" if best_id: - bp_pp = f"(b{best_id} -> {calculate_weighted_pp(score.pp, best_id):.2f}pp)" + bp_pp = f"(b{best_id} -> {calculate_weighted_pp(score.pp, best_id - 1):.2f}pp)" result = f"""{score.beatmap.beatmapset.title} [{score.beatmap.version}] ({score.gamemode.name.lower()}) Played at {score.started_at}