Skip to content

Auditoria Final Smart Pointer e NPC Crystal

Mateuzkl edited this page Apr 28, 2026 · 1 revision

Auditoria Final Smart Pointer e NPC Crystal

Status: 28 de abril de 2026
Branch: refactor/atlas-smartptr
Projeto: TFS 1.8 Downgrade 8.60

Esta pagina documenta o estado final da auditoria de ownership em C++ e o suporte novo para NPCs RevScript no estilo Crystal Server.


Resumo Direto

O TFS 1.8-8.60 agora esta com ownership normal 100% em RAII:

Area Resultado
new T comum/dono em src/ 0
delete ptr comum/dono em src/ 0
Hits std::make_unique / make_unique< 128
Hits std::make_shared / make_shared< 75
Referencias unique_ptr 130
Referencias shared_ptr 373
Referencias weak_ptr 84
Valgrind memcheck 0 errors, 0 leaks

O grep generico para new e delete nao e a verdade final porque pega falso positivo:

  • SQL DELETE FROM
  • construtores deletados com = delete
  • comentarios
  • strings Lua
  • metodos Lua chamados :delete
  • placement-new do Lua userdata
  • operator new/delete interno de allocator

O resultado importante e:

Raw new/delete dono comum em src/: 0

Raw Pointer nao e sempre bug

Ainda existem Player*, Item*, Creature*, Tile* e outros ponteiros crus no codigo.

Isso nao significa ownership perigoso.

No TFS, muitos T* sao apenas observadores rapidos, parametros temporarios, indices internos ou handles de compatibilidade. A vida real do objeto fica segurada por shared_ptr, unique_ptr, containers, Lua userdata ou registries controlados da engine.

Exemplos que estao corretos:

Padrao Motivo
Player* player = ... Observador local sem posse.
Thing*, Item*, Tile* em parametros API classica do TFS observa o objeto, nao vira dona dele.
Placement-new em luascript.cpp / luascript.h Constroi valor C++ dentro da memoria do Lua userdata.
operator new/delete em lockfree.h Contrato de allocator STL: memoria crua, vida do objeto e do container.
OpenSSL *_new() Envolvido imediatamente em unique_ptr com deleter correto.

Nao converta tudo para shared_ptr no automatico. Isso pode criar ownership duplicado, ciclos e overhead desnecessario.


Modelo Atual de Ownership

Area da engine Modelo atual
Players unordered_map<uint32_t, weak_ptr<Player>> + anchors de vida
Creatures vida em shared_ptr<Creature>, relacoes em weak_ptr
Monsters / NPCs shared_ptr onde precisa, unique_ptr para posse local estrita
Items factory com shared_ptr<Item>
Tiles unique_ptr<Tile> e containers com smart pointers
Conditions unique_ptr<Condition>
Scheduler / dispatcher unique_ptr<Task> / unique_ptr<SchedulerTask>
Lua userdata construcao segura, handoff controlado, validacao por weak_ptr
NPC handlers unique_ptr<NpcEventsHandler>

Esse modelo segue a linha robusta do Atlas, mas mantendo o comportamento especifico do TFS 1.8-8.60.


Comando Valgrind Definitivo

Use:

bash tools/run-valgrind.sh

O script compila o preset Valgrind, copia o binario final para ./tfs, mantem o diretorio de execucao na raiz do servidor e roda:

valgrind \
  --tool=memcheck \
  --leak-check=full \
  --show-leak-kinds=definite \
  --track-origins=yes \
  --num-callers=50 \
  --leak-resolution=high \
  --error-limit=no \
  --expensive-definedness-checks=yes \
  --partial-loads-ok=yes \
  --log-file=valgrind-definitive.log \
  ./tfs

Resultado esperado quando esta limpo:

All heap blocks were freed -- no leaks are possible
ERROR SUMMARY: 0 errors from 0 contexts

Suporte a NPC RevScript do Crystal Server

O loader de NPC agora aceita packs Crystal Server sem nome de pasta hardcoded.

Estrutura suportada:

data/npc/
├── lib/
│   ├── npc.lua
│   └── crystalcompat/
├── lua/
│   └── npcs_tfs_originais.lua
├── npc_CRYSTALSERVER_REV/
│   ├── alesar.lua
│   └── subpasta/
│       └── Delowen.lua
└── qualquer_nome_de_pasta/
    └── sub/
        └── npc.lua

Regras:

  • data/npc/lib/ e biblioteca e nao e carregada como NPC.
  • Qualquer outra pasta direta dentro de data/npc/ e lida automaticamente.
  • A busca e recursiva.
  • Arquivos .lua sao ordenados antes de carregar.
  • Arquivos com # no nome continuam ignorados.
  • Pode renomear npc_CRYSTALSERVER_REV; o C++ nao depende desse nome.
  • Subpastas funcionam automaticamente.

Camada crystalcompat

A lib em data/npc/lib/crystalcompat/ da suporte aos scripts Crystal que esperam globals antigos ou dofile() relativo.

O que ela cobre:

  • Deteccao da pasta do script atual.
  • Fallback dinamico de dofile() sem hardcodar nome de pasta.
  • Suporte a subpastas.
  • Compatibilidade com helpers de storage/global storage.
  • Defaults seguros de eventos para NPC nao ficar invisivel ou mudo sem motivo.
  • Suporte a scripts com NpcType:new("Nome") e tambem Game.createNpcType("Nome").

Assim da para importar pack Crystal com o minimo de edicao.


Foco e Movimento do NPC

O comportamento de foco foi igualado entre NPC XML, NPC RevScript TFS e NPC Lua Crystal.

Comportamento correto:

  1. Player fala hi.
  2. NPC vira para o player.
  3. NPC para de andar enquanto esta focado.
  4. NPC volta a andar somente quando perde o foco.

Pontos corrigidos:

  • Npc::setCreatureFocus limpa direcoes pendentes e para o evento de walk.
  • Npc::onThink nao faz walk random com foco ativo.
  • Npc::getNextStep retorna cedo enquanto existe foco.
  • XML/Crystal agora seguem o mesmo comportamento dos RevScript modernos.

Diagnostico de NPC nao encontrado

Quando um NPC nao e encontrado, o log agora explica:

  • Nao achou RevScript em nenhuma pasta carregada de data/npc/, exceto lib/.
  • O XML data/npc/<nome>.xml tambem nao existe.
  • Sugere criar .lua com NpcType:new("<nome>") ou conferir o nome exato no mapa, inclusive maiusculas/minusculas.

O XML tambem ficou mais seguro:

  • Se o arquivo nao existe, retorna false silencioso para permitir fallback.
  • Se existe mas esta malformado, gera LOG_ERROR com descricao do parser.

Efeito de Teleport Corrigido

Game::internalTeleport agora aceita efeito opcional.

Padrao continua igual:

doTeleportThing(cid, pos)

manda CONST_ME_TELEPORT.

Para movimento sem efeito:

doTeleportThing(cid, pos, CONST_ME_NONE)
creature:teleportTo(pos, false, CONST_ME_NONE)

Isso remove o efeito azul falso em escadas, buracos, portas, walkback, rollback de instancias e movimentos que nao sao portal real.


Conclusao Final

Estado atual:

  • Raw new/delete dono comum: zerado.
  • Scheduler/Lua raw delete pendente: resolvido; contagem antiga era falso positivo de grep.
  • Player map com dangling pointer: resolvido com weak_ptr<Player>.
  • NPC Crystal RevScript: suporta pasta renomeada, subpasta e lib de compatibilidade.
  • Valgrind/ASAN: limpo nos testes do usuario.

Os T* restantes devem ser tratados como observadores, nao como donos, salvo se uma auditoria futura provar o contrario.

Clone this wiki locally