From b63bf1c1e616419a1607e8ac7bff212040c35cd3 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 13 Mar 2026 12:57:02 +0100 Subject: [PATCH] Core/Misc: Reduce memory usage when data query cache is disabled in config --- src/server/game/Entities/Conversation/Conversation.cpp | 1 + src/server/game/Entities/Corpse/Corpse.cpp | 1 + src/server/game/Entities/Creature/Creature.cpp | 2 ++ src/server/game/Entities/Creature/CreatureData.h | 5 +++-- src/server/game/Entities/Creature/GossipDef.cpp | 2 +- .../game/Entities/DynamicObject/DynamicObject.cpp | 1 + src/server/game/Entities/GameObject/GameObject.cpp | 2 ++ src/server/game/Entities/GameObject/GameObjectData.h | 6 ++++-- .../Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp | 1 + .../game/Entities/Item/AzeriteItem/AzeriteItem.cpp | 1 + src/server/game/Entities/Item/Container/Bag.cpp | 10 +++++----- src/server/game/Entities/SceneObject/SceneObject.cpp | 1 + src/server/game/Entities/Transport/Transport.cpp | 1 + src/server/game/Entities/Unit/CharmInfo.cpp | 6 ------ src/server/game/Entities/Unit/CharmInfo.h | 2 -- src/server/game/Globals/ObjectMgr.cpp | 7 +++++-- src/server/game/Globals/ObjectMgr.h | 2 +- src/server/game/Handlers/QueryHandler.cpp | 4 ++-- src/server/game/Quests/QuestDef.cpp | 2 ++ src/server/game/Quests/QuestDef.h | 4 ++-- src/server/game/Server/Packets/QueryPackets.cpp | 6 ++---- tests/DummyData.cpp | 3 ++- 22 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/server/game/Entities/Conversation/Conversation.cpp b/src/server/game/Entities/Conversation/Conversation.cpp index d6e9cebeef..af6a8e69b0 100644 --- a/src/server/game/Entities/Conversation/Conversation.cpp +++ b/src/server/game/Entities/Conversation/Conversation.cpp @@ -30,6 +30,7 @@ #include "PhasingHandler.h" #include "Player.h" #include "UpdateData.h" +#include "WorldPacket.h" #include "WorldSession.h" Conversation::Conversation() : WorldObject(false), _duration(0), _textureKitId(0) diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index b8507adefa..ef9c25b32d 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -28,6 +28,7 @@ #include "Player.h" #include "StringConvert.h" #include "UpdateData.h" +#include "WorldPacket.h" #include Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index e075cc62ee..6b8c53a527 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -167,6 +167,8 @@ CreatureModel const* CreatureTemplate::GetFirstVisibleModel() const void CreatureTemplate::InitializeQueryData() { + QueryData = std::make_unique(TOTAL_LOCALES); + for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc) { if (!sWorld->getBoolConfig(CONFIG_LOAD_LOCALES) && loc != DEFAULT_LOCALE) diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index 969cf8ddbf..f9a67cc181 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -25,11 +25,12 @@ #include "SharedDefines.h" #include "SpawnData.h" #include "UnitDefines.h" -#include "WorldPacket.h" +#include #include #include #include +class WorldPacket; struct ItemTemplate; enum class VisibilityDistanceType : uint8; @@ -533,7 +534,7 @@ struct TC_GAME_API CreatureTemplate uint32 flags_extra; uint32 ScriptID; std::string StringId; - WorldPacket QueryData[TOTAL_LOCALES]; + std::unique_ptr QueryData; CreatureModel const* GetModelByIdx(uint32 idx) const; CreatureModel const* GetRandomValidModel() const; CreatureModel const* GetFirstValidModel() const; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index c1a359b0ff..b40a1be654 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -558,7 +558,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const { - if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES)) + if (quest->QueryData) _session->SendPacket(&quest->QueryData[static_cast(_session->GetSessionDbLocaleIndex())]); else { diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index fdb2a12373..92b10eef53 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -30,6 +30,7 @@ #include "Transport.h" #include "Unit.h" #include "UpdateData.h" +#include "WorldPacket.h" DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject), _aura(nullptr), _removedAura(nullptr), _caster(nullptr), _duration(0), _isViewpoint(false) diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 9fea3ade32..9e73254866 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -63,6 +63,8 @@ void GameObjectTemplate::InitializeQueryData() { + QueryData = std::make_unique(TOTAL_LOCALES); + for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc) { if (!sWorld->getBoolConfig(CONFIG_LOAD_LOCALES) && loc != DEFAULT_LOCALE) diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 23d06d671c..951b077c90 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -22,11 +22,13 @@ #include "QuaternionData.h" #include "SharedDefines.h" #include "SpawnData.h" -#include "WorldPacket.h" #include +#include #include #include +class WorldPacket; + enum class GameObjectChestFlags : int32 { Consumable = 0x0001, @@ -883,7 +885,7 @@ struct GameObjectTemplate std::string AIName; uint32 ScriptId; std::string StringId; - WorldPacket QueryData[TOTAL_LOCALES]; + std::unique_ptr QueryData; // helpers bool IsDespawnAtAction() const diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp index 5ab7fb4bde..9d7726e6e3 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp @@ -20,6 +20,7 @@ #include "DB2Stores.h" #include "Player.h" #include "UpdateData.h" +#include "WorldPacket.h" AzeriteEmpoweredItem::AzeriteEmpoweredItem() { diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp index 7b87b88b8d..865dbe9c0c 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp @@ -24,6 +24,7 @@ #include "GameTime.h" #include "Player.h" #include "UpdateData.h" +#include "WorldPacket.h" #include #include diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index 91824e6f62..f0fbd3027c 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -15,14 +15,14 @@ * with this program. If not, see . */ -#include "Common.h" -#include "ObjectMgr.h" -#include "DatabaseEnv.h" - #include "Bag.h" +#include "Common.h" +#include "DatabaseEnv.h" #include "Log.h" -#include "UpdateData.h" +#include "ObjectMgr.h" #include "Player.h" +#include "UpdateData.h" +#include "WorldPacket.h" Bag::Bag(): Item() { diff --git a/src/server/game/Entities/SceneObject/SceneObject.cpp b/src/server/game/Entities/SceneObject/SceneObject.cpp index aa098b96e9..ed7b49fc26 100644 --- a/src/server/game/Entities/SceneObject/SceneObject.cpp +++ b/src/server/game/Entities/SceneObject/SceneObject.cpp @@ -25,6 +25,7 @@ #include "SpellAuras.h" #include "UpdateData.h" #include "Util.h" +#include "WorldPacket.h" SceneObject::SceneObject() : WorldObject(false) { diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 1ae219bb17..a6018bf7bf 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -29,6 +29,7 @@ #include "Totem.h" #include "UpdateData.h" #include "Vehicle.h" +#include "WorldPacket.h" #include #include diff --git a/src/server/game/Entities/Unit/CharmInfo.cpp b/src/server/game/Entities/Unit/CharmInfo.cpp index a9e01ed6c3..7f9f7b1161 100644 --- a/src/server/game/Entities/Unit/CharmInfo.cpp +++ b/src/server/game/Entities/Unit/CharmInfo.cpp @@ -275,12 +275,6 @@ void CharmInfo::LoadPetActionBar(const std::string& data) } } -void CharmInfo::BuildActionBar(WorldPacket* data) -{ - for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - *data << uint32(PetActionBar[i].packedData); -} - void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state) { for (uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) diff --git a/src/server/game/Entities/Unit/CharmInfo.h b/src/server/game/Entities/Unit/CharmInfo.h index e21cf4f0f7..caa34f7ca6 100644 --- a/src/server/game/Entities/Unit/CharmInfo.h +++ b/src/server/game/Entities/Unit/CharmInfo.h @@ -23,7 +23,6 @@ class SpellInfo; class Unit; -class WorldPacket; constexpr uint8 MAX_SPELL_CHARM = 4; constexpr uint8 MAX_SPELL_VEHICLE = 6; @@ -107,7 +106,6 @@ struct TC_GAME_API CharmInfo bool AddSpellToActionBar(SpellInfo const* spellInfo, ActiveStates newstate = ACT_DECIDE, uint8 preferredSlot = 0); bool RemoveSpellFromActionBar(uint32 spell_id); void LoadPetActionBar(const std::string& data); - void BuildActionBar(WorldPacket* data); void SetSpellAutocast(SpellInfo const* spellInfo, bool state); void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 50dd1e3f90..3126b09860 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -11001,8 +11001,11 @@ void ObjectMgr::InitializeQueriesData(QueryDataGroup mask) void QuestPOIData::InitializeQueryData() { - QueryDataBuffer << *this; - QueryDataBuffer.shrink_to_fit(); + ByteBuffer tempBuffer; + tempBuffer << *this; + tempBuffer.shrink_to_fit(); + + QueryDataBuffer = std::move(tempBuffer).Release(); } void ObjectMgr::LoadSceneTemplates() diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 66802e6736..45a1f8b0c3 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -822,7 +822,7 @@ struct QuestPOIData std::vector Blobs; void InitializeQueryData(); - ByteBuffer QueryDataBuffer; + std::vector QueryDataBuffer; }; typedef std::unordered_map QuestPOIContainer; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 21d10291a6..e836843bba 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -78,7 +78,7 @@ void WorldSession::HandleCreatureQuery(WorldPackets::Query::QueryCreature& packe Difficulty difficulty = _player->GetMap()->GetDifficultyID(); // Cache only exists for difficulty base - if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES) && difficulty == DIFFICULTY_NONE) + if (ci->QueryData && difficulty == DIFFICULTY_NONE) SendPacket(&ci->QueryData[static_cast(GetSessionDbLocaleIndex())]); else { @@ -103,7 +103,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPackets::Query::QueryGameObj { if (GameObjectTemplate const* info = sObjectMgr->GetGameObjectTemplate(packet.GameObjectID)) { - if (sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES)) + if (info->QueryData) SendPacket(&info->QueryData[static_cast(GetSessionDbLocaleIndex())]); else { diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 47e3cee22b..bab0407ba5 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -650,6 +650,8 @@ bool Quest::CanIncreaseRewardedQuestCounters() const void Quest::InitializeQueryData() { + QueryData = std::make_unique(TOTAL_LOCALES); + for (uint8 loc = LOCALE_enUS; loc < TOTAL_LOCALES; ++loc) { if (!sWorld->getBoolConfig(CONFIG_LOAD_LOCALES) && loc != DEFAULT_LOCALE) diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index f9c40d7098..3f0a116ea5 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -27,12 +27,12 @@ #include "RaceMask.h" #include "SharedDefines.h" #include "UniqueTrackablePtr.h" -#include "WorldPacket.h" #include #include #include class Player; +class WorldPacket; enum Difficulty : int16; namespace WorldPackets @@ -778,7 +778,7 @@ class TC_GAME_API Quest std::vector DependentPreviousQuests; std::vector DependentBreadcrumbQuests; - std::array QueryData; + std::unique_ptr QueryData; private: uint32 _rewItemsCount = 0; diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index 7e6fd6446c..8b57913c0b 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -427,12 +427,10 @@ WorldPacket const* QuestPOIQueryResponse::Write() _worldPacket << Size(QuestPOIDataStats); _worldPacket << Size(QuestPOIDataStats); - bool useCache = sWorld->getBoolConfig(CONFIG_CACHE_DATA_QUERIES); - for (QuestPOIData const* questPOIData : QuestPOIDataStats) { - if (useCache) - _worldPacket.append(questPOIData->QueryDataBuffer); + if (!questPOIData->QueryDataBuffer.empty()) + _worldPacket.append(questPOIData->QueryDataBuffer.data(), questPOIData->QueryDataBuffer.size()); else _worldPacket << *questPOIData; } diff --git a/tests/DummyData.cpp b/tests/DummyData.cpp index 4d89a2b02a..e08601e808 100644 --- a/tests/DummyData.cpp +++ b/tests/DummyData.cpp @@ -21,12 +21,13 @@ #include "ItemDefines.h" #include "ItemTemplate.h" #include "ObjectMgr.h" +#include // std::memset /*static*/ ItemTemplate& UnitTestDataLoader::GetItemTemplate(uint32 itemId, std::string_view name) { ItemTemplate& t = sObjectMgr->_itemTemplateStore[itemId]; ItemEntry* itemEntry = new ItemEntry(); - memset(itemEntry, 0, sizeof(ItemEntry)); + std::memset(itemEntry, 0, sizeof(ItemEntry)); itemEntry->ID = itemId; itemEntry->ClassID = ITEM_CLASS_MISCELLANEOUS; t.BasicData = itemEntry;