"""Full-night digester: detail EVERY session that contains a mission. digest.py only detailed the last 3 sessions, which is wrong for the end-of-night files (25 sessions, with the two bad matches in the middle and the clean 3-player matches at the end). A session is detailed if it contains any death/respawn/damage marker; menu-only sessions collapse to one line. """ import os import re import sys DIR = os.path.dirname(os.path.abspath(__file__)) FILES = { "full_sauron_XIAOLONG.log": "SAURON (XIAOLONG) -- hosted matches", "full_elengil_ALIA.log": "Elengil (ALIA) -- desync + limp-skate reporter", "full_rajel_GAMERSLAB.log": "RajelAran (GAMERSLAB) -- voice-replay reporter", "full_connman_MSFIREFLY.log": "Conn Man (MS-FIREFLY)", "roll_sauron_XIAOLONG.log": "SAURON rollover (late matches)", "roll_rajel_GAMERSLAB.log": "RajelAran rollover (late matches)", } KEEP = re.compile( r"\[respawn\]|\[damage\]|\[deathfx\]|DESTROYED|SWALLOWED|RECOVERED" r"|PLAYER_LINK|\[matchlog\]|KILL|DEATH" r"|\[steamnet\]|PEER_|ROUTE_|HELLO|LOBBY" r"|MakeMessage|DynamicEntity|interest|CollisionVolume|collision volume" r"|WARNING|ERROR|Fail\(|assert|crash|EXCEPTION|BUG \(Gitea" r"|acquireFails|pool exhaust|DROP transient" r"|\[gimp|\[exp\]|\[tick\]|SESSION build=", re.I) MISSION = re.compile(r"\[respawn\]|DESTROYED|\[tick\]|\[exp\]", re.I) MAXPERSESS = 150 def run(): total = 0 for f, who in FILES.items(): p = os.path.join(DIR, f) if not os.path.exists(p): print("MISSING", f) continue raw = open(p, encoding="latin-1", errors="replace").read().splitlines() b = [i for i, l in enumerate(raw) if "BT411 SESSION build=" in l] or [0] b.append(len(raw)) out = [f"##### {who} ({f}, {len(raw)} lines, {len(b)-1} sessions)"] for idx, (s, e) in enumerate(zip(b, b[1:])): block = raw[s:e] head = block[0][:140] if block else "" build = re.search(r"build=([0-9.]+)", head) build = build.group(1) if build else "?" local = re.search(r"local=([0-9: -]+)", head) local = local.group(1).strip() if local else "?" has_mission = any(MISSION.search(l) for l in block) if not has_mission: out.append(f"-- session {idx+1}: build={build} local={local} " f"[{e-s} lines, no mission -- menu/abort]") continue kept = [f" {s+i+1}: {l[:185]}" for i, l in enumerate(block) if KEEP.search(l)] noise = (e - s) - len(kept) out.append("") out.append(f"===== session {idx+1}/{len(b)-1} build={build} local={local} " f"raw lines {s+1}-{e}") if len(kept) > MAXPERSESS: h = MAXPERSESS // 2 kept = kept[:h] + [f" ... {len(kept)-MAXPERSESS} elided ..."] + kept[-h:] out.extend(kept) out.append(f" [telemetry suppressed: {noise}]") d = "\n".join(out) o = os.path.join(DIR, "d2_" + f.replace(".log", ".txt")) open(o, "w", encoding="utf-8").write(d) total += len(d) nmiss = d.count("===== session") print("%-30s -> %6.1f KB (%d mission sessions detailed)" % (f, len(d)/1024, nmiss)) print("total: %.1f KB" % (total/1024)) run()