1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-28 20:27:46 +00:00

Structure changes, adjustments to flow;

This commit is contained in:
Maru 2018-03-20 01:44:04 -03:00
parent c1cd763fba
commit e506a42dea
11 changed files with 144 additions and 20 deletions

View file

@ -736,9 +736,9 @@ namespace Core {
enum class SocialRequestResponse : uint8_t
{
Decline,
Accept,
Cancel,
Decline = 0,
Accept = 1,
Cancel = 2
};
typedef std::vector< PlayerStateFlag > PlayerStateFlagList;

View file

@ -199,6 +199,7 @@ namespace Packets {
CFDutyInfoHandler = 0x0078, // updated 4.2
SocialReqSendHandler = 0x00CA, // updated 4.2
SocialReqProcessHandler = 0x00CC, // updated 4.2
ChatHandler = 0x00C7, // updated 4.2

View file

@ -207,7 +207,13 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
calculateStats();
m_friendsListId = g_fw.get< Social::SocialMgr < Social::FriendList > >()->loadFriendsList( m_id );
auto friendListMgr = g_fw.get< Social::SocialMgr < Social::FriendList > >();
if( !friendListMgr->loadFriendsList( m_id ) )
{
pLog->error( "[" + char_id_str + "] Failed to load friends list!" );
}
pLog->debug( std::to_string( m_id ) + " ID, has group ID: " + std::to_string( m_friendsListId ) );
// first login, run the script event

View file

@ -55,6 +55,7 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive,
setZoneHandler( ClientZoneIpcType::LogoutHandler, "LogoutHandler", &GameConnection::logoutHandler );
setZoneHandler( ClientZoneIpcType::SocialReqSendHandler, "SocialReqSendHandler", &GameConnection::socialReqSendHandler );
setZoneHandler( ClientZoneIpcType::SocialReqProcessHandler, "SocialReqProcessHandler", &GameConnection::socialReqProcessHandler );
setZoneHandler( ClientZoneIpcType::SocialListHandler, "SocialListHandler", &GameConnection::socialListHandler );
setZoneHandler( ClientZoneIpcType::SetSearchInfoHandler, "SetSearchInfoHandler", &GameConnection::setSearchInfoHandler );
setZoneHandler( ClientZoneIpcType::ReqSearchInfoHandler, "ReqSearchInfoHandler", &GameConnection::reqSearchInfoHandler );

View file

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

View file

@ -511,19 +511,44 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
}
void Core::Network::GameConnection::socialReqResponseHandler( const Packets::GamePacket& inPacket,
void Core::Network::GameConnection::socialReqProcessHandler( const Packets::GamePacket& inPacket,
Entity::Player& player )
{
auto targetId = inPacket.getValAt< uint32_t >( 0x20 );
auto category = inPacket.getValAt< Common::SocialCategory >( 0x28 );
auto action = inPacket.getValAt< Common::SocialRequestAction >( 0x29 );
auto friendListMgr = g_fw.get< Social::SocialMgr< Social::FriendList > >();
ZoneChannelPacket< FFXIVIpcSocialRequestError > info( targetId, player.getId() );
ZoneChannelPacket< FFXIVIpcSocialRequestResponse > response( targetId, player.getId() );
info.data().category = category;
response.data().category = category;
switch( action )
{
case SocialRequestAction::Accept:
{
auto recipientFriendsList = g_fw.get< Social::SocialMgr< Social::FriendList > >()->findGroupById( player.getId() );
// Load our target's friendlist, hoping it's still in memory.. (target could have gone offline at this point)
if( !friendListMgr->loadFriendsList( targetId ) )
{
g_fw.get< Logger >()->error( "Failed to load friend list for character ID " + std::to_string( targetId ) + ", removing entry." );
}
auto senderFriendsList = friendListMgr->findGroupById( targetId );
senderFriendsList->processInvite( player.getContentId(), SocialRequestAction::Accept );
//todo: FICK
recipientFriendsList->processInvite( targetId, SocialRequestAction::Accept );
}
default:
break;
}
//auto pQR = g_database.query( "SELECT Name FROM dbchara WHERE CharacterId = " + to_string( targetId ) );
auto name = player.getName();
/*

View file

@ -33,7 +33,9 @@ uint32_t FriendList::addMember( uint64_t contentId, FriendEntryType friendEntryT
uint32_t logMessage = 0;
m_members.push_back( contentId );
// todo: index logmessage.. report error (-1)
const int32_t index = Group::findNextAvailableIndex();
FriendEntry friendEntry;
friendEntry.timestamp = std::time( nullptr );
@ -41,11 +43,74 @@ uint32_t FriendList::addMember( uint64_t contentId, FriendEntryType friendEntryT
friendEntry.entryStatus = friendEntryType;
friendEntry.unknown = 0;
m_entries.push_back( friendEntry );
m_members[index] = contentId;
m_entries[index] = friendEntry;
return logMessage;
}
uint32_t FriendList::removeMember( uint64_t contentId )
{
assert( contentId != 0 );
uint32_t logMessage = 0;
// todo: index logmessage.. report error (-1)
const uint32_t index = getFriendIndex( contentId );
m_members[index] = 0;
auto entry = m_entries[index];
entry.entryStatus = FriendEntryType::Invalid;
entry.friendGroup = 0;
entry.timestamp = 0;
entry.unknown = 0;
return logMessage;
}
uint32_t FriendList::processInvite( uint64_t contentId, Common::SocialRequestAction action )
{
uint32_t logMessage = 0;
std::vector< uint64_t >::iterator it;
it = std::find( m_members.begin(), m_members.end(), contentId );
auto dataIndex = std::distance( m_members.begin(), it );
auto friendEntryData = m_entries.at( dataIndex );
// todo: check timestamp, if expired etc.
switch( action )
{
case Common::SocialRequestAction::Accept:
{
friendEntryData.entryStatus = FriendEntryType::Added;
break;
}
case Common::SocialRequestAction::Decline:
{
removeMember( contentId );
}
default:
break;
}
}
uint32_t FriendList::getFriendIndex( uint64_t contentId )
{
std::vector< uint64_t >::iterator it;
it = std::find( m_members.begin(), m_members.end(), contentId );
return std::distance( m_members.begin(), it );
}
std::vector< FriendEntry >& FriendList::getEntries()
{
return m_entries;
@ -86,11 +151,14 @@ std::vector< PlayerEntry > FriendList::getFriendListEntries( uint16_t entryAmoun
std::vector< PlayerEntry > entryList = {};
uint16_t limit = 0;
for ( const auto& member : m_members )
for( const auto& member : m_members )
{
if ( limit == entryAmount )
if( limit == entryAmount )
break;
if( member == 0 )
continue;
entryList.push_back( generatePlayerEntry( member ) );
limit++;
}

View file

@ -17,6 +17,7 @@ namespace Social {
enum FriendEntryType : uint8_t
{
Invalid = 0,
Added = 0x10,
SentRequest = 0x20,
ReceivedRequest = 0x30
@ -44,6 +45,12 @@ public:
uint32_t addMember( uint64_t contentId, FriendEntryType friendEntryType );
uint32_t processInvite( uint64_t contentId, Common::SocialRequestAction );
uint32_t removeMember( uint64_t contentId );
uint32_t getFriendIndex( uint64_t contentId );
/*! access entry vector */
std::vector< FriendEntry >& getEntries();

View file

@ -15,15 +15,25 @@
#include "Framework.h"
#include "Forwards.h"
#include <set>
extern Core::Framework g_fw;
using namespace Core::Social;
using namespace Core::Network;
uint32_t Group::findNextAvailableIndex() const
int32_t Group::findNextAvailableIndex() const
{
// todo: perhaps throw an exception instead of returning -1 if not available?
auto const it = std::find( std::begin( m_members ), std::end( m_members ), 0 );
if( it == m_members.end() )
{
return -1;
}
return std::distance( m_members.begin(), it );
}
// todo: invite map in g_serverZone.getGroupMgr(GroupType) and look up

View file

@ -64,7 +64,7 @@ public:
//virtual void populateGroupMembers();
uint32_t findNextAvailableIndex() const;
int32_t findNextAvailableIndex() const;
/*! access member vector */
std::vector< uint64_t >& getMembers();
@ -72,6 +72,9 @@ public:
/*! get container limit */
uint32_t getCapacity() const;
/*! get group id */
uint64_t getId() const;
/*! get total size of group (members + invites) */
uint32_t Group::getTotalSize() const;
@ -87,6 +90,8 @@ protected:
uint32_t m_maxRoles{ 50 };
std::chrono::steady_clock::time_point m_createTime{ std::chrono::steady_clock::now() };
// todo: it might be interesting to consider moving to a map with entries and sorting that out.
// it does imply useless information being stored in the case of a few groups, which is why I'm not doing it atm
std::vector< uint64_t > m_members;
private:

View file

@ -72,7 +72,7 @@ public:
return false;
}
uint64_t loadFriendsList( uint32_t characterId );
bool loadFriendsList( uint32_t characterId );
protected:
// those would be implemented in T, so you'd have T.m_type and T.m_maxEntries
@ -109,8 +109,12 @@ bool Core::Social::SocialMgr< T >::init()
}
template<> inline
uint64_t Core::Social::SocialMgr< Core::Social::FriendList >::loadFriendsList( uint32_t characterId )
bool Core::Social::SocialMgr< Core::Social::FriendList >::loadFriendsList( uint32_t characterId )
{
// Check if our group has already been loaded..
auto group = findGroupById( characterId );
if( group )
return true;
auto pDb = g_fw.get< Db::DbWorkerPool< Db::CharaDbConnection > >();
auto res = pDb->query( "SELECT CharacterId, CharacterIdList, InviteDataList "
@ -135,10 +139,7 @@ uint64_t Core::Social::SocialMgr< Core::Social::FriendList >::loadFriendsList( u
{
std::vector< uint64_t > list( friends.size() / 8 );
// todo: fix this garbage check
if( list.at( 0 ) != 0 )
{
friendsList.getMembers() = list;
}
friendsList.getMembers() = list;
}
// Insert invite data from binary data
@ -155,9 +156,9 @@ uint64_t Core::Social::SocialMgr< Core::Social::FriendList >::loadFriendsList( u
auto friendListPtr = boost::make_shared< Social::FriendList >( friendsList );
m_groups[groupID] = friendListPtr;
m_groups.emplace( characterId, friendListPtr );
return groupID;
return true;
}