Skip to content

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 02:50
· 117 commits to main since this release

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. O amount decodificado 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 & 3 de 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.
  • 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, e HaveQuestData é 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:
    • faction via GetQuestFactionGroup (não existe API de facção exigida; este
      global legado é a única fonte)
    • uiMap via GetQuestUiMapID
    • repeatable, waypointText, e level do 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 == false no 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
    TOC Camelot) 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 ponteiros next pendurados, 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.
      Entra C_Secrets.ShouldUnitIdentityBeSecret como 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
  • 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
  • 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
  • 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.