diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 48385b773..bf5271908 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -301,10 +301,8 @@ bool Guild::CheckGuildStructure() int32 GM_rights = GetRank(m_LeaderGuid); if (GM_rights == -1) { - DelMember(m_LeaderGuid); - // check no members case (disbanded) - if (members.empty()) - return false; + if (DelMember(m_LeaderGuid)) + return false; // guild will disbanded and deleted in caller } else if (GM_rights != GR_GUILDMASTER) SetLeader(m_LeaderGuid); @@ -488,7 +486,15 @@ void Guild::SetLeader(ObjectGuid guid) CharacterDatabase.PExecute("UPDATE guild SET leaderguid='%u' WHERE guildid='%u'", guid.GetCounter(), m_Id); } -void Guild::DelMember(ObjectGuid guid, bool isDisbanding) +/** + * Remove character from guild + * + * @param guid Character that removed from guild + * @param isDisbanding Flag set if function called from Guild::Disband, so not need update DB in per-member mode only or leader update + * + * @return true, if guild need to be disband and erase (no members or can't setup leader) + */ +bool Guild::DelMember(ObjectGuid guid, bool isDisbanding) { uint32 lowguid = guid.GetCounter(); @@ -513,11 +519,9 @@ void Guild::DelMember(ObjectGuid guid, bool isDisbanding) newLeaderGUID = ObjectGuid(HIGHGUID_PLAYER, i->first); } } + if (!best) - { - Disband(); - return; - } + return true; SetLeader(newLeaderGUID); @@ -547,6 +551,8 @@ void Guild::DelMember(ObjectGuid guid, bool isDisbanding) if (!isDisbanding) UpdateAccountsNumber(); + + return members.empty(); } void Guild::BroadcastToGuild(WorldSession *session, const std::string& msg, uint32 language) @@ -685,6 +691,11 @@ void Guild::SetRankRights(uint32 rankId, uint32 rights) CharacterDatabase.PExecute("UPDATE guild_rank SET rights='%u' WHERE rid='%u' AND guildid='%u'", rights, rankId, m_Id); } +/** + * Disband guild including cleanup structures and DB + * + * Note: guild object need deleted after this in caller code. + */ void Guild::Disband() { BroadcastEvent(GE_DISBANDED); diff --git a/src/game/Guild.h b/src/game/Guild.h index d93d2a2cb..0c97ee342 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -324,7 +324,7 @@ class Guild void SetLeader(ObjectGuid guid); bool AddMember(ObjectGuid plGuid, uint32 plRank); - void DelMember(ObjectGuid guid, bool isDisbanding = false); + bool DelMember(ObjectGuid guid, bool isDisbanding = false); //lowest rank is the count of ranks - 1 (the highest rank_id in table) uint32 GetLowestRank() const { return m_Ranks.size() - 1; } diff --git a/src/game/GuildHandler.cpp b/src/game/GuildHandler.cpp index 3e3a9c094..883be7ec7 100644 --- a/src/game/GuildHandler.cpp +++ b/src/game/GuildHandler.cpp @@ -177,7 +177,14 @@ void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket) return; } - guild->DelMember(slot->guid); + // possible last member removed, do cleanup, and no need events + if (guild->DelMember(slot->guid)) + { + guild->Disband(); + delete guild; + return; + } + // Put record into guild log guild->LogGuildEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, GetPlayer()->GetObjectGuid(), slot->guid); @@ -376,16 +383,23 @@ void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/) if (_player->GetObjectGuid() == guild->GetLeaderGuid()) { guild->Disband(); + delete guild; + return; + } + + SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), ERR_PLAYER_NO_MORE_IN_GUILD); + + if (guild->DelMember(_player->GetObjectGuid())) + { + guild->Disband(); + delete guild; return; } - guild->DelMember(_player->GetObjectGuid()); // Put record into guild log guild->LogGuildEvent(GUILD_EVENT_LOG_LEAVE_GUILD, _player->GetObjectGuid()); guild->BroadcastEvent(GE_LEFT, _player->GetObjectGuid(), _player->GetName()); - - SendGuildCommandResult(GUILD_QUIT_S, guild->GetName(), ERR_PLAYER_NO_MORE_IN_GUILD); } void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) @@ -406,6 +420,7 @@ void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/) } guild->Disband(); + delete guild; DEBUG_LOG("WORLD: Guild Successfully Disbanded"); } diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 39cdefd24..edad06b5a 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -3608,7 +3608,12 @@ bool ChatHandler::HandleGuildUninviteCommand(char *args) if (!targetGuild) return false; - targetGuild->DelMember(target_guid); + if (targetGuild->DelMember(target_guid)) + { + targetGuild->Disband(); + delete targetGuild; + } + return true; } @@ -3651,7 +3656,7 @@ bool ChatHandler::HandleGuildDeleteCommand(char* args) return false; char* guildStr = ExtractQuotedArg(&args); - if(!guildStr) + if (!guildStr) return false; std::string gld = guildStr; @@ -3660,7 +3665,8 @@ bool ChatHandler::HandleGuildDeleteCommand(char* args) if (!targetGuild) return false; - targetGuild->Disband (); + targetGuild->Disband(); + delete targetGuild; return true; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ce5562109..149587753 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4174,8 +4174,16 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe // remove from guild if (uint32 guildId = GetGuildIdFromDB(playerguid)) + { if (Guild* guild = sGuildMgr.GetGuildById(guildId)) - guild->DelMember(playerguid); + { + if (guild->DelMember(playerguid)) + { + guild->Disband(); + delete guild; + } + } + } // remove from arena teams LeaveAllArenaTeams(playerguid); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 34df3207b..37456a529 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11533" + #define REVISION_NR "11534" #endif // __REVISION_NR_H__