Commit graph

916 commits

Author SHA1 Message Date
Kelsi
a3279ea1ad fix: async Warden PAGE_A/PAGE_B checks to prevent main-loop stalls
Move 5-second brute-force HMAC-SHA1 code pattern searches to a
background thread via std::async. The main loop now detects PAGE_A/B
checks, launches the response builder async, and drains the result
in update() — encrypting and sending on the main thread to keep
wardenCrypto_ RC4 state thread-safe.

Also adds Turtle WoW PE binary support (isTurtle flag, dedicated exe
search, runtime patches), searchCodePattern with result caching,
writeLE32 public API, and Warden scan entry verification.
2026-03-16 16:46:29 -07:00
Kelsi
f0a515ff9c fix: stabilize classic/turtle world session handling
Some checks failed
Build / Build (arm64) (push) Has been cancelled
Build / Build (x86-64) (push) Has been cancelled
Build / Build (macOS arm64) (push) Has been cancelled
Build / Build (windows-arm64) (push) Has been cancelled
Build / Build (windows-x86-64) (push) Has been cancelled
Security / CodeQL (C/C++) (push) Has been cancelled
Security / Semgrep (push) Has been cancelled
Security / Sanitizer Build (ASan/UBSan) (push) Has been cancelled
2026-03-15 06:13:36 -07:00
Kelsi
6ede9a2968 refactor: derive turtle opcodes from classic 2026-03-15 02:55:05 -07:00
Kelsi
0b6265bc55 fix: align turtle protocol compatibility 2026-03-15 01:47:36 -07:00
Kelsi
b0fafe5efa fix: stabilize turtle world entry session handling 2026-03-15 01:21:23 -07:00
Kelsi
eea3784976 fix: harden turtle movement parsing and warden fallback 2026-03-14 22:18:28 -07:00
Kelsi
075b4c1772 fix(gameplay): tighten TB elevator bounds and reset stale combat visuals
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
2026-03-14 09:19:16 -07:00
Kelsi
2c32b72f95 feat(ui): show keyring in inventory 2026-03-14 08:42:25 -07:00
Kelsi
800862c50a fix(ui): cache ghost opacity updates to state changes 2026-03-14 08:31:08 -07:00
Kelsi
cebca9a882 fix(gameplay): stabilize run animation and clean ghost/death visuals 2026-03-14 08:27:32 -07:00
Kelsi
9cd52c4dd7 fix(loot): gate auto-loot sends per loot session 2026-03-14 07:31:15 -07:00
Kelsi
c1baffadf0 fix(input): release mouse on stalls and clean quest keybind duplication 2026-03-14 07:29:39 -07:00
Kelsi
5fa5020af5 fix(mail): use attachment item guid for WotLK take item 2026-03-14 07:11:18 -07:00
Kelsi
5b195781ad fix(death): restore corpse reclaim and enforce ghost grayscale 2026-03-14 06:43:49 -07:00
Kelsi
6cfb439fd6 fix(vulkan): defer resource frees until frame fence 2026-03-14 03:32:31 -07:00
Kelsi
64483a31d5 fix(combattext): show power drain separately from damage 2026-03-13 23:56:44 -07:00
Kelsi
57265bfa4f fix(combattext): render evade results explicitly 2026-03-13 23:32:57 -07:00
Kelsi
3f1083e9b5 fix(combatlog): consume reflect payload in spell-go miss entries 2026-03-13 23:15:56 -07:00
Kelsi
77d53baa09 fix(combattext): render deflect and reflect miss events 2026-03-13 23:08:49 -07:00
Kelsi
3ef5b546fb fix(combatlog): render instakill events explicitly 2026-03-13 22:22:00 -07:00
Kelsi
91dc45d19e fix(combatlog): dedupe duplicate spellsteal aura logs 2026-03-13 20:23:24 -07:00
Kelsi
c45951b368 fix(combatlog): distinguish spellsteal from dispel 2026-03-13 19:58:37 -07:00
Kelsi
e51b215f85 feat: add DISPEL and INTERRUPT combat log entries for dispel/spellsteal/interrupt events
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
2026-03-13 12:03:07 -07:00
Kelsi
d40e8f1618 fix: combat log uses actual attacker/victim GUIDs instead of current target
addCombatText now accepts optional srcGuid/dstGuid parameters. When
provided, the persistent combat log resolves names from the actual
packet GUIDs rather than always falling back to playerGuid/targetGuid.

Updated handleAttackerStateUpdate, handleSpellDamageLog,
handleSpellHealLog, and SMSG_PERIODICAURALOG to pass data.attackerGuid
/ data.targetGuid (or casterGuid/victimGuid), so the combat log
correctly records the attacker name when being hit by enemies the
player has not selected as their current target.

All 48 existing call sites use the 0/0 default and are unaffected.
2026-03-13 11:48:42 -07:00
Kelsi
ef7494700e feat: parse and display Heroic/Unique/Unique-Equipped item flags in tooltips 2026-03-13 11:32:32 -07:00
Kelsi
03f8642fad feat: parse and display elemental resistances and race restrictions in item tooltips
- Store holyRes/fireRes/natureRes/frostRes/shadowRes/arcaneRes in ItemQueryResponseData
- Parse resistance fields in WotLK, TBC, and Classic parsers (previously discarded)
- Display non-zero resistances (e.g. "+40 Fire Resistance") in both tooltip paths
- Add getPlayerRace() accessor to GameHandler
- Show race restriction line (e.g. "Races: Blood Elf, Draenei") in both tooltip paths,
  highlighted red when player's race is not allowed
- Useful for fire/nature/frost resist gear (Onyxia, AQ40, Naxx encounters)
2026-03-13 11:23:55 -07:00
Kelsi
b0b47c354a feat: parse and display item skill/reputation requirements in tooltips
- Store requiredSkill, requiredSkillRank, allowableClass, allowableRace,
  requiredReputationFaction, and requiredReputationRank from
  SMSG_ITEM_QUERY_SINGLE_RESPONSE in ItemQueryResponseData (was discarded)
- Show "Requires <Skill> (<rank>)" in item tooltip, highlighted red when
  the player doesn't have sufficient skill level
- Show "Requires <Rank> with <Faction>" for reputation-gated items
- Skill names resolved from SkillLine.dbc; faction names from Faction.dbc
- Also fix loot window tooltip suppressing items with names starting with 'I'
2026-03-13 11:11:33 -07:00
Kelsi
a6c4f6d2e9 feat: show effective skill value with bonus indicator in skills panel
Read the third update field (bonusTemp/bonusPerm) for each skill slot so the
skills tab displays the actual buffed value rather than just the base value.
Skills buffed by food/potions/items now show "value / max (+N)" with a cyan
name, and maxed-out skills show a gold bar and name for quick identification.
2026-03-13 10:58:05 -07:00
Kelsi
bbbc4efced feat: add Heirloom and Artifact item quality tiers with light gold color
Extends ItemQuality enum with ARTIFACT (6) and HEIRLOOM (7) to match
WotLK 3.3.5a quality values, with light gold color (e6cc80) and
display name support in inventory UI and tooltips.
2026-03-13 10:22:34 -07:00
Kelsi
cc24597983 feat: show hearthstone bind zone name in tooltip instead of continent 2026-03-13 10:18:31 -07:00
Kelsi
b03c326bcd feat: show logout countdown overlay with cancel button 2026-03-13 10:13:54 -07:00
Kelsi
792d8e1cf5 feat: show estimated BG wait time in queue indicator 2026-03-13 10:10:04 -07:00
Kelsi
727dfa5c6c feat: integrate lightning system for storm weather and heavy rain
The lightning system (lightning.hpp/cpp) was fully implemented but never
wired into the renderer. Connect it now:
- Enable lightning during server storm weather (wType==3, intensity>0.1)
  and heavy rain (wType==1, intensity>0.7) as a bonus visual
- Scale lightning intensity proportionally to weather intensity
- Render in both parallel (SEC_POST) and fallback rendering paths
- Update and shutdown alongside the weather system
- Show active lightning info in the performance HUD weather section
2026-03-13 09:52:23 -07:00
Kelsi
d58c2f4269 feat: show taxi flight destination indicator below minimap
Stores the destination node name when activateTaxi() is called and
displays a "✈ → <Destination>" indicator in the minimap indicator
stack while isOnTaxiFlight() is true. Falls back to "✈ In Flight"
when the destination name is unavailable.
2026-03-13 09:44:27 -07:00
Kelsi
f5a834b543 feat: add /clear chat command and movement speed display in stats
- /clear slash command empties the chat history (was listed in
  autocomplete but never handled)
- Stats panel shows run/flight/swim speed as percentage of base only
  when non-default (e.g. mounted or speed-buffed), under a new
  Movement section
2026-03-13 09:38:39 -07:00
Kelsi
2b79f9d121 feat: add spell power and healing bonus to WotLK character stats
Tracks PLAYER_FIELD_MOD_DAMAGE_DONE_POS (7 schools at field 1171) and
PLAYER_FIELD_MOD_HEALING_DONE_POS (field 1192) from server update fields.

getSpellPower() returns the max damage bonus across magic schools 1-6.
getHealingPower() returns the raw healing bonus.

Both values displayed in the character screen Combat section alongside
the previously added attack power, dodge, parry, crit, and rating fields.
2026-03-13 08:37:55 -07:00
Kelsi
c0ffca68f2 feat: track and display WotLK server-authoritative combat stats
Adds update field tracking for WotLK secondary combat statistics:
- UNIT_FIELD_ATTACK_POWER / RANGED_ATTACK_POWER (fields 123, 126)
- PLAYER_DODGE/PARRY/BLOCK/CRIT_PERCENTAGE (fields 1025-1029)
- PLAYER_RANGED_CRIT_PERCENTAGE, PLAYER_SPELL_CRIT_PERCENTAGE1 (1030, 1032)
- PLAYER_FIELD_COMBAT_RATING_1 (25 slots at 1231, hit/expertise/haste/etc.)

Both CREATE_OBJECT and VALUES update paths now populate these fields.
The Character screen Stats tab shows them when received from the server,
with graceful fallback when not available (Classic/TBC expansions).

Field indices verified against AzerothCore 3.3.5a UpdateFields.h.
2026-03-13 08:35:18 -07:00
Kelsi
ea7b276125 refactor: use gameHandler.getMapName in instance lockout window
Replaces the static local Map.dbc cache in renderInstanceLockoutsWindow()
with the existing GameHandler::getMapName() accessor, eliminating duplicate
DBC loading. Moves getMapName declaration to public interface.
2026-03-13 08:23:43 -07:00
Kelsi
75139aca77 feat: display LFG dungeon name in DungeonFinder UI status banner
Extend the LFGDungeons.dbc name lookup to the Dungeon Finder window UI:
- Queued state: "In queue for Culling of Stratholme (1:23)"
- Proposal state: "Group found for Halls of Lightning!"
- InDungeon state: "In dungeon (Utgarde Pinnacle)"
- FinishedDungeon state: "Culling of Stratholme complete"
- Proposal accept banner: "A group has been found for <dungeon>!"
All states fall back gracefully when DBC name is unavailable.
2026-03-13 08:16:59 -07:00
Kelsi
ed02f5872a feat: show LFG dungeon name in Dungeon Finder queue messages
Add LFGDungeons.dbc cache (loadLfgDungeonDbc / getLfgDungeonName) and
use it to enrich three LFG chat messages in WotLK:
- handleLfgJoinResult: "Joined the queue for Culling of Stratholme."
- handleLfgProposalUpdate case 1: "Group found for Halls of Lightning!"
- handleLfgProposalUpdate case 2: "A group has been found for ... Accept or decline."
Falls back to generic text when DBC is unavailable or dungeon ID unknown.
2026-03-13 08:14:47 -07:00
Kelsi
2c72d8462d feat: add map name lookups and improve instance/RAF/misc feedback
- Add getMapName() helper backed by Map.dbc (parallel to getAreaName)
- SMSG_RAID_INSTANCE_MESSAGE: show dungeon name instead of raw map ID
- SMSG_INSTANCE_RESET: show dungeon name instead of raw map ID
- SMSG_INSTANCE_RESET_FAILED: show dungeon name instead of raw map ID
- SMSG_EQUIPMENT_SET_SAVED: show "Equipment set saved." confirmation
- SMSG_PROPOSE_LEVEL_GRANT: show mentor name offering a level grant (RAF)
- SMSG_REFER_A_FRIEND_EXPIRED: show link-expired message
- SMSG_REFER_A_FRIEND_FAILURE: show reason-mapped error message
- SMSG_REPORT_PVP_AFK_RESULT: show success/failure feedback
- SMSG_QUEST_CONFIRM_ACCEPT: add playerNameCache fallback for sharer name
2026-03-13 07:10:10 -07:00
Kelsi
4507a223cc feat: color-code ENERGIZE combat text by power type
Mana (0)=blue, Rage (1)=red, Focus (2)=orange, Energy (3)=yellow,
Runic Power (6)=teal. Previously all energize events showed as blue
regardless of resource type, making it impossible to distinguish
e.g. a Warrior's Rage generation from a Mage's Mana return.

Power type is now captured from SMSG_SPELLENERGIZELOG (uint8) and
SMSG_PERIODICAURALOG OBS_MOD_POWER/PERIODIC_ENERGIZE (uint32 cast
to uint8) and stored in CombatTextEntry::powerType.
2026-03-13 06:08:21 -07:00
Kelsi
2c6902d27d fix: mining nodes no longer report invalid target and now open loot after gather
Two bugs fixed:
1. Retry logic (for Classic) re-sent CMSG_GAMEOBJ_USE at 0.15s while the
   gather cast was in-flight, causing SPELL_FAILED_BAD_TARGETS. Now clears
   pendingGameObjectLootRetries_ as soon as SMSG_SPELL_START shows the player
   started a cast (gather accepted).

2. CMSG_LOOT was sent immediately before the gather cast completed, then
   never sent again — so the loot window never opened. Now tracks the last
   interacted GO and sends CMSG_LOOT in handleSpellGo once the gather spell
   completes, matching how the real client behaves.
2026-03-13 04:37:36 -07:00
Kelsi
4272491d56 feat: send CMSG_SET_ACTION_BUTTON to server when action bar slot changes
Action bar changes (dragging spells/items) were only saved locally.
Now notifies the server via CMSG_SET_ACTION_BUTTON so the layout
persists across relogs. Supports Classic (5-byte) and TBC/WotLK
(packed uint32) wire formats.
2026-03-13 04:25:05 -07:00
Kelsi
499638142e feat: make quest tracker movable, resizable, and right-edge-anchored
- Remove NoDecoration flag to allow ImGui drag/resize
- Store questTrackerRightOffset_ instead of absolute X so tracker
  stays pinned to the right edge when the window is resized
- Persist position (right offset + Y) and size in settings.cfg
- Clamp to screen bounds after drag
2026-03-13 04:04:29 -07:00
Kelsi
85767187b1 fix: clear gameObjectDisplayIdWmoCache_ on world transition, add stale-entry guard
gameObjectDisplayIdWmoCache_ was not cleared on world unload/transition,
causing stale WMO model IDs (e.g. 40006, 40003) to be looked up after
the renderer cleared its model list, resulting in "Cannot create instance
of unloaded WMO model" errors on zone re-entry.

Changes:
- Clear gameObjectDisplayIdWmoCache_ alongside other GO caches on world reset
- Add WMORenderer::isModelLoaded() for cache-hit validation
- Inline GO WMO path now verifies cached model is still renderer-resident
  before using it; evicts stale entries and falls back to reload
2026-03-13 03:43:55 -07:00
Kelsi
ebd9cf5542 fix: handle MSG_MOVE_SET_*_SPEED opcodes to suppress unhandled opcode warnings 2026-03-13 03:13:29 -07:00
Kelsi
f855327054 fix: eliminate 490ms transport-doodad stall and GPU device-loss crash
Three root causes identified from wowee.log crash at frame 134368:

1. processPendingTransportDoodads() was doing N separate synchronous
   GPU uploads (vkQueueSubmit + vkWaitForFences per texture per doodad).
   With 30+ doodads × multiple textures, this caused the 489ms stall in
   the 'gameobject/transport queues' update stage. Fixed by wrapping the
   entire batch in beginUploadBatch()/endUploadBatch() so all texture
   layout transitions are submitted in a single async command buffer.

2. Game objects whose M2 model has no geometry/particles (empty or
   unsupported format) were retried every frame because loadModel()
   returns false without adding to gameObjectDisplayIdModelCache_.
   Added gameObjectDisplayIdFailedCache_ to permanently skip these
   display IDs after the first failure, stopping the per-frame spam.

3. renderM2Ribbons() only checked ribbonPipeline_ != null, not
   ribbonAdditivePipeline_. If additive pipeline creation failed, any
   ribbon with additive blending would call vkCmdBindPipeline with
   VK_NULL_HANDLE, causing VK_ERROR_DEVICE_LOST on the GPU side.
   Extended the early-return guard to cover both ribbon pipelines.
2026-03-13 01:45:31 -07:00
Kelsi
1108aa9ae6 feat: implement M2 ribbon emitter rendering for spell trail effects
Parse M2RibbonEmitter data (WotLK format) from M2 files — bone index,
position, color/alpha/height tracks, edgesPerSecond, edgeLifetime,
gravity. Add CPU-side trail simulation per instance (edge birth at bone
world position, lifetime expiry, gravity droop). New m2_ribbon.vert/frag
shaders render a triangle-strip quad per emitter using the existing
particleTexLayout_ descriptor set. Supports both alpha-blend and additive
pipeline variants based on material blend mode. Fixes invisible spell
trail effects (~5-10%% of spell visuals) that were silently skipped.
2026-03-13 01:17:30 -07:00
Kelsi
022d387d95 fix: correct corpse retrieval coordinate mismatch and detect corpse objects
- canReclaimCorpse() and getCorpseDistance() compared canonical movementInfo
  (x=north=server_y, y=west=server_x) against raw server corpseX_/Y_ causing
  the proximity check to always report wrong distance even when standing on corpse
- Fix: use corpseY_ for canonical north and corpseX_ for canonical west
- Also detect OBJECT_TYPE_CORPSE update blocks owned by the player to set
  corpse coordinates at login-as-ghost (before SMSG_DEATH_RELEASE_LOC arrives)
2026-03-13 00:59:43 -07:00