aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp19
-rw-r--r--src/server/game/DataStores/DB2Stores.h13
-rw-r--r--src/server/game/DataStores/DB2Utility.cpp163
-rw-r--r--src/server/game/DataStores/DB2Utility.h40
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Globals/ObjectMgr.h4
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp165
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp76
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.cpp10
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.h7
-rw-r--r--src/server/shared/DataStores/DB2Store.h100
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;