From e07b182a19c00bee0db87a11bb68073e71caff26 Mon Sep 17 00:00:00 2001 From: Alice Ogeda Date: Mon, 13 Dec 2021 22:36:29 -0300 Subject: [PATCH] add blacklist mgr + handlers + paging; --- src/api/PlayerMinimal.cpp | 11 +- src/common/Database/ZoneDbConnection.cpp | 15 ++ src/common/Database/ZoneDbConnection.h | 4 + .../Network/PacketDef/Zone/ClientZoneDef.h | 11 ++ src/world/Actor/Player.cpp | 10 +- src/world/Actor/Player.h | 12 +- src/world/Actor/PlayerSql.cpp | 43 ++++- src/world/Manager/BlacklistMgr.cpp | 151 ++++++++++++++++++ src/world/Manager/BlacklistMgr.h | 24 +++ src/world/Manager/FriendListMgr.cpp | 7 +- src/world/Manager/FriendListMgr.h | 2 + src/world/Network/GameConnection.cpp | 5 +- src/world/Network/GameConnection.h | 6 +- .../Network/Handlers/BlacklistHandler.cpp | 104 ++++++++++++ .../Network/Handlers/CommonListHandler.cpp | 8 +- .../Network/Handlers/FriendListHandlers.cpp | 2 +- src/world/Network/Handlers/PacketHandlers.cpp | 21 --- src/world/WorldServer.cpp | 7 +- 18 files changed, 400 insertions(+), 43 deletions(-) create mode 100644 src/world/Manager/BlacklistMgr.cpp create mode 100644 src/world/Manager/BlacklistMgr.h create mode 100644 src/world/Network/Handlers/BlacklistHandler.cpp diff --git a/src/api/PlayerMinimal.cpp b/src/api/PlayerMinimal.cpp index 2a82747b..41b6c919 100644 --- a/src/api/PlayerMinimal.cpp +++ b/src/api/PlayerMinimal.cpp @@ -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 diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 9b07ae09..9e2c671c 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -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, " diff --git a/src/common/Database/ZoneDbConnection.h b/src/common/Database/ZoneDbConnection.h index bc51e3e5..7a1c3b41 100644 --- a/src/common/Database/ZoneDbConnection.h +++ b/src/common/Database/ZoneDbConnection.h @@ -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, diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 4d699aba..9815aa2e 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -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 > { diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 5221115f..bc64228c 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -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 ); diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 7f978814..6cd2ea0c 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -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; diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index 379070f8..f9dee2eb 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -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(); diff --git a/src/world/Manager/BlacklistMgr.cpp b/src/world/Manager/BlacklistMgr.cpp new file mode 100644 index 00000000..e1df89fa --- /dev/null +++ b/src/world/Manager/BlacklistMgr.cpp @@ -0,0 +1,151 @@ +#include +#include + +#include +#include +#include + +#include +#include + +#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, Entity::Player& target ) +{ + // add target to blacklist + + if( source.getCharacterId() == target.getCharacterId() ) + { + // can't add self to blacklist + return false; + } + + if( isBlacklisted( source, target ) ) + { + // target already added to blacklist + 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(); + + // 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, Entity::Player& target ) +{ + // remove target from blacklist + + auto sourceIdx = getEntryIndex( source, target.getCharacterId() ); + + if( !isBlacklisted( source, target ) ) + { + // target not in blacklist + return false; + } + + // set target slot to 0 + auto& sourceBL = source.getBlacklistID(); + sourceBL[sourceIdx] = 0; + source.updateDbBlacklist(); + + 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 valid entries left + + 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, Entity::Player& target ) +{ + return getEntryIndex( source, target.getCharacterId() ) != -1; +} + +ptrdiff_t Sapphire::World::Manager::BlacklistMgr::getEntryIndex( Entity::Player& source, uint64_t characterId ) +{ + 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 ); +} \ No newline at end of file diff --git a/src/world/Manager/BlacklistMgr.h b/src/world/Manager/BlacklistMgr.h new file mode 100644 index 00000000..e88383ee --- /dev/null +++ b/src/world/Manager/BlacklistMgr.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include "ForwardsZone.h" + +namespace Sapphire::World::Manager +{ + class BlacklistMgr + { + public: + BlacklistMgr() = default; + + bool onAddCharacter( Entity::Player& source, Entity::Player& target ); + bool onRemoveCharacter( Entity::Player& source, Entity::Player& target ); + + bool onGetBlacklistPage( Entity::Player& source, uint8_t key, uint8_t nextIdx ); + + bool isBlacklisted( Entity::Player& source, Entity::Player& target ); + + private: + ptrdiff_t getEntryIndex( Entity::Player& source, uint64_t characterId ); + }; +} diff --git a/src/world/Manager/FriendListMgr.cpp b/src/world/Manager/FriendListMgr.cpp index d5e8d468..d6d3a762 100644 --- a/src/world/Manager/FriendListMgr.cpp +++ b/src/world/Manager/FriendListMgr.cpp @@ -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; @@ -140,6 +140,11 @@ bool Sapphire::World::Manager::FriendListMgr::onAssignGroup( Entity::Player& sou return true; } +bool Sapphire::World::Manager::FriendListMgr::isFriend( Entity::Player& source, Entity::Player& target ) +{ + return getEntryIndex( source, target.getCharacterId() ) != -1; +} + ptrdiff_t Sapphire::World::Manager::FriendListMgr::getEntryIndex( Entity::Player& source, uint64_t characterId ) { auto& sourceFL = source.getFriendListID(); diff --git a/src/world/Manager/FriendListMgr.h b/src/world/Manager/FriendListMgr.h index 7bf32d40..cf6dd17e 100644 --- a/src/world/Manager/FriendListMgr.h +++ b/src/world/Manager/FriendListMgr.h @@ -19,6 +19,8 @@ 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 ); + private: ptrdiff_t getEntryIndex( Entity::Player& source, uint64_t characterId ); }; diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index c3c3c0ba..773a47bc 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -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; diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index e6b68cee..b4d9c765 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -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 ); }; } diff --git a/src/world/Network/Handlers/BlacklistHandler.cpp b/src/world/Network/Handlers/BlacklistHandler.cpp new file mode 100644 index 00000000..01c7a5e3 --- /dev/null +++ b/src/world/Network/Handlers/BlacklistHandler.cpp @@ -0,0 +1,104 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#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& server = Common::Service< Sapphire::World::WorldServer >::ref(); + auto& blMgr = Common::Service< Sapphire::World::Manager::BlacklistMgr >::ref(); + + const auto packet = ZoneChannelPacket< Client::FFXIVIpcGetBlacklist >( inPacket ); + auto& data = packet.data(); + + // TODO: remove this paging test!! + /* + for( size_t i = 0; i < 200; ++i ) + { + player.getBlacklistID()[i] = player.getCharacterId(); + } + */ + + blMgr.onGetBlacklistPage( player, data.RequestKey, data.NextIndex ); +} + +void Sapphire::Network::GameConnection::blacklistAddHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) +{ + auto& server = Common::Service< Sapphire::World::WorldServer >::ref(); + auto& blMgr = Common::Service< Sapphire::World::Manager::BlacklistMgr >::ref(); + + const auto packet = ZoneChannelPacket< Client::FFXIVIpcBlacklistAdd >( inPacket ); + auto& data = packet.data(); + + auto resultPacket = makeZonePacket< Server::FFXIVIpcBlacklistAddResult >( player.getId() ); + + std::string targetName( data.TargetCharacterName ); + + auto target = server.getPlayer( targetName ); + + if( !target || !blMgr.onAddCharacter( player, *target ) ) + { + resultPacket->data().Result = 0x7; // TODO: find the correct value for each invalid arg + } + else + { + Server::BlacklistCharacter blChar; + blChar.CharacterID = target->getCharacterId(); + strcpy( blChar.CharacterName, target->getName().c_str() ); + + resultPacket->data().AddedCharacter = blChar; + resultPacket->data().Identity = target->getGender(); + resultPacket->data().Result = 0; + } + + queueOutPacket( resultPacket ); +} + +void Sapphire::Network::GameConnection::blacklistRemoveHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) +{ + auto& server = Common::Service< Sapphire::World::WorldServer >::ref(); + auto& blMgr = Common::Service< Sapphire::World::Manager::BlacklistMgr >::ref(); + + const auto packet = ZoneChannelPacket< Client::FFXIVIpcBlacklistRemove >( inPacket ); + auto& data = packet.data(); + + auto resultPacket = makeZonePacket< Server::FFXIVIpcBlacklistRemoveResult >( player.getId() ); + + std::string targetName( data.TargetCharacterName ); + + auto target = server.getPlayer( targetName ); + + if( !target || !blMgr.onRemoveCharacter( player, *target ) ) + { + resultPacket->data().Result = 0x7; // TODO: find the correct value for each invalid arg + } + else + { + Server::BlacklistCharacter blChar; + blChar.CharacterID = target->getCharacterId(); + strcpy( blChar.CharacterName, target->getName().c_str() ); + + resultPacket->data().RemovedCharacter = blChar; + resultPacket->data().Identity = target->getGender(); + resultPacket->data().Result = 0; + } + + queueOutPacket( resultPacket ); +} \ No newline at end of file diff --git a/src/world/Network/Handlers/CommonListHandler.cpp b/src/world/Network/Handlers/CommonListHandler.cpp index e75c36f3..00ec9245 100644 --- a/src/world/Network/Handlers/CommonListHandler.cpp +++ b/src/world/Network/Handlers/CommonListHandler.cpp @@ -75,14 +75,14 @@ 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 ) { @@ -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 ); } \ No newline at end of file diff --git a/src/world/Network/Handlers/FriendListHandlers.cpp b/src/world/Network/Handlers/FriendListHandlers.cpp index 7ef4a7ab..df49dcf7 100644 --- a/src/world/Network/Handlers/FriendListHandlers.cpp +++ b/src/world/Network/Handlers/FriendListHandlers.cpp @@ -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(); diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index af24371a..c61a790a 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -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 ) { diff --git a/src/world/WorldServer.cpp b/src/world/WorldServer.cpp index 560927eb..c9ab8879 100644 --- a/src/world/WorldServer.cpp +++ b/src/world/WorldServer.cpp @@ -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 );