-
Notifications
You must be signed in to change notification settings - Fork 37
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.
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/deleteinterno de allocator
O resultado importante e:
Raw new/delete dono comum em src/: 0
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.
| 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.
Use:
bash tools/run-valgrind.shO 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 \
./tfsResultado esperado quando esta limpo:
All heap blocks were freed -- no leaks are possible
ERROR SUMMARY: 0 errors from 0 contexts
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
.luasao ordenados antes de carregar. - Arquivos com
#no nome continuam ignorados. - Pode renomear
npc_CRYSTALSERVER_REV; o C++ nao depende desse nome. - Subpastas funcionam automaticamente.
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 tambemGame.createNpcType("Nome").
Assim da para importar pack Crystal com o minimo de edicao.
O comportamento de foco foi igualado entre NPC XML, NPC RevScript TFS e NPC Lua Crystal.
Comportamento correto:
- Player fala
hi. - NPC vira para o player.
- NPC para de andar enquanto esta focado.
- NPC volta a andar somente quando perde o foco.
Pontos corrigidos:
-
Npc::setCreatureFocuslimpa direcoes pendentes e para o evento de walk. -
Npc::onThinknao faz walk random com foco ativo. -
Npc::getNextStepretorna cedo enquanto existe foco. - XML/Crystal agora seguem o mesmo comportamento dos RevScript modernos.
Quando um NPC nao e encontrado, o log agora explica:
- Nao achou RevScript em nenhuma pasta carregada de
data/npc/, excetolib/. - O XML
data/npc/<nome>.xmltambem nao existe. - Sugere criar
.luacomNpcType:new("<nome>")ou conferir o nome exato no mapa, inclusive maiusculas/minusculas.
O XML tambem ficou mais seguro:
- Se o arquivo nao existe, retorna
falsesilencioso para permitir fallback. - Se existe mas esta malformado, gera
LOG_ERRORcom descricao do parser.
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.
Estado atual:
- Raw
new/deletedono 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.