From e2aaafaca20d7b339158450b2d1864507a67a91c Mon Sep 17 00:00:00 2001 From: devRaGonSa Date: Tue, 19 May 2026 11:58:47 +0200 Subject: [PATCH] feat: capture rcon session gamestate fields --- backend/app/rcon_client.py | 17 +++++++++++++++++ backend/app/rcon_historical_read_model.py | 16 ++++++---------- backend/app/rcon_historical_storage.py | 10 ++++++++-- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/backend/app/rcon_client.py b/backend/app/rcon_client.py index 81a2fa1..809830c 100644 --- a/backend/app/rcon_client.py +++ b/backend/app/rcon_client.py @@ -452,6 +452,23 @@ def query_live_server_sample( "current_map": ( _string_or_none(session.get("mapId")) or _string_or_none(session.get("mapName")) ), + "game_mode": _string_or_none(session.get("gameMode")), + "allied_score": _coerce_optional_int(session.get("alliedScore")), + "axis_score": _coerce_optional_int(session.get("axisScore")), + "winner": _resolve_rcon_winner( + _coerce_optional_int(session.get("alliedScore")), + _coerce_optional_int(session.get("axisScore")), + ), + "allied_faction": _string_or_none(session.get("alliedFaction")), + "axis_faction": _string_or_none(session.get("axisFaction")), + "allied_players": _coerce_optional_int(session.get("alliedPlayerCount")), + "axis_players": _coerce_optional_int(session.get("axisPlayerCount")), + "remaining_match_time_seconds": _coerce_optional_int(session.get("remainingMatchTime")), + "match_time_seconds": _coerce_optional_int(session.get("matchTime")), + "queue_count": _coerce_optional_int(session.get("queueCount")), + "max_queue_count": _coerce_optional_int(session.get("maxQueueCount")), + "vip_queue_count": _coerce_optional_int(session.get("vipQueueCount")), + "max_vip_queue_count": _coerce_optional_int(session.get("maxVipQueueCount")), "region": target.region, "source_name": target.source_name, "snapshot_origin": "real-rcon", diff --git a/backend/app/rcon_historical_read_model.py b/backend/app/rcon_historical_read_model.py index 96792e8..ac983d9 100644 --- a/backend/app/rcon_historical_read_model.py +++ b/backend/app/rcon_historical_read_model.py @@ -59,11 +59,8 @@ def list_rcon_historical_recent_activity( "name": item.get("map_name"), "pretty_name": normalize_map_name(item.get("map_pretty_name") or item.get("map_name")), }, - "result": { - "allied_score": None, - "axis_score": None, - "winner": None, - }, + "result": _build_rcon_result(item.get("latest_payload")), + "gamestate": _build_rcon_gamestate(item.get("latest_payload")), "player_count": int(round(float(item.get("average_players") or 0))), "peak_players": item.get("peak_players"), "sample_count": item.get("sample_count"), @@ -100,6 +97,8 @@ def describe_rcon_historical_read_model() -> dict[str, object]: "server_summary": "exact", "recent_matches": "approximate", "competitive_quality": "partial", + "result": "session-score", + "gamestate": "session", "player_stats": "unavailable", }, "limitations": [ @@ -155,11 +154,8 @@ def get_rcon_historical_match_detail( "name": item.get("map_name"), "pretty_name": normalize_map_name(item.get("map_pretty_name") or item.get("map_name")), }, - "result": { - "allied_score": None, - "axis_score": None, - "winner": None, - }, + "result": _build_rcon_result(item.get("latest_payload")), + "gamestate": _build_rcon_gamestate(item.get("latest_payload")), "player_count": int(round(float(item.get("average_players") or 0))), "peak_players": item.get("peak_players"), "sample_count": item.get("sample_count"), diff --git a/backend/app/rcon_historical_storage.py b/backend/app/rcon_historical_storage.py index 3f59662..3afc072 100644 --- a/backend/app/rcon_historical_storage.py +++ b/backend/app/rcon_historical_storage.py @@ -446,7 +446,8 @@ def list_rcon_historical_competitive_windows( windows.max_players, windows.status, windows.confidence_mode, - windows.capabilities_json + windows.capabilities_json, + windows.latest_payload_json FROM rcon_historical_competitive_windows AS windows INNER JOIN rcon_historical_targets AS targets ON targets.id = windows.target_id @@ -485,6 +486,7 @@ def list_rcon_historical_competitive_windows( "status": row["status"], "confidence_mode": row["confidence_mode"], "capabilities": _deserialize_json_object(row["capabilities_json"]), + "latest_payload": _deserialize_json_object(row["latest_payload_json"]), } ) return items @@ -611,7 +613,8 @@ def find_rcon_historical_competitive_window( windows.total_players, windows.peak_players, windows.confidence_mode, - windows.capabilities_json + windows.capabilities_json, + windows.latest_payload_json FROM rcon_historical_competitive_windows AS windows INNER JOIN rcon_historical_targets AS targets ON targets.id = windows.target_id @@ -732,6 +735,7 @@ def get_rcon_historical_competitive_window_by_session( "peak_players": int(row["peak_players"] or 0), "confidence_mode": row["confidence_mode"], "capabilities": _deserialize_json_object(row["capabilities_json"]), + "latest_payload": _deserialize_json_object(row["latest_payload_json"]), } @@ -986,6 +990,8 @@ def _build_competitive_capabilities() -> dict[str, object]: "recent_matches": COMPETITIVE_MODE_APPROXIMATE, "server_summary": COMPETITIVE_MODE_EXACT, "competitive_quality": COMPETITIVE_MODE_PARTIAL, + "result": "session-score", + "gamestate": "session", "player_stats": "unavailable", }