From 83eef878fb9b40c44353e9ac31202855c290b28e Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 14 Apr 2026 04:20:28 -0700 Subject: [PATCH] fix: validate displayId range and skip missing equipment textures Reject displayId values >100k (corrupted update-field data) to avoid pointless DBC lookups and log spam. Add fileExists() guard before using base texture path in 4 equipment compositing code paths that were falling through without checking, causing excessive "Texture not found" warnings when users have incomplete MPQ extractions. --- src/core/entity_spawner.cpp | 8 ++++++++ src/core/entity_spawner_player.cpp | 4 +++- src/core/entity_spawner_processing.cpp | 6 ++++-- src/ui/game_screen_hud.cpp | 5 +++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/core/entity_spawner.cpp b/src/core/entity_spawner.cpp index 0e8fb7e6..a904c048 100644 --- a/src/core/entity_spawner.cpp +++ b/src/core/entity_spawner.cpp @@ -649,6 +649,14 @@ void EntitySpawner::buildCreatureDisplayLookups() { } std::string EntitySpawner::getModelPathForDisplayId(uint32_t displayId) const { + // WotLK 3.3.5a CreatureDisplayInfo tops out around ~32000; values far + // beyond that are corrupted update-field data or packet parse errors. + // Silently reject to avoid pointless DBC lookups and log spam. + constexpr uint32_t kMaxReasonableDisplayId = 100000; + if (displayId == 0 || displayId > kMaxReasonableDisplayId) { + return ""; + } + if (displayId == 30412) return "Creature\\Gryphon\\Gryphon.m2"; if (displayId == 30413) return "Creature\\Wyvern\\Wyvern.m2"; diff --git a/src/core/entity_spawner_player.cpp b/src/core/entity_spawner_player.cpp index 92240fd9..6a564dc9 100644 --- a/src/core/entity_spawner_player.cpp +++ b/src/core/entity_spawner_player.cpp @@ -769,10 +769,12 @@ void EntitySpawner::setOnlinePlayerEquipment(uint64_t guid, std::string base = "Item\\TextureComponents\\" + std::string(componentDirs[region]) + "\\" + texName; std::string genderPath = base + (isFemale ? "_F.blp" : "_M.blp"); std::string unisexPath = base + "_U.blp"; + std::string basePath = base + ".blp"; std::string fullPath; if (assetManager_->fileExists(genderPath)) fullPath = genderPath; else if (assetManager_->fileExists(unisexPath)) fullPath = unisexPath; - else fullPath = base + ".blp"; + else if (assetManager_->fileExists(basePath)) fullPath = basePath; + else continue; regionLayers.emplace_back(region, fullPath); } diff --git a/src/core/entity_spawner_processing.cpp b/src/core/entity_spawner_processing.cpp index 828bf3ce..60626898 100644 --- a/src/core/entity_spawner_processing.cpp +++ b/src/core/entity_spawner_processing.cpp @@ -463,9 +463,10 @@ void EntitySpawner::processCreatureSpawnQueue(bool unlimited) { std::string(compDirs[region]) + "\\" + texName; std::string gp = base + (isFem ? "_F.blp" : "_M.blp"); std::string up = base + "_U.blp"; + std::string bp = base + ".blp"; if (am->fileExists(gp)) displaySkinPaths.push_back(gp); else if (am->fileExists(up)) displaySkinPaths.push_back(up); - else displaySkinPaths.push_back(base + ".blp"); + else if (am->fileExists(bp)) displaySkinPaths.push_back(bp); } } } @@ -673,9 +674,10 @@ std::vector EntitySpawner::resolveEquipmentTexturePaths(uint64_t gu std::string(componentDirs[region]) + "\\" + texName; std::string genderPath = base + (isFemale ? "_F.blp" : "_M.blp"); std::string unisexPath = base + "_U.blp"; + std::string basePath = base + ".blp"; if (assetManager_->fileExists(genderPath)) paths.push_back(genderPath); else if (assetManager_->fileExists(unisexPath)) paths.push_back(unisexPath); - else paths.push_back(base + ".blp"); + else if (assetManager_->fileExists(basePath)) paths.push_back(basePath); } } return paths; diff --git a/src/ui/game_screen_hud.cpp b/src/ui/game_screen_hud.cpp index c725326f..5897c8d8 100644 --- a/src/ui/game_screen_hud.cpp +++ b/src/ui/game_screen_hud.cpp @@ -315,9 +315,10 @@ void GameScreen::updateCharacterTextures(game::Inventory& inventory) { fullPath = genderPath; } else if (assetManager->fileExists(unisexPath)) { fullPath = unisexPath; - } else { - // Last resort: try without suffix + } else if (assetManager->fileExists(base + ".blp")) { fullPath = base + ".blp"; + } else { + continue; } regionLayers.emplace_back(region, fullPath); }