mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/DataStores: Added an extra safeguard for loading db2 hotfix locale tables - invalid row will no longer cause crashes
This commit is contained in:
@@ -1135,8 +1135,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
return false;
|
||||
}
|
||||
|
||||
PhaseGroupEntry const* phase = sPhaseGroupStore.LookupEntry(phaseGroup);
|
||||
if (!phase)
|
||||
if (sDB2Manager.GetPhasesForGroup(phaseGroup).empty())
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid phase group id %u for creature " SI64FMTD ", skipped", phaseGroup, e.entryOrGuid);
|
||||
return false;
|
||||
|
||||
@@ -23,39 +23,39 @@
|
||||
#include "World.h"
|
||||
#include <functional>
|
||||
|
||||
DB2Storage<AreaGroupEntry> sAreaGroupStore(AreaGroupFormat, HOTFIX_SEL_AREA_GROUP);
|
||||
DB2Storage<AreaGroupMemberEntry> sAreaGroupMemberStore(AreaGroupMemberFormat, HOTFIX_SEL_AREA_GROUP_MEMBER);
|
||||
DB2Storage<BroadcastTextEntry> sBroadcastTextStore(BroadcastTextFormat, HOTFIX_SEL_BROADCAST_TEXT);
|
||||
DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesFormat, HOTFIX_SEL_CURRENCY_TYPES);
|
||||
DB2Storage<CurvePointEntry> sCurvePointStore(CurvePointFormat, HOTFIX_SEL_CURVE_POINT);
|
||||
DB2Storage<HolidaysEntry> sHolidaysStore(HolidaysEntryFormat, HOTFIX_SEL_HOLIDAYS);
|
||||
DB2Storage<ItemAppearanceEntry> sItemAppearanceStore(ItemAppearanceFormat, HOTFIX_SEL_ITEM_APPEARANCE);
|
||||
DB2Storage<ItemBonusEntry> sItemBonusStore(ItemBonusFormat, HOTFIX_SEL_ITEM_BONUS);
|
||||
DB2Storage<ItemBonusTreeNodeEntry> sItemBonusTreeNodeStore(ItemBonusTreeNodeFormat, HOTFIX_SEL_ITEM_BONUS_TREE_NODE);
|
||||
DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore(ItemCurrencyCostFormat, HOTFIX_SEL_ITEM_CURRENCY_COST);
|
||||
DB2Storage<ItemEffectEntry> sItemEffectStore(ItemEffectFormat, HOTFIX_SEL_ITEM_EFFECT);
|
||||
DB2Storage<ItemEntry> sItemStore(ItemFormat, HOTFIX_SEL_ITEM);
|
||||
DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostFormat, HOTFIX_SEL_ITEM_EXTENDED_COST);
|
||||
DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore(ItemModifiedAppearanceFormat, HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE);
|
||||
DB2Storage<ItemSparseEntry> sItemSparseStore(ItemSparseFormat, HOTFIX_SEL_ITEM_SPARSE);
|
||||
DB2Storage<ItemXBonusTreeEntry> sItemXBonusTreeStore(ItemXBonusTreeFormat, HOTFIX_SEL_ITEM_X_BONUS_TREE);
|
||||
DB2Storage<KeyChainEntry> sKeyChainStore(KeyChainFormat, HOTFIX_SEL_KEY_CHAIN);
|
||||
DB2Storage<MountEntry> sMountStore(MountFormat, HOTFIX_SEL_MOUNT);
|
||||
DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore(OverrideSpellDataFormat, HOTFIX_SEL_OVERRIDE_SPELL_DATA);
|
||||
DB2Storage<PhaseGroupEntry> sPhaseGroupStore(PhaseGroupFormat, HOTFIX_SEL_PHASE_GROUP);
|
||||
DB2Storage<SoundEntriesEntry> sSoundEntriesStore(SoundEntriesFormat, HOTFIX_SEL_SOUND_ENTRIES);
|
||||
DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore(SpellAuraRestrictionsFormat, HOTFIX_SEL_SPELL_AURA_RESTRICTIONS);
|
||||
DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore(SpellCastingRequirementsFormat, HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS);
|
||||
DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore(SpellClassOptionsFormat, HOTFIX_SEL_SPELL_CLASS_OPTIONS);
|
||||
DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore(SpellLearnSpellFormat, HOTFIX_SEL_SPELL_LEARN_SPELL);
|
||||
DB2Storage<SpellMiscEntry> sSpellMiscStore(SpellMiscFormat, HOTFIX_SEL_SPELL_MISC);
|
||||
DB2Storage<SpellPowerEntry> sSpellPowerStore(SpellPowerFormat, HOTFIX_SEL_SPELL_POWER);
|
||||
DB2Storage<SpellReagentsEntry> sSpellReagentsStore(SpellReagentsFormat, HOTFIX_SEL_SPELL_REAGENTS);
|
||||
DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostFormat, HOTFIX_SEL_SPELL_RUNE_COST);
|
||||
DB2Storage<SpellTotemsEntry> sSpellTotemsStore(SpellTotemsFormat, HOTFIX_SEL_SPELL_TOTEMS);
|
||||
DB2Storage<TaxiNodesEntry> sTaxiNodesStore(TaxiNodesFormat, HOTFIX_SEL_TAXI_NODES);
|
||||
DB2Storage<TaxiPathEntry> sTaxiPathStore(TaxiPathFormat, HOTFIX_SEL_TAXI_PATH);
|
||||
DB2Storage<TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeFormat, HOTFIX_SEL_TAXI_PATH_NODE);
|
||||
DB2Storage<AreaGroupEntry> sAreaGroupStore("AreaGroup.db2", AreaGroupFormat, HOTFIX_SEL_AREA_GROUP);
|
||||
DB2Storage<AreaGroupMemberEntry> sAreaGroupMemberStore("AreaGroupMember.db2", AreaGroupMemberFormat, HOTFIX_SEL_AREA_GROUP_MEMBER);
|
||||
DB2Storage<BroadcastTextEntry> sBroadcastTextStore("BroadcastText.db2", BroadcastTextFormat, HOTFIX_SEL_BROADCAST_TEXT);
|
||||
DB2Storage<CurrencyTypesEntry> sCurrencyTypesStore("CurrencyTypes.db2", CurrencyTypesFormat, HOTFIX_SEL_CURRENCY_TYPES);
|
||||
DB2Storage<CurvePointEntry> sCurvePointStore("CurvePoint.db2", CurvePointFormat, HOTFIX_SEL_CURVE_POINT);
|
||||
DB2Storage<HolidaysEntry> sHolidaysStore("Holidays.db2", HolidaysEntryFormat, HOTFIX_SEL_HOLIDAYS);
|
||||
DB2Storage<ItemAppearanceEntry> sItemAppearanceStore("ItemAppearance.db2", ItemAppearanceFormat, HOTFIX_SEL_ITEM_APPEARANCE);
|
||||
DB2Storage<ItemBonusEntry> sItemBonusStore("ItemBonus.db2", ItemBonusFormat, HOTFIX_SEL_ITEM_BONUS);
|
||||
DB2Storage<ItemBonusTreeNodeEntry> sItemBonusTreeNodeStore("ItemBonusTreeNode.db2", ItemBonusTreeNodeFormat, HOTFIX_SEL_ITEM_BONUS_TREE_NODE);
|
||||
DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore("ItemCurrencyCost.db2", ItemCurrencyCostFormat, HOTFIX_SEL_ITEM_CURRENCY_COST);
|
||||
DB2Storage<ItemEffectEntry> sItemEffectStore("ItemEffect.db2", ItemEffectFormat, HOTFIX_SEL_ITEM_EFFECT);
|
||||
DB2Storage<ItemEntry> sItemStore("Item.db2", ItemFormat, HOTFIX_SEL_ITEM);
|
||||
DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore("ItemExtendedCost.db2", ItemExtendedCostFormat, HOTFIX_SEL_ITEM_EXTENDED_COST);
|
||||
DB2Storage<ItemModifiedAppearanceEntry> sItemModifiedAppearanceStore("ItemModifiedAppearance.db2", ItemModifiedAppearanceFormat, HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE);
|
||||
DB2Storage<ItemSparseEntry> sItemSparseStore("Item-sparse.db2", ItemSparseFormat, HOTFIX_SEL_ITEM_SPARSE);
|
||||
DB2Storage<ItemXBonusTreeEntry> sItemXBonusTreeStore("ItemXBonusTree.db2", ItemXBonusTreeFormat, HOTFIX_SEL_ITEM_X_BONUS_TREE);
|
||||
DB2Storage<KeyChainEntry> sKeyChainStore("KeyChain.db2", KeyChainFormat, HOTFIX_SEL_KEY_CHAIN);
|
||||
DB2Storage<MountEntry> sMountStore("Mount.db2", MountFormat, HOTFIX_SEL_MOUNT);
|
||||
DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore("OverrideSpellData.db2", OverrideSpellDataFormat, HOTFIX_SEL_OVERRIDE_SPELL_DATA);
|
||||
DB2Storage<PhaseXPhaseGroupEntry> sPhaseXPhaseGroupStore("PhaseXPhaseGroup.db2", PhaseXPhaseGroupFormat, HOTFIX_SEL_PHASE_GROUP);
|
||||
DB2Storage<SoundEntriesEntry> sSoundEntriesStore("SoundEntries.db2", SoundEntriesFormat, HOTFIX_SEL_SOUND_ENTRIES);
|
||||
DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore("SpellAuraRestrictions.db2", SpellAuraRestrictionsFormat, HOTFIX_SEL_SPELL_AURA_RESTRICTIONS);
|
||||
DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore("SpellCastingRequirements.db2", SpellCastingRequirementsFormat, HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS);
|
||||
DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore("SpellClassOptions.db2", SpellClassOptionsFormat, HOTFIX_SEL_SPELL_CLASS_OPTIONS);
|
||||
DB2Storage<SpellLearnSpellEntry> sSpellLearnSpellStore("SpellLearnSpell.db2", SpellLearnSpellFormat, HOTFIX_SEL_SPELL_LEARN_SPELL);
|
||||
DB2Storage<SpellMiscEntry> sSpellMiscStore("SpellMisc.db2", SpellMiscFormat, HOTFIX_SEL_SPELL_MISC);
|
||||
DB2Storage<SpellPowerEntry> sSpellPowerStore("SpellPower.db2", SpellPowerFormat, HOTFIX_SEL_SPELL_POWER);
|
||||
DB2Storage<SpellReagentsEntry> sSpellReagentsStore("SpellReagents.db2", SpellReagentsFormat, HOTFIX_SEL_SPELL_REAGENTS);
|
||||
DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore("SpellRuneCost.db2", SpellRuneCostFormat, HOTFIX_SEL_SPELL_RUNE_COST);
|
||||
DB2Storage<SpellTotemsEntry> sSpellTotemsStore("SpellTotems.db2", SpellTotemsFormat, HOTFIX_SEL_SPELL_TOTEMS);
|
||||
DB2Storage<TaxiNodesEntry> sTaxiNodesStore("TaxiNodes.db2", TaxiNodesFormat, HOTFIX_SEL_TAXI_NODES);
|
||||
DB2Storage<TaxiPathEntry> sTaxiPathStore("TaxiPath.db2", TaxiPathFormat, HOTFIX_SEL_TAXI_PATH);
|
||||
DB2Storage<TaxiPathNodeEntry> sTaxiPathNodeStore("TaxiPathNode.db2", TaxiPathNodeFormat, HOTFIX_SEL_TAXI_PATH_NODE);
|
||||
|
||||
SpellPowerBySpellIDMap sSpellPowerBySpellIDStore;
|
||||
TaxiMask sTaxiNodesMask;
|
||||
@@ -71,17 +71,16 @@ typedef std::list<std::string> DB2StoreProblemList;
|
||||
uint32 DB2FilesCount = 0;
|
||||
|
||||
template<class T>
|
||||
inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, DB2Manager::StorageMap& stores, 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)
|
||||
{
|
||||
// compatibility format and C++ structure sizes
|
||||
ASSERT(DB2FileLoader::GetFormatRecordSize(storage->GetFormat()) == sizeof(T),
|
||||
"Size of '%s' set by format string (%u) not equal size of C++ structure (" SZFMTD ").",
|
||||
filename.c_str(), DB2FileLoader::GetFormatRecordSize(storage->GetFormat()), sizeof(T));
|
||||
storage->GetFileName().c_str(), DB2FileLoader::GetFormatRecordSize(storage->GetFormat()), sizeof(T));
|
||||
|
||||
++DB2FilesCount;
|
||||
|
||||
std::string db2_filename = db2_path + filename;
|
||||
if (storage->Load(db2_filename.c_str(), uint32(sWorld->GetDefaultDbcLocale())))
|
||||
if (storage->Load(db2_path, uint32(sWorld->GetDefaultDbcLocale())))
|
||||
{
|
||||
storage->LoadFromDB();
|
||||
|
||||
@@ -91,15 +90,8 @@ inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, D
|
||||
continue;
|
||||
|
||||
if (availableDb2Locales & (1 << i))
|
||||
{
|
||||
std::string localizedName(db2_path);
|
||||
localizedName.append(localeNames[i]);
|
||||
localizedName.push_back('/');
|
||||
localizedName.append(filename);
|
||||
|
||||
if (!storage->LoadStringsFrom(localizedName.c_str(), i))
|
||||
if (!storage->LoadStringsFrom((db2_path + localeNames[i] + '/'), i))
|
||||
availableDb2Locales &= ~(1 << i); // mark as not available for speedup next checks
|
||||
}
|
||||
|
||||
storage->LoadStringsFromDB(i);
|
||||
}
|
||||
@@ -107,16 +99,17 @@ inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, D
|
||||
else
|
||||
{
|
||||
// sort problematic db2 to (1) non compatible and (2) nonexistent
|
||||
if (FILE* f = fopen(db2_filename.c_str(), "rb"))
|
||||
if (FILE* f = fopen((db2_path + storage->GetFileName()).c_str(), "rb"))
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << db2_filename << " exists, and has " << storage->GetFieldCount() << " field(s) (expected " << strlen(storage->GetFormat()) << "). Extracted file might be from wrong client version.";
|
||||
stream << storage->GetFileName() << " exists, and has " << storage->GetFieldCount() << " field(s) (expected " << strlen(storage->GetFormat())
|
||||
<< "). Extracted file might be from wrong client version.";
|
||||
std::string buf = stream.str();
|
||||
errlist.push_back(buf);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
errlist.push_back(db2_filename);
|
||||
errlist.push_back(storage->GetFileName());
|
||||
}
|
||||
|
||||
stores[storage->GetHash()] = storage;
|
||||
@@ -131,39 +124,39 @@ void DB2Manager::LoadStores(std::string const& dataPath)
|
||||
DB2StoreProblemList bad_db2_files;
|
||||
uint32 availableDb2Locales = 0xFF;
|
||||
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sAreaGroupStore, db2Path, "AreaGroup.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sAreaGroupMemberStore, db2Path, "AreaGroupMember.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sBroadcastTextStore, db2Path, "BroadcastText.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sCurrencyTypesStore, db2Path, "CurrencyTypes.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, &sItemAppearanceStore, db2Path, "ItemAppearance.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemBonusStore, db2Path, "ItemBonus.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemBonusTreeNodeStore, db2Path, "ItemBonusTreeNode.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemEffectStore, db2Path, "ItemEffect.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemExtendedCostStore, db2Path, "ItemExtendedCost.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, &sItemStore, db2Path, "Item.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemXBonusTreeStore, db2Path, "ItemXBonusTree.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sKeyChainStore, db2Path, "KeyChain.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sMountStore, db2Path, "Mount.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, &sSoundEntriesStore, db2Path, "SoundEntries.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, &sSpellLearnSpellStore, db2Path, "SpellLearnSpell.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, &sTaxiPathNodeStore, db2Path, "TaxiPathNode.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sTaxiPathStore, db2Path, "TaxiPath.db2");
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sAreaGroupStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sAreaGroupMemberStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sBroadcastTextStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sCurrencyTypesStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sCurvePointStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sHolidaysStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemAppearanceStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemBonusStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemBonusTreeNodeStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemCurrencyCostStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemEffectStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemExtendedCostStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemModifiedAppearanceStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemSparseStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sItemXBonusTreeStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sKeyChainStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sMountStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sOverrideSpellDataStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sPhaseXPhaseGroupStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSoundEntriesStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellAuraRestrictionsStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellCastingRequirementsStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellClassOptionsStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellLearnSpellStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellMiscStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellPowerStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellReagentsStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellRuneCostStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sSpellTotemsStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sTaxiNodesStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sTaxiPathNodeStore, db2Path);
|
||||
LoadDB2(availableDb2Locales, bad_db2_files, _stores, &sTaxiPathStore, db2Path);
|
||||
|
||||
for (AreaGroupMemberEntry const* areaGroupMember : sAreaGroupMemberStore)
|
||||
_areaGroupMembers[areaGroupMember->AreaGroupID].push_back(areaGroupMember->AreaID);
|
||||
@@ -201,7 +194,7 @@ void DB2Manager::LoadStores(std::string const& dataPath)
|
||||
for (MountEntry const* mount : sMountStore)
|
||||
_mountsBySpellId[mount->SpellId] = mount;
|
||||
|
||||
for (PhaseGroupEntry const* group : sPhaseGroupStore)
|
||||
for (PhaseXPhaseGroupEntry const* group : sPhaseXPhaseGroupStore)
|
||||
if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID))
|
||||
_phasesByGroup[group->PhaseGroupID].insert(phase->ID);
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ extern DB2Storage<ItemEntry> sItemStore;
|
||||
extern DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore;
|
||||
extern DB2Storage<ItemSparseEntry> sItemSparseStore;
|
||||
extern DB2Storage<OverrideSpellDataEntry> sOverrideSpellDataStore;
|
||||
extern DB2Storage<PhaseGroupEntry> sPhaseGroupStore;
|
||||
extern DB2Storage<SoundEntriesEntry> sSoundEntriesStore;
|
||||
extern DB2Storage<SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore;
|
||||
extern DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore;
|
||||
|
||||
@@ -289,7 +289,7 @@ struct OverrideSpellDataEntry
|
||||
uint32 PlayerActionbarFileDataID; // 12
|
||||
};
|
||||
|
||||
struct PhaseGroupEntry
|
||||
struct PhaseXPhaseGroupEntry
|
||||
{
|
||||
uint32 ID;
|
||||
uint32 PhaseID;
|
||||
|
||||
@@ -37,7 +37,7 @@ char const ItemXBonusTreeFormat[] = "nii";
|
||||
char const KeyChainFormat[] = "nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
char const MountFormat[] = "niiisssiii";
|
||||
char const OverrideSpellDataFormat[] = "niiiiiiiiiiii";
|
||||
char const PhaseGroupFormat[] = "nii";
|
||||
char const PhaseXPhaseGroupFormat[] = "nii";
|
||||
char const SoundEntriesFormat[] = "nisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiififfiifffffii";
|
||||
char const SpellAuraRestrictionsFormat[] = "niiiiiiii";
|
||||
char const SpellCastingRequirementsFormat[] = "niiiiii";
|
||||
|
||||
@@ -18,10 +18,7 @@
|
||||
#include "Common.h"
|
||||
#include "DB2StorageLoader.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include "Log.h"
|
||||
|
||||
DB2FileLoader::DB2FileLoader()
|
||||
{
|
||||
@@ -422,7 +419,7 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin
|
||||
return stringPool;
|
||||
}
|
||||
|
||||
char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool)
|
||||
char* DB2DatabaseLoader::Load(const char* format, uint32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool)
|
||||
{
|
||||
// Even though this query is executed only once, prepared statement is used to send data from mysql server in binary format
|
||||
PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement));
|
||||
@@ -563,7 +560,7 @@ char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint3
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
void DB2DatabaseLoader::LoadStrings(const char* format, int32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool)
|
||||
void DB2DatabaseLoader::LoadStrings(const char* format, uint32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool)
|
||||
{
|
||||
PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(preparedStatement);
|
||||
stmt->setString(0, localeNames[locale]);
|
||||
@@ -588,35 +585,40 @@ void DB2DatabaseLoader::LoadStrings(const char* format, int32 preparedStatement,
|
||||
uint32 indexValue = fields[0].GetUInt32();
|
||||
|
||||
// Attempt to overwrite existing data
|
||||
char* dataValue = indexTable[indexValue];
|
||||
for (uint32 x = 0; x < fieldCount; x++)
|
||||
if (char* dataValue = indexTable[indexValue])
|
||||
{
|
||||
switch (format[x])
|
||||
for (uint32 x = 0; x < fieldCount; x++)
|
||||
{
|
||||
case FT_FLOAT:
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
offset += 4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
offset += 1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
switch (format[x])
|
||||
{
|
||||
// fill only not filled entries
|
||||
LocalizedString* db2str = *(LocalizedString**)(&dataValue[offset]);
|
||||
if (db2str->Str[locale] == nullStr)
|
||||
if (char* str = AddLocaleString(db2str, locale, fields[1 + stringFieldNumInRecord].GetString()))
|
||||
stringPool.push_back(str);
|
||||
case FT_FLOAT:
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
offset += 4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
offset += 1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
{
|
||||
// fill only not filled entries
|
||||
LocalizedString* db2str = *(LocalizedString**)(&dataValue[offset]);
|
||||
if (db2str->Str[locale] == nullStr)
|
||||
if (char* str = AddLocaleString(db2str, locale, fields[1 + stringFieldNumInRecord].GetString()))
|
||||
stringPool.push_back(str);
|
||||
|
||||
++stringFieldNumInRecord;
|
||||
offset += sizeof(char*);
|
||||
break;
|
||||
++stringFieldNumInRecord;
|
||||
offset += sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(offset == recordSize);
|
||||
ASSERT(offset == recordSize);
|
||||
}
|
||||
else
|
||||
TC_LOG_ERROR("sql.sql", "Hotfix locale table for storage %s references row that does not exist %u!", _storageName.c_str(), indexValue);
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
return;
|
||||
|
||||
@@ -109,9 +109,14 @@ private:
|
||||
class DB2DatabaseLoader
|
||||
{
|
||||
public:
|
||||
char* Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool);
|
||||
void LoadStrings(const char* format, int32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool);
|
||||
explicit DB2DatabaseLoader(std::string const& storageName) : _storageName(storageName) { }
|
||||
|
||||
char* Load(const char* format, uint32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool);
|
||||
void LoadStrings(const char* format, uint32 preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool);
|
||||
static char* AddLocaleString(LocalizedString* holder, uint32 locale, std::string const& value);
|
||||
|
||||
private:
|
||||
std::string _storageName;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,13 +48,20 @@ class DB2Storage : public DB2StorageBase
|
||||
public:
|
||||
typedef DBStorageIterator<T> iterator;
|
||||
|
||||
DB2Storage(char const* f, int32 preparedStmtIndex)
|
||||
: _indexTableSize(0), _fieldCount(0), _format(f), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
|
||||
DB2Storage(char const* fileName, char const* format, uint32 preparedStmtIndex)
|
||||
: _fileName(fileName), _indexTableSize(0), _fieldCount(0), _format(format), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
|
||||
{
|
||||
_indexTable.AsT = NULL;
|
||||
}
|
||||
|
||||
~DB2Storage() { Clear(); }
|
||||
~DB2Storage()
|
||||
{
|
||||
delete[] reinterpret_cast<char*>(_indexTable.AsT);
|
||||
delete[] reinterpret_cast<char*>(_dataTable);
|
||||
delete[] reinterpret_cast<char*>(_dataTableEx);
|
||||
for (char* stringPool : _stringPoolList)
|
||||
delete[] stringPool;
|
||||
}
|
||||
|
||||
bool HasRecord(uint32 id) const override { return id < _indexTableSize && _indexTable.AsT[id] != nullptr; }
|
||||
void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const override
|
||||
@@ -105,14 +112,15 @@ public:
|
||||
void EraseRecord(uint32 id) override { if (id < _indexTableSize) _indexTable.AsT[id] = nullptr; }
|
||||
|
||||
T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : _indexTable.AsT[id]; }
|
||||
std::string const& GetFileName() const { return _fileName; }
|
||||
uint32 GetNumRows() const { return _indexTableSize; }
|
||||
char const* GetFormat() const { return _format; }
|
||||
uint32 GetFieldCount() const { return _fieldCount; }
|
||||
bool Load(char const* fn, uint32 locale)
|
||||
bool Load(std::string const& path, uint32 locale)
|
||||
{
|
||||
DB2FileLoader db2;
|
||||
// Check if load was successful, only then continue
|
||||
if (!db2.Load(fn, _format))
|
||||
if (!db2.Load((path + _fileName).c_str(), _format))
|
||||
return false;
|
||||
|
||||
_fieldCount = db2.GetCols();
|
||||
@@ -135,7 +143,7 @@ public:
|
||||
return _indexTable.AsT != NULL;
|
||||
}
|
||||
|
||||
bool LoadStringsFrom(char const* fn, uint32 locale)
|
||||
bool LoadStringsFrom(std::string const& path, uint32 locale)
|
||||
{
|
||||
// DB2 must be already loaded using Load
|
||||
if (!_indexTable.AsT)
|
||||
@@ -143,7 +151,7 @@ public:
|
||||
|
||||
DB2FileLoader db2;
|
||||
// Check if load was successful, only then continue
|
||||
if (!db2.Load(fn, _format))
|
||||
if (!db2.Load((path + _fileName).c_str(), _format))
|
||||
return false;
|
||||
|
||||
// load strings from another locale db2 data
|
||||
@@ -155,11 +163,8 @@ public:
|
||||
|
||||
void LoadFromDB()
|
||||
{
|
||||
if (_hotfixStatement == -1)
|
||||
return;
|
||||
|
||||
char* extraStringHolders = nullptr;
|
||||
if (char* dataTable = DB2DatabaseLoader().Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPoolList))
|
||||
if (char* dataTable = DB2DatabaseLoader(_fileName).Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPoolList))
|
||||
_dataTableEx = reinterpret_cast<T*>(dataTable);
|
||||
|
||||
if (extraStringHolders)
|
||||
@@ -168,42 +173,17 @@ public:
|
||||
|
||||
void LoadStringsFromDB(uint32 locale)
|
||||
{
|
||||
if (_hotfixStatement == -1)
|
||||
return;
|
||||
|
||||
if (!DB2FileLoader::GetFormatStringFieldCount(_format))
|
||||
return;
|
||||
|
||||
DB2DatabaseLoader().LoadStrings(_format, _hotfixStatement + 1, locale, _indexTable.AsChar, _stringPoolList);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (!_indexTable.AsT)
|
||||
return;
|
||||
|
||||
delete[] reinterpret_cast<char*>(_indexTable.AsT);
|
||||
_indexTable.AsT = nullptr;
|
||||
|
||||
delete[] reinterpret_cast<char*>(_dataTable);
|
||||
_dataTable = nullptr;
|
||||
|
||||
delete[] reinterpret_cast<char*>(_dataTableEx);
|
||||
_dataTableEx = nullptr;
|
||||
|
||||
while (!_stringPoolList.empty())
|
||||
{
|
||||
delete[] _stringPoolList.front();
|
||||
_stringPoolList.pop_front();
|
||||
}
|
||||
|
||||
_indexTableSize = 0;
|
||||
DB2DatabaseLoader(_fileName).LoadStrings(_format, _hotfixStatement + 1, locale, _indexTable.AsChar, _stringPoolList);
|
||||
}
|
||||
|
||||
iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); }
|
||||
iterator end() { return iterator(_indexTable.AsT, _indexTableSize, _indexTableSize); }
|
||||
|
||||
private:
|
||||
std::string _fileName;
|
||||
uint32 _indexTableSize;
|
||||
uint32 _fieldCount;
|
||||
char const* _format;
|
||||
@@ -215,7 +195,7 @@ private:
|
||||
T* _dataTable;
|
||||
T* _dataTableEx;
|
||||
StringPoolList _stringPoolList;
|
||||
int32 _hotfixStatement;
|
||||
uint32 _hotfixStatement;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user