refactor(Core/Packets): Rewrite various instance packets to modern class. (#22762)

This commit is contained in:
Benjamin Jackson
2026-02-13 09:22:45 -05:00
committed by GitHub
parent c251b46892
commit 24f5f289f0
8 changed files with 258 additions and 62 deletions

View File

@@ -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;

View File

@@ -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());
}
/*********************************************************/

View File

@@ -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());

View File

@@ -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<Player*, Position>::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();

View File

@@ -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"

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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__

View File

@@ -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