diff --git a/handlers/admin/recompute_sm5_scores.py b/handlers/admin/recompute_sm5_scores.py new file mode 100644 index 0000000..4e6c25c --- /dev/null +++ b/handlers/admin/recompute_sm5_scores.py @@ -0,0 +1,44 @@ +from sanic import Request + +from db.sm5 import SM5Game, SM5_LASERRANK_VERSION +from helpers.sm5helper import update_winner +from shared import app +from utils import admin_only + +_BATCH_SIZE = 20 + + +@app.get("/admin/recompute_sm5_scores") +#@admin_only +async def recompute_sm5_scores(request: Request) -> str: + response = await request.respond(content_type="text/html") + + await response.send("

Updating...

\n") + + updated_games_count = 0 + + while True: + # Get all SM5 games. We only need those that aren't already on the latest version. + games = await SM5Game.filter(laserrank_version__not=SM5_LASERRANK_VERSION).limit(_BATCH_SIZE).all() + + # Keep going until there's nothing left to update. + if not games: + break + + update_count = await _update_games(games) + updated_games_count += update_count + await response.send(f"Updated {update_count} games\n
") + + await response.send(f"

All done.

\n{updated_games_count} games updated.\n") + + return "" + + +async def _update_games(games: list[SM5Game]) -> int: + for game in games: + if game.laserrank_version < 2: + await update_winner(game) + game.laserrank_version = SM5_LASERRANK_VERSION + await game.save() + + return len(games) diff --git a/helpers/sm5helper.py b/helpers/sm5helper.py index a794188..177eb93 100644 --- a/helpers/sm5helper.py +++ b/helpers/sm5helper.py @@ -589,6 +589,33 @@ async def get_sm5_rating_over_time(entity_id: str, min_time: datetime = _MIN_DAT min_date=min_date, max_date=max_date, data_points=data_points ) +async def update_winner(game: SM5Game): + """Updates the following fields in the game: + + last_team_standing, winner, winner_color. + + Will not call save() after the update is done. + """ + # Determine whether one team eliminated the other. + game.last_team_standing = await get_sm5_last_team_standing(game) + + # winner determination + winner = game.last_team_standing + + if not winner: + red_score = await game.get_team_score(Team.RED) + green_score = await game.get_team_score(Team.GREEN) + if red_score > green_score: + winner = Team.RED + elif red_score < green_score: + winner = Team.GREEN + else: # tie or no winner or something crazy happened + winner = None + + game.winner = winner + game.winner_color = winner.value if winner else "none" + + async def get_sm5_last_team_standing(game: SM5Game) -> Optional[Team]: """Returns the team that eliminated the other team. @@ -610,32 +637,6 @@ async def get_sm5_last_team_standing(game: SM5Game) -> Optional[Team]: return next(iter(alive_player_count.keys())) -async def compute_sm5_elimination_bonus(game: SM5Game) -> SM5Game: - """Adds 10,000 points to the score of a team if it eliminated the others. - - Will also recompute the winner of the game. - - Will not do anything if the game ended early. - - NOTE that this will update the database with the new values if a change was made! Don't call this twice on the same - game. - """ - # Nop if the game ended early. - if game.ended_early: - return game - - eliminating_team = await get_sm5_last_team_standing(game) - - if not eliminating_team: - # No elimination. Do nothing. - return game - - # Add the bonus. - game.scores - - - - def _create_lives_snapshot(lives_timeline: dict[int, list[int]], current_lives: dict[int, int]): for entity_end_id, lives in current_lives.items(): lives_timeline[entity_end_id].append(lives) diff --git a/helpers/tdfhelper.py b/helpers/tdfhelper.py index a929296..e31192e 100644 --- a/helpers/tdfhelper.py +++ b/helpers/tdfhelper.py @@ -13,7 +13,7 @@ from db.types import EventType, PlayerStateType, Team from helpers import ratinghelper from helpers.ratinghelper import MU, SIGMA -from helpers.sm5helper import get_sm5_last_team_standing +from helpers.sm5helper import update_winner def element_to_color(element: str) -> str: @@ -213,26 +213,8 @@ async def parse_sm5_game(file_location: str) -> SM5Game: await game.save() logger.debug("Inital game save complete") + await update_winner(game) - # Determine whether one team eliminated the other. - game.last_team_standing = await get_sm5_last_team_standing(game) - - # winner determination - - winner = game.last_team_standing - - if not winner: - red_score = await game.get_team_score(Team.RED) - green_score = await game.get_team_score(Team.GREEN) - if red_score > green_score: - winner = Team.RED - elif red_score < green_score: - winner = Team.GREEN - else: # tie or no winner or something crazy happened - winner = None - - game.winner = winner - game.winner_color = winner.value if winner else "none" game.laserrank_version = SM5_LASERRANK_VERSION await game.save()