From 9e152f253fcfed50bc83b487e34f4c141a5b9e4a Mon Sep 17 00:00:00 2001 From: Maru Date: Tue, 19 Dec 2017 03:42:04 -0200 Subject: [PATCH] Reworking some more on group generation and flow; --- .../Network/PacketDef/Zone/ServerZoneDef.h | 9 ++- src/servers/Server_Zone/Actor/Player.cpp | 6 +- src/servers/Server_Zone/Actor/Player.h | 4 +- .../Server_Zone/Actor/Social/FriendList.h | 17 ++---- .../Server_Zone/Actor/Social/Group.cpp | 61 ++++++++++++++++--- src/servers/Server_Zone/Actor/Social/Group.h | 17 +++--- .../Actor/Social/Manager/FriendListMgr.cpp | 23 +++---- .../Actor/Social/Manager/FriendListMgr.h | 17 +++--- .../Actor/Social/Manager/GroupMgr.cpp | 23 ++++++- .../Actor/Social/Manager/GroupMgr.h | 35 +++++++++-- .../Network/Handlers/PacketHandlers.cpp | 19 +++++- src/servers/Server_Zone/ServerZone.cpp | 3 + 12 files changed, 167 insertions(+), 67 deletions(-) diff --git a/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h b/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h index 0724bae5..5048a60c 100644 --- a/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/servers/Server_Common/Network/PacketDef/Zone/ServerZoneDef.h @@ -81,7 +81,12 @@ struct FFXIVIpcPlayTime : FFXIVIpcBasePacket */ struct PlayerEntry { uint64_t contentId; - uint8_t bytes[12]; + uint32_t timestamp; + uint8_t bytes[4]; + uint8_t status; // bitmask. friend: if it's a request, if added, recipient/sender + uint8_t unknown; // maybe bitmask? a value of 4 sets it to linkshell request + uint8_t entryIcon; // observed in friend group icon, sideffects for displaying text + uint8_t unavailable; // bool uint16_t zoneId; uint8_t grandCompany; uint8_t clientLanguage; @@ -95,7 +100,7 @@ struct PlayerEntry { uint16_t padding2; uint8_t one; char name[0x20]; - char fcTag[9]; + char fcTag[5]; }; struct FFXIVIpcSocialRequestReceive : FFXIVIpcBasePacket diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 2e2762d6..74df7bd1 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -303,9 +303,9 @@ void Core::Entity::Player::sendStats() queuePacket( statPacket ); } -Social::FriendListPtr Core::Entity::Player::getFriendsList() const +uint64_t Core::Entity::Player::getFriendsListId() const { - return m_friendsList; + return m_friendsListId; } void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type ) @@ -447,7 +447,7 @@ void Core::Entity::Player::setZone( uint32_t zoneId ) //todo: change this to extern, global obj Core::Entity::Social::FriendListMgr fListMgr = {}; - m_friendsList = fListMgr.getPlayerFriendsList( getId() ); + m_friendsListId = fListMgr.fetchPlayerFriendsList( getId() ); m_itemLevel = getInventory()->calculateEquippedGearItemLevel(); sendItemLevel(); diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index d7e6c0c7..1e0a26bb 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -363,7 +363,7 @@ public: // Social-based ////////////////////////////////////////////////////////////////////////////////////////////////////// - Social::FriendListPtr getFriendsList() const; + uint64_t getFriendsListId() const; // Aetheryte / Action / Attribute bitmasks @@ -627,7 +627,7 @@ private: // Social-based - Social::FriendListPtr m_friendsList; + uint64_t m_friendsListId; uint8_t m_equipDisplayFlags; diff --git a/src/servers/Server_Zone/Actor/Social/FriendList.h b/src/servers/Server_Zone/Actor/Social/FriendList.h index bc535758..07e7c099 100644 --- a/src/servers/Server_Zone/Actor/Social/FriendList.h +++ b/src/servers/Server_Zone/Actor/Social/FriendList.h @@ -26,11 +26,9 @@ class FriendList : public Group { public: - FriendList( uint64_t id, uint64_t ownerId, uint32_t maxCapacity, time_point createTime ) : - Group( id, ownerId, maxCapacity, createTime ), - m_id( id ), m_ownerId( ownerId ), m_maxCapacity( maxCapacity ), m_createTime( createTime ) {}; - - ~FriendList() {}; + FriendList( uint64_t id, uint64_t ownerId ) : + Group( id, ownerId ), + m_id( id ), m_ownerId( ownerId ) {}; /*virtual void load(); virtual void update(); @@ -48,16 +46,11 @@ public: -private: - GroupType m_type{ GroupType::FriendList }; +protected: uint64_t m_id{ 0 }; uint64_t m_ownerId{ 0 }; + GroupType m_type{ GroupType::FriendList }; uint32_t m_maxCapacity{ 200 }; - uint32_t m_maxRoles{ 8 }; - time_point m_createTime{ std::chrono::steady_clock::now() }; - std::map< uint64_t, GroupMember > m_members; - std::map< uint64_t, uint64_t > m_invites; // - diff --git a/src/servers/Server_Zone/Actor/Social/Group.cpp b/src/servers/Server_Zone/Actor/Social/Group.cpp index 0b8654d3..8ca4a402 100644 --- a/src/servers/Server_Zone/Actor/Social/Group.cpp +++ b/src/servers/Server_Zone/Actor/Social/Group.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -12,6 +13,7 @@ #include "Group.h" extern Core::ServerZone g_serverZone; +extern Core::Logger g_log; using namespace Core::Entity::Social; @@ -43,6 +45,7 @@ Core::Network::Packets::GamePacketPtr Group::addMember( 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 ) { @@ -63,6 +66,40 @@ Core::Network::Packets::GamePacketPtr Group::addMember( Core::Entity::PlayerPtr return packet; } +Core::Network::Packets::GamePacketPtr Group::inviteMember( Core::Entity::PlayerPtr pSender, Core::Entity::PlayerPtr pRecipient, uint64_t senderId, uint64_t recipientId ) +{ + assert( pSender != nullptr || senderId != 0 ); + + auto packet = GamePacketNew< Server::FFXIVIpcSocialRequestResponse, ServerZoneIpcType >( recipientId, senderId ); + packet.data().contentId = recipientId; + packet.data().category = Common::SocialCategory::Friends; + + if ( m_invites.size() < m_maxCapacity ) + { + GroupMember member; + member.inviterId = senderId; + member.role = 0; + member.contentId = recipientId; + member.name = pSender->getName(); + + m_invites.emplace( recipientId, member ); + } + + return packet; +} + +// todo: fix +Core::Network::Packets::GamePacketPtr Group::removeMember( Core::Entity::PlayerPtr pSender, Core::Entity::PlayerPtr pRecipient, uint64_t senderId, uint64_t recipientId ) +{ + assert( pSender != nullptr || senderId != 0 ); + + auto packet = GamePacketNew< Server::FFXIVIpcSocialRequestResponse, ServerZoneIpcType >( recipientId, senderId ); + packet.data().contentId = recipientId; + packet.data().category = Common::SocialCategory::Friends; + + return packet; +} + void Group::sendPacketToMembers( Core::Network::Packets::GamePacketPtr pPacket, bool invitesToo ) { assert( pPacket ); @@ -86,31 +123,41 @@ Core::Network::Packets::Server::PlayerEntry Group::generatePlayerEntry( GroupMem // We check if player is online. If so, we can pull more data - otherwise just name // todo: set as offline in one of the unknown values, if session does not exist - auto pSession = g_serverZone.getSession( groupMember.contentId ); // todo: aa i don't like this. maybe just store their ID instead of contentID??? - entry.bytes[3] = 0x10; - entry.bytes[4] = 0x00; - entry.bytes[6] = 0x3F; - entry.bytes[11] = 0x10; + auto pSession = g_serverZone.getSession( groupMember.name ); // todo: aa i don't like this. maybe just store their ID instead of contentID??? + + entry.timestamp = 1512799339; + entry.status = 2; + entry.unknown = 0; + //entry.entryIcon = 0xf; + entry.unavailable = 0; // unavailable (other world) + entry.one = 0; + if( pSession ) { auto pPlayer = pSession->getPlayer(); entry.contentId = pPlayer->getContentId(); - entry.bytes[2] = pPlayer->getCurrentZone()->getId(); + //entry.bytes[2] = pPlayer->getCurrentZone()->getId(); entry.classJob = pPlayer->getClass(); entry.level = pPlayer->getLevel(); entry.zoneId = pPlayer->getCurrentZone()->getId(); entry.grandCompany = pPlayer->getGc(); - memcpy( &entry.fcTag[0], "Meme", 9 ); + memcpy( &entry.fcTag[0], "Meme", 4 ); entry.clientLanguage = 2; entry.knownLanguages = 0x0F; entry.onlineStatusMask = pPlayer->getOnlineStatusMask(); + + g_log.debug( std::to_string( pPlayer->getContentId() ) ); } // TODO: no idea what this does - me neither //listPacket.data().entries[0].one = 1; + g_log.debug( std::to_string(groupMember.contentId) ); + + g_log.debug( std::to_string( entry.contentId ) ); + return entry; } diff --git a/src/servers/Server_Zone/Actor/Social/Group.h b/src/servers/Server_Zone/Actor/Social/Group.h index a315d19c..d970b520 100644 --- a/src/servers/Server_Zone/Actor/Social/Group.h +++ b/src/servers/Server_Zone/Actor/Social/Group.h @@ -40,9 +40,8 @@ enum class GroupType : uint8_t class Group : public boost::enable_shared_from_this< Group > { public: - Group( uint64_t id, uint64_t ownerId, uint32_t maxCapacity, time_point createTime ) : - m_id( id ), m_ownerId( m_ownerId ), m_maxCapacity( maxCapacity ), m_createTime( createTime ) {}; - ~Group() {}; + Group( uint64_t id, uint64_t ownerId ) : + m_id( id ), m_ownerId( m_ownerId ) {}; bool isParty() const; bool isFriendList() const; @@ -53,10 +52,10 @@ public: bool isContentGroup() const; virtual Core::Network::Packets::GamePacketPtr addMember( PlayerPtr pSender, PlayerPtr pRecipient, uint64_t senderId = 0, uint64_t recipientId = 0 ); - /* + virtual Core::Network::Packets::GamePacketPtr inviteMember( PlayerPtr pSender, PlayerPtr pRecipient, uint64_t senderId = 0, uint64_t recipientId = 0 ); virtual Core::Network::Packets::GamePacketPtr removeMember( PlayerPtr pSender, PlayerPtr pRecipient, uint64_t senderId = 0, uint64_t recipientId = 0 ); - virtual Core::Network::Packets::GamePacketPtr kickMember( PlayerPtr pSender, PlayerPtr pRecipient, uint64_t senderId = 0, uint64_t recipientId = 0 );*/ + //virtual Core::Network::Packets::GamePacketPtr kickMember( PlayerPtr pSender, PlayerPtr pRecipient, uint64_t senderId = 0, uint64_t recipientId = 0 ); virtual void sendPacketToMembers( Core::Network::Packets::GamePacketPtr pPacket, bool invitesToo = false ); /*! generates a player entry used for lists (social, etc) */ @@ -69,7 +68,7 @@ public: /*! get container limit */ uint32_t getCapacity() const; -private: +protected: GroupType m_type{ GroupType::None }; uint64_t m_id{ 0 }; uint64_t m_ownerId{ 0 }; @@ -77,10 +76,10 @@ private: uint32_t m_maxRoles{ 50 }; time_point m_createTime{ std::chrono::steady_clock::now() }; std::map< uint64_t, GroupMember > m_members; - std::map< uint64_t, uint64_t > m_invites; // - - + std::map< uint64_t, GroupMember > m_invites; // +private: + /*virtual void load(); virtual void update(); diff --git a/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.cpp b/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.cpp index 373d4bf4..7db0ffbf 100644 --- a/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.cpp +++ b/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.cpp @@ -14,27 +14,22 @@ using namespace Core::Entity; Core::Entity::Social::FriendListMgr::FriendListMgr() { -} - -Core::Entity::Social::FriendListMgr::~FriendListMgr() -{ - -} +} bool Social::FriendListMgr::init() { return true; } -Social::FriendListPtr Social::FriendListMgr::getPlayerFriendsList( uint32_t playerId ) +uint64_t Social::FriendListMgr::fetchPlayerFriendsList( uint32_t playerId ) { - std::mt19937_64 engine( std::random_device{}( ) ); - std::uniform_int_distribution distribution; - auto ui64 = distribution( engine ); + uint64_t newGroupId = generateGroupId(); - FriendList nFriendList( ui64, playerId, 200, std::chrono::steady_clock::now() ); + auto pFriendList = boost::make_shared< FriendList >( newGroupId, playerId ); - FriendListPtr pFriendList = boost::make_shared< FriendList >( nFriendList ); - pFriendList->getCapacity(); - return pFriendList; + m_groups.emplace( newGroupId, pFriendList ); + + g_log.debug( std::to_string( m_groups.size() ) ); + + return newGroupId; } \ No newline at end of file diff --git a/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.h b/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.h index 560cd7eb..c513cfeb 100644 --- a/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.h +++ b/src/servers/Server_Zone/Actor/Social/Manager/FriendListMgr.h @@ -16,22 +16,23 @@ namespace Core { namespace Entity { namespace Social { -class FriendListMgr +class FriendListMgr : public GroupMgr { public: FriendListMgr(); - ~FriendListMgr(); bool init(); - FriendListPtr getPlayerFriendsList( uint32_t playerId ); - + uint64_t fetchPlayerFriendsList( uint32_t playerId ); + /* + FriendListPtr findGroupByInviteIdForPlayer( uint64_t playerId ) const; + FriendListPtr findGroupById( uint64_t groupId ) const; + */ + std::map< uint64_t, FriendListPtr > m_groups; private: + // todo: can we handle this m_groups grouptype better..? + GroupType m_type{ GroupType::FriendList }; - uint64_t m_groupCount{ 0 }; - uint32_t m_maxEntries{ 0xFFFFFFFF }; - std::map< uint64_t, GroupPtr > m_groups; // < groupid, groupPtr > - std::map< uint64_t, uint64_t > m_invites; // < recipient, groupid > }; diff --git a/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.cpp b/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.cpp index 70d86f03..9510ee9a 100644 --- a/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.cpp +++ b/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.cpp @@ -8,6 +8,11 @@ Social::GroupMgr::GroupMgr() } +Social::GroupMgr::~GroupMgr() +{ + +} + Social::GroupPtr Social::GroupMgr::findGroupByInviteIdForPlayer( uint64_t playerId ) const { auto it = m_invites.find( playerId ); @@ -18,7 +23,7 @@ Social::GroupPtr Social::GroupMgr::findGroupByInviteIdForPlayer( uint64_t player return nullptr; } -Social::GroupPtr Core::Entity::Social::GroupMgr::findGroupById( uint64_t groupId ) const +Social::GroupPtr Social::GroupMgr::findGroupById( uint64_t groupId ) const { auto it = m_groups.find( groupId ); if( it != m_groups.end() ) @@ -26,4 +31,20 @@ Social::GroupPtr Core::Entity::Social::GroupMgr::findGroupById( uint64_t groupId return it->second; } return nullptr; +} + +uint64_t Social::GroupMgr::generateGroupId() +{ + m_lastGroupId++; + return m_lastGroupId; +} + +bool Social::GroupMgr::hasInvite( uint64_t playerId ) const +{ + auto it = m_invites.find( playerId ); + if ( it != m_invites.end() ) + { + return true; + } + return false; } \ No newline at end of file diff --git a/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.h b/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.h index 4e519b33..8e7f603b 100644 --- a/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.h +++ b/src/servers/Server_Zone/Actor/Social/Manager/GroupMgr.h @@ -12,20 +12,38 @@ namespace Core { namespace Entity { namespace Social { -class GroupMgr : public boost::enable_shared_from_this< GroupMgr > +class GroupMgr { public: GroupMgr(); + virtual ~GroupMgr(); - GroupPtr findGroupByInviteIdForPlayer( uint64_t playerId ) const; - GroupPtr findGroupById( uint64_t groupId ) const; + virtual GroupPtr findGroupByInviteIdForPlayer( uint64_t playerId ) const; + virtual GroupPtr findGroupById( uint64_t groupId ) const; + /* + template + GroupPtr findGroup( uint64_t arg ) + { + auto it = m_groups.find( groupId ); + if ( it != m_groups.end() ) + { + return it->second; + } + return nullptr; + }*/ -private: + bool hasInvite( uint64_t playerId ) const; + +protected: GroupType m_type{ GroupType::None }; uint64_t m_groupCount{ 0 }; uint32_t m_maxEntries{ 0xFFFFFFFF }; - std::map< uint64_t, GroupPtr > m_groups; - std::map< uint64_t, uint64_t > m_invites; // < recipient, groupid > + + std::map< uint64_t, uint64_t > m_invites; + + uint64_t m_lastGroupId{ 0 }; + + // < recipient, groupid > //virtual GroupPtr createGroup( PlayerPtr pOwner ) = 0; /* @@ -40,6 +58,11 @@ private: friend virtual void disband(); */ + virtual uint64_t generateGroupId(); + +private: + std::map< uint64_t, GroupPtr > m_groups; + }; } diff --git a/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp index c6735f21..fbe88d4e 100644 --- a/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/PacketHandlers.cpp @@ -36,6 +36,7 @@ #include "Event/EventHelper.h" #include "Action/Action.h" #include "Action/ActionTeleport.h" +#include "Actor/Social/Manager/FriendListMgr.h" extern Core::Logger g_log; @@ -43,6 +44,7 @@ extern Core::ServerZone g_serverZone; extern Core::ZoneMgr g_zoneMgr; extern Core::Data::ExdData g_exdData; extern Core::DebugCommandHandler g_gameCommandMgr; +extern Core::Entity::Social::FriendListMgr g_friendListMgr; using namespace Core::Common; using namespace Core::Network::Packets; @@ -476,10 +478,12 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket uint16_t i = 0; - g_log.debug( std::to_string( player.getFriendsList()->getMembers().size() ) ); + auto playerFriendsList = g_friendListMgr.findGroupById( player.getFriendsListId() ); - for ( auto member : player.getFriendsList()->getMembers() ) + // todo: move this garbage else fucking where + for ( auto member : playerFriendsList->getMembers() ) { + // more elegant way to break over list entries pls if ( i == 10 ) break; @@ -686,7 +690,16 @@ void Core::Network::GameConnection::socialReqSendHandler( const Packets::GamePac pRecipient->queuePacket( packet ); pRecipient->sendDebug( "ding ding" ); - pRecipient->getFriendsList()->addMember( player.getAsPlayer(), pRecipient, player.getId(), pRecipient->getId() ); + auto recipientFriendsList = g_friendListMgr.findGroupById( pRecipient->getFriendsListId() ); + + auto senderResultPacket = recipientFriendsList->inviteMember( player.getAsPlayer(), pRecipient, player.getId(), pRecipient->getId() ); + + player.queuePacket( senderResultPacket ); + + if ( recipientFriendsList->isFriendList() ) + { + g_log.debug( "he HAA HAAA" ); + } response.data().messageId = typeMessage[category]; } diff --git a/src/servers/Server_Zone/ServerZone.cpp b/src/servers/Server_Zone/ServerZone.cpp index a863b06a..4de459c2 100644 --- a/src/servers/Server_Zone/ServerZone.cpp +++ b/src/servers/Server_Zone/ServerZone.cpp @@ -41,6 +41,7 @@ Core::Data::ExdData g_exdData; Core::ZoneMgr g_zoneMgr; Core::LinkshellMgr g_linkshellMgr; Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb; +Core::Entity::Social::FriendListMgr g_friendListMgr; Core::ServerZone::ServerZone( const std::string& configPath ) : m_configPath( configPath ), @@ -219,6 +220,8 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) return; } + g_friendListMgr.init(); + Network::HivePtr hive( new Network::Hive() ); Network::addServerToHive< Network::GameConnection >( m_ip, m_port, hive );