---
name: cabal-pacotes-chat
description: "Formatos reais dos pacotes de chat e megafone do EP33, capturados do fio, e por que a janela de sistema nao aceita texto livre"
metadata: 
  node_type: memory
  type: project
  originSessionId: 153bd067-f5ce-4a37-9378-d46c0afa3789
  modified: 2026-08-16T20:20:26.892Z
---

Formatos capturados ao vivo no canal 1 (hook na funcao de criptografia de saida
`0xB43F60`, que ve todo pacote de saida ainda em texto claro). A numeracao de
opcode no fio bate com `WorldSvr/PacketManager/Protodefs.h` do fonte.

**Chat normal — opcode 217 (`NFY_MESSAGEEVNT`)**

```
+0  WORD  magic 0xB7E2
+2  WORD  tamanho total
+4  WORD  217
+6  DWORD charIdx de quem falou
+10 BYTE  tipo (3 = cracha de GM; todo o resto sai igual)
+11 WORD  total - 13
+13 WORD  3 + tamanho da mensagem
+15 BYTE  fe fe a0   (prefixo do texto)
+18 char  mensagem, sem terminador
    3 bytes zero no fim
```

Nao carrega nome: o cliente resolve pelo charIdx. **Com charIdx = 0 nao aparece
nada**, e com um charIdx que o cliente nao conhece tambem nao. Por isso nao serve
para anuncio global.

**Megafone — opcode 2091** (nao esta no Protodefs.h; a lista do fonte e incompleta)

```
+0  WORD  magic 0xB7E2
+2  WORD  tamanho total
+4  WORD  2091
+6  DWORD charIdx  (pode ser 0)
+10 BYTE  0
+11 BYTE  1        (variar de 0 a 5 nao muda nada)
+12 BYTE  tamanho do nome
+13 WORD  2 + tamanho da msg + 3
+15 char  nome (max 16, sem terminador)
    WORD  tamanho da mensagem
    char  mensagem
    3 bytes zero no fim
```

Leva o nome escrito dentro do pacote, entao **funciona para anuncio global**:
aparece para todos, em qualquer mapa, com cor propria, sem depender de
personagem nenhum. E o unico canal de texto livre global num cliente sem
modificacao.

**A janela de mensagem do sistema nao aceita texto livre.** O texto dela mora
criptografado dentro do cliente (`.enc`) e o servidor so manda um numero
escolhendo qual frase mostrar — via codigo de erro (`NFS_LASTERRCODE`,
`SendErrorCode` no fonte). A linha "Item Obtained" e gerada pelo cliente a
partir do `S2C_ITEMLOOTING`, que so carrega numeros (ItemIdx, slot) e vai so
para quem pegou o item; mandar para os outros criaria item fantasma na mochila.
O unico pacote que nomeia outra pessoa e `NFY_PARTYQUESTITEMLOOTING` (378),
exclusivo de item de missao em grupo.

**`S2C_ITEMLOOTING` (opcode 153 = 0x99), formato real capturado:**

```
e2b7 | 1d00 | 9900 | 60 | d5080002 00000000 | 01000000 00000000 | 0700 | 00000000
magic  len29  op153  res      ItemIdx (8)         ItemOpt (8)      slot   Duration
```

O `bResult` de sucesso e **96 (0x60, LR_SUCCESS)** — com 0 ou 1 o cliente
ignora o pacote em silencio.  Com 96 ele processa, mas **derruba o cliente** se
a coleta nao foi pedida por ele.  Nao serve para anuncio.

Testados e **descartados** (nao renderizam nada): opcodes 241, 243, 394, 397,
677, 678, 2090, 2092, 2093, 2094 — em formato de megafone, de chat e simples.
Secoes de `.ini` do tipo `[ItemDropBroadcast]` / `[ItemBroadcast]` nao existem
neste binario; dica de outra build.

**Pacotes que CHEGAM (cliente -> servidor).**  Ponto de escuta: `0xB3D7F8`,
`call *0x178(%rax)` — aparece **uma unica vez no binario inteiro**, e' o funil
por onde passa todo pacote recebido, ja decifrado.  Argumentos:
`rdi` = conexao, `rsi` = pacote, `rdx` = tamanho.  Sao 6 bytes
(`ff 90 78 01 00 00`), entao o remendo e' `call rel32` + `nop`.  O `%rax`
original e' so' `*(void**)self`, da' para recuperar dentro do gancho.

O cabecalho da entrada **nao e' igual ao da saida**:

```
saida:    magic(2)  tamanho(2)  opcode(2)  corpo
entrada:  magic(2)  tamanho(2)  zeros(4)   opcode(2)  corpo
```

Os 4 zeros sao sobra do campo de cifra.  Prova: existe pacote de entrada com
10 bytes no total (`e2 b7 0a 00 00 00 00 00 a4 0c`), opcode encostado no fim.

O gancho pega **toda** conexao, inclusive as entre servidores — no start do
canal aparecem opcodes 3173/3311 com 4,5 KB, que sao tabelas do DBAgent, nao
do cliente.

Ver [[cabal-extender-modulos]], [[cabal-source-ep33]] e [[cabal-eventpass]].
