aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-12-24 22:24:32 +0100
committerShauren <shauren.trinity@gmail.com>2014-12-24 22:24:32 +0100
commitae8814772fa4a63d42b4f588bc99d88fd4d3d6e8 (patch)
tree6797d6427859e15a396d14be396374f4d13c2ae9 /src
parent09f57db03d352a12d18d06a9c1616045f233dc4d (diff)
Core/DataStores: Implemented loading hotfixes database into DB2Storage
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp41
-rw-r--r--src/server/game/Globals/ObjectMgr.h3
-rw-r--r--src/server/game/World/World.cpp3
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.cpp (renamed from src/server/shared/DataStores/DB2FileLoader.cpp)183
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.h (renamed from src/server/shared/DataStores/DB2FileLoader.h)9
-rw-r--r--src/server/shared/DataStores/DB2Store.h69
-rw-r--r--src/server/shared/Database/Implementation/HotfixDatabase.cpp2
-rw-r--r--src/server/shared/Database/Implementation/HotfixDatabase.h1
9 files changed, 189 insertions, 126 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 39e5d443871..42902e08466 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -50,7 +50,7 @@ DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostEnt
DB2Storage<SpellTotemsEntry> sSpellTotemsStore(SpellTotemsEntryfmt);
DB2Storage<TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
DB2Storage<TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
-DB2Storage<TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
+DB2Storage<TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt, HOTFIX_SEL_TAXI_PATH_NODE);
TaxiMask sTaxiNodesMask;
TaxiMask sOldContinentsNodesMask;
TaxiMask sHordeTaxiNodesMask;
@@ -86,6 +86,8 @@ inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, D
std::string db2_filename = db2_path + filename;
if (storage.Load(db2_filename.c_str(), uint32(sWorld->GetDefaultDbcLocale())))
{
+ storage.LoadSQLData();
+
for (uint32 i = 0; i < TOTAL_LOCALES; ++i)
{
if (!(availableDb2Locales & (1 << i)))
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index f9c532d23dd..dc326555c36 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -8675,47 +8675,6 @@ void ObjectMgr::LoadHotfixData()
TC_LOG_INFO("server.loading", ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadMissingKeyChains()
-{
- uint32 oldMSTime = getMSTime();
-
- QueryResult result = WorldDatabase.Query("SELECT keyId, k1, k2, k3, k4, k5, k6, k7, k8, "
- "k9, k10, k11, k12, k13, k14, k15, k16, "
- "k17, k18, k19, k20, k21, k22, k23, k24, "
- "k25, k26, k27, k28, k29, k30, k31, k32 "
- "FROM keychain_db2 ORDER BY keyId DESC");
-
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 KeyChain entries. DB table `keychain_db2` is empty.");
- return;
- }
-
- uint32 count = 0;
-
- do
- {
- Field* fields = result->Fetch();
- uint32 id = fields[0].GetUInt32();
-
- KeyChainEntry* kce = sKeyChainStore.CreateEntry(id, true);
- if (!kce)
- {
- TC_LOG_ERROR("sql.sql", "Could not create KeyChainEntry %u, skipped.", id);
- continue;
- }
-
- kce->Id = id;
- for (uint32 i = 0; i < KEYCHAIN_SIZE; ++i)
- kce->Key[i] = fields[1 + i].GetUInt8();
-
- ++count;
- }
- while (result->NextRow());
-
- TC_LOG_INFO("server.loading", ">> Loaded %u KeyChain 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 9b83ce27392..134e9bf7483 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -1354,9 +1354,6 @@ class ObjectMgr
return ret ? ret : time(NULL);
}
- void LoadMissingKeyChains();
-
-
void LoadRaceAndClassExpansionRequirements();
void LoadRealmNames();
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index a3ee2fa1265..b1e0b1795e0 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1923,9 +1923,6 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("misc", "Loading hotfix info...");
sObjectMgr->LoadHotfixData();
- TC_LOG_INFO("server.loading", "Loading missing KeyChains...");
- sObjectMgr->LoadMissingKeyChains();
-
TC_LOG_INFO("server.loading", "Loading race and class expansion requirements...");
sObjectMgr->LoadRaceAndClassExpansionRequirements();
diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp
index 7a27072dd20..1e68c4881f8 100644
--- a/src/server/shared/DataStores/DB2FileLoader.cpp
+++ b/src/server/shared/DataStores/DB2StorageLoader.cpp
@@ -16,11 +16,12 @@
*/
#include "Common.h"
+#include "DB2StorageLoader.h"
+#include "Database/DatabaseEnv.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "DB2FileLoader.h"
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
DB2FileLoader::DB2FileLoader()
{
@@ -233,23 +234,22 @@ uint32 DB2FileLoader::GetFormatStringsFields(const char * format)
char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable)
{
-
typedef char * ptr;
if (strlen(format) != fieldCount)
return NULL;
//get struct size and index pos
- int32 i;
- uint32 recordsize=GetFormatRecordSize(format, &i);
+ int32 indexField;
+ uint32 recordsize = GetFormatRecordSize(format, &indexField);
- if (i >= 0)
+ if (indexField >= 0)
{
uint32 maxi = 0;
//find max index
for (uint32 y = 0; y < recordCount; y++)
{
- uint32 ind=getRecord(y).getUInt(i);
- if (ind>maxi)
+ uint32 ind = getRecord(y).getUInt(indexField);
+ if (ind > maxi)
maxi = ind;
}
@@ -266,14 +266,12 @@ char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**
char* dataTable = new char[recordCount * recordsize];
- uint32 offset=0;
+ uint32 offset = 0;
- for (uint32 y =0; y < recordCount; y++)
+ for (uint32 y = 0; y < recordCount; y++)
{
- if (i>=0)
- {
- indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
- }
+ if (indexField >= 0)
+ indexTable[getRecord(y).getUInt(indexField)] = &dataTable[offset];
else
indexTable[y] = &dataTable[offset];
@@ -310,10 +308,13 @@ static char const* const nullStr = "";
char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable)
{
if (strlen(format) != fieldCount)
- return NULL;
+ return nullptr;
// we store flat holders pool as single memory block
size_t stringFields = GetFormatStringsFields(format);
+ if (!stringFields)
+ return nullptr;
+
// each string field at load have array of string for each locale
size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize;
@@ -325,7 +326,7 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
for (size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i)
((char const**)stringHoldersPool)[i] = nullStr;
- uint32 offset=0;
+ uint32 offset = 0;
// assign string holders to string field slots
for (uint32 y = 0; y < recordCount; y++)
@@ -333,6 +334,7 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
uint32 stringFieldNum = 0;
for (uint32 x = 0; x < fieldCount; x++)
+ {
switch (format[x])
{
case FT_FLOAT:
@@ -357,7 +359,8 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
case FT_SORT:
break;
default:
- assert(false && "unknown format character");
+ ASSERT(false, "unknown format character %c", format[x]);
+ }
}
}
@@ -370,39 +373,141 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin
if (strlen(format) != fieldCount)
return NULL;
- char* stringPool= new char[stringSize];
+ char* stringPool = new char[stringSize];
memcpy(stringPool, stringTable, stringSize);
uint32 offset = 0;
- for (uint32 y =0; y < recordCount; y++)
+ for (uint32 y = 0; y < recordCount; y++)
{
for (uint32 x = 0; x < fieldCount; x++)
- switch (format[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**)(&dataTable[offset]);
- if (db2str->Str[locale] == nullStr)
+ case FT_FLOAT:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_STRING:
{
- const char * st = getRecord(y).getString(x);
- db2str->Str[locale] = stringPool + (st - (const char*)stringTable);
- }
+ // fill only not filled entries
+ LocalizedString* db2str = *(LocalizedString**)(&dataTable[offset]);
+ if (db2str->Str[locale] == nullStr)
+ {
+ const char * st = getRecord(y).getString(x);
+ db2str->Str[locale] = stringPool + (st - (const char*)stringTable);
+ }
- offset += sizeof(char*);
- break;
+ offset += sizeof(char*);
+ break;
+ }
}
}
}
return stringPool;
}
+
+char* DB2DatabaseLoader::Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool)
+{
+ PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement));
+ if (!result)
+ return nullptr;
+
+ if (strlen(format) + 1 /*VerifiedBuild*/ != result->GetFieldCount())
+ return nullptr;
+
+ //get struct size and index pos
+ int32 indexField;
+ uint32 recordSize = DB2FileLoader::GetFormatRecordSize(format, &indexField);
+
+ // we store flat holders pool as single memory block
+ size_t stringFields = DB2FileLoader::GetFormatStringsFields(format);
+
+ // each string field at load have array of string for each locale
+ size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
+ size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize;
+ size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * result->GetRowCount();
+
+ if (stringFields)
+ stringHolders = new char[stringHoldersPoolSize];
+ else
+ stringHolders = nullptr;
+
+ std::unordered_map<uint32, char*> tempIndexTable;
+ tempIndexTable.reserve(result->GetRowCount());
+ char* dataTable = new char[result->GetRowCount() * recordSize];
+ uint32 offset = 0;
+
+ uint32 oldIndexSize = records;
+ uint32 rec = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 stringFieldNum = 0;
+
+ if (indexField >= 0)
+ {
+ uint32 indexValue = fields[indexField].GetUInt32();
+ tempIndexTable[indexValue] = &dataTable[offset];
+ if (records <= indexValue)
+ records = indexValue + 1;
+ }
+ else
+ tempIndexTable[records++] = &dataTable[offset];
+
+ for (uint32 x = 0; x < result->GetFieldCount(); x++)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = fields[x].GetFloat();
+ offset += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *((int32*)(&dataTable[offset])) = fields[x].GetInt32();
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((int8*)(&dataTable[offset])) = fields[x].GetInt8();
+ offset += 1;
+ break;
+ case FT_STRING:
+ {
+ std::string value = fields[x].GetString();
+ LocalizedString** slot = (LocalizedString**)(&dataTable[offset]);
+ *slot = (LocalizedString*)(&stringHolders[stringHoldersRecordPoolSize * rec++ + stringHolderSize * stringFieldNum]);
+ // Value in database field must be for enUS locale
+ char* str = new char[value.length() + 1];
+ strcpy(str, value.c_str());
+ stringPool.push_back(str);
+ (*slot)->Str[LOCALE_enUS] = str;
+ ++stringFieldNum;
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+ } while (result->NextRow());
+
+ // Reallocate index if needed
+ if (records > oldIndexSize)
+ {
+ char** tmpIdxTable = new char*[records];
+ memset(tmpIdxTable, 0, records * sizeof(char*));
+ memcpy(tmpIdxTable, indexTable, oldIndexSize * sizeof(char*));
+ delete[] indexTable;
+ indexTable = tmpIdxTable;
+ }
+
+ // Merge new data into index
+ for (auto itr = tempIndexTable.begin(); itr != tempIndexTable.end(); ++itr)
+ indexTable[itr->first] = itr->second;
+
+ return dataTable;
+}
diff --git a/src/server/shared/DataStores/DB2FileLoader.h b/src/server/shared/DataStores/DB2StorageLoader.h
index 86350ebf1d6..82f5ff02afe 100644
--- a/src/server/shared/DataStores/DB2FileLoader.h
+++ b/src/server/shared/DataStores/DB2StorageLoader.h
@@ -104,4 +104,11 @@ private:
int unk5; // WDB2
};
-#endif \ No newline at end of file
+class DB2DatabaseLoader
+{
+public:
+
+ char* Load(const char* format, int32 preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool);
+};
+
+#endif
diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h
index 77d6c4144e5..84134c48160 100644
--- a/src/server/shared/DataStores/DB2Store.h
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -18,7 +18,7 @@
#ifndef DB2STORE_H
#define DB2STORE_H
-#include "DB2FileLoader.h"
+#include "DB2StorageLoader.h"
#include "Common.h"
#include "ByteBuffer.h"
#include <vector>
@@ -101,12 +101,11 @@ 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, uint32, ByteBuffer&);
public:
- DB2Storage(char const* f, EntryChecker checkEntry = NULL, PacketWriter writePacket = NULL) :
- nCount(0), fieldCount(0), fmt(f), m_dataTable(NULL)
+ DB2Storage(char const* f, int32 preparedStmtIndex = -1, EntryChecker checkEntry = nullptr, PacketWriter writePacket = nullptr)
+ : nCount(0), fieldCount(0), fmt(f), m_dataTable(nullptr), m_dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
{
indexTable.asT = NULL;
CheckEntry = checkEntry ? checkEntry : (EntryChecker)&DB2StorageHasEntry<T>;
@@ -125,30 +124,6 @@ public:
WritePacket(*this, id, locale, buffer);
}
- T* CreateEntry(uint32 id, bool evenIfExists = false)
- {
- if (evenIfExists && LookupEntry(id))
- return NULL;
-
- if (id >= nCount)
- {
- // reallocate index table
- char** tmpIdxTable = new char*[id + 1];
- memset(tmpIdxTable, 0, (id + 1) * sizeof(char*));
- memcpy(tmpIdxTable, indexTable.asChar, nCount * sizeof(char*));
- delete[] reinterpret_cast<char*>(indexTable.asT);
- nCount = id + 1;
- indexTable.asChar = tmpIdxTable;
- }
-
- T* entryDst = new T;
- m_dataTableEx.push_back(entryDst);
- indexTable.asT[id] = entryDst;
- return entryDst;
- }
-
- void EraseEntry(uint32 id) { indexTable.asT[id] = NULL; }
-
bool Load(char const* fn, uint32 locale)
{
DB2FileLoader db2;
@@ -163,10 +138,13 @@ public:
m_dataTable = reinterpret_cast<T*>(db2.AutoProduceData(fmt, nCount, indexTable.asChar));
// create string holders for loaded string fields
- m_stringPoolList.push_back(db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable));
+ if (char* stringHolders = db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable))
+ {
+ m_stringPoolList.push_back(stringHolders);
- // load strings from dbc data
- m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
+ // load strings from dbc data
+ m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
+ }
// error in dbc file at loading if NULL
return indexTable.asT != NULL;
@@ -184,25 +162,39 @@ public:
return false;
// load strings from another locale dbc data
- m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
+ if (DB2FileLoader::GetFormatStringsFields(fmt))
+ m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
return true;
}
+ void LoadSQLData()
+ {
+ if (_hotfixStatement == -1)
+ return;
+
+ DB2DatabaseLoader db2;
+ char* extraStringHolders = nullptr;
+ if (char* dataTable = db2.Load(fmt, _hotfixStatement, nCount, indexTable.asChar, extraStringHolders, m_stringPoolList))
+ {
+ m_dataTableEx = reinterpret_cast<T*>(dataTable);
+ m_stringPoolList.push_back(extraStringHolders);
+ }
+ }
+
void Clear()
{
if (!indexTable.asT)
return;
delete[] reinterpret_cast<char*>(indexTable.asT);
- indexTable.asT = NULL;
+ indexTable.asT = nullptr;
delete[] reinterpret_cast<char*>(m_dataTable);
- m_dataTable = NULL;
+ m_dataTable = nullptr;
- for (typename DataTableEx::iterator itr = m_dataTableEx.begin(); itr != m_dataTableEx.end(); ++itr)
- delete *itr;
- m_dataTableEx.clear();
+ delete[] reinterpret_cast<char*>(m_dataTableEx);
+ m_dataTableEx = nullptr;
while (!m_stringPoolList.empty())
{
@@ -226,8 +218,9 @@ private:
char** asChar;
} indexTable;
T* m_dataTable;
- DataTableEx m_dataTableEx;
+ T* m_dataTableEx;
StringPoolList m_stringPoolList;
+ int32 _hotfixStatement;
};
#endif
diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.cpp b/src/server/shared/Database/Implementation/HotfixDatabase.cpp
index f60287ef1a7..ae9ec73c9bc 100644
--- a/src/server/shared/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/shared/Database/Implementation/HotfixDatabase.cpp
@@ -21,4 +21,6 @@ void HotfixDatabaseConnection::DoPrepareStatements()
{
if (!m_reconnecting)
m_stmts.resize(MAX_HOTFIXDATABASE_STATEMENTS);
+
+ PrepareStatement(HOTFIX_SEL_TAXI_PATH_NODE, "SELECT * FROM taxi_path_node", CONNECTION_SYNCH);
}
diff --git a/src/server/shared/Database/Implementation/HotfixDatabase.h b/src/server/shared/Database/Implementation/HotfixDatabase.h
index 13c3af6714e..5ee09ccd014 100644
--- a/src/server/shared/Database/Implementation/HotfixDatabase.h
+++ b/src/server/shared/Database/Implementation/HotfixDatabase.h
@@ -42,6 +42,7 @@ enum HotfixDatabaseStatements
name for a suiting suffix.
*/
+ HOTFIX_SEL_TAXI_PATH_NODE,
MAX_HOTFIXDATABASE_STATEMENTS
};