Core/PacketIO: Fixed unneccessary packet spam when units become visible for players

Before this change, one player starting to see any unit (CreateObject) would trigger sending root, feather fall, water walk, hover, can turn while falling and double jump status changes to ALL nearby players
This commit is contained in:
Shauren
2016-10-21 18:24:47 +02:00
parent a3b953952a
commit 537ff17ca0
7 changed files with 203 additions and 126 deletions
+26 -20
View File
@@ -4235,7 +4235,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
setDeathState(ALIVE);
SetWaterWalking(false, true);
// add the flag to make sure opcode is always sent
AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
SetWaterWalking(false);
if (!HasUnitState(UNIT_STATE_STUNNED))
SetRooted(false);
@@ -23096,9 +23098,31 @@ void Player::SendInitialPacketsAfterAddToMap()
if (HasAuraType(SPELL_AURA_MOD_STUN))
SetRooted(true);
WorldPackets::Movement::MoveSetCompoundState setCompoundState;
// manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that must not be re-applied.
if (HasAuraType(SPELL_AURA_MOD_ROOT) || HasAuraType(SPELL_AURA_MOD_ROOT_2))
SetRooted(true, true);
setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ROOT, m_movementCounter++);
if (HasAuraType(SPELL_AURA_FEATHER_FALL))
setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_FEATHER_FALL, m_movementCounter++);
if (HasAuraType(SPELL_AURA_WATER_WALK))
setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_WATER_WALK, m_movementCounter++);
if (HasAuraType(SPELL_AURA_HOVER))
setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_HOVERING, m_movementCounter++);
if (HasAuraType(SPELL_AURA_CAN_TURN_WHILE_FALLING))
setCompoundState.StateChanges.emplace_back(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, m_movementCounter++);
if (HasAura(SPELL_DH_DOUBLE_JUMP))
setCompoundState.StateChanges.emplace_back(SMSG_MOVE_ENABLE_DOUBLE_JUMP, m_movementCounter++);
if (!setCompoundState.StateChanges.empty())
{
setCompoundState.MoverGUID = GetGUID();
SendDirectMessage(setCompoundState.Write());
}
SendAurasForTarget(this);
SendEnchantmentDurations(); // must be after add to map
@@ -23452,24 +23476,6 @@ void Player::SendAurasForTarget(Unit* target) const
if (!target || target->GetVisibleAuras().empty()) // speedup things
return;
/*! Blizz sends certain movement packets sometimes even before CreateObject
These movement packets are usually found in SMSG_COMPRESSED_MOVES
*/
if (target->HasAuraType(SPELL_AURA_FEATHER_FALL))
target->SetFeatherFall(true, true);
if (target->HasAuraType(SPELL_AURA_WATER_WALK))
target->SetWaterWalking(true, true);
if (target->HasAuraType(SPELL_AURA_HOVER))
target->SetHover(true, true);
if (target->HasAuraType(SPELL_AURA_CAN_TURN_WHILE_FALLING))
target->SetCanTurnWhileFalling(true, true);
if (target->HasAura(SPELL_DH_DOUBLE_JUMP))
target->SetDoubleJump(true, true);
Unit::VisibleAuraContainer const& visibleAuras = target->GetVisibleAuras();
WorldPackets::Spells::AuraUpdate update;
+61 -79
View File
@@ -15372,25 +15372,22 @@ bool Unit::SetWalk(bool enable)
return true;
}
bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
bool Unit::SetDisableGravity(bool disable)
{
if (!packetOnly)
{
if (disable == IsLevitating())
return false;
if (disable == IsLevitating())
return false;
if (disable)
{
AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION);
SetFall(false);
}
else
{
RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
SetFall(true);
}
if (disable)
{
AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION);
SetFall(false);
}
else
{
RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
SetFall(true);
}
static OpcodeServer const gravityOpcodeTable[2][2] =
@@ -15503,18 +15500,15 @@ bool Unit::SetCanFly(bool enable)
return true;
}
bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
bool Unit::SetWaterWalking(bool enable)
{
if (!packetOnly)
{
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
return false;
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
return false;
if (enable)
AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
}
if (enable)
AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
static OpcodeServer const waterWalkingOpcodeTable[2][2] =
{
@@ -15543,18 +15537,15 @@ bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
return true;
}
bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
bool Unit::SetFeatherFall(bool enable)
{
if (!packetOnly)
{
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
return false;
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
return false;
if (enable)
AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
}
if (enable)
AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
else
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
static OpcodeServer const featherFallOpcodeTable[2][2] =
{
@@ -15583,31 +15574,28 @@ bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
return true;
}
bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
bool Unit::SetHover(bool enable)
{
if (!packetOnly)
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
return false;
float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
if (enable)
{
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
return false;
float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
if (enable)
//! No need to check height on ascent
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
if (hoverHeight)
UpdateHeight(GetPositionZ() + hoverHeight);
}
else
{
RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
if (hoverHeight)
{
//! No need to check height on ascent
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
if (hoverHeight)
UpdateHeight(GetPositionZ() + hoverHeight);
}
else
{
RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
if (hoverHeight)
{
float newZ = GetPositionZ() - hoverHeight;
UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
UpdateHeight(newZ);
}
float newZ = GetPositionZ() - hoverHeight;
UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
UpdateHeight(newZ);
}
}
@@ -15709,18 +15697,15 @@ bool Unit::SetCanTransitionBetweenSwimAndFly(bool enable)
return true;
}
bool Unit::SetCanTurnWhileFalling(bool enable, bool packetOnly /*= false*/)
bool Unit::SetCanTurnWhileFalling(bool enable)
{
if (!packetOnly)
{
if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING))
return false;
if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING))
return false;
if (enable)
AddExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
else
RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
}
if (enable)
AddExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
else
RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_CAN_TURN_WHILE_FALLING);
static OpcodeServer const canTurnWhileFallingOpcodeTable[2] =
{
@@ -15743,18 +15728,15 @@ bool Unit::SetCanTurnWhileFalling(bool enable, bool packetOnly /*= false*/)
return true;
}
bool Unit::SetDoubleJump(bool enable, bool packetOnly /*= false*/)
bool Unit::SetDoubleJump(bool enable)
{
if (!packetOnly)
{
if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP))
return false;
if (enable == HasExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP))
return false;
if (enable)
AddExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
else
RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
}
if (enable)
AddExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
else
RemoveExtraUnitMovementFlag(MOVEMENTFLAG2_DOUBLE_JUMP);
static OpcodeServer const doubleJumpOpcodeTable[2] =
{
+6 -6
View File
@@ -1690,17 +1690,17 @@ class TC_GAME_API Unit : public WorldObject
bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); }
bool IsHovering() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_HOVER); }
bool SetWalk(bool enable);
bool SetDisableGravity(bool disable, bool packetOnly = false);
bool SetDisableGravity(bool disable);
bool SetFall(bool enable);
bool SetSwim(bool enable);
bool SetCanFly(bool enable);
bool SetWaterWalking(bool enable, bool packetOnly = false);
bool SetFeatherFall(bool enable, bool packetOnly = false);
bool SetHover(bool enable, bool packetOnly = false);
bool SetWaterWalking(bool enable);
bool SetFeatherFall(bool enable);
bool SetHover(bool enable);
bool SetCollision(bool disable);
bool SetCanTransitionBetweenSwimAndFly(bool enable);
bool SetCanTurnWhileFalling(bool enable, bool packetOnly = false);
bool SetDoubleJump(bool enable, bool packetOnly = false);
bool SetCanTurnWhileFalling(bool enable);
bool SetDoubleJump(bool enable);
void SendSetVehicleRecId(uint32 vehicleId);
void SetInFront(WorldObject const* target);
@@ -128,7 +128,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailListEntry const
data.WriteBits(entry.Body.size(), 13);
data.FlushBits();
for (auto const& att : entry.Attachments)
for (WorldPackets::Mail::MailAttachedItem const& att : entry.Attachments)
data << att;
if (entry.SenderCharacter)
@@ -157,7 +157,7 @@ WorldPacket const* WorldPackets::Mail::MailListResult::Write()
_worldPacket << uint32(Mails.size());
_worldPacket << int32(TotalNumRecords);
for (auto const& mail : Mails)
for (MailListEntry const& mail : Mails)
_worldPacket << mail;
return &_worldPacket;
@@ -532,22 +532,27 @@ WorldPacket const* WorldPackets::Movement::MoveTeleport::Write()
return &_worldPacket;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementForce const& movementForce)
{
data << movementForce.ID;
data << movementForce.Origin;
data << movementForce.Direction;
data << movementForce.TransportPosition;
data << movementForce.TransportID;
data << movementForce.Magnitude;
data.WriteBits(movementForce.Type, 2);
data.FlushBits();
return data;
}
WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write()
{
_worldPacket << *movementInfo;
_worldPacket << int32(MovementForces.size());
for (WorldPackets::Movement::MovementForce const& force : MovementForces)
{
_worldPacket << force.ID;
_worldPacket << force.Origin;
_worldPacket << force.Direction;
_worldPacket << force.TransportPosition;
_worldPacket << force.TransportID;
_worldPacket << force.Magnitude;
_worldPacket.WriteBits(force.Type, 2);
_worldPacket.FlushBits();
}
_worldPacket << force;
_worldPacket.WriteBit(WalkSpeed.is_initialized());
_worldPacket.WriteBit(RunSpeed.is_initialized());
@@ -679,14 +684,7 @@ WorldPacket const* WorldPackets::Movement::MoveUpdateRemoveMovementForce::Write(
WorldPacket const* WorldPackets::Movement::MoveUpdateApplyMovementForce::Write()
{
_worldPacket << *movementInfo;
_worldPacket << Force.ID;
_worldPacket << Force.Origin;
_worldPacket << Force.Direction;
_worldPacket << Force.TransportPosition;
_worldPacket << Force.TransportID;
_worldPacket << Force.Magnitude;
_worldPacket.WriteBits(Force.Type, 2);
_worldPacket.FlushBits();
_worldPacket << Force;
return &_worldPacket;
}
@@ -760,3 +758,55 @@ WorldPacket const* WorldPackets::Movement::ResumeToken::Write()
return &_worldPacket;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MoveSetCompoundState::MoveStateChange const& stateChange)
{
data << uint16(stateChange.MessageID);
data << uint32(stateChange.SequenceIndex);
data.WriteBit(stateChange.Speed.is_initialized());
data.WriteBit(stateChange.KnockBack.is_initialized());
data.WriteBit(stateChange.VehicleRecID.is_initialized());
data.WriteBit(stateChange.CollisionHeight.is_initialized());
data.WriteBit(stateChange.MovementForce_.is_initialized());
data.WriteBit(stateChange.Unknown.is_initialized());
data.FlushBits();
if (stateChange.CollisionHeight)
{
data << float(stateChange.CollisionHeight->Height);
data << float(stateChange.CollisionHeight->Scale);
data.WriteBits(stateChange.CollisionHeight->Reason, 2);
data.FlushBits();
}
if (stateChange.Speed)
data << float(*stateChange.Speed);
if (stateChange.KnockBack)
{
data << float(stateChange.KnockBack->HorzSpeed);
data << stateChange.KnockBack->Direction;
data << float(stateChange.KnockBack->InitVertSpeed);
}
if (stateChange.VehicleRecID)
data << int32(*stateChange.VehicleRecID);
if (stateChange.MovementForce_)
data << *stateChange.MovementForce_;
if (stateChange.Unknown)
data << *stateChange.Unknown;
return data;
}
WorldPacket const* WorldPackets::Movement::MoveSetCompoundState::Write()
{
_worldPacket << MoverGUID;
_worldPacket << uint32(StateChanges.size());
for (MoveStateChange const& stateChange : StateChanges)
_worldPacket << stateChange;
return &_worldPacket;
}
@@ -536,6 +536,45 @@ namespace WorldPackets
uint32 SequenceIndex = 1;
uint32 Reason = 1;
};
class MoveSetCompoundState final : public ServerPacket
{
public:
struct CollisionHeightInfo
{
float Height = 0.0f;
float Scale = 0.0f;
UpdateCollisionHeightReason Reason;
};
struct KnockBackInfo
{
float HorzSpeed = 0.0f;
G3D::Vector2 Direction;
float InitVertSpeed = 0.0f;
};
struct MoveStateChange
{
MoveStateChange(OpcodeServer messageId, uint32 sequenceIndex) : MessageID(messageId), SequenceIndex(sequenceIndex) { }
uint16 MessageID = 0;
uint32 SequenceIndex = 0;
Optional<float> Speed;
Optional<KnockBackInfo> KnockBack;
Optional<int32> VehicleRecID;
Optional<CollisionHeightInfo> CollisionHeight;
Optional<MovementForce> MovementForce_;
Optional<ObjectGuid> Unknown;
};
MoveSetCompoundState() : ServerPacket(SMSG_MOVE_SET_COMPOUND_STATE, 4 + 1) { }
WorldPacket const* Write() override;
ObjectGuid MoverGUID;
std::vector<MoveStateChange> StateChanges;
};
}
ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey);
+1 -1
View File
@@ -1365,7 +1365,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TURN_WHILE_FALLING, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FEATHER_FALL, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);