diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 92b42d735..0e75edaf6 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -794,6 +794,13 @@ enum InstanceResetWarningType RAID_INSTANCE_EXPIRED = 5 }; +enum InstanceResetFailureReason : uint32 +{ + INSTANCE_RESET_FAILED = 0, // Cannot reset %s. There are players still inside the instance. + INSTANCE_RESET_FAILED_OFFLINE = 1, // Cannot reset %s. There are players offline in your party. + INSTANCE_RESET_FAILED_ZONING = 2, // Cannot reset %s. There are players in your party attempting to zone into an instance. +}; + class InstanceSave; enum RestFlag @@ -2010,7 +2017,7 @@ public: void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty = -1); static void ResetInstances(ObjectGuid guid, uint8 method, bool isRaid); void SendResetInstanceSuccess(uint32 MapId); - void SendResetInstanceFailed(uint32 reason, uint32 MapId); + void SendResetInstanceFailed(InstanceResetFailureReason reason, uint32 MapId); void SendResetFailedNotify(uint32 mapid); bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override; diff --git a/src/server/game/Entities/Player/PlayerMisc.cpp b/src/server/game/Entities/Player/PlayerMisc.cpp index 0d3311a6c..91459d848 100644 --- a/src/server/game/Entities/Player/PlayerMisc.cpp +++ b/src/server/game/Entities/Player/PlayerMisc.cpp @@ -17,6 +17,7 @@ #include "AccountMgr.h" #include "GameTime.h" +#include "InstancePackets.h" #include "MapMgr.h" #include "Player.h" #include "ScriptMgr.h" @@ -166,29 +167,25 @@ void Player::SendExplorationExperience(uint32 Area, uint32 Experience) void Player::SendDungeonDifficulty(bool IsInGroup) { - uint8 val = 0x00000001; - WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12); - data << (uint32)GetDungeonDifficulty(); - data << uint32(val); - data << uint32(IsInGroup); - SendDirectMessage(&data); + WorldPackets::Instance::SetDungeonDifficulty setDungeonDifficulty; + setDungeonDifficulty.Difficulty = GetDungeonDifficulty(); + setDungeonDifficulty.IsInGroup = IsInGroup; + SendDirectMessage(setDungeonDifficulty.Write()); } void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty) { - uint8 val = 0x00000001; - WorldPacket data(MSG_SET_RAID_DIFFICULTY, 12); - data << uint32(forcedDifficulty == -1 ? GetRaidDifficulty() : forcedDifficulty); - data << uint32(val); - data << uint32(IsInGroup); - SendDirectMessage(&data); + WorldPackets::Instance::SetRaidDifficulty setRaidDifficulty; + setRaidDifficulty.Difficulty = (forcedDifficulty == -1 ? GetRaidDifficulty() : forcedDifficulty); + setRaidDifficulty.IsInGroup = IsInGroup; + SendDirectMessage(setRaidDifficulty.Write()); } void Player::SendResetFailedNotify(uint32 mapid) { - WorldPacket data(SMSG_RESET_FAILED_NOTIFY, 4); - data << uint32(mapid); - SendDirectMessage(&data); + WorldPackets::Instance::ResetFailedNotify resetFailedNotify; + resetFailedNotify.MapId = mapid; + SendDirectMessage(resetFailedNotify.Write()); } /// Reset all solo instances and optionally send a message on success for each @@ -220,7 +217,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid) } else { - p->SendResetInstanceFailed(0, instanceSave->GetMapId()); + p->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); @@ -255,7 +252,7 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid) } else { - p->SendResetInstanceFailed(0, instanceSave->GetMapId()); + p->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); @@ -325,22 +322,17 @@ void Player::ResetInstances(ObjectGuid guid, uint8 method, bool isRaid) void Player::SendResetInstanceSuccess(uint32 MapId) { - WorldPacket data(SMSG_INSTANCE_RESET, 4); - data << uint32(MapId); - SendDirectMessage(&data); + WorldPackets::Instance::InstanceReset instanceReset; + instanceReset.MapId = MapId; + SendDirectMessage(instanceReset.Write()); } -void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) +void Player::SendResetInstanceFailed(InstanceResetFailureReason reason, uint32 MapId) { - /*reasons for instance reset failure: - // 0: There are players inside the instance. - // 1: There are players offline in your party. - // 2>: There are players in your party attempting to zone into an instance. - */ - WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 4); - data << uint32(reason); - data << uint32(MapId); - SendDirectMessage(&data); + WorldPackets::Instance::InstanceResetFailed instanceResetFailed; + instanceResetFailed.Reason = reason; + instanceResetFailed.MapId = MapId; + SendDirectMessage(instanceResetFailed.Write()); } /*********************************************************/ diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index d2338ca81..548c4787f 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -2150,7 +2150,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* leader) } else { - leader->SendResetInstanceFailed(0, instanceSave->GetMapId()); + leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); @@ -2178,7 +2178,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* leader) } else { - leader->SendResetInstanceFailed(0, instanceSave->GetMapId()); + leader->SendResetInstanceFailed(INSTANCE_RESET_FAILED, instanceSave->GetMapId()); } sInstanceSaveMgr->DeleteInstanceSavedData(instanceSave->GetInstanceId()); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index c8af95af2..4c3ba5502 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -29,6 +29,7 @@ #include "GossipDef.h" #include "Group.h" #include "GuildMgr.h" +#include "InstancePackets.h" #include "InstanceScript.h" #include "Language.h" #include "Log.h" @@ -1240,7 +1241,7 @@ void WorldSession::HandleSetTitleOpcode(WorldPacket& recv_data) GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title); } -void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleResetInstancesOpcode(WorldPackets::Instance::ResetInstances& /*packet*/) { LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES"); @@ -1253,17 +1254,14 @@ void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recv_data*/) Player::ResetInstances(_player->GetGUID(), INSTANCE_RESET_ALL, false); } -void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data) +void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPackets::Instance::SetDungeonDifficultyClient& packet) { LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY"); - uint32 mode; - recv_data >> mode; - - if (mode >= MAX_DUNGEON_DIFFICULTY) + if (packet.Mode >= MAX_DUNGEON_DIFFICULTY) return; - if (Difficulty(mode) == _player->GetDungeonDifficulty()) + if (Difficulty(packet.Mode) == _player->GetDungeonDifficulty()) return; Group* group = _player->GetGroup(); @@ -1291,7 +1289,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data) } group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player); - group->SetDungeonDifficulty(Difficulty(mode)); + group->SetDungeonDifficulty(Difficulty(packet.Mode)); } } else @@ -1302,21 +1300,18 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data) return; } Player::ResetInstances(_player->GetGUID(), INSTANCE_RESET_CHANGE_DIFFICULTY, false); - _player->SetDungeonDifficulty(Difficulty(mode)); + _player->SetDungeonDifficulty(Difficulty(packet.Mode)); } } -void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) +void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Instance::SetRaidDifficultyClient& packet) { LOG_DEBUG("network", "MSG_SET_RAID_DIFFICULTY"); - uint32 mode; - recv_data >> mode; - - if (mode >= MAX_RAID_DIFFICULTY) + if (packet.Mode >= MAX_RAID_DIFFICULTY) return; - if (Difficulty(mode) == _player->GetRaidDifficulty()) + if (Difficulty(packet.Mode) == _player->GetRaidDifficulty()) return; Group* group = _player->GetGroup(); @@ -1357,7 +1352,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) return; } - if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (uint32(mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup()) + if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (uint32(packet.Mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup()) { if (!currMap) currMap = groupGuy->GetMap(); @@ -1371,7 +1366,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) if (!groupGuy->IsAlive() || groupGuy->IsInCombat() || groupGuy->GetVictim() || groupGuy->m_mover != groupGuy || groupGuy->IsNonMeleeSpellCast(true) || (!groupGuy->GetMotionMaster()->empty() && groupGuy->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE) || !groupGuy->movespline->Finalized() || !groupGuy->GetMap()->ToInstanceMap() || !groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript() || groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress() - || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(mode)), groupGuy->GetMap()->GetId(), false)) + || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(packet.Mode)), groupGuy->GetMap()->GetId(), false)) { _player->SendRaidDifficulty(group != nullptr); return; @@ -1443,12 +1438,12 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) if (!anyoneInside) // pussywizard: don't reset if changing ICC/RS difficulty while inside group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player); - group->SetRaidDifficulty(Difficulty(mode)); + group->SetRaidDifficulty(Difficulty(packet.Mode)); group->SetDifficultyChangePrevention(DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED); for (std::map::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr) { - itr->first->SetRaidDifficulty(Difficulty(mode)); // needed for teleport not to fail + itr->first->SetRaidDifficulty(Difficulty(packet.Mode)); // needed for teleport not to fail if (!itr->first->TeleportTo(*(foundMaps.begin()), itr->second.GetPositionX(), itr->second.GetPositionY(), itr->second.GetPositionZ(), itr->second.GetOrientation())) itr->first->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 2"); } @@ -1462,7 +1457,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recv_data) return; } Player::ResetInstances(_player->GetGUID(), INSTANCE_RESET_CHANGE_DIFFICULTY, true); - _player->SetRaidDifficulty(Difficulty(mode)); + _player->SetRaidDifficulty(Difficulty(packet.Mode)); } } @@ -1698,11 +1693,8 @@ void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/) _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); } -void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) +void WorldSession::HandleInstanceLockResponse(WorldPackets::Instance::InstanceLockResponse& packet) { - uint8 accept; - recvPacket >> accept; - if (!_player->HasPendingBind() || _player->GetPendingBind() != _player->GetInstanceId() || (_player->GetGroup() && _player->GetGroup()->isLFGGroup() && _player->GetGroup()->IsLfgRandomInstance())) { LOG_DEBUG("network.opcode", "InstanceLockResponse: Player {} ({}) tried to bind himself/teleport to graveyard without a pending bind!", @@ -1710,7 +1702,7 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) return; } - if (accept) + if (packet.Accept) _player->BindToInstance(); else _player->RepopAtGraveyard(); diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index 0f2774836..8cdbc7cda 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -25,6 +25,7 @@ #include "CombatLogPackets.h" #include "CombatPackets.h" #include "GuildPackets.h" +#include "InstancePackets.h" #include "ItemPackets.h" #include "LFGPackets.h" #include "MiscPackets.h" diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp new file mode 100644 index 000000000..9a344f807 --- /dev/null +++ b/src/server/game/Server/Packets/InstancePackets.cpp @@ -0,0 +1,73 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "InstancePackets.h" + +WorldPacket const* WorldPackets::Instance::InstanceReset::Write() +{ + _worldPacket << MapId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::InstanceResetFailed::Write() +{ + _worldPacket << Reason; + _worldPacket << MapId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::SetDungeonDifficulty::Write() +{ + _worldPacket << Difficulty; + _worldPacket << Unk; + _worldPacket << IsInGroup; + + return &_worldPacket; +} + +void WorldPackets::Instance::SetDungeonDifficultyClient::Read() +{ + _worldPacket >> Mode; +} + +WorldPacket const* WorldPackets::Instance::ResetFailedNotify::Write() +{ + _worldPacket << MapId; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::SetRaidDifficulty::Write() +{ + _worldPacket << Difficulty; + _worldPacket << Unk; + _worldPacket << IsInGroup; + + return &_worldPacket; +} + +void WorldPackets::Instance::SetRaidDifficultyClient::Read() +{ + _worldPacket >> Mode; +} + +void WorldPackets::Instance::InstanceLockResponse::Read() +{ + _worldPacket >> Accept; +} diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h new file mode 100644 index 000000000..3f95b6242 --- /dev/null +++ b/src/server/game/Server/Packets/InstancePackets.h @@ -0,0 +1,123 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef InstancePackets_h__ +#define InstancePackets_h__ + +#include "Packet.h" +#include "Player.h" + +namespace WorldPackets +{ + namespace Instance + { + class InstanceReset final : public ServerPacket + { + public: + InstanceReset() : ServerPacket(SMSG_INSTANCE_RESET, 4) {} + + WorldPacket const* Write() override; + + uint32 MapId = 0; + }; + + class InstanceResetFailed final : public ServerPacket + { + public: + InstanceResetFailed() : ServerPacket(SMSG_INSTANCE_RESET_FAILED, 4 + 4) {} + + WorldPacket const* Write() override; + + InstanceResetFailureReason Reason = INSTANCE_RESET_FAILED; + uint32 MapId = 0; + }; + + class SetDungeonDifficulty final : public ServerPacket + { + public: + SetDungeonDifficulty() : ServerPacket(MSG_SET_DUNGEON_DIFFICULTY, 12) {} + + WorldPacket const* Write() override; + + uint32 Difficulty = -1; // @TODO: Check if cast to Dungeon type will cause problems (SetRaidDifficulty() too) + uint32 Unk = 0x00000001; + uint32 IsInGroup = 0; + }; + + class SetDungeonDifficultyClient final : public ClientPacket + { + public: + SetDungeonDifficultyClient(WorldPacket&& packet) : ClientPacket(MSG_SET_DUNGEON_DIFFICULTY, std::move(packet)) {} + + void Read() override; + + uint32 Mode = DUNGEON_DIFFICULTY_NORMAL; + }; + + class ResetFailedNotify final : public ServerPacket + { + public: + ResetFailedNotify() : ServerPacket(SMSG_RESET_FAILED_NOTIFY, 4) {} + + WorldPacket const* Write() override; + + uint32 MapId = 0; + }; + + class SetRaidDifficulty final : public ServerPacket + { + public: + SetRaidDifficulty() : ServerPacket(MSG_SET_RAID_DIFFICULTY, 12) {} + + WorldPacket const* Write() override; + + uint32 Difficulty = -1; + uint32 Unk = 0x00000001; + uint32 IsInGroup = 0; + }; + + class SetRaidDifficultyClient final : public ClientPacket + { + public: + SetRaidDifficultyClient(WorldPacket&& packet) : ClientPacket(MSG_SET_RAID_DIFFICULTY, std::move(packet)) {} + + void Read() override; + + uint32 Mode = RAID_DIFFICULTY_10MAN_NORMAL; + }; + + class ResetInstances final : public ClientPacket + { + public: + ResetInstances(WorldPacket&& packet) : ClientPacket(CMSG_RESET_INSTANCES, std::move(packet)) {} + + void Read() override {}; + }; + + class InstanceLockResponse final : public ClientPacket + { + public: + InstanceLockResponse(WorldPacket&& packet) : ClientPacket(CMSG_INSTANCE_LOCK_RESPONSE, std::move(packet)) {} + + void Read() override; + + uint8 Accept = 0; + }; + } +} + +#endif // InstancePackets_h__ diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 4a113d881..1ea355538 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -204,6 +204,14 @@ namespace WorldPackets class Hello; class TrainerBuySpell; } + + namespace Instance + { + class SetDungeonDifficultyClient; + class SetRaidDifficultyClient; + class ResetInstances; + class InstanceLockResponse; + } } enum AccountDataType @@ -988,16 +996,16 @@ public: // opcodes handlers void HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet); void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet); void HandleFarSightOpcode(WorldPacket& recvData); - void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData); - void HandleSetRaidDifficultyOpcode(WorldPacket& recvData); + void HandleSetDungeonDifficultyOpcode(WorldPackets::Instance::SetDungeonDifficultyClient& packet); + void HandleSetRaidDifficultyOpcode(WorldPackets::Instance::SetRaidDifficultyClient& packet); void HandleMoveFlagChangeOpcode(WorldPacket& recvData); void HandleSetTitleOpcode(WorldPacket& recvData); void HandleRealmSplitOpcode(WorldPacket& recvData); void HandleTimeSyncResp(WorldPacket& recvData); void HandleWhoisOpcode(WorldPacket& recvData); - void HandleResetInstancesOpcode(WorldPacket& recvData); + void HandleResetInstancesOpcode(WorldPackets::Instance::ResetInstances& packet); void HandleHearthAndResurrect(WorldPacket& recvData); - void HandleInstanceLockResponse(WorldPacket& recvPacket); + void HandleInstanceLockResponse(WorldPackets::Instance::InstanceLockResponse& packet); void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); // Battlefield