diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 19 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 13 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Utility.cpp | 163 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Utility.h | 40 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 165 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 76 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 3 | ||||
-rw-r--r-- | src/server/shared/DataStores/DB2FileLoader.cpp | 10 | ||||
-rw-r--r-- | src/server/shared/DataStores/DB2FileLoader.h | 7 | ||||
-rw-r--r-- | src/server/shared/DataStores/DB2Store.h | 100 |
12 files changed, 351 insertions, 251 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index f4570a1c17e..59926cd2b5c 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -17,17 +17,21 @@ #include "DB2Stores.h" #include "DB2fmt.h" +#include "DB2Utility.h" #include "Common.h" #include "Log.h" -DB2Storage<ItemEntry> sItemStore(Itemfmt); +DB2Storage<ItemEntry> sItemStore(Itemfmt, &DB2Utilities::HasItemEntry, &DB2Utilities::WriteItemDbReply); DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore(ItemCurrencyCostfmt); DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt); -DB2Storage<ItemSparseEntry> sItemSparseStore(ItemSparsefmt); +DB2Storage<ItemSparseEntry> sItemSparseStore(ItemSparsefmt, &DB2Utilities::HasItemSparseEntry, &DB2Utilities::WriteItemSparseDbReply); DB2Storage<KeyChainEntry> sKeyChainStore(KeyChainfmt); typedef std::list<std::string> StoreProblemList1; +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) @@ -70,6 +74,8 @@ inline void LoadDB2(StoreProblemList1& errlist, DB2Storage<T>& storage, std::str else errlist.push_back(db2_filename); } + + DB2Stores[storage.GetHash()] = &storage; } void LoadDB2Stores(std::string const& dataPath) @@ -109,3 +115,12 @@ void LoadDB2Stores(std::string const& dataPath) sLog->outInfo(LOG_FILTER_GENERAL, ">> Initialized %d DB2 data stores.", DB2FilesCount); } + +DB2StorageBase const* GetDB2Storage(uint32 type) +{ + DB2StorageMap::const_iterator itr = DB2Stores.find(type); + if (itr != DB2Stores.end()) + return itr->second; + + return NULL; +} diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index f57da14419c..17a92f98cde 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -22,15 +22,6 @@ #include "DB2Structure.h" #include <string> -enum DB2Hash -{ - DB2_HASH_ITEM = 0x50238EC2, - DB2_HASH_ITEM_CURRENCY_COST = 0x6FE05AE9, - DB2_HASH_ITEM_EXTENDED_COST = 0xBB858355, - DB2_HASH_ITEM_SPARSE = 0x919BE54E, - DB2_HASH_KEYCHAIN = 0x6D8A2694, -}; - extern DB2Storage<ItemEntry> sItemStore; extern DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore; extern DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore; @@ -39,4 +30,6 @@ extern DB2Storage<KeyChainEntry> sKeyChainStore; void LoadDB2Stores(std::string const& dataPath); -#endif
\ No newline at end of file +DB2StorageBase const* GetDB2Storage(uint32 type); + +#endif diff --git a/src/server/game/DataStores/DB2Utility.cpp b/src/server/game/DataStores/DB2Utility.cpp new file mode 100644 index 00000000000..4ff06298660 --- /dev/null +++ b/src/server/game/DataStores/DB2Utility.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2013 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "DB2Utility.h" +#include "ObjectMgr.h" + +inline bool ItemExists(uint32 id) +{ + return sObjectMgr->GetItemTemplate(id) != NULL; +} + +bool DB2Utilities::HasItemEntry(DB2Storage<ItemEntry> const& /*store*/, uint32 id) +{ + return ItemExists(id); +} + +bool DB2Utilities::HasItemSparseEntry(DB2Storage<ItemSparseEntry> const& /*store*/, uint32 id) +{ + return ItemExists(id); +} + +void DB2Utilities::WriteItemDbReply(DB2Storage<ItemEntry> const& /*store*/, uint32 id, ByteBuffer& buffer) +{ + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(id); + ASSERT(proto); + + buffer << uint32(proto->ItemId); + buffer << uint32(proto->Class); + buffer << uint32(proto->SubClass); + buffer << int32(proto->SoundOverrideSubclass); + buffer << uint32(proto->Material); + buffer << uint32(proto->DisplayInfoID); + buffer << uint32(proto->InventoryType); + buffer << uint32(proto->Sheath); +} + +void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*store*/, uint32 id, ByteBuffer& buffer) +{ + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(id); + ASSERT(proto); + + buffer << uint32(proto->ItemId); + buffer << uint32(proto->Quality); + buffer << uint32(proto->Flags); + buffer << uint32(proto->Flags2); + buffer << float(proto->Unk430_1); + buffer << float(proto->Unk430_2); + buffer << uint32(proto->BuyCount); + buffer << int32(proto->BuyPrice); + buffer << uint32(proto->SellPrice); + buffer << uint32(proto->InventoryType); + buffer << int32(proto->AllowableClass); + buffer << int32(proto->AllowableRace); + buffer << uint32(proto->ItemLevel); + buffer << uint32(proto->RequiredLevel); + buffer << uint32(proto->RequiredSkill); + buffer << uint32(proto->RequiredSkillRank); + buffer << uint32(proto->RequiredSpell); + buffer << uint32(proto->RequiredHonorRank); + buffer << uint32(proto->RequiredCityRank); + buffer << uint32(proto->RequiredReputationFaction); + buffer << uint32(proto->RequiredReputationRank); + buffer << int32(proto->MaxCount); + buffer << int32(proto->Stackable); + buffer << uint32(proto->ContainerSlots); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buffer << uint32(proto->ItemStat[x].ItemStatType); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buffer << int32(proto->ItemStat[x].ItemStatValue); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buffer << int32(proto->ItemStat[x].ItemStatUnk1); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) + buffer << int32(proto->ItemStat[x].ItemStatUnk2); + + buffer << uint32(proto->ScalingStatDistribution); + buffer << uint32(proto->DamageType); + buffer << uint32(proto->Delay); + buffer << float(proto->RangedModRange); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buffer << int32(proto->Spells[x].SpellId); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buffer << uint32(proto->Spells[x].SpellTrigger); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buffer << int32(proto->Spells[x].SpellCharges); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buffer << int32(proto->Spells[x].SpellCooldown); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buffer << uint32(proto->Spells[x].SpellCategory); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) + buffer << int32(proto->Spells[x].SpellCategoryCooldown); + + buffer << uint32(proto->Bonding); + + // item name + std::string name = proto->Name1; + buffer << uint16(name.length()); + if (name.length()) + buffer << name; + + for (uint32 i = 0; i < 3; ++i) // other 3 names + buffer << uint16(0); + + std::string desc = proto->Description; + buffer << uint16(desc.length()); + if (desc.length()) + buffer << desc; + + buffer << uint32(proto->PageText); + buffer << uint32(proto->LanguageID); + buffer << uint32(proto->PageMaterial); + buffer << uint32(proto->StartQuest); + buffer << uint32(proto->LockID); + buffer << int32(proto->Material); + buffer << uint32(proto->Sheath); + buffer << int32(proto->RandomProperty); + buffer << int32(proto->RandomSuffix); + buffer << uint32(proto->ItemSet); + + buffer << uint32(proto->Area); + buffer << uint32(proto->Map); + buffer << uint32(proto->BagFamily); + buffer << uint32(proto->TotemCategory); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) + buffer << uint32(proto->Socket[x].Color); + + for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) + buffer << uint32(proto->Socket[x].Content); + + buffer << uint32(proto->socketBonus); + buffer << uint32(proto->GemProperties); + buffer << float(proto->ArmorDamageModifier); + buffer << int32(proto->Duration); + buffer << uint32(proto->ItemLimitCategory); + buffer << uint32(proto->HolidayId); + buffer << float(proto->StatScalingFactor); // StatScalingFactor + buffer << uint32(proto->CurrencySubstitutionId); + buffer << uint32(proto->CurrencySubstitutionCount); +} diff --git a/src/server/game/DataStores/DB2Utility.h b/src/server/game/DataStores/DB2Utility.h new file mode 100644 index 00000000000..120ffd1cd27 --- /dev/null +++ b/src/server/game/DataStores/DB2Utility.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2013 TrintiyCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DB2PACKETWRITER_H +#define DB2PACKETWRITER_H + +#include "Define.h" + +template<class T> +class DB2Storage; +class ByteBuffer; +struct ItemEntry; +struct ItemSparseEntry; + +namespace DB2Utilities +{ + // + bool HasItemEntry(DB2Storage<ItemEntry> const& store, uint32 id); + bool HasItemSparseEntry(DB2Storage<ItemSparseEntry> const& store, uint32 id); + + // + void WriteItemDbReply(DB2Storage<ItemEntry> const& store, uint32 id, ByteBuffer& buffer); + void WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& store, uint32 id, ByteBuffer& buffer); +} + +#endif // DB2PACKETWRITER_H diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index ec44ff8977d..e9181cebbc3 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8737,7 +8737,7 @@ void ObjectMgr::LoadHotfixData() HotfixInfo info; info.Entry = fields[0].GetUInt32(); - info.Type = DB2Hash(fields[1].GetUInt32()); + info.Type = fields[1].GetUInt32(); info.Timestamp = fields[2].GetUInt64(); _hotfixData.push_back(info); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 9987df7591f..9e5b94a9242 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -641,7 +641,7 @@ typedef UNORDERED_MAP<uint32, DungeonEncounterList> DungeonEncounterContainer; struct HotfixInfo { - DB2Hash Type; + uint32 Type; uint32 Timestamp; uint32 Entry; }; @@ -1229,7 +1229,7 @@ class ObjectMgr void LoadHotfixData(); HotfixData const& GetHotfixData() const { return _hotfixData; } - time_t GetHotfixDate(uint32 entry, DB2Hash type) const + time_t GetHotfixDate(uint32 entry, uint32 type) const { time_t ret = 0; for (HotfixData::const_iterator itr = _hotfixData.begin(); itr != _hotfixData.end(); ++itr) diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 29af6fdc8f4..ef23c41690a 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -279,171 +279,6 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData) _player->DestroyItem(bag, slot, true); } -void WorldSession::SendItemDb2Reply(uint32 entry) -{ - WorldPacket data(SMSG_DB_REPLY, 44); - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(entry); - if (!proto) - { - data << -int32(entry); // entry - data << uint32(DB2_HASH_ITEM); - data << uint32(time(NULL)); // hotfix date - data << uint32(0); // size of next block - return; - } - - data << uint32(entry); - data << uint32(DB2_HASH_ITEM); - data << uint32(sObjectMgr->GetHotfixDate(entry, DB2_HASH_ITEM)); - - ByteBuffer buff; - buff << uint32(entry); - buff << uint32(proto->Class); - buff << uint32(proto->SubClass); - buff << int32(proto->SoundOverrideSubclass); - buff << uint32(proto->Material); - buff << uint32(proto->DisplayInfoID); - buff << uint32(proto->InventoryType); - buff << uint32(proto->Sheath); - - data << uint32(buff.size()); - data.append(buff); - - SendPacket(&data); -} - -void WorldSession::SendItemSparseDb2Reply(uint32 entry) -{ - WorldPacket data(SMSG_DB_REPLY, 526); - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(entry); - if (!proto) - { - data << -int32(entry); // entry - data << uint32(DB2_HASH_ITEM_SPARSE); - data << uint32(time(NULL)); // hotfix date - data << uint32(0); // size of next block - return; - } - - data << uint32(entry); - data << uint32(DB2_HASH_ITEM_SPARSE); - data << uint32(sObjectMgr->GetHotfixDate(entry, DB2_HASH_ITEM_SPARSE)); - - ByteBuffer buff; - buff << uint32(entry); - buff << uint32(proto->Quality); - buff << uint32(proto->Flags); - buff << uint32(proto->Flags2); - buff << float(proto->Unk430_1); - buff << float(proto->Unk430_2); - buff << uint32(proto->BuyCount); - buff << int32(proto->BuyPrice); - buff << uint32(proto->SellPrice); - buff << uint32(proto->InventoryType); - buff << int32(proto->AllowableClass); - buff << int32(proto->AllowableRace); - buff << uint32(proto->ItemLevel); - buff << uint32(proto->RequiredLevel); - buff << uint32(proto->RequiredSkill); - buff << uint32(proto->RequiredSkillRank); - buff << uint32(proto->RequiredSpell); - buff << uint32(proto->RequiredHonorRank); - buff << uint32(proto->RequiredCityRank); - buff << uint32(proto->RequiredReputationFaction); - buff << uint32(proto->RequiredReputationRank); - buff << int32(proto->MaxCount); - buff << int32(proto->Stackable); - buff << uint32(proto->ContainerSlots); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) - buff << uint32(proto->ItemStat[x].ItemStatType); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) - buff << int32(proto->ItemStat[x].ItemStatValue); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) - buff << int32(proto->ItemStat[x].ItemStatUnk1); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x) - buff << int32(proto->ItemStat[x].ItemStatUnk2); - - buff << uint32(proto->ScalingStatDistribution); - buff << uint32(proto->DamageType); - buff << uint32(proto->Delay); - buff << float(proto->RangedModRange); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buff << int32(proto->Spells[x].SpellId); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buff << uint32(proto->Spells[x].SpellTrigger); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buff << int32(proto->Spells[x].SpellCharges); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buff << int32(proto->Spells[x].SpellCooldown); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buff << uint32(proto->Spells[x].SpellCategory); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x) - buff << int32(proto->Spells[x].SpellCategoryCooldown); - - buff << uint32(proto->Bonding); - - // item name - std::string name = proto->Name1; - buff << uint16(name.length()); - if (name.length()) - buff << name; - - for (uint32 i = 0; i < 3; ++i) // other 3 names - buff << uint16(0); - - std::string desc = proto->Description; - buff << uint16(desc.length()); - if (desc.length()) - buff << desc; - - buff << uint32(proto->PageText); - buff << uint32(proto->LanguageID); - buff << uint32(proto->PageMaterial); - buff << uint32(proto->StartQuest); - buff << uint32(proto->LockID); - buff << int32(proto->Material); - buff << uint32(proto->Sheath); - buff << int32(proto->RandomProperty); - buff << int32(proto->RandomSuffix); - buff << uint32(proto->ItemSet); - - buff << uint32(proto->Area); - buff << uint32(proto->Map); - buff << uint32(proto->BagFamily); - buff << uint32(proto->TotemCategory); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) - buff << uint32(proto->Socket[x].Color); - - for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x) - buff << uint32(proto->Socket[x].Content); - - buff << uint32(proto->socketBonus); - buff << uint32(proto->GemProperties); - buff << float(proto->ArmorDamageModifier); - buff << int32(proto->Duration); - buff << uint32(proto->ItemLimitCategory); - buff << uint32(proto->HolidayId); - buff << float(proto->StatScalingFactor); // StatScalingFactor - buff << uint32(proto->CurrencySubstitutionId); - buff << uint32(proto->CurrencySubstitutionCount); - - data << uint32(buff.size()); - data.append(buff); - - SendPacket(&data); -} - void WorldSession::HandleReadItem(WorldPacket& recvData) { uint8 bag, slot; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index a0a721c8971..2d454dae927 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1865,6 +1865,14 @@ void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket) uint32 type, count; recvPacket >> type; + DB2StorageBase const* store = GetDB2Storage(type); + if (!store) + { + sLog->outError(LOG_FILTER_NETWORKIO, "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", type); + recvPacket.rfinish(); + return; + } + count = recvPacket.ReadBits(23); ObjectGuid* guids = new ObjectGuid[count]; @@ -1893,61 +1901,31 @@ void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket) recvPacket >> entry; recvPacket.ReadByteSeq(guids[i][2]); - switch (type) + if (!store->HasRecord(entry)) { - case DB2_HASH_ITEM: - SendItemDb2Reply(entry); - break; - case DB2_HASH_ITEM_SPARSE: - SendItemSparseDb2Reply(entry); - break; - case DB2_HASH_KEYCHAIN: - SendKeyChainDb2Reply(entry); - break; - default: - { - WorldPacket data(SMSG_DB_REPLY, 4 * 4); - data << -int32(entry); - data << uint32(type); - data << uint32(time(NULL)); - data << uint32(0); - SendPacket(&data); - - sLog->outError(LOG_FILTER_NETWORKIO, "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u, entry %u", type, entry); - recvPacket.rfinish(); - break; - } + WorldPacket data(SMSG_DB_REPLY, 4 * 4); + data << -int32(entry); + data << uint32(store->GetHash()); + data << uint32(time(NULL)); + data << uint32(0); + SendPacket(&data); + continue; } - } - delete[] guids; -} - -void WorldSession::SendKeyChainDb2Reply(uint32 entry) -{ - WorldPacket data(SMSG_DB_REPLY, 44); - KeyChainEntry const* keyChain = sKeyChainStore.LookupEntry(entry); - if (!keyChain) - { - data << -int32(entry); // entry - data << uint32(DB2_HASH_KEYCHAIN); - data << uint32(time(NULL)); // hotfix date - data << uint32(0); // size of next block - return; - } - - data << uint32(entry); - data << uint32(DB2_HASH_KEYCHAIN); - data << uint32(sObjectMgr->GetHotfixDate(entry, DB2_HASH_KEYCHAIN)); + WorldPacket data(SMSG_DB_REPLY); + data << int32(entry); + data << uint32(store->GetHash()); + data << uint32(sObjectMgr->GetHotfixDate(entry, store->GetHash())); - ByteBuffer buff; - buff << uint32(entry); - buff.append(keyChain->Key, KEYCHAIN_SIZE); + size_t sizePos = data.wpos(); + data << uint32(0); // size of next block + store->WriteRecord(entry, data); + data.put<uint32>(sizePos, data.wpos() - sizePos - 4); - data << uint32(buff.size()); - data.append(buff); + SendPacket(&data); + } - SendPacket(&data); + delete[] guids; } void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 9680ac0d5e5..be3362d746f 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -645,9 +645,6 @@ class WorldSession void HandleSwapInvItemOpcode(WorldPacket& recvPacket); void HandleDestroyItemOpcode(WorldPacket& recvPacket); void HandleAutoEquipItemOpcode(WorldPacket& recvPacket); - void SendItemDb2Reply(uint32 entry); - void SendItemSparseDb2Reply(uint32 entry); - void SendKeyChainDb2Reply(uint32 entry); void HandleSellItemOpcode(WorldPacket& recvPacket); void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket); void HandleBuyItemOpcode(WorldPacket& recvPacket); diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp index 0de3b94b5d4..83e6e83104f 100644 --- a/src/server/shared/DataStores/DB2FileLoader.cpp +++ b/src/server/shared/DataStores/DB2FileLoader.cpp @@ -30,17 +30,17 @@ DB2FileLoader::DB2FileLoader() bool DB2FileLoader::Load(const char *filename, const char *fmt) { - uint32 header = 48; if (data) { delete [] data; - data=NULL; + data = NULL; } FILE* f = fopen(filename, "rb"); if (!f) return false; + uint32 header; if (fread(&header, 4, 1, f) != 1) // Signature { fclose(f); @@ -114,12 +114,12 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt) if (build > 12880) { - if (fread(&unk2, 4, 1, f) != 1) // Unknown WDB2 + if (fread(&minIndex, 4, 1, f) != 1) // MinIndex WDB2 { fclose(f); return false; } - EndianConvert(unk2); + EndianConvert(minIndex); if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2 { @@ -145,7 +145,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt) if (maxIndex != 0) { - int32 diff = maxIndex - unk2 + 1; + int32 diff = maxIndex - minIndex + 1; fseek(f, diff * 4 + diff * 2, SEEK_CUR); // diff * 4: an index for rows, diff * 2: a memory allocation bank } diff --git a/src/server/shared/DataStores/DB2FileLoader.h b/src/server/shared/DataStores/DB2FileLoader.h index c30e33c29f6..5d3c8449442 100644 --- a/src/server/shared/DataStores/DB2FileLoader.h +++ b/src/server/shared/DataStores/DB2FileLoader.h @@ -25,8 +25,8 @@ class DB2FileLoader { public: - DB2FileLoader(); - ~DB2FileLoader(); + DB2FileLoader(); + ~DB2FileLoader(); bool Load(const char *filename, const char *fmt); @@ -76,6 +76,7 @@ class DB2FileLoader uint32 GetNumRows() const { return recordCount;} uint32 GetCols() const { return fieldCount; } uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; } + uint32 GetHash() const { return tableHash; } bool IsLoaded() const { return (data != NULL); } char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable); char* AutoProduceStringsArrayHolders(const char* fmt, char* dataTable); @@ -97,7 +98,7 @@ private: uint32 build; // WDB2 int unk1; // WDB2 (Unix time in WCH2) - int unk2; // WDB2 + int minIndex; // WDB2 int maxIndex; // WDB2 (index table) int locale; // WDB2 int unk5; // WDB2 diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h index c8f51bc96cb..e4f91beb592 100644 --- a/src/server/shared/DataStores/DB2Store.h +++ b/src/server/shared/DataStores/DB2Store.h @@ -19,30 +19,105 @@ #define DB2STORE_H #include "DB2FileLoader.h" -#include "DB2fmt.h" -#include "Log.h" -#include "Field.h" -#include "DatabaseWorkerPool.h" -#include "Implementation/WorldDatabase.h" -#include "DatabaseEnv.h" - +#include "ByteBuffer.h" #include <vector> +/// Interface class for common access +class DB2StorageBase +{ +public: + virtual ~DB2StorageBase() { } + + uint32 GetHash() const { return tableHash; } + + virtual bool HasRecord(uint32 id) const = 0; + + virtual void WriteRecord(uint32 id, ByteBuffer& buffer) const = 0; + +protected: + uint32 tableHash; +}; + +template<class T> +class DB2Storage; + +template<class T> +bool DB2StorageHasEntry(DB2Storage<T> const& store, uint32 id) +{ + return store.LookupEntry(id) != NULL; +} + template<class T> -class DB2Storage +void WriteDB2RecordToPacket(DB2Storage<T> const& store, uint32 id, ByteBuffer& buffer) +{ + uint8 const* entry = (uint8 const*)store.LookupEntry(id); + ASSERT(entry); + + std::string format = store.GetFormat(); + for (uint32 i = 0; i < format.length(); ++i) + { + switch (format[i]) + { + case FT_IND: + case FT_INT: + buffer << *(uint32*)entry; + entry += 4; + break; + case FT_FLOAT: + buffer << *(float*)entry; + entry += 4; + break; + case FT_BYTE: + buffer << *(uint8*)entry; + entry += 1; + break; + case FT_STRING: + { + size_t len = strlen(*(char**)entry); + buffer << uint16(len); + if (len) + buffer << *(char**)entry; + entry += sizeof(char*); + break; + } + case FT_NA: + case FT_SORT: + buffer << uint32(0); + break; + case FT_NA_BYTE: + buffer << uint8(0); + break; + } + } +} + +template<class T> +class DB2Storage : public DB2StorageBase { typedef std::list<char*> StringPoolList; typedef std::vector<T*> DataTableEx; + typedef bool(*EntryChecker)(DB2Storage<T> const&, uint32); + typedef void(*PacketWriter)(DB2Storage<T> const&, uint32, ByteBuffer&); public: - explicit DB2Storage(char const* f) : nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) { } + DB2Storage(char const* f, EntryChecker checkEntry = NULL, PacketWriter writePacket = NULL) : + nCount(0), fieldCount(0), fmt(f), indexTable(NULL), m_dataTable(NULL) + { + CheckEntry = checkEntry ? checkEntry : &DB2StorageHasEntry<T>; + WritePacket = writePacket ? writePacket : &WriteDB2RecordToPacket<T>; + } + ~DB2Storage() { Clear(); } + bool HasRecord(uint32 id) const { return CheckEntry(*this, id); } T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable[id]; } uint32 GetNumRows() const { return nCount; } char const* GetFormat() const { return fmt; } uint32 GetFieldCount() const { return fieldCount; } + void WriteRecord(uint32 id, ByteBuffer& buffer) const + { + WritePacket(*this, id, buffer); + } - /// Copies the provided entry and stores it. T* CreateEntry(uint32 id, bool evenIfExists = false) { if (evenIfExists && LookupEntry(id)) @@ -75,6 +150,7 @@ public: return false; fieldCount = db2.GetCols(); + tableHash = db2.GetHash(); // load raw non-string data m_dataTable = (T*)db2.AutoProduceData(fmt, nCount, (char**&)indexTable); @@ -130,10 +206,12 @@ public: nCount = 0; } + EntryChecker CheckEntry; + PacketWriter WritePacket; + private: uint32 nCount; uint32 fieldCount; - uint32 recordSize; char const* fmt; T** indexTable; T* m_dataTable; |