Core/Movement: converted CMSG_MOVE_SET_COLLISION_HEIGHT_ACK and SMSG_MOVE_UPDATE_COLLISION_HEIGHT to packet class

* added new MovementInfo helpers for easy access to all packet related data
This commit is contained in:
Ovahlord committed 2020-05-10 01:31:53 +02:00
1 parent 557d5497a3
commit a2cea3ce08
11 files changed
+547 -329

No files matched your search

@@ -0,0 +1,134 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MovementInfo.h"
#include "GameTime.h"
#include "Log.h"
#include "UnitDefines.h"
#include "G3DPosition.hpp"
void MovementInfo::ResetTransport()
{
transport.Reset();
}
void MovementInfo::ResetJump()
{
jump.Reset();
}
bool MovementInfo::HasFallDirection() const
{
return HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR);
}
bool MovementInfo::HasFallData() const
{
return (HasFallDirection() || jump.fallTime != 0);
}
bool MovementInfo::HasMovementFlags() const
{
return GetMovementFlags() != 0;
};
bool MovementInfo::HasExtraMovementFlags() const
{
return GetExtraMovementFlags() != 0;
};
bool MovementInfo::HasSpline() const
{
// Todo: handle this
return false;
};
bool MovementInfo::HasHeightChangeFailed() const
{
// Todo: handle this
return false;
}
bool MovementInfo::HasTime() const
{
return time != 0;
}
bool MovementInfo::HasOrientation() const
{
return !G3D::fuzzyEq(pos.GetOrientation(), 0.0f);
}
bool MovementInfo::HasSplineElevation() const
{
return HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
}
bool MovementInfo::HasPitch() const
{
return (HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING));
}
bool MovementInfo::HasTransportData() const
{
return !transport.guid.IsEmpty();
}
bool MovementInfo::HasTransportVehicleId() const
{
return HasTransportData() && transport.vehicleId != 0;
}
bool MovementInfo::HasTransportTime2() const
{
return HasTransportData() && transport.time2 != 0;
}
void MovementInfo::OutDebug()
{
TC_LOG_DEBUG("misc", "MOVEMENT INFO");
TC_LOG_DEBUG("misc", "%s", guid.ToString().c_str());
TC_LOG_DEBUG("misc", "flags %u", flags);
TC_LOG_DEBUG("misc", "flags2 %u", flags2);
TC_LOG_DEBUG("misc", "time %u current time " UI64FMTD "", flags2, uint64(::GameTime::GetGameTime()));
TC_LOG_DEBUG("misc", "position: `%s`", pos.ToString().c_str());
if (transport.guid)
{
TC_LOG_DEBUG("misc", "TRANSPORT:");
TC_LOG_DEBUG("misc", "%s", transport.guid.ToString().c_str());
TC_LOG_DEBUG("misc", "position: `%s`", transport.pos.ToString().c_str());
TC_LOG_DEBUG("misc", "seat: %i", transport.seat);
TC_LOG_DEBUG("misc", "time: %u", transport.time);
if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
TC_LOG_DEBUG("misc", "time2: %u", transport.time2);
if (transport.vehicleId)
TC_LOG_INFO("misc", "vehicleId: %u", transport.vehicleId);
}
if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
TC_LOG_DEBUG("misc", "pitch: %f", pitch);
if (flags & MOVEMENTFLAG_FALLING || jump.fallTime)
{
TC_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
if (flags & MOVEMENTFLAG_FALLING)
TC_LOG_DEBUG("misc", "j_zspeed: %f j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.zspeed, jump.sinAngle, jump.cosAngle, jump.xyspeed);
}
if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
TC_LOG_DEBUG("misc", "splineElevation: %f", splineElevation);
}
+15 -9
View File
@@ -95,15 +95,21 @@ struct MovementInfo
uint32 GetFallTime() const { return jump.fallTime; }
void SetFallTime(uint32 time) { jump.fallTime = time; }
void ResetTransport()
{
transport.Reset();
}
void ResetJump()
{
jump.Reset();
}
void ResetTransport();
void ResetJump();
bool HasFallDirection() const;
bool HasFallData() const;
bool HasMovementFlags() const;
bool HasExtraMovementFlags() const;
bool HasSpline() const;
bool HasHeightChangeFailed() const;
bool HasTime() const;
bool HasOrientation() const;
bool HasSplineElevation() const;
bool HasPitch() const;
bool HasTransportData() const;
bool HasTransportVehicleId() const;
bool HasTransportTime2() const;
void OutDebug();
};
@@ -1151,41 +1151,6 @@ bool Object::PrintIndexError(uint32 index, bool set) const
return false;
}
void MovementInfo::OutDebug()
{
TC_LOG_DEBUG("misc", "MOVEMENT INFO");
TC_LOG_DEBUG("misc", "%s", guid.ToString().c_str());
TC_LOG_DEBUG("misc", "flags %u", flags);
TC_LOG_DEBUG("misc", "flags2 %u", flags2);
TC_LOG_DEBUG("misc", "time %u current time " UI64FMTD "", flags2, uint64(::GameTime::GetGameTime()));
TC_LOG_DEBUG("misc", "position: `%s`", pos.ToString().c_str());
if (transport.guid)
{
TC_LOG_DEBUG("misc", "TRANSPORT:");
TC_LOG_DEBUG("misc", "%s", transport.guid.ToString().c_str());
TC_LOG_DEBUG("misc", "position: `%s`", transport.pos.ToString().c_str());
TC_LOG_DEBUG("misc", "seat: %i", transport.seat);
TC_LOG_DEBUG("misc", "time: %u", transport.time);
if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
TC_LOG_DEBUG("misc", "time2: %u", transport.time2);
if (transport.vehicleId)
TC_LOG_INFO("misc", "vehicleId: %u", transport.vehicleId);
}
if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
TC_LOG_DEBUG("misc", "pitch: %f", pitch);
if (flags & MOVEMENTFLAG_FALLING || jump.fallTime)
{
TC_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
if (flags & MOVEMENTFLAG_FALLING)
TC_LOG_DEBUG("misc", "j_zspeed: %f j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.zspeed, jump.sinAngle, jump.cosAngle, jump.xyspeed);
}
if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
TC_LOG_DEBUG("misc", "splineElevation: %f", splineElevation);
}
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0),
m_name(""), m_isActive(false), m_isFarVisible(false), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
m_transport(nullptr), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_outdoors(true), m_liquidStatus(LIQUID_MAP_NO_WATER),
+89 -83
View File
@@ -27775,6 +27775,94 @@ bool Player::CanUseMastery() const
return HasSpell(MasterySpells[getClass()]);
}
void Player::ValidateMovementInfo(MovementInfo* mi)
{
//! Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview.
//! Might be subject to latency, so just remove improper flags.
#ifdef TRINITY_DEBUG
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
{ \
if (check) \
{ \
TC_LOG_DEBUG("entities.unit", "Player::ValidateMovementInfo: Violation of MovementFlags found (%s). " \
"MovementFlags: %u, MovementFlags2: %u for player %s. Mask %u will be removed.", \
STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetGUID().ToString().c_str(), maskToRemove); \
mi->RemoveMovementFlag((maskToRemove)); \
} \
}
#else
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
if (check) \
mi->RemoveMovementFlag((maskToRemove));
#endif
if (!m_unitMovedByMe->GetVehicleBase() || !(m_unitMovedByMe->GetVehicle()->GetVehicleInfo()->Flags & VEHICLE_FLAG_FIXED_POSITION))
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), MOVEMENTFLAG_ROOT);
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
It will freeze clients that receive this player's movement info.
*/
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_MASK_MOVING),
MOVEMENTFLAG_MASK_MOVING);
//! Cannot hover without SPELL_AURA_HOVER
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !m_unitMovedByMe->HasAuraType(SPELL_AURA_HOVER),
MOVEMENTFLAG_HOVER);
//! Cannot ascend and descend at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING),
MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
//! Cannot move left and right at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT),
MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
//! Cannot strafe left and right at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT),
MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
//! Cannot pitch up and down at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN),
MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
//! Cannot move forwards and backwards at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD),
MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
//! Cannot walk on water without SPELL_AURA_WATER_WALK except for ghosts
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) &&
!m_unitMovedByMe->HasAuraType(SPELL_AURA_WATER_WALK) &&
!m_unitMovedByMe->HasAuraType(SPELL_AURA_GHOST),
MOVEMENTFLAG_WATERWALKING);
//! Cannot feather fall without SPELL_AURA_FEATHER_FALL
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !m_unitMovedByMe->HasAuraType(SPELL_AURA_FEATHER_FALL),
MOVEMENTFLAG_FALLING_SLOW);
/*! Cannot fly if no fly auras present. Exception is being a GM.
Note that we check for account level instead of Player::IsGameMaster() because in some
situations it may be feasable to use .gm fly on as a GM without having .gm on,
e.g. aerial combat.
*/
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSession()->GetSecurity() == SEC_PLAYER &&
!m_unitMovedByMe->HasAuraType(SPELL_AURA_FLY) &&
!m_unitMovedByMe->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING),
MOVEMENTFLAG_FALLING);
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION) && G3D::fuzzyEq(mi->splineElevation, 0.0f), MOVEMENTFLAG_SPLINE_ELEVATION);
// Client first checks if spline elevation != 0, then verifies flag presence
if (G3D::fuzzyNe(mi->splineElevation, 0.0f))
mi->AddMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
#undef REMOVE_VIOLATING_FLAGS
}
void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::ExtraMovementStatusElement* extras /*= nullptr*/)
{
MovementStatusElements const* sequence = GetMovementStatusElementsSequence(static_cast<OpcodeClient>(data.GetOpcode()));
@@ -27990,89 +28078,7 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
mi->guid = guid;
mi->transport.guid = tguid;
//! Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview.
//! Might be subject to latency, so just remove improper flags.
#ifdef TRINITY_DEBUG
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
{ \
if (check) \
{ \
TC_LOG_DEBUG("entities.unit", "Player::ReadMovementInfo: Violation of MovementFlags found (%s). " \
"MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \
STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetGUID().GetCounter(), maskToRemove); \
mi->RemoveMovementFlag((maskToRemove)); \
} \
}
#else
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
if (check) \
mi->RemoveMovementFlag((maskToRemove));
#endif
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
It will freeze clients that receive this player's movement info.
*/
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_MASK_MOVING),
MOVEMENTFLAG_MASK_MOVING);
//! Cannot hover without SPELL_AURA_HOVER
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !HasAuraType(SPELL_AURA_HOVER),
MOVEMENTFLAG_HOVER);
//! Cannot ascend and descend at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING),
MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
//! Cannot move left and right at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT),
MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
//! Cannot strafe left and right at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT),
MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
//! Cannot pitch up and down at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN),
MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
//! Cannot move forwards and backwards at the same time
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD),
MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
//! Cannot walk on water without SPELL_AURA_WATER_WALK except for ghosts
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) &&
!HasAuraType(SPELL_AURA_WATER_WALK) &&
!HasAuraType(SPELL_AURA_GHOST),
MOVEMENTFLAG_WATERWALKING);
//! Cannot feather fall without SPELL_AURA_FEATHER_FALL
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !HasAuraType(SPELL_AURA_FEATHER_FALL),
MOVEMENTFLAG_FALLING_SLOW);
/*! Cannot fly if no fly auras present. Exception is being a GM.
Note that we check for account level instead of Player::IsGameMaster() because in some
situations it may be feasable to use .gm fly on as a GM without having .gm on,
e.g. aerial combat.
*/
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && ToPlayer()->GetSession()->GetSecurity() == SEC_PLAYER &&
!ToPlayer()->m_unitMovedByMe->HasAuraType(SPELL_AURA_FLY) &&
!ToPlayer()->m_unitMovedByMe->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING),
MOVEMENTFLAG_FALLING);
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING) && (!hasFallData || !hasFallDirection), MOVEMENTFLAG_FALLING);
REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION) && G3D::fuzzyEq(mi->splineElevation, 0.0f), MOVEMENTFLAG_SPLINE_ELEVATION);
// Client first checks if spline elevation != 0, then verifies flag presence
if (hasSplineElevation)
mi->AddMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
#undef REMOVE_VIOLATING_FLAGS
ValidateMovementInfo(mi);
}
void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const
+3
View File
@@ -2356,6 +2356,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
/*! These methods send different packets to the client in apply and unapply case.
These methods are only sent to the current unit.
*/
void ValidateMovementInfo(MovementInfo* mi);
void SendMovementSetCanTransitionBetweenSwimAndFly(bool apply);
void SendMovementSetCollisionHeight(float height, UpdateCollisionHeightReason reason);
+1 -1
View File
@@ -13823,7 +13823,7 @@ void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusEle
break;
case MSETimestamp:
if (hasTimestamp)
data << getMSTime();
data << mi.time;
break;
case MSEPositionX:
data << GetPositionX();
+6 -8
View File
@@ -682,16 +682,14 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData)
_player->SummonIfPossible(agree);
}
void WorldSession::HandleSetCollisionHeightAck(WorldPacket& recvPacket)
void WorldSession::HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCollisionHeightAck& packet)
{
TC_LOG_DEBUG("network", "CMSG_MOVE_SET_COLLISION_HEIGHT_ACK");
_player->ValidateMovementInfo(&packet.Data.Status);
static MovementStatusElements const heightElement = MSEExtraFloat;
Movement::ExtraMovementStatusElement extra(&heightElement);
MovementInfo movementInfo;
GetPlayer()->ReadMovementInfo(recvPacket, &movementInfo, &extra);
Movement::PacketSender(_player, NULL_OPCODE, NULL_OPCODE, SMSG_MOVE_UPDATE_COLLISION_HEIGHT, &extra).Send();
WorldPackets::Movement::MoveUpdateCollisionHeight updateCollisionHeight;
updateCollisionHeight.Height = packet.Height;
updateCollisionHeight.Status = &_player->m_movementInfo;
_player->SendMessageToSet(updateCollisionHeight.Write(), false);
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData)
@@ -2503,77 +2503,6 @@ MovementStatusElements const MovementUpdateFlightSpeed[] =
MSEEnd
};
MovementStatusElements const MovementUpdateCollisionHeight[] =
{
MSEPositionZ,
MSEExtraElement,
MSEPositionX,
MSEPositionY,
MSEHasGuidByte6,
MSEHasGuidByte7,
MSEHasSplineElevation,
MSEHasTransportData,
MSEHasTransportGuidByte6,
MSEHasTransportGuidByte4,
MSEHasTransportGuidByte3,
MSEHasTransportGuidByte7,
MSEHasTransportGuidByte5,
MSEHasTransportGuidByte1,
MSEHasTransportGuidByte0,
MSEHasTransportGuidByte2,
MSEHasGuidByte3,
MSEHasOrientation,
MSEHasGuidByte4,
MSEHasGuidByte5,
MSEHasTimestamp,
MSEHasFallData,
MSEHasGuidByte0,
MSEHasPitch,
MSEZeroBit,
MSEHasGuidByte2,
MSEHasMovementFlags,
MSEHasFallDirection,
MSEHasGuidByte1,
MSEHasMovementFlags2,
MSEHasSpline,
MSEMovementFlags2,
MSEMovementFlags,
MSEGuidByte3,
MSETransportGuidByte7,
MSETransportTime,
MSETransportGuidByte4,
MSETransportVehicleId,
MSETransportTime2,
MSETransportGuidByte5,
MSETransportOrientation,
MSETransportPositionX,
MSETransportGuidByte6,
MSETransportGuidByte0,
MSETransportPositionY,
MSETransportGuidByte2,
MSETransportPositionZ,
MSETransportGuidByte3,
MSETransportGuidByte1,
MSETransportSeat,
MSEPitch,
MSEGuidByte6,
MSEFallCosAngle,
MSEFallSinAngle,
MSEFallHorizontalSpeed,
MSEFallVerticalSpeed,
MSEFallTime,
MSEGuidByte7,
MSEOrientation,
MSEGuidByte0,
MSEGuidByte5,
MSEGuidByte4,
MSESplineElevation,
MSETimestamp,
MSEGuidByte2,
MSEGuidByte1,
MSEEnd,
};
MovementStatusElements const MovementForceRunSpeedChangeAck[] =
{
MSECounter,
@@ -2648,82 +2577,6 @@ MovementStatusElements const MovementForceRunSpeedChangeAck[] =
MSEEnd,
};
MovementStatusElements const MovementSetCollisionHeightAck[] =
{
MSEExtraElement,
MSEPositionX,
MSEPositionZ,
MSECounter,
MSEPositionY,
MSEHasGuidByte6,
MSEHasGuidByte4,
MSEZeroBit,
MSEZeroBit,
MSEHasPitch,
MSEHasGuidByte5,
MSEZeroBit,
MSEHasGuidByte2,
MSEHasGuidByte1,
MSEHasFallData,
MSEHasGuidByte3,
MSEHasSpline,
MSEHasGuidByte7,
MSEHasMovementFlags,
MSEHasTransportData,
MSEHasTimestamp,
MSEHasSplineElevation,
MSEHasMovementFlags2,
MSEHasOrientation,
MSEHasGuidByte0,
MSEHasTransportGuidByte4,
MSEHasTransportGuidByte3,
MSEHasTransportTime2,
MSEHasVehicleId,
MSEHasTransportGuidByte5,
MSEHasTransportGuidByte1,
MSEHasTransportGuidByte7,
MSEHasTransportGuidByte2,
MSEHasTransportGuidByte6,
MSEHasTransportGuidByte0,
MSEMovementFlags2,
MSEMovementFlags,
MSEHasFallDirection,
MSEGuidByte0,
MSEGuidByte3,
MSEGuidByte1,
MSEGuidByte5,
MSEGuidByte7,
MSEGuidByte6,
MSEGuidByte2,
MSEGuidByte4,
MSETransportPositionX,
MSETransportGuidByte4,
MSETransportTime2,
MSETransportGuidByte0,
MSETransportOrientation,
MSETransportPositionY,
MSETransportGuidByte7,
MSETransportSeat,
MSETransportGuidByte5,
MSETransportGuidByte2,
MSETransportTime,
MSETransportGuidByte6,
MSETransportGuidByte3,
MSETransportGuidByte1,
MSETransportVehicleId,
MSETransportPositionZ,
MSEFallVerticalSpeed,
MSEFallTime,
MSEFallCosAngle,
MSEFallSinAngle,
MSEFallHorizontalSpeed,
MSETimestamp,
MSESplineElevation,
MSEOrientation,
MSEPitch,
MSEEnd,
};
MovementStatusElements const MovementForceFlightSpeedChangeAck[] =
{
MSECounter,
@@ -5684,10 +5537,6 @@ MovementStatusElements const* GetMovementStatusElementsSequence(uint32 opcode)
return MovementSetCanFlyAck;
case CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK:
return MovementSetCanTransitionBetweenSwimAndFlyAck;
case CMSG_MOVE_SET_COLLISION_HEIGHT_ACK:
return MovementSetCollisionHeightAck;
case SMSG_MOVE_UPDATE_COLLISION_HEIGHT:
return MovementUpdateCollisionHeight;
case CMSG_MOVE_WATER_WALK_ACK:
return MovementWaterWalkAck;
case MSG_MOVE_SET_RUN_MODE:
@@ -24,73 +24,59 @@
WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
{
bool hasFallDirection = Status->HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR);
bool hasFallData = hasFallDirection || Status->jump.fallTime != 0;
bool hasMovementFlags = Status->GetMovementFlags() != 0;
bool hasExtraMovementFlags = Status->GetExtraMovementFlags() != 0;
bool hasSpline = false; // todo 4.x send this info
bool heightChangeFailed = false; // todo 4.x send this info
bool hasTime = Status->time != 0;
bool hasOrientation = !G3D::fuzzyEq(Status->pos.GetOrientation(), 0.0f);
bool hasSplineElevation = Status->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
bool hasPitch = Status->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || Status->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
bool hasTransportData = !Status->transport.guid.IsEmpty();
bool hasTransportVehicleId = hasTransportData && Status->transport.vehicleId != 0;
bool hasTransportTime2 = hasTransportData && Status->transport.time2 != 0;
ObjectGuid guid = Status->guid;
ObjectGuid transportGuid = Status->transport.guid;
_worldPacket.WriteBit(hasFallData);
_worldPacket.WriteBit(Status->HasFallData());
_worldPacket.WriteBit(guid[3]);
_worldPacket.WriteBit(guid[6]);
_worldPacket.WriteBit(!hasExtraMovementFlags);
_worldPacket.WriteBit(hasSpline);
_worldPacket.WriteBit(!hasTime);
_worldPacket.WriteBit(!Status->HasExtraMovementFlags());
_worldPacket.WriteBit(Status->HasSpline());
_worldPacket.WriteBit(!Status->HasTime());
_worldPacket.WriteBit(guid[0]);
_worldPacket.WriteBit(guid[1]);
if (hasExtraMovementFlags)
if (Status->HasExtraMovementFlags())
_worldPacket.WriteBits(Status->GetExtraMovementFlags(), 12);
_worldPacket.WriteBit(guid[7]);
_worldPacket.WriteBit(!hasMovementFlags);
_worldPacket.WriteBit(!hasOrientation);
_worldPacket.WriteBit(!Status->HasMovementFlags());
_worldPacket.WriteBit(!Status->HasOrientation());
_worldPacket.WriteBit(guid[2]);
_worldPacket.WriteBit(!hasSplineElevation);
_worldPacket.WriteBit(heightChangeFailed);
_worldPacket.WriteBit(!Status->HasSplineElevation());
_worldPacket.WriteBit(Status->HasHeightChangeFailed());
_worldPacket.WriteBit(guid[4]);
if (hasFallData)
_worldPacket.WriteBit(hasFallDirection);
if (Status->HasFallData())
_worldPacket.WriteBit(Status->HasFallDirection());
_worldPacket.WriteBit(guid[5]);
_worldPacket.WriteBit(hasTransportData);
if (hasMovementFlags)
_worldPacket.WriteBit(Status->HasTransportData());
if (Status->HasMovementFlags())
_worldPacket.WriteBits(Status->GetMovementFlags(), 30);
if (hasTransportData)
if (Status->HasTransportData())
{
_worldPacket.WriteBit(transportGuid[3]);
_worldPacket.WriteBit(hasTransportVehicleId);
_worldPacket.WriteBit(Status->HasTransportVehicleId());
_worldPacket.WriteBit(transportGuid[6]);
_worldPacket.WriteBit(transportGuid[1]);
_worldPacket.WriteBit(transportGuid[7]);
_worldPacket.WriteBit(transportGuid[0]);
_worldPacket.WriteBit(transportGuid[4]);
_worldPacket.WriteBit(hasTransportTime2);
_worldPacket.WriteBit(Status->HasTransportTime2());
_worldPacket.WriteBit(transportGuid[5]);
_worldPacket.WriteBit(transportGuid[2]);
}
_worldPacket.WriteBit(!hasPitch);
_worldPacket.WriteBit(!Status->HasPitch());
_worldPacket.FlushBits();
_worldPacket.WriteByteSeq(guid[5]);
if (hasFallData)
if (Status->HasFallData())
{
if (hasFallDirection)
if (Status->HasFallDirection())
{
_worldPacket << float(Status->jump.xyspeed);
_worldPacket << float(Status->jump.sinAngle);
@@ -101,27 +87,27 @@ WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
_worldPacket << uint32(Status->jump.fallTime);
}
if (hasSplineElevation)
if (Status->HasSplineElevation())
_worldPacket << float(Status->splineElevation);
_worldPacket.WriteByteSeq(guid[7]);
_worldPacket << float(Status->pos.GetPositionY());
_worldPacket.WriteByteSeq(guid[3]);
if (hasTransportData)
if (Status->HasTransportData())
{
if (hasTransportVehicleId)
if (Status->HasTransportVehicleId())
_worldPacket << uint32(Status->transport.vehicleId);
_worldPacket.WriteByteSeq(transportGuid[6]);
_worldPacket << uint8(Status->transport.seat);
_worldPacket << int8(Status->transport.seat);
_worldPacket.WriteByteSeq(transportGuid[5]);
_worldPacket << float(Status->transport.pos.GetPositionX());
_worldPacket.WriteByteSeq(transportGuid[1]);
_worldPacket << float(Status->transport.pos.GetOrientation());
_worldPacket.WriteByteSeq(transportGuid[2]);
if (hasTransportTime2)
if (Status->HasTransportTime2())
_worldPacket << uint32(Status->transport.time2);
_worldPacket.WriteByteSeq(transportGuid[0]);
@@ -138,16 +124,16 @@ WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
_worldPacket.WriteByteSeq(guid[6]);
_worldPacket << float(Status->pos.GetPositionZ());
if (hasTime)
if (Status->HasTime())
_worldPacket << uint32(Status->time);
_worldPacket.WriteByteSeq(guid[2]);
if (hasPitch)
if (Status->HasPitch())
_worldPacket << float(Status->pitch);
_worldPacket.WriteByteSeq(guid[0]);
if (hasOrientation)
if (Status->HasOrientation())
_worldPacket << float(Status->pos.GetOrientation());
_worldPacket.WriteByteSeq(guid[1]);
@@ -155,6 +141,126 @@ WorldPacket const* WorldPackets::Movement::MoveUpdate::Write()
return &_worldPacket;
}
void WorldPackets::Movement::MoveSetCollisionHeightAck::Read()
{
_worldPacket >> Height;
_worldPacket >> Data.Status.pos.m_positionX;
_worldPacket >> Data.Status.pos.m_positionZ;
_worldPacket >> Data.AckIndex;
_worldPacket >> Data.Status.pos.m_positionY;
Data.Status.guid[6] = _worldPacket.ReadBit();
Data.Status.guid[4] = _worldPacket.ReadBit();
Reason = UpdateCollisionHeightReason(_worldPacket.ReadBits(2));
bool hasPitch = !_worldPacket.ReadBit();
Data.Status.guid[5] = _worldPacket.ReadBit();
_worldPacket.ReadBit(); // HeightChangeFailed
Data.Status.guid[2] = _worldPacket.ReadBit();
Data.Status.guid[1] = _worldPacket.ReadBit();
bool hasFallData = _worldPacket.ReadBit();
Data.Status.guid[3] = _worldPacket.ReadBit();
_worldPacket.ReadBit(); // HasSpline
Data.Status.guid[7] = _worldPacket.ReadBit();
bool hasMovementFlags = !_worldPacket.ReadBit();
bool hasTransportData = _worldPacket.ReadBit();
bool hasTime = !_worldPacket.ReadBit();
bool hasSplineElevation = !_worldPacket.ReadBit();
bool hasExtraMovementFlags = !_worldPacket.ReadBit();
bool hasOrientation = !_worldPacket.ReadBit();
Data.Status.guid[0] = _worldPacket.ReadBit();
bool hasTransportTime2 = false;
bool hasVehicleId = false;
if (hasTransportData)
{
Data.Status.transport.guid[4] = _worldPacket.ReadBit();
Data.Status.transport.guid[3] = _worldPacket.ReadBit();
hasTransportTime2 = _worldPacket.ReadBit();
hasVehicleId = _worldPacket.ReadBit();
Data.Status.transport.guid[5] = _worldPacket.ReadBit();
Data.Status.transport.guid[1] = _worldPacket.ReadBit();
Data.Status.transport.guid[7] = _worldPacket.ReadBit();
Data.Status.transport.guid[2] = _worldPacket.ReadBit();
Data.Status.transport.guid[6] = _worldPacket.ReadBit();
Data.Status.transport.guid[0] = _worldPacket.ReadBit();
}
if (hasExtraMovementFlags)
Data.Status.flags2 = _worldPacket.ReadBits(12);
if (hasMovementFlags)
Data.Status.flags = _worldPacket.ReadBits(30);
bool hasFallDirection = false;
if (hasFallData)
hasFallDirection = _worldPacket.ReadBit();
_worldPacket.ReadByteSeq(Data.Status.guid[0]);
_worldPacket.ReadByteSeq(Data.Status.guid[3]);
_worldPacket.ReadByteSeq(Data.Status.guid[1]);
_worldPacket.ReadByteSeq(Data.Status.guid[5]);
_worldPacket.ReadByteSeq(Data.Status.guid[7]);
_worldPacket.ReadByteSeq(Data.Status.guid[6]);
_worldPacket.ReadByteSeq(Data.Status.guid[2]);
_worldPacket.ReadByteSeq(Data.Status.guid[4]);
if (hasTransportData)
{
_worldPacket >> Data.Status.transport.pos.m_positionX;
_worldPacket.ReadByteSeq(Data.Status.transport.guid[4]);
if (hasTransportTime2)
_worldPacket >> Data.Status.transport.time2;
_worldPacket.ReadByteSeq(Data.Status.transport.guid[0]);
float o = 0.f;
_worldPacket >> o;
Data.Status.transport.pos.SetOrientation(o);
_worldPacket >> Data.Status.transport.pos.m_positionY;
_worldPacket.ReadByteSeq(Data.Status.transport.guid[7]);
_worldPacket >> Data.Status.transport.seat;
_worldPacket.ReadByteSeq(Data.Status.transport.guid[5]);
_worldPacket.ReadByteSeq(Data.Status.transport.guid[2]);
_worldPacket >> Data.Status.transport.time;
_worldPacket.ReadByteSeq(Data.Status.transport.guid[6]);
_worldPacket.ReadByteSeq(Data.Status.transport.guid[3]);
_worldPacket.ReadByteSeq(Data.Status.transport.guid[1]);
if (hasVehicleId)
_worldPacket >> Data.Status.transport.vehicleId;
_worldPacket >> Data.Status.transport.pos.m_positionZ;
}
if (hasFallData)
{
_worldPacket >> Data.Status.jump.zspeed;
_worldPacket >> Data.Status.jump.fallTime;
if (hasFallDirection)
{
_worldPacket >> Data.Status.jump.cosAngle;
_worldPacket >> Data.Status.jump.sinAngle;
_worldPacket >> Data.Status.jump.xyspeed;
}
}
if (hasTime)
_worldPacket >> Data.Status.time;
if (hasSplineElevation)
_worldPacket >> Data.Status.splineElevation;
if (hasOrientation)
{
float o = 0.f;
_worldPacket >> o;
Data.Status.pos.SetOrientation(o);
}
if (hasPitch)
_worldPacket >> Data.Status.pitch;
}
WorldPacket const* WorldPackets::Movement::TransferPending::Write()
{
_worldPacket.WriteBit(TransferSpellID.is_initialized());
@@ -229,6 +335,125 @@ WorldPacket const* WorldPackets::Movement::MoveSetCollisionHeight::Write()
return &_worldPacket;
}
WorldPacket const* WorldPackets::Movement::MoveUpdateCollisionHeight::Write()
{
_worldPacket << float(Status->pos.GetPositionZ());
_worldPacket << float(Height);
_worldPacket << float(Status->pos.GetPositionX());
_worldPacket << float(Status->pos.GetPositionY());
_worldPacket.WriteBit(Status->guid[6]);
_worldPacket.WriteBit(Status->guid[7]);
_worldPacket.WriteBit(!Status->HasSplineElevation());
_worldPacket.WriteBit(Status->HasTransportData());
if (Status->HasTransportData())
{
_worldPacket.WriteBit(Status->transport.guid[6]);
_worldPacket.WriteBit(Status->transport.guid[4]);
_worldPacket.WriteBit(Status->transport.guid[3]);
_worldPacket.WriteBit(Status->transport.guid[7]);
_worldPacket.WriteBit(Status->transport.guid[5]);
_worldPacket.WriteBit(Status->HasTransportVehicleId());
_worldPacket.WriteBit(Status->transport.guid[1]);
_worldPacket.WriteBit(Status->transport.guid[0]);
_worldPacket.WriteBit(Status->transport.guid[2]);
_worldPacket.WriteBit(Status->HasTransportTime2());
}
_worldPacket.WriteBit(Status->guid[3]);
_worldPacket.WriteBit(!Status->HasOrientation());
_worldPacket.WriteBit(Status->guid[4]);
_worldPacket.WriteBit(Status->guid[5]);
_worldPacket.WriteBit(!Status->HasTime());
_worldPacket.WriteBit(Status->HasFallData());
_worldPacket.WriteBit(Status->guid[0]);
_worldPacket.WriteBit(!Status->HasPitch());
_worldPacket.WriteBit(Status->HasHeightChangeFailed());
_worldPacket.WriteBit(Status->guid[2]);
_worldPacket.WriteBit(!Status->HasMovementFlags());
if (Status->HasFallData())
_worldPacket.WriteBit(Status->HasFallDirection());
_worldPacket.WriteBit(Status->guid[1]);
_worldPacket.WriteBit(!Status->HasExtraMovementFlags());
_worldPacket.WriteBit(Status->HasSpline());
if (Status->HasExtraMovementFlags())
_worldPacket.WriteBits(Status->GetExtraMovementFlags(), 12);
if (Status->HasMovementFlags())
_worldPacket.WriteBits(Status->GetMovementFlags(), 30);
_worldPacket.FlushBits();
_worldPacket.WriteByteSeq(Status->guid[3]);
if (Status->HasTransportData())
{
_worldPacket.WriteByteSeq(Status->transport.guid[7]);
_worldPacket << uint32(Status->transport.time);
_worldPacket.WriteByteSeq(Status->transport.guid[4]);
if (Status->HasTransportVehicleId())
_worldPacket << uint32(Status->transport.vehicleId);
if (Status->HasTransportTime2())
_worldPacket << uint32(Status->transport.time2);
_worldPacket.WriteByteSeq(Status->transport.guid[5]);
_worldPacket << float(Status->transport.pos.GetOrientation());
_worldPacket << float(Status->transport.pos.GetPositionX());
_worldPacket.WriteByteSeq(Status->transport.guid[6]);
_worldPacket.WriteByteSeq(Status->transport.guid[0]);
_worldPacket << float(Status->transport.pos.GetPositionY());
_worldPacket.WriteByteSeq(Status->transport.guid[2]);
_worldPacket << float(Status->transport.pos.GetPositionZ());
_worldPacket.WriteByteSeq(Status->transport.guid[3]);
_worldPacket.WriteByteSeq(Status->transport.guid[1]);
_worldPacket << int8(Status->transport.seat);
}
if (Status->HasPitch())
_worldPacket << float(Status->pitch);
_worldPacket.WriteByteSeq(Status->guid[6]);
if (Status->HasFallData())
{
if (Status->HasFallDirection())
{
_worldPacket << float(Status->jump.cosAngle);
_worldPacket << float(Status->jump.sinAngle);
_worldPacket << float(Status->jump.xyspeed);
}
_worldPacket << float(Status->jump.zspeed);
_worldPacket << uint32(Status->jump.fallTime);
}
_worldPacket.WriteByteSeq(Status->guid[7]);
if (Status->HasOrientation())
_worldPacket << float(Status->pos.GetOrientation());
_worldPacket.WriteByteSeq(Status->guid[0]);
_worldPacket.WriteByteSeq(Status->guid[5]);
_worldPacket.WriteByteSeq(Status->guid[4]);
if (Status->HasSplineElevation())
_worldPacket << float(Status->splineElevation);
if (Status->HasTime())
_worldPacket << uint32(Status->time);
_worldPacket.WriteByteSeq(Status->guid[2]);
_worldPacket.WriteByteSeq(Status->guid[1]);
return &_worldPacket;
}
WorldPacket const* WorldPackets::Movement::MoveKnockBack::Write()
{
_worldPacket.WriteBit(MoverGUID[0]);
@@ -26,6 +26,12 @@ namespace WorldPackets
{
namespace Movement
{
struct MovementAck
{
MovementInfo Status;
int32 AckIndex = 0;
};
class TC_GAME_API MoveUpdate final : public ServerPacket
{
public:
@@ -36,6 +42,20 @@ namespace WorldPackets
MovementInfo* Status = nullptr;
};
class MoveSetCollisionHeightAck final : public ClientPacket
{
public:
MoveSetCollisionHeightAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_SET_COLLISION_HEIGHT_ACK, std::move(packet)) { }
void Read() override;
MovementAck Data;
UpdateCollisionHeightReason Reason = UPDATE_COLLISION_HEIGHT_MOUNT;
float Height = 1.0f;
};
class TransferPending final : public ServerPacket
{
struct ShipTransferPending
@@ -99,6 +119,17 @@ namespace WorldPackets
UpdateCollisionHeightReason Reason = UPDATE_COLLISION_HEIGHT_MOUNT;
};
class MoveUpdateCollisionHeight final : public ServerPacket
{
public:
MoveUpdateCollisionHeight() : ServerPacket(SMSG_MOVE_UPDATE_COLLISION_HEIGHT) { }
WorldPacket const* Write() override;
MovementInfo* Status = nullptr;
float Height = 1.0f;
};
struct MoveKnockBackSpeeds
{
float HorzSpeed = 0.0f;
+2 -1
View File
@@ -143,6 +143,7 @@ namespace WorldPackets
namespace Movement
{
class MoveSetCollisionHeightAck;
class SuspendTokenResponse;
}
@@ -651,7 +652,7 @@ class TC_GAME_API WorldSession
void HandleGravityAckMessage(WorldPacket & recvData);
void HandleMoveTeleportAck(WorldPacket& recvPacket);
void HandleForceSpeedChangeAck(WorldPacket& recvData);
void HandleSetCollisionHeightAck(WorldPacket& recvPacket);
void HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCollisionHeightAck& packet);
void HandlePingOpcode(WorldPacket& recvPacket);
void HandleRepopRequestOpcode(WorldPacket& recvPacket);