fix(render): code quality cleanup

Magic number elimination:
- Create protocol_constants.hpp, warden_constants.hpp,
  render_constants.hpp, ui_constants.hpp
- Replace ~55 magic numbers across game_handler, warden_handler,
  m2_renderer_render

Reduce nesting depth:
- Extract 5 parseEffect* methods from handleSpellLogExecute
  (max indent 52 → 16 cols)
- Extract resolveSpellSchool/playSpellCastSound/playSpellImpactSound
  from 3× duplicate audio blocks in handleSpellGo
- Flatten SMSG_INVENTORY_CHANGE_FAILURE with early-return guards
- Extract drawScreenEdgeVignette() for 3 duplicate vignette blocks

DRY extract patterns:
- Replace 12 compound expansion checks with isPreWotlk() across
  movement_handler (9), chat_handler (1), social_handler (1)

const to constexpr:
- Promote 23+ static const arrays/scalars to static constexpr across
  12 source files

Error handling:
- Convert PIN auth from exceptions to std::optional<PinProof>
- Add [[nodiscard]] to 15+ initialize/parse methods
- Wrap ~20 unchecked initialize() calls with LOG_WARNING/LOG_ERROR

Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
This commit is contained in:
Pavel Okhlopkov 2026-04-06 22:43:13 +03:00
parent 2e8856bacd
commit 97106bd6ae
41 changed files with 849 additions and 424 deletions

View file

@ -0,0 +1,126 @@
#pragma once
#include <cstdint>
// WoW 3.3.5a (12340) protocol constants.
// Centralised so every handler references a single source of truth.
namespace wowee {
namespace game {
// ---------------------------------------------------------------------------
// Currency
// ---------------------------------------------------------------------------
constexpr uint32_t COPPER_PER_GOLD = 10000;
constexpr uint32_t COPPER_PER_SILVER = 100;
// ---------------------------------------------------------------------------
// Unit flags (UNIT_FIELD_FLAGS — offset 46 in UnitFields)
// ---------------------------------------------------------------------------
constexpr uint32_t UNIT_FLAG_TAXI_FLIGHT = 0x00000100;
// ---------------------------------------------------------------------------
// NPC flags (UNIT_NPC_FLAGS — offset 147 in UnitFields, 3.3.5a)
// ---------------------------------------------------------------------------
constexpr uint32_t NPC_FLAG_SPIRIT_GUIDE = 0x00004000;
constexpr uint32_t NPC_FLAG_SPIRIT_HEALER = 0x00008000;
// ---------------------------------------------------------------------------
// Default action-bar spell IDs
// ---------------------------------------------------------------------------
constexpr uint32_t SPELL_ID_ATTACK = 6603;
constexpr uint32_t SPELL_ID_HEARTHSTONE = 8690;
// ---------------------------------------------------------------------------
// Class IDs
// ---------------------------------------------------------------------------
constexpr uint32_t CLASS_WARRIOR = 1;
constexpr uint32_t CLASS_PALADIN = 2;
constexpr uint32_t CLASS_HUNTER = 3;
constexpr uint32_t CLASS_ROGUE = 4;
constexpr uint32_t CLASS_PRIEST = 5;
constexpr uint32_t CLASS_DK = 6;
constexpr uint32_t CLASS_SHAMAN = 7;
constexpr uint32_t CLASS_MAGE = 8;
constexpr uint32_t CLASS_WARLOCK = 9;
constexpr uint32_t CLASS_DRUID = 11;
// ---------------------------------------------------------------------------
// Class-specific stance / form / presence spell IDs
// ---------------------------------------------------------------------------
// Warrior stances
constexpr uint32_t SPELL_BATTLE_STANCE = 2457;
constexpr uint32_t SPELL_DEFENSIVE_STANCE = 71;
constexpr uint32_t SPELL_BERSERKER_STANCE = 2458;
// Death Knight presences
constexpr uint32_t SPELL_BLOOD_PRESENCE = 48266;
constexpr uint32_t SPELL_FROST_PRESENCE = 48263;
constexpr uint32_t SPELL_UNHOLY_PRESENCE = 48265;
// Druid forms
constexpr uint32_t SPELL_BEAR_FORM = 5487;
constexpr uint32_t SPELL_DIRE_BEAR_FORM = 9634;
constexpr uint32_t SPELL_CAT_FORM = 768;
constexpr uint32_t SPELL_AQUATIC_FORM = 1066;
constexpr uint32_t SPELL_TRAVEL_FORM = 783;
constexpr uint32_t SPELL_MOONKIN_FORM = 24858;
constexpr uint32_t SPELL_FLIGHT_FORM = 33943;
constexpr uint32_t SPELL_SWIFT_FLIGHT = 40120;
constexpr uint32_t SPELL_TREE_OF_LIFE = 33891;
// Rogue
constexpr uint32_t SPELL_STEALTH = 1784;
// Priest
constexpr uint32_t SPELL_SHADOWFORM = 15473;
// ---------------------------------------------------------------------------
// Session / network timing
// ---------------------------------------------------------------------------
constexpr uint32_t SESSION_KEY_HEX_LENGTH = 40;
constexpr uint32_t RX_SILENCE_WARNING_MS = 10000; // 10 s
constexpr uint32_t RX_SILENCE_CRITICAL_MS = 15000; // 15 s
constexpr float WARDEN_GATE_LOG_INTERVAL_SEC = 30.0f;
constexpr float CLASSIC_PING_INTERVAL_SEC = 10.0f;
// ---------------------------------------------------------------------------
// Heartbeat / area-trigger intervals (seconds)
// ---------------------------------------------------------------------------
constexpr float HEARTBEAT_INTERVAL_TAXI = 0.25f;
constexpr float HEARTBEAT_INTERVAL_STATIONARY_COMBAT = 0.75f;
constexpr float HEARTBEAT_INTERVAL_MOVING_COMBAT = 0.20f;
constexpr float AREA_TRIGGER_CHECK_INTERVAL = 0.25f;
// ---------------------------------------------------------------------------
// Gameplay distance thresholds
// ---------------------------------------------------------------------------
constexpr float ENTITY_UPDATE_RADIUS = 150.0f;
constexpr float NPC_INTERACT_MAX_DISTANCE = 15.0f;
// ---------------------------------------------------------------------------
// Skill categories (from SkillLine DBC)
// ---------------------------------------------------------------------------
constexpr uint32_t SKILL_CATEGORY_PROFESSION = 11;
constexpr uint32_t SKILL_CATEGORY_SECONDARY = 9;
// ---------------------------------------------------------------------------
// DBC field-index sentinel (field lookup failure)
// ---------------------------------------------------------------------------
constexpr uint32_t DBC_FIELD_INVALID = 0xFFFFFFFF;
// ---------------------------------------------------------------------------
// Appearance byte packing
// ---------------------------------------------------------------------------
constexpr uint32_t APPEARANCE_SKIN_MASK = 0xFF;
constexpr uint32_t APPEARANCE_FACE_SHIFT = 8;
constexpr uint32_t APPEARANCE_HAIRSTYLE_SHIFT = 16;
constexpr uint32_t APPEARANCE_HAIRCOLOR_SHIFT = 24;
// ---------------------------------------------------------------------------
// Critter detection
// ---------------------------------------------------------------------------
constexpr uint32_t CRITTER_MAX_HEALTH_THRESHOLD = 100;
} // namespace game
} // namespace wowee

View file

@ -4,6 +4,7 @@
#include "game/opcode_table.hpp"
#include "game/spell_defines.hpp"
#include "game/handler_types.hpp"
#include "audio/spell_sound_manager.hpp"
#include "network/packet.hpp"
#include <array>
#include <chrono>
@ -273,6 +274,30 @@ private:
void handleChannelUpdate(network::Packet& packet);
// --- Internal helpers ---
// Resolve the magic school for a spell (for audio playback).
// Returns MagicSchool from the spell name cache, defaulting to ARCANE.
audio::SpellSoundManager::MagicSchool resolveSpellSchool(uint32_t spellId);
// Play a spell cast or impact sound via audioCoordinator, if available.
void playSpellCastSound(uint32_t spellId);
void playSpellImpactSound(uint32_t spellId);
// --- handleSpellLogExecute per-effect parsers (extracted to reduce nesting) ---
void parseEffectPowerDrain(network::Packet& packet, uint32_t effectLogCount,
uint64_t caster, uint32_t spellId, bool isPlayerCaster,
bool usesFullGuid);
void parseEffectHealthLeech(network::Packet& packet, uint32_t effectLogCount,
uint64_t caster, uint32_t spellId, bool isPlayerCaster,
bool usesFullGuid);
void parseEffectCreateItem(network::Packet& packet, uint32_t effectLogCount,
uint64_t caster, uint32_t spellId, bool isPlayerCaster);
void parseEffectInterruptCast(network::Packet& packet, uint32_t effectLogCount,
uint64_t caster, uint32_t spellId, bool isPlayerCaster,
bool usesFullGuid);
void parseEffectFeedPet(network::Packet& packet, uint32_t effectLogCount,
uint64_t caster, uint32_t spellId, bool isPlayerCaster);
// Find the on-use spell for an item (trigger=0 Use or trigger=5 NoDelay).
// CMSG_USE_ITEM requires a valid spellId or the server silently ignores it.
uint32_t findOnUseSpellId(uint32_t itemId) const;

View file

@ -0,0 +1,65 @@
#pragma once
#include <cstdint>
// Warden anti-cheat protocol constants for WoW 3.3.5a (12340).
// Server-to-Client (SMSG) and Client-to-Server (CMSG) sub-opcodes,
// memory region boundaries, check sizes, and result codes.
namespace wowee {
namespace game {
// ---------------------------------------------------------------------------
// Warden sub-opcodes (inside SMSG_WARDEN_DATA / CMSG_WARDEN_DATA)
// ---------------------------------------------------------------------------
// Server → Client
constexpr uint8_t WARDEN_SMSG_MODULE_USE = 0x00;
constexpr uint8_t WARDEN_SMSG_MODULE_CACHE = 0x01;
constexpr uint8_t WARDEN_SMSG_CHEAT_CHECKS_REQUEST = 0x02;
constexpr uint8_t WARDEN_SMSG_MODULE_INITIALIZE = 0x03;
constexpr uint8_t WARDEN_SMSG_HASH_REQUEST = 0x05;
// Client → Server
constexpr uint8_t WARDEN_CMSG_MODULE_MISSING = 0x00;
constexpr uint8_t WARDEN_CMSG_MODULE_OK = 0x01;
constexpr uint8_t WARDEN_CMSG_CHEAT_CHECKS_RESULT = 0x02;
constexpr uint8_t WARDEN_CMSG_HASH_RESULT = 0x04;
// ---------------------------------------------------------------------------
// PE section boundaries (Wow.exe 3.3.5a 12340, default base 0x400000)
// ---------------------------------------------------------------------------
constexpr uint32_t PE_TEXT_SECTION_BASE = 0x400000;
constexpr uint32_t PE_TEXT_SECTION_END = 0x800000;
constexpr uint32_t PE_RDATA_SECTION_BASE = 0x7FF000;
constexpr uint32_t PE_DATA_RAW_SECTION_BASE = 0x827000;
constexpr uint32_t PE_BSS_SECTION_BASE = 0x883000;
constexpr uint32_t PE_BSS_SECTION_END = 0xD06000;
// Windows KUSER_SHARED_DATA page (read-only, always mapped)
constexpr uint32_t KUSER_SHARED_DATA_BASE = 0x7FFE0000;
constexpr uint32_t KUSER_SHARED_DATA_END = 0x7FFF0000;
// ---------------------------------------------------------------------------
// Well-known memory addresses
// ---------------------------------------------------------------------------
constexpr uint32_t WARDEN_TICKCOUNT_ADDRESS = 0x00CF0BC8;
constexpr uint32_t WARDEN_WIN_VERSION_ADDRESS = 0x7FFE026C;
// ---------------------------------------------------------------------------
// Check sizes (bytes)
// ---------------------------------------------------------------------------
constexpr uint32_t WARDEN_CR_HEADER_SIZE = 17;
constexpr uint32_t WARDEN_CR_ENTRY_SIZE = 68;
constexpr uint32_t WARDEN_PAGE_CHECK_SIZE = 29;
constexpr uint32_t WARDEN_PAGE_A_SHORT_SIZE = 24;
constexpr uint32_t WARDEN_KNOWN_CODE_SCAN_OFFSET = 13856;
// ---------------------------------------------------------------------------
// Memory-check result codes
// ---------------------------------------------------------------------------
constexpr uint8_t WARDEN_MEM_CHECK_SUCCESS = 0x00;
constexpr uint8_t WARDEN_MEM_CHECK_UNMAPPED = 0xE9;
constexpr uint8_t WARDEN_PAGE_CHECK_FOUND = 0x4A;
} // namespace game
} // namespace wowee