diff --git a/src/common/Network/PacketDef/ServerIpcs.h b/src/common/Network/PacketDef/ServerIpcs.h index 87af482f..1b4d62e6 100644 --- a/src/common/Network/PacketDef/ServerIpcs.h +++ b/src/common/Network/PacketDef/ServerIpcs.h @@ -375,7 +375,7 @@ namespace Sapphire::Network::Packets GroundMarker = 0x335, Frontline01Result = 0x336, Frontline01BaseInfo = 0x337, - FinishContentMatchToClient = 0x338, + FinishContentMatchToClient = 0x339, UnMountLink = 0x33E, }; diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 694f9b1c..aa2c6a48 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1614,6 +1614,20 @@ namespace Sapphire::Network::Packets::WorldPackets::Server uint8_t unknown3; }; + struct FFXIVIpcFinishContentMatchToClient : FFXIVIpcBasePacket< FinishContentMatchToClient > + { + uint8_t classJob; + uint8_t progress; + uint8_t playerNum; + uint8_t unknown1; + uint16_t territoryType; + uint8_t __padding2; + uint8_t __padding3; + uint32_t flags; + uint32_t finishContentMatchFlags; + uint64_t startTime; + }; + /** * Structural representation of the packet sent by the server * to update contents available in duty finder or raid finder diff --git a/src/world/ContentFinder/ContentFinder.cpp b/src/world/ContentFinder/ContentFinder.cpp index 8d53c2ea..b37bf8ff 100644 --- a/src/world/ContentFinder/ContentFinder.cpp +++ b/src/world/ContentFinder/ContentFinder.cpp @@ -8,6 +8,7 @@ #include "Network/PacketWrappers/UpdateFindContentPacket.h" #include "Network/PacketWrappers/UpdateContentPacket.h" #include "Network/PacketWrappers/NotifyFindContentPacket.h" +#include "Network/PacketWrappers/FinishContentMatchToClientPacket.h" #include "Territory/Territory.h" #include "Territory/InstanceContent.h" @@ -53,15 +54,11 @@ void World::ContentFinder::update() { uint32_t inProgress = 0; // 0x01 - in progress uint32_t dutyProgress = 0; - uint32_t flags = 0; // 0x20 freerole, 0x40 ownrequest, 0x100 random + // uint32_t flags = 0; // 0x20 freerole, 0x40 ownrequest, 0x100 random - // Undersized - if( content->m_flags & 0x01 ) - flags |= 0x20; - - auto updatePacket = makeUpdateFindContent( queuedPlayer->getEntityId(), contentInfo->data().TerritoryType, - SetResultMatched, inProgress, queuedPlayer->m_classJob, dutyProgress, flags ); - server.queueForPlayer( queuedPlayer->getCharacterId(), updatePacket ); + auto finishContentMatchPacket = makeFinishContentMatchToClient( queuedPlayer->getEntityId(), contentInfo->data().TerritoryType, + queuedPlayer->m_classJob, content->m_players.size(), dutyProgress, content->m_flags ); + server.queueForPlayer( queuedPlayer->getCharacterId(), finishContentMatchPacket ); } content->setState( WaitingForAccept ); @@ -81,8 +78,8 @@ void World::ContentFinder::update() for( auto& queuedPlayer : content->m_players ) { - auto updatePacket = makeUpdateFindContent( queuedPlayer->getEntityId(), 0x06, - SetResultReadyToEnter, 0, queuedPlayer->m_classJob, 0 ); + auto updatePacket = makeUpdateFindContent( queuedPlayer->getEntityId(), instance->getTerritoryTypeId(), + SetResultReadyToEnter, 1 ); server.queueForPlayer( queuedPlayer->getCharacterId(), updatePacket ); pInstanceContent->bindPlayer( queuedPlayer->getEntityId() ); @@ -160,10 +157,14 @@ void World::ContentFinder::completeRegistration( const Entity::Player &player, u if( flags & 0x01 ) { auto updatePacket = makeUpdateFindContent( player.getId(), content->data().TerritoryType, - CompleteRegistration, 0x20, static_cast< uint32_t >( player.getClass() ) ); + CompleteRegistration, 1, static_cast< uint32_t >( player.getClass() ), FindContentFlag::Undersized ); server.queueForPlayer( player.getCharacterId(), updatePacket ); - queuedContent->m_flags = flags; + auto statusPacket = makeNotifyFindContentStatus( player.getId(), content->data().TerritoryType, 2, queuedContent->m_attackerCount + queuedContent->m_rangeCount, + queuedContent->m_healerCount, queuedContent->m_tankCount, 0 ); + server.queueForPlayer( player.getCharacterId(), statusPacket ); + + queuedContent->m_flags |= FindContentFlag::Undersized; queuedContent->setState( MatchingComplete ); } else @@ -172,8 +173,8 @@ void World::ContentFinder::completeRegistration( const Entity::Player &player, u CompleteRegistration, 1, static_cast< uint32_t >( player.getClass() ) ); server.queueForPlayer( player.getCharacterId(), updatePacket ); - auto statusPacket = makeNotifyFindContentStatus( player.getId(), content->data().TerritoryType, 3, queuedContent->m_attackerCount + queuedContent->m_rangeCount, - queuedContent->m_healerCount, queuedContent->m_tankCount, 0xff ); + auto statusPacket = makeNotifyFindContentStatus( player.getId(), content->data().TerritoryType, 1, queuedContent->m_attackerCount + queuedContent->m_rangeCount, + queuedContent->m_healerCount, queuedContent->m_tankCount, 0xFF ); for( auto& queuedPlayer : queuedContent->m_players ) { @@ -394,7 +395,7 @@ void World::ContentFinder::accept( Entity::Player& player ) queuedContent->getInstanceId(), queuedContent->getRegisterId(), player.getId() ); auto statusPacket = makeNotifyFindContentStatus( player.getId(), content->data().TerritoryType, 4, queuedContent->m_dpsAccepted, - queuedContent->m_healerAccepted, queuedContent->m_tankAccepted, 0x01 ); + queuedContent->m_healerAccepted, queuedContent->m_tankAccepted, 1 ); for( auto& pPlayer : queuedContent->m_players ) { diff --git a/src/world/ContentFinder/ContentFinder.h b/src/world/ContentFinder/ContentFinder.h index 5eda468b..bc77662b 100644 --- a/src/world/ContentFinder/ContentFinder.h +++ b/src/world/ContentFinder/ContentFinder.h @@ -6,6 +6,13 @@ namespace Sapphire::World { + enum FindContentFlag : uint32_t + { + Undersized = 0x20, + OwnRequest = 0x40, + Random = 0x100 + }; + enum UpdateFindContentKind : uint8_t { CompleteRegistration = 0, // value1 is used to call setResultFindSuccess if bit1 or bit2 is set, value2 is passed to setFindInfo diff --git a/src/world/Network/Handlers/CFHandlers.cpp b/src/world/Network/Handlers/CFHandlers.cpp index 61c0484c..47441eb8 100644 --- a/src/world/Network/Handlers/CFHandlers.cpp +++ b/src/world/Network/Handlers/CFHandlers.cpp @@ -121,7 +121,7 @@ void Sapphire::Network::GameConnection::acceptContent( const Packets::FFXIVARR_P packet.data().accept, packet.data().territoryId, packet.data().territoryType ); auto& contentFinder = Common::Service< World::ContentFinder >::ref(); - if( packet.data().accept ) + if( packet.data().accept == 0 ) contentFinder.accept( player ); else contentFinder.withdraw( player ); diff --git a/src/world/Network/PacketWrappers/FinishContentMatchToClientPacket.h b/src/world/Network/PacketWrappers/FinishContentMatchToClientPacket.h new file mode 100644 index 00000000..535b7147 --- /dev/null +++ b/src/world/Network/PacketWrappers/FinishContentMatchToClientPacket.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include "Actor/Player.h" +#include "Forwards.h" + +namespace Sapphire::Network::Packets::WorldPackets::Server +{ + + /** + * @brief Packet to display a quest specific info message. + */ + class FinishContentMatchToClientPacket : public ZoneChannelPacket< FFXIVIpcFinishContentMatchToClient > + { + public: + FinishContentMatchToClientPacket( uint32_t playerId, uint16_t terriId, uint8_t classJob, uint8_t playerNum, uint8_t progress = 0, uint32_t flags = 0, uint32_t finishContentMatchFlags = 0 ) : + ZoneChannelPacket< FFXIVIpcFinishContentMatchToClient >( playerId, playerId ) + { + initialize( terriId, classJob, playerNum, progress, flags, finishContentMatchFlags ); + }; + + private: + void initialize( uint16_t terriId, uint8_t classJob, uint8_t playerNum, uint8_t progress, uint32_t flags, uint32_t finishContentMatchFlags ) + { + m_data.territoryType = terriId; + m_data.classJob = classJob; + m_data.playerNum = playerNum; + m_data.progress = progress; + m_data.flags = flags; + m_data.finishContentMatchFlags = finishContentMatchFlags; + m_data.startTime = Common::Util::getTimeSeconds(); + }; + }; + + template< typename... Args > + std::shared_ptr< FinishContentMatchToClientPacket > makeFinishContentMatchToClient( Args... args ) + { + return std::make_shared< FinishContentMatchToClientPacket >( args... ); + } +}