Channel Followup: avoid setting an invisible gm as Channel owner (#17597)
* Core/Chat: avoid setting an invisible gm (as in .gm visible off) as channel owner, giving it away to other players. - This can now only happen if the channel is empty or every other member is an invisible gm, too. Fixes #17424 * Feedback based changes
This commit is contained in:
1 parent
6edd4536cf
commit
f404226fb1
3 files changed
+52
-6
No files matched your search
@@ -29,6 +29,7 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team /*= 0*/)
|
||||
_announceEnabled(true),
|
||||
_ownershipEnabled(true),
|
||||
_persistentChannel(false),
|
||||
_isOwnerInvisible(false),
|
||||
_channelFlags(0),
|
||||
_channelId(channelId),
|
||||
_channelTeam(team),
|
||||
@@ -197,8 +198,11 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
|
||||
SendToAll(&data);
|
||||
}
|
||||
|
||||
bool newChannel = _playersStore.empty();
|
||||
|
||||
PlayerInfo& pinfo = _playersStore[guid];
|
||||
pinfo.flags = MEMBER_FLAG_NONE;
|
||||
pinfo.invisible = !player->isGMVisible();
|
||||
|
||||
WorldPacket data;
|
||||
MakeYouJoined(&data);
|
||||
@@ -213,9 +217,13 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
|
||||
UpdateChannelUseageInDB();
|
||||
|
||||
// If the channel has no owner yet and ownership is allowed, set the new owner.
|
||||
if (!_ownerGuid && _ownershipEnabled)
|
||||
// or if the owner was a GM with .gm visible off
|
||||
// don't do this if the new player is, too, an invis GM, unless the channel was empty
|
||||
if (_ownershipEnabled && (newChannel || !pinfo.IsInvisible()) && (!_ownerGuid || _isOwnerInvisible))
|
||||
{
|
||||
SetOwner(guid, _playersStore.size() > 1);
|
||||
_isOwnerInvisible = pinfo.IsInvisible();
|
||||
|
||||
SetOwner(guid, !newChannel && !_isOwnerInvisible);
|
||||
pinfo.SetModerator(true);
|
||||
}
|
||||
}
|
||||
@@ -262,13 +270,28 @@ void Channel::LeaveChannel(Player* player, bool send)
|
||||
// Update last_used timestamp in db
|
||||
UpdateChannelUseageInDB();
|
||||
|
||||
// If the channel owner left and there are still players inside, pick a new owner
|
||||
// If the channel owner left and there are players still inside, pick a new owner
|
||||
// do not pick invisible gm owner unless there are only invisible gms in that channel (rare)
|
||||
if (changeowner && _ownershipEnabled && !_playersStore.empty())
|
||||
{
|
||||
auto itr = _playersStore.begin();
|
||||
ObjectGuid newowner = itr->first;
|
||||
PlayerContainer::iterator itr;
|
||||
for (itr = _playersStore.begin(); itr != _playersStore.end(); ++itr)
|
||||
{
|
||||
if (!itr->second.IsInvisible())
|
||||
break;
|
||||
}
|
||||
|
||||
if (itr == _playersStore.end())
|
||||
itr = _playersStore.begin();
|
||||
|
||||
ObjectGuid newOwner = itr->first;
|
||||
itr->second.SetModerator(true);
|
||||
SetOwner(newowner);
|
||||
|
||||
SetOwner(newOwner);
|
||||
|
||||
// if the new owner is invisible gm, set flag to automatically choose a new owner
|
||||
if (itr->second.IsInvisible())
|
||||
_isOwnerInvisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,6 +491,19 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
|
||||
SetMute(newp->GetGUID(), set);
|
||||
}
|
||||
|
||||
void Channel::SetInvisible(Player const* player, bool on)
|
||||
{
|
||||
auto itr = _playersStore.find(player->GetGUID());
|
||||
if (itr == _playersStore.end())
|
||||
return;
|
||||
|
||||
itr->second.SetInvisible(on);
|
||||
|
||||
// we happen to be owner too, update flag
|
||||
if (_ownerGuid == player->GetGUID())
|
||||
_isOwnerInvisible = on;
|
||||
}
|
||||
|
||||
void Channel::SetOwner(Player const* player, std::string const& newname)
|
||||
{
|
||||
ObjectGuid guid = player->GetGUID();
|
||||
|
||||
@@ -119,6 +119,10 @@ class TC_GAME_API Channel
|
||||
struct PlayerInfo
|
||||
{
|
||||
uint8 flags;
|
||||
bool invisible;
|
||||
|
||||
bool IsInvisible() const { return invisible; }
|
||||
void SetInvisible(bool on) { invisible = on; }
|
||||
|
||||
bool HasFlag(uint8 flag) const { return (flags & flag) != 0; }
|
||||
void SetFlag(uint8 flag) { flags |= flag; }
|
||||
@@ -182,6 +186,8 @@ class TC_GAME_API Channel
|
||||
void SetMute(Player const* player, std::string const& newname) { SetMode(player, newname, false, true); }
|
||||
void UnsetMute(Player const* player, std::string const& newname) { SetMode(player, newname, false, false); }
|
||||
|
||||
void SetInvisible(Player const* player, bool on);
|
||||
|
||||
void SetOwner(ObjectGuid guid, bool exclaim = true);
|
||||
void SetOwner(Player const* player, std::string const& name);
|
||||
void SendWhoOwner(ObjectGuid guid);
|
||||
@@ -292,6 +298,7 @@ class TC_GAME_API Channel
|
||||
bool _announceEnabled; //< Whether we should broadcast a packet whenever a player joins/exits the channel
|
||||
bool _ownershipEnabled; //< Whether the channel has to maintain an owner
|
||||
bool _persistentChannel; //< Whether the channel is saved to DB
|
||||
bool _isOwnerInvisible; //< Whether the channel is owned by invisible GM, ownership should change to first player that joins channel
|
||||
|
||||
uint8 _channelFlags;
|
||||
uint32 _channelId;
|
||||
|
||||
@@ -2695,6 +2695,9 @@ void Player::SetGMVisible(bool on)
|
||||
|
||||
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GM, GetSession()->GetSecurity());
|
||||
}
|
||||
|
||||
for (Channel* channel : m_channels)
|
||||
channel->SetInvisible(this, !on);
|
||||
}
|
||||
|
||||
bool Player::IsGroupVisibleFor(Player const* p) const
|
||||
|
||||
Reference in new issue
Block a user