From b1e430cf39dcba35011625e5933c5a2587e87601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=82=B3=E3=83=AC=E3=83=83=E3=83=88?= <59412435+collett8192@users.noreply.github.com> Date: Tue, 10 Aug 2021 15:55:10 +0900 Subject: [PATCH] CF register fix. (#719) * CF register fix. * typo --- src/common/Network/PacketDef/Ipcs.h | 2 +- .../Network/PacketDef/Zone/ClientZoneDef.h | 6 ++ src/world/Actor/Player.cpp | 8 +- src/world/Actor/Player.h | 3 +- src/world/Network/GameConnection.cpp | 2 +- src/world/Network/Handlers/CFHandlers.cpp | 88 ++++++++++--------- 6 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index a0b26779..c33cfad6 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -320,7 +320,7 @@ namespace Sapphire::Network::Packets FinishLoadingHandler = 0x0217, // updated 5.58 - CFCommenceHandler = 0xF118, // updated 5.35 hotfix + CFCommenceHandler = 0x02A3, // updated 5.58 CFCancelHandler = 0x00A9, // updated 5.58 CFRegisterDuty = 0x036A, // updated 5.58 diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 45840848..0d67ea61 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -446,6 +446,12 @@ struct FFXIVIpcHousingEditInterior : uint16_t slot[10]; }; +struct FFXIVIpcCFCommenceHandler : + FFXIVIpcBasePacket< CFCommenceHandler > +{ + uint64_t param; +}; + } #endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 9c10ebb8..7f089e92 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -81,7 +81,8 @@ Sapphire::Entity::Player::Player() : m_directorInitialized( false ), m_onEnterEventDone( false ), m_falling( false ), - m_pQueuedAction( nullptr ) + m_pQueuedAction( nullptr ), + m_cfNotifiedContent( 0 ) { m_id = 0; m_currentStance = Stance::Passive; @@ -239,13 +240,16 @@ uint64_t Sapphire::Entity::Player::getOnlineStatusMask() const return m_onlineStatus; } -void Sapphire::Entity::Player::prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime, uint16_t animation ) +void Sapphire::Entity::Player::prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime, uint16_t animation, uint8_t param4, uint8_t param7, uint8_t unknown ) { auto preparePacket = makeZonePacket< FFXIVIpcPrepareZoning >( getId() ); preparePacket->data().targetZone = targetZone; preparePacket->data().fadeOutTime = fadeOutTime; preparePacket->data().animation = animation; preparePacket->data().fadeOut = static_cast< uint8_t >( fadeOut ? 1 : 0 ); + preparePacket->data().param4 = param4; + preparePacket->data().param7 = param7; + preparePacket->data().unknown = unknown; queuePacket( preparePacket ); } diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 81d5a599..0b95ab24 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -547,7 +547,7 @@ namespace Sapphire::Entity void dyeItemFromDyeingInfo(); /*! prepares zoning / fades out the screen */ - void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime = 0, uint16_t animation = 0 ); + void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime = 0, uint16_t animation = 0, uint8_t param4 = 0, uint8_t param7 = 0, uint8_t unknown = 0 ); /*! get player's title list (available titles) */ uint8_t* getTitleList(); @@ -1005,6 +1005,7 @@ namespace Sapphire::Entity uint64_t m_lastMoveTime; uint8_t m_lastMoveflag; bool m_falling; + uint16_t m_cfNotifiedContent; std::vector< ShopBuyBackEntry >& getBuyBackListForShop( uint32_t shopId ); void addBuyBackItemForShop( uint32_t shopId, const ShopBuyBackEntry& entry ); diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 7e360ada..17907571 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -120,7 +120,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH setZoneHandler( ClientZoneIpcType::CFRegisterDuty, "CFRegisterDuty", &GameConnection::cfRegisterDuty ); setZoneHandler( ClientZoneIpcType::CFRegisterRoulette, "CFRegisterRoulette", &GameConnection::cfRegisterRoulette ); setZoneHandler( ClientZoneIpcType::CFCommenceHandler, "CFDutyAccepted", &GameConnection::cfDutyAccepted ); - setZoneHandler( ClientZoneIpcType::CFCancelHandler, "CFCancel", &GameConnection::cfCancel ); + //setZoneHandler( ClientZoneIpcType::CFCancelHandler, "CFCancel", &GameConnection::cfCancel ); setZoneHandler( ClientZoneIpcType::ReqEquipDisplayFlagsChange, "ReqEquipDisplayFlagsChange", &GameConnection::reqEquipDisplayFlagsHandler ); diff --git a/src/world/Network/Handlers/CFHandlers.cpp b/src/world/Network/Handlers/CFHandlers.cpp index 0cc3a39f..08e53124 100644 --- a/src/world/Network/Handlers/CFHandlers.cpp +++ b/src/world/Network/Handlers/CFHandlers.cpp @@ -12,6 +12,7 @@ #include "Network/GameConnection.h" #include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/PlayerStateFlagsPacket.h" +#include "Network/PacketDef/Zone/ClientZoneDef.h" #include "Session.h" @@ -43,9 +44,6 @@ void Sapphire::Network::GameConnection::cfRegisterDuty( const Packets::FFXIVARR_ Entity::Player& player ) { Packets::FFXIVARR_PACKET_RAW copy = inPacket; - auto& teriMgr = Common::Service< TerritoryMgr >::ref(); - auto& exdData = Common::Service< Data::ExdDataGenerated >::ref(); - std::vector< uint16_t > selectedContent; for( uint32_t offset = 0x1E; offset <= 0x26; offset += 0x2 ) @@ -54,70 +52,76 @@ void Sapphire::Network::GameConnection::cfRegisterDuty( const Packets::FFXIVARR_ if( id == 0 ) break; - player.sendDebug( "got contentId#{0}", id ); + player.sendDebug( "got contentFinderConditionId#{0}", id ); selectedContent.push_back( id ); } // todo: rand bias problem, will do for now tho auto index = static_cast< uint32_t >( std::rand() ) % selectedContent.size(); - auto contentId = selectedContent.at( index ); + auto contentFinderConditionId = selectedContent.at( index ); - player.sendDebug( "Duty register request for contentid#{0}", contentId ); - - // let's cancel it because otherwise you can't register it again - /* - auto cfCancelPacket = makeZonePacket< FFXIVIpcCFNotify >( player.getId() ); - cfCancelPacket->data().state1 = 3; - cfCancelPacket->data().state2 = 1; // Your registration is withdrawn. - queueOutPacket( cfCancelPacket ); - */ - auto packet = makeZonePacket< FFXIVIpcCFCancel >( player.getId() ); - packet->data().cancelReason = 890; - queueOutPacket( packet ); - - auto cfCondition = exdData.get< Sapphire::Data::ContentFinderCondition >( contentId ); - if( !cfCondition ) - return; - - auto instance = teriMgr.createInstanceContent( cfCondition->content ); - if( !instance ) - return; - - auto pInstance = instance->getAsInstanceContent(); - pInstance->bindPlayer( player.getId() ); - - player.sendDebug( "Created instance with id#", instance->getGuId() ); - - player.setInstance( instance ); + player.sendDebug( "Duty register request for contentFinderConditionId#{0}", contentFinderConditionId ); + player.m_cfNotifiedContent = contentFinderConditionId; + auto notify = makeZonePacket< FFXIVIpcCFNotify >( player.getId() ); + notify->data().state1 = 8195; + notify->data().param3 = 1; + notify->data().param4 = contentFinderConditionId; + player.queuePacket( notify ); } void Sapphire::Network::GameConnection::cfRegisterRoulette( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) { - /* - auto cfCancelPacket = makeZonePacket< FFXIVIpcCFNotify >( player.getId() ); - cfCancelPacket->data().state1 = 3; - cfCancelPacket->data().state2 = 1; // Your registration is withdrawn. - queueOutPacket( cfCancelPacket ); - */ auto packet = makeZonePacket< FFXIVIpcCFCancel >( player.getId() ); packet->data().cancelReason = 890; queueOutPacket( packet ); - player.sendDebug( "Roulette register" ); + player.sendDebug( "Roulette register not implemented." ); } void Sapphire::Network::GameConnection::cfDutyAccepted( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) { - player.sendDebug( "TODO: Duty accept" ); -} + const auto packetIn = ZoneChannelPacket< Client::FFXIVIpcCFCommenceHandler >( inPacket ); + if( packetIn.data().param == 0 ) + { + // accept + if( player.m_cfNotifiedContent > 0 ) + { + auto& teriMgr = Common::Service< TerritoryMgr >::ref(); + auto instance = teriMgr.createInstanceContent( player.m_cfNotifiedContent ); + if( !instance ) + return; + + player.m_cfNotifiedContent = 0; + auto pInstance = instance->getAsInstanceContent(); + pInstance->bindPlayer( player.getId() ); + + player.sendDebug( "Created instance with id#{}", instance->getGuId() ); + + player.prepareZoning( pInstance->getTerritoryTypeId(), true, 1, 0, 0, 1, 9 ); + + auto sourceZoneGuId = player.getCurrentTerritory()->getGuId(); + player.setInstance( instance ); + } + } + else + { + // cancel + player.m_cfNotifiedContent = 0; + auto packet = makeZonePacket< FFXIVIpcCFCancel >( player.getId() ); + packet->data().cancelReason = 890; + queueOutPacket( packet ); + } +} +/* void Sapphire::Network::GameConnection::cfCancel( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) { auto packet = makeZonePacket< FFXIVIpcCFCancel >( player.getId() ); packet->data().cancelReason = 890; queueOutPacket( packet ); -} \ No newline at end of file +} +*/ \ No newline at end of file