From ac2748a141fcea3b5d4bdad3f502252061f3f00f Mon Sep 17 00:00:00 2001 From: hunuza Date: Sat, 29 Nov 2008 10:07:58 +0100 Subject: [PATCH] [6897] Avoid DB access on uninvite from group. Signed-off-by: hunuza --- src/game/Group.cpp | 38 ++++++++++------- src/game/Group.h | 15 ++++++- src/game/GroupHandler.cpp | 88 +++++++++++++++++++-------------------- src/game/Guild.h | 2 +- src/game/Player.cpp | 43 ++++++++++++------- src/game/Player.h | 1 + src/game/WorldSession.h | 3 +- src/shared/revision_nr.h | 2 +- 8 files changed, 113 insertions(+), 79 deletions(-) diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 9cf107f06..de97b70b3 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -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)) diff --git a/src/game/Group.h b/src/game/Group.h index 6160fd0f2..a9e6a733f 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -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 InvitesList; + typedef std::set InvitesList; typedef std::vector 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 { diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index ad56314e7..2d05e6655 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -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) -{ - Group *group = GetPlayer()->GetGroup(); - if(!group) - return; - - if(_player->InBattleGround()) + // can't uninvite yourself + if(GetPlayer()->GetName() == membername) { - 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 ) diff --git a/src/game/Guild.h b/src/game/Guild.h index 31da4438a..a97a8cfb0 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -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) { diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 2f76c0632..5a517f45d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2024,23 +2024,23 @@ bool Player::IsInSameGroupWith(Player const* p) const /// \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 { - Group* group = GetGroupInvite(); - group->RemoveInvite(this); - - if(group->GetMembersCount() <= 1) // group has just 1 member => disband + if(group->IsCreated()) { - if(group->IsCreated()) - { - group->Disband(true); - objmgr.RemoveGroup(group); - } - else - group->RemoveAllInvites(); - - delete group; + group->Disband(true); + objmgr.RemoveGroup(group); } + else + group->RemoveAllInvites(); + + delete group; } } @@ -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); diff --git a/src/game/Player.h b/src/game/Player.h index fefcaa04d..bc7e3d39c 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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 &GetGridRef() { return m_gridRef; } MapReference &GetMapRef() { return m_mapRef; } diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 6a8d609d9..6077d42b4 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -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 ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c526a60bc..4a197620a 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 "6896" + #define REVISION_NR "6897" #endif // __REVISION_NR_H__