diff options
author | Shauren <shauren.trinity@gmail.com> | 2016-10-21 18:24:47 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-10-21 18:24:47 +0200 |
commit | 537ff17ca07bcb4aafc5857e4232bdf2d50b7b67 (patch) | |
tree | b5885432a3eac3363d440fa2d9af3a47a59d4de9 | |
parent | a3b953952ae987b4fb8cc6d4b7a4395981e99bc2 (diff) |
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
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 46 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 138 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 12 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MailPackets.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.cpp | 86 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MovementPackets.h | 39 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 |
7 files changed, 202 insertions, 125 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e2b38a50603..2c030d0c58a 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 750643ec126..ca44e62923d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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; + if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) + return false; - float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); + float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT); - if (enable) - { - //! No need to check height on ascent - AddUnitMovementFlag(MOVEMENTFLAG_HOVER); - if (hoverHeight) - UpdateHeight(GetPositionZ() + hoverHeight); - } - else + if (enable) + { + //! No need to check height on ascent + AddUnitMovementFlag(MOVEMENTFLAG_HOVER); + if (hoverHeight) + UpdateHeight(GetPositionZ() + hoverHeight); + } + else + { + RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER); + if (hoverHeight) { - 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] = { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 58cab981dfc..a521a782a0d 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -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); diff --git a/src/server/game/Server/Packets/MailPackets.cpp b/src/server/game/Server/Packets/MailPackets.cpp index f8922d5bbaf..472c33503cb 100644 --- a/src/server/game/Server/Packets/MailPackets.cpp +++ b/src/server/game/Server/Packets/MailPackets.cpp @@ -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; diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp index 0a77af16b83..1a04aa52a50 100644 --- a/src/server/game/Server/Packets/MovementPackets.cpp +++ b/src/server/game/Server/Packets/MovementPackets.cpp @@ -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; +} diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h index 1c21c034c86..83c53812ea3 100644 --- a/src/server/game/Server/Packets/MovementPackets.h +++ b/src/server/game/Server/Packets/MovementPackets.h @@ -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); diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index c242d9ee929..4fbc0b700fd 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -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); |