aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjackpoz <giacomopoz@gmail.com>2013-09-05 21:51:02 +0200
committerjackpoz <giacomopoz@gmail.com>2013-09-05 22:10:46 +0200
commit9ce70fb3c945e7c10c63d78d18e479a1c11b6211 (patch)
tree4edaac177227497ff0b89a70d6d688835cdf02d5
parentd5d0802262637d5b32555ec453b2034b6be247b8 (diff)
Core/Guild: Fix memory leak on Guild disband
Fix memory leak when disbanding a Guild, removed from GuildMgr but never deleted. Due to the different ways of how Guild::Disband() and Guild::DeleteMember() are called, each call to these methods has a different way to delete the Guild if empty/invalid. Valgrind log: 2,127 (240 direct, 1,887 indirect) bytes in 1 blocks are definitely lost in loss record 54 of 81 at operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by guild_commandscript::HandleGuildCreateCommand(ChatHandler*, char const*) (cs_guild.cpp:91) by ChatHandler::ExecuteCommandInTable(ChatCommand*, char const*, std::string const&) (Chat.cpp:339) by ChatHandler::ExecuteCommandInTable(ChatCommand*, char const*, std::string const&) (Chat.cpp:320) by ChatHandler::ParseCommands(char const*) (Chat.cpp:466) by WorldSession::HandleMessagechatOpcode(WorldPacket&) (ChatHandler.cpp:217) by WorldSession::Update(unsigned int, PacketFilter&) (WorldSession.cpp:317) by World::UpdateSessions(unsigned int) (World.cpp:2632) by World::Update(unsigned int) (World.cpp:1989) by WorldRunnable::run() (WorldRunnable.cpp:60) by ACE_Based::Thread::ThreadTask(void*) (Threading.cpp:186) by ACE_OS_Thread_Adapter::invoke() (in /usr/lib/libACE-6.0.3.so)
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Guilds/Guild.cpp13
-rw-r--r--src/server/game/Guilds/Guild.h2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp2
-rw-r--r--src/server/scripts/Commands/cs_guild.cpp3
5 files changed, 17 insertions, 5 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index b1ee724e5f7..9bdc1ebdfc5 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4713,7 +4713,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
if (uint32 guildId = GetGuildIdFromDB(playerguid))
if (Guild* guild = sGuildMgr->GetGuildById(guildId))
- guild->DeleteMember(guid);
+ guild->DeleteMember(guid, false, false, true);
// remove from arena teams
LeaveAllArenaTeams(playerguid);
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index ab0f1e572f1..cc15d15fdf9 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1578,6 +1578,8 @@ void Guild::HandleAcceptMember(WorldSession* session)
void Guild::HandleLeaveMember(WorldSession* session)
{
Player* player = session->GetPlayer();
+ bool disband = false;
+
// If leader is leaving
if (_IsLeader(player))
{
@@ -1585,8 +1587,11 @@ void Guild::HandleLeaveMember(WorldSession* session)
// Leader cannot leave if he is not the last member
SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_LEADER_LEAVE);
else
+ {
// Guild is disbanded if leader leaves.
Disband();
+ disband = true;
+ }
}
else
{
@@ -1599,6 +1604,9 @@ void Guild::HandleLeaveMember(WorldSession* session)
}
sCalendarMgr->RemovePlayerGuildEventsAndSignups(player->GetGUID(), GetId());
+
+ if (disband)
+ delete this;
}
void Guild::HandleRemoveMember(WorldSession* session, std::string const& name)
@@ -1812,6 +1820,7 @@ void Guild::HandleDisband(WorldSession* session)
{
Disband();
TC_LOG_DEBUG(LOG_FILTER_GUILD, "Guild Successfully Disbanded");
+ delete this;
}
}
@@ -2272,7 +2281,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId)
return true;
}
-void Guild::DeleteMember(uint64 guid, bool isDisbanding, bool isKicked)
+void Guild::DeleteMember(uint64 guid, bool isDisbanding, bool isKicked, bool canDeleteGuild)
{
uint32 lowguid = GUID_LOPART(guid);
Player* player = ObjectAccessor::FindPlayer(guid);
@@ -2294,6 +2303,8 @@ void Guild::DeleteMember(uint64 guid, bool isDisbanding, bool isKicked)
if (!newLeader)
{
Disband();
+ if (canDeleteGuild)
+ delete this;
return;
}
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index fab39f48fca..4d8987dbbf0 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -727,7 +727,7 @@ public:
// Members
// Adds member to guild. If rankId == GUILD_RANK_NONE, lowest rank is assigned.
bool AddMember(uint64 guid, uint8 rankId = GUILD_RANK_NONE);
- void DeleteMember(uint64 guid, bool isDisbanding = false, bool isKicked = false);
+ void DeleteMember(uint64 guid, bool isDisbanding = false, bool isKicked = false, bool canDeleteGuild = false);
bool ChangeMemberRank(uint64 guid, uint8 newRank);
// Bank
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 6a7e6c5dedd..9e1dbc133a5 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1918,7 +1918,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
if (Guild* guild = sGuildMgr->GetGuildById((result->Fetch()[0]).GetUInt32()))
- guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER));
+ guild->DeleteMember(MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER), false, false, true);
}
if (!HasPermission(RBAC_PERM_TWO_SIDE_ADD_FRIEND))
diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index 0af0da10846..040c68dbacb 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -118,6 +118,7 @@ public:
return false;
targetGuild->Disband();
+ delete targetGuild;
return true;
}
@@ -164,7 +165,7 @@ public:
if (!targetGuild)
return false;
- targetGuild->DeleteMember(targetGuid, false, true);
+ targetGuild->DeleteMember(targetGuid, false, true, true);
return true;
}