feat(beatmap,score): update beatmaps from Bancho & deleting scores (#50)

New API:

- DELETE /api/private/score/{score_id}: delete a score
- POST /api/private/beatmapsets/{beatmapset_id}/sync: request for syncing a beatmapset

New configuration:

- OLD_SCORE_PROCESSING_MODE
This commit is contained in:
MingxuanGame
2025-10-02 13:36:09 +08:00
committed by GitHub
parent 860ebe9fa9
commit 3f6776847e
22 changed files with 888 additions and 84 deletions

View File

@@ -1,5 +1,7 @@
from typing import TYPE_CHECKING
from app.calculator import calculate_score_to_level
from app.database.statistics import UserStatistics
from app.models.score import GameMode, Rank
from .lazer_user import User
@@ -12,7 +14,11 @@ from sqlmodel import (
ForeignKey,
Relationship,
SQLModel,
col,
func,
select,
)
from sqlmodel.ext.asyncio.session import AsyncSession
if TYPE_CHECKING:
from .beatmap import Beatmap
@@ -37,6 +43,43 @@ class BestScore(SQLModel, table=True):
sa_relationship_kwargs={
"foreign_keys": "[BestScore.score_id]",
"lazy": "joined",
}
},
back_populates="best_score",
)
beatmap: "Beatmap" = Relationship()
async def delete(self, session: AsyncSession):
from .score import Score
statistics = await session.exec(
select(UserStatistics).where(UserStatistics.user_id == self.user_id, UserStatistics.mode == self.gamemode)
)
statistics = statistics.first()
if statistics:
statistics.total_score -= self.total_score
statistics.ranked_score -= self.total_score
statistics.level_current = calculate_score_to_level(statistics.total_score)
match self.rank:
case Rank.X:
statistics.grade_ss -= 1
case Rank.XH:
statistics.grade_ssh -= 1
case Rank.S:
statistics.grade_s -= 1
case Rank.SH:
statistics.grade_sh -= 1
case Rank.A:
statistics.grade_a -= 1
max_combo = (
await session.exec(
select(func.max(Score.max_combo)).where(
Score.user_id == self.user_id,
col(Score.id).in_(select(BestScore.score_id)),
Score.gamemode == self.gamemode,
)
)
).first()
statistics.maximum_combo = max(0, max_combo or 0)
await session.delete(self)