From 11561184e6b8b5b9442fb63c31259be31d5b2fbe Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 31 Mar 2026 00:48:03 -0700 Subject: [PATCH 1/5] fix: silence all -Wunused-parameter warnings in entity_controller Suppress 9 unused parameter warnings in IObjectTypeHandler interface methods and their overrides by commenting out parameter names: - Base class: onCreate/onValuesUpdate/onMovementUpdate default empty implementations (parameters intentionally unused in base) - ItemTypeHandler::onCreate: entity param forwarded only to onCreateItem which doesn't need it - CorpseTypeHandler::onCreate: entity param not needed for corpse spawn Build now produces zero warnings (excluding third-party stb headers). --- include/game/entity_controller.hpp | 8 ++++---- src/game/entity_controller.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/game/entity_controller.hpp b/include/game/entity_controller.hpp index ee63504c..1a8d1f7b 100644 --- a/include/game/entity_controller.hpp +++ b/include/game/entity_controller.hpp @@ -236,10 +236,10 @@ private: // Allows extending object-type handling without modifying handler dispatch. struct IObjectTypeHandler { virtual ~IObjectTypeHandler() = default; - virtual void onCreate(const UpdateBlock& block, std::shared_ptr& entity, - bool& newItemCreated) {} - virtual void onValuesUpdate(const UpdateBlock& block, std::shared_ptr& entity) {} - virtual void onMovementUpdate(const UpdateBlock& block, std::shared_ptr& entity) {} + virtual void onCreate(const UpdateBlock& /*block*/, std::shared_ptr& /*entity*/, + bool& /*newItemCreated*/) {} + virtual void onValuesUpdate(const UpdateBlock& /*block*/, std::shared_ptr& /*entity*/) {} + virtual void onMovementUpdate(const UpdateBlock& /*block*/, std::shared_ptr& /*entity*/) {} }; struct UnitTypeHandler; struct PlayerTypeHandler; diff --git a/src/game/entity_controller.cpp b/src/game/entity_controller.cpp index 6f74f46e..6a9cc826 100644 --- a/src/game/entity_controller.cpp +++ b/src/game/entity_controller.cpp @@ -1266,14 +1266,14 @@ struct EntityController::GameObjectTypeHandler : EntityController::IObjectTypeHa struct EntityController::ItemTypeHandler : EntityController::IObjectTypeHandler { EntityController& ctl_; explicit ItemTypeHandler(EntityController& c) : ctl_(c) {} - void onCreate(const UpdateBlock& block, std::shared_ptr& entity, bool& newItemCreated) override { ctl_.onCreateItem(block, newItemCreated); } + void onCreate(const UpdateBlock& block, std::shared_ptr& /*entity*/, bool& newItemCreated) override { ctl_.onCreateItem(block, newItemCreated); } void onValuesUpdate(const UpdateBlock& block, std::shared_ptr& entity) override { ctl_.onValuesUpdateItem(block, entity); } }; struct EntityController::CorpseTypeHandler : EntityController::IObjectTypeHandler { EntityController& ctl_; explicit CorpseTypeHandler(EntityController& c) : ctl_(c) {} - void onCreate(const UpdateBlock& block, std::shared_ptr& entity, bool&) override { ctl_.onCreateCorpse(block); } + void onCreate(const UpdateBlock& block, std::shared_ptr& /*entity*/, bool&) override { ctl_.onCreateCorpse(block); } }; // ============================================================ From 681e25a4f2167d23b78478ffb4a5c720c98d0253 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 31 Mar 2026 00:54:46 -0700 Subject: [PATCH 2/5] fix: clean up unused parameter style in entity_controller Use nameless parameters instead of /*comment*/ syntax for unused args in IObjectTypeHandler interface defaults and overrides. --- include/game/entity_controller.hpp | 7 +++---- src/game/entity_controller.cpp | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/game/entity_controller.hpp b/include/game/entity_controller.hpp index 1a8d1f7b..5b220ead 100644 --- a/include/game/entity_controller.hpp +++ b/include/game/entity_controller.hpp @@ -236,10 +236,9 @@ private: // Allows extending object-type handling without modifying handler dispatch. struct IObjectTypeHandler { virtual ~IObjectTypeHandler() = default; - virtual void onCreate(const UpdateBlock& /*block*/, std::shared_ptr& /*entity*/, - bool& /*newItemCreated*/) {} - virtual void onValuesUpdate(const UpdateBlock& /*block*/, std::shared_ptr& /*entity*/) {} - virtual void onMovementUpdate(const UpdateBlock& /*block*/, std::shared_ptr& /*entity*/) {} + virtual void onCreate(const UpdateBlock&, std::shared_ptr&, bool&) {} + virtual void onValuesUpdate(const UpdateBlock&, std::shared_ptr&) {} + virtual void onMovementUpdate(const UpdateBlock&, std::shared_ptr&) {} }; struct UnitTypeHandler; struct PlayerTypeHandler; diff --git a/src/game/entity_controller.cpp b/src/game/entity_controller.cpp index 6a9cc826..361e650d 100644 --- a/src/game/entity_controller.cpp +++ b/src/game/entity_controller.cpp @@ -1266,14 +1266,14 @@ struct EntityController::GameObjectTypeHandler : EntityController::IObjectTypeHa struct EntityController::ItemTypeHandler : EntityController::IObjectTypeHandler { EntityController& ctl_; explicit ItemTypeHandler(EntityController& c) : ctl_(c) {} - void onCreate(const UpdateBlock& block, std::shared_ptr& /*entity*/, bool& newItemCreated) override { ctl_.onCreateItem(block, newItemCreated); } + void onCreate(const UpdateBlock& block, std::shared_ptr&, bool& newItemCreated) override { ctl_.onCreateItem(block, newItemCreated); } void onValuesUpdate(const UpdateBlock& block, std::shared_ptr& entity) override { ctl_.onValuesUpdateItem(block, entity); } }; struct EntityController::CorpseTypeHandler : EntityController::IObjectTypeHandler { EntityController& ctl_; explicit CorpseTypeHandler(EntityController& c) : ctl_(c) {} - void onCreate(const UpdateBlock& block, std::shared_ptr& /*entity*/, bool&) override { ctl_.onCreateCorpse(block); } + void onCreate(const UpdateBlock& block, std::shared_ptr&, bool&) override { ctl_.onCreateCorpse(block); } }; // ============================================================ From f3f7511105eb2896d10ea64c6fcd03af71b93d78 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 31 Mar 2026 01:10:43 -0700 Subject: [PATCH 3/5] fix: send Warden HASH_RESULT fallback instead of skipping response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, WotLK/TBC servers with no CR match would skip the HASH_REQUEST response entirely to "avoid account bans". This caused a guaranteed kick-on-timeout for ALL WotLK servers including permissive ones like ChromieCraft/AzerothCore. Now sends a best-effort fallback hash (SHA1 of module image or raw data) for all server types. Permissive servers accept this and continue the session normally. Strict servers (Warmane) will reject it but only kick — same outcome as the previous skip behavior, just faster feedback. For strict servers, the correct fix remains providing a .cr file with pre-computed seed→reply entries for each module. --- src/game/warden_handler.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/game/warden_handler.cpp b/src/game/warden_handler.cpp index 1bd28a73..3fc1a9ad 100644 --- a/src/game/warden_handler.cpp +++ b/src/game/warden_handler.cpp @@ -535,22 +535,15 @@ void WardenHandler::handleWardenData(network::Packet& packet) { bool isTurtle = isActiveExpansion("turtle"); bool isClassic = (owner_.build <= 6005) && !isTurtle; - if (!isTurtle && !isClassic) { - // WotLK/TBC (AzerothCore, etc.): strict servers BAN for wrong HASH_RESULT. - // Without a matching CR entry we cannot compute the correct hash - // (requires executing the module's native init function). - // Safest action: don't respond. Server will time-out and kick (not ban). - LOG_WARNING("Warden: HASH_REQUEST seed=", seedHex, - " — no CR match, SKIPPING response to avoid account ban"); - LOG_WARNING("Warden: To fix, provide a .cr file with the correct seed→reply entry for this module"); - // Stay in WAIT_HASH_REQUEST — server will eventually kick. - break; - } + // Previously we skipped the response for WotLK/TBC to avoid bans on strict + // servers (e.g. Warmane). However, most servers (AzerothCore, ChromieCraft, + // TrinityCore) are permissive and only kick — not ban — for wrong hashes. + // Skipping causes a guaranteed kick-on-timeout, while sending a fallback + // hash at least lets permissive servers continue the session. + // For strict servers, provide a .cr file with the correct seed→reply. - // Turtle/Classic: lenient servers (log-only penalties, no bans). - // Send a best-effort fallback hash so we can continue the handshake. LOG_WARNING("Warden: No CR match (seed=", seedHex, - "), sending fallback hash (lenient server)"); + "), sending fallback hash"); std::vector fallbackReply; if (wardenLoadedModule_ && wardenLoadedModule_->isLoaded()) { From 5ad225313dc842edaac26fcd2c3fcd4cede4f0d0 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 31 Mar 2026 01:18:58 -0700 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20revert=20Warden=20HASH=5FRESULT=20fa?= =?UTF-8?q?llback=20=E2=80=94=20silence=20is=20correct=20behavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ChromieCraft/AzerothCore tolerates no HASH_RESULT response (continues session without Warden checks), but immediately kicks on a WRONG hash. The previous commit sent a fallback SHA1 which the server rejected, breaking login that was working before. Restore the skip behavior for WotLK/TBC: stay silent on HASH_REQUEST when no CR match exists, and advance to WAIT_CHECKS so the rest of the session proceeds normally. Turtle/Classic servers still get the fallback hash since they're lenient about wrong values. --- src/game/warden_handler.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/game/warden_handler.cpp b/src/game/warden_handler.cpp index 3fc1a9ad..a5f38714 100644 --- a/src/game/warden_handler.cpp +++ b/src/game/warden_handler.cpp @@ -535,15 +535,19 @@ void WardenHandler::handleWardenData(network::Packet& packet) { bool isTurtle = isActiveExpansion("turtle"); bool isClassic = (owner_.build <= 6005) && !isTurtle; - // Previously we skipped the response for WotLK/TBC to avoid bans on strict - // servers (e.g. Warmane). However, most servers (AzerothCore, ChromieCraft, - // TrinityCore) are permissive and only kick — not ban — for wrong hashes. - // Skipping causes a guaranteed kick-on-timeout, while sending a fallback - // hash at least lets permissive servers continue the session. - // For strict servers, provide a .cr file with the correct seed→reply. + if (!isTurtle && !isClassic) { + // WotLK/TBC: don't respond to HASH_REQUEST without a valid CR match. + // ChromieCraft/AzerothCore tolerates the silence (no ban, no kick), + // but REJECTS a wrong hash and closes the connection immediately. + // Staying silent lets the server continue the session without Warden checks. + LOG_WARNING("Warden: HASH_REQUEST seed=", seedHex, + " — no CR match, skipping response (server tolerates silence)"); + wardenState_ = WardenState::WAIT_CHECKS; + break; + } LOG_WARNING("Warden: No CR match (seed=", seedHex, - "), sending fallback hash"); + "), sending fallback hash (lenient server)"); std::vector fallbackReply; if (wardenLoadedModule_ && wardenLoadedModule_->isLoaded()) { From ea8b0d93052f0c556b918752318a8b2b46166df9 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 31 Mar 2026 01:27:32 -0700 Subject: [PATCH 5/5] fix: reduce warmup ground-check timeout from 20s to 5s The warmup loop waited up to 20 seconds for getHeightAt() to return a terrain height within 15 units of spawn Z before accepting the ground as ready. In practice, the terrain was loaded and the character was visibly standing on it, but the height sample didn't match closely enough (terrain LOD, chunk boundary, or server Z vs client height mismatch). Reduce the tile-count fallback timeout from 20s to 5s: if at least 4 tiles are loaded after 5 seconds, accept the ground as ready. The exact height check still runs in the first 5 seconds for fast-path cases where it does match. --- src/core/application.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/application.cpp b/src/core/application.cpp index 4da62a1c..c0038782 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -5385,8 +5385,12 @@ void Application::loadOnlineWorldTerrain(uint32_t mapId, float x, float y, float } } } - // After 20s, accept any loaded terrain (fallback for unusual spawns) - if (!groundReady && elapsed >= 20.0f) { + // After 5s with enough tiles loaded, accept terrain as ready even if + // the height sample doesn't match spawn Z exactly. This handles cases + // where getHeightAt returns a slightly different value than the server's + // spawn Z (e.g. terrain LOD, MCNK chunk boundaries, or spawn inside a + // building where floor height differs from terrain below). + if (!groundReady && elapsed >= 5.0f) { if (auto* tm = renderer->getTerrainManager()) { if (tm->getLoadedTileCount() >= 4) { groundReady = true;