From 2c50cc94e18741254c61158f717ce6dd837e20c0 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 30 Mar 2026 17:26:13 -0700 Subject: [PATCH] docs: add why-comments to TBC parsers, bell audio, portrait preview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - packet_parsers_tbc: explain spline waypoint cap (DoS prevention), spline compression flags (Catmull-Rom 0x80000 / linear 0x2000 use uncompressed format, others use packed delta), spell hit target cap (128 >> real AOE max of ~20), guild roster cap (1000 safety limit) - ambient_sound_manager: explain 1.5s bell toll spacing — matches retail WoW cadence, allows each toll to ring out before the next - character_preview.hpp: explain 4:5 portrait aspect ratio for full-body character display in creation/selection screen --- include/rendering/character_preview.hpp | 2 ++ src/audio/ambient_sound_manager.cpp | 3 ++- src/game/packet_parsers_tbc.cpp | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/rendering/character_preview.hpp b/include/rendering/character_preview.hpp index 7ff5352c..965d6913 100644 --- a/include/rendering/character_preview.hpp +++ b/include/rendering/character_preview.hpp @@ -81,6 +81,8 @@ private: // ImGui texture handle for displaying the preview (VkDescriptorSet in Vulkan backend) VkDescriptorSet imguiTextureId_ = VK_NULL_HANDLE; + // 4:5 portrait aspect ratio — taller than wide to show full character body + // from head to feet in the character creation/selection screen static constexpr int fboWidth_ = 400; static constexpr int fboHeight_ = 500; diff --git a/src/audio/ambient_sound_manager.cpp b/src/audio/ambient_sound_manager.cpp index 70574f79..a2719c32 100644 --- a/src/audio/ambient_sound_manager.cpp +++ b/src/audio/ambient_sound_manager.cpp @@ -921,7 +921,8 @@ void AmbientSoundManager::updateBellTolls(float deltaTime) { static_cast(currentCity_)); } - // Play remaining tolls with 1.5 second delay between each + // Play remaining tolls with 1.5s spacing — matches retail WoW bell cadence + // (long enough for each toll to ring out before the next begins) if (remainingTolls_ > 0) { bellTollDelay_ += deltaTime; diff --git a/src/game/packet_parsers_tbc.cpp b/src/game/packet_parsers_tbc.cpp index 8d86a808..165a4348 100644 --- a/src/game/packet_parsers_tbc.cpp +++ b/src/game/packet_parsers_tbc.cpp @@ -155,6 +155,7 @@ bool TbcPacketParsers::parseMovementBlock(network::Packet& packet, UpdateBlock& /*uint32_t splineId =*/ packet.readUInt32(); uint32_t pointCount = packet.readUInt32(); + // Cap waypoints to prevent DoS from malformed packets allocating huge arrays if (pointCount > 256) return false; // points + endPoint (no splineMode in TBC) @@ -690,6 +691,8 @@ bool TbcPacketParsers::parseMonsterMove(network::Packet& packet, MonsterMoveData if (pointCount == 0) return true; if (pointCount > 16384) return false; + // Spline points are stored uncompressed when Catmull-Rom interpolation (0x80000) + // or linear movement (0x2000) flags are set; otherwise they use packed delta format bool uncompressed = (data.splineFlags & (0x00080000 | 0x00002000)) != 0; if (uncompressed) { for (uint32_t i = 0; i < pointCount - 1; i++) { @@ -1359,6 +1362,8 @@ bool TbcPacketParsers::parseSpellGo(network::Packet& packet, SpellGoData& data) return false; } + // Cap hit targets to prevent oversized allocations from malformed spell packets. + // 128 is well above any real WoW AOE spell target count (max ~20 in practice). const uint8_t rawHitCount = packet.readUInt8(); if (rawHitCount > 128) { LOG_WARNING("[TBC] Spell go: hitCount capped (requested=", static_cast(rawHitCount), ")"); @@ -1819,6 +1824,8 @@ bool TbcPacketParsers::parseGuildRoster(network::Packet& packet, GuildRosterData } uint32_t numMembers = packet.readUInt32(); + // Safety cap — guilds rarely exceed 500 members; 1000 prevents excessive + // memory allocation from malformed packets while covering all real cases const uint32_t MAX_GUILD_MEMBERS = 1000; if (numMembers > MAX_GUILD_MEMBERS) { LOG_WARNING("TBC GuildRoster: numMembers capped (requested=", numMembers, ")");