Entities/Unit: Cleanup all the direct accesses to m_unitMovedByMe. Refactor the field to be protected. Add assertions to catch dangling pointers.

(cherry picked from commit 396f87c30d)
This commit is contained in:
Treeston
2019-06-23 16:44:37 +02:00
committed by Shauren
parent 06823f19cd
commit edc7583119
6 changed files with 48 additions and 63 deletions

View File

@@ -23990,7 +23990,7 @@ bool Player::IsNeverVisibleFor(WorldObject const* seer) const
bool Player::CanAlwaysSee(WorldObject const* obj) const
{
// Always can see self
if (m_unitMovedByMe == obj)
if (GetUnitBeingMoved() == obj)
return true;
ObjectGuid guid = m_activePlayerData->FarsightObject;
@@ -24431,7 +24431,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
initialSetup.ServerExpansionLevel = sWorld->getIntConfig(CONFIG_EXPANSION);
SendDirectMessage(initialSetup.Write());
SetMover(this);
SetMovedUnit(this);
}
void Player::SendInitialPacketsAfterAddToMap()
@@ -25748,19 +25748,7 @@ void Player::SetClientControl(Unit* target, bool allowMove)
SetViewpoint(target, allowMove);
if (allowMove)
SetMover(target);
}
void Player::SetMover(Unit* target)
{
m_unitMovedByMe->m_playerMovingMe = nullptr;
m_unitMovedByMe = target;
m_unitMovedByMe->m_playerMovingMe = this;
WorldPackets::Movement::MoveSetActiveMover packet;
packet.MoverGUID = target->GetGUID();
SendDirectMessage(packet.Write());
SetMovedUnit(target);
}
void Player::UpdateZoneDependentAuras(uint32 newZone)

View File

@@ -2369,15 +2369,12 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
/*********************************************************/
void UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode);
// only changed for direct client control (possess, vehicle etc.), not stuff you control using pet commands
Unit* m_unitMovedByMe;
WorldObject* m_seer;
void SetFallInformation(uint32 time, float z);
void HandleFall(MovementInfo const& movementInfo);
void SetClientControl(Unit* target, bool allowMove);
void SetMover(Unit* target);
void SetSeer(WorldObject* target) { m_seer = target; }
void SetViewpoint(WorldObject* target, bool apply);
WorldObject* GetViewpoint() const;

View File

@@ -298,11 +298,10 @@ SpellNonMeleeDamage::SpellNonMeleeDamage(Unit* _attacker, Unit* _target, SpellIn
}
Unit::Unit(bool isWorldObject) :
WorldObject(isWorldObject), m_playerMovingMe(nullptr), m_lastSanctuaryTime(0), LastCharmerGUID(),
movespline(new Movement::MoveSpline()), m_ControlledByPlayer(false), m_AutoRepeatFirstCast(false),
m_procDeep(0), m_transformSpell(0), m_removedAurasCount(0),
m_interruptMask(SpellAuraInterruptFlags::None), m_interruptMask2(SpellAuraInterruptFlags2::None),
m_charmer(nullptr), m_charmed(nullptr),
WorldObject(isWorldObject), m_lastSanctuaryTime(0), LastCharmerGUID(), movespline(new Movement::MoveSpline()),
m_ControlledByPlayer(false), m_AutoRepeatFirstCast(false), m_procDeep(0), m_transformSpell(0),
m_removedAurasCount(0), m_interruptMask(SpellAuraInterruptFlags::None), m_interruptMask2(SpellAuraInterruptFlags2::None),
m_unitMovedByMe(nullptr), m_playerMovingMe(nullptr), m_charmer(nullptr), m_charmed(nullptr),
i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_vehicle(nullptr),
m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_Diminishing(), m_isEngaged(false), m_combatManager(this),
m_threatManager(this), m_aiLocked(false), _playHoverAnim(false), _aiAnimKitId(0), _movementAnimKitId(0), _meleeAnimKitId(0),
@@ -433,6 +432,7 @@ Unit::~Unit()
ASSERT(m_removedAuras.empty());
ASSERT(m_gameObj.empty());
ASSERT(m_dynObj.empty());
ASSERT(!m_playerMovingMe);
}
void Unit::Update(uint32 p_time)
@@ -8093,7 +8093,7 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate)
pet->SetSpeedRate(mtype, m_speed_rate[mtype]);
}
if (Player* playerMover = GetPlayerBeingMoved()) // unit controlled by a player.
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved())) // unit controlled by a player.
{
// Send notification to self
WorldPackets::Movement::MoveSetSpeed selfpacket(moveTypeToOpcode[mtype][1]);
@@ -9481,18 +9481,15 @@ void CharmInfo::SetSpellAutocast(SpellInfo const* spellInfo, bool state)
}
}
Unit* Unit::GetUnitBeingMoved() const
void Unit::SetMovedUnit(Unit* target)
{
if (Player const* player = ToPlayer())
return player->m_unitMovedByMe;
return nullptr;
}
m_unitMovedByMe->m_playerMovingMe = nullptr;
m_unitMovedByMe = ASSERT_NOTNULL(target);
m_unitMovedByMe->m_playerMovingMe = ASSERT_NOTNULL(ToPlayer());
Player* Unit::GetPlayerBeingMoved() const
{
if (Unit* mover = GetUnitBeingMoved())
return mover->ToPlayer();
return nullptr;
WorldPackets::Movement::MoveSetActiveMover packet;
packet.MoverGUID = target->GetGUID();
ToPlayer()->SendDirectMessage(packet.Write());
}
uint32 createProcHitMask(SpellNonMeleeDamage* damageInfo, SpellMissInfo missCondition)
@@ -10740,7 +10737,7 @@ void Unit::SetRooted(bool apply, bool packetOnly /*= false*/)
{ SMSG_MOVE_SPLINE_ROOT, SMSG_MOVE_ROOT }
};
if (Player* playerMover = GetPlayerBeingMoved()) // unit controlled by a player.
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved())) // unit controlled by a player.
{
WorldPackets::Movement::MoveSetFlag packet(rootOpcodeTable[apply][1]);
packet.MoverGUID = GetGUID();
@@ -11534,7 +11531,7 @@ void Unit::KnockbackFrom(Position const& origin, float speedXY, float speedZ, Mo
if (Unit* charmer = GetCharmer())
{
player = charmer->ToPlayer();
if (player && player->m_unitMovedByMe != this)
if (player && player->GetUnitBeingMoved() != this)
player = nullptr;
}
}
@@ -12002,7 +11999,8 @@ void Unit::SendTeleportPacket(Position const& pos)
moveUpdateTeleport.MovementForces = _movementForces->GetForces();
Unit* broadcastSource = this;
if (Player* playerMover = GetPlayerBeingMoved())
// should this really be the unit _being_ moved? not the unit doing the moving?
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
float x, y, z, o;
pos.GetPosition(x, y, z, o);
@@ -12360,7 +12358,7 @@ bool Unit::SetDisableGravity(bool disable)
{ SMSG_MOVE_SPLINE_DISABLE_GRAVITY, SMSG_MOVE_DISABLE_GRAVITY }
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(gravityOpcodeTable[disable][1]);
packet.MoverGUID = GetGUID();
@@ -12438,7 +12436,7 @@ bool Unit::SetCanFly(bool enable)
if (!enable && GetTypeId() == TYPEID_PLAYER)
ToPlayer()->SetFallInformation(0, GetPositionZ());
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(flyOpcodeTable[enable][1]);
packet.MoverGUID = GetGUID();
@@ -12475,7 +12473,7 @@ bool Unit::SetWaterWalking(bool enable)
{ SMSG_MOVE_SPLINE_SET_WATER_WALK, SMSG_MOVE_SET_WATER_WALK }
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(waterWalkingOpcodeTable[enable][1]);
packet.MoverGUID = GetGUID();
@@ -12513,7 +12511,7 @@ bool Unit::SetFeatherFall(bool enable)
{ SMSG_MOVE_SPLINE_SET_FEATHER_FALL, SMSG_MOVE_SET_FEATHER_FALL }
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(featherFallOpcodeTable[enable][1]);
packet.MoverGUID = GetGUID();
@@ -12566,7 +12564,7 @@ bool Unit::SetHover(bool enable)
{ SMSG_MOVE_SPLINE_SET_HOVER, SMSG_MOVE_SET_HOVERING }
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(hoverOpcodeTable[enable][1]);
packet.MoverGUID = GetGUID();
@@ -12603,7 +12601,7 @@ bool Unit::SetCollision(bool disable)
{ SMSG_MOVE_SPLINE_DISABLE_COLLISION, SMSG_MOVE_DISABLE_COLLISION }
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(collisionOpcodeTable[disable][1]);
packet.MoverGUID = GetGUID();
@@ -12643,7 +12641,7 @@ bool Unit::SetCanTransitionBetweenSwimAndFly(bool enable)
SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(swimToFlyTransOpcodeTable[enable]);
packet.MoverGUID = GetGUID();
@@ -12675,7 +12673,7 @@ bool Unit::SetCanTurnWhileFalling(bool enable)
SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(canTurnWhileFallingOpcodeTable[enable]);
packet.MoverGUID = GetGUID();
@@ -12706,7 +12704,7 @@ bool Unit::SetCanDoubleJump(bool enable)
SMSG_MOVE_ENABLE_DOUBLE_JUMP
};
if (Player* playerMover = GetPlayerBeingMoved())
if (Player* playerMover = Unit::ToPlayer(GetUnitBeingMoved()))
{
WorldPackets::Movement::MoveSetFlag packet(doubleJumpOpcodeTable[enable]);
packet.MoverGUID = GetGUID();

View File

@@ -1288,14 +1288,14 @@ class TC_GAME_API Unit : public WorldObject
void DeleteCharmInfo();
void SetPetNumberForClient(uint32 petNumber) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PetNumber), petNumber); }
void SetPetNameTimestamp(uint32 timestamp) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PetNameTimestamp), timestamp); }
// all of these are for DIRECT CLIENT CONTROL only
void SetMovedUnit(Unit* target);
// returns the unit that this player IS CONTROLLING
Unit* GetUnitBeingMoved() const;
// returns the player that this player IS CONTROLLING
Player* GetPlayerBeingMoved() const;
Unit* GetUnitBeingMoved() const { return m_unitMovedByMe; }
// returns the player that this unit is BEING CONTROLLED BY
Player* GetPlayerMovingMe() const { return m_playerMovingMe; }
// only set for direct client control (possess effects, vehicles and similar)
Player* m_playerMovingMe;
SharedVisionList const& GetSharedVisionList() { return m_sharedVision; }
void AddPlayerToVision(Player* player);
void RemovePlayerFromVision(Player* player);
@@ -1918,6 +1918,8 @@ class TC_GAME_API Unit : public WorldObject
float m_speed_rate[MAX_MOVE_TYPE];
Unit* m_unitMovedByMe; // only ever set for players, and only for direct client control
Player* m_playerMovingMe; // only set for direct client control (possess effects, vehicles and similar)
Unit* m_charmer; // Unit that is charming ME
Unit* m_charmed; // Unit that is being charmed BY ME
CharmInfo* m_charmInfo;

View File

@@ -249,7 +249,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck
{
TC_LOG_DEBUG("network", "CMSG_MOVE_TELEPORT_ACK: Guid: %s, Sequence: %u, Time: %u", packet.MoverGUID.ToString().c_str(), packet.AckIndex, packet.MoveTime);
Player* plMover = _player->m_unitMovedByMe->ToPlayer();
Player* plMover = _player->GetUnitBeingMoved()->ToPlayer();
if (!plMover || !plMover->IsBeingTeleportedNear())
return;
@@ -296,7 +296,7 @@ void WorldSession::HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMov
void WorldSession::HandleMovementOpcode(OpcodeClient opcode, MovementInfo& movementInfo)
{
Unit* mover = _player->m_unitMovedByMe;
Unit* mover = _player->GetUnitBeingMoved();
ASSERT(mover != nullptr); // there must always be a mover
@@ -529,8 +529,8 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPackets::Movement::MovementSpe
void WorldSession::HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover& packet)
{
if (GetPlayer()->IsInWorld())
if (_player->m_unitMovedByMe->GetGUID() != packet.ActiveMover)
TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s" , packet.ActiveMover.ToString().c_str(), _player->m_unitMovedByMe->GetGUID().ToString().c_str());
if (_player->GetUnitBeingMoved()->GetGUID() != packet.ActiveMover)
TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s" , packet.ActiveMover.ToString().c_str(), _player->GetUnitBeingMoved()->GetGUID().ToString().c_str());
}
void WorldSession::HandleMoveKnockBackAck(WorldPackets::Movement::MoveKnockBackAck& movementAck)

View File

@@ -43,7 +43,7 @@ void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet)
Player* user = _player;
// ignore for remote control state
if (user->m_unitMovedByMe != user)
if (user->GetUnitBeingMoved() != user)
return;
Item* item = user->GetUseableItemByPos(packet.PackSlot, packet.Slot);
@@ -137,7 +137,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet)
Player* player = GetPlayer();
// ignore for remote control state
if (player->m_unitMovedByMe != player)
if (player->GetUnitBeingMoved() != player)
return;
TC_LOG_INFO("network", "bagIndex: %u, slot: %u", packet.Slot, packet.PackSlot);
@@ -248,8 +248,8 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUs
if (GameObject* obj = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid))
{
// ignore for remote control state
if (GetPlayer()->m_unitMovedByMe != GetPlayer())
if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_unitMovedByMe) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
if (GetPlayer()->GetUnitBeingMoved() != GetPlayer())
if (!(GetPlayer()->IsOnVehicle(GetPlayer()->GetUnitBeingMoved()) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
return;
obj->Use(GetPlayer());
@@ -259,7 +259,7 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUs
void WorldSession::HandleGameobjectReportUse(WorldPackets::GameObject::GameObjReportUse& packet)
{
// ignore for remote control state
if (_player->m_unitMovedByMe != _player)
if (_player->GetUnitBeingMoved() != _player)
return;
if (GameObject* go = GetPlayer()->GetGameObjectIfCanInteractWith(packet.Guid))
@@ -274,7 +274,7 @@ void WorldSession::HandleGameobjectReportUse(WorldPackets::GameObject::GameObjRe
void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast)
{
// ignore for remote control state (for player case)
Unit* mover = _player->m_unitMovedByMe;
Unit* mover = _player->GetUnitBeingMoved();
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
return;
@@ -482,7 +482,7 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode(WorldPackets::Spells::Cance
void WorldSession::HandleCancelChanneling(WorldPackets::Spells::CancelChannelling& /*cancelChanneling*/)
{
// ignore for remote control state (for player case)
Unit* mover = _player->m_unitMovedByMe;
Unit* mover = _player->GetUnitBeingMoved();
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
return;
@@ -492,7 +492,7 @@ void WorldSession::HandleCancelChanneling(WorldPackets::Spells::CancelChannellin
void WorldSession::HandleTotemDestroyed(WorldPackets::Totem::TotemDestroyed& totemDestroyed)
{
// ignore for remote control state
if (_player->m_unitMovedByMe != _player)
if (_player->GetUnitBeingMoved() != _player)
return;
uint8 slotId = totemDestroyed.Slot;