From c6ab951025b0be3b0f64dc8bb0703d4aa8bdb003 Mon Sep 17 00:00:00 2001 From: et65 Date: Tue, 19 May 2015 02:55:53 +0100 Subject: Core/PacketsIO: Implemented or updated most of party related packets. Packets updated or implemented : - SMSG_INSTANCE_INFO : updated - CMSG_SAVE_CUF_PROFILES : updated - SMSG_LOAD_CUF_PROFILES : updated - SMSG_PARTY_COMMAND_RESULT : updated - CMSG_PARTY_INVITE : updated - SMSG_PARTY_INVITE : updated - CMSG_PARTY_INVITE_RESPONSE : updated - CMSG_PARTY_UNINVITE : updated - SMSG_GROUP_UNINVITE : updated - CMSG_LEAVE_GROUP : updated - SMSG_GROUP_DECLINE : updated - SMSG_GROUP_DESTROYED : updated - CMSG_MINIMAP_PING : updated - SMSG_MINIMAP_PING : updated - CMSG_CONVERT_RAID : updated - CMSG_SET_EVERYONE_IS_ASSISTANT - CMSG_DO_READY_CHECK : updated - CMSG_READY_CHECK_RESPONSE : updated - SMSG_READY_CHECK_COMPLETED : updated - SMSG_READY_CHECK_RESPONSE : updated - SMSG_READY_CHECK_STARTED : updated - CMSG_REQUEST_PARTY_JOIN_UPDATES : implemented (source : sniffs) - CMSG_REQUEST_PARTY_MEMBER_STATE : updated - SMSG_PARTY_MEMBER_STATE : updated - SMSG_PARTY_UPDATE : updated - CMSG_REQUEST_RAID_INFO : updated - CMSG_INITIATE_ROLE_POLL : updated - SMSG_ROLE_POLL_INFORM : updated - CMSG_SET_ROLE : updated - SMSG_ROLE_CHANGED_INFORM : updated - CMSG_CHANGE_SUB_GROUP : updated - CMSG_SWAP_SUB_GROUPS : implemented - CMSG_SET_ASSISTANT_LEADER : updated - CMSG_SET_PARTY_LEADER : updated - SMSG_GROUP_NEW_LEADER : updated - CMSG_CLEAR_RAID_MARKER : implemented - SMSG_RAID_MARKERS_CHANGED : implemented - CMSG_UPDATE_RAID_TARGET : updated - SMSG_SEND_RAID_TARGET_UPDATE_ALL : updated - SMSG_SEND_RAID_TARGET_UPDATE_SINGLE : updated - CMSG_OPT_OUT_OF_LOOT : updated - CMSG_SET_LOOT_METHOD : updated About group update flags: - Not sure they are use for now. - Pets now have their group update flags. - Pets'power is no send to client anymore. - Changes about them are inspired from SMSG_PARTY_MEMBER_STATS parsing of WowPacketParser, but it seems this packet is not use anymore. CHAT_MSG_RAID has been fixed. About Ready check: - Correctly implemented this function. - An update function has been added to Group class, and to GroupMgr class in order to manage the ready check expiration (when 35 seconds were gone, players who have not answered must be reported as AFK) About Raid markers: - Old spell effect SPELL_EFFECT_SUMMON_OBJECT_SLOT3 has been renamed to SPELL_EFFECT_CHANGE_RAID_MARKER and implemented. I'm sure about that because raid markers spells are the only spells that have this effect type. Source: WowPacketParser, and sniffs from official. --- src/server/game/Battlegrounds/Battleground.cpp | 4 +- src/server/game/Chat/Channels/Channel.cpp | 4 +- src/server/game/Chat/Chat.cpp | 6 +- src/server/game/DungeonFinding/LFGMgr.cpp | 2 +- src/server/game/DungeonFinding/LFGQueue.cpp | 12 +- src/server/game/Entities/Pet/Pet.cpp | 22 +- src/server/game/Entities/Pet/Pet.h | 8 +- src/server/game/Entities/Player/Player.cpp | 107 ++- src/server/game/Entities/Player/Player.h | 75 +- src/server/game/Entities/Unit/Unit.cpp | 58 +- src/server/game/Globals/ObjectMgr.cpp | 19 + src/server/game/Globals/ObjectMgr.h | 3 +- src/server/game/Groups/Group.cpp | 451 +++++++--- src/server/game/Groups/Group.h | 153 +++- src/server/game/Groups/GroupMgr.cpp | 7 + src/server/game/Groups/GroupMgr.h | 2 + src/server/game/Guilds/Guild.cpp | 4 +- src/server/game/Handlers/ChatHandler.cpp | 16 +- src/server/game/Handlers/GroupHandler.cpp | 983 ++++----------------- src/server/game/Handlers/LFGHandler.cpp | 2 +- src/server/game/Handlers/MiscHandler.cpp | 121 +-- src/server/game/Handlers/PetHandler.cpp | 3 +- src/server/game/Handlers/SpellHandler.cpp | 4 +- src/server/game/Maps/Map.h | 2 +- src/server/game/Miscellaneous/SharedDefines.h | 2 +- src/server/game/Server/Packets/ChatPackets.cpp | 2 +- src/server/game/Server/Packets/ChatPackets.h | 2 +- src/server/game/Server/Packets/InstancePackets.cpp | 26 + src/server/game/Server/Packets/InstancePackets.h | 24 + src/server/game/Server/Packets/MiscPackets.cpp | 69 ++ src/server/game/Server/Packets/MiscPackets.h | 21 + src/server/game/Server/Packets/PartyPackets.cpp | 716 +++++++++++++++ src/server/game/Server/Packets/PartyPackets.h | 616 +++++++++++++ src/server/game/Server/Protocol/Opcodes.cpp | 85 +- src/server/game/Server/WorldSession.h | 96 +- src/server/game/Spells/Spell.h | 1 + src/server/game/Spells/SpellEffects.cpp | 21 +- src/server/game/Spells/SpellInfo.cpp | 2 +- src/server/game/Texts/ChatTextBuilder.h | 4 +- src/server/game/Texts/CreatureTextMgr.cpp | 4 +- src/server/game/World/World.cpp | 9 +- src/server/scripts/Commands/cs_debug.cpp | 2 +- src/server/shared/Common.h | 11 + src/server/shared/Logging/Log.h | 5 +- 44 files changed, 2425 insertions(+), 1361 deletions(-) create mode 100644 src/server/game/Server/Packets/PartyPackets.cpp create mode 100644 src/server/game/Server/Packets/PartyPackets.h (limited to 'src') diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index c6c46c48f50..f37526ae71b 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -71,7 +71,7 @@ namespace Trinity void do_helper(WorldPacket& data, char const* text) { WorldPackets::Chat::Chat packet; - packet.Initalize(_msgtype, LANG_UNIVERSAL, _source, _source, text); + packet.Initialize(_msgtype, LANG_UNIVERSAL, _source, _source, text); packet.Write(); data = packet.Move(); } @@ -98,7 +98,7 @@ namespace Trinity snprintf(str, 2048, text, arg1str, arg2str); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgtype, LANG_UNIVERSAL, _source, _source, str); + packet.Initialize(_msgtype, LANG_UNIVERSAL, _source, _source, str); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 2ac84063664..90c44aa501b 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -626,10 +626,10 @@ void Channel::Say(ObjectGuid const& guid, std::string const& what, uint32 lang) WorldPackets::Chat::Chat packet; if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) - packet.Initalize(CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); + packet.Initialize(CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name); else { - packet.Initalize(CHAT_MSG_CHANNEL, Language(lang), nullptr, nullptr, what, 0, _name); + packet.Initialize(CHAT_MSG_CHANNEL, Language(lang), nullptr, nullptr, what, 0, _name); packet.SenderGUID = guid; packet.TargetGUID = guid; } diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index c7952d7758c..ed6aa52da5a 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -201,7 +201,7 @@ void ChatHandler::SendSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); m_session->SendPacket(packet.Write()); } @@ -219,7 +219,7 @@ void ChatHandler::SendGlobalSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); sWorld->SendGlobalMessage(packet.Write()); } @@ -237,7 +237,7 @@ void ChatHandler::SendGlobalGMSysMessage(const char *str) while (char* line = LineFromMessage(pos)) { - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); sWorld->SendGlobalGMMessage(packet.Write()); } diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index b077f3e6110..e786c3b9c7c 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -412,7 +412,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const joinData.result = LFG_JOIN_NOT_MEET_REQS; else if (grp) { - if (grp->GetMembersCount() > MAXGROUPSIZE) + if (grp->GetMembersCount() > MAX_GROUP_SIZE) joinData.result = LFG_JOIN_TOO_MUCH_MEMBERS; else { diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index 97f87a4d814..30e9a587353 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -323,7 +323,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) LfgRolesMap proposalRoles; // Check for correct size - if (check.size() > MAXGROUPSIZE || check.empty()) + if (check.size() > MAX_GROUP_SIZE || check.empty()) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s): Size wrong - Not compatibles", strGuids.c_str()); return LFG_INCOMPATIBLES_WRONG_GROUP_SIZE; @@ -349,7 +349,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) // Check if more than one LFG group and number of players joining uint8 numPlayers = 0; uint8 numLfgGroups = 0; - for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAXGROUPSIZE; ++it) + for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAX_GROUP_SIZE; ++it) { ObjectGuid guid = *it; LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid); @@ -374,8 +374,8 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) } } - // Group with less that MAXGROUPSIZE members always compatible - if (check.size() == 1 && numPlayers != MAXGROUPSIZE) + // Group with less that MAX_GROUP_SIZE members always compatible + if (check.size() == 1 && numPlayers != MAX_GROUP_SIZE) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) single group. Compatibles", strGuids.c_str()); LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front()); @@ -396,7 +396,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) return LFG_INCOMPATIBLES_MULTIPLE_LFG_GROUPS; } - if (numPlayers > MAXGROUPSIZE) + if (numPlayers > MAX_GROUP_SIZE) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Too much players (%u)", strGuids.c_str(), numPlayers); SetCompatibles(strGuids, LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS); @@ -473,7 +473,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) } // Enough players? - if (numPlayers != MAXGROUPSIZE) + if (numPlayers != MAX_GROUP_SIZE) { TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Compatibles but not enough players(%u)", strGuids.c_str(), numPlayers); LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 05d649fe632..82b55e23349 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -39,7 +39,7 @@ Pet::Pet(Player* owner, PetType type) : Guardian(NULL, owner, true), m_usedTalentCount(0), m_removed(false), - m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false), + m_petType(type), m_duration(0), m_groupUpdateMask(0), m_loading(false), m_declinedname(NULL) { ASSERT(GetOwner()); @@ -337,8 +337,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c owner->PetSpellInitialize(); - if (owner->GetGroup()) - owner->SetGroupUpdateFlag(GROUP_UPDATE_PET); + SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL); // TODO: 6.x remove/update pet talents //owner->SendTalentsInfoData(true); @@ -1938,6 +1937,21 @@ void Pet::SetDisplayId(uint32 modelId) if (!isControlled()) return; + SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); +} + +void Pet::SetGroupUpdateFlag(uint32 flag) +{ + if (GetOwner()->GetGroup()) + { + m_groupUpdateMask |= flag; + GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); + } +} + +void Pet::ResetGroupUpdateFlag() +{ + m_groupUpdateMask = GROUP_UPDATE_FLAG_PET_NONE; if (GetOwner()->GetGroup()) - GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID); + GetOwner()->RemoveGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 494db54208d..70f14fbd7ca 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -134,9 +134,9 @@ class Pet : public Guardian uint32 m_usedTalentCount; - uint64 GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; } - void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); } - void ResetAuraUpdateMaskForRaid() { m_auraRaidUpdateMask = 0; } + uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } + void SetGroupUpdateFlag(uint32 flag); + void ResetGroupUpdateFlag(); DeclinedName const* GetDeclinedNames() const { return m_declinedname; } @@ -147,9 +147,9 @@ class Pet : public Guardian protected: PetType m_petType; int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) - uint64 m_auraRaidUpdateMask; bool m_loading; uint32 m_regenTimer; + uint32 m_groupUpdateMask; DeclinedName *m_declinedname; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a3a602d2f4a..419992f3408 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -100,6 +100,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "WorldStatePackets.h" +#include "InstancePackets.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -701,7 +702,6 @@ Player::Player(WorldSession* session): Unit(true) // group is initialized in the reference constructor SetGroupInvite(NULL); m_groupUpdateMask = 0; - m_auraRaidUpdateMask = 0; m_bPassOnGroupLoot = false; duel = NULL; @@ -887,7 +887,6 @@ Player::Player(WorldSession* session): Unit(true) _maxPersonalArenaRate = 0; memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*)); - memset(_CUFProfiles, 0, MAX_CUF_PROFILES * sizeof(CUFProfile*)); m_achievementMgr = new AchievementMgr(this); m_reputationMgr = new ReputationMgr(this); @@ -927,9 +926,6 @@ Player::~Player() for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) delete _voidStorageItems[i]; - for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) - delete _CUFProfiles[i]; - ClearResurrectRequestData(); sWorld->DecreasePlayerCount(); @@ -7387,7 +7383,11 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) // group update if (GetGroup()) + { SetGroupUpdateFlag(GROUP_UPDATE_FULL); + if (Pet* pet = GetPet()) + pet->SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL); + } m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -17350,7 +17350,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) _LoadCUFProfiles(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES)); - std::unique_ptr garrison(new Garrison(this)); + std::unique_ptr garrison = Trinity::make_unique(this); if (garrison->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON_BLUEPRINTS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON_BUILDINGS))) @@ -17369,19 +17369,19 @@ void Player::_LoadCUFProfiles(PreparedQueryResult result) // SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ? Field* fields = result->Fetch(); - uint8 id = fields[0].GetUInt8(); - std::string name = fields[1].GetString(); - uint16 frameHeight = fields[2].GetUInt16(); - uint16 frameWidth = fields[3].GetUInt16(); - uint8 sortBy = fields[4].GetUInt8(); - uint8 healthText = fields[5].GetUInt8(); - uint32 boolOptions = fields[6].GetUInt32(); - uint8 unk146 = fields[7].GetUInt8(); - uint8 unk147 = fields[8].GetUInt8(); - uint8 unk148 = fields[9].GetUInt8(); - uint16 unk150 = fields[10].GetUInt16(); - uint16 unk152 = fields[11].GetUInt16(); - uint16 unk154 = fields[12].GetUInt16(); + uint8 id = fields[0].GetUInt8(); + std::string name = fields[1].GetString(); + uint16 frameHeight = fields[2].GetUInt16(); + uint16 frameWidth = fields[3].GetUInt16(); + uint8 sortBy = fields[4].GetUInt8(); + uint8 healthText = fields[5].GetUInt8(); + uint32 boolOptions = fields[6].GetUInt32(); + uint8 topPoint = fields[7].GetUInt8(); + uint8 bottomPoint = fields[8].GetUInt8(); + uint8 leftPoint = fields[9].GetUInt8(); + uint16 topOffset = fields[10].GetUInt16(); + uint16 bottomOffset = fields[11].GetUInt16(); + uint16 leftOffset = fields[12].GetUInt16(); if (id > MAX_CUF_PROFILES) { @@ -17389,7 +17389,7 @@ void Player::_LoadCUFProfiles(PreparedQueryResult result) continue; } - _CUFProfiles[id] = new CUFProfile(name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154); + _CUFProfiles[id] = Trinity::make_unique(name, frameHeight, frameWidth, sortBy, healthText, boolOptions, topPoint, bottomPoint, leftPoint, topOffset, bottomOffset, leftOffset); } while (result->NextRow()); } @@ -18557,12 +18557,7 @@ void Player::SetPendingBind(uint32 instanceId, uint32 bindTimer) void Player::SendRaidInfo() { - uint32 counter = 0; - - WorldPacket data(SMSG_INSTANCE_INFO, 4); - - size_t p_counter = data.wpos(); - data << uint32(counter); // placeholder + WorldPackets::Instance::InstanceInfo instanceInfo; time_t now = time(NULL); @@ -18573,27 +18568,28 @@ void Player::SendRaidInfo() if (itr->second.perm) { InstanceSave* save = itr->second.save; - bool isHeroic = save->GetDifficultyID() == DIFFICULTY_10_HC || save->GetDifficultyID() == DIFFICULTY_25_HC; - uint32 completedEncounters = 0; + + WorldPackets::Instance::InstanceLockInfos lockInfos; + + lockInfos.InstanceID = save->GetInstanceId(); + lockInfos.MapID = save->GetMapId(); + lockInfos.DifficultyID = save->GetDifficultyID(); + lockInfos.TimeRemaining = save->GetResetTime() - now; + + lockInfos.CompletedMask = 0; if (Map* map = sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId())) if (InstanceScript* instanceScript = ((InstanceMap*)map)->GetInstanceScript()) - completedEncounters = instanceScript->GetCompletedEncounterMask(); + lockInfos.CompletedMask = instanceScript->GetCompletedEncounterMask(); + + lockInfos.Locked = lockInfos.TimeRemaining <= 0; + lockInfos.Extended = false; - data << uint32(save->GetMapId()); // map id - data << uint32(save->GetDifficultyID()); // difficulty - data << uint32(isHeroic); // heroic - data << uint64(save->GetInstanceId()); // instance id - data << uint8(1); // expired = 0 - data << uint8(0); // extended = 1 - data << uint32(save->GetResetTime() - now); // reset time - data << uint32(completedEncounters); // completed encounters mask - ++counter; + instanceInfo.LockList.push_back(lockInfos); } } } - data.put(p_counter, counter); - GetSession()->SendPacket(&data); + GetSession()->SendPacket(instanceInfo.Write()); } /// convert the player's binds to the group @@ -19418,13 +19414,13 @@ void Player::_SaveCUFProfiles(SQLTransaction& trans) stmt->setUInt16(4, _CUFProfiles[i]->FrameWidth); stmt->setUInt8(5, _CUFProfiles[i]->SortBy); stmt->setUInt8(6, _CUFProfiles[i]->HealthText); - stmt->setUInt32(7, _CUFProfiles[i]->BoolOptions.to_ulong()); // 27 of 32 fields used, fits in an int - stmt->setUInt8(8, _CUFProfiles[i]->Unk146); - stmt->setUInt8(9, _CUFProfiles[i]->Unk147); - stmt->setUInt8(10, _CUFProfiles[i]->Unk148); - stmt->setUInt16(11, _CUFProfiles[i]->Unk150); - stmt->setUInt16(12, _CUFProfiles[i]->Unk152); - stmt->setUInt16(13, _CUFProfiles[i]->Unk154); + stmt->setUInt32(7, _CUFProfiles[i]->BoolOptions.to_ulong()); // 25 of 32 fields used, fits in an int + stmt->setUInt8(8, _CUFProfiles[i]->TopPoint); + stmt->setUInt8(9, _CUFProfiles[i]->BottomPoint); + stmt->setUInt8(10, _CUFProfiles[i]->LeftPoint); + stmt->setUInt16(11, _CUFProfiles[i]->TopOffset); + stmt->setUInt16(12, _CUFProfiles[i]->BottomOffset); + stmt->setUInt16(13, _CUFProfiles[i]->LeftOffset); } trans->Append(stmt); @@ -20220,7 +20216,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) GetSession()->SendPacket(&data); if (GetGroup()) - SetGroupUpdateFlag(GROUP_UPDATE_PET); + SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); } } @@ -20259,7 +20255,7 @@ void Player::Say(std::string const& text, Language language, WorldObject const* sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SAY, language, this, this, _text); + packet.Initialize(CHAT_MSG_SAY, language, this, this, _text); SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } @@ -20269,7 +20265,7 @@ void Player::Yell(std::string const& text, Language language, WorldObject const* sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_YELL, language, this, this, _text); + packet.Initialize(CHAT_MSG_YELL, language, this, this, _text); SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true); } @@ -20279,7 +20275,7 @@ void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/ sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); + packet.Initialize(CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text); SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)); } @@ -20292,7 +20288,7 @@ void Player::WhisperAddon(std::string const& text, const std::string& prefix, Pl return; WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); + packet.Initialize(CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix); receiver->SendDirectMessage(packet.Write()); } @@ -20309,14 +20305,14 @@ void Player::Whisper(std::string const& text, Language language, Player* target, sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target); WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_WHISPER, Language(language), this, this, _text); + packet.Initialize(CHAT_MSG_WHISPER, Language(language), this, this, _text); target->SendDirectMessage(packet.Write()); // rest stuff shouldn't happen in case of addon message if (isAddonMessage) return; - packet.Initalize(CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); + packet.Initialize(CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); SendDirectMessage(packet.Write()); if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster()) @@ -22636,9 +22632,8 @@ void Player::SendUpdateToOutOfRangeGroupMembers() group->UpdatePlayerOutOfRange(this); m_groupUpdateMask = GROUP_UPDATE_FLAG_NONE; - m_auraRaidUpdateMask = 0; if (Pet* pet = GetPet()) - pet->ResetAuraUpdateMaskForRaid(); + pet->ResetGroupUpdateFlag(); } void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index df08a1b30d4..c7af9426623 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -207,8 +207,9 @@ enum CUFBoolOptions CUF_DISPLAY_POWER_BAR, CUF_DISPLAY_BORDER, CUF_USE_CLASS_COLORS, - CUF_DISPLAY_NON_BOSS_DEBUFFS, CUF_DISPLAY_HORIZONTAL_GROUPS, + CUF_DISPLAY_NON_BOSS_DEBUFFS, + CUF_DYNAMIC_POSITION, CUF_LOCKED, CUF_SHOWN, CUF_AUTO_ACTIVATE_2_PLAYERS, @@ -222,9 +223,6 @@ enum CUFBoolOptions CUF_AUTO_ACTIVATE_SPEC_2, CUF_AUTO_ACTIVATE_PVP, CUF_AUTO_ACTIVATE_PVE, - CUF_UNK_145, - CUF_UNK_156, - CUF_UNK_157, // The unks is _LOCKED and _SHOWN and _DYNAMIC, unknown order @@ -236,32 +234,32 @@ struct CUFProfile { CUFProfile() : ProfileName(), BoolOptions() // might want to change default value for options { - FrameHeight = 0; - FrameWidth = 0; - SortBy = 0; - HealthText = 0; - Unk146 = 0; - Unk147 = 0; - Unk148 = 0; - Unk150 = 0; - Unk152 = 0; - Unk154 = 0; + FrameHeight = 0; + FrameWidth = 0; + SortBy = 0; + HealthText = 0; + TopPoint = 0; + BottomPoint = 0; + LeftPoint = 0; + TopOffset = 0; + BottomOffset = 0; + LeftOffset = 0; } CUFProfile(const std::string& name, uint16 frameHeight, uint16 frameWidth, uint8 sortBy, uint8 healthText, uint32 boolOptions, - uint8 unk146, uint8 unk147, uint8 unk148, uint16 unk150, uint16 unk152, uint16 unk154) + uint8 topPoint, uint8 bottomPoint, uint8 leftPoint, uint16 topOffset, uint16 bottomOffset, uint16 leftOffset) : ProfileName(name), BoolOptions((int)boolOptions) { - FrameHeight = frameHeight; - FrameWidth = frameWidth; - SortBy = sortBy; - HealthText = healthText; - Unk146 = unk146; - Unk147 = unk147; - Unk148 = unk148; - Unk150 = unk150; - Unk152 = unk152; - Unk154 = unk154; + FrameHeight = frameHeight; + FrameWidth = frameWidth; + SortBy = sortBy; + HealthText = healthText; + TopPoint = topPoint; + BottomPoint = bottomPoint; + LeftPoint = leftPoint; + TopOffset = topOffset; + BottomOffset = bottomOffset; + LeftOffset = leftOffset; } std::string ProfileName; @@ -270,15 +268,15 @@ struct CUFProfile uint8 SortBy; uint8 HealthText; - // LeftAlign, TopAlight, BottomAllign (unk order) - uint8 Unk146; - uint8 Unk147; - uint8 Unk148; + // LeftAlign, TopAlight, BottomAlign + uint8 TopPoint; + uint8 BottomPoint; + uint8 LeftPoint; - // LeftOffset, TopOffset and BottomOffset (unk order) - uint16 Unk150; - uint16 Unk152; - uint16 Unk154; + // LeftOffset, TopOffset and BottomOffset + uint16 TopOffset; + uint16 BottomOffset; + uint16 LeftOffset; std::bitset BoolOptions; @@ -1737,8 +1735,9 @@ class Player : public Unit, public GridObject void AddTimedQuest(uint32 questId) { m_timedquests.insert(questId); } void RemoveTimedQuest(uint32 questId) { m_timedquests.erase(questId); } - void SaveCUFProfile(uint8 id, CUFProfile* profile) { delete _CUFProfiles[id]; _CUFProfiles[id] = profile; } ///> Replaces a CUF profile at position 0-4 - CUFProfile* GetCUFProfile(uint8 id) const { return _CUFProfiles[id]; } ///> Retrieves a CUF profile at position 0-4 + void SaveCUFProfile(uint8 id, std::nullptr_t) { _CUFProfiles[id] = nullptr; } ///> Empties a CUF profile at position 0-4 + void SaveCUFProfile(uint8 id, std::unique_ptr profile) { _CUFProfiles[id] = std::move(profile); } ///> Replaces a CUF profile at position 0-4 + CUFProfile* GetCUFProfile(uint8 id) const { return _CUFProfiles[id].get(); } ///> Retrieves a CUF profile at position 0-4 uint8 GetCUFProfilesCount() const { uint8 count = 0; @@ -2522,8 +2521,7 @@ class Player : public Unit, public GridObject uint8 GetSubGroup() const { return m_group.getSubGroup(); } uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } - uint64 GetAuraUpdateMaskForRaid() const { return m_auraRaidUpdateMask; } - void SetAuraUpdateMaskForRaid(uint8 slot) { m_auraRaidUpdateMask |= (uint64(1) << slot); } + void RemoveGroupUpdateFlag(uint32 flag) { m_groupUpdateMask &= ~flag; } Player* GetNextRandomRaidMember(float radius); PartyResult CanUninviteFromGroup(ObjectGuid guidMember = ObjectGuid::Empty) const; @@ -2889,7 +2887,6 @@ class Player : public Unit, public GridObject GroupReference m_originalGroup; Group* m_groupInvite; uint32 m_groupUpdateMask; - uint64 m_auraRaidUpdateMask; bool m_bPassOnGroupLoot; // last used pet number (for BG's) @@ -2912,7 +2909,7 @@ class Player : public Unit, public GridObject uint8 m_grantableLevels; - CUFProfile* _CUFProfiles[MAX_CUF_PROFILES]; + std::array, MAX_CUF_PROFILES> _CUFProfiles = {}; private: // internal common parts for CanStore/StoreItem functions diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 7ae20779fa7..a581e612980 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6957,15 +6957,11 @@ void Unit::setPowerType(Powers new_powertype) if (ToPlayer()->GetGroup()) ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POWER_TYPE); } - else if (Pet* pet = ToCreature()->ToPet()) + /*else if (Pet* pet = ToCreature()->ToPet()) TODO 6.x { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_POWER_TYPE); + }*/ float powerMultiplier = 1.0f; if (!IsPet()) @@ -11470,11 +11466,7 @@ void Unit::SetHealth(uint32 val) else if (Pet* pet = ToCreature()->ToPet()) { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP); - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_HP); } } @@ -11495,11 +11487,7 @@ void Unit::SetMaxHealth(uint32 val) else if (Pet* pet = ToCreature()->ToPet()) { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP); - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_HP); } if (val < health) @@ -11551,15 +11539,11 @@ void Unit::SetPower(Powers power, int32 val) if (player->GetGroup()) player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_CUR_POWER); } - else if (Pet* pet = ToCreature()->ToPet()) + /*else if (Pet* pet = ToCreature()->ToPet()) TODO 6.x { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER); + }*/ } void Unit::SetMaxPower(Powers power, int32 val) @@ -11577,15 +11561,11 @@ void Unit::SetMaxPower(Powers power, int32 val) if (ToPlayer()->GetGroup()) ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_MAX_POWER); } - else if (Pet* pet = ToCreature()->ToPet()) + /*else if (Pet* pet = ToCreature()->ToPet()) TODO 6.x { if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MAX_POWER); + }*/ if (val < cur_power) SetPower(power, val); @@ -13007,23 +12987,13 @@ void Unit::UpdateAuraForGroup(uint8 slot) if (Player* player = ToPlayer()) { if (player->GetGroup()) - { player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS); - player->SetAuraUpdateMaskForRaid(slot); - } } else if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsPet()) { Pet* pet = ((Pet*)this); if (pet->isControlled()) - { - Unit* owner = GetOwner(); - if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup()) - { - owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS); - pet->SetAuraUpdateMaskForRaid(slot); - } - } + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_AURAS); } } @@ -16401,7 +16371,7 @@ void Unit::Whisper(std::string const& text, Language language, Player* target, b LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); WorldPackets::Chat::Chat packet; - packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); + packet.Initialize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale); target->SendDirectMessage(packet.Write()); } @@ -16448,7 +16418,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex(); WorldPackets::Chat::Chat packet; - packet.Initalize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, DB2Manager::GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); + packet.Initialize(isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, DB2Manager::GetBroadcastTextValue(bct, locale, getGender()), 0, "", locale); target->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index ac87f58af5c..10288cff927 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2242,6 +2242,25 @@ bool ObjectMgr::GetPlayerNameByGUID(ObjectGuid const& guid, std::string& name) return false; } +bool ObjectMgr::GetPlayerNameAndClassByGUID(ObjectGuid const& guid, std::string& name, uint8& _class) +{ + if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) + { + name = player->GetName(); + _class = player->getClass(); + return true; + } + + if (CharacterInfo const* characterInfo = sWorld->GetCharacterInfo(guid)) + { + name = characterInfo->Name; + _class = characterInfo->Class; + return true; + } + + return false; +} + uint32 ObjectMgr::GetPlayerTeamByGUID(ObjectGuid const& guid) { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index dc26e30773c..4277ab74048 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -780,6 +780,7 @@ class ObjectMgr * @return true if player was found, false otherwise */ static bool GetPlayerNameByGUID(ObjectGuid const& guid, std::string& name); + static bool GetPlayerNameAndClassByGUID(ObjectGuid const& guid, std::string& name, uint8& _class); static uint32 GetPlayerTeamByGUID(ObjectGuid const& guid); static uint32 GetPlayerAccountIdByGUID(ObjectGuid const& guid); static uint32 GetPlayerAccountIdByPlayerName(std::string const& name); @@ -1364,7 +1365,7 @@ class ObjectMgr { auto itr = _guidGenerators.find(high); if (itr == _guidGenerators.end()) - itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr>(new ObjectGuidGenerator()))).first; + itr = _guidGenerators.insert(std::make_pair(high, Trinity::make_unique>())).first; return *itr->second; } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index f359e1eff57..fadf7e1970e 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -21,6 +21,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "Player.h" +#include "Pet.h" #include "World.h" #include "ObjectMgr.h" #include "GroupMgr.h" @@ -35,6 +36,7 @@ #include "Util.h" #include "LFGMgr.h" #include "UpdateFieldFlags.h" +#include "PartyPackets.h" Roll::Roll(ObjectGuid _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid), itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count), @@ -55,11 +57,15 @@ Loot* Roll::getLoot() Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL), m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_NORMAL_RAID), m_legacyRaidDifficulty(DIFFICULTY_10_N), -m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), -m_masterLooterGuid(), m_subGroupsCounts(NULL), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0) +m_bgGroup(nullptr), m_bfGroup(nullptr), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), +m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0), +m_readyCheckStarted(false), m_readyCheckTimer(0), m_activeMarkers(0) { - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].Clear(); + + for (uint8 i = 0; i < RAID_MARKERS_COUNT; ++i) + m_markers[i] = nullptr; } Group::~Group() @@ -176,7 +182,7 @@ void Group::LoadGroupFromDB(Field* fields) m_looterGuid = ObjectGuid::Create(fields[2].GetUInt64()); m_lootThreshold = ItemQualities(fields[3].GetUInt8()); - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].SetRawValue(fields[4 + i].GetBinary()); m_groupType = GroupType(fields[12].GetUInt8()); @@ -199,7 +205,7 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin member.guid = ObjectGuid::Create(guidLow); // skip non-existed member - if (!ObjectMgr::GetPlayerNameByGUID(member.guid, member.name)) + if (!ObjectMgr::GetPlayerNameAndClassByGUID(member.guid, member.name, member._class)) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER); stmt->setUInt64(0, guidLow); @@ -207,9 +213,10 @@ void Group::LoadMemberFromDB(ObjectGuid::LowType guidLow, uint8 memberFlags, uin return; } - member.group = subgroup; - member.flags = memberFlags; - member.roles = roles; + member.group = subgroup; + member.flags = memberFlags; + member.roles = roles; + member.readyChecked = false; m_memberSlots.push_back(member); @@ -368,7 +375,7 @@ bool Group::AddMember(Player* player) bool groupFound = false; for (; subGroup < MAX_RAID_SUBGROUPS; ++subGroup) { - if (m_subGroupsCounts[subGroup] < MAXGROUPSIZE) + if (m_subGroupsCounts[subGroup] < MAX_GROUP_SIZE) { groupFound = true; break; @@ -380,11 +387,13 @@ bool Group::AddMember(Player* player) } MemberSlot member; - member.guid = player->GetGUID(); - member.name = player->GetName(); - member.group = subGroup; - member.flags = 0; - member.roles = 0; + member.guid = player->GetGUID(); + member.name = player->GetName(); + member._class = player->getClass(); + member.group = subGroup; + member.flags = 0; + member.roles = 0; + member.readyChecked = false; m_memberSlots.push_back(member); SubGroupCounterIncrease(subGroup); @@ -407,7 +416,7 @@ bool Group::AddMember(Player* player) if (!isRaidGroup()) // reset targetIcons for non-raid-groups { - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) m_targetIcons[i].Clear(); } @@ -455,7 +464,11 @@ bool Group::AddMember(Player* player) } } } + player->SetGroupUpdateFlag(GROUP_UPDATE_FULL); + if (Pet* pet = player->GetPet()) + pet->SetGroupUpdateFlag(GROUP_UPDATE_PET_FULL); + UpdatePlayerOutOfRange(player); // quest related GO state dependent from raid membership @@ -552,12 +565,6 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R player->GetSession()->SendPacket(&data); } - // Do we really need to send this opcode? - data.Initialize(SMSG_PARTY_UPDATE, 1+1+1+1+8+4+4+8); - data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0); - data << m_guid << uint32(m_counter) << uint32(0) << uint64(0); - player->GetSession()->SendPacket(&data); - _homebindIfInstance(player); } @@ -644,7 +651,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R } } -void Group::ChangeLeader(ObjectGuid newLeaderGuid) +void Group::ChangeLeader(ObjectGuid newLeaderGuid, int8 partyIndex) { member_witerator slot = _getMemberWSlot(newLeaderGuid); @@ -707,9 +714,10 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid) m_leaderName = newLeader->GetName(); ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, false); - WorldPacket data(SMSG_GROUP_NEW_LEADER, m_leaderName.size()+1); - data << slot->name; - BroadcastPacket(&data, true); + WorldPackets::Party::GroupNewLeader groupNewLeader; + groupNewLeader.Name = m_leaderName; + groupNewLeader.PartyIndex = partyIndex; + BroadcastPacket(groupNewLeader.Write(), true); } void Group::Disband(bool hideDestroy /* = false */) @@ -1491,45 +1499,38 @@ void Group::CountTheRoll(Rolls::iterator rollI) delete roll; } -void Group::SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid) +void Group::SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy, uint8 partyIndex) { - if (id >= TARGETICONCOUNT) + if (symbol >= TARGET_ICONS_COUNT) return; // clean other icons - if (!targetGuid.IsEmpty()) - for (int i = 0; i < TARGETICONCOUNT; ++i) - if (m_targetIcons[i] == targetGuid) - SetTargetIcon(i, ObjectGuid::Empty, ObjectGuid::Empty); + if (!target.IsEmpty()) + for (uint8 i = 0; i < TARGET_ICONS_COUNT; ++i) + if (m_targetIcons[i] == target) + SetTargetIcon(i, ObjectGuid::Empty, changedBy, partyIndex); - m_targetIcons[id] = targetGuid; + m_targetIcons[symbol] = target; - WorldPacket data(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, (1+8+1+8)); - data << uint8(0); // set targets - data << whoGuid; - data << uint8(id); - data << targetGuid; - BroadcastPacket(&data, true); + WorldPackets::Party::SendRaidTargetUpdateSingle updateSingle; + updateSingle.PartyIndex = partyIndex; + updateSingle.Target = target; + updateSingle.ChangedBy = changedBy; + updateSingle.Symbol = symbol; + BroadcastPacket(updateSingle.Write(), true); } -void Group::SendTargetIconList(WorldSession* session) +void Group::SendTargetIconList(WorldSession* session, int8 partyIndex) { if (!session) return; - WorldPacket data(SMSG_SEND_RAID_TARGET_UPDATE_ALL, (1+TARGETICONCOUNT*9)); - data << uint8(1); // list targets + WorldPackets::Party::SendRaidTargetUpdateAll updateAll; + updateAll.PartyIndex = partyIndex; + for (uint8 i = 0; i < TARGET_ICONS_COUNT; i++) + updateAll.TargetIcons.insert(std::pair(i, m_targetIcons[i])); - for (uint8 i = 0; i < TARGETICONCOUNT; ++i) - { - if (m_targetIcons[i].IsEmpty()) - continue; - - data << uint8(i); - data << m_targetIcons[i]; - } - - session->SendPacket(&data); + session->SendPacket(updateAll.Write()); } void Group::SendUpdate() @@ -1556,56 +1557,79 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) slot = &(*witr); } - WorldPacket data(SMSG_PARTY_UPDATE, (1+1+1+1+1+4+8+4+4+(GetMembersCount()-1)*(13+8+1+1+1+1)+8+1+8+1+1+1+1)); - data << uint8(m_groupType); // group type (flags in 3.3) - data << uint8(slot->group); - data << uint8(slot->flags); - data << uint8(slot->roles); - if (isLFGGroup()) - { - data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done - data << uint32(sLFGMgr->GetDungeon(m_guid)); - data << uint8(0); // 4.x new - } + WorldPackets::Party::PartyUpdate partyUpdate; - data << m_guid; - data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent - data << uint32(GetMembersCount()-1); - for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + partyUpdate.PartyType = m_groupType; + partyUpdate.PartyIndex = 0; + partyUpdate.PartyFlags = uint8(IsCreated()); + + partyUpdate.PartyGUID = m_guid; + partyUpdate.LeaderGUID = m_leaderGuid; + + partyUpdate.SequenceNum = m_counter++; // 3.3, value increases every time this packet gets sent + + partyUpdate.MyIndex = -1; + uint8 index = 0; + for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr, ++index) { if (slot->guid == citr->guid) - continue; + partyUpdate.MyIndex = index; Player* member = ObjectAccessor::FindConnectedPlayer(citr->guid); - uint8 onlineState = (member && !member->GetSession()->PlayerLogout()) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; - onlineState = onlineState | ((isBGGroup() || isBFGroup()) ? MEMBER_STATUS_PVP : 0); + WorldPackets::Party::GroupPlayerInfos playerInfos; - data << citr->name; - data << citr->guid; // guid - data << uint8(onlineState); // online-state - data << uint8(citr->group); // groupid - data << uint8(citr->flags); // See enum GroupMemberFlags - data << uint8(citr->roles); // Lfg Roles + playerInfos.GUID = citr->guid; + playerInfos.Name = citr->name; + playerInfos.Class = citr->_class; + + playerInfos.Status = MEMBER_STATUS_OFFLINE; + if (member && member->GetSession() && !member->GetSession()->PlayerLogout()) + playerInfos.Status = MEMBER_STATUS_ONLINE | (isBGGroup() || isBFGroup() ? MEMBER_STATUS_PVP : 0); + + playerInfos.Subgroup = citr->group; // groupid + playerInfos.Flags = citr->flags; // See enum GroupMemberFlags + playerInfos.RolesAssigned = citr->roles; // Lfg Roles + + partyUpdate.PlayerList.push_back(playerInfos); } - data << m_leaderGuid; // leader guid + if (GetMembersCount() > 1) + { + // LootSettings + partyUpdate.LootSettings = boost::in_place(); + partyUpdate.LootSettings->Method = m_lootMethod; + partyUpdate.LootSettings->Threshold = m_lootThreshold; + partyUpdate.LootSettings->LootMaster = m_lootMethod == MASTER_LOOT ? m_masterLooterGuid : ObjectGuid::Empty; + + // Difficulty Settings + partyUpdate.DifficultySettings = boost::in_place(); + partyUpdate.DifficultySettings->DungeonDifficultyID = m_dungeonDifficulty; + partyUpdate.DifficultySettings->RaidDifficultyID = m_raidDifficulty; + partyUpdate.DifficultySettings->LegacyRaidDifficultyID = m_legacyRaidDifficulty; + } - if (GetMembersCount() - 1) + // LfgInfos + if (isLFGGroup()) { - data << uint8(m_lootMethod); // loot method + partyUpdate.LfgInfos = boost::in_place(); - if (m_lootMethod == MASTER_LOOT) - data << m_masterLooterGuid; // master looter guid - else - data << uint64(0); + partyUpdate.LfgInfos->Slot = sLFGMgr->GetDungeon(m_guid); + partyUpdate.LfgInfos->BootCount = 0; // new 6.x + partyUpdate.LfgInfos->Aborted = false; // new 6.x + + partyUpdate.LfgInfos->MyFlags = 0; // new 6.x + partyUpdate.LfgInfos->MyRandomSlot = 0; // new 6.x + + partyUpdate.LfgInfos->MyPartialClear = sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0; // FIXME - Dungeon save status? 2 = done + partyUpdate.LfgInfos->MyGearDiff = 0.f; // new 6.x + partyUpdate.LfgInfos->MyFirstReward = false; // new 6.x - data << uint8(m_lootThreshold); // loot threshold - data << uint8(m_dungeonDifficulty); // Dungeon Difficulty - data << uint8(m_raidDifficulty); // Raid Difficulty + partyUpdate.LfgInfos->MyStrangerCount = 0; // new 6.x + partyUpdate.LfgInfos->MyKickVoteCount = 0; // new 6.x } - player->GetSession()->SendPacket(&data); + player->GetSession()->SendPacket(partyUpdate.Write()); } void Group::UpdatePlayerOutOfRange(Player* player) @@ -1613,15 +1637,15 @@ void Group::UpdatePlayerOutOfRange(Player* player) if (!player || !player->IsInWorld()) return; - WorldPacket data; - player->GetSession()->BuildPartyMemberStatsChangedPacket(player, &data); + WorldPackets::Party::PartyMemberStats packet; + packet.Initialize(player); Player* member; for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { member = itr->GetSource(); if (member && member != player && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(), false))) - member->GetSession()->SendPacket(&data); + member->GetSession()->SendPacket(packet.Write()); } } @@ -1653,32 +1677,6 @@ void Group::BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRai } } -void Group::BroadcastReadyCheck(WorldPacket const* packet) -{ - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* player = itr->GetSource(); - if (player && player->GetSession()) - if (IsLeader(player->GetGUID()) || IsAssistant(player->GetGUID())) - player->GetSession()->SendPacket(packet); - } -} - -void Group::OfflineReadyCheck() -{ - for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) - { - Player* player = ObjectAccessor::FindConnectedPlayer(citr->guid); - if (!player || !player->GetSession()) - { - WorldPacket data(SMSG_READY_CHECK_RESPONSE, 9); - data << citr->guid; - data << uint8(0); - BroadcastReadyCheck(&data); - } - } -} - bool Group::_setMembersGroup(ObjectGuid guid, uint8 group) { member_witerator slot = _getMemberWSlot(guid); @@ -1725,8 +1723,8 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) if (slot == m_memberSlots.end()) return; + uint8 prevSubGroup = slot->group; // Abort if the player is already in the target sub group - uint8 prevSubGroup = GetMemberGroup(guid); if (prevSubGroup == group) return; @@ -1758,7 +1756,6 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) else { // If player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference - prevSubGroup = player->GetOriginalSubGroup(); player->GetOriginalGroupRef().setSubGroup(group); } } @@ -1767,6 +1764,51 @@ void Group::ChangeMembersGroup(ObjectGuid guid, uint8 group) SendUpdate(); } +void Group::SwapMembersGroups(ObjectGuid firstGuid, ObjectGuid secondGuid) +{ + if (!isRaidGroup()) + return; + + member_witerator slots[2]; + slots[0] = _getMemberWSlot(firstGuid); + slots[1] = _getMemberWSlot(secondGuid); + if (slots[0] == m_memberSlots.end() || slots[1] == m_memberSlots.end()) + return; + + if (slots[0]->group == slots[1]->group) + return; + + uint8 tmp = slots[0]->group; + slots[0]->group = slots[1]->group; + slots[1]->group = tmp; + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + for (uint8 i = 0; i < 2; i++) + { + // Preserve new sub group in database for non-raid groups + if (!isBGGroup() && !isBFGroup()) + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_MEMBER_SUBGROUP); + + stmt->setUInt8(0, slots[i]->group); + stmt->setUInt64(1, slots[i]->guid.GetCounter()); + + trans->Append(stmt); + } + + if (Player* player = ObjectAccessor::FindConnectedPlayer(slots[i]->guid)) + { + if (player->GetGroup() == this) + player->GetGroupRef().setSubGroup(slots[i]->group); + else + player->GetOriginalGroupRef().setSubGroup(slots[i]->group); + } + } + CharacterDatabase.CommitTransaction(trans); + + SendUpdate(); +} + // Retrieve the next Round-Roubin player for the group // // No update done if loot method is FFA. @@ -2262,9 +2304,167 @@ void Group::SetLfgRoles(ObjectGuid guid, uint8 roles) SendUpdate(); } +uint8 Group::GetLfgRoles(ObjectGuid guid) +{ + member_witerator slot = _getMemberWSlot(guid); + if (slot == m_memberSlots.end()) + return 0; + + return slot->roles; +} + +void Group::Update(uint32 diff) +{ + UpdateReadyCheck(diff); +} + +void Group::UpdateReadyCheck(uint32 diff) +{ + if (!m_readyCheckStarted) + return; + + m_readyCheckTimer -= diff; + if (m_readyCheckTimer <= 0) + EndReadyCheck(); +} + +void Group::StartReadyCheck(ObjectGuid starterGuid, int8 partyIndex, uint32 duration) +{ + if (m_readyCheckStarted) + return; + + member_witerator slot = _getMemberWSlot(starterGuid); + if (slot == m_memberSlots.end()) + return ; + + m_readyCheckStarted = true; + m_readyCheckTimer = duration; + + SetOfflineMembersReadyChecked(); + + SetMemberReadyChecked(&(*slot)); + + WorldPackets::Party::ReadyCheckStarted readyCheckStarted; + readyCheckStarted.PartyGUID = m_guid; + readyCheckStarted.PartyIndex = partyIndex; + readyCheckStarted.InitiatorGUID = starterGuid; + readyCheckStarted.Duration = duration; + BroadcastPacket(readyCheckStarted.Write(), false); +} + +void Group::EndReadyCheck(void) +{ + if (!m_readyCheckStarted) + return; + + m_readyCheckStarted = false; + m_readyCheckTimer = 0; + + ResetMemberReadyChecked(); + + WorldPackets::Party::ReadyCheckCompleted readyCheckCompleted; + readyCheckCompleted.PartyIndex = 0; + readyCheckCompleted.PartyGUID = m_guid; + BroadcastPacket(readyCheckCompleted.Write(), false); +} + +bool Group::IsReadyCheckCompleted(void) const +{ + for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + if (!citr->readyChecked) + return false; + return true; +} + +void Group::SetMemberReadyCheck(ObjectGuid guid, bool ready) +{ + if (!m_readyCheckStarted) + return; + + member_witerator slot = _getMemberWSlot(guid); + if (slot != m_memberSlots.end()) + SetMemberReadyCheck(&(*slot), ready); +} + +void Group::SetMemberReadyCheck(MemberSlot* slot, bool ready) +{ + WorldPackets::Party::ReadyCheckResponse response; + response.PartyGUID = m_guid; + response.Player = slot->guid; + response.IsReady = ready; + BroadcastPacket(response.Write(), false); + + SetMemberReadyChecked(slot); +} + +void Group::SetOfflineMembersReadyChecked(void) +{ + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + { + Player* player = ObjectAccessor::FindConnectedPlayer(itr->guid); + if (!player || !player->GetSession()) + SetMemberReadyCheck(&(*itr), false); + } +} + +void Group::SetMemberReadyChecked(MemberSlot* slot) +{ + slot->readyChecked = true; + if (IsReadyCheckCompleted()) + EndReadyCheck(); +} + +void Group::ResetMemberReadyChecked(void) +{ + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + itr->readyChecked = false; +} + +void Group::AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid) +{ + if (markerId >= RAID_MARKERS_COUNT || m_markers[markerId]) + return; + + m_activeMarkers |= (1 << markerId); + m_markers[markerId] = Trinity::make_unique(mapId, positionX, positionY, positionZ, transportGuid); + SendRaidMarkersChanged(); +} + +void Group::DeleteRaidMarker(uint8 markerId) +{ + if (markerId > RAID_MARKERS_COUNT) + return; + + for (uint8 i = 0; i < RAID_MARKERS_COUNT; i++) + if (m_markers[i] && (markerId == i || markerId == RAID_MARKERS_COUNT)) + { + m_markers[i] = nullptr; + m_activeMarkers &= ~(1 << i); + } + + SendRaidMarkersChanged(); +} + +void Group::SendRaidMarkersChanged(WorldSession* session, int8 partyIndex) +{ + WorldPackets::Party::RaidMarkersChanged packet; + + packet.PartyIndex = partyIndex; + packet.ActiveMarkers = m_activeMarkers; + + for (uint8 i = 0; i < RAID_MARKERS_COUNT; i++) + if (m_markers[i]) + packet.RaidMarkers.push_back(m_markers[i].get()); + + if (session) + session->SendPacket(packet.Write()); + else + BroadcastPacket(packet.Write(), false); +} + bool Group::IsFull() const { - return isRaidGroup() ? (m_memberSlots.size() >= MAXRAIDSIZE) : (m_memberSlots.size() >= MAXGROUPSIZE); + return isRaidGroup() ? (m_memberSlots.size() >= MAX_RAID_SIZE) : (m_memberSlots.size() >= MAX_GROUP_SIZE); } bool Group::isLFGGroup() const @@ -2371,10 +2571,9 @@ bool Group::SameSubGroup(ObjectGuid guid1, MemberSlot const* slot2) const bool Group::HasFreeSlotSubGroup(uint8 subgroup) const { - return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE); + return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAX_GROUP_SIZE); } - uint8 Group::GetMemberGroup(ObjectGuid guid) const { member_citerator mslot = _getMemberCSlot(guid); @@ -2522,3 +2721,15 @@ void Group::ToggleGroupMemberFlag(member_witerator slot, uint8 flag, bool apply) slot->flags &= ~flag; } +void Group::SetEveryoneIsAssistant(bool apply) +{ + if (apply) + m_groupType = GroupType(m_groupType | GROUPTYPE_EVERYONE_ASSISTANT); + else + m_groupType = GroupType(m_groupType & ~GROUPTYPE_EVERYONE_ASSISTANT); + + for (member_witerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) + ToggleGroupMemberFlag(itr, MEMBER_FLAG_ASSISTANT, apply); + + SendUpdate(); +} diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 4154f31a410..e14ca6c976b 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -38,10 +38,14 @@ class WorldSession; struct MapEntry; -#define MAXGROUPSIZE 5 -#define MAXRAIDSIZE 40 -#define MAX_RAID_SUBGROUPS MAXRAIDSIZE/MAXGROUPSIZE -#define TARGETICONCOUNT 8 +#define MAX_GROUP_SIZE 5 +#define MAX_RAID_SIZE 40 +#define MAX_RAID_SUBGROUPS MAX_RAID_SIZE / MAX_GROUP_SIZE + +#define TARGET_ICONS_COUNT 8 +#define RAID_MARKERS_COUNT 8 + +#define READYCHECK_DURATION 35000 enum RollVote { @@ -81,50 +85,59 @@ enum GroupMemberAssignment enum GroupType { - GROUPTYPE_NORMAL = 0x00, - GROUPTYPE_BG = 0x01, - GROUPTYPE_RAID = 0x02, - GROUPTYPE_BGRAID = GROUPTYPE_BG | GROUPTYPE_RAID, // mask - GROUPTYPE_LFG_RESTRICTED = 0x04, // Script_HasLFGRestrictions() - GROUPTYPE_LFG = 0x08, + GROUPTYPE_NORMAL = 0x00, + GROUPTYPE_BG = 0x01, + GROUPTYPE_RAID = 0x02, + GROUPTYPE_BGRAID = GROUPTYPE_BG | GROUPTYPE_RAID, // mask + GROUPTYPE_LFG_RESTRICTED = 0x04, // Script_HasLFGRestrictions() + GROUPTYPE_LFG = 0x08, + GROUPTYPE_EVERYONE_ASSISTANT = 0x40, // Script_IsEveryoneAssistant() (4.x) // 0x10, leave/change group?, I saw this flag when leaving group and after leaving BG while in group // GROUPTYPE_ONE_PERSON_PARTY = 0x20, 4.x Script_IsOnePersonParty() - // GROUPTYPE_EVERYONE_ASSISTANT = 0x40 4.x Script_IsEveryoneAssistant() }; enum GroupUpdateFlags { GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing - GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16 (GroupMemberStatusFlag) - GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32 (HP) - GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32 (HP) - GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 (PowerType) - GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // int16 (power value) - GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // int16 (power value) - GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 (level value) - GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 (zone id) - GROUP_UPDATE_FLAG_UNK100 = 0x00000100, // int16 (unk) - GROUP_UPDATE_FLAG_POSITION = 0x00000200, // uint16 (x), uint16 (y), uint16 (z) - GROUP_UPDATE_FLAG_AURAS = 0x00000400, // uint8 (unk), uint64 (mask), uint32 (count), for each bit set: uint32 (spell id) + uint16 (AuraFlags) (if has flags Scalable -> 3x int32 (bps)) - GROUP_UPDATE_FLAG_PET_GUID = 0x00000800, // uint64 (pet guid) - GROUP_UPDATE_FLAG_PET_NAME = 0x00001000, // cstring (name, NULL terminated string) - GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00002000, // uint16 (model id) - GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00004000, // uint32 (HP) - GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00008000, // uint32 (HP) - GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00010000, // uint8 (PowerType) - GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00020000, // uint16 (power value) - GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00040000, // uint16 (power value) - GROUP_UPDATE_FLAG_PET_AURAS = 0x00080000, // [see GROUP_UPDATE_FLAG_AURAS] - GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00100000, // int32 (vehicle seat id) - GROUP_UPDATE_FLAG_PHASE = 0x00200000, // int32 (unk), uint32 (phase count), for (count) uint16(phaseId) - - GROUP_UPDATE_PET = GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | - GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | - GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER | GROUP_UPDATE_FLAG_PET_AURAS, // all pet flags - GROUP_UPDATE_FULL = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | - GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | - GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | - GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_PET | GROUP_UPDATE_FLAG_PHASE // all known flags, except UNK100 and VEHICLE_SEAT + GROUP_UPDATE_FLAG_UNK704 = 0x00000001, // uint8[2] (unk) + GROUP_UPDATE_FLAG_STATUS = 0x00000002, // uint16 (GroupMemberStatusFlag) + GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000004, // uint8 (PowerType) + GROUP_UPDATE_FLAG_UNK322 = 0x00000008, // uint16 (unk) + GROUP_UPDATE_FLAG_CUR_HP = 0x00000010, // uint32 (HP) + GROUP_UPDATE_FLAG_MAX_HP = 0x00000020, // uint32 (max HP) + GROUP_UPDATE_FLAG_CUR_POWER = 0x00000040, // int16 (power value) + GROUP_UPDATE_FLAG_MAX_POWER = 0x00000080, // int16 (max power value) + GROUP_UPDATE_FLAG_LEVEL = 0x00000100, // uint16 (level value) + GROUP_UPDATE_FLAG_UNK200000 = 0x00000200, // int16 (unk) + GROUP_UPDATE_FLAG_ZONE = 0x00000400, // uint16 (zone id) + GROUP_UPDATE_FLAG_UNK2000000 = 0x00000800, // int16 (unk) + GROUP_UPDATE_FLAG_UNK4000000 = 0x00001000, // int32 (unk) + GROUP_UPDATE_FLAG_POSITION = 0x00002000, // uint16 (x), uint16 (y), uint16 (z) + GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00104000, // int32 (vehicle seat id) + GROUP_UPDATE_FLAG_AURAS = 0x00008000, // uint8 (unk), uint64 (mask), uint32 (count), for each bit set: uint32 (spell id) + uint16 (AuraFlags) (if has flags Scalable -> 3x int32 (bps)) + GROUP_UPDATE_FLAG_PET = 0x00010000, // complex (pet) + GROUP_UPDATE_FLAG_PHASE = 0x00020000, // int32 (unk), uint32 (phase count), for (count) uint16(phaseId) + + GROUP_UPDATE_FULL = GROUP_UPDATE_FLAG_UNK704 | GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_POWER_TYPE | + GROUP_UPDATE_FLAG_UNK322 | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | + GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | + GROUP_UPDATE_FLAG_UNK200000 | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_UNK2000000 | + GROUP_UPDATE_FLAG_UNK4000000 | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_VEHICLE_SEAT | + GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET | GROUP_UPDATE_FLAG_PHASE // all known flags +}; + +enum GroupUpdatePetFlags +{ + GROUP_UPDATE_FLAG_PET_NONE = 0x00000000, // nothing + GROUP_UPDATE_FLAG_PET_GUID = 0x00000001, // ObjectGuid (pet guid) + GROUP_UPDATE_FLAG_PET_NAME = 0x00000002, // cstring (name, NULL terminated string) + GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00000004, // uint16 (model id) + GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00000008, // uint32 (HP) + GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00000010, // uint32 (max HP) + GROUP_UPDATE_FLAG_PET_AURAS = 0x00000020, // [see GROUP_UPDATE_FLAG_AURAS] + + GROUP_UPDATE_PET_FULL = GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | + GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_AURAS // all pet flags }; class Roll : public LootValidatorRef @@ -160,6 +173,18 @@ struct InstanceGroupBind InstanceGroupBind() : save(NULL), perm(false) { } }; +struct RaidMarker +{ + WorldLocation Location; + ObjectGuid TransportGUID; + + RaidMarker(uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid = ObjectGuid::Empty) + { + Location.WorldRelocate(mapId, positionX, positionY, positionZ); + TransportGUID = transportGuid; + } +}; + /** request member stats checken **/ /// @todo uninvite people that not accepted invite class Group @@ -169,9 +194,11 @@ class Group { ObjectGuid guid; std::string name; + uint8 _class; uint8 group; uint8 flags; uint8 roles; + bool readyChecked; }; typedef std::list MemberSlotList; typedef MemberSlotList::const_iterator member_citerator; @@ -197,7 +224,7 @@ class Group bool AddLeaderInvite(Player* player); bool AddMember(Player* player); bool RemoveMember(ObjectGuid guid, const RemoveMethod &method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = NULL); - void ChangeLeader(ObjectGuid guid); + void ChangeLeader(ObjectGuid guid, int8 partyIndex = 0); void SetLootMethod(LootMethod method); void SetLooterGuid(ObjectGuid guid); void SetMasterLooterGuid(ObjectGuid guid); @@ -205,6 +232,31 @@ class Group void SetLootThreshold(ItemQualities threshold); void Disband(bool hideDestroy = false); void SetLfgRoles(ObjectGuid guid, uint8 roles); + uint8 GetLfgRoles(ObjectGuid guid); + void SetEveryoneIsAssistant(bool apply); + + // Update + void Update(uint32 diff); + void UpdateReadyCheck(uint32 diff); + + // Ready check + void StartReadyCheck(ObjectGuid starterGuid, int8 partyIndex, uint32 duration = READYCHECK_DURATION); + void EndReadyCheck(); + + bool IsReadyCheckStarted(void) const { return m_readyCheckStarted; } + bool IsReadyCheckCompleted(void) const; + + void SetOfflineMembersReadyChecked(void); + void SetMemberReadyCheck(ObjectGuid guid, bool ready); + void SetMemberReadyCheck(MemberSlot* slot, bool ready); + + void SetMemberReadyChecked(MemberSlot* slot); + void ResetMemberReadyChecked(void); + + // Raid Markers + void AddRaidMarker(uint8 markerId, uint32 mapId, float positionX, float positionY, float positionZ, ObjectGuid transportGuid = ObjectGuid::Empty); + void DeleteRaidMarker(uint8 markerId); + void SendRaidMarkersChanged(WorldSession* session = nullptr, int8 partyIndex = 0); // properties accessories bool IsFull() const; @@ -254,7 +306,8 @@ class Group GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgOrTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot, ObjectGuid& errorGuid); void ChangeMembersGroup(ObjectGuid guid, uint8 group); - void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid); + void SwapMembersGroups(ObjectGuid firstGuid, ObjectGuid secondGuid); + void SetTargetIcon(uint8 symbol, ObjectGuid target, ObjectGuid changedBy, uint8 partyIndex); void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag); void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag); @@ -269,7 +322,7 @@ class Group // -no description- //void SendInit(WorldSession* session); - void SendTargetIconList(WorldSession* session); + void SendTargetIconList(WorldSession* session, int8 partyIndex = 0); void SendUpdate(); void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = NULL); void UpdatePlayerOutOfRange(Player* player); @@ -290,8 +343,6 @@ class Group void BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty); void BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty); - void BroadcastReadyCheck(WorldPacket const* packet); - void OfflineReadyCheck(); /*********************************************************/ /*** LOOT SYSTEM ***/ @@ -351,7 +402,7 @@ class Group Difficulty m_legacyRaidDifficulty; Battleground* m_bgGroup; Battlefield* m_bfGroup; - ObjectGuid m_targetIcons[TARGETICONCOUNT]; + ObjectGuid m_targetIcons[TARGET_ICONS_COUNT]; LootMethod m_lootMethod; ItemQualities m_lootThreshold; ObjectGuid m_looterGuid; @@ -363,5 +414,13 @@ class Group uint32 m_counter; // used only in SMSG_GROUP_LIST uint32 m_maxEnchantingLevel; uint32 m_dbStoreId; // Represents the ID used in database (Can be reused by other groups if group was disbanded) + + // Ready Check + bool m_readyCheckStarted; + int32 m_readyCheckTimer; + + // Raid markers + std::array, RAID_MARKERS_COUNT> m_markers; + uint32 m_activeMarkers; }; #endif diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp index f0c764e7269..7fb239cec48 100644 --- a/src/server/game/Groups/GroupMgr.cpp +++ b/src/server/game/Groups/GroupMgr.cpp @@ -233,3 +233,10 @@ void GroupMgr::LoadGroups() TC_LOG_INFO("server.loading", ">> Loaded %u group-instance saves in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } } + +void GroupMgr::Update(uint32 diff) +{ + for (GroupContainer::iterator itr = GroupStore.begin(); itr != GroupStore.end(); itr++) + if (itr->second) + itr->second->Update(diff); +} diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h index 6aafe77432c..2fdd6d978e9 100644 --- a/src/server/game/Groups/GroupMgr.h +++ b/src/server/game/Groups/GroupMgr.h @@ -50,6 +50,8 @@ public: void AddGroup(Group* group); void RemoveGroup(Group* group); + void Update(uint32 diff); + protected: ObjectGuid::LowType NextGroupId; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index c5812999490..0225c9405ce 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -2466,7 +2466,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { WorldPackets::Chat::Chat packet; - packet.Initalize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), nullptr, msg); + packet.Initialize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), nullptr, msg); WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindConnectedPlayer()) @@ -2481,7 +2481,7 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std:: if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK)) { WorldPackets::Chat::Chat packet; - packet.Initalize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), nullptr, msg, 0, "", DEFAULT_LOCALE, prefix); + packet.Initialize(officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), nullptr, msg, 0, "", DEFAULT_LOCALE, prefix); WorldPacket const* data = packet.Write(); for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindPlayer()) diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index b5550c2c073..b9fd383b19d 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -288,7 +288,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID())); break; } @@ -320,8 +320,8 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, } case CHAT_MSG_RAID: { - Group* group = GetPlayer()->GetOriginalGroup(); - if (!group) + Group* group = GetPlayer()->GetGroup(); + if (!group || !group->isRaidGroup() || group->isBGGroup()) return; if (group->IsLeader(GetPlayer()->GetGUID())) @@ -330,7 +330,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false); break; } @@ -344,7 +344,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, WorldPackets::Chat::Chat packet; //in battleground, raid warning is sent only to players in battleground - code is ok - packet.Initalize(CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); + packet.Initialize(CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(packet.Write(), false); break; } @@ -381,7 +381,7 @@ void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), Language(lang), sender, nullptr, msg); + packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false); break; } @@ -484,7 +484,7 @@ void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std: } WorldPackets::Chat::Chat packet; - packet.Initalize(type, LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix); + packet.Initialize(type, LANG_ADDON, sender, nullptr, text, 0, "", DEFAULT_LOCALE, prefix); group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, subGroup, sender->GetGUID()); break; } @@ -666,7 +666,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) return; WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); + packet.Initialize(CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); player->SendDirectMessage(packet.Write()); } diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 9552c9a0655..4aef42fed8d 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -35,6 +35,7 @@ #include "SpellAuraEffects.h" #include "MiscPackets.h" #include "LootPackets.h" +#include "PartyPackets.h" class Aura; @@ -51,103 +52,59 @@ class Aura; void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val /* = 0 */) { - WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4 + 8); - data << uint32(operation); - data << member; - data << uint32(res); - data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S) - data << uint64(0); // player who caused error (in some cases). - - SendPacket(&data); -} - -void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) -{ - ObjectGuid crossRealmGuid; // unused - - recvData.read_skip(); // Non-zero in cross realm invites - recvData.read_skip(); // Always 0 - - crossRealmGuid[2] = recvData.ReadBit(); - crossRealmGuid[7] = recvData.ReadBit(); - - uint8 realmLen = recvData.ReadBits(9); - - crossRealmGuid[3] = recvData.ReadBit(); - - uint8 nameLen = recvData.ReadBits(10); - - crossRealmGuid[5] = recvData.ReadBit(); - crossRealmGuid[4] = recvData.ReadBit(); - crossRealmGuid[6] = recvData.ReadBit(); - crossRealmGuid[0] = recvData.ReadBit(); - crossRealmGuid[1] = recvData.ReadBit(); + WorldPackets::Party::PartyCommandResult packet; - recvData.ReadByteSeq(crossRealmGuid[4]); - recvData.ReadByteSeq(crossRealmGuid[7]); - recvData.ReadByteSeq(crossRealmGuid[6]); + packet.Name = member; + packet.Command = uint8(operation); + packet.Result = uint8(res); + packet.ResultData = val; + packet.ResultGUID = ObjectGuid::Empty; - std::string memberName, realmName; - memberName = recvData.ReadString(nameLen); - realmName = recvData.ReadString(realmLen); // unused - - recvData.ReadByteSeq(crossRealmGuid[1]); - recvData.ReadByteSeq(crossRealmGuid[0]); - recvData.ReadByteSeq(crossRealmGuid[5]); - recvData.ReadByteSeq(crossRealmGuid[3]); - recvData.ReadByteSeq(crossRealmGuid[2]); - - // attempt add selected player - - // cheating - if (!normalizePlayerName(memberName)) - { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); - return; - } + SendPacket(packet.Write()); +} - Player* player = ObjectAccessor::FindPlayerByName(memberName); +void WorldSession::HandlePartyInviteOpcode(WorldPackets::Party::PartyInviteClient& packet) +{ + Player* player = ObjectAccessor::FindPlayerByName(packet.TargetName); // no player if (!player) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, packet.TargetName, ERR_BAD_PLAYER_NAME_S); return; } // restrict invite to GMs if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_BAD_PLAYER_NAME_S); return; } // can't group with if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_PLAYER_WRONG_FACTION); return; } if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_TARGET_NOT_IN_INSTANCE_S); return; } // just ignore us if (player->GetInstanceId() != 0 && player->GetDungeonDifficultyID() != GetPlayer()->GetDungeonDifficultyID()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_IGNORING_YOU_S); return; } if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID())) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_IGNORING_YOU_S); return; } - ObjectGuid invitedGuid = player->GetGUID(); - Group* group = GetPlayer()->GetGroup(); if (group && group->isBGGroup()) group = GetPlayer()->GetOriginalGroup(); @@ -155,67 +112,18 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) Group* group2 = player->GetGroup(); if (group2 && group2->isBGGroup()) group2 = player->GetOriginalGroup(); + // player already in another group or invited if (group2 || player->GetGroupInvite()) { - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_ALREADY_IN_GROUP_S); if (group2) { // tell the player that they were invited but it failed as they were already in a group - WorldPacket data(SMSG_PARTY_INVITE, 45); - - data.WriteBit(0); - - data.WriteBit(invitedGuid[0]); - data.WriteBit(invitedGuid[3]); - data.WriteBit(invitedGuid[2]); - - data.WriteBit(0); // Inverse already in group - - data.WriteBit(invitedGuid[6]); - data.WriteBit(invitedGuid[5]); - - data.WriteBits(0, 9); // Realm name - - data.WriteBit(invitedGuid[4]); - - data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length - - data.WriteBits(0, 24); // Count 2 - - data.WriteBit(0); - - data.WriteBit(invitedGuid[1]); - data.WriteBit(invitedGuid[7]); - - data.FlushBits(); - - data.WriteByteSeq(invitedGuid[1]); - data.WriteByteSeq(invitedGuid[4]); - - data << int32(getMSTime()); - data << int32(0); - data << int32(0); - - data.WriteByteSeq(invitedGuid[6]); - data.WriteByteSeq(invitedGuid[0]); - data.WriteByteSeq(invitedGuid[2]); - data.WriteByteSeq(invitedGuid[3]); - - // for count2 { int32(0) } - - data.WriteByteSeq(invitedGuid[5]); - - // data.append(realm name); - - data.WriteByteSeq(invitedGuid[7]); - - data.WriteString(GetPlayer()->GetName()); // inviter name - - data << int32(0); - - player->GetSession()->SendPacket(&data); + WorldPackets::Party::PartyInvite partyInvite; + partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, false); + player->GetSession()->SendPacket(partyInvite.Write()); } return; @@ -264,79 +172,21 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) } } - // ok, we do it - WorldPacket data(SMSG_PARTY_INVITE, 45); - - data.WriteBit(0); - - data.WriteBit(invitedGuid[0]); - data.WriteBit(invitedGuid[3]); - data.WriteBit(invitedGuid[2]); - - data.WriteBit(1); // Inverse already in group - - data.WriteBit(invitedGuid[6]); - data.WriteBit(invitedGuid[5]); - - data.WriteBits(0, 9); // Realm name - - data.WriteBit(invitedGuid[4]); - - data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length - - data.WriteBits(0, 24); // Count 2 - - data.WriteBit(0); - - data.WriteBit(invitedGuid[1]); - data.WriteBit(invitedGuid[7]); - - data.FlushBits(); + WorldPackets::Party::PartyInvite partyInvite; + partyInvite.Initialize(GetPlayer(), packet.ProposedRoles, true); + player->GetSession()->SendPacket(partyInvite.Write()); - data.WriteByteSeq(invitedGuid[1]); - data.WriteByteSeq(invitedGuid[4]); - - data << int32(getMSTime()); - data << int32(0); - data << int32(0); - - data.WriteByteSeq(invitedGuid[6]); - data.WriteByteSeq(invitedGuid[0]); - data.WriteByteSeq(invitedGuid[2]); - data.WriteByteSeq(invitedGuid[3]); - - // for count2 { int32(0) } - - data.WriteByteSeq(invitedGuid[5]); - - // data.append(realm name); - - data.WriteByteSeq(invitedGuid[7]); - - data.WriteString(GetPlayer()->GetName()); - - data << int32(0); - - player->GetSession()->SendPacket(&data); - - SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK); + SendPartyResult(PARTY_OP_INVITE, player->GetName(), ERR_PARTY_RESULT_OK); } -void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) +void WorldSession::HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet) { - recvData.ReadBit(); // unk always 0 - bool accept = recvData.ReadBit(); - - // Never actually received? - /*if (accept) - recvData.read_skip(); // unk*/ - Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; - if (accept) + if (packet.Accept) { // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); @@ -391,28 +241,22 @@ void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) return; // report - WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().size()); - data << GetPlayer()->GetName(); - leader->GetSession()->SendPacket(&data); + WorldPackets::Party::GroupDecline decline(GetPlayer()->GetName()); + leader->GetSession()->SendPacket(decline.Write()); } } -void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) +void WorldSession::HandlePartyUninviteOpcode(WorldPackets::Party::PartyUninvite& packet) { - ObjectGuid guid; - std::string reason; - recvData >> guid; - recvData >> reason; - - //can't uninvite yourself - if (guid == GetPlayer()->GetGUID()) + // can't uninvite yourself + if (packet.TargetGUID == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteGuidOpcode: leader %s (%s) tried to uninvite himself from the group.", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); return; } - PartyResult res = GetPlayer()->CanUninviteFromGroup(guid); + PartyResult res = GetPlayer()->CanUninviteFromGroup(packet.TargetGUID); if (res != ERR_PARTY_RESULT_OK) { SendPartyResult(PARTY_OP_UNINVITE, "", res); @@ -423,13 +267,13 @@ void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) // grp is checked already above in CanUninviteFromGroup() ASSERT(grp); - if (grp->IsMember(guid)) + if (grp->IsMember(packet.TargetGUID)) { - Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str()); + Player::RemoveFromGroup(grp, packet.TargetGUID, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), packet.Reason.c_str()); return; } - if (Player* player = grp->GetInvited(guid)) + if (Player* player = grp->GetInvited(packet.TargetGUID)) { player->UninviteFromGroup(); return; @@ -438,12 +282,9 @@ void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) SendPartyResult(PARTY_OP_UNINVITE, "", ERR_TARGET_NOT_IN_GROUP_S); } -void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) +void WorldSession::HandleSetPartyLeaderOpcode(WorldPackets::Party::SetPartyLeader& packet) { - ObjectGuid guid; - recvData >> guid; - - Player* player = ObjectAccessor::FindConnectedPlayer(guid); + Player* player = ObjectAccessor::FindConnectedPlayer(packet.TargetGUID); Group* group = GetPlayer()->GetGroup(); if (!group || !player) @@ -453,87 +294,35 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData) return; // Everything's fine, accepted. - group->ChangeLeader(guid); + group->ChangeLeader(packet.TargetGUID, packet.PartyIndex); group->SendUpdate(); } -void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData) +void WorldSession::HandleSetRoleOpcode(WorldPackets::Party::SetRole& packet) { - 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_ROLE_CHANGED_INFORM, 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()) + WorldPackets::Party::RoleChangedInform roleChangedInform; + + Group* group = GetPlayer()->GetGroup(); + uint8 oldRole = group ? group->GetLfgRoles(packet.TargetGUID) : 0; + if (oldRole == packet.Role) + return; + + roleChangedInform.PartyIndex = packet.PartyIndex; + roleChangedInform.From = GetPlayer()->GetGUID(); + roleChangedInform.ChangedUnit = packet.TargetGUID; + roleChangedInform.OldRole = oldRole; + roleChangedInform.NewRole = packet.Role; + + if (group) { - /// @todo probably should be sent only if (oldRole != newRole) - group->BroadcastPacket(&data, false); - group->SetLfgRoles(guid2, newRole); + group->BroadcastPacket(roleChangedInform.Write(), false); + group->SetLfgRoles(packet.TargetGUID, packet.Role); } else - SendPacket(&data); + SendPacket(roleChangedInform.Write()); } -void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) +void WorldSession::HandleLeaveGroupOpcode(WorldPackets::Party::LeaveGroup& /*packet*/) { Group* grp = GetPlayer()->GetGroup(); if (!grp) @@ -554,13 +343,8 @@ void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/) GetPlayer()->RemoveFromGroup(GROUP_REMOVEMETHOD_LEAVE); } -void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData) +void WorldSession::HandleSetLootMethodOpcode(WorldPackets::Party::SetLootMethod& packet) { - uint32 lootMethod; - ObjectGuid lootMaster; - uint32 lootThreshold; - recvData >> lootMethod >> lootMaster >> lootThreshold; - Group* group = GetPlayer()->GetGroup(); if (!group) return; @@ -569,20 +353,20 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket& recvData) if (!group->IsLeader(GetPlayer()->GetGUID())) return; - if (lootMethod > NEED_BEFORE_GREED) + if (packet.LootMethod > NEED_BEFORE_GREED) return; - if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT) + if (packet.LootThreshold < ITEM_QUALITY_UNCOMMON || packet.LootThreshold > ITEM_QUALITY_ARTIFACT) return; - if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster)) + if (packet.LootMethod == MASTER_LOOT && !group->IsMember(packet.LootMasterGUID)) return; /********************/ // everything's fine, do it - group->SetLootMethod((LootMethod)lootMethod); - group->SetMasterLooterGuid(lootMaster); - group->SetLootThreshold((ItemQualities)lootThreshold); + group->SetLootMethod((LootMethod)packet.LootMethod); + group->SetMasterLooterGuid(packet.LootMasterGUID); + group->SetLootThreshold((ItemQualities)packet.LootThreshold); group->SendUpdate(); } @@ -605,28 +389,16 @@ void WorldSession::HandleLootRoll(WorldPackets::Loot::LootRoll& packet) } } -void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData) +void WorldSession::HandleMinimapPingOpcode(WorldPackets::Party::MinimapPingClient& packet) { - 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(SMSG_MINIMAP_PING, (8+4+4)); - data << GetPlayer()->GetGUID(); - data << float(x); - data << float(y); - GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID()); + WorldPackets::Party::MinimapPing minimapPing; + minimapPing.Sender = GetPlayer()->GetGUID(); + minimapPing.PositionX = packet.PositionX; + minimapPing.PositionY = packet.PositionY; + GetPlayer()->GetGroup()->BroadcastPacket(minimapPing.Write(), true, -1, GetPlayer()->GetGUID()); } void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet) @@ -643,8 +415,6 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& // everything's fine, do it roll = urand(minimum, maximum); - //TC_LOG_DEBUG("misc", "ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll); - WorldPackets::Misc::RandomRoll randomRoll; randomRoll.Min = minimum; randomRoll.Max = maximum; @@ -657,44 +427,31 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& SendPacket(randomRoll.Write()); } -void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData) +void WorldSession::HandleUpdateRaidTargetOpcode(WorldPackets::Party::UpdateRaidTarget& packet) { - 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 (packet.Symbol == 0xFF) // target icon request + group->SendTargetIconList(this, packet.PartyIndex); + else // target icon update { if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) return; - ObjectGuid guid; - recvData >> guid; - - if (guid.IsPlayer()) + if (packet.Target.IsPlayer()) { - Player* target = ObjectAccessor::FindConnectedPlayer(guid); - + Player* target = ObjectAccessor::FindConnectedPlayer(packet.Target); if (!target || target->IsHostileTo(GetPlayer())) return; } - group->SetTargetIcon(x, _player->GetGUID(), guid); + group->SetTargetIcon(packet.Symbol, packet.Target, GetPlayer()->GetGUID(), packet.PartyIndex); } } -void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData) +void WorldSession::HandleConvertRaidOpcode(WorldPackets::Party::ConvertRaid& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) @@ -711,71 +468,56 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData) 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) + if (packet.Raid) group->ConvertToRaid(); else group->ConvertToGroup(); } -void WorldSession::HandleGroupRequestJoinUpdates(WorldPacket& /*recvData*/) +void WorldSession::HandleRequestPartyJoinUpdates(WorldPackets::Party::RequestPartyJoinUpdates& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) return; - // does some stuff. dunno what. + group->SendTargetIconList(this, packet.PartyIndex); + group->SendRaidMarkersChanged(this, packet.PartyIndex); } -void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData) +void WorldSession::HandleChangeSubGroupOpcode(WorldPackets::Party::ChangeSubGroup& packet) { // 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 (groupNr >= MAX_RAID_SUBGROUPS) + if (packet.NewSubGroup >= MAX_RAID_SUBGROUPS) return; ObjectGuid senderGuid = GetPlayer()->GetGUID(); if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) return; - if (!group->HasFreeSlotSubGroup(groupNr)) + if (!group->HasFreeSlotSubGroup(packet.NewSubGroup)) return; - Player* movedPlayer = ObjectAccessor::FindConnectedPlayerByName(name); - ObjectGuid guid; - - if (movedPlayer) - guid = movedPlayer->GetGUID(); - else - { - CharacterDatabase.EscapeString(name); - guid = ObjectMgr::GetPlayerGUIDByName(name.c_str()); - } - - group->ChangeMembersGroup(guid, groupNr); + group->ChangeMembersGroup(packet.TargetGUID, packet.NewSubGroup); } -void WorldSession::HandleGroupSwapSubGroupOpcode(WorldPacket& recvData) +void WorldSession::HandleSwapSubGroupsOpcode(WorldPackets::Party::SwapSubGroups& packet) { - std::string unk1; - std::string unk2; + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; - recvData >> unk1; - recvData >> unk2; + ObjectGuid senderGuid = GetPlayer()->GetGUID(); + if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) + return; + + group->SwapMembersGroups(packet.FirstTarget, packet.SecondTarget); } -void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket& recvData) +void WorldSession::HandleSetAssistantLeaderOpcode(WorldPackets::Party::SetAssistantLeader& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) @@ -784,12 +526,7 @@ void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket& recvData) if (!group->IsLeader(GetPlayer()->GetGUID())) return; - ObjectGuid guid; - bool apply; - recvData >> guid; - recvData >> apply; - - group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT); + group->SetGroupMemberFlag(packet.Target, packet.Apply, MEMBER_FLAG_ASSISTANT); } void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) @@ -826,509 +563,103 @@ void WorldSession::HandlePartyAssignmentOpcode(WorldPacket& recvData) group->SendUpdate(); } -void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket& recvData) +void WorldSession::HandleDoReadyCheckOpcode(WorldPackets::Party::DoReadyCheck& packet) { 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(SMSG_READY_CHECK_STARTED, 8); - data << GetPlayer()->GetGUID(); - group->BroadcastPacket(&data, false, -1); + /** error handling **/ + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + /********************/ - group->OfflineReadyCheck(); - } - else // answer - { - uint8 state; - recvData >> state; - - // everything's fine, do it - WorldPacket data(SMSG_READY_CHECK_RESPONSE, 9); - data << GetPlayer()->GetGUID(); - data << uint8(state); - group->BroadcastReadyCheck(&data); - } + // everything's fine, do it + group->StartReadyCheck(GetPlayer()->GetGUID(), packet.PartyIndex); } -void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data) +void WorldSession::HandleReadyCheckResponseOpcode(WorldPackets::Party::ReadyCheckResponseClient& packet) { - uint32 mask = player->GetGroupUpdateFlag(); - - if (mask == GROUP_UPDATE_FLAG_NONE) + Group* group = GetPlayer()->GetGroup(); + if (!group) return; - std::set const& phases = player->GetPhases(); - - if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also - mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); - - if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets - mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); - - data->Initialize(SMSG_PARTY_MEMBER_STATE, 80); // average value - *data << player->GetPackGUID(); - *data << uint32(mask); - - if (mask & GROUP_UPDATE_FLAG_STATUS) - { - uint16 playerStatus = MEMBER_STATUS_ONLINE; - if (player->IsPvP()) - playerStatus |= MEMBER_STATUS_PVP; - - if (!player->IsAlive()) - { - if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - playerStatus |= MEMBER_STATUS_GHOST; - else - playerStatus |= MEMBER_STATUS_DEAD; - } - - if (player->IsFFAPvP()) - playerStatus |= MEMBER_STATUS_PVP_FFA; - - if (player->isAFK()) - playerStatus |= MEMBER_STATUS_AFK; - - if (player->isDND()) - playerStatus |= MEMBER_STATUS_DND; - - *data << uint16(playerStatus); - } - - if (mask & GROUP_UPDATE_FLAG_CUR_HP) - *data << uint32(player->GetHealth()); - - if (mask & GROUP_UPDATE_FLAG_MAX_HP) - *data << uint32(player->GetMaxHealth()); - - Powers powerType = player->getPowerType(); - if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) - *data << uint8(powerType); - - if (mask & GROUP_UPDATE_FLAG_CUR_POWER) - *data << uint16(player->GetPower(powerType)); - - if (mask & GROUP_UPDATE_FLAG_MAX_POWER) - *data << uint16(player->GetMaxPower(powerType)); - - if (mask & GROUP_UPDATE_FLAG_LEVEL) - *data << uint16(player->getLevel()); - - if (mask & GROUP_UPDATE_FLAG_ZONE) - *data << uint16(player->GetZoneId()); - - if (mask & GROUP_UPDATE_FLAG_UNK100) - *data << uint16(0); - - if (mask & GROUP_UPDATE_FLAG_POSITION) - { - *data << uint16(player->GetPositionX()); - *data << uint16(player->GetPositionY()); - *data << uint16(player->GetPositionZ()); - } - - if (mask & GROUP_UPDATE_FLAG_AURAS) - { - *data << uint8(0); - uint64 auramask = player->GetAuraUpdateMaskForRaid(); - *data << uint64(auramask); - *data << uint32(MAX_AURAS); // count - for (uint32 i = 0; i < MAX_AURAS; ++i) - { - if (auramask & (uint64(1) << i)) - { - AuraApplication const* aurApp = player->GetVisibleAura(i); - if (!aurApp) - { - *data << uint32(0); - *data << uint16(0); - continue; - } - - *data << uint32(aurApp->GetBase()->GetId()); - *data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - *data << int32(eff->GetAmount()); - else - *data << int32(0); - } - } - } - } - } - - Pet* pet = player->GetPet(); - if (mask & GROUP_UPDATE_FLAG_PET_GUID) - { - if (pet) - *data << pet->GetGUID(); - else - *data << ObjectGuid::Empty; - } - - if (mask & GROUP_UPDATE_FLAG_PET_NAME) - { - if (pet) - *data << pet->GetName(); - else - *data << uint8(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) - { - if (pet) - *data << uint16(pet->GetDisplayId()); - else - *data << uint16(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) - { - if (pet) - *data << uint32(pet->GetHealth()); - else - *data << uint32(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) - { - if (pet) - *data << uint32(pet->GetMaxHealth()); - else - *data << uint32(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) - { - if (pet) - *data << uint8(pet->getPowerType()); - else - *data << uint8(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) - { - if (pet) - *data << uint16(pet->GetPower(pet->getPowerType())); - else - *data << uint16(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) - { - if (pet) - *data << uint16(pet->GetMaxPower(pet->getPowerType())); - else - *data << uint16(0); - } - - if (mask & GROUP_UPDATE_FLAG_PET_AURAS) - { - if (pet) - { - *data << uint8(0); - uint64 auramask = pet->GetAuraUpdateMaskForRaid(); - *data << uint64(auramask); - *data << uint32(MAX_AURAS); // count - for (uint32 i = 0; i < MAX_AURAS; ++i) - { - if (auramask & (uint64(1) << i)) - { - AuraApplication const* aurApp = pet->GetVisibleAura(i); - if (!aurApp) - { - *data << uint32(0); - *data << uint16(0); - continue; - } - - *data << uint32(aurApp->GetBase()->GetId()); - *data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - *data << int32(eff->GetAmount()); - else - *data << int32(0); - } - } - } - } - } - else - { - *data << uint8(0); - *data << uint64(0); - } - } - - if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) - { - if (Vehicle* veh = player->GetVehicle()) - *data << uint32(veh->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]); - else - *data << uint32(0); - - } - - if (mask & GROUP_UPDATE_FLAG_PHASE) - { - *data << uint32(phases.empty() ? 8 : 0); - *data << uint32(phases.size()); - for (std::set::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - *data << uint16(*itr); - } + // everything's fine, do it + group->SetMemberReadyCheck(GetPlayer()->GetGUID(), packet.IsReady); } -/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ -void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) +void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPackets::Party::RequestPartyMemberStats& packet) { - ObjectGuid Guid; - recvData >> Guid; + WorldPackets::Party::PartyMemberStats partyMemberStats; - Player* player = ObjectAccessor::FindConnectedPlayer(Guid); + Player* player = ObjectAccessor::FindConnectedPlayer(packet.TargetGUID); if (!player) { - WorldPacket data(SMSG_PARTY_MEMBER_STATE, 3 + 4 + 2); - data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related - data << Guid.WriteAsPacked(); - data << uint32(GROUP_UPDATE_FLAG_STATUS); - data << uint16(MEMBER_STATUS_OFFLINE); - SendPacket(&data); - return; - } - - Pet* pet = player->GetPet(); - Powers powerType = player->getPowerType(); - std::set const& phases = player->GetPhases(); - - WorldPacket data(SMSG_PARTY_MEMBER_STATE, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); - data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related - data << player->GetPackGUID(); - - uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP - | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL - | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS - | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; - - if (powerType != POWER_MANA) - updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; - - if (pet) - updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP - | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; - - if (player->GetVehicle()) - updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; - - if (!phases.empty()) - updateFlags |= GROUP_UPDATE_FLAG_PHASE; - - uint16 playerStatus = MEMBER_STATUS_ONLINE; - if (player->IsPvP()) - playerStatus |= MEMBER_STATUS_PVP; - - if (!player->IsAlive()) - { - if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - playerStatus |= MEMBER_STATUS_GHOST; - else - playerStatus |= MEMBER_STATUS_DEAD; - } - - if (player->IsFFAPvP()) - playerStatus |= MEMBER_STATUS_PVP_FFA; - - if (player->isAFK()) - playerStatus |= MEMBER_STATUS_AFK; - - if (player->isDND()) - playerStatus |= MEMBER_STATUS_DND; - - data << uint32(updateFlags); - data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS - data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP - data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP - if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) - data << uint8(powerType); - - data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER - data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER - data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL - data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE - data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION - data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION - data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION - - // GROUP_UPDATE_FLAG_AURAS - data << uint8(1); - uint64 auramask = 0; - size_t maskPos = data.wpos(); - data << uint64(auramask); // placeholder - data << uint32(MAX_AURAS); // count - - for (uint8 i = 0; i < MAX_AURAS; ++i) - { - if (AuraApplication const* aurApp = player->GetVisibleAura(i)) - { - auramask |= (uint64(1) << i); - - data << uint32(aurApp->GetBase()->GetId()); - data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - data << int32(eff->GetAmount()); - else - data << int32(0); - } - } - } - } - - data.put(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS - - if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) - data << pet->GetGUID(); - - data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME - data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID - - if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) - data << uint32(pet->GetHealth()); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) - data << uint32(pet->GetMaxHealth()); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) - data << (uint8)pet->getPowerType(); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) - data << uint16(pet->GetPower(pet->getPowerType())); - - if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) - data << uint16(pet->GetMaxPower(pet->getPowerType())); - - // GROUP_UPDATE_FLAG_PET_AURAS - uint64 petAuraMask = 0; - data << uint8(1); - maskPos = data.wpos(); - data << uint64(petAuraMask); // placeholder - data << uint32(MAX_AURAS); // count - if (pet) - { - for (uint8 i = 0; i < MAX_AURAS; ++i) - { - if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) - { - petAuraMask |= (uint64(1) << i); - - data << uint32(aurApp->GetBase()->GetId()); - data << uint16(aurApp->GetFlags()); - - if (aurApp->GetFlags() & AFLAG_SCALABLE) - { - for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) - data << int32(eff->GetAmount()); - else - data << int32(0); - } - } - } - } - } - - data.put(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS - - if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) - data << uint32(player->GetVehicle()->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]); - - if (updateFlags & GROUP_UPDATE_FLAG_PHASE) - { - data << uint32(phases.empty() ? 8 : 0); - data << uint32(phases.size()); - for (std::set::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - data << uint16(*itr); + partyMemberStats.MemberStats.GUID = packet.TargetGUID; + partyMemberStats.MemberStats.Status = MEMBER_STATUS_OFFLINE; } + else + partyMemberStats.Initialize(player); - SendPacket(&data); + SendPacket(partyMemberStats.Write()); } -void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket& /*recvData*/) +void WorldSession::HandleRequestRaidInfoOpcode(WorldPackets::Party::RequestRaidInfo& /*packet*/) { // every time the player checks the character screen _player->SendRaidInfo(); } -void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData) +void WorldSession::HandleOptOutOfLootOpcode(WorldPackets::Party::OptOutOfLoot& packet) { - bool passOnLoot; - recvData >> passOnLoot; // 1 always pass, 0 do not pass - // ignore if player not loaded if (!GetPlayer()) // needed because STATUS_AUTHED { - if (passOnLoot) + if (packet.PassOnLoot) TC_LOG_ERROR("network", "CMSG_OPT_OUT_OF_LOOT value<>0 for not-loaded character!"); return; } - GetPlayer()->SetPassOnGroupLoot(passOnLoot != 0); + GetPlayer()->SetPassOnGroupLoot(packet.PassOnLoot); } -void WorldSession::HandleRolePollBeginOpcode(WorldPacket& recvData) +void WorldSession::HandleInitiateRolePoll(WorldPackets::Party::InitiateRolePoll& packet) { Group* group = GetPlayer()->GetGroup(); if (!group) return; - if (recvData.empty()) - { - if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) - return; + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; - ObjectGuid guid = GetPlayer()->GetGUID(); - - WorldPacket data(SMSG_ROLE_POLL_INFORM, 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); - } + ObjectGuid guid = GetPlayer()->GetGUID(); + + WorldPackets::Party::RolePollInform rolePollInform; + rolePollInform.From = GetPlayer()->GetGUID(); + rolePollInform.PartyIndex = packet.PartyIndex; + group->BroadcastPacket(rolePollInform.Write(), 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); +} + +void WorldSession::HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& packet) +{ + Group* group = GetPlayer()->GetGroup(); + if (!group) + return; + + if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + return; + + group->DeleteRaidMarker(packet.MarkerId); } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index c4d3358a333..4a3866cbb1b 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -86,7 +86,7 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData) { if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) || (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() && - (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) + (GetPlayer()->GetGroup()->GetMembersCount() == MAX_GROUP_SIZE || !GetPlayer()->GetGroup()->isLFGGroup()))) { recvData.rfinish(); return; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 025bb45b42b..1715e1643ea 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1213,129 +1213,28 @@ void WorldSession::HandleObjectUpdateRescuedOpcode(WorldPackets::Misc::ObjectUpd _player->m_clientGUIDs.insert(objectUpdateRescued.ObjectGUID); } -void WorldSession::HandleSaveCUFProfiles(WorldPacket& recvPacket) +void WorldSession::HandleSaveCUFProfiles(WorldPackets::Misc::SaveCUFProfiles& packet) { - uint8 count = (uint8)recvPacket.ReadBits(20); - - if (count > MAX_CUF_PROFILES) + if (packet.CUFProfiles.size() > MAX_CUF_PROFILES) { TC_LOG_ERROR("entities.player", "HandleSaveCUFProfiles - %s tried to save more than %i CUF profiles. Hacking attempt?", GetPlayerName().c_str(), MAX_CUF_PROFILES); - recvPacket.rfinish(); return; } - CUFProfile* profiles[MAX_CUF_PROFILES]; - uint8 strlens[MAX_CUF_PROFILES]; - - for (uint8 i = 0; i < count; ++i) - { - profiles[i] = new CUFProfile; - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_2 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_10_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_UNK_157 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_HEAL_PREDICTION , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_1 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVP , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_POWER_BAR , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_15_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_40_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_PETS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_5_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS, recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_2_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_UNK_156 , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_NON_BOSS_DEBUFFS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_MAIN_TANK_AND_ASSIST , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_AGGRO_HIGHLIGHT , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_3_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_BORDER , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_USE_CLASS_COLORS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_UNK_145 , recvPacket.ReadBit()); - strlens[i] = (uint8)recvPacket.ReadBits(8); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVE , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_DISPLAY_HORIZONTAL_GROUPS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_25_PLAYERS , recvPacket.ReadBit()); - profiles[i]->BoolOptions.set(CUF_KEEP_GROUPS_TOGETHER , recvPacket.ReadBit()); - } - - for (uint8 i = 0; i < count; ++i) - { - recvPacket >> profiles[i]->Unk146; - profiles[i]->ProfileName = recvPacket.ReadString(strlens[i]); - recvPacket >> profiles[i]->Unk152; - recvPacket >> profiles[i]->FrameHeight; - recvPacket >> profiles[i]->FrameWidth; - recvPacket >> profiles[i]->Unk150; - recvPacket >> profiles[i]->HealthText; - recvPacket >> profiles[i]->Unk147; - recvPacket >> profiles[i]->SortBy; - recvPacket >> profiles[i]->Unk154; - recvPacket >> profiles[i]->Unk148; - - GetPlayer()->SaveCUFProfile(i, profiles[i]); - } + for (uint8 i = 0; i < packet.CUFProfiles.size(); ++i) + GetPlayer()->SaveCUFProfile(i, std::move(packet.CUFProfiles[i])); - for (uint8 i = count; i < MAX_CUF_PROFILES; ++i) - GetPlayer()->SaveCUFProfile(i, NULL); + for (uint8 i = packet.CUFProfiles.size(); i < MAX_CUF_PROFILES; ++i) + GetPlayer()->SaveCUFProfile(i, nullptr); } void WorldSession::SendLoadCUFProfiles() { Player* player = GetPlayer(); - uint8 count = player->GetCUFProfilesCount(); + WorldPackets::Misc::LoadCUFProfiles loadCUFProfiles; - ByteBuffer byteBuffer(25 * count); - WorldPacket data(SMSG_LOAD_CUF_PROFILES, 5 * count + 25 * count); - - data.WriteBits(count, 20); - for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i) - { - CUFProfile* profile = player->GetCUFProfile(i); - if (!profile) - continue; - - data.WriteBit(profile->BoolOptions[CUF_UNK_157]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_10_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_5_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_25_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HEAL_PREDICTION]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVE]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HORIZONTAL_GROUPS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_40_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_3_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_AGGRO_HIGHLIGHT]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_BORDER]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_2_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_NON_BOSS_DEBUFFS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_MAIN_TANK_AND_ASSIST]); - data.WriteBit(profile->BoolOptions[CUF_UNK_156]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_2]); - data.WriteBit(profile->BoolOptions[CUF_USE_CLASS_COLORS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_POWER_BAR]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_1]); - data.WriteBits(profile->ProfileName.size(), 8); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS]); - data.WriteBit(profile->BoolOptions[CUF_KEEP_GROUPS_TOGETHER]); - data.WriteBit(profile->BoolOptions[CUF_UNK_145]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_15_PLAYERS]); - data.WriteBit(profile->BoolOptions[CUF_DISPLAY_PETS]); - data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVP]); - - byteBuffer << uint16(profile->Unk154); - byteBuffer << uint16(profile->FrameHeight); - byteBuffer << uint16(profile->Unk152); - byteBuffer << uint8(profile->Unk147); - byteBuffer << uint16(profile->Unk150); - byteBuffer << uint8(profile->Unk146); - byteBuffer << uint8(profile->HealthText); - byteBuffer << uint8(profile->SortBy); - byteBuffer << uint16(profile->FrameWidth); - byteBuffer << uint8(profile->Unk148); - byteBuffer.WriteString(profile->ProfileName); - } - - data.FlushBits(); - data.append(byteBuffer); - SendPacket(&data); + for (uint8 i = 0; i < MAX_CUF_PROFILES; i++) + loadCUFProfiles.CUFProfiles.push_back(player->GetCUFProfile(i)); + SendPacket(loadCUFProfiles.Write()); } diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 7f1782ea1f0..429d3565052 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -616,8 +616,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) pet->SetName(name); - if (pet->GetOwner()->GetGroup()) - pet->GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); + pet->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME); pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 3d2f60929fb..2d3090825da 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -281,8 +281,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast) caster = _player; } - // check known spell - if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellInfo->Id)) + // check known spell or raid marker spell (which not requires player to know it) + if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellInfo->Id) && !spellInfo->HasEffect(SPELL_EFFECT_CHANGE_RAID_MARKER)) return; // Check possible spell cast overrides diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index a2faa8cc0a0..fb1ac3cc62d 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -699,7 +699,7 @@ class Map : public GridRefManager { auto itr = _guidGenerators.find(high); if (itr == _guidGenerators.end()) - itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr>(new ObjectGuidGenerator()))).first; + itr = _guidGenerators.insert(std::make_pair(high, Trinity::make_unique>())).first; return *itr->second; } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index ed004c6174d..03cde264734 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -1113,7 +1113,7 @@ enum SpellEffectName SPELL_EFFECT_REPUTATION = 103, SPELL_EFFECT_SUMMON_OBJECT_SLOT1 = 104, SPELL_EFFECT_SUMMON_OBJECT_SLOT2 = 105, - SPELL_EFFECT_SUMMON_OBJECT_SLOT3 = 106, + SPELL_EFFECT_CHANGE_RAID_MARKER = 106, SPELL_EFFECT_SUMMON_OBJECT_SLOT4 = 107, SPELL_EFFECT_DISPEL_MECHANIC = 108, SPELL_EFFECT_RESURRECT_PET = 109, diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp index 260770e65fe..e3df4f5a15d 100644 --- a/src/server/game/Server/Packets/ChatPackets.cpp +++ b/src/server/game/Server/Packets/ChatPackets.cpp @@ -92,7 +92,7 @@ void WorldPackets::Chat::ChatMessageEmote::Read() Text = _worldPacket.ReadString(len); } -void WorldPackets::Chat::Chat::Initalize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, +void WorldPackets::Chat::Chat::Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId /*= 0*/, std::string channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string addonPrefix /*= ""*/) { // Clear everything because same packet can be used multiple times diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h index 5bc55952168..3bfac840ecc 100644 --- a/src/server/game/Server/Packets/ChatPackets.h +++ b/src/server/game/Server/Packets/ChatPackets.h @@ -151,7 +151,7 @@ namespace WorldPackets public: Chat() : ServerPacket(SMSG_CHAT, 100) { } - void Initalize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId = 0, std::string channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string addonPrefix = ""); + void Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId = 0, std::string channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string addonPrefix = ""); WorldPacket const* Write() override; uint8 SlashCmd = 0; ///< @see enum ChatMsg diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp index 50b2a66a8b8..db5bdcbd9e8 100644 --- a/src/server/game/Server/Packets/InstancePackets.cpp +++ b/src/server/game/Server/Packets/InstancePackets.cpp @@ -30,3 +30,29 @@ WorldPacket const* WorldPackets::Instance::UpdateInstanceOwnership::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Instance::InstanceInfo::Write() +{ + _worldPacket << int32(LockList.size()); + + for (InstanceLockInfos const& lockInfos : LockList) + _worldPacket << lockInfos; + + return &_worldPacket; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Instance::InstanceLockInfos const& lockInfos) +{ + data << lockInfos.MapID; + data << lockInfos.DifficultyID; + data << lockInfos.InstanceID; + data << lockInfos.TimeRemaining; + data << lockInfos.CompletedMask; + + data.WriteBit(lockInfos.Locked); + data.WriteBit(lockInfos.Extended); + + data.FlushBits(); + + return data; +} diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h index 09f6c1efdcb..e38bcb97462 100644 --- a/src/server/game/Server/Packets/InstancePackets.h +++ b/src/server/game/Server/Packets/InstancePackets.h @@ -46,7 +46,31 @@ namespace WorldPackets int32 IOwnInstance = 0; // Used to control whether "Reset all instances" button appears on the UI - Script_CanShowResetInstances() // but it has been deperecated in favor of simply checking group leader, being inside an instance or using dungeon finder }; + + struct InstanceLockInfos + { + uint64 InstanceID = 0u; + uint32 MapID = 0u; + uint32 DifficultyID = 0u; + int32 TimeRemaining = 0; + uint32 CompletedMask = 0u; + + bool Locked = false; + bool Extended = false; + }; + + class InstanceInfo final : public ServerPacket + { + public: + InstanceInfo() : ServerPacket(SMSG_INSTANCE_INFO, 4) { } + + WorldPacket const* Write() override; + + std::vector LockList; + }; } } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Instance::InstanceLockInfos const& lockInfos); + #endif // InstancePackets_h__ diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index a12ff537050..bbd3fcb2ba7 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -451,3 +451,72 @@ WorldPacket const* WorldPackets::Misc::Dismount::Write() return &_worldPacket; } + +void WorldPackets::Misc::SaveCUFProfiles::Read() +{ + uint32 count; + _worldPacket >> count; + + for (uint8 i = 0; i < count && i < MAX_CUF_PROFILES; i++) + { + std::unique_ptr cufProfile = Trinity::make_unique(); + + uint8 strLen = _worldPacket.ReadBits(7); + + // Bool Options + for (uint8 option = 0; option < CUF_BOOL_OPTIONS_COUNT; option++) + cufProfile->BoolOptions.set(option, _worldPacket.ReadBit()); + + // Other Options + _worldPacket >> cufProfile->FrameHeight; + _worldPacket >> cufProfile->FrameWidth; + + _worldPacket >> cufProfile->SortBy; + _worldPacket >> cufProfile->HealthText; + + _worldPacket >> cufProfile->TopPoint; + _worldPacket >> cufProfile->BottomPoint; + _worldPacket >> cufProfile->LeftPoint; + + _worldPacket >> cufProfile->TopOffset; + _worldPacket >> cufProfile->BottomOffset; + _worldPacket >> cufProfile->LeftOffset; + + cufProfile->ProfileName = _worldPacket.ReadString(strLen); + + CUFProfiles.push_back(std::move(cufProfile)); + } +} + +WorldPacket const* WorldPackets::Misc::LoadCUFProfiles::Write() +{ + _worldPacket << uint32(CUFProfiles.size()); + + for (CUFProfile const* cufProfile : CUFProfiles) + { + _worldPacket.WriteBits(cufProfile->ProfileName.size(), 7); + + // Bool Options + for (uint8 option = 0; option < CUF_BOOL_OPTIONS_COUNT; option++) + _worldPacket.WriteBit(cufProfile->BoolOptions[option]); + + // Other Options + _worldPacket << cufProfile->FrameHeight; + _worldPacket << cufProfile->FrameWidth; + + _worldPacket << cufProfile->SortBy; + _worldPacket << cufProfile->HealthText; + + _worldPacket << cufProfile->TopPoint; + _worldPacket << cufProfile->BottomPoint; + _worldPacket << cufProfile->LeftPoint; + + _worldPacket << cufProfile->TopOffset; + _worldPacket << cufProfile->BottomOffset; + _worldPacket << cufProfile->LeftOffset; + + _worldPacket.WriteString(cufProfile->ProfileName); + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index fda0e44990e..93bac0d208b 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -24,6 +24,7 @@ #include "G3D/Vector3.h" #include "Object.h" #include "Unit.h" +#include "Player.h" #include "Weather.h" namespace WorldPackets @@ -642,6 +643,26 @@ namespace WorldPackets ObjectGuid Guid; }; + + class SaveCUFProfiles final : public ClientPacket + { + public: + SaveCUFProfiles(WorldPacket&& packet) : ClientPacket(CMSG_SAVE_CUF_PROFILES, std::move(packet)) { } + + void Read() override; + + std::vector> CUFProfiles; + }; + + class LoadCUFProfiles final : public ServerPacket + { + public: + LoadCUFProfiles() : ServerPacket(SMSG_LOAD_CUF_PROFILES, 20) { } + + WorldPacket const* Write() override; + + std::vector CUFProfiles; + }; } } diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp new file mode 100644 index 00000000000..9696cb6a3fc --- /dev/null +++ b/src/server/game/Server/Packets/PartyPackets.cpp @@ -0,0 +1,716 @@ +/* + * Copyright (C) 2008-2015 TrinityCore + * + * 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 "PartyPackets.h" + +#include "Player.h" +#include "Pet.h" +#include "Vehicle.h" +#include "SpellAuras.h" +#include "SpellAuraEffects.h" + +WorldPacket const* WorldPackets::Party::PartyCommandResult::Write() +{ + _worldPacket.WriteBits(Name.size(), 9); + + _worldPacket.WriteBits(Command, 4); + _worldPacket.WriteBits(Result, 6); + + _worldPacket << ResultData; + _worldPacket << ResultGUID; + _worldPacket.WriteString(Name); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +void WorldPackets::Party::PartyInviteClient::Read() +{ + uint32 targetNameLen, targetRealmLen; + + _worldPacket >> PartyIndex; + _worldPacket >> ProposedRoles; + _worldPacket >> TargetGUID; + _worldPacket >> TargetCfgRealmID; + + targetNameLen = _worldPacket.ReadBits(9); + targetRealmLen = _worldPacket.ReadBits(9); + + TargetName = _worldPacket.ReadString(targetNameLen); + TargetRealm = _worldPacket.ReadString(targetRealmLen); +} + +WorldPacket const* WorldPackets::Party::PartyInvite::Write() +{ + // Order guessed + _worldPacket.WriteBit(CanAccept); + _worldPacket.WriteBit(MightCRZYou); + _worldPacket.WriteBit(MustBeBNetFriend); + _worldPacket.WriteBit(AllowMultipleRoles); + _worldPacket.WriteBit(IsXRealm); + + _worldPacket.WriteBits(InviterName.size(), 6); + + _worldPacket << InviterGUID; + _worldPacket << InviterBNetAccountId; + + _worldPacket << InviterVirtualRealmAddress; + _worldPacket << Unk1; + + _worldPacket.WriteBit(IsLocal); + _worldPacket.WriteBit(Unk2); + + _worldPacket.FlushBits(); + + _worldPacket.WriteBits(InviterRealmNameActual.size(), 8); + _worldPacket.WriteBits(InviterRealmNameNormalized.size(), 8); + _worldPacket.WriteString(InviterRealmNameActual); + _worldPacket.WriteString(InviterRealmNameNormalized); + + _worldPacket << ProposedRoles; + _worldPacket << int32(LfgSlots.size()); + _worldPacket << LfgCompletedMask; + + _worldPacket.WriteString(InviterName); + + for (int32 LfgSlot : LfgSlots) + _worldPacket << LfgSlot; + + return &_worldPacket; +} + +void WorldPackets::Party::PartyInvite::Initialize(Player* const inviter, int32 proposedRoles, bool canAccept) +{ + CanAccept = canAccept; + + InviterName = inviter->GetName(); + InviterGUID = inviter->GetGUID(); + InviterBNetAccountId = inviter->GetSession()->GetAccountGUID(); + + ProposedRoles = proposedRoles; + + std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index); + + InviterVirtualRealmAddress = GetVirtualRealmAddress(); + InviterRealmNameActual = realmName; + InviterRealmNameNormalized = realmName; +} + +void WorldPackets::Party::PartyInviteResponse::Read() +{ + _worldPacket >> PartyIndex; + + Accept = _worldPacket.ReadBit(); + + bool hasRolesDesired = _worldPacket.ReadBit(); + if (hasRolesDesired) + { + RolesDesired = boost::in_place(); + _worldPacket >> *RolesDesired; + } +} + +void WorldPackets::Party::PartyUninvite::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; + + uint8 reasonLen = _worldPacket.ReadBits(8); + Reason = _worldPacket.ReadString(reasonLen); +} + +WorldPacket const* WorldPackets::Party::GroupDecline::Write() +{ + _worldPacket.WriteBits(Name.length(), 9); + _worldPacket.FlushBits(); + _worldPacket.WriteString(Name); + + return &_worldPacket; +} + +void WorldPackets::Party::RequestPartyMemberStats::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; +} + +WorldPacket const* WorldPackets::Party::PartyMemberStats::Write() +{ + _worldPacket.WriteBit(ForEnemy); + + _worldPacket << MemberStats; + + return &_worldPacket; +} + +void WorldPackets::Party::SetPartyLeader::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; +} + +void WorldPackets::Party::SetRole::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> TargetGUID; + _worldPacket >> Role; +} + +WorldPacket const* WorldPackets::Party::RoleChangedInform::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << From; + _worldPacket << ChangedUnit; + _worldPacket << OldRole; + _worldPacket << NewRole; + + return &_worldPacket; +} + +void WorldPackets::Party::LeaveGroup::Read() +{ + _worldPacket >> PartyIndex; +} + +void WorldPackets::Party::SetLootMethod::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> LootMethod; + _worldPacket >> LootMasterGUID; + _worldPacket >> LootThreshold; +} + +void WorldPackets::Party::MinimapPingClient::Read() +{ + _worldPacket >> PositionX; + _worldPacket >> PositionY; + _worldPacket >> PartyIndex; +} + +WorldPacket const* WorldPackets::Party::MinimapPing::Write() +{ + _worldPacket << Sender; + _worldPacket << PositionX; + _worldPacket << PositionY; + + return &_worldPacket; +} + +void WorldPackets::Party::UpdateRaidTarget::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> Target; + _worldPacket >> Symbol; +} + +WorldPacket const* WorldPackets::Party::SendRaidTargetUpdateSingle::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << Symbol; + _worldPacket << Target; + _worldPacket << ChangedBy; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::SendRaidTargetUpdateAll::Write() +{ + _worldPacket << PartyIndex; + + _worldPacket << int32(TargetIcons.size()); + + std::map::const_iterator itr; + for (itr = TargetIcons.begin(); itr != TargetIcons.end(); itr++) + { + _worldPacket << itr->second; + _worldPacket << itr->first; + } + + return &_worldPacket; +} + +void WorldPackets::Party::ConvertRaid::Read() +{ + Raid = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::RequestPartyJoinUpdates::Read() +{ + _worldPacket >> PartyIndex; +} + +void WorldPackets::Party::SetAssistantLeader::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> Target; + Apply = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::DoReadyCheck::Read() +{ + _worldPacket >> PartyIndex; +} + +WorldPacket const* WorldPackets::Party::ReadyCheckStarted::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << PartyGUID; + _worldPacket << InitiatorGUID; + _worldPacket << Duration; + + return &_worldPacket; +} + +void WorldPackets::Party::ReadyCheckResponseClient::Read() +{ + _worldPacket >> PartyIndex; + IsReady = _worldPacket.ReadBit(); +} + +WorldPacket const* WorldPackets::Party::ReadyCheckResponse::Write() +{ + _worldPacket << PartyGUID; + _worldPacket << Player; + + _worldPacket.WriteBit(IsReady); + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::ReadyCheckCompleted::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << PartyGUID; + + return &_worldPacket; +} + +void WorldPackets::Party::OptOutOfLoot::Read() +{ + PassOnLoot = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::InitiateRolePoll::Read() +{ + _worldPacket >> PartyIndex; +} + +WorldPacket const* WorldPackets::Party::RolePollInform::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << From; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::GroupNewLeader::Write() +{ + _worldPacket << PartyIndex; + _worldPacket.WriteBits(Name.size(), 6); + _worldPacket.WriteString(Name); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Party::PartyUpdate::Write() +{ + _worldPacket << PartyType; + _worldPacket << PartyIndex; + _worldPacket << PartyFlags; + + _worldPacket << MyIndex; + _worldPacket << PartyGUID; + _worldPacket << SequenceNum; + _worldPacket << LeaderGUID; + + _worldPacket << PlayerList; + + _worldPacket.WriteBit(LfgInfos.is_initialized()); + _worldPacket.WriteBit(LootSettings.is_initialized()); + _worldPacket.WriteBit(DifficultySettings.is_initialized()); + + _worldPacket.FlushBits(); + + if (LfgInfos.is_initialized()) + _worldPacket << *LfgInfos; + + if (LootSettings.is_initialized()) + _worldPacket << *LootSettings; + + if (DifficultySettings.is_initialized()) + _worldPacket << *DifficultySettings; + + return &_worldPacket; +} + +void WorldPackets::Party::SetEveryoneIsAssistant::Read() +{ + _worldPacket >> PartyIndex; + EveryoneIsAssistant = _worldPacket.ReadBit(); +} + +void WorldPackets::Party::ChangeSubGroup::Read() +{ + _worldPacket >> TargetGUID; + _worldPacket >> PartyIndex; + _worldPacket >> NewSubGroup; +} + +void WorldPackets::Party::SwapSubGroups::Read() +{ + _worldPacket >> PartyIndex; + _worldPacket >> FirstTarget; + _worldPacket >> SecondTarget; +} + +void WorldPackets::Party::ClearRaidMarker::Read() +{ + _worldPacket >> MarkerId; +} + +WorldPacket const* WorldPackets::Party::RaidMarkersChanged::Write() +{ + _worldPacket << PartyIndex; + _worldPacket << ActiveMarkers; + + _worldPacket.WriteBits(RaidMarkers.size(), 4); + _worldPacket.FlushBits(); + + for (RaidMarker* raidMarker : RaidMarkers) + { + _worldPacket << raidMarker->TransportGUID; + _worldPacket << raidMarker->Location.GetMapId(); + _worldPacket << raidMarker->Location.PositionXYZStream(); + } + + return &_worldPacket; +} + +void WorldPackets::Party::PartyMemberStats::Initialize(Player const* player) +{ + ForEnemy = false; + + MemberStats.GUID = player->GetGUID(); + + // Status + MemberStats.Status = MEMBER_STATUS_ONLINE; + + if (player->IsPvP()) + MemberStats.Status |= MEMBER_STATUS_PVP; + + if (!player->IsAlive()) + { + if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + MemberStats.Status |= MEMBER_STATUS_GHOST; + else + MemberStats.Status |= MEMBER_STATUS_DEAD; + } + + if (player->IsFFAPvP()) + MemberStats.Status |= MEMBER_STATUS_PVP_FFA; + + if (player->isAFK()) + MemberStats.Status |= MEMBER_STATUS_AFK; + + if (player->isDND()) + MemberStats.Status |= MEMBER_STATUS_DND; + + // Level + MemberStats.Level = player->getLevel(); + + // Health + MemberStats.CurrentHealth = player->GetHealth(); + MemberStats.MaxHealth = player->GetMaxHealth(); + + // Power + MemberStats.PowerType = player->getPowerType(); + MemberStats.CurrentPower = player->GetPower(player->getPowerType()); + MemberStats.MaxPower = player->GetMaxPower(player->getPowerType()); + + // Position + MemberStats.ZoneID = player->GetZoneId(); + MemberStats.PositionX = int16(player->GetPositionX()); + MemberStats.PositionY = int16(player->GetPositionY()); + MemberStats.PositionZ = int16(player->GetPositionZ()); + + // Unk + MemberStats.Unk322 = 0; // Always 0 + MemberStats.Unk704[0] = 1; // Always 1 + MemberStats.Unk704[1] = 0; // Always 0 + MemberStats.Unk200000 = 0; // Always 0 + + MemberStats.Unk2000000 = 0; + MemberStats.Unk4000000 = 0; + + // Vehicle + if (player->GetVehicle() && player->GetVehicle()->GetVehicleInfo()) + MemberStats.VehicleSeat = player->GetVehicle()->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]; + + // Auras + for (uint8 i = 0; i < MAX_AURAS; ++i) + { + if (AuraApplication const* aurApp = player->GetVisibleAura(i)) + { + WorldPackets::Party::GroupAura aura; + + aura.SpellId = aurApp->GetBase()->GetId(); + aura.EffectMask = aurApp->GetEffectMask(); + aura.Scalings = aurApp->GetFlags(); // ?? + + if (aurApp->GetFlags() & AFLAG_SCALABLE) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + float scale = 0.f; + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + scale = float(eff->GetAmount()); + aura.EffectScales.push_back(scale); + } + } + + MemberStats.AuraList.push_back(aura); + } + } + + // Phases + std::set const& phases = player->GetPhases(); + MemberStats.Phases.PhaseShiftFlags = 0x08 | (phases.size() ? 0x10 : 0); + MemberStats.Phases.PersonalGUID = ObjectGuid::Empty; + for (uint32 phaseId : phases) + { + WorldPackets::Party::GroupPhase phase; + phase.Id = phaseId; + phase.Flags = 1; + MemberStats.Phases.List.push_back(phase); + } + + // Pet + if (player->GetPet()) + { + Pet* pet = player->GetPet(); + + MemberStats.PetStats = boost::in_place(); + + MemberStats.PetStats->GUID = pet->GetGUID(); + MemberStats.PetStats->Name = pet->GetName(); + MemberStats.PetStats->ModelId = pet->GetDisplayId(); + + MemberStats.PetStats->CurrentHealth = pet->GetHealth(); + MemberStats.PetStats->MaxHealth = pet->GetMaxHealth(); + + for (uint8 i = 0; i < MAX_AURAS; ++i) + { + if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) + { + WorldPackets::Party::GroupAura aura; + + aura.SpellId = aurApp->GetBase()->GetId(); + aura.EffectMask = aurApp->GetEffectMask(); + aura.Scalings = aurApp->GetFlags(); // ?? + + if (aurApp->GetFlags() & AFLAG_SCALABLE) + { + for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + float scale = 0.f; + if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) + scale = float(eff->GetAmount()); + aura.EffectScales.push_back(scale); + } + } + + MemberStats.PetStats->AuraList.push_back(aura); + } + } + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhase const& phase) +{ + data << phase.Flags; + data << phase.Id; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhases const& phases) +{ + data << phases.PhaseShiftFlags; + data << int32(phases.List.size()); + data << phases.PersonalGUID; + + for (WorldPackets::Party::GroupPhase const& phase : phases.List) + data << phase; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupAura const& aura) +{ + data << aura.SpellId; + data << aura.Scalings; + data << aura.EffectMask; + + data << int32(aura.EffectScales.size()); + for (float scale : aura.EffectScales) + data << scale; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, std::vector const& auraList) +{ + data << int32(auraList.size()); + for (WorldPackets::Party::GroupAura const& aura : auraList) + data << aura; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPetStats const& petStats) +{ + data << petStats.GUID; + + data << petStats.ModelId; + + data << petStats.CurrentHealth; + data << petStats.MaxHealth; + + data << petStats.AuraList; + + data.WriteBits(petStats.Name.size(), 8); + data.FlushBits(); + data.WriteString(petStats.Name); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupMemberStats const& memberStats) +{ + data << memberStats.GUID; + + for (uint8 i = 0; i < 2; i++) + data << memberStats.Unk704[i]; + + data << memberStats.Status; + + data << memberStats.PowerType; + + data << memberStats.Unk322; + + data << memberStats.CurrentHealth; + data << memberStats.MaxHealth; + + data << memberStats.CurrentPower; + data << memberStats.MaxPower; + + data << memberStats.Level; + + data << memberStats.Unk200000; + + data << memberStats.ZoneID; + + data << memberStats.Unk2000000; + data << memberStats.Unk4000000; + + data << memberStats.PositionX; + data << memberStats.PositionY; + data << memberStats.PositionZ; + + data << memberStats.VehicleSeat; + + data << int32(memberStats.AuraList.size()); + + data << memberStats.Phases; + + for (WorldPackets::Party::GroupAura const& aura : memberStats.AuraList) + data << aura; + + data.WriteBit(memberStats.PetStats.is_initialized()); + data.FlushBits(); + + if (memberStats.PetStats.is_initialized()) + data << *memberStats.PetStats; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, std::vector const& playerList) +{ + data << int32(playerList.size()); + + for (WorldPackets::Party::GroupPlayerInfos const& playerInfos : playerList) + data << playerInfos; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPlayerInfos const& playerInfos) +{ + data.WriteBits(playerInfos.Name.size(), 6); + data.FlushBits(); + + data << playerInfos.GUID; + data << playerInfos.Status; + data << playerInfos.Subgroup; + data << playerInfos.Flags; + data << playerInfos.RolesAssigned; + data << playerInfos.Class; + + data.WriteString(playerInfos.Name); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLfgInfos const& lfgInfos) +{ + data << lfgInfos.MyFlags; + data << lfgInfos.Slot; + data << lfgInfos.MyRandomSlot; + data << lfgInfos.MyPartialClear; + data << lfgInfos.MyGearDiff; + data << lfgInfos.MyStrangerCount; + data << lfgInfos.MyKickVoteCount; + data << lfgInfos.BootCount; + + data.WriteBit(lfgInfos.Aborted); + data.WriteBit(lfgInfos.MyFirstReward); + data.FlushBits(); + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLootSettings const& lootSettings) +{ + data << lootSettings.Method; + data << lootSettings.LootMaster; + data << lootSettings.Threshold; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupDifficultySettings const& difficultySettings) +{ + data << difficultySettings.DungeonDifficultyID; + data << difficultySettings.RaidDifficultyID; + data << difficultySettings.LegacyRaidDifficultyID; + + return data; +} diff --git a/src/server/game/Server/Packets/PartyPackets.h b/src/server/game/Server/Packets/PartyPackets.h new file mode 100644 index 00000000000..ed3eed60ef4 --- /dev/null +++ b/src/server/game/Server/Packets/PartyPackets.h @@ -0,0 +1,616 @@ +/* + * Copyright (C) 2008-2015 TrinityCore + * + * 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 . + */ + +#ifndef PartyPackets_h__ +#define PartyPackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" +#include "Group.h" + +namespace WorldPackets +{ + namespace Party + { + class PartyCommandResult final : public ServerPacket + { + public: + PartyCommandResult() : ServerPacket(SMSG_PARTY_COMMAND_RESULT, 23) { } + + WorldPacket const* Write() override; + + std::string Name; + uint8 Command = 0u; + uint8 Result = 0u; + uint32 ResultData = 0u; + ObjectGuid ResultGUID; + }; + + class PartyInviteClient final : public ClientPacket + { + public: + PartyInviteClient(WorldPacket&& packet) : ClientPacket(CMSG_PARTY_INVITE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + int32 ProposedRoles = 0; + int32 TargetCfgRealmID = 0; + std::string TargetName; + std::string TargetRealm; + ObjectGuid TargetGUID; + }; + + class PartyInvite final : public ServerPacket + { + public: + PartyInvite() : ServerPacket(SMSG_PARTY_INVITE, 55) { } + + WorldPacket const* Write() override; + void Initialize(Player* const inviter, int32 proposedRoles, bool canAccept); + + bool MightCRZYou = false; + bool MustBeBNetFriend = false; + bool AllowMultipleRoles = false; + bool Unk2 = false; + int16 Unk1 = 0; + + bool CanAccept = false; + + // Inviter + ObjectGuid InviterGUID; + ObjectGuid InviterBNetAccountId; + std::string InviterName; + + // Realm + bool IsXRealm = false; + bool IsLocal = true; + uint32 InviterVirtualRealmAddress = 0u; + std::string InviterRealmNameActual; + std::string InviterRealmNameNormalized; + + // Lfg + int32 ProposedRoles = 0; + int32 LfgCompletedMask = 0; + std::vector LfgSlots; + }; + + class PartyInviteResponse final : public ClientPacket + { + public: + PartyInviteResponse(WorldPacket&& packet) : ClientPacket(CMSG_PARTY_INVITE_RESPONSE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + bool Accept = false; + Optional RolesDesired; + }; + + class PartyUninvite final : public ClientPacket + { + public: + PartyUninvite(WorldPacket&& packet) : ClientPacket(CMSG_PARTY_UNINVITE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + std::string Reason; + }; + + class GroupDecline final : public ServerPacket + { + public: + GroupDecline(std::string const& name) : ServerPacket(SMSG_GROUP_DECLINE, 2 + name.size()), Name(name) { } + + WorldPacket const* Write() override; + + std::string Name; + }; + + class RequestPartyMemberStats final : public ClientPacket + { + public: + RequestPartyMemberStats(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PARTY_MEMBER_STATS, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + }; + + struct GroupPhase + { + uint16 Flags = 0u; + uint16 Id = 0u; + }; + + struct GroupPhases + { + int32 PhaseShiftFlags = 0; + ObjectGuid PersonalGUID; + std::vector List; + }; + + struct GroupAura + { + uint32 SpellId = 0u; + uint8 Scalings = 0; + uint32 EffectMask = 0u; + std::vector EffectScales; + }; + + struct GroupPetStats + { + ObjectGuid GUID; + std::string Name; + int16 ModelId = 0; + + int32 CurrentHealth = 0; + int32 MaxHealth = 0; + + std::vector AuraList; + }; + + struct GroupMemberStats + { + ObjectGuid GUID; + int16 Level = 0; + int16 Status = 0; + + int32 CurrentHealth = 0; + int32 MaxHealth; + + uint8 PowerType = 0u; + int16 CurrentPower = 0; + int16 MaxPower = 0; + + int16 ZoneID = 0; + int16 PositionX = 0; + int16 PositionY = 0; + int16 PositionZ = 0; + + int32 VehicleSeat = 0; + + GroupPhases Phases; + std::vector AuraList; + Optional PetStats; + + int16 Unk322 = 0; + int16 Unk200000 = 0; + int16 Unk2000000 = 0; + int32 Unk4000000 = 0; + int8 Unk704[2]; + }; + + class PartyMemberStats final : public ServerPacket + { + public: + PartyMemberStats() : ServerPacket(SMSG_PARTY_MEMBER_STATE, 80) { } + + WorldPacket const* Write() override; + void Initialize(Player const* player); + + GroupMemberStats MemberStats; + bool ForEnemy = false; + }; + + class SetPartyLeader final : public ClientPacket + { + public: + SetPartyLeader(WorldPacket&& packet) : ClientPacket(CMSG_SET_PARTY_LEADER, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + }; + + class SetRole final : public ClientPacket + { + public: + SetRole(WorldPacket&& packet) : ClientPacket(CMSG_SET_ROLE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid TargetGUID; + int32 Role = 0; + }; + + class RoleChangedInform final : public ServerPacket + { + public: + RoleChangedInform() : ServerPacket(SMSG_ROLE_CHANGED_INFORM, 41) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid From; + ObjectGuid ChangedUnit; + int32 OldRole = 0; + int32 NewRole = 0; + }; + + class LeaveGroup final : public ClientPacket + { + public: + LeaveGroup(WorldPacket&& packet) : ClientPacket(CMSG_LEAVE_GROUP, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class SetLootMethod final : public ClientPacket + { + public: + SetLootMethod(WorldPacket&& packet) : ClientPacket(CMSG_SET_LOOT_METHOD, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid LootMasterGUID; + uint8 LootMethod = 0u; + uint32 LootThreshold = 0u; + }; + + class MinimapPingClient final : public ClientPacket + { + public: + MinimapPingClient(WorldPacket&& packet) : ClientPacket(CMSG_MINIMAP_PING, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + float PositionX = 0.f; + float PositionY = 0.f; + }; + + class MinimapPing final : public ServerPacket + { + public: + MinimapPing() : ServerPacket(SMSG_MINIMAP_PING, 24) { } + + WorldPacket const* Write() override; + + ObjectGuid Sender; + float PositionX = 0.f; + float PositionY = 0.f; + }; + + class UpdateRaidTarget final : public ClientPacket + { + public: + UpdateRaidTarget(WorldPacket&& packet) : ClientPacket(CMSG_UPDATE_RAID_TARGET, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + ObjectGuid Target; + int8 Symbol = 0; + }; + + class SendRaidTargetUpdateSingle final : public ServerPacket + { + public: + SendRaidTargetUpdateSingle() : ServerPacket(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, 34) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid Target; + ObjectGuid ChangedBy; + int8 Symbol = 0; + }; + + class SendRaidTargetUpdateAll final : public ServerPacket + { + public: + SendRaidTargetUpdateAll() : ServerPacket(SMSG_SEND_RAID_TARGET_UPDATE_ALL, 1 + TARGET_ICONS_COUNT * (1 + 16)) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + std::map TargetIcons; + }; + + class ConvertRaid final : public ClientPacket + { + public: + ConvertRaid(WorldPacket&& packet) : ClientPacket(CMSG_CONVERT_RAID, std::move(packet)) { } + + void Read() override; + + bool Raid = false; + }; + + class RequestPartyJoinUpdates final : public ClientPacket + { + public: + RequestPartyJoinUpdates(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PARTY_JOIN_UPDATES, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class SetAssistantLeader final : public ClientPacket + { + public: + SetAssistantLeader(WorldPacket&& packet) : ClientPacket(CMSG_SET_ASSISTANT_LEADER, std::move(packet)) { } + + void Read() override; + + ObjectGuid Target; + int8 PartyIndex = 0; + bool Apply = false; + }; + + class DoReadyCheck final : public ClientPacket + { + public: + DoReadyCheck(WorldPacket&& packet) : ClientPacket(CMSG_DO_READY_CHECK, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class ReadyCheckStarted final : public ServerPacket + { + public: + ReadyCheckStarted() : ServerPacket(SMSG_READY_CHECK_STARTED, 37) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid PartyGUID; + ObjectGuid InitiatorGUID; + uint32 Duration = 0u; + }; + + class ReadyCheckResponseClient final : public ClientPacket + { + public: + ReadyCheckResponseClient(WorldPacket&& packet) : ClientPacket(CMSG_READY_CHECK_RESPONSE, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + bool IsReady = false; + }; + + class ReadyCheckResponse final : public ServerPacket + { + public: + ReadyCheckResponse() : ServerPacket(SMSG_READY_CHECK_RESPONSE, 19) { } + + WorldPacket const* Write() override; + + ObjectGuid PartyGUID; + ObjectGuid Player; + bool IsReady = false; + }; + + class ReadyCheckCompleted final : public ServerPacket + { + public: + ReadyCheckCompleted() : ServerPacket(SMSG_READY_CHECK_COMPLETED, 17) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid PartyGUID; + }; + + class RequestRaidInfo final : public ClientPacket + { + public: + RequestRaidInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_RAID_INFO, std::move(packet)) { } + + void Read() override { } + }; + + class OptOutOfLoot final : public ClientPacket + { + public: + OptOutOfLoot(WorldPacket&& packet) : ClientPacket(CMSG_OPT_OUT_OF_LOOT, std::move(packet)) { } + + void Read() override; + + bool PassOnLoot = false; + }; + + class InitiateRolePoll final : public ClientPacket + { + public: + InitiateRolePoll(WorldPacket&& packet) : ClientPacket(CMSG_INITIATE_ROLE_POLL, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + }; + + class RolePollInform final : public ServerPacket + { + public: + RolePollInform() : ServerPacket(SMSG_ROLE_POLL_INFORM, 17) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + ObjectGuid From; + }; + + class GroupNewLeader final : public ServerPacket + { + public: + GroupNewLeader() : ServerPacket(SMSG_GROUP_NEW_LEADER, 14) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + std::string Name; + }; + + struct GroupPlayerInfos + { + ObjectGuid GUID; + std::string Name; + uint8 Class = 0; + + uint8 Status = 0u; + uint8 Subgroup = 0u; + uint8 Flags = 0u; + uint8 RolesAssigned = 0u; + }; + + struct GroupLfgInfos + { + int32 Slot = 0u; + int8 BootCount = 0; + + bool Aborted = false; + + int32 MyRandomSlot = 0; + uint8 MyFlags = 0u; + uint8 MyPartialClear = 0u; + float MyGearDiff = 0.f; + + int8 MyStrangerCount = 0; + int8 MyKickVoteCount = 0; + + bool MyFirstReward = false; + }; + + struct GroupLootSettings + { + uint8 Method = 0u; + ObjectGuid LootMaster; + uint8 Threshold = 0u; + }; + + struct GroupDifficultySettings + { + uint32 DungeonDifficultyID = 0u; + uint32 RaidDifficultyID = 0u; + uint32 LegacyRaidDifficultyID = 0u; + }; + + class PartyUpdate final : public ServerPacket + { + public: + PartyUpdate() : ServerPacket(SMSG_PARTY_UPDATE, 200) { } + + WorldPacket const* Write() override; + + int8 PartyFlags = 0; + int8 PartyIndex = 0; + int8 PartyType = 0; + + ObjectGuid PartyGUID; + ObjectGuid LeaderGUID; + + int32 MyIndex = 0; + int32 SequenceNum = 0; + + std::vector PlayerList; + + Optional LfgInfos; + Optional LootSettings; + Optional DifficultySettings; + }; + + class SetEveryoneIsAssistant final : public ClientPacket + { + public: + SetEveryoneIsAssistant(WorldPacket&& packet) : ClientPacket(CMSG_SET_EVERYONE_IS_ASSISTANT, std::move(packet)) { } + + void Read() override; + + int8 PartyIndex = 0; + bool EveryoneIsAssistant = false; + }; + + class ChangeSubGroup final : public ClientPacket + { + public: + ChangeSubGroup(WorldPacket&& packet) : ClientPacket(CMSG_CHANGE_SUB_GROUP, std::move(packet)) { } + + void Read() override; + + ObjectGuid TargetGUID; + int8 PartyIndex = 0; + uint8 NewSubGroup = 0u; + }; + + class SwapSubGroups final : public ClientPacket + { + public: + SwapSubGroups(WorldPacket&& packet) : ClientPacket(CMSG_SWAP_SUB_GROUPS, std::move(packet)) { } + + void Read() override; + + ObjectGuid FirstTarget; + ObjectGuid SecondTarget; + int8 PartyIndex = 0; + }; + + class ClearRaidMarker final : public ClientPacket + { + public: + ClearRaidMarker(WorldPacket&& packet) : ClientPacket(CMSG_CLEAR_RAID_MARKER, std::move(packet)) { } + + void Read() override; + + uint8 MarkerId = 0u; + }; + + class RaidMarkersChanged final : public ServerPacket + { + public: + RaidMarkersChanged() : ServerPacket(SMSG_RAID_MARKERS_CHANGED, 6) { } + + WorldPacket const* Write() override; + + int8 PartyIndex = 0; + uint32 ActiveMarkers = 0u; + + std::vector RaidMarkers; + }; + } +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhase const& phase); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPhases const& phases); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupAura const& aura); +ByteBuffer& operator<<(ByteBuffer& data, std::vector const& auraList); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPetStats const& petStats); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupMemberStats const& memberStats); + +ByteBuffer& operator<<(ByteBuffer& data, std::vector const& playerList); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupPlayerInfos const& playerInfos); + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLfgInfos const& lfgInfos); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupLootSettings const& lootSettings); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Party::GroupDifficultySettings const& difficultySettings); + +#endif // PartyPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 4c87e00fc91..9b30be91ee3 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -33,6 +33,7 @@ #include "Packets/GameObjectPackets.h" #include "Packets/GarrisonPackets.h" #include "Packets/GuildPackets.h" +#include "Packets/PartyPackets.h" #include "Packets/InspectPackets.h" #include "Packets/InstancePackets.h" #include "Packets/ItemPackets.h" @@ -259,7 +260,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHALLENGE_MODE_REQUEST_MAP_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHANGE_BAG_SLOT_FLAG, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHANGE_MONUMENT_APPEARANCE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANGE_SUB_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupChangeSubGroupOpcode ); + DEFINE_HANDLER(CMSG_CHANGE_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ChangeSubGroup, &WorldSession::HandleChangeSubGroupOpcode); DEFINE_HANDLER(CMSG_CHARACTER_RENAME_REQUEST, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharacterRenameRequest, &WorldSession::HandleCharRenameOpcode); DEFINE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharCustomize, &WorldSession::HandleCharCustomizeOpcode); DEFINE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CharDelete, &WorldSession::HandleCharDeleteOpcode); @@ -315,7 +316,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_CHECK_RAF_EMAIL_ENABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHECK_WOW_TOKEN_VETERAN_ELIGIBILITY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_CHOICE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::ClearRaidMarker, &WorldSession::HandleClearRaidMarker); DEFINE_HANDLER(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::ClearTradeItem, &WorldSession::HandleClearTradeItemOpcode); DEFINE_HANDLER(CMSG_CLIENT_PORT_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::PortGraveyard, &WorldSession::HandlePortGraveyard); DEFINE_HANDLER(CMSG_CLOSE_INTERACTION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -331,7 +332,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_COMPLETE_MOVIE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_CONFIRM_RESPEC_WIPE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleConfirmRespecWipeOpcode ); DEFINE_HANDLER(CMSG_CONNECT_TO_FAILED, STATUS_NEVER, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); - DEFINE_OPCODE_HANDLER_OLD(CMSG_CONVERT_RAID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupRaidConvertOpcode ); + DEFINE_HANDLER(CMSG_CONVERT_RAID, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ConvertRaid, &WorldSession::HandleConvertRaidOpcode); DEFINE_HANDLER(CMSG_CREATE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::CreateCharacter, &WorldSession::HandleCharCreateOpcode); DEFINE_HANDLER(CMSG_CREATE_SHIPMENT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk); @@ -357,7 +358,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_DISCARDED_TIME_SYNC_ACKS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_DISMISS_CRITTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter ); DEFINE_HANDLER(CMSG_DO_MASTER_LOOT_ROLL, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_DO_READY_CHECK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode ); + DEFINE_HANDLER(CMSG_DO_READY_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::DoReadyCheck, &WorldSession::HandleDoReadyCheckOpcode); DEFINE_HANDLER(CMSG_DUEL_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Duel::DuelResponse, &WorldSession::HandleDuelResponseOpcode); DEFINE_HANDLER(CMSG_EJECT_PASSENGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::EjectPassenger, &WorldSession::HandleEjectPassenger); DEFINE_HANDLER(CMSG_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::EmoteClient, &WorldSession::HandleEmoteOpcode); @@ -458,7 +459,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_HEARTH_AND_RESURRECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battleground::HearthAndResurrect, &WorldSession::HandleHearthAndResurrect); DEFINE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::IgnoreTrade, &WorldSession::HandleIgnoreTradeOpcode); DEFINE_HANDLER(CMSG_INCREASE_CAST_TIME_FOR_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_INITIATE_ROLE_POLL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRolePollBeginOpcode); + DEFINE_HANDLER(CMSG_INITIATE_ROLE_POLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::InitiateRolePoll, &WorldSession::HandleInitiateRolePoll); DEFINE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::InitiateTrade, &WorldSession::HandleInitiateTradeOpcode); DEFINE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::Inspect, &WorldSession::HandleInspectOpcode); DEFINE_HANDLER(CMSG_INSPECT_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::InspectPVPRequest, &WorldSession::HandleInspectPVP); @@ -471,7 +472,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_KEYBOUND_OVERRIDE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LEARN_PET_SPECIALIZATION_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LEARN_TALENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Talent::LearnTalents, &WorldSession::HandleLearnTalentsOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_LEAVE_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupDisbandOpcode ); + DEFINE_HANDLER(CMSG_LEAVE_GROUP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::LeaveGroup, &WorldSession::HandleLeaveGroupOpcode); DEFINE_HANDLER(CMSG_LEAVE_PET_BATTLE_QUEUE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LFG_LIST_APPLY_TO_GROUP, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_LFG_LIST_CANCEL_APPLICATION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -514,7 +515,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MAIL_TAKE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeItem, &WorldSession::HandleMailTakeItem); DEFINE_HANDLER(CMSG_MAIL_TAKE_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::MailTakeMoney, &WorldSession::HandleMailTakeMoney); DEFINE_OPCODE_HANDLER_OLD(CMSG_MASTER_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIMAP_PING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode ); + DEFINE_HANDLER(CMSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::MinimapPingClient, &WorldSession::HandleMinimapPingOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_MISSILE_TRAJECTORY_COLLISION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition ); DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_MOUNT_SPECIAL_ANIM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode ); @@ -590,10 +591,10 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_OPEN_MISSION_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_OPEN_SHIPMENT_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_OPEN_TRADESKILL_NPC, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_OPT_OUT_OF_LOOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteResponseOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PARTY_UNINVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode ); + DEFINE_HANDLER(CMSG_OPT_OUT_OF_LOOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::OptOutOfLoot, &WorldSession::HandleOptOutOfLootOpcode); + DEFINE_HANDLER(CMSG_PARTY_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::PartyInviteClient, &WorldSession::HandlePartyInviteOpcode); + DEFINE_HANDLER(CMSG_PARTY_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::PartyInviteResponse, &WorldSession::HandlePartyInviteResponseOpcode); + DEFINE_HANDLER(CMSG_PARTY_UNINVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::PartyUninvite, &WorldSession::HandlePartyUninviteOpcode); DEFINE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionBuy, &WorldSession::HandlePetitionBuy); DEFINE_HANDLER(CMSG_PETITION_RENAME_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionRenameGuild, &WorldSession::HandlePetitionRenameGuild); DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList); @@ -655,7 +656,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_PUSH_RESULT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult ); DEFINE_HANDLER(CMSG_QUEUED_MESSAGES_END, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::RandomRollClient, &WorldSession::HandleRandomRollOpcode); - DEFINE_HANDLER(CMSG_READY_CHECK_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_READY_CHECK_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::ReadyCheckResponseClient, &WorldSession::HandleReadyCheckResponseOpcode); DEFINE_HANDLER(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::ReadItem, &WorldSession::HandleReadItem); DEFINE_HANDLER(CMSG_RECLAIM_CORPSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::ReclaimCorpse, &WorldSession::HandleReclaimCorpse); DEFINE_HANDLER(CMSG_RECRUIT_A_FRIEND, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -676,12 +677,12 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_REQUEST_GUILD_REWARDS_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Guild::RequestGuildRewardsList, &WorldSession::HandleRequestGuildRewardsList); DEFINE_HANDLER(CMSG_REQUEST_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Inspect::RequestHonorStats, &WorldSession::HandleRequestHonorStatsOpcode); DEFINE_HANDLER(CMSG_REQUEST_LFG_LIST_BLACKLIST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRequestJoinUpdates); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); + DEFINE_HANDLER(CMSG_REQUEST_PARTY_JOIN_UPDATES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestPartyJoinUpdates, &WorldSession::HandleRequestPartyJoinUpdates); + DEFINE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestPartyMemberStats, &WorldSession::HandleRequestPartyMemberStatsOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); DEFINE_HANDLER(CMSG_REQUEST_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::RequestPlayedTime, &WorldSession::HandlePlayedTime); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PVP_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestPvpReward ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_RAID_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode ); + DEFINE_HANDLER(CMSG_REQUEST_RAID_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::RequestRaidInfo, &WorldSession::HandleRequestRaidInfoOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_RATED_BATTLEFIELD_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRatedBattlefieldInfo); DEFINE_HANDLER(CMSG_REQUEST_RESEARCH_HISTORY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode ); @@ -695,7 +696,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_RESURRECT_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::ResurrectResponse, &WorldSession::HandleResurrectResponse); DEFINE_HANDLER(CMSG_REVERT_MONUMENT_APPEARANCE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_RIDE_VEHICLE_INTERACT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Vehicle::RideVehicleInteract, &WorldSession::HandleRideVehicleInteract); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SAVE_CUF_PROFILES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSaveCUFProfiles ); + DEFINE_HANDLER(CMSG_SAVE_CUF_PROFILES, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::SaveCUFProfiles, &WorldSession::HandleSaveCUFProfiles); DEFINE_HANDLER(CMSG_SAVE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::SaveEquipmentSet, &WorldSession::HandleEquipmentSetSave); DEFINE_HANDLER(CMSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Guild::SaveGuildEmblem, &WorldSession::HandleSaveGuildEmblem); DEFINE_HANDLER(CMSG_SCENE_PLAYBACK_CANCELED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Scenes::ScenePlaybackCanceled, &WorldSession::HandleScenePlaybackCanceled); @@ -716,7 +717,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Movement::SetActiveMover, &WorldSession::HandleSetActiveMoverOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel ); DEFINE_HANDLER(CMSG_SET_ADVANCED_COMBAT_LOGGING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupAssistantLeaderOpcode); + DEFINE_HANDLER(CMSG_SET_ASSISTANT_LEADER, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetAssistantLeader, &WorldSession::HandleSetAssistantLeaderOpcode); DEFINE_HANDLER(CMSG_SET_BACKPACK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_BANK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_BANK_BAG_SLOT_FLAG, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -724,22 +725,22 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SET_CURRENCY_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_DIFFICULTY_ID, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_DUNGEON_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetDungeonDifficulty, &WorldSession::HandleSetDungeonDifficultyOpcode); - DEFINE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetEveryoneIsAssistant, &WorldSession::HandleSetEveryoneIsAssistant); DEFINE_HANDLER(CMSG_SET_FACTION_AT_WAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetFactionAtWar, &WorldSession::HandleSetFactionAtWar); DEFINE_HANDLER(CMSG_SET_FACTION_INACTIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetFactionInactive, &WorldSession::HandleSetFactionInactiveOpcode); DEFINE_HANDLER(CMSG_SET_FACTION_NOT_AT_WAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::SetFactionNotAtWar, &WorldSession::HandleSetFactionNotAtWar); DEFINE_HANDLER(CMSG_SET_INSERT_ITEMS_LEFT_TO_RIGHT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_LFG_BONUS_FACTION_ID, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_LOOT_METHOD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMethodOpcode ); + DEFINE_HANDLER(CMSG_SET_LOOT_METHOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::SetLootMethod, &WorldSession::HandleSetLootMethodOpcode); DEFINE_HANDLER(CMSG_SET_LOOT_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PARTY_ASSIGNMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PARTY_LEADER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSetLeaderOpcode ); + DEFINE_HANDLER(CMSG_SET_PARTY_LEADER, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetPartyLeader, &WorldSession::HandleSetPartyLeaderOpcode); DEFINE_HANDLER(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames ); DEFINE_HANDLER(CMSG_SET_PREFERRED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_PVP, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetRaidDifficulty, &WorldSession::HandleSetRaidDifficultyOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ROLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSetRolesOpcode ); + DEFINE_HANDLER(CMSG_SET_ROLE, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetRole, &WorldSession::HandleSetRoleOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend ); DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetSelection, &WorldSession::HandleSetSelectionOpcode); DEFINE_HANDLER(CMSG_SET_SHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::SetSheathed, &WorldSession::HandleSetSheathedOpcode); @@ -775,7 +776,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapInvItem, &WorldSession::HandleSwapInvItemOpcode); DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem); - DEFINE_OPCODE_HANDLER_OLD(CMSG_SWAP_SUB_GROUPS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleGroupSwapSubGroupOpcode ); + DEFINE_HANDLER(CMSG_SWAP_SUB_GROUPS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SwapSubGroups, &WorldSession::HandleSwapSubGroupsOpcode); DEFINE_HANDLER(CMSG_SWAP_VOID_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::VoidStorage::SwapVoidItem, &WorldSession::HandleVoidSwapItem); DEFINE_HANDLER(CMSG_TABARD_VENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTabardVendorActivateOpcode); DEFINE_HANDLER(CMSG_TALK_TO_GOSSIP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleGossipHelloOpcode); @@ -809,7 +810,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData); DEFINE_HANDLER(CMSG_UPDATE_CLIENT_SETTINGS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_RAID_TARGET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode ); + DEFINE_HANDLER(CMSG_UPDATE_RAID_TARGET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::UpdateRaidTarget, &WorldSession::HandleUpdateRaidTargetOpcode); DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_AUCTIONABLE_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Token::UpdateListedAuctionableTokens, &WorldSession::HandleUpdateListedAuctionableTokens); DEFINE_HANDLER(CMSG_UPDATE_WOW_TOKEN_COUNT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_UPGRADE_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -1169,10 +1170,10 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_ACTION_THROTTLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_NEW_LEADER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_NEW_LEADER, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1248,7 +1249,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_ENCOUNTER_TIMER_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_GROUP_SIZE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1298,7 +1299,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_ACCOUNT_RESTORE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_CHARACTER_COPY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_GET_ACCOUNT_CHARACTER_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_EQUIPMENT_SET, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_SELECTED_TROPHY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SET_TIME_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -1327,7 +1328,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MASTER_LOOT_CANDIDATE_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_COMPONENTED_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_CREATURE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1431,11 +1432,11 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_SHIPMENT_NPC_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_INVITE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_KILL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PENDING_RAID_LOCK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1539,12 +1540,12 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_DIFFICULTY_SET, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RANDOM_ROLL, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BATTLEFIELD_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_STARTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_COMPLETED, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_READY_CHECK_STARTED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_RESULT_OK, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1573,9 +1574,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHANGED_INFORM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHANGED_INFORM, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHOSEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_INFORM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_INFORM, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_RUNE_REGEN_DEBUG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_BOOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCENARIO_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1594,8 +1595,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_ITEM_PASSIVES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_KNOWN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index bd4fefdd665..d8bad3d4933 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -171,6 +171,9 @@ namespace WorldPackets class ChannelPlayerCommand; class JoinChannel; class LeaveChannel; + class UserlistAdd; + class UserlistRemove; + class UserlistUpdate; } namespace Chat @@ -275,6 +278,11 @@ namespace WorldPackets class RequestHonorStats; } + namespace Instance + { + class InstanceInfo; + } + namespace Item { class AutoEquipItem; @@ -338,6 +346,8 @@ namespace WorldPackets class CompleteCinematic; class NextCinematicCamera; class FarSight; + class LoadCUFProfiles; + class SaveCUFProfiles; } namespace Movement @@ -360,6 +370,47 @@ namespace WorldPackets class TrainerBuySpell; } + namespace Party + { + class PartyCommandResult; + class PartyInviteClient; + class PartyInvite; + class PartyInviteResponse; + class PartyUninvite; + class GroupDecline; + class RequestPartyMemberStats; + class PartyMemberStats; + class SetPartyLeader; + class SetRole; + class RoleChangedInform; + class SetLootMethod; + class LeaveGroup; + class MinimapPingClient; + class MinimapPing; + class UpdateRaidTarget; + class SendRaidTargetUpdateSingle; + class SendRaidTargetUpdateAll; + class ConvertRaid; + class RequestPartyJoinUpdates; + class SetAssistantLeader; + class DoReadyCheck; + class ReadyCheckStarted; + class ReadyCheckResponseClient; + class ReadyCheckResponse; + class ReadyCheckCompleted; + class RequestRaidInfo; + class OptOutOfLoot; + class InitiateRolePoll; + class RolePollInform; + class GroupNewLeader; + class PartyUpdate; + class SetEveryoneIsAssistant; + class ChangeSubGroup; + class SwapSubGroups; + class RaidMarkersChanged; + class ClearRaidMarker; + } + namespace Petition { class DeclinePetition; @@ -855,8 +906,6 @@ class WorldSession void SendNotInArenaTeamPacket(uint8 type); void SendPetitionShowList(ObjectGuid guid); - void BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data); - void DoLootRelease(ObjectGuid lguid); // Account mute time @@ -1051,28 +1100,31 @@ class WorldSession void HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeSkipped& moveTimeSkipped); void HandleMovementAckMessage(WorldPackets::Movement::MovementAckMessage& movementAck); - void HandleRequestRaidInfoOpcode(WorldPacket& recvData); + void HandleRequestRaidInfoOpcode(WorldPackets::Party::RequestRaidInfo& packet); - void HandleGroupInviteOpcode(WorldPacket& recvPacket); + void HandlePartyInviteOpcode(WorldPackets::Party::PartyInviteClient& packet); //void HandleGroupCancelOpcode(WorldPacket& recvPacket); - void HandleGroupInviteResponseOpcode(WorldPacket& recvPacket); - void HandleGroupUninviteOpcode(WorldPacket& recvPacket); - void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket); - void HandleGroupSetRolesOpcode(WorldPacket& recvData); - void HandleGroupDisbandOpcode(WorldPacket& recvPacket); - void HandleOptOutOfLootOpcode(WorldPacket& recvData); - void HandleLootMethodOpcode(WorldPacket& recvPacket); + void HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet); + void HandlePartyUninviteOpcode(WorldPackets::Party::PartyUninvite& packet); + void HandleSetPartyLeaderOpcode(WorldPackets::Party::SetPartyLeader& packet); + void HandleSetRoleOpcode(WorldPackets::Party::SetRole& packet); + void HandleLeaveGroupOpcode(WorldPackets::Party::LeaveGroup& packet); + void HandleOptOutOfLootOpcode(WorldPackets::Party::OptOutOfLoot& packet); + void HandleSetLootMethodOpcode(WorldPackets::Party::SetLootMethod& packet); void HandleLootRoll(WorldPackets::Loot::LootRoll& packet); - void HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData); - void HandleRaidTargetUpdateOpcode(WorldPacket& recvData); - void HandleRaidReadyCheckOpcode(WorldPacket& recvData); - void HandleGroupRaidConvertOpcode(WorldPacket& recvData); - void HandleGroupRequestJoinUpdates(WorldPacket& recvData); - void HandleGroupChangeSubGroupOpcode(WorldPacket& recvData); - void HandleGroupSwapSubGroupOpcode(WorldPacket& recvData); - void HandleGroupAssistantLeaderOpcode(WorldPacket& recvData); + void HandleRequestPartyMemberStatsOpcode(WorldPackets::Party::RequestPartyMemberStats& packet); + void HandleUpdateRaidTargetOpcode(WorldPackets::Party::UpdateRaidTarget& packet); + void HandleDoReadyCheckOpcode(WorldPackets::Party::DoReadyCheck& packet); + void HandleReadyCheckResponseOpcode(WorldPackets::Party::ReadyCheckResponseClient& packet); + void HandleConvertRaidOpcode(WorldPackets::Party::ConvertRaid& packet); + void HandleRequestPartyJoinUpdates(WorldPackets::Party::RequestPartyJoinUpdates& packet); + void HandleChangeSubGroupOpcode(WorldPackets::Party::ChangeSubGroup& packet); + void HandleSwapSubGroupsOpcode(WorldPackets::Party::SwapSubGroups& packet); + void HandleSetAssistantLeaderOpcode(WorldPackets::Party::SetAssistantLeader& packet); void HandlePartyAssignmentOpcode(WorldPacket& recvData); - void HandleRolePollBeginOpcode(WorldPacket& recvData); + void HandleInitiateRolePoll(WorldPackets::Party::InitiateRolePoll& packet); + void HandleSetEveryoneIsAssistant(WorldPackets::Party::SetEveryoneIsAssistant& packet); + void HandleClearRaidMarker(WorldPackets::Party::ClearRaidMarker& packet); void HandleDeclinePetition(WorldPackets::Petition::DeclinePetition& packet); void HandleOfferPetition(WorldPackets::Petition::OfferPetition& packet); @@ -1337,7 +1389,7 @@ class WorldSession void HandleWardenDataOpcode(WorldPacket& recvData); void HandleWorldTeleportOpcode(WorldPacket& recvData); - void HandleMinimapPingOpcode(WorldPacket& recvData); + void HandleMinimapPingOpcode(WorldPackets::Party::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); void HandleFarSightOpcode(WorldPackets::Misc::FarSight& packet); void HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDungeonDifficulty& setDungeonDifficulty); @@ -1470,7 +1522,7 @@ class WorldSession void HandleRequestWowTokenMarketPrice(WorldPackets::Token::RequestWowTokenMarketPrice& requestWowTokenMarketPrice); // Compact Unit Frames (4.x) - void HandleSaveCUFProfiles(WorldPacket& recvPacket); + void HandleSaveCUFProfiles(WorldPackets::Misc::SaveCUFProfiles& packet); void SendLoadCUFProfiles(); // Garrison diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 3ca8550b3ce..ec716a0e03d 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -338,6 +338,7 @@ class Spell void EffectApplyGlyph(SpellEffIndex effIndex); void EffectEnchantHeldItem(SpellEffIndex effIndex); void EffectSummonObject(SpellEffIndex effIndex); + void EffectChangeRaidMarker(SpellEffIndex effIndex); void EffectResurrect(SpellEffIndex effIndex); void EffectParry(SpellEffIndex effIndex); void EffectBlock(SpellEffIndex effIndex); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9e4f0608a38..faa897d866f 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -180,7 +180,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectReputation, //103 SPELL_EFFECT_REPUTATION &Spell::EffectSummonObject, //104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 &Spell::EffectSummonObject, //105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - &Spell::EffectSummonObject, //106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + &Spell::EffectChangeRaidMarker, //106 SPELL_EFFECT_CHANGE_RAID_MARKER &Spell::EffectSummonObject, //107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 &Spell::EffectDispelMechanic, //108 SPELL_EFFECT_DISPEL_MECHANIC &Spell::EffectResurrectPet, //109 SPELL_EFFECT_RESURRECT_PET @@ -4648,6 +4648,25 @@ void Spell::EffectPullTowards(SpellEffIndex /*effIndex*/) unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ); } +void Spell::EffectChangeRaidMarker(SpellEffIndex /*effIndex*/) +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) + return; + + Player* player = m_caster->ToPlayer(); + if (!player || !m_targets.HasDst()) + return; + + Group* group = player->GetGroup(); + if (!group || (group->isRaidGroup() && !group->IsLeader(player->GetGUID()) && !group->IsAssistant(player->GetGUID()))) + return; + + float x, y, z; + destTarget->GetPosition(x, y, z); + + group->AddRaidMarker(damage, player->GetMapId(), x, y, z); +} + void Spell::EffectDispelMechanic(SpellEffIndex /*effIndex*/) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 4db7091f971..0bdb36b988f 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -806,7 +806,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_CHANGE_RAID_MARKER {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index dcee6f08ac3..167680f1cd2 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -34,7 +34,7 @@ namespace Trinity { BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(_textId); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); + packet.Initialize(_msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _source->getGender()) : "", _achievementId, "", locale); packet.Write(); data = packet.Move(); } @@ -56,7 +56,7 @@ namespace Trinity void operator()(WorldPacket& data, LocaleConstant locale) { WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, _language, _source, _target, _text, 0, "", locale); + packet.Initialize(_msgType, _language, _source, _target, _text, 0, "", locale); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 281504b9aaf..c1ea235a3e2 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -37,7 +37,7 @@ class CreatureTextBuilder { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, Language(_language), _source, _target, text, 0, "", locale); + packet.Initialize(_msgType, Language(_language), _source, _target, text, 0, "", locale); packet.Write(); data = packet.Move(); } @@ -62,7 +62,7 @@ class PlayerTextBuilder { std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); WorldPackets::Chat::Chat packet; - packet.Initalize(_msgType, Language(_language), _talker, _target, text, 0, "", locale); + packet.Initialize(_msgType, Language(_language), _talker, _target, text, 0, "", locale); packet.Write(); data = packet.Move(); } diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 9b8c63000fc..d68da8fbc63 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2252,6 +2252,9 @@ void World::Update(uint32 diff) sLFGMgr->Update(diff); RecordTimeDiff("UpdateLFGMgr"); + sGroupMgr->Update(diff); + RecordTimeDiff("GroupMgr"); + // execute callbacks from sql queries that were queued recently ProcessQueryCallbacks(); RecordTimeDiff("ProcessQueryCallbacks"); @@ -2381,7 +2384,7 @@ namespace Trinity while (char* line = ChatHandler::LineFromMessage(text)) { WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); packet.Write(); dataList.emplace_back(new WorldPacket(packet.Move())); } @@ -2447,7 +2450,7 @@ void World::SendGlobalText(const char* text, WorldSession* self) while (char* line = ChatHandler::LineFromMessage(pos)) { WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); SendGlobalMessage(packet.Write(), self); } @@ -2481,7 +2484,7 @@ bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession void World::SendZoneText(uint32 zone, const char* text, WorldSession* self, uint32 team) { WorldPackets::Chat::Chat packet; - packet.Initalize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text); + packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text); SendZoneMessage(zone, packet.Write(), self, team); } diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index ecd98595723..7f1a364fd57 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -485,7 +485,7 @@ public: char const* msg = "testtest"; uint8 type = atoi(args); WorldPackets::Chat::Chat packet; - packet.Initalize(ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); + packet.Initialize(ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan"); handler->GetSession()->SendPacket(packet.Write()); return true; } diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index dc9e948966d..e83340bdd84 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -164,4 +165,14 @@ struct LocalizedString template using Optional = boost::optional; +namespace Trinity +{ + //! std::make_unique implementation (TODO: remove this once C++14 is supported) + template + std::unique_ptr make_unique(Args&& ...args) + { + return std::unique_ptr(new T(std::forward(args)...)); + } +} + #endif diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index e22a06e635e..5b3782fce55 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -23,6 +23,7 @@ #include "Appender.h" #include "Logger.h" #include "StringFormat.h" +#include "Common.h" #include #include @@ -64,7 +65,7 @@ class Log template inline void outMessage(std::string const& filter, LogLevel const level, const char* fmt, Args const&... args) { - write(std::unique_ptr(new LogMessage(level, filter, Trinity::StringFormat(fmt, args...)))); + write(Trinity::make_unique(level, filter, Trinity::StringFormat(fmt, args...))); } template @@ -73,7 +74,7 @@ class Log if (!ShouldLog("commands.gm", LOG_LEVEL_INFO)) return; - std::unique_ptr msg(new LogMessage(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...)))); + std::unique_ptr msg = Trinity::make_unique(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...))); msg->param1 = std::to_string(account); -- cgit v1.2.3