diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-12-24 22:24:32 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-12-24 22:24:32 +0100 |
commit | ae8814772fa4a63d42b4f588bc99d88fd4d3d6e8 (patch) | |
tree | 6797d6427859e15a396d14be396374f4d13c2ae9 /src | |
parent | 09f57db03d352a12d18d06a9c1616045f233dc4d (diff) |
Core/DataStores: Implemented loading hotfixes database into DB2Storage
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 41 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 3 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 | ||||
-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.h | 69 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/HotfixDatabase.cpp | 2 | ||||
-rw-r--r-- | src/server/shared/Database/Implementation/HotfixDatabase.h | 1 |
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 }; |