diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 45dfd30bd..2a356f644 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -1134,3 +1134,85 @@ void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData) GetPlayer()->SetPassOnGroupLoot(passOnLoot); } + +void WorldSession::HandleGroupSwapSubGroupOpcode(WorldPacket& recv_data) +{ + std::string playerName1, playerName2; + + // first = moved from, second = moved to + recv_data >> playerName1; + recv_data >> playerName2; + + if (!normalizePlayerName(playerName1)) + { + SendPartyResult(PARTY_OP_SWAP, playerName1, ERR_GROUP_SWAP_FAILED); + return; + } + if (!normalizePlayerName(playerName2)) + { + SendPartyResult(PARTY_OP_SWAP, playerName1, ERR_GROUP_SWAP_FAILED); + return; + } + + Group* group = GetPlayer()->GetGroup(); + if (!group || !group->isRaidGroup()) + { + return; + } + + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + { + return; + } + + //get guid, member may be offline + auto getGuid = [&group](std::string const& playerName) + { + // no player, cheating? + if (!group->GetMemberGUID(playerName)) + { + return uint64(0); + } + + if (Player* player = ObjectAccessor::FindPlayerByName(playerName.c_str())) + { + return player->GetGUID(); + } + else + { + if (uint64 guid = sObjectMgr->GetPlayerGUIDByName(playerName)) + { + return guid; + } + else + { + return uint64(0); // no player - again, cheating? + } + } + }; + + uint64 guid1 = getGuid(playerName1); + uint64 guid2 = getGuid(playerName2); + + if(!guid1 || !guid2) + { + SendPartyResult(PARTY_OP_SWAP, playerName1, ERR_GROUP_SWAP_FAILED); + return; + } + + uint8 groupId1 = group->GetMemberGroup(guid1); + uint8 groupId2 = group->GetMemberGroup(guid2); + + if (groupId1 == MAX_RAID_SUBGROUPS + 1 || groupId2 == MAX_RAID_SUBGROUPS + 1) + { + return; + } + + if (groupId1 == groupId2) + { + return; + } + + group->ChangeMembersGroup(guid1, groupId2); + group->ChangeMembersGroup(guid2, groupId1); +} diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 632b24e99..3a1a250f9 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -654,7 +654,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupChangeSubGroupOpcode }, /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode }, - /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSwapSubGroupOpcode }, /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleAutoStoreBankItemOpcode }, /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleAutoBankItemOpcode }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 64543337c..7d3cf766c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -524,6 +524,7 @@ public: // opcodes handlers void HandleLootMethodOpcode(WorldPacket& recvPacket); void HandleLootRoll(WorldPacket& recvData); void HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData); + void HandleGroupSwapSubGroupOpcode(WorldPacket& recvData); void HandleRaidTargetUpdateOpcode(WorldPacket& recvData); void HandleRaidReadyCheckOpcode(WorldPacket& recvData); void HandleRaidReadyCheckFinishedOpcode(WorldPacket& recvData);