From f440a7479f75dfb60e2a09c81471791579aac58c Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Sun, 26 Nov 2023 20:34:45 +0100 Subject: [PATCH] fix(Core/Groups): Create the group at first invite (#17869) * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/132538db1dfb3c495294eeb5acfead59dea02b5c) * cherry-pick commit (https://github.com/TrinityCore/TrinityCore/commit/250e8d998bca7f239e2393b6d002441f70d4daf0) * part https://github.com/azerothcore/azerothcore-wotlk/issues/11070 Co-authored-by: Treeston <14020072+Treeston@users.noreply.github.com> --- src/server/game/Entities/Player/Player.cpp | 10 ++- src/server/game/Groups/Group.h | 1 + src/server/game/Handlers/GroupHandler.cpp | 88 +++++++++++----------- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 293f47898..5a2860613 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2298,7 +2298,6 @@ 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() { Group* group = GetGroupInvite(); @@ -2307,14 +2306,17 @@ void Player::UninviteFromGroup() group->RemoveInvite(this); - if (group->GetMembersCount() <= 1) // group has just 1 member => disband + if (group->IsCreated()) { - if (group->IsCreated()) + if (group->GetMembersCount() <= 1) // group has just 1 member => disband { group->Disband(true); group = nullptr; // gets deleted in disband } - else + } + else + { + if (group->GetInviteeCount() <= 1) { group->RemoveAllInvites(); delete group; diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index b508d1edc..1659711b1 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -243,6 +243,7 @@ public: GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); } GroupReference const* GetFirstMember() const { return m_memberMgr.getFirst(); } uint32 GetMembersCount() const { return m_memberSlots.size(); } + uint32 GetInviteeCount() const { return m_invitees.size(); } uint8 GetMemberGroup(ObjectGuid guid) const; diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 2e4f9f063..9609d8b64 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -73,81 +73,73 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) return; } - Player* player = ObjectAccessor::FindPlayerByName(membername, false); + Player* invitingPlayer = GetPlayer(); + Player* invitedPlayer = ObjectAccessor::FindPlayerByName(membername, false); // no player or cheat self-invite - if (!player || player == GetPlayer()) + if (!invitedPlayer || invitedPlayer == invitingPlayer) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } - if (!sScriptMgr->CanGroupInvite(GetPlayer(), membername)) + if (!sScriptMgr->CanGroupInvite(invitingPlayer, membername)) return; - if (GetPlayer()->IsSpectator() || player->IsSpectator()) + if (invitingPlayer->IsSpectator() || invitedPlayer->IsSpectator()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_INVITE_RESTRICTED); return; } // restrict invite to GMs - if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster()) + if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !invitingPlayer->IsGameMaster() && invitedPlayer->IsGameMaster()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S); return; } // can't group with - if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeamId() != player->GetTeamId()) + if (!invitingPlayer->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && invitingPlayer->GetTeamId() != invitedPlayer->GetTeamId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION); return; } - if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) + if (invitingPlayer->GetInstanceId() != 0 && invitedPlayer->GetInstanceId() != 0 && invitingPlayer->GetInstanceId() != invitedPlayer->GetInstanceId() && invitingPlayer->GetMapId() == invitedPlayer->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us - if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty()) + if (invitedPlayer->GetInstanceId() != 0 && invitedPlayer->GetDungeonDifficulty() != invitingPlayer->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } - if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID())) + if (invitedPlayer->GetSocial()->HasIgnore(invitingPlayer->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; } - if (!player->GetSocial()->HasFriend(GetPlayer()->GetGUID()) && GetPlayer()->GetLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ)) + if (!invitedPlayer->GetSocial()->HasFriend(invitingPlayer->GetGUID()) && invitingPlayer->GetLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ)) { - SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_INVITE_RESTRICTED); + SendPartyResult(PARTY_OP_INVITE, invitedPlayer->GetName(), ERR_INVITE_RESTRICTED); return; } - Group* group = GetPlayer()->GetGroup(); - if (group) - { - if (group->isLFGGroup() && group->IsLfgRandomInstance()) - { - SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S); - return; - } + Group* group = invitingPlayer->GetGroup(); + if (group && group->isBGGroup()) + group = invitingPlayer->GetOriginalGroup(); + if (!group) + group = invitingPlayer->GetGroupInvite(); - if (group->isBGGroup() || group->isBFGroup()) - { - group = GetPlayer()->GetOriginalGroup(); - } - } - - Group* group2 = player->GetGroup(); - if (group2 && (group2->isBGGroup() || group2->isBFGroup())) - group2 = player->GetOriginalGroup(); + Group* group2 = invitedPlayer->GetGroup(); + if (group2 && group2->isBGGroup()) + group2 = invitedPlayer->GetOriginalGroup(); // player already in another group or invited - if (group2 || player->GetGroupInvite()) + if (group2 || invitedPlayer->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S); @@ -156,11 +148,11 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) // tell the player that they were invited but it failed as they were already in a group WorldPacket data(SMSG_GROUP_INVITE, 25); // guess size data << uint8(0); // invited/already in group flag - data << GetPlayer()->GetName(); // max len 48 + data << invitingPlayer->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk - player->GetSession()->SendPacket(&data); + invitedPlayer->GetSession()->SendPacket(&data); } return; @@ -169,7 +161,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) if (group) { // not have permissions for invite - if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + if (!group->IsLeader(invitingPlayer->GetGUID()) && !group->IsAssistant(invitingPlayer->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; @@ -183,22 +175,22 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) } // xinef: if player has no group, check group invite - if (!group && GetPlayer()->GetGroupInvite() && GetPlayer()->GetGroupInvite()->GetLeaderGUID() == GetPlayer()->GetGUID()) - group = GetPlayer()->GetGroupInvite(); + if (!group && invitingPlayer->GetGroupInvite() && invitingPlayer->GetGroupInvite()->GetLeaderGUID() == invitingPlayer->GetGUID()) + group = invitingPlayer->GetGroupInvite(); // ok, but group not exist, start a new group // but don't create and save the group to the DB until // at least one person joins if (!group) { - group = new Group; + group = new Group(); // new group: if can't add then delete - if (!group->AddLeaderInvite(GetPlayer())) + if (!group->AddLeaderInvite(invitingPlayer)) { delete group; return; } - if (!group->AddInvite(player)) + if (!group->AddInvite(invitedPlayer)) { delete group; return; @@ -207,7 +199,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) else { // already existed group: if can't add then just leave - if (!group->AddInvite(player)) + if (!group->AddInvite(invitedPlayer)) { return; } @@ -216,11 +208,11 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << uint8(1); // invited/already in group flag - data << GetPlayer()->GetName(); // max len 48 + data << invitingPlayer->GetName(); // max len 48 data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk - player->GetSession()->SendPacket(&data); + invitedPlayer->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); } @@ -446,7 +438,8 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) { Group* grp = GetPlayer()->GetGroup(); - if (!grp) + Group* grpInvite = GetPlayer()->GetGroupInvite(); + if (!grp && !grpInvite) return; if (_player->InBattleground()) @@ -459,9 +452,16 @@ void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) /********************/ // everything's fine, do it - SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), ERR_PARTY_RESULT_OK); - - GetPlayer()->RemoveFromGroup(GROUP_REMOVEMETHOD_LEAVE); + if (grp) + { + SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), ERR_PARTY_RESULT_OK); + GetPlayer()->RemoveFromGroup(GROUP_REMOVEMETHOD_LEAVE); + } + else if (grpInvite && grpInvite->GetLeaderGUID() == GetPlayer()->GetGUID()) + { // pending group creation being cancelled + SendPartyResult(PARTY_OP_LEAVE, GetPlayer()->GetName(), ERR_PARTY_RESULT_OK); + grpInvite->Disband(); + } } void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData)