mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-24 22:26:22 +00:00
fix(Core/Movement): Implement order counters (#23015)
This commit is contained in:
@@ -1998,7 +1998,7 @@ void Creature::setDeathState(DeathState state, bool despawn)
|
||||
m_formation->FormationReset(true, false);
|
||||
|
||||
bool needsFalling = !despawn && (IsFlying() || IsHovering()) && !IsUnderWater();
|
||||
SetHover(false, false, false);
|
||||
SetHover(false);
|
||||
SetDisableGravity(false, false, false);
|
||||
|
||||
if (needsFalling)
|
||||
@@ -3244,8 +3244,9 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly /*= false*/, bool
|
||||
{
|
||||
WorldPacket data(disable ? SMSG_MOVE_GRAVITY_DISABLE : SMSG_MOVE_GRAVITY_ENABLE, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
data << m_movedByPlayer->ToPlayer()->GetSession()->GetOrderCounter(); // movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
m_movedByPlayer->ToPlayer()->GetSession()->IncrementOrderCounter();
|
||||
|
||||
data.Initialize(MSG_MOVE_GRAVITY_CHNG, 64);
|
||||
data << GetPackGUID();
|
||||
@@ -3318,107 +3319,6 @@ void Creature::RefreshSwimmingFlag(bool recheck)
|
||||
SetUnitFlag(UNIT_FLAG_SWIMMING);
|
||||
}
|
||||
|
||||
bool Creature::SetCanFly(bool enable, bool /*packetOnly*/ /* = false */)
|
||||
{
|
||||
if (!Unit::SetCanFly(enable))
|
||||
return false;
|
||||
|
||||
if (m_movedByPlayer)
|
||||
{
|
||||
sScriptMgr->AnticheatSetCanFlybyServer(m_movedByPlayer->ToPlayer(), enable);
|
||||
|
||||
if (!enable)
|
||||
m_movedByPlayer->ToPlayer()->SetFallInformation(GameTime::GetGameTime().count(), m_movedByPlayer->ToPlayer()->GetPositionZ());
|
||||
|
||||
WorldPacket data(enable ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_UPDATE_CAN_FLY, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
m_movedByPlayer->ToPlayer()->SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_FLYING : SMSG_SPLINE_MOVE_UNSET_FLYING, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Creature::SetWaterWalking(bool enable, bool packetOnly /* = false */)
|
||||
{
|
||||
if (!packetOnly && !Unit::SetWaterWalking(enable))
|
||||
return false;
|
||||
|
||||
if (m_movedByPlayer)
|
||||
{
|
||||
WorldPacket data(enable ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_WATER_WALK, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
m_movedByPlayer->ToPlayer()->SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_WATER_WALK : SMSG_SPLINE_MOVE_LAND_WALK, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Creature::SetFeatherFall(bool enable, bool packetOnly /* = false */)
|
||||
{
|
||||
if (!packetOnly && !Unit::SetFeatherFall(enable))
|
||||
return false;
|
||||
|
||||
if (m_movedByPlayer)
|
||||
{
|
||||
WorldPacket data(enable ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_FEATHER_FALL, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
m_movedByPlayer->ToPlayer()->SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_FEATHER_FALL : SMSG_SPLINE_MOVE_NORMAL_FALL, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Creature::SetHover(bool enable, bool packetOnly /*= false*/, bool updateAnimationTier /*= true*/)
|
||||
{
|
||||
if (!packetOnly && !Unit::SetHover(enable))
|
||||
return false;
|
||||
|
||||
if (updateAnimationTier && IsAlive() && !HasUnitState(UNIT_STATE_ROOT) && !IsRooted())
|
||||
{
|
||||
if (IsLevitating())
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_FLY);
|
||||
else if (IsHovering())
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_HOVER);
|
||||
else
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, UNIT_BYTE1_FLAG_GROUND);
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
float Creature::GetAggroRange(Unit const* target) const
|
||||
{
|
||||
// Determines the aggro range for creatures
|
||||
|
||||
@@ -143,10 +143,6 @@ public:
|
||||
bool SetWalk(bool enable) override;
|
||||
bool SetDisableGravity(bool disable, bool packetOnly = false, bool updateAnimationTier = true) override;
|
||||
bool SetSwim(bool enable) override;
|
||||
bool SetCanFly(bool enable, bool packetOnly = false) override;
|
||||
bool SetWaterWalking(bool enable, bool packetOnly = false) override;
|
||||
bool SetFeatherFall(bool enable, bool packetOnly = false) override;
|
||||
bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true) override;
|
||||
bool HasSpellFocus(Spell const* focusSpell = nullptr) const;
|
||||
|
||||
struct
|
||||
|
||||
@@ -1337,9 +1337,10 @@ void Player::SendTeleportAckPacket()
|
||||
{
|
||||
WorldPacket data(MSG_MOVE_TELEPORT_ACK, 41);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); // this value increments every time
|
||||
data << GetSession()->GetOrderCounter(); // movement counter
|
||||
BuildMovementPacket(&data);
|
||||
GetSession()->SendPacket(&data);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit* target /*= nullptr*/, bool newInstance /*= false*/)
|
||||
@@ -4425,27 +4426,29 @@ void Player::DeleteOldRecoveryItems(uint32 keepDays)
|
||||
void Player::SetMovement(PlayerMovementType pType)
|
||||
{
|
||||
WorldPacket data;
|
||||
const PackedGuid& guid = GetPackGUID();
|
||||
switch (pType)
|
||||
{
|
||||
case MOVE_ROOT:
|
||||
data.Initialize(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size() + 4);
|
||||
data.Initialize(SMSG_FORCE_MOVE_ROOT, guid.size() + 4);
|
||||
break;
|
||||
case MOVE_UNROOT:
|
||||
data.Initialize(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size() + 4);
|
||||
data.Initialize(SMSG_FORCE_MOVE_UNROOT, guid.size() + 4);
|
||||
break;
|
||||
case MOVE_WATER_WALK:
|
||||
data.Initialize(SMSG_MOVE_WATER_WALK, GetPackGUID().size() + 4);
|
||||
data.Initialize(SMSG_MOVE_WATER_WALK, guid.size() + 4);
|
||||
break;
|
||||
case MOVE_LAND_WALK:
|
||||
data.Initialize(SMSG_MOVE_LAND_WALK, GetPackGUID().size() + 4);
|
||||
data.Initialize(SMSG_MOVE_LAND_WALK, guid.size() + 4);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("entities.player", "Player::SetMovement: Unsupported move type ({}), data not sent to client.", pType);
|
||||
return;
|
||||
}
|
||||
data << GetPackGUID();
|
||||
data << uint32(0);
|
||||
data << guid;
|
||||
data << GetSession()->GetOrderCounter(); // movement counter
|
||||
GetSession()->SendPacket(&data);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
/* Preconditions:
|
||||
@@ -11701,13 +11704,56 @@ void Player::SendInitialPacketsAfterAddToMap()
|
||||
if (HasStunAura())
|
||||
SetMovement(MOVE_ROOT);
|
||||
|
||||
WorldPacket setCompoundState(SMSG_MULTIPLE_MOVES, 100);
|
||||
setCompoundState << uint32(0); // size placeholder
|
||||
|
||||
// manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that must not be re-applied.
|
||||
if (HasRootAura())
|
||||
if (IsImmobilizedState())
|
||||
{
|
||||
WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
|
||||
data2 << GetPackGUID();
|
||||
data2 << (uint32)2;
|
||||
SendMessageToSet(&data2, true);
|
||||
auto const counter = GetSession()->GetOrderCounter();
|
||||
setCompoundState << uint8(2 + GetPackGUID().size() + 4);
|
||||
setCompoundState << uint16(SMSG_FORCE_MOVE_ROOT);
|
||||
setCompoundState << GetPackGUID();
|
||||
setCompoundState << uint32(counter);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
if (HasAuraType(SPELL_AURA_FEATHER_FALL))
|
||||
{
|
||||
auto const counter = GetSession()->GetOrderCounter();
|
||||
setCompoundState << uint8(2 + GetPackGUID().size() + 4);
|
||||
setCompoundState << uint16(SMSG_MOVE_FEATHER_FALL);
|
||||
setCompoundState << GetPackGUID();
|
||||
setCompoundState << uint32(counter);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
if (HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
{
|
||||
auto const counter = GetSession()->GetOrderCounter();
|
||||
setCompoundState << uint8(2 + GetPackGUID().size() + 4);
|
||||
setCompoundState << uint16(SMSG_MOVE_WATER_WALK);
|
||||
setCompoundState << GetPackGUID();
|
||||
setCompoundState << uint32(counter);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
if (HasAuraType(SPELL_AURA_HOVER))
|
||||
{
|
||||
auto const counter = GetSession()->GetOrderCounter();
|
||||
setCompoundState << uint8(2 + GetPackGUID().size() + 4);
|
||||
setCompoundState << uint16(SMSG_MOVE_SET_HOVER);
|
||||
setCompoundState << GetPackGUID();
|
||||
setCompoundState << uint32(counter);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
// TODO: Pending mount protocol
|
||||
|
||||
if (setCompoundState.size() > 4)
|
||||
{
|
||||
setCompoundState.put<uint32>(0, setCompoundState.size() - 4);
|
||||
SendDirectMessage(&setCompoundState);
|
||||
}
|
||||
|
||||
SendEnchantmentDurations(); // must be after add to map
|
||||
@@ -15932,8 +15978,9 @@ bool Player::SetDisableGravity(bool disable, bool packetOnly /*= false*/, bool /
|
||||
|
||||
WorldPacket data(disable ? SMSG_MOVE_GRAVITY_DISABLE : SMSG_MOVE_GRAVITY_ENABLE, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
data << GetSession()->GetOrderCounter(); // movement counter
|
||||
SendDirectMessage(&data);
|
||||
GetSession()->IncrementOrderCounter();
|
||||
|
||||
data.Initialize(MSG_MOVE_GRAVITY_CHNG, 64);
|
||||
data << GetPackGUID();
|
||||
@@ -15942,91 +15989,6 @@ bool Player::SetDisableGravity(bool disable, bool packetOnly /*= false*/, bool /
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::SetCanFly(bool apply, bool packetOnly /*= false*/)
|
||||
{
|
||||
sScriptMgr->AnticheatSetCanFlybyServer(this, apply);
|
||||
|
||||
if (!packetOnly && !Unit::SetCanFly(apply))
|
||||
return false;
|
||||
|
||||
if (!apply)
|
||||
SetFallInformation(GameTime::GetGameTime().count(), GetPositionZ());
|
||||
|
||||
WorldPacket data(apply ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_UPDATE_CAN_FLY, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::SetHover(bool apply, bool packetOnly /*= false*/, bool /*updateAnimationTier = true*/)
|
||||
{
|
||||
// moved inside, flag can be removed on landing and wont send appropriate packet to client when aura is removed
|
||||
if (!packetOnly /* && !Unit::SetHover(apply)*/)
|
||||
{
|
||||
Unit::SetHover(apply);
|
||||
// return false;
|
||||
}
|
||||
|
||||
WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_HOVER, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::SetWaterWalking(bool apply, bool packetOnly /*= false*/)
|
||||
{
|
||||
// moved inside, flag can be removed on landing and wont send appropriate packet to client when aura is removed
|
||||
if (!packetOnly /* && !Unit::SetWaterWalking(apply)*/)
|
||||
{
|
||||
Unit::SetWaterWalking(apply);
|
||||
// return false;
|
||||
}
|
||||
|
||||
WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_WATER_WALK, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Player::SetFeatherFall(bool apply, bool packetOnly /*= false*/)
|
||||
{
|
||||
// Xinef: moved inside, flag can be removed on landing and wont send appropriate packet to client when aura is removed
|
||||
if (!packetOnly/* && !Unit::SetFeatherFall(apply)*/)
|
||||
{
|
||||
Unit::SetFeatherFall(apply);
|
||||
//return false;
|
||||
}
|
||||
|
||||
WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12);
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); //! movement counter
|
||||
SendDirectMessage(&data);
|
||||
|
||||
data.Initialize(MSG_MOVE_FEATHER_FALL, 64);
|
||||
data << GetPackGUID();
|
||||
BuildMovementPacket(&data);
|
||||
SendMessageToSet(&data, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
Guild* Player::GetGuild() const
|
||||
{
|
||||
uint32 guildId = GetGuildId();
|
||||
|
||||
@@ -2564,13 +2564,10 @@ public:
|
||||
void RemoveFromWhisperWhiteList(ObjectGuid guid) { WhisperList.remove(guid); }
|
||||
|
||||
bool SetDisableGravity(bool disable, bool packetOnly = false, bool updateAnimationTier = true) override;
|
||||
bool SetCanFly(bool apply, bool packetOnly = false) override;
|
||||
bool SetWaterWalking(bool apply, bool packetOnly = false) override;
|
||||
bool SetFeatherFall(bool apply, bool packetOnly = false) override;
|
||||
bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true) override;
|
||||
|
||||
[[nodiscard]] bool CanFly() const override { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
|
||||
[[nodiscard]] bool CanEnterWater() const override { return true; }
|
||||
bool IsFreeFlying() const { return HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || HasAuraType(SPELL_AURA_FLY); }
|
||||
|
||||
// saving
|
||||
void AdditionalSavingAddMask(uint8 mask) { m_additionalSaveTimer = 2000; m_additionalSaveMask |= mask; }
|
||||
|
||||
@@ -244,8 +244,6 @@ Unit::Unit() : WorldObject(),
|
||||
|
||||
_dualWieldMode = DualWieldMode::AUTO;
|
||||
|
||||
m_rootTimes = 0;
|
||||
|
||||
m_state = 0;
|
||||
m_deathState = DeathState::Alive;
|
||||
|
||||
@@ -4332,10 +4330,10 @@ void Unit::ProcessTerrainStatusUpdate()
|
||||
|
||||
LiquidData const& liquidData = GetLiquidData();
|
||||
|
||||
// remove appropriate auras if we are swimming/not swimming respectively
|
||||
if (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING)
|
||||
// remove appropriate auras if we are swimming/not swimming respectively - exact mirror of client logic
|
||||
if (liquidData.Status & MAP_LIQUID_STATUS_SWIMMING && (liquidData.Level - GetPositionZ()) > GetCollisionHeight() * 0.75f) // Shallow water at ~75% of collision height)
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_ABOVEWATER);
|
||||
else if (!isSwimming())
|
||||
else
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_NOT_UNDERWATER);
|
||||
|
||||
// liquid aura handling
|
||||
@@ -13607,9 +13605,10 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
|
||||
|
||||
WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
|
||||
data << GetPackGUID();
|
||||
data << uint32(GameTime::GetGameTime().count()); // Packet counter
|
||||
data << player->GetSession()->GetOrderCounter(); // movement counter
|
||||
data << player->GetCollisionHeight();
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
|
||||
@@ -13623,13 +13622,14 @@ void Unit::Dismount()
|
||||
SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
|
||||
RemoveUnitFlag(UNIT_FLAG_MOUNT);
|
||||
|
||||
if (Player* thisPlayer = ToPlayer())
|
||||
if (Player* player = ToPlayer())
|
||||
{
|
||||
WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
|
||||
data << GetPackGUID();
|
||||
data << uint32(GameTime::GetGameTime().count()); // Packet counter
|
||||
data << thisPlayer->GetCollisionHeight();
|
||||
thisPlayer->GetSession()->SendPacket(&data);
|
||||
data << player->GetSession()->GetOrderCounter(); // movement counter
|
||||
data << player->GetCollisionHeight();
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
|
||||
WorldPacket data(SMSG_DISMOUNT, 8);
|
||||
@@ -14643,11 +14643,13 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
|
||||
return;
|
||||
}
|
||||
data << GetPackGUID();
|
||||
data << (uint32)0; // moveEvent, NUM_PMOVE_EVTS = 0x39
|
||||
data << (IsPlayer() ? ToPlayer()->GetSession()->GetOrderCounter() : uint32(0)); // movement counter
|
||||
if (mtype == MOVE_RUN)
|
||||
data << uint8(0); // new 2.1.0
|
||||
data << float(GetSpeed(mtype));
|
||||
SendMessageToSet(&data, true);
|
||||
if (IsPlayer()) // TODO: Resolve this mess
|
||||
ToPlayer()->GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16806,6 +16808,15 @@ bool Unit::IsStandState() const
|
||||
return !IsSitState() && s != UNIT_STAND_STATE_SLEEP && s != UNIT_STAND_STATE_KNEEL;
|
||||
}
|
||||
|
||||
bool Unit::IsStandUpOnMovementState() const
|
||||
{
|
||||
uint8 s = getStandState();
|
||||
return
|
||||
s == UNIT_STAND_STATE_SIT_CHAIR || s == UNIT_STAND_STATE_SIT_LOW_CHAIR ||
|
||||
s == UNIT_STAND_STATE_SIT_MEDIUM_CHAIR || s == UNIT_STAND_STATE_SIT_HIGH_CHAIR ||
|
||||
s == UNIT_STAND_STATE_SIT || s == UNIT_STAND_STATE_SLEEP;
|
||||
}
|
||||
|
||||
void Unit::SetStandState(uint8 state)
|
||||
{
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_STAND_STATE, state);
|
||||
@@ -18302,9 +18313,6 @@ void Unit::SetRooted(bool apply, bool isStun)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
if (m_rootTimes > 0) // blizzard internal check?
|
||||
m_rootTimes++;
|
||||
|
||||
// MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
|
||||
// this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
|
||||
// setting MOVEMENTFLAG_ROOT
|
||||
@@ -18336,8 +18344,9 @@ void Unit::SetRooted(bool apply, bool isStun)
|
||||
{
|
||||
WorldPacket data(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size() + 4);
|
||||
data << GetPackGUID();
|
||||
data << m_rootTimes;
|
||||
data << m_movedByPlayer->ToPlayer()->GetSession()->GetOrderCounter(); // movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
m_movedByPlayer->ToPlayer()->GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -18356,8 +18365,9 @@ void Unit::SetRooted(bool apply, bool isStun)
|
||||
{
|
||||
WorldPacket data(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size() + 4);
|
||||
data << GetPackGUID();
|
||||
data << m_rootTimes;
|
||||
data << m_movedByPlayer->ToPlayer()->GetSession()->GetOrderCounter(); // movement counter
|
||||
m_movedByPlayer->ToPlayer()->SendDirectMessage(&data);
|
||||
m_movedByPlayer->ToPlayer()->GetSession()->IncrementOrderCounter();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -19261,16 +19271,14 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
|
||||
|
||||
WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8 + 4 + 4 + 4 + 4 + 4));
|
||||
data << GetPackGUID();
|
||||
data << uint32(0); // counter
|
||||
data << player->GetSession()->GetOrderCounter(); // movement counter
|
||||
data << float(vcos); // x direction
|
||||
data << float(vsin); // y direction
|
||||
data << float(speedXY); // Horizontal speed
|
||||
data << float(-speedZ); // Z Movement speed (vertical)
|
||||
|
||||
player->GetSession()->SendPacket(&data);
|
||||
|
||||
if (player->HasIncreaseMountedFlightSpeedAura() || player->HasFlyAura())
|
||||
player->SetCanFly(true, true);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
|
||||
player->SetCanKnockback(true);
|
||||
}
|
||||
@@ -20464,39 +20472,168 @@ bool Unit::SetSwim(bool enable)
|
||||
*
|
||||
* Doesn't inform the client.
|
||||
*/
|
||||
bool Unit::SetCanFly(bool enable, bool /*packetOnly = false */)
|
||||
void Unit::SetCanFly(bool enable)
|
||||
{
|
||||
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
|
||||
return false;
|
||||
bool isClientControlled = IsClientControlled();
|
||||
|
||||
if (enable)
|
||||
if (!isClientControlled)
|
||||
{
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_MASK_MOVING_FLY);
|
||||
if (enable)
|
||||
m_movementInfo.AddMovementFlag(MOVEMENTFLAG_CAN_FLY);
|
||||
else
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_CAN_FLY);
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!IsInWorld()) // is sent on add to map
|
||||
return;
|
||||
|
||||
if (isClientControlled)
|
||||
{
|
||||
if (Player const* player = GetClientControlling())
|
||||
{
|
||||
auto const counter = player->GetSession()->GetOrderCounter();
|
||||
|
||||
WorldPacket data(enable ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY, GetPackGUID().size() + 4);
|
||||
data << GetPackGUID();
|
||||
data << counter;
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_FLYING : SMSG_SPLINE_MOVE_UNSET_FLYING, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allow to walk on water. Doesn't inform the client.
|
||||
* Need to use SendMovementWaterWalking() if it's for players.
|
||||
*/
|
||||
bool Unit::SetWaterWalking(bool enable, bool /*packetOnly = false*/)
|
||||
void Unit::SetFeatherFall(bool enable)
|
||||
{
|
||||
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
|
||||
return false;
|
||||
bool isClientControlled = IsClientControlled();
|
||||
|
||||
if (!isClientControlled)
|
||||
{
|
||||
if (enable)
|
||||
m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
|
||||
else
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
|
||||
}
|
||||
|
||||
if (!IsInWorld()) // is sent on add to map
|
||||
return;
|
||||
|
||||
if (isClientControlled)
|
||||
{
|
||||
if (Player const* player = GetClientControlling())
|
||||
{
|
||||
auto const counter = player->GetSession()->GetOrderCounter();
|
||||
|
||||
WorldPacket data(enable ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, GetPackGUID().size() + 4);
|
||||
|
||||
data << GetPackGUID();
|
||||
data << counter;
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
|
||||
// start fall from current height
|
||||
if (!enable)
|
||||
const_cast<Player*>(player)->SetFallInformation(0, GetPositionZ());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_FEATHER_FALL : SMSG_SPLINE_MOVE_NORMAL_FALL);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Unit::SetHover(bool enable)
|
||||
{
|
||||
bool isClientControlled = IsClientControlled();
|
||||
|
||||
if (!isClientControlled)
|
||||
{
|
||||
if (enable)
|
||||
m_movementInfo.AddMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
else
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
}
|
||||
|
||||
float hoverHeight = GetHoverHeight();
|
||||
|
||||
if (enable)
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
|
||||
{
|
||||
if (hoverHeight && GetPositionZ() - GetMap()->GetHeight(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ()) < hoverHeight)
|
||||
Relocate(GetPositionX(), GetPositionY(), GetPositionZ() + hoverHeight);
|
||||
}
|
||||
else
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
|
||||
{
|
||||
if (IsAlive() || !IsUnit())
|
||||
{
|
||||
float newZ = std::max<float>(GetMap()->GetHeight(GetPhaseMask(), GetPositionX(), GetPositionY(), GetPositionZ()), GetPositionZ() - hoverHeight);
|
||||
UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
|
||||
Relocate(GetPositionX(), GetPositionY(), newZ);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
if (!IsInWorld()) // is sent on add to map
|
||||
return;
|
||||
|
||||
if (isClientControlled)
|
||||
{
|
||||
if (Player const* player = GetClientControlling())
|
||||
{
|
||||
WorldPacket data(enable ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, GetPackGUID().size() + 4);
|
||||
|
||||
auto const counter = player->GetSession()->GetOrderCounter();
|
||||
|
||||
data << GetPackGUID();
|
||||
data << counter;
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Unit::SetWaterWalking(bool enable)
|
||||
{
|
||||
bool isClientControlled = IsClientControlled();
|
||||
|
||||
if (!isClientControlled)
|
||||
{
|
||||
if (enable)
|
||||
m_movementInfo.AddMovementFlag(MOVEMENTFLAG_WATERWALKING);
|
||||
else
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_WATERWALKING);
|
||||
}
|
||||
|
||||
if (!IsInWorld()) // is sent on add to map
|
||||
return;
|
||||
|
||||
if (isClientControlled)
|
||||
{
|
||||
if (Player const* player = GetClientControlling())
|
||||
{
|
||||
auto const counter = player->GetSession()->GetOrderCounter();
|
||||
|
||||
WorldPacket data(enable ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, GetPackGUID().size() + 4);
|
||||
data << GetPackGUID();
|
||||
data << counter;
|
||||
player->GetSession()->SendPacket(&data);
|
||||
player->GetSession()->IncrementOrderCounter();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket data(enable ? SMSG_SPLINE_MOVE_WATER_WALK : SMSG_SPLINE_MOVE_LAND_WALK, 9);
|
||||
data << GetPackGUID();
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void Unit::SendMovementWaterWalking(Player* sendTo)
|
||||
@@ -20508,19 +20645,6 @@ void Unit::SendMovementWaterWalking(Player* sendTo)
|
||||
sendTo->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
bool Unit::SetFeatherFall(bool enable, bool /*packetOnly = false*/)
|
||||
{
|
||||
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
|
||||
return false;
|
||||
|
||||
if (enable)
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
|
||||
else
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::SendMovementFeatherFall(Player* sendTo)
|
||||
{
|
||||
if (!movespline->Initialized())
|
||||
@@ -20530,34 +20654,6 @@ void Unit::SendMovementFeatherFall(Player* sendTo)
|
||||
sendTo->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
bool Unit::SetHover(bool enable, bool /*packetOnly = false*/, bool /*updateAnimationTier = true*/)
|
||||
{
|
||||
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
|
||||
return false;
|
||||
|
||||
float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
if (hoverHeight && GetPositionZ() - GetFloorZ() < hoverHeight)
|
||||
UpdateHeight(GetPositionZ() + hoverHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
|
||||
if (hoverHeight && (!isDying() || !IsCreature()))
|
||||
{
|
||||
float newZ = std::max<float>(GetFloorZ(), GetPositionZ() - hoverHeight);
|
||||
UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
|
||||
UpdateHeight(newZ);
|
||||
}
|
||||
SendMovementFlagUpdate(); // pussywizard: needed for falling after death (instead of falling onto air at hover height)
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::SendMovementHover(Player* sendTo)
|
||||
{
|
||||
if (!movespline->Initialized())
|
||||
@@ -21203,3 +21299,58 @@ std::string Unit::GetDebugInfo() const
|
||||
<< " Class: " << std::to_string(getClass());
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
bool Unit::IsClientControlled(Player const* exactClient /*= nullptr*/) const
|
||||
{
|
||||
// Severvide method to check if unit is client controlled (optionally check for specific client in control)
|
||||
|
||||
// Applies only to player controlled units
|
||||
if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
|
||||
return false;
|
||||
|
||||
// These flags are meant to be used when server controls this unit, client control is taken away
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING)))
|
||||
return false;
|
||||
|
||||
// If unit is possessed, it has lost original control...
|
||||
if (ObjectGuid const& guid = GetCharmerGUID())
|
||||
{
|
||||
// ... but if it is a possessing charm, then we have to check if some other player controls it
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED) && guid.IsPlayer())
|
||||
return (exactClient ? (exactClient->GetGUID() == guid) : true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// By default: players have client control over themselves
|
||||
if (IsPlayer())
|
||||
return (exactClient ? (exactClient == this) : true);
|
||||
return false;
|
||||
}
|
||||
|
||||
Player const* Unit::GetClientControlling() const
|
||||
{
|
||||
// Serverside reverse "mover" deduction logic at controlled unit
|
||||
|
||||
// Applies only to player controlled units
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED))
|
||||
{
|
||||
// Charm always removes control from original client...
|
||||
if (GetCharmerGUID())
|
||||
{
|
||||
// ... but if it is a possessing charm, some other client may have control
|
||||
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_POSSESSED))
|
||||
{
|
||||
Unit const* charmer = GetCharmer();
|
||||
if (charmer && charmer->IsPlayer())
|
||||
return static_cast<Player const*>(charmer);
|
||||
}
|
||||
}
|
||||
else if (IsPlayer())
|
||||
{
|
||||
// Check if anything prevents original client from controlling
|
||||
if (IsClientControlled(static_cast<Player const*>(this)))
|
||||
return static_cast<Player const*>(this);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -744,6 +744,7 @@ public:
|
||||
void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; }
|
||||
|
||||
inline bool IsCrowdControlled() const { return HasFlag(UNIT_FIELD_FLAGS, (UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_STUNNED)); }
|
||||
inline bool IsImmobilizedState() const { return HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED); }
|
||||
|
||||
/*********************************************************/
|
||||
/*** UNIT TYPES, CLASSES, RACES... ***/
|
||||
@@ -826,6 +827,11 @@ public:
|
||||
bool IsValidAssistTarget(Unit const* target) const;
|
||||
bool _IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) const;
|
||||
|
||||
// Client controlled: check if unit currently is under client control (has active "mover"), optionally check for specific client (server-side)
|
||||
bool IsClientControlled(Player const* exactClient = nullptr) const;
|
||||
// Controlling client: server PoV on which client (player) controls movement of the unit at the moment, obtain "mover" (server-side)
|
||||
Player const* GetClientControlling() const;
|
||||
|
||||
// Combat range
|
||||
[[nodiscard]] float GetBoundaryRadius() const { return m_floatValues[UNIT_FIELD_BOUNDINGRADIUS]; }
|
||||
[[nodiscard]] float GetCombatReach() const override { return m_floatValues[UNIT_FIELD_COMBATREACH]; }
|
||||
@@ -1676,10 +1682,10 @@ public:
|
||||
virtual bool SetWalk(bool enable);
|
||||
virtual bool SetDisableGravity(bool disable, bool packetOnly = false, bool updateAnimationTier = true);
|
||||
virtual bool SetSwim(bool enable);
|
||||
virtual bool SetCanFly(bool enable, bool packetOnly = false);
|
||||
virtual bool SetWaterWalking(bool enable, bool packetOnly = false);
|
||||
virtual bool SetFeatherFall(bool enable, bool packetOnly = false);
|
||||
virtual bool SetHover(bool enable, bool packetOnly = false, bool updateAnimationTier = true);
|
||||
void SetCanFly(bool enable);
|
||||
void SetWaterWalking(bool enable);
|
||||
void SetFeatherFall(bool enable);
|
||||
void SetHover(bool enable);
|
||||
|
||||
MotionMaster* GetMotionMaster() { return i_motionMaster; }
|
||||
[[nodiscard]] const MotionMaster* GetMotionMaster() const { return i_motionMaster; }
|
||||
@@ -1706,6 +1712,7 @@ public:
|
||||
[[nodiscard]] uint8 getStandState() const { return GetByteValue(UNIT_FIELD_BYTES_1, 0); }
|
||||
[[nodiscard]] bool IsSitState() const;
|
||||
[[nodiscard]] bool IsStandState() const;
|
||||
[[nodiscard]] bool IsStandUpOnMovementState() const;
|
||||
void SetStandState(uint8 state);
|
||||
|
||||
void SetStandFlags(uint8 flags) { SetByteFlag(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_VIS_FLAG, flags); }
|
||||
@@ -2129,8 +2136,6 @@ protected:
|
||||
bool m_applyResilience;
|
||||
bool _instantCast;
|
||||
|
||||
uint32 m_rootTimes;
|
||||
|
||||
private:
|
||||
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent, ProcEventInfo const& eventInfo);
|
||||
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, ProcEventInfo const& eventInfo);
|
||||
|
||||
@@ -412,6 +412,8 @@ enum MovementFlags
|
||||
MOVEMENTFLAG_MASK_PLAYER_ONLY =
|
||||
MOVEMENTFLAG_FLYING,
|
||||
|
||||
MOVEMENTFLAG_MASK_MOVING_OR_TURN = MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING,
|
||||
|
||||
/// Movement flags that have change status opcodes associated for players
|
||||
MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT |
|
||||
MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER
|
||||
|
||||
@@ -949,12 +949,6 @@ void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recv_data*/)
|
||||
GetPlayer()->GetCinematicMgr()->BeginCinematic();
|
||||
}
|
||||
|
||||
void WorldSession::HandleFeatherFallAck(WorldPacket& recv_data)
|
||||
{
|
||||
// no used
|
||||
recv_data.rfinish(); // prevent warnings spam
|
||||
}
|
||||
|
||||
void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data)
|
||||
{
|
||||
uint8 ActionBar;
|
||||
@@ -1519,12 +1513,13 @@ void WorldSession::HandleCancelMountAuraOpcode(WorldPacket& /*recv_data*/)
|
||||
_player->RemoveAurasByType(SPELL_AURA_MOUNTED);
|
||||
}
|
||||
|
||||
void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data)
|
||||
void WorldSession::HandleMoveFlagChangeOpcode(WorldPacket& recv_data)
|
||||
{
|
||||
// fly mode on/off
|
||||
LOG_DEBUG("network", "WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
|
||||
LOG_DEBUG("network", "WORLD: {}", GetOpcodeNameForLogging((Opcodes)recv_data.GetOpcode()));
|
||||
|
||||
ObjectGuid guid;
|
||||
uint32 counter;
|
||||
uint32 isApplied;
|
||||
recv_data >> guid.ReadAsPacked();
|
||||
|
||||
if (!_player)
|
||||
@@ -1533,17 +1528,42 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data)
|
||||
return;
|
||||
}
|
||||
|
||||
recv_data.read_skip<uint32>(); // unk
|
||||
recv_data >> counter;
|
||||
|
||||
MovementInfo movementInfo;
|
||||
movementInfo.guid = guid;
|
||||
ReadMovementInfo(recv_data, &movementInfo);
|
||||
|
||||
recv_data.read_skip<float>(); // unk2
|
||||
recv_data >> isApplied;
|
||||
|
||||
sScriptMgr->AnticheatSetCanFlybyServer(_player, movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY));
|
||||
|
||||
_player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
|
||||
Unit* mover = _player->m_mover;
|
||||
Player* plrMover = mover->ToPlayer();
|
||||
|
||||
mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
|
||||
|
||||
Opcodes response;
|
||||
|
||||
switch (recv_data.GetOpcode())
|
||||
{
|
||||
case CMSG_MOVE_HOVER_ACK: response = MSG_MOVE_HOVER; break;
|
||||
case CMSG_MOVE_FEATHER_FALL_ACK: response = MSG_MOVE_FEATHER_FALL; break;
|
||||
case CMSG_MOVE_WATER_WALK_ACK: response = MSG_MOVE_WATER_WALK; break;
|
||||
case CMSG_MOVE_SET_CAN_FLY_ACK: response = MSG_MOVE_UPDATE_CAN_FLY; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (!ProcessMovementInfo(movementInfo, mover, plrMover, recv_data))
|
||||
{
|
||||
recv_data.rfinish(); // prevent warnings spam
|
||||
return;
|
||||
}
|
||||
|
||||
WorldPacket data(response, 8);
|
||||
data << guid.WriteAsPacked();
|
||||
WriteMovementInfo(&data, &movementInfo);
|
||||
_player->m_mover->SendMessageToSet(&data, _player);
|
||||
}
|
||||
|
||||
void WorldSession::HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& /*packet*/)
|
||||
|
||||
@@ -370,82 +370,44 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
|
||||
movementInfo.guid = guid;
|
||||
ReadMovementInfo(recvData, &movementInfo);
|
||||
|
||||
// Stop emote on move
|
||||
if (Player* plrMover = mover->ToPlayer())
|
||||
{
|
||||
if (plrMover->GetUInt32Value(UNIT_NPC_EMOTESTATE) != EMOTE_ONESHOT_NONE && movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
|
||||
{
|
||||
plrMover->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!movementInfo.pos.IsPositionValid())
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
}
|
||||
|
||||
recvData.rfinish(); // prevent warnings spam
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mover->movespline->Finalized())
|
||||
if (!ProcessMovementInfo(movementInfo, mover, plrMover, recvData))
|
||||
{
|
||||
recvData.rfinish(); // prevent warnings spam
|
||||
return;
|
||||
}
|
||||
|
||||
// Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
|
||||
if (mover->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
|
||||
{
|
||||
// Xinef: skip moving packets
|
||||
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
}
|
||||
return;
|
||||
}
|
||||
movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
|
||||
/* process position-change */
|
||||
WorldPacket data(opcode, recvData.size());
|
||||
movementInfo.guid = mover->GetGUID();
|
||||
WriteMovementInfo(&data, &movementInfo);
|
||||
mover->SendMessageToSet(&data, _player);
|
||||
}
|
||||
|
||||
if (mover->IsCreature())
|
||||
{
|
||||
movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
|
||||
movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ());
|
||||
movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
|
||||
}
|
||||
void WorldSession::SynchronizeMovement(MovementInfo& movementInfo)
|
||||
{
|
||||
int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
|
||||
if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
|
||||
{
|
||||
LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
|
||||
movementInfo.time = getMSTime();
|
||||
}
|
||||
|
||||
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
else
|
||||
{
|
||||
// We were teleported, skip packets that were broadcast before teleport
|
||||
if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
//LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
|
||||
}
|
||||
recvData.rfinish(); // prevent warnings spam
|
||||
return;
|
||||
}
|
||||
movementInfo.time = (uint32)movementTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
|
||||
movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
}
|
||||
void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover)
|
||||
{
|
||||
SynchronizeMovement(movementInfo);
|
||||
|
||||
recvData.rfinish(); // prevent warnings spam
|
||||
return;
|
||||
}
|
||||
mover->UpdatePosition(movementInfo.pos);
|
||||
mover->m_movementInfo = movementInfo;
|
||||
|
||||
if (mover->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
// if we boarded a transport, add us to it
|
||||
if (plrMover)
|
||||
if (Player* plrMover = mover->ToPlayer())
|
||||
{
|
||||
if (!plrMover->GetTransport())
|
||||
{
|
||||
@@ -483,13 +445,155 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
|
||||
else if (mover->IsPlayer())
|
||||
{
|
||||
sScriptMgr->AnticheatSetUnderACKmount(plrMover); // just for safe
|
||||
if (Player* plrMover = mover->ToPlayer())
|
||||
{
|
||||
if (plrMover->GetTransport()) // if we were on a transport, leave
|
||||
{
|
||||
sScriptMgr->AnticheatSetUnderACKmount(plrMover); // just for safe
|
||||
|
||||
plrMover->m_transport->RemovePassenger(plrMover);
|
||||
plrMover->m_transport = nullptr;
|
||||
movementInfo.transport.Reset();
|
||||
plrMover->m_transport->RemovePassenger(plrMover);
|
||||
plrMover->m_transport = nullptr;
|
||||
movementInfo.transport.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some vehicles allow the passenger to turn by himself
|
||||
if (Vehicle* vehicle = mover->GetVehicle())
|
||||
{
|
||||
if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
|
||||
{
|
||||
if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
|
||||
{
|
||||
mover->SetOrientation(movementInfo.pos.GetOrientation());
|
||||
mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Player* plrMover = mover->ToPlayer()) // nothing is charmed, or player charmed
|
||||
{
|
||||
if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
|
||||
plrMover->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
|
||||
{
|
||||
if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
|
||||
{
|
||||
if (plrMover->IsAlive())
|
||||
{
|
||||
plrMover->SetPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
|
||||
// player can be alive if GM
|
||||
if (plrMover->IsAlive())
|
||||
plrMover->KillPlayer();
|
||||
}
|
||||
else if (!plrMover->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
|
||||
{
|
||||
GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover, plrMover->GetTeamId());
|
||||
if (grave)
|
||||
{
|
||||
plrMover->TeleportTo(grave->Map, grave->x, grave->y, grave->z, plrMover->GetOrientation());
|
||||
plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WorldSession::VerifyMovementInfo(MovementInfo const& movementInfo, Player* plrMover, Unit* mover, Opcodes opcode) const
|
||||
{
|
||||
if (!movementInfo.pos.IsPositionValid())
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mover->movespline->Finalized())
|
||||
return false;
|
||||
|
||||
// Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
|
||||
if (mover->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
|
||||
{
|
||||
// Xinef: skip moving packets
|
||||
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool jumpopcode = false;
|
||||
if (opcode == MSG_MOVE_JUMP)
|
||||
{
|
||||
jumpopcode = true;
|
||||
if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
|
||||
{
|
||||
plrMover->GetSession()->KickPlayer();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* start some hack detection */
|
||||
if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
|
||||
{
|
||||
plrMover->GetSession()->KickPlayer();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
// We were teleported, skip packets that were broadcast before teleport
|
||||
if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
//LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
|
||||
movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
|
||||
{
|
||||
if (plrMover)
|
||||
{
|
||||
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldSession::ProcessMovementInfo(MovementInfo& movementInfo, Unit* mover, Player* plrMover, WorldPacket& recvData)
|
||||
{
|
||||
Opcodes opcode = (Opcodes)recvData.GetOpcode();
|
||||
if (!VerifyMovementInfo(movementInfo, plrMover, mover, opcode))
|
||||
return false;
|
||||
|
||||
if (mover->HasUnitFlag(UNIT_FLAG_DISABLE_MOVE))
|
||||
{
|
||||
movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
|
||||
|
||||
if (mover->IsCreature())
|
||||
{
|
||||
movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
|
||||
movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ());
|
||||
movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
|
||||
}
|
||||
}
|
||||
|
||||
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
|
||||
@@ -523,89 +627,19 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
|
||||
sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode);
|
||||
}
|
||||
|
||||
bool jumpopcode = false;
|
||||
if (opcode == MSG_MOVE_JUMP)
|
||||
if (movementInfo.GetMovementFlags() & MOVEMENTFLAG_MASK_MOVING_OR_TURN)
|
||||
{
|
||||
jumpopcode = true;
|
||||
if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
|
||||
{
|
||||
plrMover->GetSession()->KickPlayer();
|
||||
return;
|
||||
}
|
||||
if (mover->IsStandState())
|
||||
mover->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
mover->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
|
||||
}
|
||||
|
||||
/* start some hack detection */
|
||||
if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
|
||||
{
|
||||
plrMover->GetSession()->KickPlayer();
|
||||
return;
|
||||
}
|
||||
|
||||
/* process position-change */
|
||||
WorldPacket data(opcode, recvData.size());
|
||||
int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
|
||||
if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
|
||||
{
|
||||
LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
|
||||
movementInfo.time = getMSTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
movementInfo.time = (uint32) movementTime;
|
||||
}
|
||||
|
||||
movementInfo.guid = mover->GetGUID();
|
||||
WriteMovementInfo(&data, &movementInfo);
|
||||
mover->SendMessageToSet(&data, _player);
|
||||
|
||||
mover->m_movementInfo = movementInfo;
|
||||
|
||||
// Some vehicles allow the passenger to turn by himself
|
||||
if (Vehicle* vehicle = mover->GetVehicle())
|
||||
{
|
||||
if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
|
||||
{
|
||||
if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
|
||||
{
|
||||
mover->SetOrientation(movementInfo.pos.GetOrientation());
|
||||
mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
mover->UpdatePosition(movementInfo.pos);
|
||||
|
||||
if (plrMover) // nothing is charmed, or player charmed
|
||||
{
|
||||
if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
|
||||
plrMover->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
HandleMoverRelocation(movementInfo, mover);
|
||||
|
||||
if (plrMover && opcode != CMSG_MOVE_KNOCK_BACK_ACK)
|
||||
plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
|
||||
|
||||
if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
|
||||
if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
|
||||
{
|
||||
if (plrMover->IsAlive())
|
||||
{
|
||||
plrMover->SetPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
|
||||
plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
|
||||
// player can be alive if GM
|
||||
if (plrMover->IsAlive())
|
||||
plrMover->KillPlayer();
|
||||
}
|
||||
else if (!plrMover->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
|
||||
{
|
||||
GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover, plrMover->GetTeamId());
|
||||
if (grave)
|
||||
{
|
||||
plrMover->TeleportTo(grave->Map, grave->x, grave->y, grave->z, plrMover->GetOrientation());
|
||||
plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldSession::HandleForceSpeedChangeAck(WorldPacket& recvData)
|
||||
@@ -762,11 +796,13 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket& recvData)
|
||||
{
|
||||
LOG_DEBUG("network", "CMSG_MOVE_KNOCK_BACK_ACK");
|
||||
|
||||
Unit* mover = _player->m_mover;
|
||||
|
||||
ObjectGuid guid;
|
||||
recvData >> guid.ReadAsPacked();
|
||||
|
||||
// pussywizard: typical check for incomming movement packets
|
||||
if (!_player->m_mover || !_player->m_mover->IsInWorld() || _player->m_mover->IsDuringRemoveFromWorld() || guid != _player->m_mover->GetGUID())
|
||||
if (!mover || !mover->IsInWorld() || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
|
||||
{
|
||||
recvData.rfinish(); // prevent warnings spam
|
||||
return;
|
||||
@@ -778,7 +814,10 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket& recvData)
|
||||
movementInfo.guid = guid;
|
||||
ReadMovementInfo(recvData, &movementInfo);
|
||||
|
||||
_player->m_mover->m_movementInfo = movementInfo;
|
||||
mover->m_movementInfo = movementInfo;
|
||||
|
||||
if (mover->IsPlayer() && static_cast<Player*>(mover)->IsFreeFlying())
|
||||
mover->SetCanFly(true);
|
||||
|
||||
WorldPacket data(MSG_MOVE_KNOCK_BACK, 66);
|
||||
data << guid.WriteAsPacked();
|
||||
@@ -793,38 +832,6 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket& recvData)
|
||||
_player->SendMessageToSet(&data, false);
|
||||
}
|
||||
|
||||
void WorldSession::HandleMoveHoverAck(WorldPacket& recvData)
|
||||
{
|
||||
LOG_DEBUG("network", "CMSG_MOVE_HOVER_ACK");
|
||||
|
||||
ObjectGuid guid;
|
||||
recvData >> guid.ReadAsPacked();
|
||||
|
||||
recvData.read_skip<uint32>(); // unk
|
||||
|
||||
MovementInfo movementInfo;
|
||||
movementInfo.guid = guid;
|
||||
ReadMovementInfo(recvData, &movementInfo);
|
||||
|
||||
recvData.read_skip<uint32>(); // unk2
|
||||
}
|
||||
|
||||
void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recvData)
|
||||
{
|
||||
LOG_DEBUG("network", "CMSG_MOVE_WATER_WALK_ACK");
|
||||
|
||||
ObjectGuid guid;
|
||||
recvData >> guid.ReadAsPacked();
|
||||
|
||||
recvData.read_skip<uint32>(); // unk
|
||||
|
||||
MovementInfo movementInfo;
|
||||
movementInfo.guid = guid;
|
||||
ReadMovementInfo(recvData, &movementInfo);
|
||||
|
||||
recvData.read_skip<uint32>(); // unk2
|
||||
}
|
||||
|
||||
void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData)
|
||||
{
|
||||
if (!_player->IsAlive() || _player->IsInCombat())
|
||||
|
||||
@@ -374,7 +374,7 @@ void OpcodeTable::Initialize()
|
||||
/*0x0F3*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_NORMAL_FALL, STATUS_NEVER);
|
||||
/*0x0F4*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER);
|
||||
/*0x0F5*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER);
|
||||
/*0x0F6*/ DEFINE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveHoverAck );
|
||||
/*0x0F6*/ DEFINE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveFlagChangeOpcode );
|
||||
/*0x0F7*/ DEFINE_SERVER_OPCODE_HANDLER(MSG_MOVE_HOVER, STATUS_NEVER);
|
||||
/*0x0F8*/ DEFINE_HANDLER(CMSG_TRIGGER_CINEMATIC_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
/*0x0F9*/ DEFINE_HANDLER(CMSG_OPENING_CINEMATIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
@@ -847,8 +847,8 @@ void OpcodeTable::Initialize()
|
||||
/*0x2CC*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, STATUS_NEVER);
|
||||
/*0x2CD*/ DEFINE_HANDLER(CMSG_REQUEST_RAID_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode );
|
||||
/*0x2CE*/ DEFINE_HANDLER(CMSG_MOVE_TIME_SKIPPED, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTimeSkippedOpcode );
|
||||
/*0x2CF*/ DEFINE_HANDLER(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck );
|
||||
/*0x2D0*/ DEFINE_HANDLER(CMSG_MOVE_WATER_WALK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck );
|
||||
/*0x2CF*/ DEFINE_HANDLER(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveFlagChangeOpcode );
|
||||
/*0x2D0*/ DEFINE_HANDLER(CMSG_MOVE_WATER_WALK_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveFlagChangeOpcode );
|
||||
/*0x2D1*/ DEFINE_HANDLER(CMSG_MOVE_NOT_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveNotActiveMover );
|
||||
/*0x2D2*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER);
|
||||
/*0x2D3*/ DEFINE_HANDLER(CMSG_BATTLEFIELD_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode );
|
||||
@@ -965,7 +965,7 @@ void OpcodeTable::Initialize()
|
||||
/*0x342*/ DEFINE_HANDLER(MSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
/*0x343*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER);
|
||||
/*0x344*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER);
|
||||
/*0x345*/ DEFINE_HANDLER(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode );
|
||||
/*0x345*/ DEFINE_HANDLER(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveFlagChangeOpcode );
|
||||
/*0x346*/ DEFINE_HANDLER(CMSG_MOVE_SET_FLY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
|
||||
/*0x347*/ DEFINE_HANDLER(CMSG_SOCKET_GEMS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSocketOpcode );
|
||||
/*0x348*/ DEFINE_HANDLER(CMSG_ARENA_TEAM_CREATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
|
||||
@@ -136,7 +136,8 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 accountFlags, s
|
||||
_addonMessageReceiveCount(0),
|
||||
_timeSyncClockDeltaQueue(6),
|
||||
_timeSyncClockDelta(0),
|
||||
_pendingTimeSyncRequests()
|
||||
_pendingTimeSyncRequests(),
|
||||
_orderCounter(0)
|
||||
{
|
||||
memset(m_Tutorials, 0, sizeof(m_Tutorials));
|
||||
|
||||
|
||||
@@ -379,6 +379,10 @@ public:
|
||||
|
||||
void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
|
||||
void WriteMovementInfo(WorldPacket* data, MovementInfo* mi);
|
||||
void SynchronizeMovement(MovementInfo& movementInfo);
|
||||
void HandleMoverRelocation(MovementInfo& movementInfo, Unit* mover);
|
||||
bool VerifyMovementInfo(MovementInfo const& movementInfo, Player* plrMover, Unit* mover, Opcodes opcode) const;
|
||||
bool ProcessMovementInfo(MovementInfo& movementInfo, Unit* mover, Player* plrMover, WorldPacket& recvData);
|
||||
|
||||
void SendPacket(WorldPacket const* packet);
|
||||
void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName* declinedName);
|
||||
@@ -582,6 +586,10 @@ public:
|
||||
// Time Synchronisation
|
||||
void ResetTimeSync();
|
||||
void SendTimeSync();
|
||||
|
||||
// Movement packet order
|
||||
uint32 GetOrderCounter() const { return _orderCounter; }
|
||||
void IncrementOrderCounter() { ++_orderCounter; }
|
||||
public: // opcodes handlers
|
||||
void Handle_NULL(WorldPacket& null); // not used
|
||||
void Handle_EarlyProccess(WorldPacket& recvPacket); // just mark packets processed in WorldSocket::OnRead
|
||||
@@ -620,11 +628,6 @@ public: // opcodes handlers
|
||||
// new party stats
|
||||
void HandleInspectHonorStatsOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleMoveWaterWalkAck(WorldPacket& recvPacket);
|
||||
void HandleFeatherFallAck(WorldPacket& recvData);
|
||||
|
||||
void HandleMoveHoverAck(WorldPacket& recvData);
|
||||
|
||||
void HandleMountSpecialAnimOpcode(WorldPacket& recvdata);
|
||||
|
||||
// character view
|
||||
@@ -969,7 +972,7 @@ public: // opcodes handlers
|
||||
void HandleFarSightOpcode(WorldPacket& recvData);
|
||||
void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData);
|
||||
void HandleSetRaidDifficultyOpcode(WorldPacket& recvData);
|
||||
void HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData);
|
||||
void HandleMoveFlagChangeOpcode(WorldPacket& recvData);
|
||||
void HandleSetTitleOpcode(WorldPacket& recvData);
|
||||
void HandleRealmSplitOpcode(WorldPacket& recvData);
|
||||
void HandleTimeSyncResp(WorldPacket& recvData);
|
||||
@@ -1237,6 +1240,8 @@ private:
|
||||
uint32 _timeSyncNextCounter;
|
||||
uint32 _timeSyncTimer;
|
||||
|
||||
uint32 _orderCounter;
|
||||
|
||||
WorldSession(WorldSession const& right) = delete;
|
||||
WorldSession& operator=(WorldSession const& right) = delete;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user