From a4a7bb265d889bb71e7fb07badc3ac7e67d3d613 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 12 Jun 2026 17:35:26 -0400 Subject: [PATCH] Fix Hardcore leaderboard death overlay --- backend/app.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/backend/app.py b/backend/app.py index af97321..b857724 100644 --- a/backend/app.py +++ b/backend/app.py @@ -1727,6 +1727,7 @@ def _hc_merge_character_rows(rows): merged["total_enemies_killed"] = total_kills merged["alive"] = alive merged["dead_at"] = dead_at + _hc_apply_canonical_death_overlay(merged) merged["last_seen_at"] = last_seen_at or None merged["updated_at"] = updated_at or None @@ -1734,6 +1735,79 @@ def _hc_merge_character_rows(rows): return combined + +def _hc_death_overlay_int(value): + try: + if value is None or value == "": + return None + return int(value) + except Exception: + return None + + +def _hc_canonical_accounts_root(): + import os + from pathlib import Path + + return Path(os.environ.get( + "PSOPEEPS_HC_CANONICAL_ACCOUNTS_ROOT", + "/home/rbatty/.local/share/psopeeps_account_sync/canonical/accounts", + )) + + +def _hc_canonical_slot_is_dead(guild_card, character_slot): + import json + + account_id = _hc_death_overlay_int(guild_card) + slot = _hc_death_overlay_int(character_slot) + if account_id is None or slot is None: + return False + + players_dir = _hc_canonical_accounts_root() / f"{account_id:010d}" / "system" / "players" + if not players_dir.exists(): + return False + + if any(players_dir.glob(f"player_*_{slot}.psochar.hardcore-dead")): + return True + + deaths_log = players_dir / "hardcore-deaths.jsonl" + if not deaths_log.exists(): + return False + + suffix = f"_{slot}.psochar" + try: + lines = deaths_log.read_text(errors="replace").splitlines() + except Exception: + return False + + for line in lines: + line = line.strip() + if not line: + continue + try: + entry = json.loads(line) + except Exception: + continue + + if _hc_death_overlay_int(entry.get("account_id")) != account_id: + continue + + if str(entry.get("character_file") or "").endswith(suffix): + return True + + return False + + +def _hc_apply_canonical_death_overlay(row): + if _hc_canonical_slot_is_dead( + row.get("guild_card") or row.get("account_id"), + row.get("character_slot"), + ): + row["alive"] = False + row.setdefault("dead_at", "canonical-hardcore-dead") + return row + + def _hc_combined_payload(): source_rows, errors = _hc_get_source_characters() combined = _hc_merge_character_rows(source_rows)