2021-12-01 21:30:12 -03:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iterator>
|
|
|
|
|
|
|
|
#include <Logging/Logger.h>
|
|
|
|
#include <Service.h>
|
|
|
|
#include <Util/Util.h>
|
|
|
|
|
|
|
|
#include "Actor/Player.h"
|
|
|
|
#include "FriendListMgr.h"
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
using namespace Sapphire;
|
|
|
|
using namespace Sapphire::World::Manager;
|
|
|
|
|
|
|
|
bool FriendListMgr::onInviteCreate( Entity::Player& source, Entity::Player& target )
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
auto& sourceFL = source.getFriendListID();
|
|
|
|
auto& targetFL = target.getFriendListID();
|
|
|
|
|
|
|
|
// check if player already has been invited or friends
|
2021-12-13 22:36:29 -03:00
|
|
|
if( isFriend( source, target ) )
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
// already invited/friends
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if there are slots available to allocate and get idx
|
|
|
|
auto sourceIdx = getEntryIndex( source, 0 );
|
|
|
|
auto targetIdx = getEntryIndex( target, 0 );
|
|
|
|
|
|
|
|
if( sourceIdx == -1 || targetIdx == -1 )
|
|
|
|
{
|
|
|
|
// todo: complain about having too many friends
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& sourceFLData = source.getFriendListData();
|
|
|
|
auto& targetFLData = target.getFriendListData();
|
|
|
|
|
|
|
|
// add ID and data to arrays of both players
|
2021-12-02 15:06:52 -03:00
|
|
|
sourceFL[ sourceIdx ] = target.getCharacterId();
|
|
|
|
targetFL[ targetIdx ] = source.getCharacterId();
|
2021-12-01 21:30:12 -03:00
|
|
|
|
|
|
|
|
|
|
|
Common::HierarchyData hierarchy;
|
|
|
|
hierarchy.data.dateAdded = Common::Util::getTimeSeconds();
|
|
|
|
hierarchy.data.group = 0;
|
|
|
|
hierarchy.data.type = Common::HierarchyType::FRIENDLIST;
|
|
|
|
|
2021-12-13 23:04:07 -03:00
|
|
|
// set hierarchy status for invite sender
|
|
|
|
hierarchy.data.status = Common::HierarchyStatus::SentRequest;
|
2021-12-02 15:06:52 -03:00
|
|
|
sourceFLData[ sourceIdx ] = hierarchy;
|
2021-12-01 21:30:12 -03:00
|
|
|
|
2021-12-13 23:04:07 -03:00
|
|
|
// set hierarchy status for invite receiver
|
2021-12-01 21:30:12 -03:00
|
|
|
hierarchy.data.status = Common::HierarchyStatus::ReceivedRequest;
|
2021-12-02 15:06:52 -03:00
|
|
|
targetFLData[ targetIdx ] = hierarchy;
|
2021-12-01 21:30:12 -03:00
|
|
|
|
|
|
|
// force db update for friendlist
|
|
|
|
source.updateDbFriendList();
|
|
|
|
target.updateDbFriendList();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
bool FriendListMgr::onInviteAccept( Entity::Player& source, Entity::Player& target )
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
// accept friend invite
|
|
|
|
auto sourceIdx = getEntryIndex( source, target.getCharacterId() );
|
|
|
|
auto targetIdx = getEntryIndex( target, source.getCharacterId() );
|
|
|
|
|
|
|
|
if( sourceIdx == -1 || targetIdx == -1 )
|
|
|
|
{
|
|
|
|
// currently not friends
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& sourceFLData = source.getFriendListData();
|
|
|
|
auto& targetFLData = target.getFriendListData();
|
|
|
|
|
2021-12-13 23:04:07 -03:00
|
|
|
// currently, type on hierarchy indicates invite type - since it is no longer an invite, set type to NONE
|
2021-12-02 15:06:52 -03:00
|
|
|
sourceFLData[ sourceIdx ].data.status = Common::HierarchyStatus::Added;
|
|
|
|
sourceFLData[ sourceIdx ].data.type = Common::HierarchyType::NONE_2;
|
|
|
|
targetFLData[ targetIdx ].data.status = Common::HierarchyStatus::Added;
|
|
|
|
targetFLData[ targetIdx ].data.type = Common::HierarchyType::NONE_2;
|
2021-12-01 21:30:12 -03:00
|
|
|
|
|
|
|
source.updateDbFriendList();
|
|
|
|
target.updateDbFriendList();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
bool FriendListMgr::onInviteDecline( Entity::Player& source, Entity::Player& target )
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
// decline friend invite
|
|
|
|
auto sourceIdx = getEntryIndex( source, target.getCharacterId() );
|
|
|
|
auto targetIdx = getEntryIndex( target, source.getCharacterId() );
|
|
|
|
|
|
|
|
if( sourceIdx == -1 || targetIdx == -1 )
|
|
|
|
{
|
|
|
|
// currently not friends
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& sourceFL = source.getFriendListID();
|
|
|
|
auto& targetFL = target.getFriendListID();
|
|
|
|
|
|
|
|
auto& sourceFLData = source.getFriendListData();
|
|
|
|
auto& targetFLData = target.getFriendListData();
|
|
|
|
|
2021-12-02 15:06:52 -03:00
|
|
|
sourceFL[ sourceIdx ] = 0;
|
|
|
|
targetFL[ targetIdx ] = 0;
|
2021-12-01 21:30:12 -03:00
|
|
|
|
2021-12-02 15:06:52 -03:00
|
|
|
sourceFLData[ sourceIdx ].u64 = 0;
|
|
|
|
targetFLData[ targetIdx ].u64 = 0;
|
2021-12-01 21:30:12 -03:00
|
|
|
|
|
|
|
source.updateDbFriendList();
|
|
|
|
target.updateDbFriendList();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
bool FriendListMgr::onRemoveFriend( Entity::Player& source, Entity::Player& target )
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
// remove friend
|
|
|
|
// this not retail accurate - retail only removes source friendlist, but that also makes it more complicated for readding friend
|
|
|
|
// this will simply remove the entry from both players
|
|
|
|
|
|
|
|
return onInviteDecline( source, target );
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
bool FriendListMgr::onAssignGroup( Entity::Player& source, Entity::Player& target, uint8_t group )
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
// assign group to friend entry (to source only)
|
|
|
|
auto sourceIdx = getEntryIndex( source, target.getCharacterId() );
|
|
|
|
|
|
|
|
if( sourceIdx == -1 )
|
|
|
|
{
|
|
|
|
// currently not friends
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& sourceFLData = source.getFriendListData();
|
|
|
|
|
2021-12-02 15:06:52 -03:00
|
|
|
sourceFLData[ sourceIdx ].data.group = group;
|
2021-12-01 21:30:12 -03:00
|
|
|
|
|
|
|
source.updateDbFriendList();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
bool FriendListMgr::isFriend( Entity::Player& source, Entity::Player& target ) const
|
2021-12-13 22:36:29 -03:00
|
|
|
{
|
|
|
|
return getEntryIndex( source, target.getCharacterId() ) != -1;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
ptrdiff_t FriendListMgr::getEntryIndex( Entity::Player& source, uint64_t characterId ) const
|
2021-12-01 21:30:12 -03:00
|
|
|
{
|
|
|
|
auto& sourceFL = source.getFriendListID();
|
|
|
|
auto sourceInvIt = std::find( std::begin( sourceFL ), std::end( sourceFL ), characterId );
|
|
|
|
|
|
|
|
// not found
|
|
|
|
if( sourceInvIt == sourceFL.end() )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return sourceInvIt - std::begin( sourceFL );
|
|
|
|
}
|