From 29428599e10ffd194558b75fd29e17ed3ce10ef4 Mon Sep 17 00:00:00 2001 From: Maru Date: Sun, 18 Mar 2018 01:25:38 -0300 Subject: [PATCH] Further list handling; --- .../Network/Handlers/PacketHandlers.cpp | 20 ++----- .../sapphire_zone/Social/FriendList.cpp | 56 +++++++++++++------ src/servers/sapphire_zone/Social/FriendList.h | 25 ++++++++- src/servers/sapphire_zone/Social/Group.cpp | 28 ++++------ src/servers/sapphire_zone/Social/Group.h | 4 +- .../sapphire_zone/Social/Manager/SocialMgr.h | 42 ++++++++------ 6 files changed, 104 insertions(+), 71 deletions(-) diff --git a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp index 218b0af2..dc801eee 100644 --- a/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/PacketHandlers.cpp @@ -497,19 +497,7 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket g_fw.get< Logger >()->debug( "aaa" + std::to_string( i ) ); // todo: replace this with call for generating the entire vector - listPacket.data().entries[i] = Core::Social::FriendList::generatePlayerEntry( member, false ); - i++; - } - - for ( auto invite : playerFriendsList->getInvites() ) - { - // more elegant way to break over list entries pls - if ( i == 10 ) - break; - - g_fw.get< Logger >()->debug( "aaa" + std::to_string( i ) ); - // todo: replace this with call for generating the entire vector - listPacket.data().entries[i] = Core::Social::FriendList::generatePlayerEntry( invite, true ); + listPacket.data().entries[i] = Core::Social::FriendList::generatePlayerEntry( member ); i++; } @@ -660,7 +648,7 @@ void Core::Network::GameConnection::socialReqSendHandler( const Packets::GamePac auto recipientFriendsList = g_fw.get< Social::SocialMgr< Social::FriendList > >()->findGroupById( pRecipient->getFriendsListId() ); // If any of these are true, an error has occured. - if( senderFriendsList->hasInvite( recipientId ) || senderFriendsList->hasMember( recipientId ) ) + if( senderFriendsList->hasMember( recipientId ) ) { logMessage = 312; // That player is already a friend or has been sent a request. } @@ -679,7 +667,7 @@ void Core::Network::GameConnection::socialReqSendHandler( const Packets::GamePac else { // Catch any other, unreported mess - logMessage = senderFriendsList->addInvite( recipientId ); + //logMessage = senderFriendsList->addInvite( recipientId ); } } @@ -722,7 +710,7 @@ void Core::Network::GameConnection::socialReqSendHandler( const Packets::GamePac auto recipientFriendsList = g_fw.get< Social::SocialMgr< Social::FriendList > >()->findGroupById( pRecipient->getFriendsListId() ); - recipientFriendsList->addInvite( player.getId() ); + //recipientFriendsList->addInvite( player.getId() ); auto senderResultPacket = GamePacketNew< Server::FFXIVIpcSocialRequestResponse, ServerZoneIpcType >( pRecipient->getId(), player.getId() ); senderResultPacket.data().contentId = pRecipient->getId(); diff --git a/src/servers/sapphire_zone/Social/FriendList.cpp b/src/servers/sapphire_zone/Social/FriendList.cpp index 5afcad8d..ad896639 100644 --- a/src/servers/sapphire_zone/Social/FriendList.cpp +++ b/src/servers/sapphire_zone/Social/FriendList.cpp @@ -1,4 +1,6 @@ #include +#include + #include #include @@ -24,6 +26,31 @@ using namespace Core::Network::Packets::Server; using namespace Core::Social; + +uint32_t FriendList::addMember( uint64_t contentId, FriendEntryType friendEntryType ) +{ + assert( contentId != 0 ); + + uint32_t logMessage = 0; + + m_members.insert( contentId ); + + FriendEntry friendEntry; + friendEntry.timestamp = std::time( nullptr ); + friendEntry.friendGroup = 0; + friendEntry.entryStatus = friendEntryType; + friendEntry.unknown = 0; + + m_entries.insert( friendEntry ); + + return logMessage; +} + +std::set< FriendEntry >& FriendList::getEntries() +{ + return m_entries; +} + /* uint32_t Group::addInvite( uint64_t characterId ) { @@ -53,26 +80,17 @@ uint32_t Group::addInvite( uint64_t characterId ) return logMessage; } */ -std::vector< PlayerEntry > Core::Social::FriendList::getFriendListEntries( uint16_t entryAmount ) +std::vector< PlayerEntry > FriendList::getFriendListEntries( uint16_t entryAmount ) { std::vector< PlayerEntry > entryList = {}; uint16_t limit = 0; - for ( const auto& member : m_groupMembers ) + for ( const auto& member : m_members ) { if ( limit == entryAmount ) break; - entryList.push_back( generatePlayerEntry( member, false ) ); - limit++; - } - - for ( const auto& invite : m_groupInvites ) - { - if ( limit == entryAmount ) - break; - - entryList.push_back( generatePlayerEntry( invite, true ) ); + entryList.push_back( generatePlayerEntry( member ) ); limit++; } @@ -81,17 +99,20 @@ std::vector< PlayerEntry > Core::Social::FriendList::getFriendListEntries( uint1 //todo: generalize this for linkshell etc -Core::Network::Packets::Server::PlayerEntry FriendList::generatePlayerEntry( uint64_t characterId, bool isInvite ) +Core::Network::Packets::Server::PlayerEntry FriendList::generatePlayerEntry( uint64_t contentId ) { // We check if player is online. If so, we can pull data from existing session in memory // Otherwise, we pull from SQL. We can optimize this later, there are quite a few choices here - auto pSession = g_fw.get< ServerZone >()->getSession( characterId ); + auto pSession = g_fw.get< ServerZone >()->getSession( contentId ); + + auto dataIndex = m_members.find( contentId ); + auto friendEntry = m_entries; // todo: set as offline in one of the unknown values, if session does not exist Core::Network::Packets::Server::PlayerEntry entry = {}; - entry.contentId = characterId; + entry.contentId = contentId; entry.timestamp = 1517767262; // todo: if invite change these @@ -131,7 +152,8 @@ Core::Network::Packets::Server::PlayerEntry FriendList::generatePlayerEntry( uin auto stmt = pDb->getPreparedStatement( Db::CharaDbStatements::CHARA_SEL ); - stmt->setUInt( 1, characterId ); + //todo: this WILL break + stmt->setUInt( 1, contentId ); auto res = pDb->query( stmt ); // todo: Is this correct? Seems so judging from retail @@ -161,7 +183,7 @@ Core::Network::Packets::Server::PlayerEntry FriendList::generatePlayerEntry( uin // TODO: no idea what this does - me neither //listPacket.data().entries[0].one = 1; - g_fw.get< Logger >()->debug( std::to_string( characterId ) ); + g_fw.get< Logger >()->debug( std::to_string( contentId ) ); //g_fw.get< Logger >()->debug( std::to_string( entry.contentId ) ); diff --git a/src/servers/sapphire_zone/Social/FriendList.h b/src/servers/sapphire_zone/Social/FriendList.h index 6a1608b2..5eb9be07 100644 --- a/src/servers/sapphire_zone/Social/FriendList.h +++ b/src/servers/sapphire_zone/Social/FriendList.h @@ -15,6 +15,21 @@ namespace Core { namespace Social { +enum class FriendEntryType : uint8_t +{ + Added = 0x10, + SentRequest = 0x20, + ReceivedRequest = 0x30 +}; + +struct FriendEntry +{ + uint32_t timestamp; + FriendEntryType entryStatus; + uint8_t unknown; + uint8_t friendGroup; +}; + class FriendList : public Group { @@ -25,15 +40,21 @@ public: std::vector< Network::Packets::Server::PlayerEntry > getFriendListEntries( uint16_t entryAmount ); - static Core::Network::Packets::Server::PlayerEntry generatePlayerEntry( uint64_t characterId, bool isInvite ); + Core::Network::Packets::Server::PlayerEntry generatePlayerEntry( uint64_t contentId ); + + uint32_t addMember( uint64_t contentId, FriendEntryType friendEntryType ); + + /*! access entry vector */ + std::set< FriendEntry >& getEntries(); protected: uint64_t m_id{ 0 }; uint64_t m_ownerId{ 0 }; GroupType m_type{ GroupType::FriendList }; uint32_t m_maxCapacity{ 200 }; - + // todo: (urgent) think of a way to only use a single std set, use index based for correlating with data + std::set< FriendEntry > m_entries; }; diff --git a/src/servers/sapphire_zone/Social/Group.cpp b/src/servers/sapphire_zone/Social/Group.cpp index fc35192d..90713df3 100644 --- a/src/servers/sapphire_zone/Social/Group.cpp +++ b/src/servers/sapphire_zone/Social/Group.cpp @@ -22,20 +22,20 @@ using namespace Core::Network; // todo: invite map in g_serverZone.getGroupMgr(GroupType) and look up -uint32_t Group::addMember( uint64_t characterId ) +uint32_t Group::addMember( uint64_t contentId ) { - assert( characterId != 0 ); + assert( contentId != 0 ); uint32_t logMessage = 0; - m_members.insert( characterId ); + m_members.insert( contentId ); return logMessage; } -bool Group::hasMember( uint64_t memberId ) const +bool Group::hasMember( uint64_t contentId ) const { - return m_members.find( memberId ) != m_members.end(); + return m_members.find( contentId ) != m_members.end(); } Core::Network::Packets::GamePacketPtr Group::processInvite( uint64_t recipientId, uint64_t senderId ) @@ -97,7 +97,7 @@ Core::Network::Packets::GamePacketPtr Group::addMember2( Core::Entity::PlayerPtr auto packet = GamePacketNew< Server::FFXIVIpcSocialRequestResponse, ServerZoneIpcType >( recipientId, senderId ); packet.data().contentId = recipientContentId; packet.data().category = Common::SocialCategory::Friends; - + /* if( m_members.size() < m_maxCapacity ) { // todo: broadcast join message @@ -113,7 +113,7 @@ Core::Network::Packets::GamePacketPtr Group::addMember2( Core::Entity::PlayerPtr else { } - + */ return packet; } @@ -125,7 +125,7 @@ Packets::GamePacketPtr Group::inviteMember2( Core::Entity::PlayerPtr pSender, Co auto packet = Packets::GamePacketNew< Packets::Server::FFXIVIpcSocialRequestResponse, Packets::ServerZoneIpcType >( recipientId, senderId ); packet.data().contentId = recipientId; packet.data().category = Common::SocialCategory::Friends; - +/* if( m_invites.size() < m_maxCapacity ) { GroupMember member; @@ -136,7 +136,7 @@ Packets::GamePacketPtr Group::inviteMember2( Core::Entity::PlayerPtr pSender, Co m_invites.emplace( recipientId, member ); } - + */ return packet; } @@ -157,7 +157,7 @@ void Group::sendPacketToMembers( Core::Network::Packets::GamePacketPtr pPacket, assert( pPacket ); for( const auto& member : m_members ) { - auto pSession = g_fw.get< ServerZone >()->getSession( member.second.characterId ); + auto pSession = g_fw.get< ServerZone >()->getSession( member ); if( pSession ) { pSession->getPlayer()->queuePacket( pPacket ); @@ -169,13 +169,9 @@ void Group::sendPacketToMembers( Core::Network::Packets::GamePacketPtr pPacket, std::set< uint64_t >& Group::getMembers() { - return m_groupMembers; + return m_members; } -std::set< uint64_t >& Group::getInvites() -{ - return m_groupInvites; -} uint32_t Group::getCapacity() const { @@ -184,7 +180,7 @@ uint32_t Group::getCapacity() const uint32_t Group::getTotalSize() const { - return m_groupMembers.size() + m_groupInvites.size(); + return m_members.size(); } bool Group::isParty() const diff --git a/src/servers/sapphire_zone/Social/Group.h b/src/servers/sapphire_zone/Social/Group.h index 256d230a..7ebe7802 100644 --- a/src/servers/sapphire_zone/Social/Group.h +++ b/src/servers/sapphire_zone/Social/Group.h @@ -50,7 +50,7 @@ public: // New group system: return error code for logmessage - virtual uint32_t addMember( uint64_t characterId ); + virtual uint32_t addMember( uint64_t contentId ); //virtual uint32_t addInvite( uint64_t characterId ); virtual Core::Network::Packets::GamePacketPtr processInvite( uint64_t recipientId, uint64_t senderId ); @@ -74,7 +74,7 @@ public: uint32_t Group::getTotalSize() const; /*! check if group has member */ - bool hasMember( uint64_t memberId ) const; + bool hasMember( uint64_t contentId ) const; protected: diff --git a/src/servers/sapphire_zone/Social/Manager/SocialMgr.h b/src/servers/sapphire_zone/Social/Manager/SocialMgr.h index 392ad1b5..5e16d663 100644 --- a/src/servers/sapphire_zone/Social/Manager/SocialMgr.h +++ b/src/servers/sapphire_zone/Social/Manager/SocialMgr.h @@ -124,30 +124,36 @@ uint64_t Core::Social::SocialMgr< Core::Social::FriendList >::loadFriendsList( u uint64_t ownerId = res->getUInt64( 1 ); auto groupID = generateGroupId(); - auto friendsList = Core::Social::FriendList( groupID, ownerId ); + auto friendsList = Social::FriendList( groupID, ownerId ); - auto func = []( std::set< uint64_t >& outList, std::vector< char >& inData ) - { - if ( inData.size() ) - { - std::vector< uint64_t > list( inData.size() / 8 ); - // todo: fix this garbage. maybe get rid of lambda altogether - if( list.at( 0 ) != 0 ) - { - outList.insert( list.begin(), list.end() ); - } - } - }; + // Insert friend content IDs from binary data std::vector< char > friends; friends = res->getBlobVector( 2 ); - func( friendsList.getMembers(), friends ); - std::vector< char > friendInvites; - friendInvites = res->getBlobVector( 3 ); - func( friendsList.getInvites(), friendInvites ); + if( friends.size() ) + { + std::vector< uint64_t > list( friends.size() / 8 ); + // todo: fix this garbage check + if( list.at( 0 ) != 0 ) + { + friendsList.getMembers().insert( list.begin(), list.end() ); + } + } - auto friendListPtr = boost::make_shared< Core::Social::FriendList >( friendsList ); + // Insert invite data from binary data + + std::vector< char > inviteData; + inviteData = res->getBlobVector( 3 ); + + if( inviteData.size() ) + { + std::vector< Social::FriendEntry > list( friends.size() / 8 ); + + friendsList.getEntries().insert( list.begin(), list.end() ); + } + + auto friendListPtr = boost::make_shared< Social::FriendList >( friendsList ); m_groups[groupID] = friendListPtr;