Core/Spells: Corrected client control checks in spell packets
Closes #26510 Closes #27863 (cherry picked from commit 0a34290484f3e90a2a642986de682a8b0c7e3815)
This commit is contained in:
@@ -48,10 +48,6 @@
|
||||
|
||||
void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet)
|
||||
{
|
||||
// ignore for remote control state
|
||||
if (_player->GetUnitBeingMoved() != _player)
|
||||
return;
|
||||
|
||||
// Skip casting invalid spells right away
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.Cast.SpellID, _player->GetMap()->GetDifficultyID());
|
||||
if (!spellInfo)
|
||||
@@ -71,8 +67,9 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
|
||||
Player* player = GetPlayer();
|
||||
|
||||
// ignore for remote control state
|
||||
if (player->GetUnitBeingMoved() != player)
|
||||
if (player->IsCharmed())
|
||||
return;
|
||||
|
||||
TC_LOG_INFO("network", "bagIndex: {}, slot: {}", packet.Slot, packet.PackSlot);
|
||||
|
||||
// additional check, client outputs message on its own
|
||||
@@ -205,8 +202,8 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUs
|
||||
if (GameObject* obj = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid))
|
||||
{
|
||||
// ignore for remote control state
|
||||
if (GetPlayer()->GetUnitBeingMoved() != GetPlayer())
|
||||
if (!(GetPlayer()->IsOnVehicle(GetPlayer()->GetUnitBeingMoved()) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
|
||||
if (GetPlayer()->IsCharmed())
|
||||
if (!(GetPlayer()->IsOnVehicle(GetPlayer()->GetCharmed()) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
|
||||
return;
|
||||
|
||||
obj->Use(GetPlayer());
|
||||
@@ -216,7 +213,7 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUs
|
||||
void WorldSession::HandleGameobjectReportUse(WorldPackets::GameObject::GameObjReportUse& packet)
|
||||
{
|
||||
// ignore for remote control state
|
||||
if (_player->GetUnitBeingMoved() != _player)
|
||||
if (_player->IsCharmed())
|
||||
return;
|
||||
|
||||
if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid))
|
||||
@@ -238,33 +235,20 @@ void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& castRe
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->GetUnitBeingMoved();
|
||||
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Unit* castingUnit = mover;
|
||||
if (castingUnit->IsCreature() && !castingUnit->ToCreature()->HasSpell(spellInfo->Id))
|
||||
{
|
||||
// If the vehicle creature does not have the spell but it allows the passenger to cast own spells
|
||||
// change caster to player and let him cast
|
||||
if (!_player->IsOnVehicle(castingUnit) || spellInfo->CheckVehicle(_player) != SPELL_CAST_OK)
|
||||
return;
|
||||
|
||||
castingUnit = _player;
|
||||
}
|
||||
|
||||
if (castRequest.Cast.MoveUpdate.has_value())
|
||||
HandleMovementOpcode(CMSG_MOVE_STOP, *castRequest.Cast.MoveUpdate);
|
||||
|
||||
if (_player->CanRequestSpellCast(spellInfo, castingUnit))
|
||||
_player->RequestSpellCast(std::make_unique<SpellCastRequest>(std::move(castRequest.Cast), castingUnit->GetGUID()));
|
||||
if (_player->CanRequestSpellCast(spellInfo, _player))
|
||||
_player->RequestSpellCast(std::make_unique<SpellCastRequest>(std::move(castRequest.Cast), _player->GetGUID()));
|
||||
else
|
||||
Spell::SendCastResult(_player, spellInfo, {}, castRequest.Cast.CastID, SPELL_FAILED_SPELL_IN_PROGRESS);
|
||||
}
|
||||
|
||||
void WorldSession::HandleCancelCastOpcode(WorldPackets::Spells::CancelCast& packet)
|
||||
{
|
||||
if (_player->IsCharmed())
|
||||
return;
|
||||
|
||||
if (_player->IsNonMeleeSpellCast(false))
|
||||
{
|
||||
_player->InterruptNonMeleeSpells(false, packet.SpellID, false);
|
||||
@@ -378,7 +362,7 @@ void WorldSession::HandleCancelChanneling(WorldPackets::Spells::CancelChannellin
|
||||
{
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->GetUnitBeingMoved();
|
||||
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
|
||||
if (!mover)
|
||||
return;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cancelChanneling.ChannelSpell, mover->GetMap()->GetDifficultyID());
|
||||
@@ -405,7 +389,7 @@ void WorldSession::HandleSpellEmpowerRelease(WorldPackets::Spells::SpellEmpowerR
|
||||
{
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->GetUnitBeingMoved();
|
||||
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
|
||||
if (!mover)
|
||||
return;
|
||||
|
||||
Spell* spell = mover->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
||||
@@ -419,7 +403,7 @@ void WorldSession::HandleSpellEmpowerRestart(WorldPackets::Spells::SpellEmpowerR
|
||||
{
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->GetUnitBeingMoved();
|
||||
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
|
||||
if (!mover)
|
||||
return;
|
||||
|
||||
Spell* spell = mover->GetCurrentSpell(CURRENT_CHANNELED_SPELL);
|
||||
@@ -432,7 +416,7 @@ void WorldSession::HandleSpellEmpowerRestart(WorldPackets::Spells::SpellEmpowerR
|
||||
void WorldSession::HandleTotemDestroyed(WorldPackets::Totem::TotemDestroyed& totemDestroyed)
|
||||
{
|
||||
// ignore for remote control state
|
||||
if (_player->GetUnitBeingMoved() != _player)
|
||||
if (_player->IsCharmed())
|
||||
return;
|
||||
|
||||
uint8 slotId = totemDestroyed.Slot;
|
||||
|
||||
@@ -6958,16 +6958,8 @@ SpellCastResult Spell::CheckCasterAuras(int32* param1) const
|
||||
// Get unit state
|
||||
uint32 const unitflag = unitCaster->m_unitData->Flags;
|
||||
|
||||
// this check should only be done when player does cast directly
|
||||
// (ie not when it's called from a script) Breaks for example PlayerAI when charmed
|
||||
/*
|
||||
if (!unitCaster->GetCharmerGUID().IsEmpty())
|
||||
{
|
||||
if (Unit* charmer = unitCaster->GetCharmer())
|
||||
if (charmer->GetUnitBeingMoved() != unitCaster && !CheckSpellCancelsCharm(param1))
|
||||
result = SPELL_FAILED_CHARMED;
|
||||
}
|
||||
*/
|
||||
if (m_fromClient && unitCaster->IsCharmed() && unitCaster->IsPlayer() && !CheckSpellCancelsCharm(param1))
|
||||
result = SPELL_FAILED_CHARMED;
|
||||
|
||||
// spell has attribute usable while having a cc state, check if caster has allowed mechanic auras, another mechanic types must prevent cast spell
|
||||
auto mechanicCheck = [&](AuraType type) -> SpellCastResult
|
||||
|
||||
Reference in New Issue
Block a user