aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoc13x <roc13x@gmail.com>2018-04-22 19:04:02 +0100
committerjoschiwald <joschiwald.trinity@gmail.com>2018-04-22 20:04:02 +0200
commit6b9948857057cfe495807a61b6797c75d9fc7a6a (patch)
treecd1a825be5c9a1dd57944677d09eb80ea20b21ee /src
parent4feaf2463ddf87621a3571f90043d8e8c5c1a22b (diff)
Core/Guild: Implemented guild master dethrone (#21833)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Guilds/Guild.cpp59
-rw-r--r--src/server/game/Guilds/Guild.h4
-rw-r--r--src/server/game/Handlers/GuildHandler.cpp8
-rw-r--r--src/server/game/Server/Packets/GuildPackets.cpp4
-rw-r--r--src/server/game/Server/Packets/GuildPackets.h8
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
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);