[6897] Avoid DB access on uninvite from group.

Signed-off-by: hunuza <hunuza@gmail.com>
This commit is contained in:
hunuza 2008-11-29 10:07:58 +01:00
parent bc816b70fc
commit ac2748a141
8 changed files with 113 additions and 79 deletions

View file

@ -212,7 +212,7 @@ bool Group::AddInvite(Player *player)
RemoveInvite(player);
m_invitees.insert(player->GetGUID());
m_invitees.insert(player);
player->SetGroupInvite(this);
@ -231,14 +231,7 @@ bool Group::AddLeaderInvite(Player *player)
uint32 Group::RemoveInvite(Player *player)
{
for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr)
{
if((*itr) == player->GetGUID())
{
m_invitees.erase(itr);
break;
}
}
m_invitees.erase(player);
player->SetGroupInvite(NULL);
return GetMembersCount();
@ -247,14 +240,31 @@ uint32 Group::RemoveInvite(Player *player)
void Group::RemoveAllInvites()
{
for(InvitesList::iterator itr=m_invitees.begin(); itr!=m_invitees.end(); ++itr)
{
Player *invitee = objmgr.GetPlayer(*itr);
if(invitee)
invitee->SetGroupInvite(NULL);
}
(*itr)->SetGroupInvite(NULL);
m_invitees.clear();
}
Player* Group::GetInvited(const uint64& guid) const
{
for(InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
{
if((*itr)->GetGUID() == guid)
return (*itr);
}
return NULL;
}
Player* Group::GetInvited(const std::string& name) const
{
for(InvitesList::const_iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr)
{
if((*itr)->GetName() == name)
return (*itr);
}
return NULL;
}
bool Group::AddMember(const uint64 &guid, const char* name)
{
if(!_addMember(guid, name))

View file

@ -143,7 +143,7 @@ class MANGOS_DLL_SPEC Group
typedef UNORDERED_MAP< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap;
protected:
typedef MemberSlotList::iterator member_witerator;
typedef std::set<uint64> InvitesList;
typedef std::set<Player*> InvitesList;
typedef std::vector<Roll*> Rolls;
@ -183,6 +183,17 @@ class MANGOS_DLL_SPEC Group
// member manipulation methods
bool IsMember(const uint64& guid) const { return _getMemberCSlot(guid) != m_memberSlots.end(); }
bool IsLeader(const uint64& guid) const { return (GetLeaderGUID() == guid); }
uint64 GetMemberGUID(const std::string& name)
{
for(member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr)
{
if(itr->name == name)
{
return itr->guid;
}
}
return 0;
}
bool IsAssistant(uint64 guid) const
{
member_citerator mslot = _getMemberCSlot(guid);
@ -191,6 +202,8 @@ class MANGOS_DLL_SPEC Group
return mslot->assistant;
}
Player* GetInvited(const uint64& guid) const;
Player* GetInvited(const std::string& name) const;
bool SameSubGroup(uint64 guid1,const uint64& guid2) const
{

View file

@ -42,7 +42,7 @@
-FIX sending PartyMemberStats
*/
void WorldSession::SendPartyResult(PartyOperation operation, std::string member, PartyResult res)
void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res)
{
WorldPacket data(SMSG_PARTY_COMMAND_RESULT, (8+member.size()+1));
data << (uint32)operation;
@ -246,17 +246,37 @@ void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket & recv_data)
uint64 guid;
recv_data >> guid;
if(_player->InBattleGround())
//can't uninvite yourself
if(guid == GetPlayer()->GetGUID())
{
SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
sLog.outError("WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return;
}
std::string membername;
if(!objmgr.GetPlayerNameByGUID(guid, membername))
return; // not found
PartyResult res = GetPlayer()->CanUninviteFromGroup();
if(res != PARTY_RESULT_OK)
{
SendPartyResult(PARTY_OP_LEAVE, "", res);
return;
}
HandleGroupUninvite(guid, membername);
Group* grp = GetPlayer()->GetGroup();
if(!grp)
return;
if(grp->IsMember(guid))
{
Player::RemoveFromGroup(grp,guid);
return;
}
if(Player* plr = grp->GetInvited(guid))
{
plr->UninviteFromGroup();
return;
}
SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_NOT_IN_YOUR_PARTY);
}
void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
@ -266,65 +286,41 @@ void WorldSession::HandleGroupUninviteNameOpcode(WorldPacket & recv_data)
std::string membername;
recv_data >> membername;
if(_player->InBattleGround())
{
SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_INVITE_RESTRICTED);
return;
}
// player not found
if(!normalizePlayerName(membername))
return;
uint64 guid = objmgr.GetPlayerGUIDByName(membername);
// player not found
if(!guid)
return;
HandleGroupUninvite(guid, membername);
}
void WorldSession::HandleGroupUninvite(uint64 guid, std::string name)
// can't uninvite yourself
if(GetPlayer()->GetName() == membername)
{
Group *group = GetPlayer()->GetGroup();
if(!group)
return;
if(_player->InBattleGround())
{
SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED);
sLog.outError("WorldSession::HandleGroupUninviteNameOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return;
}
Player *player = objmgr.GetPlayer(guid);
/** error handling **/
if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
PartyResult res = GetPlayer()->CanUninviteFromGroup();
if(res != PARTY_RESULT_OK)
{
SendPartyResult(PARTY_OP_LEAVE, "", PARTY_RESULT_YOU_NOT_LEADER);
SendPartyResult(PARTY_OP_LEAVE, "", res);
return;
}
if(!group->IsMember(guid) && (player && player->GetGroupInvite() != group))
Group* grp = GetPlayer()->GetGroup();
if(!grp)
return;
if(uint64 guid = grp->GetMemberGUID(membername))
{
SendPartyResult(PARTY_OP_LEAVE, name, PARTY_RESULT_NOT_IN_YOUR_PARTY);
Player::RemoveFromGroup(grp,guid);
return;
}
if(guid == GetPlayer()->GetGUID())
if(Player* plr = grp->GetInvited(membername))
{
sLog.outError("WorldSession::HandleGroupUninvite: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
plr->UninviteFromGroup();
return;
}
/********************/
// everything's fine, do it
if(player && player->GetGroupInvite()) // uninvite invitee
player->UninviteFromGroup();
else // uninvite member
Player::RemoveFromGroup(group,guid);
SendPartyResult(PARTY_OP_LEAVE, membername, PARTY_RESULT_NOT_IN_YOUR_PARTY);
}
void WorldSession::HandleGroupSetLeaderOpcode( WorldPacket & recv_data )

View file

@ -329,7 +329,7 @@ class Guild
{
return (members.find(LowGuid) != members.end());
}
MemberSlot* GetMemberSlot(std::string const& name, uint64& guid)
MemberSlot* GetMemberSlot(const std::string& name, uint64& guid)
{
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
{

View file

@ -2023,10 +2023,11 @@ bool Player::IsInSameGroupWith(Player const* p) const
///- If the player is invited, remove him. If the group if then only 1 person, disband the group.
/// \todo Shouldn't we also check if there is no other invitees before disbanding the group?
void Player::UninviteFromGroup()
{
if(GetGroupInvite()) // uninvited invitee
{
Group* group = GetGroupInvite();
if(!group)
return;
group->RemoveInvite(this);
if(group->GetMembersCount() <= 1) // group has just 1 member => disband
@ -2042,7 +2043,6 @@ void Player::UninviteFromGroup()
delete group;
}
}
}
void Player::RemoveFromGroup(Group* group, uint64 guid)
{
@ -18237,6 +18237,21 @@ Player* Player::GetNextRandomRaidMember(float radius)
return nearMembers[randTarget];
}
PartyResult Player::CanUninviteFromGroup() const
{
const Group* grp = GetGroup();
if(!grp)
return PARTY_RESULT_YOU_NOT_IN_GROUP;
if(!grp->IsLeader(GetGUID()) && !grp->IsAssistant(GetGUID()))
return PARTY_RESULT_YOU_NOT_LEADER;
if(InBattleGround())
return PARTY_RESULT_INVITE_RESTRICTED;
return PARTY_RESULT_OK;
}
void Player::UpdateUnderwaterState( Map* m, float x, float y, float z )
{
float water_z = m->GetWaterLevel(x,y);

View file

@ -2026,6 +2026,7 @@ class MANGOS_DLL_SPEC Player : public Unit
uint64 GetAuraUpdateMask() { return m_auraUpdateMask; }
void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); }
Player* GetNextRandomRaidMember(float radius);
PartyResult CanUninviteFromGroup() const;
GridReference<Player> &GetGridRef() { return m_gridRef; }
MapReference &GetMapRef() { return m_mapRef; }

View file

@ -83,7 +83,7 @@ class MANGOS_DLL_SPEC WorldSession
void SendNotification(int32 string_id,...);
void SendPetNameInvalid(uint32 error, std::string name, DeclinedName *declinedName);
void SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type);
void SendPartyResult(PartyOperation operation, std::string member, PartyResult res);
void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res);
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2,3);
uint32 GetSecurity() const { return _security; }
@ -332,7 +332,6 @@ class MANGOS_DLL_SPEC WorldSession
void HandleGroupDeclineOpcode(WorldPacket& recvPacket);
void HandleGroupUninviteNameOpcode(WorldPacket& recvPacket);
void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket);
void HandleGroupUninvite(uint64 guid, std::string name);
void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket);
void HandleGroupLeaveOpcode(WorldPacket& recvPacket);
void HandleGroupPassOnLootOpcode( WorldPacket &recv_data );

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "6896"
#define REVISION_NR "6897"
#endif // __REVISION_NR_H__