# -*- coding: utf-8 -*-
"""Extrai os frames 02 01 (lista de personagens) de um log do hook."""
import re
import struct
import sys


def frames_do_log(caminho):
    """Devolve os blocos RECV concatenados por socket."""
    blocos = {}
    sock = None
    with open(caminho, encoding="latin-1") as f:
        for linha in f:
            m = re.match(r"\[[\d:.]+\] (SEND|RECV) sock=(0x[0-9A-Fa-f]+) len=(\d+)", linha)
            if m:
                sock = (m.group(2), m.group(1))
                blocos.setdefault(sock, bytearray())
                continue
            if sock and re.fullmatch(r"(?:[0-9A-Fa-f]{2} )+\s*", linha):
                blocos[sock].extend(bytes.fromhex(linha.strip()))
    return blocos


def main():
    for cam in sys.argv[1:]:
        for (sk, dirn), dados in frames_do_log(cam).items():
            if dirn != "RECV":
                continue
            pos, achados = 0, []
            while pos + 4 <= len(dados):
                (t,) = struct.unpack_from(">I", dados, pos)
                if t == 0 or t > 8192 or pos + 4 + t > len(dados):
                    pos += 1
                    continue
                c = bytes(dados[pos + 4:pos + 4 + t])
                if c[:2] == bytes([2, 1]):
                    achados.append((pos, t, c))
                pos += 4 + t
            if not achados:
                continue
            print(f"--- {cam} sock={sk}: {len(achados)} frames 02 01")
            for pos, t, c in achados[:14]:
                eid = struct.unpack_from(">I", c, 7)[0]
                cl = struct.unpack_from("<H", c, 15)[0] if t > 17 else 0
                nome = ""
                if t > 400:
                    tam = struct.unpack_from("<H", c, 389)[0]
                    if 0 < tam < 40:
                        nome = c[391:391 + tam * 4].decode("utf-32-le", "replace")
                print(f"    tam={t:4} [4]={c[4]} [5]={c[5]} [6]={c[6]} id={eid:6} "
                      f"classe={cl:4} nome={nome!r}")


if __name__ == "__main__":
    main()
