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()