From 139f771e7ad675921e5c2f51fd349d25deb95874 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 7 Dec 2021 00:02:41 +0100 Subject: [PATCH] Linkshell join logic redone to use linkshell result packets. --- src/world/Manager/LinkshellMgr.cpp | 33 ++++++++---- src/world/Manager/LinkshellMgr.h | 2 +- .../Network/Handlers/LinkshellHandlers.cpp | 13 ++++- .../PacketWrappers/LinkshellResultPacket.h | 52 +++++++++++++++++++ 4 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 src/world/Network/PacketWrappers/LinkshellResultPacket.h diff --git a/src/world/Manager/LinkshellMgr.cpp b/src/world/Manager/LinkshellMgr.cpp index 9f888236..a3f21d45 100644 --- a/src/world/Manager/LinkshellMgr.cpp +++ b/src/world/Manager/LinkshellMgr.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "Session.h" @@ -218,11 +220,7 @@ void Sapphire::World::Manager::LinkshellMgr::finishLinkshellCreation( const std: { auto& server = Common::Service< World::WorldServer >::ref(); - auto linkshellResult = makeZonePacket< FFXIVIpcLinkshellResult >( player.getId() ); - linkshellResult->data().Result = result; - linkshellResult->data().UpPacketNo = 1; - linkshellResult->data().Identity = 0xFF; - strcpy( linkshellResult->data().LinkshellName, name.c_str() ); + auto linkshellResult = makeLinkshellResult( player, 0, 0, 1, 0, 0, name, "" ); server.queueForPlayer( player.getCharacterId(), linkshellResult ); } @@ -249,19 +247,32 @@ const std::vector< Sapphire::LinkshellPtr > Sapphire::World::Manager::LinkshellM return lsVec; } -void LinkshellMgr::invitePlayer( const std::string &name, uint64_t linkshellId ) +void LinkshellMgr::invitePlayer( Entity::Player& sourcePlayer, Entity::Player& invitedPlayer, uint64_t linkshellId ) { auto& server = Common::Service< World::WorldServer >::ref(); - auto invitedPlayer = server.getSession( name ); auto lsPtr = getLinkshellById( linkshellId ); - if( !invitedPlayer || !lsPtr ) - return Logger::warn( "Failed to invite player to linkshell - session/linkshell not found!" ); + if( !lsPtr ) + return Logger::warn( "Failed to invite player to linkshell - linkshell not found!" ); - lsPtr->addInvite( invitedPlayer->getPlayer()->getCharacterId() ); + lsPtr->addInvite( invitedPlayer.getCharacterId() ); writeLinkshell( lsPtr->getId() ); - sendLinkshellList( *invitedPlayer->getPlayer() ); + sendLinkshellList( invitedPlayer ); + + auto linkshellInviteResult = makeLinkshellResult( invitedPlayer, 0, 0, + WorldPackets::Client::LinkshellJoin, 0, + LinkshellResultPacket::UpdateStatus::Target, + lsPtr->getName(), sourcePlayer.getName() ); + + server.queueForPlayer( invitedPlayer.getCharacterId(), linkshellInviteResult ); + + auto linkshellInviteResult1 = makeLinkshellResult( sourcePlayer, 0, 0, + WorldPackets::Client::LinkshellJoin, 0, + LinkshellResultPacket::UpdateStatus::Execute, + lsPtr->getName(), invitedPlayer.getName() ); + + server.queueForPlayer( sourcePlayer.getCharacterId(), linkshellInviteResult1 ); } void LinkshellMgr::sendLinkshellList( Entity::Player& player ) diff --git a/src/world/Manager/LinkshellMgr.h b/src/world/Manager/LinkshellMgr.h index 2c8f37ba..0093075f 100644 --- a/src/world/Manager/LinkshellMgr.h +++ b/src/world/Manager/LinkshellMgr.h @@ -38,7 +38,7 @@ namespace Sapphire::World::Manager void finishLinkshellCreation( const std::string& name, uint32_t result, Entity::Player& player ); - void invitePlayer( const std::string& name, uint64_t linkshellId ); + void invitePlayer( Entity::Player& sourcePlayer, Entity::Player& invitedPlayer, uint64_t linkshellId ); void sendLinkshellList( Entity::Player& player ); diff --git a/src/world/Network/Handlers/LinkshellHandlers.cpp b/src/world/Network/Handlers/LinkshellHandlers.cpp index f22ef645..09df9847 100644 --- a/src/world/Network/Handlers/LinkshellHandlers.cpp +++ b/src/world/Network/Handlers/LinkshellHandlers.cpp @@ -12,6 +12,7 @@ #include "Session.h" #include "Actor/Player.h" #include "Manager/LinkshellMgr.h" +#include using namespace Sapphire::Common; using namespace Sapphire::Network::Packets; @@ -27,9 +28,19 @@ void Sapphire::Network::GameConnection::linkshellListHandler( const Packets::FFX void Sapphire::Network::GameConnection::linkshellJoinHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) { const auto lsJoinPacket = ZoneChannelPacket< Client::FFXIVIpcLinkshellJoin >( inPacket ); + auto& server = Common::Service< World::WorldServer >::ref(); auto& lsMgr = Common::Service< LinkshellMgr >::ref(); + auto charName = std::string( lsJoinPacket.data().MemberCharacterName ); - lsMgr.invitePlayer( charName, lsJoinPacket.data().LinkshellID ); + auto invitedPlayer = server.getSession( charName ); + + if( !invitedPlayer ) + { + Logger::error( std::string( __FUNCTION__ ) + " requested player \"{}\" not found!", charName ); + return; + } + + lsMgr.invitePlayer( player, *invitedPlayer->getPlayer(), lsJoinPacket.data().LinkshellID ); } diff --git a/src/world/Network/PacketWrappers/LinkshellResultPacket.h b/src/world/Network/PacketWrappers/LinkshellResultPacket.h new file mode 100644 index 00000000..d8e21781 --- /dev/null +++ b/src/world/Network/PacketWrappers/LinkshellResultPacket.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include "Forwards.h" +#include +#include +#include + +namespace Sapphire::Network::Packets::WorldPackets::Server +{ + + class LinkshellResultPacket : public ZoneChannelPacket< FFXIVIpcLinkshellResult > + { + public: + enum UpdateStatus : uint8_t + { + None = 0, + Execute = 10, + Target = 11, + Member = 12, + }; + + LinkshellResultPacket( Entity::Player& player, uint64_t linkshellId, uint64_t targetId, + uint16_t upPacketNo, uint32_t result, uint8_t updateStatus, const std::string& lsName, const std::string& targetName ) : + + ZoneChannelPacket< FFXIVIpcLinkshellResult >( player.getId(), player.getId() ) + { + initialize( player, linkshellId, targetId, upPacketNo, result, updateStatus, lsName, targetName ); + }; + + private: + void initialize( Entity::Player& player, uint64_t linkshellId, uint64_t targetId, + uint16_t upPacketNo, uint32_t result, uint8_t updateStatus, const std::string& lsName, const std::string& targetName ) + { + m_data.LinkshellID = linkshellId; + m_data.Identity = 0xFF; + m_data.UpPacketNo = static_cast< uint32_t >( upPacketNo ); + m_data.Result = result; + m_data.UpdateStatus = updateStatus; + m_data.TargetCharacterID = targetId; + strcpy( m_data.LinkshellName, lsName.c_str() ); + strcpy( m_data.TargetName, targetName.c_str() ); + }; + }; + template< typename... Args > + std::shared_ptr< LinkshellResultPacket > makeLinkshellResult( Args... args ) + { + return std::make_shared< LinkshellResultPacket >( args... ); + } +} +