diff options
Diffstat (limited to 'src')
26 files changed, 207 insertions, 171 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 603f76560de..6f14b3a04a8 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1053,7 +1053,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (!targets) break; - std::set<uint32> const& phases = GetPhasesForGroup(e.action.ingamePhaseGroup.groupId); + std::set<uint32> phases = sDB2Manager.GetPhasesForGroup(e.action.ingamePhaseGroup.groupId); for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) for (auto phase : phases) diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index f2148b6a24e..ec0bd63efc7 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -24,14 +24,11 @@ #include <functional> DB2Storage<BroadcastTextEntry> sBroadcastTextStore(BroadcastTextEntryfmt, HOTFIX_SEL_BROADCAST_TEXT); -std::map<uint32 /*curveID*/, std::map<uint32/*index*/, CurvePointEntry const*, std::greater<uint32>>> HeirloomCurvePoints; DB2Storage<CurvePointEntry> sCurvePointStore(CurvePointEntryfmt); DB2Storage<HolidaysEntry> sHolidaysStore(HolidaysEntryfmt); DB2Storage<ItemEntry> sItemStore(Itemfmt); DB2Storage<ItemAppearanceEntry> sItemAppearanceStore(ItemAppearanceEntryfmt); -std::unordered_map<uint32 /*itemId | appearanceMod << 24*/, uint32> ItemDisplayMap; DB2Storage<ItemBonusEntry> sItemBonusStore(ItemBonusEntryfmt); -std::unordered_map<uint32 /*bonusListId*/, std::vector<ItemBonusEntry const*>> ItemBonusLists; DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore(ItemCurrencyCostfmt); DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt); DB2Storage<ItemEffectEntry> sItemEffectStore(ItemEffectEntryfmt); @@ -59,28 +56,18 @@ TaxiMask sAllianceTaxiNodesMask; TaxiMask sDeathKnightTaxiNodesMask; TaxiPathSetBySource sTaxiPathSetBySource; TaxiPathNodesByPath sTaxiPathNodesByPath; -PhaseGroupContainer sPhasesByGroup; typedef std::list<std::string> DB2StoreProblemList; -typedef std::map<uint32 /*hash*/, DB2StorageBase*> DB2StorageMap; -DB2StorageMap DB2Stores; - uint32 DB2FilesCount = 0; -static bool LoadDB2_assert_print(uint32 fsize, uint32 rsize, std::string const& filename) -{ - TC_LOG_ERROR("misc", "Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).", filename.c_str(), fsize, rsize); - - // ASSERT must fail after function call - return false; -} - template<class T> -inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, DB2Storage<T>& storage, std::string const& db2_path, std::string const& filename) +inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, DB2Manager::StorageMap& stores, DB2Storage<T>& storage, std::string const& db2_path, std::string const& filename) { // compatibility format and C++ structure sizes - ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDB2_assert_print(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename)); + ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T), + "Size of '%s' set by format string (%u) not equal size of C++ structure (%u).", + DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename.c_str()); ++DB2FilesCount; @@ -121,50 +108,50 @@ inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, D errlist.push_back(db2_filename); } - DB2Stores[storage.GetHash()] = &storage; + stores[storage.GetHash()] = &storage; } -void LoadDB2Stores(std::string const& dataPath) +void DB2Manager::LoadStores(std::string const& dataPath) { std::string db2Path = dataPath + "dbc/"; DB2StoreProblemList bad_db2_files; uint32 availableDb2Locales = 0xFF; - LoadDB2(availableDb2Locales, bad_db2_files, sBroadcastTextStore, db2Path, "BroadcastText.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sCurvePointStore, db2Path, "CurvePoint.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sHolidaysStore, db2Path, "Holidays.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemStore, db2Path, "Item.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemAppearanceStore, db2Path, "ItemAppearance.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemBonusStore, db2Path, "ItemBonus.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemEffectStore, db2Path, "ItemEffect.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemModifiedAppearanceStore, db2Path, "ItemModifiedAppearance.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sKeyChainStore, db2Path, "KeyChain.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sOverrideSpellDataStore, db2Path, "OverrideSpellData.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sPhaseGroupStore, db2Path, "PhaseXPhaseGroup.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellAuraRestrictionsStore, db2Path, "SpellAuraRestrictions.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellCastingRequirementsStore, db2Path, "SpellCastingRequirements.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellClassOptionsStore, db2Path, "SpellClassOptions.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellMiscStore, db2Path, "SpellMisc.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellPowerStore, db2Path, "SpellPower.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellReagentsStore, db2Path, "SpellReagents.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellRuneCostStore, db2Path, "SpellRuneCost.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sSpellTotemsStore, db2Path, "SpellTotems.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sTaxiNodesStore, db2Path, "TaxiNodes.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sTaxiPathStore, db2Path, "TaxiPath.db2"); - LoadDB2(availableDb2Locales, bad_db2_files, sTaxiPathNodeStore, db2Path, "TaxiPathNode.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sBroadcastTextStore, db2Path, "BroadcastText.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sCurvePointStore, db2Path, "CurvePoint.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sHolidaysStore, db2Path, "Holidays.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemStore, db2Path, "Item.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemAppearanceStore, db2Path, "ItemAppearance.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemBonusStore, db2Path, "ItemBonus.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemEffectStore, db2Path, "ItemEffect.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemModifiedAppearanceStore, db2Path, "ItemModifiedAppearance.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sItemSparseStore, db2Path, "Item-sparse.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sKeyChainStore, db2Path, "KeyChain.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sOverrideSpellDataStore, db2Path, "OverrideSpellData.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sPhaseGroupStore, db2Path, "PhaseXPhaseGroup.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellAuraRestrictionsStore, db2Path, "SpellAuraRestrictions.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellCastingRequirementsStore, db2Path, "SpellCastingRequirements.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellClassOptionsStore, db2Path, "SpellClassOptions.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellMiscStore, db2Path, "SpellMisc.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellPowerStore, db2Path, "SpellPower.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellReagentsStore, db2Path, "SpellReagents.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellRuneCostStore, db2Path, "SpellRuneCost.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sSpellTotemsStore, db2Path, "SpellTotems.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sTaxiNodesStore, db2Path, "TaxiNodes.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sTaxiPathStore, db2Path, "TaxiPath.db2"); + LoadDB2(availableDb2Locales, bad_db2_files, _stores, sTaxiPathNodeStore, db2Path, "TaxiPathNode.db2"); for (uint32 i = 0; i < sItemBonusStore.GetNumRows(); ++i) if (ItemBonusEntry const* bonus = sItemBonusStore.LookupEntry(i)) - ItemBonusLists[bonus->BonusListID].push_back(bonus); + _itemBonusLists[bonus->BonusListID].push_back(bonus); for (uint32 i = 0; i < sItemModifiedAppearanceStore.GetNumRows(); ++i) if (ItemModifiedAppearanceEntry const* appearanceMod = sItemModifiedAppearanceStore.LookupEntry(i)) if (ItemAppearanceEntry const* appearance = sItemAppearanceStore.LookupEntry(appearanceMod->AppearanceID)) - ItemDisplayMap[appearanceMod->ItemID | (appearanceMod->AppearanceModID << 24)] = appearance->DisplayID; + _itemDisplayIDs[appearanceMod->ItemID | (appearanceMod->AppearanceModID << 24)] = appearance->DisplayID; { std::set<uint32> scalingCurves; @@ -175,7 +162,7 @@ void LoadDB2Stores(std::string const& dataPath) for (uint32 i = 0; i < sCurvePointStore.GetNumRows(); ++i) if (CurvePointEntry const* curvePoint = sCurvePointStore.LookupEntry(i)) if (scalingCurves.count(curvePoint->CurveID)) - HeirloomCurvePoints[curvePoint->CurveID][curvePoint->Index] = curvePoint; + _heirloomCurvePoints[curvePoint->CurveID][curvePoint->Index] = curvePoint; } for (uint32 i = 0; i < sSpellPowerStore.GetNumRows(); ++i) @@ -185,7 +172,7 @@ void LoadDB2Stores(std::string const& dataPath) for (uint32 i = 0; i < sPhaseGroupStore.GetNumRows(); ++i) if (PhaseGroupEntry const* group = sPhaseGroupStore.LookupEntry(i)) if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID)) - sPhasesByGroup[group->PhaseGroupID].insert(phase->ID); + _phasesByGroup[group->PhaseGroupID].insert(phase->ID); for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) @@ -301,16 +288,59 @@ void LoadDB2Stores(std::string const& dataPath) TC_LOG_INFO("misc", ">> Initialized %d DB2 data stores.", DB2FilesCount); } -DB2StorageBase const* GetDB2Storage(uint32 type) +DB2StorageBase const* DB2Manager::GetStorage(uint32 type) const { - DB2StorageMap::const_iterator itr = DB2Stores.find(type); - if (itr != DB2Stores.end()) + StorageMap::const_iterator itr = _stores.find(type); + if (itr != _stores.end()) return itr->second; - return NULL; + return nullptr; } -char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale /*= DEFAULT_LOCALE*/, uint8 gender /*= GENDER_MALE*/, bool forceGender /*= false*/) +void DB2Manager::LoadHotfixData() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = HotfixDatabase.Query("SELECT TableHash, RecordID, `Timestamp` FROM hotfix_data"); + + if (!result) + { + TC_LOG_INFO("misc", ">> Loaded 0 hotfix info entries."); + return; + } + + uint32 count = 0; + + _hotfixData.reserve(result->GetRowCount()); + + do + { + Field* fields = result->Fetch(); + + HotfixNotify info; + info.TableHash = fields[0].GetUInt32(); + info.Entry = fields[1].GetUInt32(); + info.Timestamp = fields[2].GetUInt32(); + _hotfixData.push_back(info); + + ++count; + } while (result->NextRow()); + + TC_LOG_INFO("misc", ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +time_t DB2Manager::GetHotfixDate(uint32 entry, uint32 type) const +{ + time_t ret = 0; + for (HotfixNotify const& hotfix : _hotfixData) + if (hotfix.Entry == entry && hotfix.TableHash == type) + if (time_t(hotfix.Timestamp) > ret) + ret = time_t(hotfix.Timestamp); + + return ret ? ret : time(NULL); +} + +char const* DB2Manager::GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale /*= DEFAULT_LOCALE*/, uint8 gender /*= GENDER_MALE*/, bool forceGender /*= false*/) { if (gender == GENDER_FEMALE && (forceGender || broadcastText->FemaleText->Str[DEFAULT_LOCALE][0] != '\0')) { @@ -326,11 +356,11 @@ char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, Local return broadcastText->MaleText->Str[DEFAULT_LOCALE]; } -uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level) +uint32 DB2Manager::GetHeirloomItemLevel(uint32 curveId, uint32 level) const { // Assuming linear item level scaling for heirlooms - auto itr = HeirloomCurvePoints.find(curveId); - if (itr == HeirloomCurvePoints.end()) + auto itr = _heirloomCurvePoints.find(curveId); + if (itr == _heirloomCurvePoints.end()) return 0; auto it2 = itr->second.begin(); // Highest scaling point @@ -345,33 +375,37 @@ uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level) return uint32(previousItr->second->Y); // Lowest scaling point } -uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) +uint32 DB2Manager::GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const { - auto itr = ItemDisplayMap.find(itemId | (appearanceModId << 24)); - if (itr != ItemDisplayMap.end()) + auto itr = _itemDisplayIDs.find(itemId | (appearanceModId << 24)); + if (itr != _itemDisplayIDs.end()) return itr->second; // Fall back to unmodified appearance if (appearanceModId) { - itr = ItemDisplayMap.find(itemId); - if (itr != ItemDisplayMap.end()) + itr = _itemDisplayIDs.find(itemId); + if (itr != _itemDisplayIDs.end()) return itr->second; } return 0; } -std::vector<ItemBonusEntry const*> GetItemBonuses(uint32 bonusListId) +DB2Manager::ItemBonusList DB2Manager::GetItemBonusList(uint32 bonusListId) const { - auto itr = ItemBonusLists.find(bonusListId); - if (itr != ItemBonusLists.end()) + auto itr = _itemBonusLists.find(bonusListId); + if (itr != _itemBonusLists.end()) return itr->second; - return std::vector<ItemBonusEntry const*>(); + return ItemBonusList(); } -std::set<uint32> const& GetPhasesForGroup(uint32 group) +std::set<uint32> DB2Manager::GetPhasesForGroup(uint32 group) const { - return sPhasesByGroup[group]; + auto itr = _phasesByGroup.find(group); + if (itr != _phasesByGroup.end()) + return itr->second; + + return std::set<uint32>(); } diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index d68c27987e1..01b28e6ec72 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -53,14 +53,54 @@ extern TaxiMask sDeathKnightTaxiNodesMask; extern TaxiPathSetBySource sTaxiPathSetBySource; extern TaxiPathNodesByPath sTaxiPathNodesByPath; -void LoadDB2Stores(std::string const& dataPath); +struct HotfixNotify +{ + uint32 TableHash; + uint32 Timestamp; + uint32 Entry; +}; -DB2StorageBase const* GetDB2Storage(uint32 type); +typedef std::vector<HotfixNotify> HotfixData; -char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); -uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level); -uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId); -std::vector<ItemBonusEntry const*> GetItemBonuses(uint32 bonusListId); -std::set<uint32> const& GetPhasesForGroup(uint32 group); +class DB2Manager +{ +public: + typedef std::map<uint32 /*hash*/, DB2StorageBase*> StorageMap; + typedef std::map<uint32 /*curveID*/, std::map<uint32/*index*/, CurvePointEntry const*, std::greater<uint32>>> HeirloomCurvesContainer; + typedef std::unordered_map<uint32 /*itemId | appearanceMod << 24*/, uint32> ItemDisplayIdContainer; + typedef std::vector<ItemBonusEntry const*> ItemBonusList; + typedef std::unordered_map<uint32 /*bonusListId*/, ItemBonusList> ItemBonusListContainer; + typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer; + + static DB2Manager& Instance() + { + static DB2Manager instance; + return instance; + } + + void LoadStores(std::string const& dataPath); + DB2StorageBase const* GetStorage(uint32 type) const; + + void LoadHotfixData(); + HotfixData const* GetHotfixData() const { return &_hotfixData; } + time_t GetHotfixDate(uint32 entry, uint32 type) const; + + static char const* GetBroadcastTextValue(BroadcastTextEntry const* broadcastText, LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false); + uint32 GetHeirloomItemLevel(uint32 curveId, uint32 level) const; + uint32 GetItemDisplayId(uint32 itemId, uint32 appearanceModId) const; + ItemBonusList GetItemBonusList(uint32 bonusListId) const; + std::set<uint32> GetPhasesForGroup(uint32 group) const; + +private: + StorageMap _stores; + HotfixData _hotfixData; + + HeirloomCurvesContainer _heirloomCurvePoints; + ItemDisplayIdContainer _itemDisplayIDs; + ItemBonusListContainer _itemBonusLists; + PhaseGroupContainer _phasesByGroup; +}; + +#define sDB2Manager DB2Manager::Instance() #endif diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 3416e562ad3..cdc83b70b2b 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -411,5 +411,4 @@ typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; #define TaxiMaskSize 114 typedef uint8 TaxiMask[TaxiMaskSize]; -typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer; #endif diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 499c87e8c58..839cff33a47 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -746,7 +746,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 /*phaseMask* SetInPhase(data->phaseid, false, true); if (data && data->phaseGroup) - for (auto ph : GetPhasesForGroup(data->phaseGroup)) + for (auto ph : sDB2Manager.GetPhasesForGroup(data->phaseGroup)) SetInPhase(ph, false, true); CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 9a6dc5879fd..270b6b67349 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -99,13 +99,13 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, ui /// OptionText if (optionBroadcastText) - strOptionText = GetBroadcastTextValue(optionBroadcastText, GetLocale()); + strOptionText = DB2Manager::GetBroadcastTextValue(optionBroadcastText, GetLocale()); else strOptionText = itr->second.OptionText; /// BoxText if (boxBroadcastText) - strBoxText = GetBroadcastTextValue(boxBroadcastText, GetLocale()); + strBoxText = DB2Manager::GetBroadcastTextValue(boxBroadcastText, GetLocale()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 382bf45052b..f3729ceb710 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -875,7 +875,7 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool a if (data->phaseGroup) { // Set the gameobject in all the phases of the phasegroup - for (auto ph : GetPhasesForGroup(data->phaseGroup)) + for (auto ph : sDB2Manager.GetPhasesForGroup(data->phaseGroup)) SetInPhase(ph, false, true); } diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 92d66d6808b..dc1b14f10f7 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -502,7 +502,7 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fi for (char const* token : bonusListIDs) { uint32 bonusListID = atoul(token); - std::vector<ItemBonusEntry const*> bonuses = GetItemBonuses(bonusListID); + DB2Manager::ItemBonusList bonuses = sDB2Manager.GetItemBonusList(bonusListID); AddDynamicValue(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS, bonusListID); for (ItemBonusEntry const* bonus : bonuses) _bonusData.AddBonus(bonus->Type, bonus->Value); @@ -1745,7 +1745,7 @@ uint32 Item::GetItemLevel() const uint32 itemLevel = stats->GetBaseItemLevel(); if (Player const* owner = GetOwner()) if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(stats->GetScalingStatDistribution())) - if (uint32 heirloomIlvl = GetHeirloomItemLevel(ssd->ItemLevelCurveID, owner->getLevel())) + if (uint32 heirloomIlvl = sDB2Manager.GetHeirloomItemLevel(ssd->ItemLevelCurveID, owner->getLevel())) itemLevel = heirloomIlvl; return std::min(std::max(itemLevel + _bonusData.ItemLevel, uint32(MIN_ITEM_LEVEL)), uint32(MAX_ITEM_LEVEL)); @@ -1769,9 +1769,9 @@ int32 Item::GetItemStatValue(uint32 index) const uint32 Item::GetDisplayId() const { if (uint32 transmogrification = GetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID)) - return GetItemDisplayId(transmogrification, GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD)); + return sDB2Manager.GetItemDisplayId(transmogrification, GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD)); - return GetItemDisplayId(GetEntry(), GetAppearanceModId()); + return sDB2Manager.GetItemDisplayId(GetEntry(), GetAppearanceModId()); } void Item::SetModifier(ItemModifier modifier, uint32 value) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ad95e908840..367f1f57d3a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -13857,12 +13857,12 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool LocaleConstant locale = GetSession()->GetSessionDbLocaleIndex(); if (optionBroadcastText) - strOptionText = GetBroadcastTextValue(optionBroadcastText, locale, getGender()); + strOptionText = DB2Manager::GetBroadcastTextValue(optionBroadcastText, locale, getGender()); else strOptionText = itr->second.OptionText; if (boxBroadcastText) - strBoxText = GetBroadcastTextValue(boxBroadcastText, locale, getGender()); + strBoxText = DB2Manager::GetBroadcastTextValue(boxBroadcastText, locale, getGender()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 046d9f7824e..03703c528c4 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -313,7 +313,7 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c if (data->phaseid) creature->SetInPhase(data->phaseid, false, true); else if (data->phaseGroup) - for (auto phase : GetPhasesForGroup(data->phaseGroup)) + for (auto phase : sDB2Manager.GetPhasesForGroup(data->phaseGroup)) creature->SetInPhase(phase, false, true); else for (auto phase : GetPhases()) // Set the creature to the transport's phases diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ed696517be9..87f01633a8a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16503,6 +16503,6 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); WorldPackets::Chat::Chat packet; - packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); + packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, DB2Manager::GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); target->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 16958a2dde8..dd2a1697e6a 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8507,39 +8507,6 @@ void ObjectMgr::LoadFactionChangeReputations() TC_LOG_INFO("server.loading", ">> Loaded %u faction change reputation pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadHotfixData() -{ - uint32 oldMSTime = getMSTime(); - - QueryResult result = WorldDatabase.Query("SELECT entry, type, UNIX_TIMESTAMP(hotfixDate) FROM hotfix_data"); - - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 hotfix info entries. DB table `hotfix_data` is empty."); - return; - } - - uint32 count = 0; - - _hotfixData.reserve(result->GetRowCount()); - - do - { - Field* fields = result->Fetch(); - - HotfixInfo info; - info.Entry = fields[0].GetUInt32(); - info.Type = fields[1].GetUInt32(); - info.Timestamp = fields[2].GetUInt64(); - _hotfixData.push_back(info); - - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - void ObjectMgr::LoadFactionChangeSpells() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 17873be4252..e8b102e2741 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -673,15 +673,6 @@ struct DungeonEncounter typedef std::list<DungeonEncounter const*> DungeonEncounterList; typedef std::unordered_map<uint32, DungeonEncounterList> DungeonEncounterContainer; -struct HotfixInfo -{ - uint32 Type; - uint32 Timestamp; - uint32 Entry; -}; - -typedef std::vector<HotfixInfo> HotfixData; - class PlayerDumpReader; class ObjectMgr @@ -1288,19 +1279,6 @@ class ObjectMgr bool IsTransportMap(uint32 mapId) const { return _transportMaps.count(mapId) != 0; } - void LoadHotfixData(); - HotfixData const& GetHotfixData() const { return _hotfixData; } - time_t GetHotfixDate(uint32 entry, uint32 type) const - { - time_t ret = 0; - for (HotfixData::const_iterator itr = _hotfixData.begin(); itr != _hotfixData.end(); ++itr) - if (itr->Entry == entry && itr->Type == type) - if (time_t(itr->Timestamp) > ret) - ret = time_t(itr->Timestamp); - - return ret ? ret : time(NULL); - } - void LoadRaceAndClassExpansionRequirements(); void LoadRealmNames(); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index de7d44bdc69..706d45c1bc4 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -44,6 +44,7 @@ #include "Pet.h" #include "PlayerDump.h" #include "Player.h" +#include "QueryPackets.h" #include "ReputationMgr.h" #include "ScriptMgr.h" #include "SharedDefines.h" @@ -927,17 +928,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) data << uint64(0); SendPacket(&data); - data.Initialize(SMSG_HOTFIX_INFO); - HotfixData const& hotfix = sObjectMgr->GetHotfixData(); - data.WriteBits(hotfix.size(), 22); - data.FlushBits(); - for (uint32 i = 0; i < hotfix.size(); ++i) - { - data << uint32(hotfix[i].Type); - data << uint32(hotfix[i].Timestamp); - data << uint32(hotfix[i].Entry); - } - SendPacket(&data); + WorldPackets::Query::HotfixNotifyBlob hotfixInfo; + hotfixInfo.Hotfixes = sDB2Manager.GetHotfixData(); + SendPacket(hotfixInfo.Write()); pCurrChar->SendInitialPacketsBeforeAddToMap(); diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index fb8e45f5f42..4beddd757da 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -247,7 +247,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& p WorldPackets::Query::QueryNPCTextResponse response; response.TextID = packet.TextID; - + if (gossip) { for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) @@ -268,7 +268,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& p void WorldSession::HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_PAGE_TEXT_QUERY"); - + uint32 pageID = packet.PageTextID; while (pageID) @@ -287,7 +287,7 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& { response.Allow = true; response.Info.ID = pageID; - + int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) if (PageTextLocale const* player = sObjectMgr->GetPageTextLocale(pageID)) @@ -296,7 +296,7 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& response.Info.NextPageID = pageText->NextPageID; pageID = pageText->NextPageID; } - + SendPacket(response.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE"); @@ -434,7 +434,7 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) { - DB2StorageBase const* store = GetDB2Storage(packet.TableHash); + DB2StorageBase const* store = sDB2Manager.GetStorage(packet.TableHash); if (!store) { TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Received unknown hotfix type: %u", packet.TableHash); @@ -450,7 +450,7 @@ void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) { response.RecordID = rec.RecordID; response.Locale = GetSessionDbcLocale(); - response.Timestamp = sObjectMgr->GetHotfixDate(rec.RecordID, packet.TableHash); + response.Timestamp = sDB2Manager.GetHotfixDate(rec.RecordID, packet.TableHash); response.Data = store; } else @@ -459,7 +459,7 @@ void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) response.RecordID = -int32(rec.RecordID); response.Timestamp = time(NULL); } - + SendPacket(response.Write()); } } diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index 19e2e436692..e083016df94 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -395,7 +395,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid trans->SetInPhase(phaseid, false, true); if (phasegroup) - for (auto ph : GetPhasesForGroup(phasegroup)) + for (auto ph : sDB2Manager.GetPhasesForGroup(phasegroup)) trans->SetInPhase(ph, false, true); if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId)) diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index cc34132b142..98f697bc8ad 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -232,7 +232,7 @@ void OutdoorPvPMgr::HandlePlayerResurrects(Player* player, uint32 zoneid) std::string OutdoorPvPMgr::GetDefenseMessage(uint32 zoneId, uint32 id, LocaleConstant locale) const { if (BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(id)) - return GetBroadcastTextValue(bct, locale); + return DB2Manager::GetBroadcastTextValue(bct, locale); TC_LOG_ERROR("outdoorpvp", "Can not find DefenseMessage (Zone: %u, Id: %u). BroadcastText (Id: %u) does not exist.", zoneId, id, id); return ""; diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index 335d261651a..f100013d7a4 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -208,3 +208,16 @@ WorldPacket const* WorldPackets::Query::DBReply::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Query::HotfixNotifyBlob::Write() +{ + _worldPacket << uint32(Hotfixes->size()); + for (HotfixNotify const& hotfix : *Hotfixes) + { + _worldPacket << uint32(hotfix.TableHash); + _worldPacket << int32(hotfix.Entry); + _worldPacket << uint32(hotfix.Timestamp); + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index 8b6eae8db56..4581c20c6e5 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -200,6 +200,16 @@ namespace WorldPackets uint32 Locale = 0; DB2StorageBase const* Data = nullptr; }; + + class HotfixNotifyBlob final : public ServerPacket + { + public: + HotfixNotifyBlob() : ServerPacket(SMSG_HOTFIX_NOTIFY_BLOB, 4) { } + + WorldPacket const* Write() override; + + HotfixData const* Hotfixes = nullptr; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index eff113b89c3..e18e5e984ac 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1012,8 +1012,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY_BLOB, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 68260414325..68fd9c30d48 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1008,8 +1008,8 @@ enum OpcodeServer : uint32 SMSG_GUILD_XP_UPDATE = 0xBADD, SMSG_HEALTH_UPDATE = 0xBADD, SMSG_HIGHEST_THREAT_UPDATE = 0x059A, - SMSG_HOTFIX_INFO = 0x1D1D, SMSG_HOTFIX_NOTIFY = 0xBADD, + SMSG_HOTFIX_NOTIFY_BLOB = 0x1D1D, SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0xBADD, SMSG_IGNORE_REQUIREMENTS_CHEAT = 0xBADD, SMSG_INITIALIZE_FACTIONS = 0x0B10, diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 9acd683fe92..21edb53d3ad 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1731,7 +1731,7 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo Unit* target = aurApp->GetTarget(); std::set<uint32> const& oldPhases = target->GetPhases(); - std::set<uint32> const& phases = GetPhasesForGroup(GetMiscValueB()); + std::set<uint32> phases = sDB2Manager.GetPhasesForGroup(GetMiscValueB()); for (auto phase : phases) target->SetInPhase(phase, false, apply); diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index 6e7a5738394..14148e0f38e 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -34,7 +34,7 @@ namespace Trinity { BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(_textId); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); + packet.Initalize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 16a1bde5a96..d0e0e5e325d 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -502,7 +502,7 @@ std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 gender, BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(groupItr->BroadcastTextId); if (bct) - baseText = GetBroadcastTextValue(bct, locale, gender); + baseText = DB2Manager::GetBroadcastTextValue(bct, locale, gender); else baseText = groupItr->text; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 7f0ea4cd583..eddad11e593 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1416,7 +1416,7 @@ void World::SetInitialWorldSettings() ///- Load the DBC files TC_LOG_INFO("server.loading", "Initialize data stores..."); LoadDBCStores(m_dataPath); - LoadDB2Stores(m_dataPath); + sDB2Manager.LoadStores(m_dataPath); sSpellMgr->LoadPetFamilySpellsStore(); @@ -1922,7 +1922,7 @@ void World::SetInitialWorldSettings() LoadCharacterInfoStore(); TC_LOG_INFO("misc", "Loading hotfix info..."); - sObjectMgr->LoadHotfixData(); + sDB2Manager.LoadHotfixData(); TC_LOG_INFO("server.loading", "Loading race and class expansion requirements..."); sObjectMgr->LoadRaceAndClassExpansionRequirements(); diff --git a/src/server/shared/DataStores/DB2StorageLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp index f716b9e805e..928ee5e8e91 100644 --- a/src/server/shared/DataStores/DB2StorageLoader.cpp +++ b/src/server/shared/DataStores/DB2StorageLoader.cpp @@ -494,7 +494,7 @@ char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint3 case FT_STRING: { LocalizedString** slot = (LocalizedString**)(&dataTable[offset]); - *slot = (LocalizedString*)(&stringHolders[stringHoldersRecordPoolSize * rec++ + stringHolderSize * stringFieldNumInRecord]); + *slot = (LocalizedString*)(&stringHolders[stringHoldersRecordPoolSize * rec + stringHolderSize * stringFieldNumInRecord]); // Value in database in main table field must be for enUS locale if (char* str = AddLocaleString(*slot, LOCALE_enUS, fields[f].GetString())) @@ -510,6 +510,8 @@ char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint3 } } } + + ++rec; } while (result->NextRow()); // Reallocate index if needed |