aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp74
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h27
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/NPCHandler.h22
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/QueryHandler.cpp10
-rwxr-xr-xsrc/server/shared/Database/SQLStorage.cpp2
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 ()