/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "WorldSession.h" #include "CharacterCache.h" #include "Common.h" #include "DatabaseEnv.h" #include "Group.h" #include "GroupMgr.h" #include "Log.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "PartyPackets.h" #include "Pet.h" #include "PhasingHandler.h" #include "Player.h" #include "SocialMgr.h" #include "SpellAuraEffects.h" #include "SpellAuras.h" #include "Util.h" #include "Vehicle.h" #include "World.h" #include "WorldPacket.h" class Aura; /* differeces from off: -you can uninvite yourself - is is useful -you can accept invitation even if leader went offline */ /* todo: -group_destroyed msg is sent but not shown -reduce xp gaining when in raid group -quest sharing has to be corrected -FIX sending PartyMemberStats */ void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val /* = 0 */) { WorldPackets::Party::PartyCommandResult packet; packet.Name = member; packet.Command = uint8(operation); packet.Result = uint8(res); packet.ResultData = val; packet.ResultGUID = ObjectGuid::Empty; SendPacket(packet.Write()); } void WorldSession::HandlePartyInviteOpcode(WorldPackets::Party::PartyInviteClient& packet) { // cheating if (!normalizePlayerName(packet.TargetName)) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_BAD_PLAYER_NAME_S); return; } Player* invitingPlayer = GetPlayer(); Player* invitedPlayer = ObjectAccessor::FindPlayerByName(packet.TargetName); // no player if (!invitedPlayer) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_BAD_PLAYER_NAME_S); return; } // player trying to invite himself (most likely cheating) if (invitedPlayer == invitingPlayer) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !invitingPlayer->IsGameMaster() && invitedPlayer->IsGameMaster()) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!invitingPlayer->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && invitingPlayer->GetTeam() != invitedPlayer->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_PLAYER_WRONG_FACTION); return; } if (invitingPlayer->GetInstanceId() != 0 && invitedPlayer->GetInstanceId() != 0 && invitingPlayer->GetInstanceId() != invitedPlayer->GetInstanceId() && invitingPlayer->GetMapId() == invitedPlayer->GetMapId()) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (invitedPlayer->GetInstanceId() != 0 && invitedPlayer->GetDungeonDifficulty() != invitingPlayer->GetDungeonDifficulty()) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_IGNORING_YOU_S); return; } if (invitedPlayer->GetSocial()->HasIgnore(invitingPlayer->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_IGNORING_YOU_S); return; } if (!invitedPlayer->GetSocial()->HasFriend(invitingPlayer->GetGUID()) && invitingPlayer->getLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ)) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_INVITE_RESTRICTED); return; } Group* group = invitingPlayer->GetGroup(); if (group && group->isBGGroup()) group = invitingPlayer->GetOriginalGroup(); if (!group) group = invitingPlayer->GetGroupInvite(); Group* group2 = invitedPlayer->GetGroup(); if (group2 && group2->isBGGroup()) group2 = invitedPlayer->GetOriginalGroup(); // player already in another group or invited if (group2 || invitedPlayer->GetGroupInvite()) { SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group WorldPackets::Party::PartyInvite partyInvite; partyInvite.Initialize(invitingPlayer, packet.ProposedRoles, false); invitedPlayer->SendDirectMessage(partyInvite.Write()); } return; } if (group) { // not have permissions for invite if (!group->IsLeader(invitingPlayer->GetGUID()) && !group->IsAssistant(invitingPlayer->GetGUID())) { if (group->IsCreated()) SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; } // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } } // 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(); // new group: if can't add then delete if (!group->AddLeaderInvite(invitingPlayer)) { delete group; return; } if (!group->AddInvite(invitedPlayer)) { group->RemoveAllInvites(); delete group; return; } } else { // already existed group: if can't add then just leave if (!group->AddInvite(invitedPlayer)) { return; } } WorldPackets::Party::PartyInvite partyInvite; partyInvite.Initialize(invitingPlayer, packet.ProposedRoles, true); invitedPlayer->SendDirectMessage(partyInvite.Write()); SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_PARTY_RESULT_OK); } void WorldSession::HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet) { Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; if (packet.Accept) { // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } // Group is full if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); // Forming a new group, create it if (!group->IsCreated()) { // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented if (!leader) { group->RemoveAllInvites(); return; } // If we're about to create a group there really should be a leader present ASSERT(leader); group->RemoveInvite(leader); group->Create(leader); sGroupMgr->AddGroup(group); } // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer())) return; group->BroadcastGroupUpdate(); } else { // Remember leader if online (group pointer will be invalid if group gets disbanded) Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID()); // uninvite, group can be deleted GetPlayer()->UninviteFromGroup(); if (!leader || !leader->GetSession()) return; // report WorldPackets::Party::GroupDecline decline(GetPlayer()->GetName()); leader->SendDirectMessage(decline.Write()); } } void WorldSession::HandleGroupClearMarker(WorldPacket& recv_data) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_CLEAR_RAID_MARKER"); uint8 marker; recv_data >> marker; if (Group* group = GetPlayer()->GetGroup()) { group->RemoveGroupMarkerMask(1 << marker); group->SendRaidMarkerUpdate(); group->RemoveMarker(); } } void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_UNINVITE_GUID"); ObjectGuid guid; std::string reason; recvData >> guid; recvData >> reason; //can't uninvite yourself if (guid == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } PartyResult res = GetPlayer()->CanUninviteFromGroup(guid); if (res != ERR_PARTY_RESULT_OK) { SendPartyResult(PARTY_OP_UNINVITE, "", res); return; } Group* grp = GetPlayer()->GetGroup(); // grp is checked already above in CanUninviteFromGroup() ASSERT(grp); if (grp->IsMember(guid)) { Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str()); return; } if (Player* player = grp->GetInvited(guid)) { player->UninviteFromGroup(); return; } SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S); } void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_UNINVITE"); std::string membername; recvData >> membername; // player not found if (!normalizePlayerName(membername)) return; // can't uninvite yourself if (GetPlayer()->GetName() == membername) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteOpcode: leader %s(%d) tried to uninvite himself from the group.", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } PartyResult res = GetPlayer()->CanUninviteFromGroup(); if (res != ERR_PARTY_RESULT_OK) { SendPartyResult(PARTY_OP_UNINVITE, "", res); return; } Group* grp = GetPlayer()->GetGroup(); if (!grp) return; if (ObjectGuid guid = grp->GetMemberGUID(membername)) { Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID()); return; } if (Player* player = grp->GetInvited(membername)) { player->UninviteFromGroup(); return; } SendPartyResult(PARTY_OP_UNINVITE, membername, ERR_TARGET_NOT_IN_GROUP_S); } void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SET_LEADER"); ObjectGuid guid; recvData >> guid; Player* player = ObjectAccessor::FindConnectedPlayer(guid); Group* group = GetPlayer()->GetGroup(); if (!group || !player) return; if (!group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group) return; // Everything's fine, accepted. group->ChangeLeader(guid); group->SendUpdate(); } void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SET_ROLES"); uint32 newRole; ObjectGuid guid1; // Assigner GUID ObjectGuid guid2; // Target GUID guid1 = GetPlayer()->GetGUID(); recvData >> newRole; guid2[2] = recvData.ReadBit(); guid2[6] = recvData.ReadBit(); guid2[3] = recvData.ReadBit(); guid2[7] = recvData.ReadBit(); guid2[5] = recvData.ReadBit(); guid2[1] = recvData.ReadBit(); guid2[0] = recvData.ReadBit(); guid2[4] = recvData.ReadBit(); recvData.ReadByteSeq(guid2[6]); recvData.ReadByteSeq(guid2[4]); recvData.ReadByteSeq(guid2[1]); recvData.ReadByteSeq(guid2[3]); recvData.ReadByteSeq(guid2[0]); recvData.ReadByteSeq(guid2[5]); recvData.ReadByteSeq(guid2[2]); recvData.ReadByteSeq(guid2[7]); WorldPacket data(SMSG_GROUP_SET_ROLE, 24); data.WriteBit(guid1[1]); data.WriteBit(guid2[0]); data.WriteBit(guid2[2]); data.WriteBit(guid2[4]); data.WriteBit(guid2[7]); data.WriteBit(guid2[3]); data.WriteBit(guid1[7]); data.WriteBit(guid2[5]); data.WriteBit(guid1[5]); data.WriteBit(guid1[4]); data.WriteBit(guid1[3]); data.WriteBit(guid2[6]); data.WriteBit(guid1[2]); data.WriteBit(guid1[6]); data.WriteBit(guid2[1]); data.WriteBit(guid1[0]); data.WriteByteSeq(guid1[7]); data.WriteByteSeq(guid2[3]); data.WriteByteSeq(guid1[6]); data.WriteByteSeq(guid2[4]); data.WriteByteSeq(guid2[0]); data << uint32(newRole); // New Role data.WriteByteSeq(guid2[6]); data.WriteByteSeq(guid2[2]); data.WriteByteSeq(guid1[0]); data.WriteByteSeq(guid1[4]); data.WriteByteSeq(guid2[1]); data.WriteByteSeq(guid1[3]); data.WriteByteSeq(guid1[5]); data.WriteByteSeq(guid1[2]); data.WriteByteSeq(guid2[5]); data.WriteByteSeq(guid2[7]); data.WriteByteSeq(guid1[1]); data << uint32(0); // Old Role if (Group* group = GetPlayer()->GetGroup()) { /// @todo probably should be sent only if (oldRole != newRole) group->BroadcastPacket(&data, false); group->SetLfgRoles(guid2, newRole); } else SendPacket(&data); } void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_DISBAND"); Group* grp = GetPlayer()->GetGroup(); Group* grpInvite = GetPlayer()->GetGroupInvite(); if (!grp && !grpInvite) return; if (_player->InBattleground()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_INVITE_RESTRICTED); return; } /** error handling **/ /********************/ // everything's fine, do it 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) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_LOOT_METHOD"); uint32 lootMethod; ObjectGuid lootMaster; uint32 lootThreshold; recvData >> lootMethod >> lootMaster >> lootThreshold; Group* group = GetPlayer()->GetGroup(); if (!group) return; /** error handling **/ if (!group->IsLeader(GetPlayer()->GetGUID())) return; if (group->isLFGGroup()) return; if (lootMethod > NEED_BEFORE_GREED) return; if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT) return; if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster)) return; /********************/ // everything's fine, do it group->SetLootMethod((LootMethod)lootMethod); group->SetMasterLooterGuid(lootMaster); group->SetLootThreshold((ItemQualities)lootThreshold); group->SendUpdate(); } void WorldSession::HandleLootRoll(WorldPacket& recvData) { ObjectGuid guid; uint32 itemSlot; uint8 rollType; recvData >> guid; // guid of the item rolled recvData >> itemSlot; recvData >> rollType; // 0: pass, 1: need, 2: greed Group* group = GetPlayer()->GetGroup(); if (!group) return; group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType); switch (rollType) { case ROLL_NEED: GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED, 1); break; case ROLL_GREED: GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED, 1); break; } } void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received MSG_MINIMAP_PING"); if (!GetPlayer()->GetGroup()) return; float x, y; recvData >> x; recvData >> y; //TC_LOG_DEBUG("misc", "Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y); /** error handling **/ /********************/ // everything's fine, do it WorldPacket data(MSG_MINIMAP_PING, (8+4+4)); data << uint64(GetPlayer()->GetGUID()); data << float(x); data << float(y); GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); } void WorldSession::HandleRandomRollOpcode(WorldPacket& recvData) { uint32 minimum, maximum; recvData >> minimum; recvData >> maximum; /** error handling **/ if (minimum > maximum || maximum > 10000) // < 32768 for urand call return; /********************/ // everything's fine, do it GetPlayer()->DoRandomRoll(minimum, maximum); } void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received MSG_RAID_TARGET_UPDATE"); Group* group = GetPlayer()->GetGroup(); if (!group) return; uint8 x; recvData >> x; /** error handling **/ /********************/ // everything's fine, do it if (x == 0xFF) // target icon request group->SendTargetIconList(this); else // target icon update { if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) return; ObjectGuid guid; recvData >> guid; if (guid.IsPlayer()) { Player* target = ObjectAccessor::FindConnectedPlayer(guid); if (!target || target->IsHostileTo(GetPlayer())) return; } group->SetTargetIcon(x, _player->GetGUID(), guid); } } void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_RAID_CONVERT"); Group* group = GetPlayer()->GetGroup(); if (!group) return; if (_player->InBattleground() || group->isLFGGroup()) return; // error handling if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2) return; // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code) SendPartyResult(PARTY_OP_INVITE, "", ERR_PARTY_RESULT_OK); // New 4.x: it is now possible to convert a raid to a group if member count is 5 or less bool toRaid; recvData >> toRaid; if (toRaid) group->ConvertToRaid(); else group->ConvertToGroup(); } void WorldSession::HandleGroupRequestJoinUpdates(WorldPacket& /*recvData*/) { Group* group = GetPlayer()->GetGroup(); if (!group) return; WorldPacket data(SMSG_REAL_GROUP_UPDATE, 1 + 4 + 8); data << uint8(group->GetGroupFlags()); data << uint32(group->GetMembersCount() - 1); data << uint64(group->GetLeaderGUID()); SendPacket(&data); } void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_CHANGE_SUB_GROUP"); // we will get correct pointer for group here, so we don't have to check if group is BG raid Group* group = GetPlayer()->GetGroup(); if (!group) return; std::string name; uint8 groupNr; recvData >> name; recvData >> groupNr; if (!normalizePlayerName(name)) return; if (groupNr >= MAX_RAID_SUBGROUPS) return; ObjectGuid senderGuid = GetPlayer()->GetGUID(); if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) return; if (!group->HasFreeSlotSubGroup(groupNr)) return; ObjectGuid guid; if (Player* movedPlayer = ObjectAccessor::FindConnectedPlayerByName(name)) guid = movedPlayer->GetGUID(); else guid = sCharacterCache->GetCharacterGuidByName(name); if (guid.IsEmpty()) return; group->ChangeMembersGroup(guid, groupNr); } void WorldSession::HandleGroupSwapSubGroupOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SWAP_SUB_GROUP"); std::string name1; std::string name2; recvData >> name1; recvData >> name2; } void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_ASSISTANT_LEADER"); Group* group = GetPlayer()->GetGroup(); if (!group) return; if (!group->IsLeader(GetPlayer()->GetGUID())) return; ObjectGuid guid; bool apply; recvData >> guid; recvData >> apply; group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT); } void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received MSG_PARTY_ASSIGNMENT"); Group* group = GetPlayer()->GetGroup(); if (!group) return; ObjectGuid senderGuid = GetPlayer()->GetGUID(); if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) return; uint8 assignment; bool apply; ObjectGuid guid; recvData >> assignment >> apply; recvData >> guid; switch (assignment) { case GROUP_ASSIGN_MAINASSIST: group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINASSIST); group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST); break; case GROUP_ASSIGN_MAINTANK: group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any. group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK); break; default: break; } group->SendUpdate(); } void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received MSG_RAID_READY_CHECK"); Group* group = GetPlayer()->GetGroup(); if (!group) return; if (recvData.empty()) // request { /** error handling **/ if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) return; /********************/ // everything's fine, do it WorldPacket data(MSG_RAID_READY_CHECK, 8); data << GetPlayer()->GetGUID(); group->BroadcastPacket(&data, false, -1); group->OfflineReadyCheck(); } else // answer { uint8 state; recvData >> state; // everything's fine, do it WorldPacket data(MSG_RAID_READY_CHECK_CONFIRM, 9); data << uint64(GetPlayer()->GetGUID()); data << uint8(state); group->BroadcastReadyCheck(&data); } } void WorldSession::HandleRaidReadyCheckFinishedOpcode(WorldPacket& /*recvData*/) { //Group* group = GetPlayer()->GetGroup(); //if (!group) // return; //if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) // return; // Is any reaction need? } /*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid Guid; recvData >> Guid; Player* player = ObjectAccessor::FindConnectedPlayer(Guid); if (!player) { WorldPackets::Party::PartyMemberState packet(true); packet.MemberGuid = Guid; packet.ChangeMask = GROUP_UPDATE_FLAG_STATUS; packet.MemberStats.Status = MEMBER_STATUS_OFFLINE; SendPacket(packet.Write()); return; } WorldPackets::Party::PartyMemberState packet(true); packet.Initialize(player); SendPacket(packet.Write()); } void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket& /*recvData*/) { // every time the player checks the character screen _player->SendRaidInfo(); } void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_OPT_OUT_OF_LOOT"); bool passOnLoot; recvData >> passOnLoot; // 1 always pass, 0 do not pass // ignore if player not loaded if (!GetPlayer()) // needed because STATUS_AUTHED { if (passOnLoot) TC_LOG_ERROR("network", "CMSG_OPT_OUT_OF_LOOT value<>0 for not-loaded character!"); return; } GetPlayer()->SetPassOnGroupLoot(passOnLoot != 0); } void WorldSession::HandleRolePollBeginOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_ROLE_POLL_BEGIN"); Group* group = GetPlayer()->GetGroup(); if (!group) return; if (recvData.empty()) { if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) return; ObjectGuid guid = GetPlayer()->GetGUID(); WorldPacket data(SMSG_ROLE_POLL_BEGIN, 8); data.WriteBit(guid[1]); data.WriteBit(guid[5]); data.WriteBit(guid[7]); data.WriteBit(guid[3]); data.WriteBit(guid[2]); data.WriteBit(guid[4]); data.WriteBit(guid[0]); data.WriteBit(guid[6]); data.WriteByteSeq(guid[4]); data.WriteByteSeq(guid[7]); data.WriteByteSeq(guid[0]); data.WriteByteSeq(guid[5]); data.WriteByteSeq(guid[1]); data.WriteByteSeq(guid[6]); data.WriteByteSeq(guid[2]); data.WriteByteSeq(guid[3]); GetPlayer()->GetGroup()->BroadcastPacket(&data, true); } } void WorldSession::HandleSetEveryoneIsAssistant(WorldPackets::Party::SetEveryoneIsAssistant& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) return; if (!group->IsLeader(GetPlayer()->GetGUID())) return; group->SetEveryoneIsAssistant(packet.EveryoneIsAssistant); }