diff --git a/src/common/Common.h b/src/common/Common.h index 389c6093..465a3a71 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -25,6 +25,8 @@ namespace Sapphire::Common float x; float y; float z; + inline bool operator == ( const FFXIVARR_POSITION3& target ) const + { return ( this->x == target.x && this->y == target.y && this->z == target.z ); } }; struct FFXIVARR_POSITION3_U16 @@ -419,7 +421,6 @@ namespace Sapphire::Common Walking = 0x02, Strafing = 0x04, Jumping = 0x10, - BackWalk = 0x06, }; enum MoveState : @@ -430,6 +431,13 @@ namespace Sapphire::Common Fall = 0x04, }; + enum MoveSpeed : + uint8_t + { + Walk = 24, + Run = 60, + }; + struct QuestActive { QuestActive() diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 75a1f959..663feb3c 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -47,6 +47,19 @@ struct FFXIVIpcClientTrigger : /* 0018 */ uint64_t param3; }; +struct FFXIVIpcUpdatePosition : + FFXIVIpcBasePacket< UpdatePositionHandler > +{ + /* 0000 */ float rotation; + /* 0004 */ uint8_t unk_1[ 3 ]; + /* 0007 */ uint8_t headPosition; + /* 0008 */ uint8_t animationType; + /* 0009 */ uint8_t animationState; + /* 000A */ uint8_t clientAnimationType; + /* 000B */ uint8_t unk_2; + /* 000C */ Common::FFXIVARR_POSITION3 position; +}; + struct FFXIVIpcSkillHandler : FFXIVIpcBasePacket< SkillHandler > { diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 65de5804..f5353adb 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -665,10 +665,11 @@ struct FFXIVIpcActorMove : FFXIVIpcBasePacket< ActorMove > { /* 0000 */ uint8_t rotation; - /* 0001 */ uint8_t unknown_1; + /* 0001 */ uint8_t headRotation; /* 0002 */ uint8_t animationType; - /* 0003 */ uint8_t unknown_3; - /* 0004 */ uint16_t unknown_4; + /* 0003 */ uint8_t animationState; + /* 0004 */ uint8_t animationSpeed; + /* 0005 */ uint8_t unkownRotation; /* 0006 */ uint16_t posX; /* 0008 */ uint16_t posY; /* 000a */ uint16_t posZ; diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 52130a41..a7d66676 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -77,7 +77,8 @@ Sapphire::Entity::Player::Player( FrameworkPtr pFw ) : m_mount( 0 ), m_emoteMode( 0 ), m_directorInitialized( false ), - m_onEnterEventDone( false ) + m_onEnterEventDone( false ), + m_falling( false ) { m_id = 0; m_currentStance = Stance::Passive; diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 388afa51..154b4fe2 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -963,6 +963,7 @@ namespace Sapphire::Entity uint64_t m_lastMoveTime; uint8_t m_lastMoveflag; + bool m_falling; private: uint32_t m_lastWrite; diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index b1bd4530..ca98c6c1 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -183,54 +183,17 @@ void Sapphire::Network::GameConnection::updatePositionHandler( FrameworkPtr pFw, if( player.isMarkedForZoning() ) return; - Packets::FFXIVARR_PACKET_RAW copy = inPacket; + const auto updatePositionPacket = ZoneChannelPacket< Client::FFXIVIpcUpdatePosition >( inPacket ); - struct testMov - { - uint32_t specialMovement : 23; // 0x00490FDA - uint32_t strafe : 7; - uint32_t moveBackward : 1; - uint32_t strafeRight : 1; // if 0, strafe left. - } IPC_OP_019A; + bool bPosChanged = true; + if( updatePositionPacket.data().position == player.getPos() ) + bPosChanged = false; - struct testMov1 - { - uint16_t bit1 : 1; // 0x00490FDA - uint16_t bit2 : 1; - uint16_t bit3 : 1; - uint16_t bit4 : 1; - uint16_t bit5 : 1; - uint16_t bit6 : 1; - uint16_t bit7 : 1; - uint16_t bit8 : 1; - uint16_t bit9 : 1; // 0x00490FDA - uint16_t bit10 : 1; - uint16_t bit11 : 1; - uint16_t bit12 : 1; - uint16_t bit13 : 1; - uint16_t bit14 : 1; - uint16_t bit15 : 1; - uint16_t bit16 : 1; - } IPC_OP_019AB; + //if( !bPosChanged && player.getRot() == updatePositionPacket.data().rotation ) + //return; - auto flags = *reinterpret_cast< uint16_t* >( ©.data[ 0x18 ] ); - memcpy( &IPC_OP_019AB, &flags, 2 ); - - auto flags1 = *reinterpret_cast< uint32_t* >( ©.data[ 0x18 ] ); - memcpy( &IPC_OP_019A, &flags1, 4 ); - - bool bPosChanged = false; - if( ( player.getPos().x != *reinterpret_cast< float* >( ©.data[ 0x1C ] ) ) || - ( player.getPos().y != *reinterpret_cast< float* >( ©.data[ 0x20 ] ) ) || - ( player.getPos().z != *reinterpret_cast< float* >( ©.data[ 0x24 ] ) ) ) - bPosChanged = true; - if( !bPosChanged && player.getRot() == *reinterpret_cast< float* >( ©.data[ 0x10 ] ) ) - return; - - player.setRot( *reinterpret_cast< float* >( ©.data[ 0x10 ] ) ); - player.setPos( *reinterpret_cast< float* >( ©.data[ 0x1C ] ), - *reinterpret_cast< float* >( ©.data[ 0x20 ] ), - *reinterpret_cast< float* >( ©.data[ 0x24 ] ) ); + player.setRot( updatePositionPacket.data().rotation ); + player.setPos( updatePositionPacket.data().position ); if( ( player.getCurrentAction() != nullptr ) && bPosChanged ) player.getCurrentAction()->setInterrupted(); @@ -239,73 +202,57 @@ void Sapphire::Network::GameConnection::updatePositionHandler( FrameworkPtr pFw, if( !player.hasInRangeActor() ) return; - auto moveState = *reinterpret_cast< uint8_t* >( ©.data[ 0x19 ] ); - auto moveType = *reinterpret_cast< uint8_t* >( ©.data[ 0x18 ] ); + auto clientAnimationType = updatePositionPacket.data().clientAnimationType; + auto animationState = updatePositionPacket.data().animationState; + auto animationType = updatePositionPacket.data().animationType; + auto headRotation = updatePositionPacket.data().headPosition; + uint8_t unkownRotation = 0; + uint16_t animationSpeed = MoveSpeed::Walk; - uint8_t unk1 = 0; - uint8_t unk2 = 0; - uint8_t unk3 = moveState; - uint16_t unk4 = 0; + animationType |= clientAnimationType; - // HACK: This part is hackish, we need to find out what all theese things really do. - //Logger::debug( std::to_string( moveState ) + " -- moveState " ); - //Logger::debug( std::to_string( moveType ) + " -- moveType " ); + bool shouldSend = true; - if( moveType & MoveType::Running ) + if( animationType & MoveType::Strafing) { - unk1 = 0x7F; - unk2 = 0x00; - unk4 = 0x3C; + if( animationType & MoveType::Walking ) + headRotation = 0xFF; + else if( headRotation < 0x7F ) + headRotation += 0x7F; + else if( headRotation > 0x7F ) + headRotation -= 0x7F; } - - if( moveType & MoveType::Strafing ) + if( animationType == MoveType::Running ) { - unk2 = 0x40; - unk1 = 0x7F; - //if( IPC_OP_019A.strafeRight == 1 ) - // unk1 = 0xbf; - //else - // unk1 = 0x5f; - unk4 = 0x3C; + headRotation = 0x7F; + animationSpeed = MoveSpeed::Run; } - - if( moveType & MoveType::Walking ) + if( animationType & MoveType::Jumping) { - unk1 = 0x7F; - unk2 = 0x02; - unk3 = 0x00; - unk4 = 0x18; + if( animationState == MoveState::Fall ) + player.m_falling = true; + else + shouldSend = false; } + else + player.m_falling = false; - if( moveType & MoveType::Walking && moveType & MoveType::Strafing ) + if( player.m_falling ) { - unk2 = 0x06; - unk1 = 0xFF; - unk4 = 0x18; - } - - if( moveType & MoveType::Jumping ) - { - - unk1 = 0x3F; - unk2 = 0x32; - unk4 = 0x5f18; - if( moveState == MoveState::Land ) - unk2 = 0x02; - + animationType += 0x10; + unkownRotation = 0x7F; } uint64_t currentTime = Util::getTimeMs(); - if( ( currentTime - player.m_lastMoveTime ) < 100 && player.m_lastMoveflag == moveState ) - return; - player.m_lastMoveTime = currentTime; - player.m_lastMoveflag = moveState; - - auto movePacket = std::make_shared< MoveActorPacket >( player, unk1, unk2, moveState, unk4 ); - player.sendToInRangeSet( movePacket ); + player.m_lastMoveflag = animationType; + if( shouldSend ) + { + auto movePacket = std::make_shared< MoveActorPacket >( player, headRotation, animationType, animationState, animationSpeed, unkownRotation ); + player.sendToInRangeSet( movePacket ); + } } void diff --git a/src/world/Network/PacketWrappers/MoveActorPacket.h b/src/world/Network/PacketWrappers/MoveActorPacket.h index f4a4f589..864d137d 100644 --- a/src/world/Network/PacketWrappers/MoveActorPacket.h +++ b/src/world/Network/PacketWrappers/MoveActorPacket.h @@ -19,21 +19,22 @@ namespace Sapphire::Network::Packets::Server public ZoneChannelPacket< FFXIVIpcActorMove > { public: - MoveActorPacket( Entity::Chara& actor, uint8_t unk1, uint8_t animationType, uint8_t unk3, uint16_t unk4 ) : + MoveActorPacket( Entity::Chara& actor, uint8_t headRotation, uint8_t animationType, uint8_t state, uint16_t animationSpeed, uint8_t unkownRotation = 0 ) : ZoneChannelPacket< FFXIVIpcActorMove >( actor.getId(), actor.getId() ) { - initialize( actor, unk1, animationType, unk3, unk4 ); + initialize( actor, headRotation, animationType, state, animationSpeed, unkownRotation ); }; private: - void initialize( Entity::Chara& actor, uint8_t unk1, uint8_t animationType, uint8_t unk3, uint16_t unk4 ) + void initialize( Entity::Chara& actor, uint8_t headRotation, uint8_t animationType, uint8_t state, uint16_t animationSpeed, uint8_t unkownRotation ) { m_data.rotation = Util::floatToUInt8Rot( actor.getRot() ); - m_data.unknown_1 = unk1; + m_data.headRotation = headRotation; m_data.animationType = animationType; - m_data.unknown_3 = unk3; - m_data.unknown_4 = unk4; + m_data.animationState = state; + m_data.animationSpeed = animationSpeed;; + m_data.unkownRotation = unkownRotation; m_data.posX = Util::floatToUInt16( actor.getPos().x ); m_data.posY = Util::floatToUInt16( actor.getPos().y ); m_data.posZ = Util::floatToUInt16( actor.getPos().z );