mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 22:37:45 +00:00
Merge pull request #743 from hkAlice/3.0-blacklist
[3.0] blacklist support;
This commit is contained in:
commit
2fe3b3d3de
19 changed files with 435 additions and 50 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -99,7 +99,6 @@ CTestTestfile.cmake
|
|||
*.cache
|
||||
*.dat
|
||||
*.suo
|
||||
*.pch
|
||||
*.ipch
|
||||
*.g.cs
|
||||
*.g.i.cs
|
||||
|
@ -112,7 +111,6 @@ CTestTestfile.cmake
|
|||
*.ilk
|
||||
/Sapphire.VC.VC.opendb
|
||||
*.user
|
||||
*.dat
|
||||
*.metagen
|
||||
*.ipdb
|
||||
*.iobj
|
||||
|
@ -145,3 +143,4 @@ doxygen/*.tmp
|
|||
# ignore config directory contents except the default file
|
||||
config/*.ini
|
||||
!config/config.ini.default
|
||||
/CMakeSettings.json
|
||||
|
|
|
@ -273,10 +273,13 @@ void PlayerMinimal::saveAsNew()
|
|||
std::vector< uint8_t > friendIds( 1600, 0 );
|
||||
std::vector< uint8_t > inviteIds( 1600, 0 );
|
||||
|
||||
stmtFriendList->setUInt64( 1, m_characterId );
|
||||
stmtFriendList->setBinary( 2, friendIds );
|
||||
stmtFriendList->setBinary( 3, inviteIds );
|
||||
g_charaDb.directExecute( stmtFriendList );
|
||||
// Blacklist related
|
||||
auto stmtBlacklist = g_charaDb.getPreparedStatement( Db::ZoneDbStatements::CHARA_BLACKLIST_INS );
|
||||
std::vector< uint8_t > blIds( 1600, 0 );
|
||||
|
||||
stmtBlacklist->setUInt64( 1, m_characterId );
|
||||
stmtBlacklist->setBinary( 2, blIds );
|
||||
g_charaDb.directExecute( stmtBlacklist );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// SET UP INVENTORIES
|
||||
|
|
|
@ -236,6 +236,21 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
|
|||
"WHERE CharacterId = ?;",
|
||||
CONNECTION_SYNC );
|
||||
|
||||
/// CHARA FRIENDLIST
|
||||
prepareStatement( CHARA_BLACKLIST_INS,
|
||||
"INSERT INTO charainfoblacklist ( CharacterId, CharacterIdList, UPDATE_DATE ) "
|
||||
" VALUES ( ?, ?, NOW() );",
|
||||
CONNECTION_SYNC );
|
||||
|
||||
prepareStatement( CHARA_BLACKLIST_UP, "UPDATE charainfoblacklist "
|
||||
" SET CharacterIdList = ?"
|
||||
" WHERE CharacterId = ?;",
|
||||
CONNECTION_ASYNC );
|
||||
|
||||
prepareStatement( CHARA_BLACKLIST_SEL, "SELECT CharacterIdList FROM charainfoblacklist "
|
||||
" WHERE CharacterId = ?;",
|
||||
CONNECTION_SYNC );
|
||||
|
||||
/// CHARA LINKSHELL
|
||||
prepareStatement( CHARA_LINKSHELL_INS,
|
||||
"INSERT INTO infolinkshell ( LinkshellId, MasterCharacterId, CharacterIdList, "
|
||||
|
|
|
@ -84,6 +84,10 @@ namespace Sapphire::Db
|
|||
CHARA_FRIENDLIST_UP,
|
||||
CHARA_FRIENDLIST_SEL,
|
||||
|
||||
CHARA_BLACKLIST_INS,
|
||||
CHARA_BLACKLIST_UP,
|
||||
CHARA_BLACKLIST_SEL,
|
||||
|
||||
CHARA_LINKSHELL_INS,
|
||||
|
||||
ZONE_SEL_BNPCS,
|
||||
|
|
|
@ -590,6 +590,17 @@ struct FFXIVIpcGetBlacklist : FFXIVIpcBasePacket< GetBlacklist >
|
|||
uint8_t RequestKey;
|
||||
};
|
||||
|
||||
struct FFXIVIpcBlacklistAdd : FFXIVIpcBasePacket< BlacklistAdd >
|
||||
{
|
||||
char TargetCharacterName[32];
|
||||
};
|
||||
|
||||
struct FFXIVIpcBlacklistRemove : FFXIVIpcBasePacket< BlacklistRemove >
|
||||
{
|
||||
uint64_t TargetCharacterID;
|
||||
char TargetCharacterName[32];
|
||||
};
|
||||
|
||||
/* 60986 */
|
||||
struct FFXIVIpcInvite : FFXIVIpcBasePacket< Invite >
|
||||
{
|
||||
|
|
|
@ -98,13 +98,13 @@ Sapphire::Entity::Player::Player() :
|
|||
memset( m_classArray.data(), 0, sizeof( m_classArray.data() ) );
|
||||
memset( m_expArray.data(), 0, sizeof( m_expArray.data() ) );
|
||||
|
||||
for( uint8_t i = 0; i < 80; i++ )
|
||||
for( uint8_t i = 0; i < 80; ++i )
|
||||
{
|
||||
m_recast[ i ] = 0.0f;
|
||||
m_recastMax[ i ] = 0.0f;
|
||||
}
|
||||
|
||||
for( auto & i : m_charaLandData )
|
||||
for( auto& i : m_charaLandData )
|
||||
{
|
||||
memset( &i, 0xFF, 8 );
|
||||
memset( &i.flags, 0, 8 );
|
||||
|
@ -2138,11 +2138,17 @@ Sapphire::Entity::Player::FriendListIDVec& Sapphire::Entity::Player::getFriendLi
|
|||
{
|
||||
return m_friendList;
|
||||
}
|
||||
|
||||
Sapphire::Entity::Player::FriendListDataVec& Sapphire::Entity::Player::getFriendListData()
|
||||
{
|
||||
return m_friendInviteList;
|
||||
}
|
||||
|
||||
Sapphire::Entity::Player::FriendListIDVec& Sapphire::Entity::Player::getBlacklistID()
|
||||
{
|
||||
return m_blacklist;
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::setLastPcSearchResult( std::vector< uint32_t > result )
|
||||
{
|
||||
m_lastPcSearch = std::move( result );
|
||||
|
|
|
@ -559,7 +559,10 @@ namespace Sapphire::Entity
|
|||
bool loadHuntingLog();
|
||||
|
||||
/*! load friendlist */
|
||||
bool loadFriendlist();
|
||||
bool loadFriendList();
|
||||
|
||||
/*! load blacklist */
|
||||
bool loadBlacklist();
|
||||
|
||||
/*! update latest sync with db */
|
||||
bool syncLastDBWrite();
|
||||
|
@ -704,6 +707,8 @@ namespace Sapphire::Entity
|
|||
|
||||
void updateDbFriendList();
|
||||
|
||||
void updateDbBlacklist();
|
||||
|
||||
void updateDbChara() const;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -801,6 +806,7 @@ namespace Sapphire::Entity
|
|||
|
||||
using FriendListIDVec = std::array< uint64_t, 200 >;
|
||||
using FriendListDataVec = std::array< Common::HierarchyData, 200 >;
|
||||
using BlacklistIDVec = std::array< uint64_t, 200 >;
|
||||
|
||||
Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index );
|
||||
|
||||
|
@ -814,6 +820,8 @@ namespace Sapphire::Entity
|
|||
FriendListIDVec& getFriendListID();
|
||||
FriendListDataVec& getFriendListData();
|
||||
|
||||
BlacklistIDVec& getBlacklistID();
|
||||
|
||||
uint64_t m_lastMoveTime{};
|
||||
uint8_t m_lastMoveflag{};
|
||||
bool m_falling;
|
||||
|
@ -972,6 +980,8 @@ namespace Sapphire::Entity
|
|||
FriendListIDVec m_friendList{};
|
||||
FriendListDataVec m_friendInviteList{};
|
||||
|
||||
BlacklistIDVec m_blacklist{};
|
||||
|
||||
uint64_t m_partyId;
|
||||
std::vector< uint32_t > m_lastPcSearch;
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId )
|
|||
|
||||
res->free();
|
||||
|
||||
if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() || !loadHuntingLog() || !loadFriendlist() )
|
||||
if( !loadActiveQuests() || !loadClassData() || !loadSearchInfo() || !loadHuntingLog() || !loadFriendList() || !loadBlacklist() )
|
||||
{
|
||||
Logger::error( "chara#{0} data corrupt!", m_characterId );
|
||||
}
|
||||
|
@ -296,6 +296,9 @@ void Sapphire::Entity::Player::updateSql()
|
|||
////// FriendList
|
||||
updateDbFriendList();
|
||||
|
||||
////// Blacklist
|
||||
updateDbBlacklist();
|
||||
|
||||
///// Store last write
|
||||
syncLastDBWrite();
|
||||
}
|
||||
|
@ -481,6 +484,20 @@ void Sapphire::Entity::Player::updateDbFriendList()
|
|||
}
|
||||
|
||||
|
||||
void Sapphire::Entity::Player::updateDbBlacklist()
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
|
||||
auto stmt = db.getPreparedStatement( Db::CHARA_BLACKLIST_UP );
|
||||
|
||||
std::vector< uint8_t > blIds( 1600 );
|
||||
|
||||
memcpy( blIds.data(), m_blacklist.data(), 1600 );
|
||||
stmt->setBinary( 1, blIds );
|
||||
stmt->setUInt64( 2, m_characterId );
|
||||
db.execute( stmt );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Player::insertDbClass( const uint8_t classJobIndex, uint8_t level ) const
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
|
@ -680,7 +697,7 @@ bool Sapphire::Entity::Player::loadInventory()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::loadFriendlist()
|
||||
bool Sapphire::Entity::Player::loadFriendList()
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_FRIENDLIST_SEL );
|
||||
|
@ -705,6 +722,28 @@ bool Sapphire::Entity::Player::loadFriendlist()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Sapphire::Entity::Player::loadBlacklist()
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto stmt = db.getPreparedStatement( Db::ZoneDbStatements::CHARA_BLACKLIST_SEL );
|
||||
stmt->setUInt64( 1, m_characterId );
|
||||
auto res = db.query( stmt );
|
||||
|
||||
if( !res->next() )
|
||||
{
|
||||
Logger::error( "Failed to load blacklist data for character#{}", m_characterId );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto blacklist = res->getBlobVector( "CharacterIdList" );
|
||||
|
||||
if( !blacklist.empty() )
|
||||
std::memcpy( m_blacklist.data(), blacklist.data(), blacklist.size() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Sapphire::Entity::Player::syncLastDBWrite()
|
||||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
|
|
224
src/world/Manager/BlacklistMgr.cpp
Normal file
224
src/world/Manager/BlacklistMgr.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <Logging/Logger.h>
|
||||
#include <Service.h>
|
||||
#include <Util/Util.h>
|
||||
|
||||
#include <Network/PacketDef/Zone/ServerZoneDef.h>
|
||||
#include <Network/PacketContainer.h>
|
||||
|
||||
#include "Actor/Player.h"
|
||||
#include "BlacklistMgr.h"
|
||||
#include "FriendListMgr.h"
|
||||
|
||||
#include "WorldServer.h"
|
||||
|
||||
using namespace Sapphire::Common;
|
||||
using namespace Sapphire::Network::Packets;
|
||||
using namespace Sapphire::Network::Packets::WorldPackets;
|
||||
|
||||
bool Sapphire::World::Manager::BlacklistMgr::onAddCharacter( Entity::Player& source, const std::string& targetName )
|
||||
{
|
||||
// add target to blacklist
|
||||
|
||||
auto& server = Common::Service< Sapphire::World::WorldServer >::ref();
|
||||
|
||||
auto pTarget = server.getPlayer( targetName );
|
||||
if( !pTarget )
|
||||
{
|
||||
// target doesn't exist in server player table
|
||||
sendAddResultPacket( source, pTarget, 0x7 );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& target = *pTarget;
|
||||
|
||||
if( source.getCharacterId() == target.getCharacterId() )
|
||||
{
|
||||
// can't add self to blacklist
|
||||
sendAddResultPacket( source, pTarget, 0x7 );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( isBlacklisted( source, target ) )
|
||||
{
|
||||
// target already added to blacklist
|
||||
sendAddResultPacket( source, pTarget, 0x7 );
|
||||
return false;
|
||||
}
|
||||
|
||||
// get next available slot in blacklist
|
||||
auto sourceIdx = getEntryIndex( source, 0 );
|
||||
|
||||
if( sourceIdx == -1 )
|
||||
{
|
||||
// no slots left in blacklist (max capacity)
|
||||
return false;
|
||||
}
|
||||
|
||||
// add target ID to blacklist
|
||||
auto& sourceBL = source.getBlacklistID();
|
||||
sourceBL[sourceIdx] = target.getCharacterId();
|
||||
|
||||
source.updateDbBlacklist();
|
||||
|
||||
sendAddResultPacket( source, pTarget, 0 );
|
||||
|
||||
// check if player is friends with target
|
||||
auto& flMgr = Common::Service< Sapphire::World::Manager::FriendListMgr >::ref();
|
||||
if( flMgr.isFriend( source, target ) )
|
||||
flMgr.onRemoveFriend( source, target );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sapphire::World::Manager::BlacklistMgr::onRemoveCharacter( Entity::Player& source, const std::string& targetName )
|
||||
{
|
||||
// remove target from blacklist
|
||||
|
||||
auto& server = Common::Service< Sapphire::World::WorldServer >::ref();
|
||||
|
||||
auto pTarget = server.getPlayer( targetName );
|
||||
if( !pTarget )
|
||||
{
|
||||
// target doesn't exist in server player table
|
||||
sendRemoveResultPacket( source, pTarget, 0x7 );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& target = *pTarget;
|
||||
|
||||
auto sourceIdx = getEntryIndex( source, target.getCharacterId() );
|
||||
|
||||
if( !isBlacklisted( source, target ) )
|
||||
{
|
||||
// target not in blacklist
|
||||
sendRemoveResultPacket( source, pTarget, 0x7 );
|
||||
return false;
|
||||
}
|
||||
|
||||
// set target slot to 0
|
||||
auto& sourceBL = source.getBlacklistID();
|
||||
sourceBL[sourceIdx] = 0;
|
||||
source.updateDbBlacklist();
|
||||
|
||||
sendRemoveResultPacket( source, pTarget, 0 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sapphire::World::Manager::BlacklistMgr::onGetBlacklistPage( Entity::Player& source, uint8_t key, uint8_t nextIdx )
|
||||
{
|
||||
// this function will handle client side indexing and paginate blacklist entries
|
||||
// it'll also be called multiple times sequentially until there are no more entries left (id == 0)
|
||||
|
||||
auto& server = Common::Service< Sapphire::World::WorldServer >::ref();
|
||||
|
||||
std::vector< Server::BlacklistCharacter > entries;
|
||||
|
||||
// blacklist entries are sent in pages of 20
|
||||
const size_t itemsPerPage = 20;
|
||||
|
||||
// get array offset/last page sent from client packet
|
||||
auto offset = nextIdx;
|
||||
|
||||
auto& idVec = source.getBlacklistID();
|
||||
|
||||
for( size_t i = offset; i < offset + itemsPerPage; ++i )
|
||||
{
|
||||
if( idVec.size() <= i )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
auto id = idVec[ i ];
|
||||
auto pPlayer = server.getPlayer( id );
|
||||
|
||||
if( !pPlayer )
|
||||
continue;
|
||||
|
||||
// build our packet entry for current iterated id
|
||||
Server::BlacklistCharacter entry{};
|
||||
|
||||
entry.CharacterID = pPlayer->getCharacterId();
|
||||
strcpy( entry.CharacterName, pPlayer->getName().c_str() );
|
||||
|
||||
// add to current page
|
||||
entries.emplace_back( entry );
|
||||
}
|
||||
|
||||
// if the page is empty, then we've reached the last page
|
||||
bool isLast = entries.empty();
|
||||
|
||||
// configure paging state for client so that it knows whether to request more entries or not
|
||||
auto blacklistPacket = makeZonePacket< Server::FFXIVIpcGetBlacklistResult >( source.getId() );
|
||||
blacklistPacket->data().Index = offset;
|
||||
blacklistPacket->data().NextIndex = isLast ? 0 : nextIdx + itemsPerPage;
|
||||
blacklistPacket->data().RequestKey = key;
|
||||
|
||||
memcpy( &blacklistPacket->data().Blacklist[ 0 ], entries.data(), sizeof( Server::BlacklistCharacter ) * entries.size() );
|
||||
|
||||
server.queueForPlayer( source.getCharacterId(), blacklistPacket );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sapphire::World::Manager::BlacklistMgr::isBlacklisted( Entity::Player& source, const Entity::Player& target ) const
|
||||
{
|
||||
return getEntryIndex( source, target.getCharacterId() ) != -1;
|
||||
}
|
||||
|
||||
ptrdiff_t Sapphire::World::Manager::BlacklistMgr::getEntryIndex( Entity::Player& source, uint64_t characterId ) const
|
||||
{
|
||||
auto& sourceBL = source.getBlacklistID();
|
||||
auto sourceBlIt = std::find( std::begin( sourceBL ), std::end( sourceBL ), characterId );
|
||||
|
||||
// not found
|
||||
if( sourceBlIt == sourceBL.end() )
|
||||
return -1;
|
||||
|
||||
return sourceBlIt - std::begin( sourceBL );
|
||||
}
|
||||
|
||||
void Sapphire::World::Manager::BlacklistMgr::sendAddResultPacket( Entity::Player& source, const Entity::PlayerPtr pTarget, uint32_t result )
|
||||
{
|
||||
auto& server = Common::Service< Sapphire::World::WorldServer >::ref();
|
||||
|
||||
auto resultPacket = makeZonePacket< Server::FFXIVIpcBlacklistAddResult >( source.getId() );
|
||||
|
||||
if( pTarget )
|
||||
{
|
||||
Server::BlacklistCharacter blChar;
|
||||
blChar.CharacterID = pTarget->getCharacterId();
|
||||
strcpy( blChar.CharacterName, pTarget->getName().c_str() );
|
||||
|
||||
resultPacket->data().AddedCharacter = blChar;
|
||||
resultPacket->data().Identity = pTarget->getGender();
|
||||
}
|
||||
|
||||
resultPacket->data().Result = result;
|
||||
|
||||
server.queueForPlayer( source.getCharacterId(), resultPacket );
|
||||
}
|
||||
|
||||
void Sapphire::World::Manager::BlacklistMgr::sendRemoveResultPacket( Entity::Player& source, const Entity::PlayerPtr pTarget, uint32_t result )
|
||||
{
|
||||
auto& server = Common::Service< Sapphire::World::WorldServer >::ref();
|
||||
|
||||
auto resultPacket = makeZonePacket< Server::FFXIVIpcBlacklistRemoveResult >( source.getId() );
|
||||
|
||||
if( pTarget )
|
||||
{
|
||||
Server::BlacklistCharacter blChar;
|
||||
blChar.CharacterID = pTarget->getCharacterId();
|
||||
strcpy( blChar.CharacterName, pTarget->getName().c_str() );
|
||||
|
||||
resultPacket->data().RemovedCharacter = blChar;
|
||||
resultPacket->data().Identity = pTarget->getGender();
|
||||
}
|
||||
|
||||
resultPacket->data().Result = result;
|
||||
|
||||
server.queueForPlayer( source.getCharacterId(), resultPacket );
|
||||
}
|
27
src/world/Manager/BlacklistMgr.h
Normal file
27
src/world/Manager/BlacklistMgr.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "ForwardsZone.h"
|
||||
|
||||
namespace Sapphire::World::Manager
|
||||
{
|
||||
class BlacklistMgr
|
||||
{
|
||||
public:
|
||||
BlacklistMgr() = default;
|
||||
|
||||
bool onAddCharacter( Entity::Player& source, const std::string& targetName );
|
||||
bool onRemoveCharacter( Entity::Player& source, const std::string& targetName );
|
||||
|
||||
bool onGetBlacklistPage( Entity::Player& source, uint8_t key, uint8_t nextIdx );
|
||||
|
||||
bool isBlacklisted( Entity::Player& source, const Entity::Player& target ) const;
|
||||
|
||||
private:
|
||||
ptrdiff_t getEntryIndex( Entity::Player& source, uint64_t characterId ) const;
|
||||
|
||||
void sendAddResultPacket( Entity::Player& source, const Entity::PlayerPtr pTarget, uint32_t result );
|
||||
void sendRemoveResultPacket( Entity::Player& source, const Entity::PlayerPtr pTarget, uint32_t result );
|
||||
};
|
||||
}
|
|
@ -14,7 +14,7 @@ bool Sapphire::World::Manager::FriendListMgr::onInviteCreate( Entity::Player& so
|
|||
auto& targetFL = target.getFriendListID();
|
||||
|
||||
// check if player already has been invited or friends
|
||||
if( getEntryIndex( source, target.getCharacterId() ) != -1 )
|
||||
if( isFriend( source, target ) )
|
||||
{
|
||||
// already invited/friends
|
||||
return false;
|
||||
|
@ -41,12 +41,13 @@ bool Sapphire::World::Manager::FriendListMgr::onInviteCreate( Entity::Player& so
|
|||
Common::HierarchyData hierarchy;
|
||||
hierarchy.data.dateAdded = Common::Util::getTimeSeconds();
|
||||
hierarchy.data.group = 0;
|
||||
hierarchy.data.status = Common::HierarchyStatus::SentRequest; // set type for invite sender
|
||||
hierarchy.data.type = Common::HierarchyType::FRIENDLIST;
|
||||
|
||||
// set hierarchy status for invite sender
|
||||
hierarchy.data.status = Common::HierarchyStatus::SentRequest;
|
||||
sourceFLData[ sourceIdx ] = hierarchy;
|
||||
|
||||
// set type for invite receiver
|
||||
// set hierarchy status for invite receiver
|
||||
hierarchy.data.status = Common::HierarchyStatus::ReceivedRequest;
|
||||
targetFLData[ targetIdx ] = hierarchy;
|
||||
|
||||
|
@ -72,6 +73,7 @@ bool Sapphire::World::Manager::FriendListMgr::onInviteAccept( Entity::Player& so
|
|||
auto& sourceFLData = source.getFriendListData();
|
||||
auto& targetFLData = target.getFriendListData();
|
||||
|
||||
// currently, type on hierarchy indicates invite type - since it is no longer an invite, set type to NONE
|
||||
sourceFLData[ sourceIdx ].data.status = Common::HierarchyStatus::Added;
|
||||
sourceFLData[ sourceIdx ].data.type = Common::HierarchyType::NONE_2;
|
||||
targetFLData[ targetIdx ].data.status = Common::HierarchyStatus::Added;
|
||||
|
@ -140,7 +142,12 @@ bool Sapphire::World::Manager::FriendListMgr::onAssignGroup( Entity::Player& sou
|
|||
return true;
|
||||
}
|
||||
|
||||
ptrdiff_t Sapphire::World::Manager::FriendListMgr::getEntryIndex( Entity::Player& source, uint64_t characterId )
|
||||
bool Sapphire::World::Manager::FriendListMgr::isFriend( Entity::Player& source, Entity::Player& target ) const
|
||||
{
|
||||
return getEntryIndex( source, target.getCharacterId() ) != -1;
|
||||
}
|
||||
|
||||
ptrdiff_t Sapphire::World::Manager::FriendListMgr::getEntryIndex( Entity::Player& source, uint64_t characterId ) const
|
||||
{
|
||||
auto& sourceFL = source.getFriendListID();
|
||||
auto sourceInvIt = std::find( std::begin( sourceFL ), std::end( sourceFL ), characterId );
|
||||
|
|
|
@ -19,7 +19,9 @@ namespace Sapphire::World::Manager
|
|||
bool onRemoveFriend( Entity::Player& source, Entity::Player& target );
|
||||
bool onAssignGroup( Entity::Player& source, Entity::Player& target, uint8_t group );
|
||||
|
||||
bool isFriend( Entity::Player& source, Entity::Player& target ) const;
|
||||
|
||||
private:
|
||||
ptrdiff_t getEntryIndex( Entity::Player& source, uint64_t characterId );
|
||||
ptrdiff_t getEntryIndex( Entity::Player& source, uint64_t characterId ) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -58,7 +58,6 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
|||
setZoneHandler( SetProfile, "SetProfile", &GameConnection::setProfileHandler );
|
||||
setZoneHandler( GetProfile, "GetProfile", &GameConnection::getProfileHandler );
|
||||
setZoneHandler( GetSearchComment, "GetSearchComment", &GameConnection::getSearchCommentHandler );
|
||||
setZoneHandler( GetBlacklist, "GetBlacklist", &GameConnection::getBlacklistHandler );
|
||||
setZoneHandler( PcSearch, "PcSearch", &GameConnection::pcSearchHandler );
|
||||
|
||||
setZoneHandler( GetCommonlist, "GetCommonlist", &GameConnection::getCommonlistHandler );
|
||||
|
@ -163,7 +162,9 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
|||
setZoneHandler( FriendlistRemove, "FriendlistRemove", &GameConnection::friendlistRemoveHandler );
|
||||
setZoneHandler( SetFriendlistGroup, "SetFriendlistGroup", &GameConnection::setFriendlistGroupHandler );
|
||||
|
||||
|
||||
setZoneHandler( GetBlacklist, "GetBlacklist", &GameConnection::getBlacklistHandler );
|
||||
setZoneHandler( BlacklistAdd, "BlacklistAdd", &GameConnection::blacklistAddHandler );
|
||||
setZoneHandler( BlacklistRemove, "BlacklistRemove", &GameConnection::blacklistRemoveHandler );
|
||||
}
|
||||
|
||||
Sapphire::Network::GameConnection::~GameConnection() = default;
|
||||
|
|
|
@ -100,8 +100,6 @@ namespace Sapphire::Network
|
|||
|
||||
DECLARE_HANDLER( setLanguageHandler );
|
||||
|
||||
DECLARE_HANDLER( getBlacklistHandler );
|
||||
|
||||
DECLARE_HANDLER( getCommonlistHandler );
|
||||
|
||||
DECLARE_HANDLER( getCommonlistDetailHandler );
|
||||
|
@ -238,7 +236,9 @@ namespace Sapphire::Network
|
|||
DECLARE_HANDLER( friendlistRemoveHandler );
|
||||
DECLARE_HANDLER( setFriendlistGroupHandler );
|
||||
|
||||
|
||||
DECLARE_HANDLER( getBlacklistHandler );
|
||||
DECLARE_HANDLER( blacklistAddHandler );
|
||||
DECLARE_HANDLER( blacklistRemoveHandler );
|
||||
};
|
||||
|
||||
}
|
||||
|
|
55
src/world/Network/Handlers/BlacklistHandler.cpp
Normal file
55
src/world/Network/Handlers/BlacklistHandler.cpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include <Common.h>
|
||||
#include <Network/CommonNetwork.h>
|
||||
#include <Network/GamePacket.h>
|
||||
|
||||
#include <Network/PacketContainer.h>
|
||||
#include <Exd/ExdData.h>
|
||||
#include <Service.h>
|
||||
#include <Network/PacketDef/Zone/ClientZoneDef.h>
|
||||
#include <Network/PacketDef/Zone/ServerZoneDef.h>
|
||||
|
||||
#include "Manager/BlacklistMgr.h"
|
||||
|
||||
#include "Network/GameConnection.h"
|
||||
|
||||
#include "Actor/Player.h"
|
||||
#include "WorldServer.h"
|
||||
|
||||
using namespace Sapphire::Common;
|
||||
using namespace Sapphire::Network::Packets;
|
||||
using namespace Sapphire::Network::Packets::WorldPackets;
|
||||
using namespace Sapphire::World::Manager;
|
||||
|
||||
void Sapphire::Network::GameConnection::getBlacklistHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
auto& blMgr = Common::Service< Sapphire::World::Manager::BlacklistMgr >::ref();
|
||||
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcGetBlacklist >( inPacket );
|
||||
auto& data = packet.data();
|
||||
|
||||
blMgr.onGetBlacklistPage( player, data.RequestKey, data.NextIndex );
|
||||
}
|
||||
|
||||
void Sapphire::Network::GameConnection::blacklistAddHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
auto& blMgr = Common::Service< Sapphire::World::Manager::BlacklistMgr >::ref();
|
||||
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcBlacklistAdd >( inPacket );
|
||||
auto& data = packet.data();
|
||||
|
||||
std::string targetName( data.TargetCharacterName );
|
||||
|
||||
blMgr.onAddCharacter( player, targetName );
|
||||
}
|
||||
|
||||
void Sapphire::Network::GameConnection::blacklistRemoveHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
auto& blMgr = Common::Service< Sapphire::World::Manager::BlacklistMgr >::ref();
|
||||
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcBlacklistRemove >( inPacket );
|
||||
auto& data = packet.data();
|
||||
|
||||
std::string targetName( data.TargetCharacterName );
|
||||
|
||||
blMgr.onRemoveCharacter( player, targetName );
|
||||
}
|
|
@ -75,16 +75,16 @@ void Sapphire::Network::GameConnection::getCommonlistHandler( const Packets::FFX
|
|||
// TODO: possibly move lambda func to util
|
||||
auto& server = Common::Service< World::WorldServer >::ref();
|
||||
|
||||
const size_t itemsPerPage = 10;
|
||||
|
||||
// this func paginates any commonlist entry, associating them with online player data and hierarchy ID (optional)
|
||||
auto generateEntries = [&]( const auto& idVec, size_t offset, const std::vector< Common::HierarchyData >& hierarchyVec ) -> std::vector< PlayerEntry >
|
||||
{
|
||||
std::vector< PlayerEntry > entries;
|
||||
|
||||
const size_t itemsPerPage = 10;
|
||||
|
||||
for( size_t i = offset; i < offset + 10; ++i )
|
||||
for( size_t i = offset; i < offset + itemsPerPage; ++i )
|
||||
{
|
||||
if( idVec.size() <= offset + i )
|
||||
if( idVec.size() <= i )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ void Sapphire::Network::GameConnection::getCommonlistHandler( const Packets::FFX
|
|||
memcpy( &listPacket->data().entries[ 0 ], page.data(), sizeof( PlayerEntry ) * page.size() );
|
||||
|
||||
listPacket->data().Index = offset;
|
||||
listPacket->data().NextIndex = isLast ? 0 : data.NextIndex + 10;
|
||||
listPacket->data().NextIndex = isLast ? 0 : data.NextIndex + itemsPerPage;
|
||||
|
||||
queueOutPacket( listPacket );
|
||||
}
|
|
@ -35,7 +35,7 @@ void Sapphire::Network::GameConnection::friendlistRemoveHandler( const Packets::
|
|||
|
||||
flMgr.onRemoveFriend( player, *target );
|
||||
|
||||
auto replyPacket = makeZonePacket< WorldPackets::Server::FFXIVIpcFriendlistRemoveResult >( player.getId() );
|
||||
auto replyPacket = makeZonePacket< Server::FFXIVIpcFriendlistRemoveResult >( player.getId() );
|
||||
auto& replyData = replyPacket->data();
|
||||
|
||||
replyData.RemovedCharacterID = target->getCharacterId();
|
||||
|
|
|
@ -388,8 +388,6 @@ void Sapphire::Network::GameConnection::newDiscoveryHandler( const Packets::FFXI
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Sapphire::Network::GameConnection::loginHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||
|
@ -398,24 +396,6 @@ void Sapphire::Network::GameConnection::loginHandler( const Packets::FFXIVARR_PA
|
|||
teriMgr.joinWorld( player );
|
||||
}
|
||||
|
||||
|
||||
void Sapphire::Network::GameConnection::getBlacklistHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||
{
|
||||
const auto packet = ZoneChannelPacket< Client::FFXIVIpcGetBlacklist >( inPacket );
|
||||
auto& data = packet.data();
|
||||
|
||||
auto blackListPacket = makeZonePacket< FFXIVIpcGetBlacklistResult >( player.getId() );
|
||||
blackListPacket->data().Index = data.NextIndex;
|
||||
blackListPacket->data().RequestKey = data.RequestKey;
|
||||
|
||||
// TODO: Fill with actual blacklist data
|
||||
//blackListPacket.data().entry[0].contentId = 1;
|
||||
//sprintf( blackListPacket.data().entry[0].name, "Test Test" );
|
||||
|
||||
queueOutPacket( blackListPacket );
|
||||
}
|
||||
|
||||
|
||||
void Sapphire::Network::GameConnection::syncHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||
Entity::Player& player )
|
||||
{
|
||||
|
@ -432,7 +412,6 @@ void Sapphire::Network::GameConnection::syncHandler( const Packets::FFXIVARR_PAC
|
|||
pSession->setLastPing( Common::Util::getTimeSeconds() );
|
||||
}
|
||||
|
||||
|
||||
void Sapphire::Network::GameConnection::setLanguageHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||
Entity::Player& player )
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "Manager/QuestMgr.h"
|
||||
#include "Manager/PartyMgr.h"
|
||||
#include "Manager/FriendListMgr.h"
|
||||
#include "Manager/BlacklistMgr.h"
|
||||
|
||||
#include "ContentFinder/ContentFinder.h"
|
||||
|
||||
|
@ -241,6 +242,7 @@ void Sapphire::World::WorldServer::run( int32_t argc, char* argv[] )
|
|||
auto pQuestMgr = std::make_shared< Manager::QuestMgr >();
|
||||
auto pPartyMgr = std::make_shared< Manager::PartyMgr >();
|
||||
auto pFriendMgr = std::make_shared< Manager::FriendListMgr >();
|
||||
auto pBlacklistMgr = std::make_shared< Manager::BlacklistMgr >();
|
||||
auto contentFinder = std::make_shared< ContentFinder >();
|
||||
|
||||
Common::Service< DebugCommandMgr >::set( pDebugCom );
|
||||
|
@ -253,6 +255,7 @@ void Sapphire::World::WorldServer::run( int32_t argc, char* argv[] )
|
|||
Common::Service< Manager::QuestMgr >::set( pQuestMgr );
|
||||
Common::Service< Manager::PartyMgr >::set( pPartyMgr );
|
||||
Common::Service< Manager::FriendListMgr >::set( pFriendMgr );
|
||||
Common::Service< Manager::BlacklistMgr >::set( pBlacklistMgr );
|
||||
Common::Service< ContentFinder >::set( contentFinder );
|
||||
|
||||
auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref();
|
||||
|
@ -558,7 +561,7 @@ Sapphire::Entity::PlayerPtr Sapphire::World::WorldServer::loadPlayer( uint32_t e
|
|||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto res = db.query( "SELECT CharacterId FROM charainfo WHERE EntityId = " + std::to_string( entityId ) );
|
||||
if( !res->next() )
|
||||
if( !res || !res->next() )
|
||||
return nullptr;
|
||||
|
||||
uint64_t characterId = res->getUInt64( 1 );
|
||||
|
@ -575,7 +578,7 @@ Sapphire::Entity::PlayerPtr Sapphire::World::WorldServer::loadPlayer( const std:
|
|||
{
|
||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||
auto res = db.query( "SELECT CharacterId FROM charainfo WHERE Name = " + playerName );
|
||||
if( !res->next() )
|
||||
if( !res || !res->next() )
|
||||
return nullptr;
|
||||
|
||||
uint64_t characterId = res->getUInt64( 1 );
|
||||
|
|
Loading…
Add table
Reference in a new issue