diff options
| -rwxr-xr-x | src/server/game/Globals/ObjectMgr.cpp | 74 | ||||
| -rwxr-xr-x | src/server/game/Globals/ObjectMgr.h | 27 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Handlers/NPCHandler.h | 22 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Handlers/QueryHandler.cpp | 10 | ||||
| -rwxr-xr-x | src/server/shared/Database/SQLStorage.cpp | 2 |
5 files changed, 72 insertions, 63 deletions
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index f5cbff826ca..ca9690c6775 100755 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2489,7 +2489,7 @@ void ObjectMgr::LoadItemPrototypes() if (proto->Bonding >= MAX_BIND_TYPE) sLog->outErrorDb("Item (Entry: %u) has wrong Bonding value (%u)",i,proto->Bonding); - if (proto->PageText && !sPageTextStore.LookupEntry<PageText>(proto->PageText)) + if (proto->PageText && !GetPageText(proto->PageText)) sLog->outErrorDb("Item (Entry: %u) has non existing first page (Id:%u)", i,proto->PageText); if (proto->LockID && !sLockStore.LookupEntry(proto->LockID)) @@ -5505,49 +5505,57 @@ void ObjectMgr::LoadPageTexts() { uint32 oldMSTime = getMSTime(); - sPageTextStore.Free(); // for reload case + QueryResult result = WorldDatabase.Query("SELECT entry, text, next_page FROM page_text"); - sPageTextStore.Load(); + if (!result) + { + sLog->outString(">> Loaded 0 page texts. DB table `page_text` is empty!"); + sLog->outString(); + return; + } - for (uint32 i = 1; i < sPageTextStore.MaxEntry; ++i) + uint32 count = 0; + do { - // check data correctness - PageText const* page = sPageTextStore.LookupEntry<PageText>(i); - if (!page) - continue; + Field* fields = result->Fetch(); - if (page->Next_Page && !sPageTextStore.LookupEntry<PageText>(page->Next_Page)) - { - sLog->outErrorDb("Page text (Id: %u) has not existing next page (Id:%u)", i,page->Next_Page); - continue; - } + const char* text = fields[1].GetCString(); + + PageText pageText; + + pageText.Text = fields[1].GetString(); + pageText.NextPage = fields[2].GetInt16(); + + PageTextStore[fields[0].GetUInt32()] = pageText; - // detect circular reference - std::set<uint32> checkedPages; - for (PageText const* pageItr = page; pageItr; pageItr = sPageTextStore.LookupEntry<PageText>(pageItr->Next_Page)) + ++count; + } + while (result->NextRow()); + + for (PageTextContainer::const_iterator itr = PageTextStore.begin(); itr != PageTextStore.end(); ++itr) + { + if (itr->second.NextPage) { - if (!pageItr->Next_Page) - break; - checkedPages.insert(pageItr->Page_ID); - if (checkedPages.find(pageItr->Next_Page)!= checkedPages.end()) - { - std::ostringstream ss; - ss << "The text page(s) "; - for (std::set<uint32>::iterator itr= checkedPages.begin(); itr != checkedPages.end(); ++itr) - ss << *itr << " "; - ss << "create(s) a circular reference, which can cause the server to freeze. Changing Next_Page of page " - << pageItr->Page_ID <<" to 0"; - sLog->outErrorDb("%s", ss.str().c_str()); - const_cast<PageText*>(pageItr)->Next_Page = 0; - break; - } + PageTextContainer::const_iterator itr2 = PageTextStore.find(itr->second.NextPage); + if (itr2 == PageTextStore.end()) + sLog->outErrorDb("Page text (Id: %u) has not existing next page (Id: %u)", itr->first, itr->second.NextPage); + } } - sLog->outString(">> Loaded %u page texts in %u ms", sPageTextStore.RecordCount, GetMSTimeDiffToNow(oldMSTime)); + sLog->outString(">> Loaded %u page texts in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); } +PageText const* ObjectMgr::GetPageText(uint32 pageEntry) +{ + PageTextContainer::const_iterator itr = PageTextStore.find(pageEntry); + if (itr != PageTextStore.end()) + return &(itr->second); + + return NULL; +} + void ObjectMgr::LoadPageTextLocales() { uint32 oldMSTime = getMSTime(); @@ -7016,7 +7024,7 @@ void ObjectMgr::LoadGameobjectInfo() if (goInfo->goober.pageId) // pageId { - if (!sPageTextStore.LookupEntry<PageText>(goInfo->goober.pageId)) + if (!GetPageText(goInfo->goober.pageId)) sLog->outErrorDb("Gameobject (Entry: %u GoType: %u) have data7=%u but PageText (Entry %u) not exist.", id,goInfo->type,goInfo->goober.pageId,goInfo->goober.pageId); } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 94953a68159..9c55933ec11 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -48,7 +48,6 @@ extern SQLStorage sCreatureDataAddonStorage; extern SQLStorage sCreatureInfoAddonStorage; extern SQLStorage sEquipmentStorage; extern SQLStorage sGOStorage; -extern SQLStorage sPageTextStore; extern SQLStorage sItemStorage; extern SQLStorage sInstanceTemplate; @@ -57,6 +56,29 @@ class Guild; class ArenaTeam; class Item; +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined(__GNUC__) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct PageText +{ + std::string Text; + uint16 NextPage; +}; + +// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform +#if defined(__GNUC__) +#pragma pack() +#else +#pragma pack(pop) +#endif + +// Faster (insert/find) than UNORDERED_MAP in this case +typedef std::map<uint32, PageText> PageTextContainer; + struct GameTele { float position_x; @@ -943,6 +965,7 @@ class ObjectMgr void LoadGameObjectForQuests(); void LoadPageTexts(); + PageText const* GetPageText(uint32 pageEntry); void LoadPlayerInfo(); void LoadPetLevelInfo(); @@ -1343,6 +1366,8 @@ class ObjectMgr LocaleConstant DBCLocaleIndex; + PageTextContainer PageTextStore; + private: void LoadScripts(ScriptsType type); void CheckScripts(ScriptsType type, std::set<int32>& ids); diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.h b/src/server/game/Server/Protocol/Handlers/NPCHandler.h index 9c1d1c0a296..2b14e0edc21 100755 --- a/src/server/game/Server/Protocol/Handlers/NPCHandler.h +++ b/src/server/game/Server/Protocol/Handlers/NPCHandler.h @@ -19,28 +19,6 @@ #ifndef __NPCHANDLER_H #define __NPCHANDLER_H -// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform -#if defined(__GNUC__) -#pragma pack(1) -#else -#pragma pack(push,1) -#endif - -struct PageText -{ - uint32 Page_ID; - char * Text; - - uint32 Next_Page; -}; - -// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform -#if defined(__GNUC__) -#pragma pack() -#else -#pragma pack(pop) -#endif - struct QEmote { uint32 _Emote; diff --git a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp index a9b6ef6c163..a19abb4534c 100755 --- a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp @@ -411,12 +411,12 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data) while (pageID) { - PageText const *pPage = sPageTextStore.LookupEntry<PageText>(pageID); + PageText const* pageText = sObjectMgr->GetPageText(pageID); // guess size WorldPacket data(SMSG_PAGE_TEXT_QUERY_RESPONSE, 50); data << pageID; - if (!pPage) + if (!pageText) { data << "Item page missing."; data << uint32(0); @@ -424,7 +424,7 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data) } else { - std::string Text = pPage->Text; + std::string Text = pageText->Text; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) @@ -432,8 +432,8 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data) sObjectMgr->GetLocaleString(pl->Text, loc_idx, Text); data << Text; - data << uint32(pPage->Next_Page); - pageID = pPage->Next_Page; + data << uint32(pageText->NextPage); + pageID = pageText->NextPage; } SendPacket(&data); diff --git a/src/server/shared/Database/SQLStorage.cpp b/src/server/shared/Database/SQLStorage.cpp index 4a31859ae8d..e9da15d9678 100755 --- a/src/server/shared/Database/SQLStorage.cpp +++ b/src/server/shared/Database/SQLStorage.cpp @@ -28,7 +28,6 @@ const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissi"; const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisii"; const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiiii"; const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiii"; -const char PageTextfmt[]="isii"; const char InstanceTemplatesrcfmt[]="iiffffsb"; const char InstanceTemplatedstfmt[]="iiffffib"; @@ -38,7 +37,6 @@ SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_ SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template"); SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameobject_template"); SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template"); -SQLStorage sPageTextStore(PageTextfmt,"entry","page_text"); SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template"); void SQLStorage::Free () |
