# -*- coding: utf-8 -*-
"""Alinha a entrada no mundo de duas capturas e mostra TODA diferenca, frame a frame.

Existe porque eu passei a tarde comparando os pacotes que EU escolhia olhar, achando todos
iguais, e concluindo errado. Aqui a comparacao e mecanica: alinha pelo opcode e reporta tudo.
"""
import re
import struct
import sys


def frames_recv(caminho):
    ev, cur = [], None
    for linha in open(caminho, encoding="latin-1"):
        m = re.match(r"\[([\d:.]+)\] (SEND|RECV) sock=(0x[0-9A-Fa-f]+) len=(\d+)", linha)
        if m:
            cur = [m.group(2), m.group(3), bytearray()]
            ev.append(cur)
            continue
        if cur is not None and re.fullmatch(r"(?:[0-9A-Fa-f]{2} )+\s*", linha):
            cur[2].extend(bytes.fromhex(linha.strip()))
    por = {}
    for direcao, sock, dados in ev:
        if direcao == "RECV":
            por.setdefault(sock, bytearray()).extend(dados)
    if not por:
        return []
    fluxo = max(por.values(), key=len)
    saida, pos = [], 0
    while pos + 4 <= len(fluxo):
        (t,) = struct.unpack_from(">I", fluxo, pos)
        if t == 0 or t > 8192 or pos + 4 + t > len(fluxo):
            pos += 1
            continue
        saida.append(bytes(fluxo[pos + 4:pos + 4 + t]))
        pos += 4 + t
    return saida


def janela(frames, quantos=30):
    """Do primeiro 06 05 (a lista de inventario da entrada) em diante."""
    for i, f in enumerate(frames):
        if f[:2] == bytes([6, 5]) and len(f) > 1000:
            return frames[max(0, i - 10):i + quantos]
    return frames[:quantos]


def main():
    a = janela(frames_recv(sys.argv[1]))
    b = janela(frames_recv(sys.argv[2]))
    print(f"{'OFICIAL':<28}{'NOSSO':<28}")
    ia = ib = 0
    while ia < len(a) or ib < len(b):
        fa = a[ia] if ia < len(a) else None
        fb = b[ib] if ib < len(b) else None
        # pula o trafego de ambiente, que nao tem por que casar
        if fa is not None and fa[:2] in (bytes([4, 1]), bytes([4, 3]), bytes([11, 0])):
            ia += 1
            continue
        if fb is not None and fb[:2] in (bytes([4, 1]), bytes([4, 3]), bytes([11, 0])):
            ib += 1
            continue
        ra = f"{fa[:2].hex(' ')} ({len(fa)}b)" if fa else "---"
        rb = f"{fb[:2].hex(' ')} ({len(fb)}b)" if fb else "---"
        nota = ""
        if fa and fb and fa[:2] == fb[:2] and len(fa) == len(fb):
            dif = [i for i in range(len(fa)) if fa[i] != fb[i]]
            # 2:6 e o numero de sequencia, 6:10 costuma ser o id do personagem
            dif = [i for i in dif if not (2 <= i < 10)]
            nota = "identico (fora seq/id)" if not dif else f"difere em {len(dif)} bytes: {dif[:14]}"
        elif fa and fb and fa[:2] != fb[:2]:
            nota = "<<< OPCODE DIFERENTE"
        print(f"  {ra:<26}{rb:<26}{nota}")
        ia += 1
        ib += 1


if __name__ == "__main__":
    main()
