From 1eaa3be773af0f8bf81d01c1dc8102100970d6eb Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 22 Aug 2017 23:53:20 +0200 Subject: [PATCH] Added new debug command to inject into chat connection\n Added base code for tell conversations, error messages not working yet --- .../Server_Common/Network/GamePacket.cpp | 1 + .../Network/PacketDef/Chat/ServerChatDef.h | 10 ++++- .../Server_Common/Network/PacketDef/Ipcs.h | 1 + src/servers/Server_Zone/Actor/Player.cpp | 13 ++++++ src/servers/Server_Zone/Actor/Player.h | 2 + .../DebugCommand/DebugCommandHandler.cpp | 8 ++++ .../DebugCommand/DebugCommandHandler.h | 1 + .../Network/Handlers/PacketHandlers.cpp | 43 +++++++++++++++++++ 8 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/servers/Server_Common/Network/GamePacket.cpp b/src/servers/Server_Common/Network/GamePacket.cpp index 9618eaa8..5ddebcf4 100644 --- a/src/servers/Server_Common/Network/GamePacket.cpp +++ b/src/servers/Server_Common/Network/GamePacket.cpp @@ -46,6 +46,7 @@ Core::Network::Packets::GamePacket::GamePacket( char * pData, uint16_t size, boo if( bWriteStamp && size > 0x18 ) { m_timeStamp = static_cast< uint32_t >( time( nullptr ) ); + *reinterpret_cast< uint16_t* >( &m_dataBuf[0] + 0x10 ) = 0x14; *reinterpret_cast< uint32_t* >( &m_dataBuf[0] + 0x18 ) = m_timeStamp; } diff --git a/src/servers/Server_Common/Network/PacketDef/Chat/ServerChatDef.h b/src/servers/Server_Common/Network/PacketDef/Chat/ServerChatDef.h index 78e6683e..7eed0dd7 100644 --- a/src/servers/Server_Common/Network/PacketDef/Chat/ServerChatDef.h +++ b/src/servers/Server_Common/Network/PacketDef/Chat/ServerChatDef.h @@ -11,7 +11,7 @@ namespace Server { /** * Structural representation of the packet sent by the server as response -* to a ping packet +* to a tell request */ struct FFXIVIpcTell : FFXIVIpcBasePacket { @@ -23,6 +23,14 @@ struct FFXIVIpcTell : FFXIVIpcBasePacket char msg[1031]; }; + /** +* Structural representation of the packet sent by the server as response +* to a failed tell because of unavailable target player +*/ +struct FFXIVIpcTellErrNotFound : FFXIVIpcBasePacket +{ + char receipientName[32]; +}; } /* Server */ } /* Packets */ diff --git a/src/servers/Server_Common/Network/PacketDef/Ipcs.h b/src/servers/Server_Common/Network/PacketDef/Ipcs.h index b6ccaa84..f0cf819c 100644 --- a/src/servers/Server_Common/Network/PacketDef/Ipcs.h +++ b/src/servers/Server_Common/Network/PacketDef/Ipcs.h @@ -186,6 +186,7 @@ namespace Packets { enum ServerChatIpcType : uint16_t { Tell = 0x0064, // updated for sb + TellErrNotFound = 0x0066, }; /** diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 8b3803a9..6a7af224 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -1255,6 +1255,19 @@ void Core::Entity::Player::queuePacket( Core::Network::Packets::GamePacketPtr pP } } +void Core::Entity::Player::queueChatPacket( Core::Network::Packets::GamePacketPtr pPacket ) +{ + auto pSession = g_serverZone.getSession( m_id ); + + if( pSession ) + { + auto pChatCon = pSession->getChatConnection(); + + if( pChatCon ) + pChatCon->queueOutPacket( pPacket ); + } +} + bool Core::Entity::Player::isLoadingComplete() const { return m_bLoadingComplete; diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index 3bcb2c57..1d788213 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -433,6 +433,8 @@ public: void sendQuestMessage( uint32_t questId, int8_t msgId, uint8_t type, uint32_t var1, uint32_t var2 ); /*! queue a packet for the player */ void queuePacket( Network::Packets::GamePacketPtr pPacket ); + /*! queue a char connection packet for the player */ + void queueChatPacket( Network::Packets::GamePacketPtr pPacket ); /*! returns true if loading is complete ( 0x69 has been received ) */ bool isLoadingComplete() const; /*! set the loading complete bool */ diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp index e2bfcaa8..88136b4f 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp @@ -46,6 +46,7 @@ Core::DebugCommandHandler::DebugCommandHandler() registerCommand( "add", &DebugCommandHandler::add, "Loads and injects a premade Packet.", Common::UserLevel::all ); //registerCommand( "debug", &DebugCommandHandler::debug, "Loads and injects a premade Packet.", Common::UserLevel::all ); registerCommand( "inject", &DebugCommandHandler::injectPacket, "Loads and injects a premade Packet.", Common::UserLevel::all ); + registerCommand( "injectc", &DebugCommandHandler::injectChatPacket, "Loads and injects a premade Packet.", Common::UserLevel::all ); registerCommand( "script_reload", &DebugCommandHandler::scriptReload, "Loads and injects a premade Packet.", Common::UserLevel::all ); registerCommand( "nudge", &DebugCommandHandler::nudge, "Nudges you forward/up/down", Common::UserLevel::all ); @@ -473,6 +474,13 @@ void Core::DebugCommandHandler::injectPacket( char * data, Core::Entity::PlayerP pSession->getZoneConnection()->injectPacket( data + 7, pPlayer ); } +void Core::DebugCommandHandler::injectChatPacket( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr< Core::DebugCommand > command ) +{ + auto pSession = g_serverZone.getSession( pPlayer->getId() ); + if( pSession ) + pSession->getChatConnection()->injectPacket( data + 8, pPlayer ); +} + void Core::DebugCommandHandler::nudge( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr command ) { std::string subCommand; diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.h b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.h index 4ea8647a..69ef7c4a 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.h +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.h @@ -35,6 +35,7 @@ public: void scriptReload( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr command ); void injectPacket( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr command ); + void injectChatPacket( char * data, Entity::PlayerPtr pPlayer, boost::shared_ptr command ); void nudge( char* data, Entity::PlayerPtr pPlayer, boost::shared_ptr command ); }; diff --git a/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp index 8f1e9995..336dded2 100644 --- a/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -547,6 +548,48 @@ void Core::Network::GameConnection::logoutHandler( const Packets::GamePacket& in void Core::Network::GameConnection::tellHandler( const Packets::GamePacket& inPacket, Entity::PlayerPtr pPlayer ) { + std::string targetPcName = inPacket.getStringAt( 0x21 ); + std::string msg = inPacket.getStringAt( 0x41 ); + auto pSession = g_serverZone.getSession( targetPcName ); + + if( !pSession ) + { + GamePacketNew< FFXIVIpcTellErrNotFound, ServerChatIpcType > tellErrPacket( pPlayer->getId() ); + strcpy( tellErrPacket.data().receipientName, targetPcName.c_str() ); + pPlayer->queueChatPacket( tellErrPacket ); + g_log.debug( "TargetPc not found" ); + return; + } + + auto pTargetPlayer = pSession->getPlayer(); + + if( pTargetPlayer->hasStateFlag( PlayerStateFlag::BetweenAreas ) || + pTargetPlayer->hasStateFlag( PlayerStateFlag::BetweenAreas1 ) ) + { + // send error for player between areas + return; + } + + if( pTargetPlayer->hasStateFlag( PlayerStateFlag::BoundByDuty ) || + pTargetPlayer->hasStateFlag( PlayerStateFlag::BoundByDuty1 ) ) + { + // send error for player bound by duty + return; + } + + if( pTargetPlayer->getOnlineStatus() == OnlineStatus::Busy ) + { + // send error for player being busy + return; + } + + GamePacketNew< FFXIVIpcTell, ServerChatIpcType > tellPacket( pPlayer->getId() ); + strcpy( tellPacket.data().msg, msg.c_str() ); + strcpy( tellPacket.data().receipientName, targetPcName.c_str() ); + //tellPacket.data().u1 = 0x92CD7337; + //tellPacket.data().u2a = 0x2E; + //tellPacket.data().u2b = 0x40; + pTargetPlayer->queueChatPacket( tellPacket ); } \ No newline at end of file