diff options
author | azazel <none@none> | 2010-08-13 17:39:43 +0600 |
---|---|---|
committer | azazel <none@none> | 2010-08-13 17:39:43 +0600 |
commit | 9bd2619425ca9d85a32007a6d9c2761d08521dcc (patch) | |
tree | 2049ddaa51c95568700137c1b357e17629f78149 | |
parent | 0f378aac24f9999adb8b218c6e080c7d22878d50 (diff) |
Fixed memory leaks at guild unload/disband (author: porteyoplait)
--HG--
branch : trunk
-rw-r--r-- | src/server/game/Guilds/Guild.cpp | 88 | ||||
-rw-r--r-- | src/server/game/Guilds/Guild.h | 6 |
2 files changed, 59 insertions, 35 deletions
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 4b5e5d6134a..2fb727f7230 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -48,7 +48,6 @@ Guild::Guild() m_CreatedDate = time(0); m_GuildBankMoney = 0; - m_PurchasedTabs = 0; m_GuildEventLogNextGuid = 0; m_GuildBankEventLogNextGuid_Money = 0; @@ -59,7 +58,7 @@ Guild::Guild() Guild::~Guild() { - + DeleteGuildBankItems(); } bool Guild::Create(Player* leader, std::string gname) @@ -76,7 +75,6 @@ bool Guild::Create(Player* leader, std::string gname) GINFO = ""; MOTD = "No message set."; m_GuildBankMoney = 0; - m_PurchasedTabs = 0; m_Id = sObjectMgr.GenerateGuildId(); sLog.outDebug("GUILD: creating guild %s to leader: %u", gname.c_str(), GUID_LOPART(m_LeaderGuid)); @@ -231,10 +229,14 @@ bool Guild::LoadGuildFromDB(QueryResult_AutoPtr guildDataResult) MOTD = fields[9].GetCppString(); m_CreatedDate = fields[10].GetUInt64(); m_GuildBankMoney = fields[11].GetUInt64(); - m_PurchasedTabs = fields[12].GetUInt32(); - if (m_PurchasedTabs > GUILD_BANK_MAX_TABS) - m_PurchasedTabs = GUILD_BANK_MAX_TABS; + uint32 purchasedTabs = fields[12].GetUInt32(); + if (purchasedTabs > GUILD_BANK_MAX_TABS) + purchasedTabs = GUILD_BANK_MAX_TABS; + + m_TabListMap.resize(purchasedTabs); + for (uint8 i = 0; i < purchasedTabs; ++i) + m_TabListMap[i] = new GuildBankTab(); return true; } @@ -613,7 +615,7 @@ void Guild::CreateRank(std::string name_,uint32 rights) //existing records in db should be deleted before calling this procedure and m_PurchasedTabs must be loaded already - for (uint32 i = 0; i < m_PurchasedTabs; ++i) + for (uint32 i = 0; i < uint32(GetPurchasedTabs()); ++i) { //create bank rights with 0 CharacterDatabase.PExecute("INSERT INTO guild_bank_right (guildid,TabId,rid) VALUES ('%u','%u','%u')", m_Id, i, new_rank_id); @@ -702,7 +704,10 @@ void Guild::Disband() CharacterDatabase.PExecute("DELETE FROM guild WHERE guildid = '%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM guild_rank WHERE guildid = '%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid = '%u'", m_Id); - // TODO item_instance should be deleted ? + + //Free bank tab used memory and delete items stored in them + DeleteGuildBankItems(true); + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid = '%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM guild_bank_right WHERE guildid = '%u'", m_Id); CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE guildid = '%u'", m_Id); @@ -1027,7 +1032,7 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec cons Item* Guild::GetItem(uint8 TabId, uint8 SlotId) { - if (TabId >= m_TabListMap.size() || SlotId >= GUILD_BANK_MAX_SLOTS) + if (TabId >= GetPurchasedTabs() || SlotId >= GUILD_BANK_MAX_SLOTS) return NULL; return m_TabListMap[TabId]->Slots[SlotId]; } @@ -1043,9 +1048,9 @@ void Guild::DisplayGuildBankTabsInfo(WorldSession *session) data << uint8(0); // TabInfo packet must be for TabId 0 data << uint32(GetMemberSlotWithdrawRem(session->GetPlayer()->GetGUIDLow(), 0)); data << uint8(1); // Tell client that this packet includes tab info - data << uint8(m_PurchasedTabs); // here is the number of tabs + data << uint8(GetPurchasedTabs()); // here is the number of tabs - for (uint8 i = 0; i < m_PurchasedTabs; ++i) + for (uint8 i = 0; i < GetPurchasedTabs(); ++i) { data << m_TabListMap[i]->Name.c_str(); data << m_TabListMap[i]->Icon.c_str(); @@ -1072,19 +1077,15 @@ void Guild::DisplayGuildBankMoneyUpdate(WorldSession *session) void Guild::CreateNewBankTab() { - if (m_PurchasedTabs >= GUILD_BANK_MAX_TABS) + if (GetPurchasedTabs() >= GUILD_BANK_MAX_TABS) return; - ++m_PurchasedTabs; - - GuildBankTab* AnotherTab = new GuildBankTab; - memset(AnotherTab->Slots, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); - m_TabListMap.resize(m_PurchasedTabs); - m_TabListMap[m_PurchasedTabs-1] = AnotherTab; + uint32 tabId = GetPurchasedTabs(); // next free id + m_TabListMap.push_back(new GuildBankTab); CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", m_Id, uint32(m_PurchasedTabs-1)); - CharacterDatabase.PExecute("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", m_Id, uint32(m_PurchasedTabs-1)); + CharacterDatabase.PExecute("DELETE FROM guild_bank_tab WHERE guildid='%u' AND TabId='%u'", m_Id, tabId); + CharacterDatabase.PExecute("INSERT INTO guild_bank_tab (guildid,TabId) VALUES ('%u','%u')", m_Id, tabId); CharacterDatabase.CommitTransaction(); } @@ -1119,24 +1120,27 @@ void Guild::LoadGuildBankFromDB() QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT TabId, TabName, TabIcon, TabText FROM guild_bank_tab WHERE guildid='%u' ORDER BY TabId", m_Id); if (!result) { - m_PurchasedTabs = 0; + m_TabListMap.clear(); return; } - m_TabListMap.resize(m_PurchasedTabs); do { Field *fields = result->Fetch(); - uint8 TabId = fields[0].GetUInt8(); + uint8 tabId = fields[0].GetUInt8(); + if (tabId >= GetPurchasedTabs()) + { + sLog.outError("Table `guild_bank_tab` have not purchased tab %u for guild %u, skipped", tabId, m_Id); + continue; + } GuildBankTab *NewTab = new GuildBankTab; - memset(NewTab->Slots, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); NewTab->Name = fields[1].GetCppString(); NewTab->Icon = fields[2].GetCppString(); NewTab->Text = fields[3].GetCppString(); - m_TabListMap[TabId] = NewTab; + m_TabListMap[tabId] = NewTab; } while (result->NextRow()); // data needs to be at first place for Item::LoadFromDB @@ -1153,7 +1157,7 @@ void Guild::LoadGuildBankFromDB() uint32 ItemGuid = fields[13].GetUInt32(); uint32 ItemEntry = fields[14].GetUInt32(); - if (TabId >= m_PurchasedTabs || TabId >= GUILD_BANK_MAX_TABS) + if (TabId >= GetPurchasedTabs()) { sLog.outError("Guild::LoadGuildBankFromDB: Invalid tab for item (GUID: %u id: #%u) in guild bank, skipped.", ItemGuid,ItemEntry); continue; @@ -1326,9 +1330,7 @@ void Guild::SetBankMoneyPerDay(uint32 rankId, uint32 money) void Guild::SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 nbSlots, bool db) { - if (rankId >= m_Ranks.size() || - TabId >= GUILD_BANK_MAX_TABS || - TabId >= m_PurchasedTabs) + if (rankId >= m_Ranks.size() || TabId >= GetPurchasedTabs()) return; if (rankId == GR_GUILDMASTER) @@ -1421,7 +1423,7 @@ void Guild::LoadGuildBankEventLogFromDB() //uint32 configCount = sWorld.getConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT); //cycle through all purchased guild bank item tabs - for (uint32 tabId = 0; tabId < m_PurchasedTabs; ++tabId) + for (uint32 tabId = 0; tabId < uint32(GetPurchasedTabs()); ++tabId) { // 0 1 2 3 4 5 6 QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog WHERE guildid='%u' AND TabId='%u' ORDER BY TimeStamp DESC,LogGuid DESC LIMIT %u", m_Id, tabId, GUILD_BANK_MAX_LOGS); @@ -1857,10 +1859,9 @@ uint8 Guild::CanStoreItem(uint8 tab, uint8 slot, GuildItemPosCountVec &dest, uin void Guild::SetGuildBankTabText(uint8 TabId, std::string text) { - if (TabId >= GUILD_BANK_MAX_TABS) - return; - if (TabId >= m_TabListMap.size()) + if (TabId >= GetPurchasedTabs()) return; + if (!m_TabListMap[TabId]) return; @@ -2339,6 +2340,27 @@ void Guild::BroadcastEvent(GuildEvents event, uint64 guid, uint8 strCount, std:: sLog.outDebug("WORLD: Sent SMSG_GUILD_EVENT"); } +void Guild::DeleteGuildBankItems( bool alsoInDB /*= false*/ ) +{ + for (size_t i = 0; i < m_TabListMap.size(); ++i) + { + for (uint8 j = 0; j < GUILD_BANK_MAX_SLOTS; ++j) + { + if (Item* pItem = m_TabListMap[i]->Slots[j]) + { + pItem->RemoveFromWorld(); + + if (alsoInDB) + pItem->DeleteFromDB(); + + delete pItem; + } + } + delete m_TabListMap[i]; + } + m_TabListMap.clear(); +} + bool GuildItemPosCount::isContainedIn(GuildItemPosCountVec const &vec) const { for (GuildItemPosCountVec::const_iterator itr = vec.begin(); itr != vec.end(); ++itr) diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index e4d02f20758..b8e2ef01795 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -230,6 +230,8 @@ struct GuildBankEventLogEntry struct GuildBankTab { + GuildBankTab() { memset(Slots, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); } + Item* Slots[GUILD_BANK_MAX_SLOTS]; std::string Name; std::string Icon; @@ -292,6 +294,7 @@ class Guild void CreateDefaultGuildRanks(int locale_idx); void Disband(); + void DeleteGuildBankItems(bool alsoInDB = false); typedef std::map<uint32, MemberSlot> MemberList; typedef std::vector<RankInfo> RankList; @@ -401,7 +404,7 @@ class Guild void SetGuildBankTabText(uint8 TabId, std::string text); void SendGuildBankTabText(WorldSession *session, uint8 TabId); void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon); - const uint8 GetPurchasedTabs() const { return m_PurchasedTabs; } + uint8 GetPurchasedTabs() const { return m_TabListMap.size(); } uint32 GetBankRights(uint32 rankId, uint8 TabId) const; bool IsMemberHaveRights(uint32 LowGuid, uint8 TabId,uint32 rights) const; bool CanMemberViewTab(uint32 LowGuid, uint8 TabId) const; @@ -464,7 +467,6 @@ class Guild uint32 m_GuildBankEventLogNextGuid_Item[GUILD_BANK_MAX_TABS]; uint64 m_GuildBankMoney; - uint8 m_PurchasedTabs; private: void UpdateAccountsNumber(); |