---
name: cabal-extender-modulos
description: "Quais módulos do lib.so (extender EP33→EP35) realmente rodam, e o shim que liga o DropEffect/LootAnnouncer"
metadata: 
  node_type: memory
  type: project
  originSessionId: 153bd067-f5ce-4a37-9378-d46c0afa3789
  modified: 2026-08-16T12:38:18.459Z
---

No `lib.so` do extender (em `/etc/cabal_bin/lib/`, ver [[cabal-server-arquitetura]]), o
`Core::Init()` chama **apenas 5** `Attach()`: Cast, ProcSystem, SockHandler, UserHandler e Fix35.

`DropEffect::Attach()`, `ForceEffect::Attach()` e `Global::Attach()` têm **zero call sites** —
estão compilados e exportados, mas mortos. Não existe arquivo de configuração que ligue/desligue
módulo: quem não está na lista do `Core::Init()` simplesmente não roda.

**Why:** é fácil olhar os símbolos do `lib.so`, ver 245 funções de jogo e concluir que tudo está
ativo. Não está. E `[RANK LIMIT]` no log do WorldSvr **não** é do extender — essa string está no
binário do WorldSvr, não no `lib.so`. O extender não escreve em lugar nenhum: o `Log::Print` dele
aponta para `/var/log/cabal/lib` e não produz arquivo.

**How to apply:** para saber se um módulo está ativo, procure `call ...NomeDoModulo6AttachEv` no
`objdump -d` do `lib.so`. Para verificar em runtime se o DropEffect subiu, leia o primeiro byte de
`0x9e2a60` no `/proc/<pid>/mem` do WorldSvr: `0x48` = sem hook, `0xff` = desvio PolyHook instalado.

## LootAnnouncer (ligado em 2026-08-16)

Vive dentro do `DropEffect.cpp:62`. Lê `/etc/cabal/Data/Lib/LootAnnouncer.json` (UTF-8), formato:
`{"Enabled": true, "AnnounceItems": [{"ItemIdx": N, "ItemKindFlags": [], "ItemOptionFlags": []}]}`.
Array vazio = casa com qualquer coisa; o match é bitwise AND != 0, não igualdade. O parser tem
null-check em tudo, então chave faltando não quebra. A chave de busca é `ItemKind & 0x06000FFF`:
bits 0-11 = Index na tabela, bits 25-26 = qual tabela — `Item.scp` → chave = Index,
`Item2.scp` → chave = Index + 33554432.

Para ligar foi preciso um shim próprio, `/etc/cabal_bin/lib/libloot_enable.so`
(fonte `loot_enable.c` + `REBUILD_loot_enable.sh` na mesma pasta), adicionado ao fim do `LD_PRELOAD`
nas 30 linhas do `cabal_server1.conf`. Ele chama `DropEffect::Attach()` de fora, **numa thread com
retry** — chamar direto do constructor falha calado, porque a ordem de construtores entre objetos do
LD_PRELOAD não é a ordem da lista e o shim rodava antes do `Core::Init()` do `lib.so`. Na prática
acerta na 2ª tentativa (+2s). O shim tem guarda de nome de processo obrigatória: o `LD_PRELOAD`
também vale para o `/bin/bash` que o supervisor usa antes do `exec`, e chamar `Attach()` ali
derrubaria o shell antes do servidor subir.
