diff options
-rw-r--r-- | src/server/game/Guilds/Guild.cpp | 59 | ||||
-rw-r--r-- | src/server/game/Guilds/Guild.h | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/GuildHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Server/Packets/GuildPackets.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/GuildPackets.h | 8 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 2 |
7 files changed, 66 insertions, 21 deletions
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 93ad5574a13..ac4f7e6e62d 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -658,6 +658,13 @@ bool Guild::Member::CheckStats() const return true; } +float Guild::Member::GetInactiveDays() const +{ + if (IsOnline()) + return 0.0f; + return float(::time(nullptr) - GetLogoutTime()) / float(DAY); +} + // Decreases amount of slots left for today. void Guild::Member::UpdateBankTabWithdrawValue(SQLTransaction& trans, uint8 tabId, uint32 amount) { @@ -1321,7 +1328,7 @@ void Guild::HandleRoster(WorldSession* session) memberData.AreaID = int32(member->GetZoneId()); memberData.PersonalAchievementPoints = int32(member->GetAchievementPoints()); memberData.GuildReputation = int32(member->GetTotalReputation()); - memberData.LastSave = float(member->IsOnline() ? 0.0f : float(::time(nullptr) - member->GetLogoutTime()) / DAY); + memberData.LastSave = member->GetInactiveDays(); //GuildRosterProfessionData @@ -1504,28 +1511,48 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo) } } -void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& name) +void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& name, bool isSelfPromote) { Player* player = session->GetPlayer(); - // Only the guild master can throne a new guild master - if (!_IsLeader(player)) - SendCommandResult(session, GUILD_COMMAND_CHANGE_LEADER, ERR_GUILD_PERMISSIONS); - // Old GM must be a guild member - else if (Member* oldGuildMaster = GetMember(player->GetGUID())) - { - // Same for the new one - if (Member* newGuildMaster = GetMember(name)) - { - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - _SetLeader(trans, newGuildMaster); - oldGuildMaster->ChangeRank(trans, GR_INITIATE); + Member* oldGuildMaster = GetMember(GetLeaderGUID()); + ASSERT(oldGuildMaster); - SendEventNewLeader(newGuildMaster, oldGuildMaster); + Member* newGuildMaster; - CharacterDatabase.CommitTransaction(trans); + if (isSelfPromote) + { + newGuildMaster = GetMember(player->GetGUID()); + if (!newGuildMaster) + return; + + if (!newGuildMaster->IsRankNotLower(GR_MEMBER) || uint32(oldGuildMaster->GetInactiveDays()) < GUILD_MASTER_DETHRONE_INACTIVE_DAYS) + { + SendCommandResult(session, GUILD_COMMAND_CHANGE_LEADER, ERR_GUILD_PERMISSIONS); + return; } } + else + { + if (!_IsLeader(player)) + { + SendCommandResult(session, GUILD_COMMAND_CHANGE_LEADER, ERR_GUILD_PERMISSIONS); + return; + } + + newGuildMaster = GetMember(name); + if (!newGuildMaster) + return; + } + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + _SetLeader(trans, newGuildMaster); + oldGuildMaster->ChangeRank(trans, GR_INITIATE); + + SendEventNewLeader(newGuildMaster, oldGuildMaster, isSelfPromote); + + CharacterDatabase.CommitTransaction(trans); } void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon) diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index d8684ebd3ea..03781d37ab0 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -48,6 +48,7 @@ enum GuildMisc GUILD_BANK_MAX_TABS = 8, // send by client for money log also GUILD_BANK_MAX_SLOTS = 98, GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB + GUILD_MASTER_DETHRONE_INACTIVE_DAYS = 90, GUILD_RANKS_MIN_COUNT = 2, GUILD_RANKS_MAX_COUNT = 10, GUILD_RANK_NONE = 0xFF, @@ -353,6 +354,7 @@ class TC_GAME_API Guild uint32 GetAccountId() const { return m_accountId; } uint8 GetRankId() const { return m_rankId; } uint64 GetLogoutTime() const { return m_logoutTime; } + float GetInactiveDays() const; std::string GetPublicNote() const { return m_publicNote; } std::string GetOfficerNote() const { return m_officerNote; } uint8 GetClass() const { return m_class; } @@ -758,7 +760,7 @@ class TC_GAME_API Guild void HandleSetMOTD(WorldSession* session, std::string const& motd); void HandleSetInfo(WorldSession* session, std::string const& info); void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo); - void HandleSetNewGuildMaster(WorldSession* session, std::string const& name); + void HandleSetNewGuildMaster(WorldSession* session, std::string const& name, bool isSelfPromote); void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon); void HandleSetMemberNote(WorldSession* session, std::string const& note, ObjectGuid guid, bool isPublic); void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots); diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 13670acfa36..d12e83bb078 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -417,10 +417,16 @@ void WorldSession::HandleGuildNewsUpdateSticky(WorldPackets::Guild::GuildNewsUpd guild->HandleNewsSetSticky(this, packet.NewsID, packet.Sticky); } +void WorldSession::HandleGuildReplaceGuildMaster(WorldPackets::Guild::GuildReplaceGuildMaster& /*replaceGuildMaster*/) +{ + if (Guild* guild = GetPlayer()->GetGuild()) + guild->HandleSetNewGuildMaster(this, "", true); +} + void WorldSession::HandleGuildSetGuildMaster(WorldPackets::Guild::GuildSetGuildMaster& packet) { if (Guild* guild = GetPlayer()->GetGuild()) - guild->HandleSetNewGuildMaster(this, packet.NewMasterName); + guild->HandleSetNewGuildMaster(this, packet.NewMasterName, false); } void WorldSession::HandleGuildSetAchievementTracking(WorldPackets::Guild::GuildSetAchievementTracking& packet) diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp index 367021001c2..777891b3cef 100644 --- a/src/server/game/Server/Packets/GuildPackets.cpp +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -320,8 +320,8 @@ void WorldPackets::Guild::GuildSetRankPermissions::Read() WorldPacket const* WorldPackets::Guild::GuildEventNewLeader::Write() { _worldPacket.WriteBit(SelfPromoted); - _worldPacket.WriteBits(NewLeaderName.length(), 6); _worldPacket.WriteBits(OldLeaderName.length(), 6); + _worldPacket.WriteBits(NewLeaderName.length(), 6); _worldPacket.FlushBits(); _worldPacket << OldLeaderGUID; @@ -329,8 +329,8 @@ WorldPacket const* WorldPackets::Guild::GuildEventNewLeader::Write() _worldPacket << NewLeaderGUID; _worldPacket << NewLeaderVirtualRealmAddress; - _worldPacket.WriteString(NewLeaderName); _worldPacket.WriteString(OldLeaderName); + _worldPacket.WriteString(NewLeaderName); return &_worldPacket; } diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h index f781e81b868..350ff772000 100644 --- a/src/server/game/Server/Packets/GuildPackets.h +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -945,6 +945,14 @@ namespace WorldPackets bool Sticky = false; }; + class GuildReplaceGuildMaster final : public ClientPacket + { + public: + GuildReplaceGuildMaster(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_REPLACE_GUILD_MASTER, std::move(packet)) { } + + void Read() override { } + }; + class GuildSetGuildMaster final : public ClientPacket { public: diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 7d893b33f7d..aabd733d554 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -455,7 +455,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_GUILD_QUERY_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildQueryNews); DEFINE_HANDLER(CMSG_GUILD_QUERY_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); - DEFINE_HANDLER(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildReplaceGuildMaster); DEFINE_HANDLER(CMSG_GUILD_SET_ACHIEVEMENT_TRACKING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetAchievementTracking); DEFINE_HANDLER(CMSG_GUILD_SET_FOCUSED_ACHIEVEMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetFocusedAchievement); DEFINE_HANDLER(CMSG_GUILD_SET_GUILD_MASTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetGuildMaster); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 4d21373730c..bba6b5ce039 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -333,6 +333,7 @@ namespace WorldPackets class RequestGuildRewardsList; class GuildQueryNews; class GuildNewsUpdateSticky; + class GuildReplaceGuildMaster; class GuildSetGuildMaster; class GuildChallengeUpdateRequest; class SaveGuildEmblem; @@ -1292,6 +1293,7 @@ class TC_GAME_API WorldSession void HandleGuildAssignRank(WorldPackets::Guild::GuildAssignMemberRank& packet); void HandleGuildLeave(WorldPackets::Guild::GuildLeave& leave); void HandleGuildDelete(WorldPackets::Guild::GuildDelete& packet); + void HandleGuildReplaceGuildMaster(WorldPackets::Guild::GuildReplaceGuildMaster& replaceGuildMaster); void HandleGuildSetAchievementTracking(WorldPackets::Guild::GuildSetAchievementTracking& packet); void HandleGuildGetAchievementMembers(WorldPackets::Achievement::GuildGetAchievementMembers& getAchievementMembers); void HandleGuildSetGuildMaster(WorldPackets::Guild::GuildSetGuildMaster& packet); |