From 606e174a9782d161e332713dc15ab77c6822806f Mon Sep 17 00:00:00 2001 From: deploy Date: Fri, 29 May 2026 17:04:40 +0000 Subject: [PATCH] fix: resolve each team independently to prevent squadron_long order inversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When one team has a dash-tag (e.g. -DSPLA-) and the opponent has a normal tag (e.g. ALUN2), batching both into resolve_clans caused the short-name pass to place the normal team first in results and the tag pass to append the dash-tagged team second — inverting the mapping vs. the teams array. Each team's players were then looked up against the wrong squadron's API, yielding curr=0 for everyone and diffs=0 on the scoreboard. Fix: resolve each team concurrently and independently so results are always index-aligned with the teams list regardless of which resolution path fires. Also propagates squadron_short to the scoreboard renderer so display names are clean (DSPLA not -DSPLA-). Co-Authored-By: Claude Sonnet 4.6 --- BOT/autologging.py | 26 +++++++++++++++++++------- BOT/scoreboard.py | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/BOT/autologging.py b/BOT/autologging.py index 9313de8..f8e0bfb 100644 --- a/BOT/autologging.py +++ b/BOT/autologging.py @@ -1633,13 +1633,25 @@ async def build_scoreboard_context( """ teams: List[Dict[str, Any]] = list((replay_data.get("teams") or [])[:2]) - squads: List[str] = [str(team["squadron"]) for team in teams if team.get("squadron")] - squads_tagged: List[str] = [str(team["squadron_tagged"]) for team in teams if team.get("squadron_tagged")] - resolved = await resolve_clans(shorts=squads, tags=squads_tagged) - long_clans = [c["long_name"] for c in resolved] - for team, long_name in zip(teams, long_clans): - if team and long_name: - team["squadron_long"] = long_name + # Resolve each team independently and concurrently so the result is always + # index-aligned with the teams list. Batching both teams into one + # resolve_clans call can invert the order when one team resolves via the + # short-name pass and the other falls through to the tag pass. + async def _resolve_team(team: dict) -> Optional[dict]: + sq = str(team.get("squadron") or "") + tag = str(team.get("squadron_tagged") or "") + if not sq and not tag: + return None + results = await resolve_clans(shorts=[sq] if sq else [], tags=[tag] if tag else []) + return results[0] if results else None + + resolved_teams = await asyncio.gather(*[_resolve_team(t) for t in teams]) + for team, result in zip(teams, resolved_teams): + if team and result: + if result.get("long_name") and result["long_name"] != "": + team["squadron_long"] = result["long_name"] + if result.get("short_name"): + team["squadron_short"] = result["short_name"] home_tag: Optional[str] = (teams[0] or {}).get("squadron") if len(teams) > 0 else None away_tag: Optional[str] = (teams[1] or {}).get("squadron") if len(teams) > 1 else None diff --git a/BOT/scoreboard.py b/BOT/scoreboard.py index 226e5fa..38c5527 100644 --- a/BOT/scoreboard.py +++ b/BOT/scoreboard.py @@ -458,7 +458,7 @@ def _create_scoreboard_sync(match_details, # --- 1) Squadron header & points --- - squadron_short = team_data.get("squadron", "Unknown") + squadron_short = team_data.get("squadron_short") or team_data.get("squadron", "Unknown") squadron_long = team_data.get("squadron_long", "Unknown") matched_diff_source = None squad_diffs = None