From 631b499414c8cbfd34c77ffeed88afb9d547bd75 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Tue, 16 Nov 2021 07:11:00 +0100 Subject: [PATCH] Core/Movement: updated collision height packet handling to ack handling --- src/server/game/Entities/Player/Player.cpp | 15 +++---- src/server/game/Entities/Player/Player.h | 3 +- src/server/game/Entities/Unit/Unit.cpp | 3 ++ src/server/game/Handlers/MovementHandler.cpp | 34 +++++++++++++-- .../game/Movement/MovementPacketSender.cpp | 43 +++++++++++++++++++ .../game/Movement/MovementPacketSender.h | 5 ++- .../game/Movement/MovementStructures.cpp | 38 ++++++++++++++-- src/server/game/Movement/MovementStructures.h | 1 + 8 files changed, 122 insertions(+), 20 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 924f467518..40bdc51b85 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -25879,6 +25879,11 @@ bool Player::SetCanTransitionBetweenSwimAndFly(bool enable) return true; } +void Player::SendMovementSetCollisionHeight(float height, UpdateCollisionHeightReason reason) +{ + MovementPacketSender::SendHeightChangeToMover(this, height, reason); +} + void Player::ResetAchievements() { m_achievementMgr->Reset(); @@ -27643,16 +27648,6 @@ VoidStorageItem* Player::GetVoidStorageItem(uint64 id, uint8& slot) const return nullptr; } -void Player::SendMovementSetCollisionHeight(float height, UpdateCollisionHeightReason reason) -{ - WorldPackets::Movement::MoveSetCollisionHeight packet; - packet.Height = height; - packet.MoverGUID = GetGUID(); - //packet.SequenceIndex = m_movementCounter++; - packet.Reason = reason; - SendDirectMessage(packet.Write()); -} - std::string Player::GetMapAreaAndZoneString() const { uint32 areaId = GetAreaId(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 864258c1a0..831f5a280d 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2147,6 +2147,7 @@ class TC_GAME_API Player : public Unit, public GridObject bool SetDisableGravity(bool disable, bool packetOnly = false, bool updateAnimationTier = true) override; bool SetCanFly(bool enable, bool packetOnly = false) override; bool SetCanTransitionBetweenSwimAndFly(bool enable) override; + void SendMovementSetCollisionHeight(float height, UpdateCollisionHeightReason reason); void SetClientControl(Unit* target, bool allowMove); @@ -2353,8 +2354,6 @@ class TC_GAME_API Player : public Unit, public GridObject void ValidateMovementInfo(MovementInfo* mi); - void SendMovementSetCollisionHeight(float height, UpdateCollisionHeightReason reason); - bool CanFly() const override { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); } bool CanEnterWater() const override { return true; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8e5997000c..0955f1170c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13900,6 +13900,9 @@ void Unit::PurgeAndApplyPendingMovementChanges(bool informObservers /* = true */ break; case MovementChangeType::SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY: Unit::SetCanTransitionBetweenSwimAndFly(pendingChange.second.apply); + break; + case MovementChangeType::SET_COLLISION_HGT: + break; default: ASSERT(false); return; diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 42ea28c71b..4d182cf08a 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -769,9 +769,37 @@ void WorldSession::HandleMoveGravityDisableAck(WorldPacket& recvData) void WorldSession::HandleSetCollisionHeightAck(WorldPacket& recvData) { MovementInfo movementInfo; - static MovementStatusElements const heightElement = MSEExtraFloat; - Movement::ExtraMovementStatusElement extras(&heightElement); - GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extras); + static MovementStatusElements const extraElements[] = + { + MSEExtraFloat, + MSEExtraTwoBits + }; + + Movement::ExtraMovementStatusElement extra(extraElements); + GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extra); + + GameClient* client = GetGameClient(); + if (!client->IsAllowedToMove(movementInfo.guid)) + return; + + Unit* mover = ObjectAccessor::GetUnit(*_player, movementInfo.guid); + + PlayerMovementPendingChange const* pendingChange = mover->GetPendingMovementChange(MovementChangeType::SET_COLLISION_HGT); + if (!pendingChange || pendingChange->movementCounter != movementInfo.movementCounter) + return; + + if (std::fabs(pendingChange->newValue - extra.Data.floatData) > 0.01f) + { + TC_LOG_INFO("cheat", "WorldSession::HandleSetCollisionHeightAck: Player %s from account id %u kicked for incorrect data returned in an ack", + _player->GetName().c_str(), _player->GetSession()->GetAccountId()); + _player->GetSession()->KickPlayer(); + return; + } + + mover->m_movementInfo = movementInfo; + mover->UpdatePosition(movementInfo.pos); + + MovementPacketSender::SendHeightChangeToObservers(mover, pendingChange->newValue); } void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData) diff --git a/src/server/game/Movement/MovementPacketSender.cpp b/src/server/game/Movement/MovementPacketSender.cpp index 4e6afd0a70..169f51b040 100644 --- a/src/server/game/Movement/MovementPacketSender.cpp +++ b/src/server/game/Movement/MovementPacketSender.cpp @@ -19,6 +19,7 @@ #include "MovementPacketSender.h" #include "MovementStructures.h" #include "Player.h" +#include "SharedDefines.h" #include "WorldPacket.h" #include "WorldSession.h" @@ -77,6 +78,48 @@ MovementChangeType MovementPacketSender::GetChangeTypeByMovementFlag(MovementFla } } +void MovementPacketSender::SendHeightChangeToMover(Unit* unit, float newHeight, UpdateCollisionHeightReason reason) +{ + GameClient* controller = unit->GetGameClientMovingMe(); + + ASSERT(controller); + + uint32 mCounter = unit->GetMovementCounterAndInc(); + PlayerMovementPendingChange pendingChange; + pendingChange.movementCounter = mCounter; + pendingChange.newValue = newHeight; + pendingChange.movementChangeType = MovementChangeType::SET_COLLISION_HGT; + unit->AssignPendingMovementChange(pendingChange.movementChangeType, std::move(pendingChange)); + static MovementStatusElements const extraElements[] = + { + MSEExtraTwoBits, + MSEExtraFloat + }; + + Movement::ExtraMovementStatusElement extra(extraElements); + extra.Data.floatData = newHeight; + extra.Data.byteData = reason; + + WorldPacket data(SMSG_MOVE_SET_COLLISION_HEIGHT, 8 + 1 + 4); + unit->WriteMovementInfo(data, &extra, &mCounter); + controller->SendDirectMessage(&data); +} + +void MovementPacketSender::SendHeightChangeToObservers(Unit* unit, float newHeight) +{ + GameClient* controller = unit->GetGameClientMovingMe(); + + ASSERT(controller); + + WorldPacket data(SMSG_MOVE_UPDATE_COLLISION_HEIGHT); + static MovementStatusElements const speedVal = MSEExtraFloat; + Movement::ExtraMovementStatusElement extra(&speedVal); + extra.Data.floatData = newHeight; + + unit->WriteMovementInfo(data, &extra); + unit->SendMessageToSet(&data, controller->GetBasePlayer()); +} + void MovementPacketSender::SendSpeedChangeToMover(Unit* unit, UnitMoveType mtype, float newSpeedFlat) { GameClient* controller = unit->GetGameClientMovingMe(); diff --git a/src/server/game/Movement/MovementPacketSender.h b/src/server/game/Movement/MovementPacketSender.h index e100a6c93e..bf39ed875f 100644 --- a/src/server/game/Movement/MovementPacketSender.h +++ b/src/server/game/Movement/MovementPacketSender.h @@ -24,6 +24,7 @@ class Player; class Unit; struct MovementInfo; enum class MovementChangeType : uint8; +enum UpdateCollisionHeightReason : uint8; //! //! movement flag changes for player controlled units: @@ -98,8 +99,8 @@ class MovementPacketSender { public: ///* height change */ - //static void SendHeightChangeToMover(Unit* unit, float newRate); - //static void SendHeightChangeToObservers(Unit* unit, float newRate); + static void SendHeightChangeToMover(Unit* unit, float newHeight, UpdateCollisionHeightReason reason); + static void SendHeightChangeToObservers(Unit* unit, float newHeight); ///* teleport */ //static void SendTeleportAckPacket(Unit* unit, MovementInfo const& movementInfo); // rename to SendTeleportToMover? diff --git a/src/server/game/Movement/MovementStructures.cpp b/src/server/game/Movement/MovementStructures.cpp index e14bd6e03b..b27810631b 100644 --- a/src/server/game/Movement/MovementStructures.cpp +++ b/src/server/game/Movement/MovementStructures.cpp @@ -2496,6 +2496,31 @@ MovementStatusElements const MovementUpdateFlightSpeed[] = MSEEnd }; +MovementStatusElements const MovementSetCollisionHeight[] = +{ + MSEExtraElement, + MSEHasGuidByte6, + MSEHasGuidByte1, + MSEHasGuidByte4, + MSEHasGuidByte7, + MSEHasGuidByte5, + MSEHasGuidByte2, + MSEHasGuidByte0, + MSEHasGuidByte3, + MSEFlushBits, + MSEGuidByte6, + MSEGuidByte0, + MSEGuidByte4, + MSEGuidByte3, + MSEGuidByte5, + MSECounter, + MSEGuidByte1, + MSEGuidByte2, + MSEGuidByte7, + MSEExtraElement, + MSEEnd +}; + MovementStatusElements const MovementUpdateCollisionHeight[] = { MSEPositionZ, @@ -2646,15 +2671,14 @@ MovementStatusElements const MovementForceRunSpeedChangeAck[] = MovementStatusElements const MovementSetCollisionHeightAck[] = { - MSEExtraElement, + MSEExtraElement, // Height MSEPositionX, MSEPositionZ, MSECounter, MSEPositionY, MSEHasGuidByte6, MSEHasGuidByte4, - MSEZeroBit, // Reason bit 1 - MSEZeroBit, // Reason bit 2 + MSEExtraElement, // Reason MSEHasPitch, MSEHasGuidByte5, MSEHasHeightChangeFailed, @@ -5482,6 +5506,9 @@ void Movement::ExtraMovementStatusElement::ReadNextElement(ByteBuffer& packet) case MSEExtraInt8: packet >> Data.byteData; break; + case MSEExtraTwoBits: + Data.byteData = packet.ReadBits(2); + break; default: ASSERT(PrintInvalidSequenceElement(element, __FUNCTION__)); break; @@ -5520,6 +5547,9 @@ void Movement::ExtraMovementStatusElement::WriteNextElement(ByteBuffer& packet) case MSEExtraInt8: packet << Data.byteData; break; + case MSEExtraTwoBits: + packet.WriteBits(Data.byteData, 2); + break; default: ASSERT(PrintInvalidSequenceElement(element, __FUNCTION__)); break; @@ -5667,6 +5697,8 @@ MovementStatusElements const* GetMovementStatusElementsSequence(uint32 opcode) return MovementSetCanTransitionBetweenSwimAndFlyAck; case CMSG_MOVE_SET_COLLISION_HEIGHT_ACK: return MovementSetCollisionHeightAck; + case SMSG_MOVE_SET_COLLISION_HEIGHT: + return MovementSetCollisionHeight; case SMSG_MOVE_UPDATE_COLLISION_HEIGHT: return MovementUpdateCollisionHeight; case CMSG_MOVE_WATER_WALK_ACK: diff --git a/src/server/game/Movement/MovementStructures.h b/src/server/game/Movement/MovementStructures.h index 6f5abbad89..db55f83384 100644 --- a/src/server/game/Movement/MovementStructures.h +++ b/src/server/game/Movement/MovementStructures.h @@ -106,6 +106,7 @@ enum MovementStatusElements // Allowed internal elements are: GUID markers (not transport), MSEExtraFloat, MSEExtraInt8 MSEExtraFloat, MSEExtraInt8, + MSEExtraTwoBits, }; namespace Movement