-am (#1333)
This commit is contained in:
+27
-5
@@ -27,11 +27,11 @@ CREATE TABLE IF NOT EXISTS match_logs (
|
||||
session_id TEXT PRIMARY KEY,
|
||||
chat_log_json TEXT,
|
||||
battle_log_json TEXT,
|
||||
event_log_json TEXT,
|
||||
built_unix INTEGER
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
def _fmt_time(ms: int) -> str:
|
||||
total_s = int(ms) // 1000
|
||||
return f"{total_s // 60:02d}:{total_s % 60:02d}"
|
||||
@@ -49,6 +49,17 @@ def _decompress_events(raw_events: Any) -> dict:
|
||||
return raw_events or {}
|
||||
|
||||
|
||||
def build_event_log(game: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Return the raw event slices the website needs for per-unit state."""
|
||||
events = _decompress_events(game.get("events", {}))
|
||||
if not isinstance(events, dict):
|
||||
return {"kills": [], "damage": []}
|
||||
return {
|
||||
"kills": list(events.get("kills") or []),
|
||||
"damage": list(events.get("damage") or []),
|
||||
}
|
||||
|
||||
|
||||
def _strip_tag(tag: str) -> str:
|
||||
s = (tag or "").strip()
|
||||
if len(s) >= 3 and not s[0].isalnum() and not s[-1].isalnum():
|
||||
@@ -166,19 +177,30 @@ def build_match_logs(game: dict[str, Any]) -> tuple[list[str], list[str]]:
|
||||
|
||||
|
||||
async def upsert_match_logs(
|
||||
db_path, session_id: str, chat_log: list[str], battle_log: list[str]
|
||||
db_path,
|
||||
session_id: str,
|
||||
chat_log: list[str],
|
||||
battle_log: list[str],
|
||||
event_log: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
import time
|
||||
async with aiosqlite.connect(db_path) as conn:
|
||||
await conn.execute(MATCH_LOGS_SQL)
|
||||
try:
|
||||
await conn.execute("ALTER TABLE match_logs ADD COLUMN event_log_json TEXT")
|
||||
except Exception:
|
||||
pass
|
||||
await conn.execute(
|
||||
"""INSERT INTO match_logs (session_id, chat_log_json, battle_log_json, built_unix)
|
||||
VALUES (?, ?, ?, ?)
|
||||
"""INSERT INTO match_logs (session_id, chat_log_json, battle_log_json, event_log_json, built_unix)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON CONFLICT(session_id) DO UPDATE SET
|
||||
chat_log_json=excluded.chat_log_json,
|
||||
battle_log_json=excluded.battle_log_json,
|
||||
event_log_json=excluded.event_log_json,
|
||||
built_unix=excluded.built_unix""",
|
||||
(str(session_id), json.dumps(chat_log, ensure_ascii=False),
|
||||
json.dumps(battle_log, ensure_ascii=False), int(time.time())),
|
||||
json.dumps(battle_log, ensure_ascii=False),
|
||||
json.dumps(event_log or {"kills": [], "damage": []}, ensure_ascii=False),
|
||||
int(time.time())),
|
||||
)
|
||||
await conn.commit()
|
||||
|
||||
@@ -13,7 +13,7 @@ ROOT = pathlib.Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
sys.path.insert(0, str(ROOT.parent / "SHARED"))
|
||||
|
||||
from BOT.match_logs import build_match_logs, upsert_match_logs, MATCH_LOGS_SQL
|
||||
from BOT.match_logs import build_event_log, build_match_logs, upsert_match_logs, MATCH_LOGS_SQL
|
||||
from BOT.storage import TSS_BATTLES_DB_PATH
|
||||
|
||||
REPLAYS = pathlib.Path(os.environ["STORAGE_VOL_PATH"]) / "REPLAYS" / "TSS"
|
||||
@@ -36,10 +36,11 @@ async def main(dry_run: bool) -> None:
|
||||
print(f" skip {sid}: {exc}")
|
||||
continue
|
||||
chat, battle = build_match_logs(game)
|
||||
event_log = build_event_log(game)
|
||||
if dry_run:
|
||||
print(f" {sid}: chat={len(chat)} battle={len(battle)}")
|
||||
print(f" {sid}: chat={len(chat)} battle={len(battle)} kills={len(event_log.get('kills') or [])}")
|
||||
else:
|
||||
await upsert_match_logs(TSS_BATTLES_DB_PATH, sid, chat, battle)
|
||||
await upsert_match_logs(TSS_BATTLES_DB_PATH, sid, chat, battle, event_log)
|
||||
done += 1
|
||||
print(f"{'Would backfill' if dry_run else 'Backfilled'} "
|
||||
f"{len(files) if dry_run else done} sessions")
|
||||
|
||||
@@ -4,7 +4,7 @@ import pathlib
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[2] / "SHARED"))
|
||||
|
||||
from BOT.match_logs import build_match_logs
|
||||
from BOT.match_logs import build_event_log, build_match_logs
|
||||
|
||||
|
||||
def _game():
|
||||
@@ -53,8 +53,15 @@ def test_events_base85_zstd_compressed():
|
||||
assert battle and "destroyed" in battle[0]
|
||||
|
||||
|
||||
def test_event_log_preserves_kill_victim_unit():
|
||||
event_log = build_event_log(_game())
|
||||
assert event_log["kills"][0]["offended_uid"] == 2
|
||||
assert event_log["kills"][0]["offended_unit"] == "germ_pz_iv"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_chat_log_format()
|
||||
test_battle_log_kill_prefix_and_text()
|
||||
test_events_base85_zstd_compressed()
|
||||
test_event_log_preserves_kill_victim_unit()
|
||||
print("ALL TESTS PASSED")
|
||||
|
||||
@@ -164,10 +164,10 @@ async def _handle_game(game: Dict[str, Any]) -> None:
|
||||
await insert_match(game)
|
||||
await insert_player_games(game)
|
||||
await upsert_tss_teams(game)
|
||||
from BOT.match_logs import build_match_logs, upsert_match_logs
|
||||
from BOT.match_logs import build_event_log, build_match_logs, upsert_match_logs
|
||||
from BOT.storage import TSS_BATTLES_DB_PATH
|
||||
chat_log, battle_log = build_match_logs(game)
|
||||
await upsert_match_logs(TSS_BATTLES_DB_PATH, sid, chat_log, battle_log)
|
||||
await upsert_match_logs(TSS_BATTLES_DB_PATH, sid, chat_log, battle_log, build_event_log(game))
|
||||
log.info("Stored game %s in DB", sid)
|
||||
except Exception as exc:
|
||||
log.error("DB insert failed for %s: %s", sid, exc)
|
||||
|
||||
Reference in New Issue
Block a user