1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-25 11:07:45 +00:00

Insane copypaste work!11!one

This commit is contained in:
Maru 2017-12-05 04:13:13 -02:00
parent 7504ab5ebf
commit 1332d580df
6 changed files with 277 additions and 26 deletions

View file

@ -58,7 +58,8 @@ namespace Packets {
SocialRequestError = 0x00AD, SocialRequestError = 0x00AD,
Playtime = 0x00B7, // updated 4.1 Playtime = 0x00B7, // updated 4.1
CFRegistered = 0x00B8, // updated 4.1 CFRegistered = 0x00B8, // updated 4.1
SocialRequestResponse = 0x00BB, // updated 4.1 SocialRequestResponse = 0x00BC, // updated 4.1
SocialRequestReceive = 0x00BD,
SocialList = 0x00BE, // updated 4.1 SocialList = 0x00BE, // updated 4.1
UpdateSearchInfo = 0x10BB, UpdateSearchInfo = 0x10BB,
InitSearchInfo = 0x00C1, // updated 4.1 InitSearchInfo = 0x00C1, // updated 4.1

View file

@ -89,7 +89,7 @@ struct PlayerEntry {
uint8_t searchComment; // bool uint8_t searchComment; // bool
char bytes1[6]; char bytes1[6];
uint64_t onlineStatusMask; uint64_t onlineStatusMask;
uint8_t classJob; Common::ClassJob classJob;
uint8_t padding; uint8_t padding;
uint16_t level; uint16_t level;
uint16_t padding2; uint16_t padding2;
@ -98,8 +98,31 @@ struct PlayerEntry {
char fcTag[9]; char fcTag[9];
}; };
struct FFXIVIpcSocialRequestReceive : FFXIVIpcBasePacket<SocialRequestReceive>
{
uint32_t actorId; // actor id of player which initiated request
uint16_t unknown;
uint16_t unknown2;
uint32_t timestamp; // must be greater than current time
uint8_t unknown3;
uint8_t unknown4; // Very likely cross-world related
Common::SocialCategory category; // 1 - party invite, 2 - friends request, 3 - ??, 4 - fc signature request, 5 - fc invite,
uint8_t unknown5;
Common::SocialRequestAction action; // 0 - ??, 1 - received, 2 - canceled, 4 - friend accept/fc sign/fc join, 5 - refuse fc petition/decline invite
uint8_t unknown6;
char name[0x20];
uint16_t unknown7;
uint16_t unknown8;
uint16_t unknown9;
};
struct FFXIVIpcSocialRequestError : FFXIVIpcBasePacket<SocialRequestError> struct FFXIVIpcSocialRequestError : FFXIVIpcBasePacket<SocialRequestError>
{ {
uint32_t messageId; // if 0 then type's message is used (type must 2/4/5 or it wont print)
Common::SocialCategory category; // 2 - friend request, 4 - fc petition, 5 - fc invitation, anything else and wont print
uint8_t unknown; // possibly padding
char name[0x20];
uint8_t unknown3[2]; // probably padding
}; };
@ -107,8 +130,8 @@ struct FFXIVIpcSocialRequestResponse : FFXIVIpcBasePacket<SocialRequestResponse>
{ {
uint64_t contentId; uint64_t contentId;
uint32_t unknown; uint32_t unknown;
uint8_t category; // Common::SocialCategory Common::SocialCategory category; // Common::SocialCategory
uint8_t response; // Common::SocialRequestResponse Common::SocialRequestResponse response; // Common::SocialRequestResponse
char name[0x20]; char name[0x20];
uint16_t padding; uint16_t padding;
}; };

View file

@ -900,6 +900,33 @@ Core::Entity::ActorPtr Core::Entity::Player::lookupTargetById( uint64_t targetId
return targetActor; return targetActor;
} }
Core::Network::Packets::Server::PlayerEntry Core::Entity::Player::generatePlayerEntry()
{
Core::Network::Packets::Server::PlayerEntry entry = {};
entry.bytes[2] = getCurrentZone()->getId();
entry.bytes[3] = 0x80;
entry.bytes[4] = 0x02;
entry.bytes[6] = 0x3B;
entry.bytes[11] = 0x10;
entry.classJob = getClass();
entry.contentId = getContentId();
entry.level = getLevel();
entry.zoneId = getCurrentZone()->getId();
entry.grandCompany = getGc();
memcpy( &entry.fcTag[0], "Meme", 9 );
entry.clientLanguage = 2;
entry.knownLanguages = 0x0F;
// TODO: no idea what this does - me neither
//listPacket.data().entries[0].one = 1;
memcpy( entry.name, getName().c_str(), strlen( getName().c_str() ) );
entry.onlineStatusMask = getOnlineStatusMask();
return entry;
}
void Core::Entity::Player::setLastPing( uint32_t ping ) void Core::Entity::Player::setLastPing( uint32_t ping )
{ {
m_lastPing = ping; m_lastPing = ping;

View file

@ -4,6 +4,7 @@
#include "src/servers/Server_Zone/Forwards.h" #include "src/servers/Server_Zone/Forwards.h"
#include <src/servers/Server_Common/Common.h> #include <src/servers/Server_Common/Common.h>
#include <src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h>
#include "Actor.h" #include "Actor.h"
#include "src/servers/Server_Zone/Inventory/Inventory.h" #include "src/servers/Server_Zone/Inventory/Inventory.h"
@ -480,6 +481,9 @@ public:
void sendUrgent( const std::string& message ); void sendUrgent( const std::string& message );
void sendDebug( const std::string& message ); void sendDebug( const std::string& message );
/*! generates a player entry used for lists (social, etc) */
Core::Network::Packets::Server::PlayerEntry generatePlayerEntry();
// Player Battle Handling // Player Battle Handling
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
void onMobAggro( BattleNpcPtr pBNpc ); void onMobAggro( BattleNpcPtr pBNpc );

View file

@ -89,6 +89,7 @@ public:
DECLARE_HANDLER( initHandler ); DECLARE_HANDLER( initHandler );
DECLARE_HANDLER( finishLoadingHandler ); DECLARE_HANDLER( finishLoadingHandler );
DECLARE_HANDLER( blackListHandler ); DECLARE_HANDLER( blackListHandler );
DECLARE_HANDLER( socialReqResponseHandler );
DECLARE_HANDLER( socialReqSendHandler ); DECLARE_HANDLER( socialReqSendHandler );
DECLARE_HANDLER( socialListHandler ); DECLARE_HANDLER( socialListHandler );
DECLARE_HANDLER( linkshellListHandler ); DECLARE_HANDLER( linkshellListHandler );

View file

@ -444,25 +444,7 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
int32_t entrysizes = sizeof( listPacket.data().entries ); int32_t entrysizes = sizeof( listPacket.data().entries );
memset( listPacket.data().entries, 0, sizeof( listPacket.data().entries ) ); memset( listPacket.data().entries, 0, sizeof( listPacket.data().entries ) );
listPacket.data().entries[0].bytes[2] = pPlayer->getCurrentZone()->getId(); listPacket.data().entries[0] = pPlayer->generatePlayerEntry();
listPacket.data().entries[0].bytes[3] = 0x80;
listPacket.data().entries[0].bytes[4] = 0x02;
listPacket.data().entries[0].bytes[6] = 0x3B;
listPacket.data().entries[0].bytes[11] = 0x10;
listPacket.data().entries[0].classJob = static_cast< uint8_t >( pPlayer->getClass() );
listPacket.data().entries[0].contentId = pPlayer->getContentId();
listPacket.data().entries[0].level = pPlayer->getLevel();
listPacket.data().entries[0].zoneId = pPlayer->getCurrentZone()->getId();
listPacket.data().entries[0].grandCompany = pPlayer->getGc();
memcpy( &listPacket.data().entries[0].fcTag[0], "Sapphire", sizeof( "Sapphire" ) );
listPacket.data().entries[0].clientLanguage = 2;
listPacket.data().entries[0].knownLanguages = 0x0F;
// TODO: no idea what this does
//listPacket.data().entries[0].one = 1;
memcpy( listPacket.data().entries[0].name, pPlayer->getName().c_str(), strlen( pPlayer->getName().c_str() ) );
listPacket.data().entries[0].onlineStatusMask = pPlayer->getOnlineStatusMask();
queueOutPacket( listPacket ); queueOutPacket( listPacket );
@ -475,6 +457,29 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
listPacket.data().sequence = count; listPacket.data().sequence = count;
memset( listPacket.data().entries, 0, sizeof( listPacket.data().entries ) ); memset( listPacket.data().entries, 0, sizeof( listPacket.data().entries ) );
// todo: for now.. just grab all actors in range and add them in. just replace logic later by using manager
uint8_t i = 0;
for( auto actor : pPlayer->getInRangeActors() )
{
auto pFriend = actor->getAsPlayer();
if( pFriend )
{
listPacket.data().entries[i] = pFriend->generatePlayerEntry();
i++;
}
// todo: remove this branch entirely when using manager. physically hurts
if( i >= 200 )
{
break;
}
}
queueOutPacket( listPacket );
} }
else if( type == 0x0e ) else if( type == 0x0e )
{ // player search result { // player search result
@ -483,10 +488,200 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
} }
void Core::Network::GameConnection::socialReqSendHandler(const Packets::GamePacket& inPacket, void Core::Network::GameConnection::socialReqResponseHandler( const Packets::GamePacket& inPacket,
Entity::PlayerPtr pPlayer) Entity::PlayerPtr pPlayer )
{ {
g_log.debug("send"); auto targetId = inPacket.getValAt< uint32_t >( 0x20 );
auto category = inPacket.getValAt< Common::SocialCategory >( 0x28 );
auto action = inPacket.getValAt< Common::SocialRequestAction >( 0x29 );
ZoneChannelPacket< FFXIVIpcSocialRequestError > info( targetId, pPlayer->getId() );
ZoneChannelPacket< FFXIVIpcSocialRequestResponse > response( targetId, pPlayer->getId() );
info.data().category = category;
response.data().category = category;
//auto pQR = g_database.query( "SELECT Name FROM dbchara WHERE CharacterId = " + to_string( targetId ) );
auto name = pPlayer->getName();
/*
if( pQR->getRowCount() > 0 )
{
name = pQR->fetch()->getString();
}
else
{
// todo: enumerate these messages
std::array< uint32_t, 5> categoryError = { 0,
320, // Unable to process party command.
310, // Unable to process friend list command.
3035, // Unable to reply. Free company invite invalid. // todo: find actual message
3035, // Unable to reply. Free company invite invalid.
};
response.data().messageId = categoryError[category];
response.data().category = category; // client only uses messageId if this is 1 for some reason
pPlayer->queuePacket( response );
return;
}*/
g_log.debug( std::to_string( static_cast<uint8_t>( action ) ) );
auto pSession = g_serverZone.getSession( targetId );
// todo: notify both inviter/invitee with 0x00CB packet
if( pSession )
{
g_log.debug( std::to_string(static_cast<uint8_t>(action)) );
}
response.data().response = Common::SocialRequestResponse::Accept;
memcpy( &( response.data().name ), name.c_str(), 32 );
pPlayer->queuePacket( response );
}
void Core::Network::GameConnection::socialReqSendHandler( const Packets::GamePacket& inPacket,
Entity::PlayerPtr pPlayer )
{
// todo: handle all social request packets here
auto category = inPacket.getValAt< Common::SocialCategory >( 0x20 );
auto name = std::string( inPacket.getStringAt( 0x21 ) );
auto pSession = g_serverZone.getSession( name );
// only the requester needs the response
ZoneChannelPacket< FFXIVIpcSocialRequestError > response( pPlayer->getId() );
memcpy( &( response.data().name ), name.c_str(), 32 );
// todo: enumerate log messages
response.data().messageId = 319; // That name does not exist. Please confirm the spelling.
response.data().category = category;
// todo: enumerate and move each of these cases into their classes?
if( pSession )
{
bool successful = false;
Entity::PlayerPtr pRecipient = pSession->getPlayer();
std::array<std::string, 5> typeVar{ "", "PartyInvite", "FriendInvite", "FreeCompanyPetition", "FreeCompanyInvite" };
// todo: proper handling of invites already sent
// todo: move this to world server
// check if an invite has already been sent by me
/*
if( pRecipient->getTempVariable( typeVar[category] + "Id" ) )
{
if( pRecipient->getTempVariable( typeVar[category] + "Id" ) == pPlayer->getId() )
{
response.data().messageId = 328; // That player has already been invited.
pPlayer->queuePacket( response );
}
return;
}*/
if( pRecipient->getId() == pPlayer->getId() )
{
response.data().messageId = 321; // Unable to invite.
}
switch( category )
{
// party invite
case Core::Common::SocialCategory::Party:
{
/*
if( pRecipient->getParty() )
{
response.data().messageId = 326; // That player is already in another party.
}
else if( pRecipient->getTempVariable( "PartyInviteId" ) == pPlayer->getId() )
{
response.data().messageId = 328; // That player has already been invited.
}
else if( pPlayer->getParty() && pPlayer->getParty()->getPartyMemberCount() >= pPlayer->getParty()->getType() )
{
response.data().messageId = 329; // Unable to invite. The party is full.
}*/
if( !pRecipient->isLoadingComplete() ) // || pRecipient->getDuty() )
{
response.data().messageId = 331; // Unable to invite. That player is currently bound by duty or in a different area.
}
else if( pRecipient->getOnlineStatus() == Common::OnlineStatus::Busy )
{
response.data().messageId = 334; // Unable to send party invite. Player's online status is set to Busy.
}
else if( pRecipient->getOnlineStatus() == Common::OnlineStatus::ViewingCutscene )
{
response.data().messageId = 336; // Unable to invite. That player is currently watching a cutscene.
}
else
{
successful = true;
}
// response.data().messageId = 62; // <name> declines the party invite.
}
break;
case Common::SocialCategory::Friends:
{
// todo: check if already on friends list or invite pending
/*
if( pPlayer->getFriendList()->find(name) )
{
response.data().messageId = 312; // That player is already a friend or has been sent a request.
}
else if( pRecipient->getFriendList()->getSize() >= 200 )
{
response.data().messageId = 314; // Unable to send friend request. The other player's friend list is full.
}
else if( pPlayer->getFriendList()->getSize() >= 200 )
{
response.data().messageId = 313; // Your friend list is full.
}
*/
successful = true;
}
break;
default:
break;
}
if( successful )
{
ZoneChannelPacket< FFXIVIpcSocialRequestReceive > packet( pPlayer->getId(), pRecipient->getId() );
std::array<uint16_t, 5> typeMessage{ 0,
1, // You invite <name> to a party.
10, // You send a friend request to <name>.
1884, // You invite <name> to your free company.
3044, // Free company petition signature request sent to <name>
};
// TODO: confirm the timers on retail
auto expireTime = time( nullptr ) + 120;
// todo: fix this for cross zone parties (move to world server)
/*
pRecipient->setTempVariable( typeVar[category] + "Id", pPlayer->getId() );
pRecipient->setTempVariable( typeVar[category] + "Timer", expireTime );*/
packet.data().actorId = pPlayer->getId();
packet.data().category = category;
packet.data().action = Core::Common::SocialRequestAction::Invite;
packet.data().unknown3 = 80;
packet.data().unknown = 46;
packet.data().unknown2 = 64;
memcpy( &( packet.data().name ), pPlayer->getName().c_str(), 32 );
pRecipient->queuePacket( packet );
pRecipient->sendDebug( "ding ding" );
response.data().messageId = typeMessage[category];
}
}
pPlayer->queuePacket( response );
// todo: handle party, friend request
g_log.debug("sent to " + name);
} }
void Core::Network::GameConnection::chatHandler( const Packets::GamePacket& inPacket, void Core::Network::GameConnection::chatHandler( const Packets::GamePacket& inPacket,