Commit graph

2656 commits

Author SHA1 Message Date
Kelsi
6343ceb151 refactor: extract updateTimers() from GameHandler::update()
Move 164 lines of timer/pending-state logic into updateTimers():
auction delay, quest accept timeouts, money delta, GO loot retries,
name query resync, loot money notifications, auto-inspect throttling.
update() is now ~430 lines (down from original 704).
2026-03-25 15:23:31 -07:00
Kelsi
7066062136 refactor: extract updateNetworking() from GameHandler::update()
Move socket update, packet processing, Warden async drain, RX silence
detection, disconnect handling, and Warden gate logging into a separate
updateNetworking() method. Reduces update() from ~704 to ~591 lines.
2026-03-25 15:19:03 -07:00
Kelsi
b2e2ad12c6 refactor: add registerWorldHandler() for state-guarded dispatch entries
Add registerWorldHandler() that wraps handler calls with an IN_WORLD
state check. Replaces 8 state-guarded lambda dispatch entries with
concise one-line registrations.
2026-03-25 15:11:15 -07:00
Kelsi
6694a0aa66 refactor: add registerHandler() to replace 120 lambda dispatch wrappers
Add registerHandler() using member function pointers, replacing 120
single-line lambda dispatch entries of the form
[this](Packet& p) { handleFoo(p); } with concise
registerHandler(Opcode::X, &GameHandler::handleFoo) calls.
2026-03-25 15:08:22 -07:00
Kelsi
d73c84d98d refactor: convert remaining 6 skipAll lambdas to registerSkipHandler
Replace all remaining inline skipAll dispatch lambdas with
registerSkipHandler() calls, including 2 standalone entries and
3 for-loop groups covering ~96 opcodes total.
2026-03-25 14:58:34 -07:00
Kelsi
5fe12f3f62 refactor: deduplicate 4 NPC window distance checks in update()
Replace 4 identical 10-line NPC distance check blocks (vendor, gossip,
taxi, trainer) with a shared lambda, reducing 40 lines to 16.
2026-03-25 14:53:16 -07:00
Kelsi
313a1877d5 refactor: add registerSkipHandler/registerErrorHandler for dispatch table
Add helpers for common dispatch table patterns: registerSkipHandler()
for opcodes that just discard data (14 sites), registerErrorHandler()
for opcodes that show an error message (3 sites). Reduces boilerplate
in registerOpcodeHandlers().
2026-03-25 14:50:18 -07:00
Kelsi
12355316b3 refactor: add Packet::hasData(), replace 52 position checks and 14 more Lua guards
Add Packet::hasData() for 'has remaining data' checks, replacing 52
verbose getReadPos()<getSize() comparisons across 3 files. Also replace
14 more standalone Lua return patterns with luaReturnNil/Zero helpers.
2026-03-25 14:39:01 -07:00
Kelsi
4c26b1a8ae refactor: add Lua return helpers to replace 178 inline guard patterns
Add luaReturnNil/luaReturnZero/luaReturnFalse helpers and replace 178
braced guard returns (109 nil, 31 zero, 38 false) in lua_engine.cpp.
Reduces visual noise in Lua binding functions.
2026-03-25 14:33:57 -07:00
Kelsi
0d9aac2656 refactor: add Packet::skipAll() to replace 186 setReadPos(getSize()) calls
Add skipAll() convenience method and replace 186 instances of the
verbose 'discard remaining packet data' idiom across game_handler
and world_packets.
2026-03-25 14:27:26 -07:00
Kelsi
4309c8c69b refactor: add isPreWotlk() helper to replace 24 compound expansion checks
Extract isPreWotlk() = isClassicLikeExpansion() || isActiveExpansion("tbc")
to replace 24 instances of the repeated compound check across packet
handlers. Clarifies intent: these code paths handle pre-WotLK packet
format differences.
2026-03-25 14:24:03 -07:00
Kelsi
e4194b1fc0 refactor: add isInWorld() and replace 119 inline state+socket checks
Add GameHandler::isInWorld() helper that encapsulates the repeated
'state == IN_WORLD && socket' guard. Replace 99 negative checks and
20 positive checks across game_handler.cpp, plus fix 2 remaining
C-style casts.
2026-03-25 14:21:19 -07:00
Kelsi
56f8f5c592 refactor: extract loadWeaponM2() to deduplicate weapon model loading
Extract shared M2+skin loading logic into Application::loadWeaponM2(),
replacing duplicate 15-line blocks in loadEquippedWeapons() and
tryAttachCreatureVirtualWeapons(). Future weapon loading changes only
need to update one place.
2026-03-25 14:17:19 -07:00
Kelsi
43caf7b5e6 refactor: add Packet::writePackedGuid, remove redundant static methods
Add writePackedGuid() to Packet class for read/write symmetry. Remove
now-redundant UpdateObjectParser::readPackedGuid and
MovementPacket::writePackedGuid static methods. Replace 6 internal
readPackedGuid calls, 9 writePackedGuid calls, and 1 inline 14-line
transport GUID write with Packet method calls.
2026-03-25 14:06:42 -07:00
Kelsi
2c79d82446 refactor: add Packet::readPackedGuid() and replace 121 static method calls
Move packed GUID reading into Packet class alongside readUInt8/readFloat.
Replace 121 UpdateObjectParser::readPackedGuid(packet) calls with
packet.readPackedGuid() across 4 files, reducing coupling between
Packet and UpdateObjectParser.
2026-03-25 13:58:48 -07:00
Kelsi
3f54d8bcb8 refactor: replace 37 reinterpret_cast writeBytes with writeFloat
Replace 37 verbose reinterpret_cast<const uint8_t*> float writes with
the existing Packet::writeFloat() method across world_packets,
packet_parsers_classic, and packet_parsers_tbc.
2026-03-25 13:54:10 -07:00
Kelsi
58839e611e chore: remove 3 unused includes from game_screen.cpp
Remove character_preview.hpp, spawn_presets.hpp, and blp_loader.hpp
which are included but not used in game_screen.cpp.
2026-03-25 13:50:22 -07:00
Kelsi
0f19ed40f8 refactor: convert 15 more renderer+sound patterns to withSoundManager
Replace 15 additional 3-line renderer acquisition + sound manager
null-check blocks with single-line withSoundManager() calls. Total
22 sites now use the helper; 11 remaining have complex multi-line
bodies or non-sound renderer usage.
2026-03-25 13:45:05 -07:00
Kelsi
ea15740e17 refactor: add withSoundManager() template to reduce renderer boilerplate
Add GameHandler::withSoundManager() that encapsulates the repeated
getInstance()->getRenderer()->getSoundManager() null-check chain.
Replace 6 call sites, with helper available for future consolidation
of remaining 25 sites.
2026-03-25 13:35:29 -07:00
Kelsi
a0267e6e95 refactor: consolidate 26 playerNameCache.find() calls to use lookupName()
Replace 26 direct playerNameCache lookups with the existing lookupName()
helper, which also provides entity-name fallback. Eliminates duplicate
cache+entity lookup patterns in chat, social, loot, and combat handlers.
Simplifies getCachedPlayerName() to delegate to lookupName().
2026-03-25 13:29:10 -07:00
Kelsi
f02fa10126 refactor: make DBC name caches mutable to eliminate 13 const_cast hacks
Mark spellNameCache_, titleNameCache_, factionNameCache_, areaNameCache_,
mapNameCache_, lfgDungeonNameCache_ and their loaded flags as mutable.
Update 6 lazy-load methods to const. Removes all 13 const_cast<GameHandler*>
calls, allowing const getters to lazily populate caches without UB.
2026-03-25 13:21:02 -07:00
Kelsi
fe043b5da8 refactor: extract getUnitByGuid() to replace 10 entity lookup + dynamic_cast patterns
Add GameHandler::getUnitByGuid() that combines entityManager.getEntity()
with dynamic_cast<Unit*>. Replaces 10 two-line lookup+cast blocks with
single-line calls.
2026-03-25 13:12:51 -07:00
Kelsi
c8617d20c8 refactor: use getSpellName/getSpellSchoolMask helpers instead of raw cache access
Replace 8 direct spellNameCache_.find() patterns with existing helper
methods: getSpellName() for name lookups, getSpellSchoolMask() for
school mask checks. Eliminates redundant loadSpellNameCache() calls
and 3-line cache lookup boilerplate at each site.
2026-03-25 13:08:10 -07:00
Kelsi
03aa915a05 refactor: move packetHasRemaining into Packet::hasRemaining method
Add Packet::hasRemaining(size_t) and remove free function from
game_handler.cpp. Replaces 8 call sites with method calls.
2026-03-25 13:02:49 -07:00
Kelsi
25d1a7742d refactor: add renderCoinsFromCopper() to eliminate copper decomposition boilerplate
Add renderCoinsFromCopper(uint64_t) overload in ui_colors.hpp that
decomposes copper into gold/silver/copper and renders. Replace 14
manual 3-line decomposition blocks across game_screen and
inventory_screen with single-line calls.
2026-03-25 12:59:31 -07:00
Kelsi
f39271453b refactor: extract applyAudioVolumes() to deduplicate 30-line audio settings block
Extract identical 30-line audio volume application block into
GameScreen::applyAudioVolumes(), replacing two copies (startup init
and settings dialog lambda) with single-line calls.
2026-03-25 12:52:07 -07:00
Kelsi
40dd39feed refactor: move hasFullPackedGuid into Packet class, deduplicate 2 definitions
Add Packet::hasFullPackedGuid() method and remove identical standalone
definitions from game_handler.cpp and packet_parsers_classic.cpp.
Replace 53 free-function calls with method calls.
2026-03-25 12:46:44 -07:00
Kelsi
376d0a0f77 refactor: add Packet::getRemainingSize() to replace 656 arithmetic expressions
Add getRemainingSize() one-liner to Packet class and replace all 656
instances of getSize()-getReadPos() across game_handler, world_packets,
and both packet parser files.
2026-03-25 12:42:56 -07:00
Kelsi
b66033c6d8 fix: toLowerInPlace infinite recursion + remove redundant callback guards
Fix toLowerInPlace() which was accidentally self-recursive (would stack
overflow on any Lua string lowering). Remove 30 redundant
if(addonEventCallback_) wrappers around pure fireAddonEvent blocks.
Extract color constants in performance_hud.cpp (24 inline literals).
2026-03-25 12:37:29 -07:00
Kelsi
b892dca0e5 refactor: replace 60+ inline color literals with shared ui::colors constants
Use kRed, kBrightGreen, kDarkGray, kLightGray from ui_colors.hpp across
8 UI files, eliminating duplicate ImVec4 color definitions throughout
the UI layer.
2026-03-25 12:29:44 -07:00
Kelsi
4d46641ac2 refactor: consolidate UI colors, quality colors, and renderCoinsText
Create shared include/ui/ui_colors.hpp with common ImGui color constants,
item quality color lookup, and renderCoinsText utility. Remove 3 duplicate
renderCoinsText implementations and 3 duplicate quality color switch
blocks across game_screen, inventory_screen, and quest_log_screen.
2026-03-25 12:27:43 -07:00
Kelsi
eea205ffc9 refactor: extract toHexString utility, more color constants, final cast cleanup
Add core::toHexString() utility in logger.hpp to replace 11 duplicate
hex-dump loops across world_packets, world_socket, and game_handler.
Add kColorBrightGreen/kColorDarkGray constants in game_screen.cpp
replacing 26 inline literals. Replace remaining ~37 C-style casts in
16 files. Normalize keybinding_manager.hpp to #pragma once.
2026-03-25 12:12:03 -07:00
Kelsi
ba99d505dd refactor: remaining C-style casts, color constants, and header guard cleanup
Replace ~37 remaining C-style casts with static_cast across 16 files.
Extract named color constants (kColorRed/Green/Yellow/Gray) and dialog
window flags (kDialogFlags) in game_screen.cpp, replacing 72 inline
literals. Normalize keybinding_manager.hpp to #pragma once.
2026-03-25 11:57:22 -07:00
Kelsi
05f2bedf88 refactor: replace C-style casts with static_cast and extract toLowerInPlace
Replace ~300 C-style casts ((int), (float), (uint32_t), etc.) with
static_cast across 15 source files. Extract toLowerInPlace() helper in
lua_engine.cpp to replace 72 identical tolower loop patterns.
2026-03-25 11:40:49 -07:00
Kelsi
d646a0451d refactor: add fireAddonEvent() helper to eliminate 170+ null checks
Add inline fireAddonEvent() that wraps the addonEventCallback_ null
check. Replace ~120 direct addonEventCallback_ calls with fireAddonEvent,
eliminating redundant null checks at each callsite and reducing
boilerplate by ~30 lines.
2026-03-25 11:34:22 -07:00
Kelsi
98b9e502c5 refactor: extract guidToUnitId/getQuestTitle helpers and misc cleanup
- Extract guidToUnitId(), getQuestTitle(), findQuestLogEntry() helpers
  to replace 14 duplicated GUID-to-unitId patterns and 7 quest log
  search patterns in game_handler.cpp
- Remove duplicate #include in renderer.cpp
- Remove commented-out model cleanup code in terrain_manager.cpp
- Replace C-style casts with static_cast in auth and transport code
2026-03-25 11:25:44 -07:00
Kelsi
087e42d7a1 fix: remove 12 duplicate dispatch registrations and fix addonEventCallback null-check bugs
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
Remove duplicate opcode registrations introduced during the switch-to-dispatch-table
refactor (PR #22), keeping the better-commented second copies. Fix 4 instances where
addonEventCallback_("UNIT_QUEST_LOG_CHANGED") was either called unconditionally
(missing braces) or had incorrect indentation inside braces.
2026-03-24 23:33:00 -07:00
Paul
fa2e8ad0fe Merge commit '6bfa3dc402' into chore/split-mega-switch-to-map 2026-03-25 07:27:03 +03:00
Paul
15f12d86b3 split mega switch 2026-03-25 07:26:38 +03:00
Kelsi
6bfa3dc402 fix: suppress spell sounds and melee swing for crafting/profession spells
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
Crafting spells (bandages, smelting, etc.) were playing magic precast/
cast-complete audio and triggering melee weapon swing animations because
they have physical school mask (1). Re-add isProfessionSpell check to
skip spell sounds and melee animation for tradeskill spells. The
character still plays the generic cast animation via spellCastAnimCallback.
2026-03-24 14:33:22 -07:00
Kelsi
432da20b3e feat: enable crafting sounds and add Create All button
Remove the isProfessionSpell sound suppression so crafting spells play
precast and cast-complete audio like combat spells. Crafting was
previously silent by design but users expect audio feedback.

Add "Create All" button to the tradeskill UI that queues 999 crafts.
The server automatically stops the queue when materials run out
(SPELL_FAILED_REAGENTS cancels the craft queue). This matches the
real WoW client's behavior for batch crafting.
2026-03-24 14:22:28 -07:00
Kelsi
1dd3823013 perf: use second GPU queue for parallel texture/buffer uploads
Request 2 queues from the graphics family when available (NVIDIA
exposes 16, AMD 2+). Upload batches now submit to queue[1] while
rendering uses queue[0], enabling parallel GPU transfers without
queue-family ownership transfer barriers (same family).

Falls back to single-queue path on GPUs with only 1 queue in the
graphics family. Transfer command pool is separate to avoid contention.
2026-03-24 14:09:16 -07:00
Kelsi
ed0cb0ad25 perf: time-budget tile finalization to prevent 1+ second main-loop stalls
processReadyTiles was calling advanceFinalization with a step limit of 1
but a single step (texture upload or M2 model load) could take 1060ms.
Replace the step counter with an 8ms wall-clock time budget (16ms during
taxi) so finalization yields to the render loop before causing a visible
stall. Heavy tiles spread across multiple frames instead of blocking.
2026-03-24 13:56:20 -07:00
Kelsi
05e85d9fa7 fix: correct melee swing sound paths to match WoW MPQ layout
The melee swing clips used non-existent paths (SwordSwing, MeleeSwing)
instead of the actual WoW 3.3.5a weapon swing files: WeaponSwings/
mWooshMedium and mWooshLarge for hit swings, MissSwings/MissWhoosh
for misses. Fixes "No melee swing SFX found in assets" warning.
2026-03-24 13:46:01 -07:00
Kelsi
7a5d80e801 fix: flush GPU before first render frame after world load
Add vkDeviceWaitIdle after world loading completes to ensure all async
texture uploads and resource creation are fully flushed before the
first render frame. Mitigates intermittent NVIDIA driver crashes at
vkCmdBeginRenderPass during initial world entry.
2026-03-24 13:34:52 -07:00
Kelsi
891b9e5822 fix: show friendly map names on loading screen (Outland not Expansion01)
Add mapDisplayName() with friendly names for continents: "Eastern
Kingdoms", "Kalimdor", "Outland", "Northrend". The loading screen
previously showed WDT directory names like "Expansion01" when
Map.dbc's localized name field was empty or matched the internal name.
2026-03-24 13:20:06 -07:00
Kelsi
9a6a430768 fix: track render pass subpass mode to prevent ImGui secondary violation
When parallel recording is active, the scene pass uses
VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS. Post-processing paths
(FSR/FXAA) end the scene pass and begin a new INLINE render pass for
the swapchain output. ImGui rendering must use the correct mode —
secondary buffers for SECONDARY passes, direct calls for INLINE.

Previously the check used a static condition based on enabled features
(!fsr && !fsr2 && !fxaa && parallel), which could mismatch if a
feature was enabled but initialization failed. Replace with
endFrameInlineMode_ flag that tracks the actual current render pass
mode at runtime, eliminating the validation error
VUID-vkCmdDrawIndexed-commandBuffer-recording that caused intermittent
NVIDIA driver crashes.
2026-03-24 13:05:27 -07:00
Kelsi
a152023e5e fix: add VkSampler cache to prevent sampler exhaustion crash
Validation layers revealed 9965 VkSamplers allocated against a device
limit of 4000 — every VkTexture created its own sampler even when
configurations were identical. This exhausted NVIDIA's sampler pool
and caused intermittent SIGSEGV in vkCmdBeginRenderPass.

Add a thread-safe sampler cache in VkContext that deduplicates samplers
by FNV-1a hash of all 14 VkSamplerCreateInfo fields. All texture,
render target, renderer, water, and loading screen sampler creation
now goes through getOrCreateSampler(). Textures set ownsSampler_=false
so shared samplers aren't double-freed.

Also auto-disable anisotropy in the cache when the physical device
doesn't support the samplerAnisotropy feature, fixing the validation
error VUID-VkSamplerCreateInfo-anisotropyEnable-01070.
2026-03-24 11:44:54 -07:00
Kelsi
1556559211 fix: skip VkPipelineCache on NVIDIA to prevent driver crash
VkPipelineCache causes vkCmdBeginRenderPass to SIGSEGV inside
libnvidia-glcore.so on NVIDIA 590.x drivers. Skip pipeline cache
creation on NVIDIA GPUs — NVIDIA drivers already provide built-in
shader disk caching, so the Vulkan-level cache is redundant.
Pipeline cache still works on AMD and other vendors.
2026-03-24 10:30:25 -07:00
Kelsi Rae Davis
0a32c0fa27
Merge pull request #21 from ldmonster/chore/add-classification-to-render
refactor(rendering): extract M2 classification into pure functions
2026-03-24 10:18:24 -07:00