From 9f100bc671316c10ff1897892ce03926cba4fd5b Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 14 Feb 2023 13:50:08 +0100 Subject: [PATCH] Fixed a couple minor struct issues and overall changed login packetflow to be more retail-like. Added a few unknown actorcontrol packets for testing. --- deps/datReader/Exd/Structs.h | 3 +- src/common/Network/CommonActorControl.h | 16 ++++++--- .../Network/PacketDef/Zone/ServerZoneDef.h | 11 +++--- src/world/Actor/Player.cpp | 3 +- src/world/Manager/DebugCommandMgr.cpp | 8 ----- src/world/Manager/PlayerMgr.cpp | 36 +++++++++++++++---- src/world/Network/GameConnection.cpp | 16 +++++---- 7 files changed, 57 insertions(+), 36 deletions(-) diff --git a/deps/datReader/Exd/Structs.h b/deps/datReader/Exd/Structs.h index c2f22a63..a93aca6b 100644 --- a/deps/datReader/Exd/Structs.h +++ b/deps/datReader/Exd/Structs.h @@ -4610,8 +4610,7 @@ namespace Excel /* 390890 */ struct Permission { - bool Flag[58]; - int8_t padding0[2]; + bool Flag[80]; }; /* 391161 */ diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 911244e0..35cd5b7a 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -92,7 +92,8 @@ namespace Sapphire::Network::ActorControl DirectorUpdate = 0x6D, - ItemObtainMsg = 0x75, + SetFateState = 0x74, + ObtainFateItem = 0x75, FateReqFailMsg = 0x76, DutyQuestScreenMsg = 0x7B, @@ -105,9 +106,12 @@ namespace Sapphire::Network::ActorControl ActionLearnMsg1 = 0x87, FreeEventPos = 0x8A, + MoveType = 0x8E, // 1 == pvp, 0 == normal DailyQuestSeed = 0x90, // param1 = the daily quest seed + SetFateProgress = 0x9B, + SetBGM = 0xA1, UnlockAetherCurrentMsg = 0xA4, @@ -119,10 +123,10 @@ namespace Sapphire::Network::ActorControl Appear = 0xC8, ZoneInDefaultPos = 0xC9, - TeleportStart = 0xCB, - TeleportInvitation = 0xCC, - TeleportDone = 0xCD, - TeleportDoneFadeOut = 0xCE, + OnExecuteTelepo = 0xCB, + OnInvitationTelepo = 0xCC, + OnExecuteTelepoAction = 0xCD, + TownTranslate = 0xCE, WarpStart = 0xCF, @@ -285,6 +289,8 @@ namespace Sapphire::Network::ActorControl SetFestival = 0x386, // param1: festival.exd index + SetCycleTimes = 0x38B, + ToggleOrchestrionUnlock = 0x396, EventBattleDialog = 0x39C, diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index e1fcee9b..a1502c2c 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -698,9 +698,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server uint8_t LinkParent; uint8_t PoseEmote; uint8_t __padding1; - uint16_t Flag; - uint8_t __padding2; - uint8_t __padding3; + uint32_t Flag; Common::StatusWork Status[30]; MountStruct Mount; uint8_t Name[32]; @@ -869,8 +867,8 @@ namespace Sapphire::Network::Packets::WorldPackets::Server uint8_t BirthMonth; uint8_t Birthday; uint8_t StartTown; - uint8_t GrandCompany; uint8_t HomePoint; + uint8_t GrandCompany; uint8_t Pet; uint8_t BuddyRank; uint8_t BuddyRankExceeded; @@ -1019,9 +1017,8 @@ namespace Sapphire::Network::Packets::WorldPackets::Server uint8_t Penalty; uint8_t Login; uint8_t __padding1; + uint16_t Lv1; uint16_t Lv; - uint8_t __padding2; - uint8_t __padding3; uint32_t BorrowAction[10]; uint8_t PhysicalBonus[6]; }; @@ -1560,7 +1557,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server uint8_t update; uint8_t __padding1; uint8_t __padding2; - struct DailyQuest dailyQuestArray[6]; + struct DailyQuest dailyQuestArray[12]; }; diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index f22053e7..d852f4c1 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1315,7 +1315,6 @@ void Player::autoAttack( CharaPtr pTarget ) entry.Type = Common::ActionEffectType::CALC_RESULT_TYPE_DAMAGE_HP; entry.Arg0 = 2; entry.Arg1 = 7; - //entry.Flag = 128; if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer ) { @@ -1441,7 +1440,7 @@ void Player::teleportQuery( uint16_t aetheryteId ) bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost; // TODO: figure out what param1 really does - queuePacket( makeActorControlSelf( getId(), TeleportStart, insufficientGil ? 2 : 0, aetheryteId ) ); + queuePacket( makeActorControlSelf( getId(), OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId ) ); if( !insufficientGil ) { diff --git a/src/world/Manager/DebugCommandMgr.cpp b/src/world/Manager/DebugCommandMgr.cpp index ad6e608b..6316f94c 100644 --- a/src/world/Manager/DebugCommandMgr.cpp +++ b/src/world/Manager/DebugCommandMgr.cpp @@ -256,14 +256,6 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< player.setCFPenaltyMinutes( static_cast< uint32_t >( minutes ) ); } - else if( subCommand == "eorzeatime" ) - { - uint64_t timestamp; - sscanf( params.c_str(), "%" SCNu64, ×tamp ); - - player.setEorzeaTimeOffset( timestamp ); - PlayerMgr::sendServerNotice( player, "Eorzea time offset: {0}", timestamp ); - } else if( subCommand == "setMount" ) { int32_t id; diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index 51394b89..acba59ad 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -406,6 +406,17 @@ void PlayerMgr::onZone( Sapphire::Entity::Player& player ) if( player.isLogin() ) { + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x169, 0 ) ); // unknown + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x54, 0 ) ); // something treasure map related? + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x23D, 0 ) ); // unknown + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 0 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 1 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 2 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 3 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 4 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 5 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 6 ) ); // SalvageSkill + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x16F, 7 ) ); // SalvageSkill server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetCharaGearParamUI, player.getEquipDisplayFlags(), 1 ) ); server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetMaxGearSets, player.getMaxGearSets() ) ); } @@ -417,19 +428,32 @@ void PlayerMgr::onZone( Sapphire::Entity::Player& player ) if( player.hasReward( Common::UnlockEntry::HuntingLog ) ) player.sendHuntingLog(); - player.sendStats(); + if( player.isLogin() ) + { + player.sendItemLevel(); + server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x39, 0 ) ); // unknown + server.queueForPlayer( player.getCharacterId(), makePlayerSetup( player ) ); + } + player.sendStats(); + player.sendRecastGroups(); + + auto classInfo = makeZonePacket< FFXIVIpcChangeClass >( player.getId() ); + classInfo->data().ClassJob = static_cast< uint8_t >( player.getClass() ); + classInfo->data().Lv = player.getLevel(); + classInfo->data().Lv1 = player.getLevel(); + if( player.isLogin() ) + classInfo->data().Login = 1; + server.queueForPlayer( player.getCharacterId(), classInfo ); + + server.queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), 0x112, 0x24 ) ); // unknown // only initialize the UI if the player in fact just logged in. if( player.isLogin() ) { auto contentFinderList = makeZonePacket< FFXIVIpcContentAttainFlags >( player.getId() ); std::memset( &contentFinderList->data(), 0xFF, sizeof( contentFinderList->data() ) ); - server.queueForPlayer( player.getCharacterId(), { contentFinderList, makePlayerSetup( player ) } ); - - onPlayerStatusUpdate( player ); - - player.sendItemLevel(); + server.queueForPlayer( player.getCharacterId(), contentFinderList ); player.clearSoldItems(); } diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 2eb780b2..cf4f40a0 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -487,7 +487,7 @@ void Sapphire::Network::GameConnection::handlePackets( const Sapphire::Network:: m_pSession = session; auto pe = std::make_shared< FFXIVRawPacket >( 0x07, 0x18, 0, 0 ); - *reinterpret_cast< unsigned int* >( &pe->data()[ 0 ] ) = 0xE0001027; + *reinterpret_cast< unsigned int* >( &pe->data()[ 0 ] ) = 0xE00392b0; *reinterpret_cast< unsigned int* >( &pe->data()[ 4 ] ) = Common::Util::getTimeSeconds(); sendSinglePacket( pe ); @@ -496,11 +496,15 @@ void Sapphire::Network::GameConnection::handlePackets( const Sapphire::Network:: { auto pe1 = std::make_shared< FFXIVRawPacket >( 0x02, 0x38, 0, 0 ); *reinterpret_cast< unsigned int* >( &pe1->data()[ 0 ] ) = entityId; - *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x20 ] ) = entityId; - *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x24 ] ) = Common::Util::getTimeSeconds(); - *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x0C ] ) = Common::Util::getTimeSeconds(); - *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x1C ] ) = Common::Util::getTimeSeconds(); - *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x18 ] ) = Common::Util::getTimeSeconds(); + *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x08 ] ) = 0x90000b60; + *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x0C ] ) = 0x00007f8B; + *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x10 ] ) = 0x7b201bf0; + *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x14 ] ) = 0x00007f8b; + *reinterpret_cast< unsigned int* >( &pe1->data()[ 0x20 ] ) = 0x00005e4c; + //*reinterpret_cast< unsigned int* >( &pe1->data()[ 0x24 ] ) = Common::Util::getTimeSeconds(); + //*reinterpret_cast< unsigned int* >( &pe1->data()[ 0x0C ] ) = Common::Util::getTimeSeconds(); + //*reinterpret_cast< unsigned int* >( &pe1->data()[ 0x1C ] ) = Common::Util::getTimeSeconds(); + //*reinterpret_cast< unsigned int* >( &pe1->data()[ 0x18 ] ) = Common::Util::getTimeSeconds(); sendSinglePacket( pe1 ); Logger::info( "[{0}] Setting session for world connection", id ); session->setZoneConnection( pCon );