Core/ObjectMgr: Refactor sPageTextStore

This commit is contained in:
leak
2011-04-28 22:13:09 +02:00
parent 85a1e9e7ab
commit 19cab2c508
5 changed files with 73 additions and 64 deletions
+42 -34
View File
@@ -2489,7 +2489,7 @@ void ObjectMgr::LoadItemPrototypes()
if (proto->Bonding >= MAX_BIND_TYPE) if (proto->Bonding >= MAX_BIND_TYPE)
sLog->outErrorDb("Item (Entry: %u) has wrong Bonding value (%u)",i,proto->Bonding); 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); sLog->outErrorDb("Item (Entry: %u) has non existing first page (Id:%u)", i,proto->PageText);
if (proto->LockID && !sLockStore.LookupEntry(proto->LockID)) if (proto->LockID && !sLockStore.LookupEntry(proto->LockID))
@@ -5505,49 +5505,57 @@ void ObjectMgr::LoadPageTexts()
{ {
uint32 oldMSTime = getMSTime(); uint32 oldMSTime = getMSTime();
sPageTextStore.Free(); // for reload case QueryResult result = WorldDatabase.Query("SELECT entry, text, next_page FROM page_text");
sPageTextStore.Load(); if (!result)
for (uint32 i = 1; i < sPageTextStore.MaxEntry; ++i)
{ {
// check data correctness sLog->outString(">> Loaded 0 page texts. DB table `page_text` is empty!");
PageText const* page = sPageTextStore.LookupEntry<PageText>(i); sLog->outString();
if (!page) return;
continue; }
if (page->Next_Page && !sPageTextStore.LookupEntry<PageText>(page->Next_Page)) uint32 count = 0;
{ do
sLog->outErrorDb("Page text (Id: %u) has not existing next page (Id:%u)", i,page->Next_Page); {
continue; Field* fields = result->Fetch();
}
// detect circular reference const char* text = fields[1].GetCString();
std::set<uint32> checkedPages;
for (PageText const* pageItr = page; pageItr; pageItr = sPageTextStore.LookupEntry<PageText>(pageItr->Next_Page)) PageText pageText;
pageText.Text = fields[1].GetString();
pageText.NextPage = fields[2].GetInt16();
PageTextStore[fields[0].GetUInt32()] = pageText;
++count;
}
while (result->NextRow());
for (PageTextContainer::const_iterator itr = PageTextStore.begin(); itr != PageTextStore.end(); ++itr)
{
if (itr->second.NextPage)
{ {
if (!pageItr->Next_Page) PageTextContainer::const_iterator itr2 = PageTextStore.find(itr->second.NextPage);
break; if (itr2 == PageTextStore.end())
checkedPages.insert(pageItr->Page_ID); sLog->outErrorDb("Page text (Id: %u) has not existing next page (Id: %u)", itr->first, itr->second.NextPage);
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;
}
} }
} }
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(); 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() void ObjectMgr::LoadPageTextLocales()
{ {
uint32 oldMSTime = getMSTime(); uint32 oldMSTime = getMSTime();
@@ -7016,7 +7024,7 @@ void ObjectMgr::LoadGameobjectInfo()
if (goInfo->goober.pageId) // pageId 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.", 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); id,goInfo->type,goInfo->goober.pageId,goInfo->goober.pageId);
} }
+26 -1
View File
@@ -48,7 +48,6 @@ extern SQLStorage sCreatureDataAddonStorage;
extern SQLStorage sCreatureInfoAddonStorage; extern SQLStorage sCreatureInfoAddonStorage;
extern SQLStorage sEquipmentStorage; extern SQLStorage sEquipmentStorage;
extern SQLStorage sGOStorage; extern SQLStorage sGOStorage;
extern SQLStorage sPageTextStore;
extern SQLStorage sItemStorage; extern SQLStorage sItemStorage;
extern SQLStorage sInstanceTemplate; extern SQLStorage sInstanceTemplate;
@@ -57,6 +56,29 @@ class Guild;
class ArenaTeam; class ArenaTeam;
class Item; 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 struct GameTele
{ {
float position_x; float position_x;
@@ -943,6 +965,7 @@ class ObjectMgr
void LoadGameObjectForQuests(); void LoadGameObjectForQuests();
void LoadPageTexts(); void LoadPageTexts();
PageText const* GetPageText(uint32 pageEntry);
void LoadPlayerInfo(); void LoadPlayerInfo();
void LoadPetLevelInfo(); void LoadPetLevelInfo();
@@ -1343,6 +1366,8 @@ class ObjectMgr
LocaleConstant DBCLocaleIndex; LocaleConstant DBCLocaleIndex;
PageTextContainer PageTextStore;
private: private:
void LoadScripts(ScriptsType type); void LoadScripts(ScriptsType type);
void CheckScripts(ScriptsType type, std::set<int32>& ids); void CheckScripts(ScriptsType type, std::set<int32>& ids);
@@ -19,28 +19,6 @@
#ifndef __NPCHANDLER_H #ifndef __NPCHANDLER_H
#define __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 struct QEmote
{ {
uint32 _Emote; uint32 _Emote;
@@ -411,12 +411,12 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)
while (pageID) while (pageID)
{ {
PageText const *pPage = sPageTextStore.LookupEntry<PageText>(pageID); PageText const* pageText = sObjectMgr->GetPageText(pageID);
// guess size // guess size
WorldPacket data(SMSG_PAGE_TEXT_QUERY_RESPONSE, 50); WorldPacket data(SMSG_PAGE_TEXT_QUERY_RESPONSE, 50);
data << pageID; data << pageID;
if (!pPage) if (!pageText)
{ {
data << "Item page missing."; data << "Item page missing.";
data << uint32(0); data << uint32(0);
@@ -424,7 +424,7 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)
} }
else else
{ {
std::string Text = pPage->Text; std::string Text = pageText->Text;
int loc_idx = GetSessionDbLocaleIndex(); int loc_idx = GetSessionDbLocaleIndex();
if (loc_idx >= 0) if (loc_idx >= 0)
@@ -432,8 +432,8 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)
sObjectMgr->GetLocaleString(pl->Text, loc_idx, Text); sObjectMgr->GetLocaleString(pl->Text, loc_idx, Text);
data << Text; data << Text;
data << uint32(pPage->Next_Page); data << uint32(pageText->NextPage);
pageID = pPage->Next_Page; pageID = pageText->NextPage;
} }
SendPacket(&data); SendPacket(&data);
@@ -28,7 +28,6 @@ const char GameObjectInfosrcfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiissi";
const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisii"; const char GameObjectInfodstfmt[]="iiissssiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisii";
const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiiii"; const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiisiiiii";
const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiii"; const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiii";
const char PageTextfmt[]="isii";
const char InstanceTemplatesrcfmt[]="iiffffsb"; const char InstanceTemplatesrcfmt[]="iiffffsb";
const char InstanceTemplatedstfmt[]="iiffffib"; const char InstanceTemplatedstfmt[]="iiffffib";
@@ -38,7 +37,6 @@ SQLStorage sCreatureInfoAddonStorage(CreatureInfoAddonInfofmt,"entry","creature_
SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template"); SQLStorage sEquipmentStorage(EquipmentInfofmt,"entry","creature_equip_template");
SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameobject_template"); SQLStorage sGOStorage(GameObjectInfosrcfmt, GameObjectInfodstfmt, "entry","gameobject_template");
SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template"); SQLStorage sItemStorage(ItemPrototypesrcfmt, ItemPrototypedstfmt, "entry","item_template");
SQLStorage sPageTextStore(PageTextfmt,"entry","page_text");
SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template"); SQLStorage sInstanceTemplate(InstanceTemplatesrcfmt, InstanceTemplatedstfmt, "map","instance_template");
void SQLStorage::Free () void SQLStorage::Free ()