Repository navigation
v2.0.0
Lodestar
v2.0.0 (2026-09-21)
Full Changelog Previous Releases
- chore(release): v2.0.0
- Merge pull request #6 from danielcosta42/feat/forever-only
Lodestar 100% Forever: dropar TBC e abrir a camada de dado - feat(forever): decoder do Cache/WDB — os ids-alvo que nenhuma API dá
tools/wdb.py lê questcache/creaturecache/gameobjectcache do cliente e
devolve JSON no schema que o roteador já consome. 23/23 registros parseiam
byte a byte no build 69913.
Por que isto importa mais do que parecia: o texto de objetivo do Forever
usa placeholder de servidor ("Kill $1oa Galak Centaurs, $2oa Galak
Outrunners"), então a regex de contagem do router NUNCA vai recuperar
quantos matar pelo texto. Oamountdecodificado do WDB é a única fonte
que existe. Sem isto, todo objetivo de conteúdo novo viraria passo sem
contador.
Extrai com confiança: name, questLevel, reqLevel, zoneOrSort, nextInChain,
faction (derivada da máscara de raça), objText, details, e objectives com
{type, id, amount, text} — mais objCreatures/objItems/objObjects.
Conferido contra valores conhecidos: 745 "Sharing the Land" nível 8, zona
215, criaturas 2949/2950/2951 x 10/8/5; NPC 2949 = "Palemane Tanner";
objeto 3656 = "Bonfire".
O que NÃO extrai, e por quê (cada um marcado com ponytail: no arquivo):- giver/ender e qualquer coordenada: o cache guarda a quest, nunca quem a
entrega. Isso é do /ls scan. - specialFlags fica 0: o Flags do cliente não é o specialFlags do Questie,
e mapear errado dispararia o teste& 3de repetível/evento do router. - startItems fica vazio: o SrcItemId é o item que o giver FORNECE, não o
que inicia a quest ao ser lootado. Semântica diferente, passo bogus.
fix(consumables): os 15 itens do checklist de raide eram de Outland e
NENHUM existe no ItemSparse do 69913 — conferido item a item. O /ls check
marcava tudo como faltando, para sempre. Trocados pelos equivalentes
vanilla, todos confirmados presentes no mesmo build.
Dado morto de Outland que sobra em FlightData/TransitData/Trainers/
ZoneData fica, e está documentado: é inalcançável (nenhum guia rota para
lá), e sai quando essas tabelas forem regeradas para o Forever.
- giver/ender e qualquer coordenada: o cache guarda a quest, nunca quem a
- fix(forever): parar de consumir o dado raspado, não só de raspá-lo
O commit anterior removeu tools/fetch_forever.py mas o import_forever.py
seguia lendo build/forever_quests.json do cache — 441 quests. Ou seja: a
posição estava no README e não no código, e o README afirma que nada é
raspado. Agora é verdade.
O passo de ingestão da Wowhead saiu do importador. Custo honesto: 4.391
quests em vez de 4.829. Aquelas 441 voltam pelo /ls scan e pelo WDB, que
são nossos e limpos — e a Wowhead tinha 1 quest em Riverglades e 0 em
Shen'dralas, que é o que de fato importa.
ForeverData.lua regenerado contra o 69913 (estava com dado do 69893):- 0 guias sem conteúdo, o que confirma que a deleção dos 106 foi completa
- 380 quests removidas em guias vivos, igual a antes
- foreverUnknown vai a 2.824 ids: não desconta mais o que a Wowhead sabia
Correção de um erro meu na doc: eu havia tirado a figura "2.824" alegando
que não era reproduzível. É — o gen_forever.py a calcula. A baseline é o
Anniversary 2.5.6.69795, não o Classic Era (1.795) nem o corte por id
= 30000 (2.844). As três estão na doc agora, com a base declarada.
import_forever.py também passa a comparar contra o 69913. - feat(forever): coletor colhe no gossip, e para de engolir título vazio
O ForeverScan agora rende muito mais por sessão e grava os campos que o
roteador exige.
Bug corrigido:q.name = q.name or GetTitleForQuestID(qid). Em Lua "" é
VERDADEIRO, então um título vazio grudava no registro e a varredura nunca
voltava a pedir aquele id — o dado ficava permanentemente pela metade. Agora
título só entra se for string não vazia, eHaveQuestDataé o teste de
cache em vez do nome gravado.
Frente nova, a de maior rendimento por esforço: colheita no GOSSIP_SHOW e
QUEST_GREETING.C_GossipInfo.GetAvailableQuests()devolve TODA quest que
o NPC oferece, com id e nível, sem aceitar nenhuma. Um clique num NPC rende
o NPC inteiro — antes só se colhia o que o jogador abrisse.
Campos que faltavam e o roteador indexa:factionvia GetQuestFactionGroup (não existe API de facção exigida; este
global legado é a única fonte)uiMapvia GetQuestUiMapIDrepeatable,waypointText, eleveldo GetInfo do log, que é melhor
fonte que GetQuestDifficultyLevel
Identidade de NPC passa por ns.UnitNpc, com preferência pelo token
"questnpc" na janela de quest. Registro que tem id de NPC não é mais
sobrescrito por um que não tem.
Cada colheita agora se identifica (build, interface, locale, facção). Sem
isso, mesclar contribuição de terceiros é adivinhação: build diferente tem
id diferente e facção decide a rota.
ok == falseno QUEST_DATA_LOAD_RESULT é tratado como AMBÍGUO — pode ser
id inexistente, recusa ou throttle. Não marca nada como inexistente.
tools/forever-scan.lua: 26 checks contra o arquivo de verdade, incluindo o
título vazio, a colheita no gossip e a proveniência.
- feat(forever)!: Lodestar passa a ser WoW: Forever e só
Dropa TBC/Anniversary por inteiro. O addon mira interface 16001 (token de
TOCCamelot) e nada mais.
O que sai:- 106 guias cujo conteúdo aquele cliente não tem (Outland, Quel'Thalas,
Azuremyst/Bloodmyst, atunações e dailies de TBC), com as entradas
correspondentes nos dois XML de include - Attunements.lua, RaidAttuneData.lua, TalentBuilds.lua, Talents.lua —
painel de raide e de talento eram de TBC (419 linhas) - o ramo dual-client do Compat.lua, e o mecanismo de guia-morto do
Guide.lua: guia sem conteúdo agora não é arquivo, não é lista escondida - avisos de montaria: os níveis do Forever não são públicos, e chutar é
pior que calar
Os 174 guias que sobrevivem FICAM. São rota vanilla, que é conteúdo válido
do Forever, e apagá-los antes de existir substituto deixaria o addon sem
nada. A troca por guias gerados do Forever é trabalho separado.
Deletar os 106 arquivos deixou 6 ponteirosnextpendurados, o que
DEGRADARIA o encadeamento: antes o guia morto ainda carregava e a cadeia
pulava através dele; com o arquivo fora, ela terminaria ali. Os 6 foram
religados no primeiro guia vivo da cadeia, e NextGuideKey agora encerra de
propósito em ponteiro pendurado em vez de estourar.
EntraC_Secrets.ShouldUnitIdentityBeSecretcomo pré-teste de identidade
(ns.UnitNpc). Na prática este cliente devolve id e nome de NPC limpos — o
que é secreto é estado de combate — mas a doc gerada marca UnitGUID e
UnitName com predicado condicional, então perguntamos antes.
tools/fetch_forever.py sai. A ToU da Fanbyte proíbe baixar conteúdo por
qualquer mecanismo que não seja navegador, e o robots.txt da Wowhead
bloqueia coletor automático por nome. Não dá pra semear dado aberto com
aquilo, e o valor era marginal: a Wowhead tem 1 quest em Riverglades e 0
em Shen'dralas.
Correções de fato: build corrente é 69913 (não 69893); Darkspear Islands é
Battleground 15v15, não zona de quest; a contagem de quests novas passa a
declarar baseline (2.844 ids >= 30000, ou 1.795 contra o Classic Era) — a
figura "2.824" não era reproduzível.
tools/forever-guides.lua reescrito para um cliente só: 22 checks passando
contra os arquivos de verdade, incluindo o encadeamento com ponteiro
pendurado e o pré-teste de Secret Values.
BREAKING CHANGE: o addon não carrega mais no TBC Anniversary.
Closes #5
- 106 guias cujo conteúdo aquele cliente não tem (Outland, Quel'Thalas,
- feat(forever): collect the quests this client is the only one that knows
The new Forever content is server-side. The DB2 tables carry quest ids and
almost no POIs (54 blobs), Questie has no Forever quest data yet, and Wowhead
knows 441 of the 2,824 ids — zero of them in Riverglades, Zephras Isle,
Darkspear Islands or Shen'dralas. So the data comes from two places.- tools/fetch_forever.py pulls Wowhead. The whole index costs ~70 requests
(?filter=minle=N;maxle=N); each quest page carries level, side, zone and the
start/end/objective points with NPC ids and coordinates. The site refuses bulk
collection (403 after ~130 pages at 1/s), so 403 and 429 mean stop, requests
are 4s apart and only ids the index knows are fetched. Everything is cached. - ForeverScan.lua collects from the client itself, which is the only source for
the new zones. /ls scan asks the server id by id (RequestLoadQuestByID); while
you play it records who gives and who takes each quest with NPC id, map and
coordinate, the objectives, and the waypoint the server itself points at. It
writes LodestarDB.scan and does nothing on Anniversary, where this is known. - tools/import_forever.py merges both with the Questie base into build/forever/,
dropping what Forever does not have. The router reads it unchanged: Ashenvale
comes out with 68 routed quests, 27 of them new; Feralas 71 with 27 new.
No guide file changed yet: how a zone's two variants coexist is still open.
tools/forever-scan.lua runs the collector under both clients stubbed (17 checks,
four hand mutants killed) and caught a real one:local x, y = p.GetXY and p:GetXY()silently drops y, so every coordinate would have been recorded nil.
Closes #3
- tools/fetch_forever.py pulls Wowhead. The whole index costs ~70 requests
- feat(forever): run on WoW: Forever, with the content that client does not have
The beta (Project Camelot, build 1.60.1.69893) runs the retail interface over
vanilla content. Its branch and project name come from the client's own crash
reports, so the TOC declares 20506, 16001.
Nothing in the executable that Lodestar calls is gone — what breaks is content:- Compat.lua reads the client once (interface number; Forever has no project id
of its own) and holds Secret Values, GUID reading and the tooltip hook, which
is TooltipDataProcessor there and OnTooltipSetUnit here. - ForeverData.lua, generated from the QuestV2 diff of the two builds: 106 guides
whose content that client lost (Outland, Quel'Thalas, the blood elf and draenei
starting zones) and 380 quests removed inside routes that still hold. Such a
guide leaves the library, the autopilot, the chain and the raid panel. - A step goes whole, not just its quest goal. A step is what it serves: dropping
only the accept out of "talk to the NPC / take the quest / walk to the spot"
would leave a talk with no coordinate that never completes, and the automatic
advance would stop right there — which is what this exists to prevent. It
stays only when something that completes on its own is left (a ding, a collect
with its own count, a goto). Across the 280 guides that removes 8.5% of the
steps and leaves zero dead ends on either client; a guide left with no steps
says so instead of opening an empty tab. - The raw step array — where Prereq harvests chains for OTHER guides — is never
mutated: a step that changes is copied. Without that, injection would depend on
the order guides were opened, and step index and ticked goal are saved by name. - Max level comes from the client, mount toasts stay on Anniversary (nobody knows
Forever's levels yet) and the talent panel keeps quiet there. - ChehulNet skips a secret GUID, verbatim with the other Chehul addons.
On Anniversary nothing changes: both lists are off and the routes are the same.
tools/forever-guides.lua proves it under both clients stubbed (26 checks, six
hand mutants killed); tools/gen_forever.py regenerates the data for a new build.
Numbers and what is still open: docs/forever.md.
Closes #1
- Compat.lua reads the client once (interface number; Forever has no project id
- Squad: capture questID from any goal in the PartyLens quest-group context
The elite/boss goal often lacks goal.q.id (it's on the pickup/turn-in goal), so
questID arrived nil and PartyLens fell back to the goal text as the title. Capture
the first goal.q.id in the step (like CurrentObjective does) so PartyLens resolves
the real quest name. - Squad: pass questID in the PartyLens quest-group context
Include the active elite/raid goal's questID so PartyLens can resolve the real
quest title and select the quest in its activity picker.