2020-09-19 19:07:09 +00:00
# include "CNShardServer.hpp"
# include "CNStructs.hpp"
# include "ChatManager.hpp"
# include "PlayerManager.hpp"
# include "BuddyManager.hpp"
2020-11-08 17:42:27 +00:00
# include "Database.hpp"
2020-09-19 19:07:09 +00:00
2020-09-23 17:52:21 +00:00
# include <iostream>
# include <chrono>
2020-09-19 19:07:09 +00:00
# include <algorithm>
2020-09-23 17:52:21 +00:00
# include <thread>
2020-09-19 19:07:09 +00:00
void BuddyManager : : init ( ) {
2020-10-05 00:03:13 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_REQUEST_MAKE_BUDDY , requestBuddy ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_FIND_NAME_MAKE_BUDDY , reqBuddyByName ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_ACCEPT_MAKE_BUDDY , reqAcceptBuddy ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_FIND_NAME_ACCEPT_BUDDY , reqFindNameBuddyAccept ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_SEND_BUDDY_FREECHAT_MESSAGE , reqBuddyFreechat ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_SEND_BUDDY_MENUCHAT_MESSAGE , reqBuddyMenuchat ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_GET_BUDDY_STATE , reqPktGetBuddyState ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_SET_BUDDY_BLOCK , reqBuddyBlock ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_REMOVE_BUDDY , reqBuddyDelete ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_BUDDY_WARP , reqBuddyWarp ) ;
2020-09-19 19:07:09 +00:00
}
2020-11-08 17:42:27 +00:00
// Refresh buddy list
void BuddyManager : : refreshBuddyList ( CNSocket * sock ) {
Player * plr = PlayerManager : : getPlayer ( sock ) ;
int buddyCnt = Database : : getNumBuddies ( plr ) ;
if ( ! validOutVarPacket ( sizeof ( sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC ) , buddyCnt , sizeof ( sBuddyBaseInfo ) ) ) {
std : : cout < < " [WARN] bad sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC packet size \n " ;
return ;
}
// initialize response struct
size_t resplen = sizeof ( sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC ) + buddyCnt * sizeof ( sBuddyBaseInfo ) ;
uint8_t respbuf [ CN_PACKET_BUFFER_SIZE ] ;
memset ( respbuf , 0 , resplen ) ;
sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC * resp = ( sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC * ) respbuf ;
sBuddyBaseInfo * respdata = ( sBuddyBaseInfo * ) ( respbuf + sizeof ( sP_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC ) ) ;
// base response fields
resp - > iBuddyCnt = buddyCnt ;
resp - > iID = plr - > iID ;
resp - > iPCUID = plr - > PCStyle . iPC_UID ;
resp - > iListNum = 0 ; // ???
int buddyIndex = 0 ;
for ( int i = 0 ; i < 50 ; i + + ) {
int64_t buddyID = plr - > buddyIDs [ i ] ;
if ( buddyID ! = 0 ) {
sBuddyBaseInfo buddyInfo = { } ;
Database : : DbPlayer buddyPlayerData = Database : : getDbPlayerById ( buddyID ) ;
buddyInfo . bBlocked = 0 ;
buddyInfo . bFreeChat = 1 ;
buddyInfo . iGender = buddyPlayerData . Gender ;
buddyInfo . iID = buddyID ;
buddyInfo . iPCUID = buddyID ;
buddyInfo . iNameCheckFlag = buddyPlayerData . NameCheck ;
buddyInfo . iPCState = buddyPlayerData . PCState ;
U8toU16 ( buddyPlayerData . FirstName , buddyInfo . szFirstName , sizeof ( buddyInfo . szFirstName ) ) ;
U8toU16 ( buddyPlayerData . LastName , buddyInfo . szLastName , sizeof ( buddyInfo . szLastName ) ) ;
respdata [ buddyIndex ] = buddyInfo ;
buddyIndex + + ;
}
}
sock - > sendPacket ( ( void * ) respbuf , P_FE2CL_REP_PC_BUDDYLIST_INFO_SUCC , resplen ) ;
}
2020-10-19 17:26:14 +00:00
// Buddy request
2020-09-19 19:07:09 +00:00
void BuddyManager : : requestBuddy ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_REQUEST_MAKE_BUDDY ) )
return ; // malformed packet
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
sP_CL2FE_REQ_REQUEST_MAKE_BUDDY * req = ( sP_CL2FE_REQ_REQUEST_MAKE_BUDDY * ) data - > buf ;
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
Player * plr = PlayerManager : : getPlayer ( sock ) ;
Player * otherPlr = PlayerManager : : getPlayerFromID ( req - > iBuddyID ) ;
2020-11-08 04:11:56 +00:00
if ( getAvailableBuddySlot ( plr ) = = - 1 | | getAvailableBuddySlot ( otherPlr ) = = - 1 )
2020-10-27 15:28:37 +00:00
{
INITSTRUCT ( sP_FE2CL_REP_REQUEST_MAKE_BUDDY_FAIL , failResp ) ;
sock - > sendPacket ( ( void * ) & failResp , P_FE2CL_REP_REQUEST_MAKE_BUDDY_FAIL , sizeof ( sP_FE2CL_REP_REQUEST_MAKE_BUDDY_FAIL ) ) ;
return ;
}
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
CNSocket * otherSock = PlayerManager : : getSockFromID ( otherPlr - > iID ) ;
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
INITSTRUCT ( sP_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC , resp ) ;
INITSTRUCT ( sP_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC_TO_ACCEPTER , otherResp ) ;
resp . iRequestID = plr - > iID ;
resp . iBuddyID = req - > iBuddyID ;
resp . iBuddyPCUID = req - > iBuddyPCUID ;
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
otherResp . iRequestID = plr - > iID ;
otherResp . iBuddyID = req - > iBuddyID ;
memcpy ( otherResp . szFirstName , plr - > PCStyle . szFirstName , sizeof ( plr - > PCStyle . szFirstName ) ) ;
memcpy ( otherResp . szLastName , plr - > PCStyle . szLastName , sizeof ( plr - > PCStyle . szLastName ) ) ;
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
std : : cout < < " Buddy ID: " < < req - > iBuddyID < < std : : endl ;
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC ) ) ;
otherSock - > sendPacket ( ( void * ) & otherResp , P_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC_TO_ACCEPTER , sizeof ( sP_FE2CL_REP_REQUEST_MAKE_BUDDY_SUCC_TO_ACCEPTER ) ) ;
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Sending buddy request by player name
2020-09-19 19:07:09 +00:00
void BuddyManager : : reqBuddyByName ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_FIND_NAME_MAKE_BUDDY ) ) {
return ; // malformed packet
}
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
sP_CL2FE_REQ_PC_FIND_NAME_MAKE_BUDDY * pkt = ( sP_CL2FE_REQ_PC_FIND_NAME_MAKE_BUDDY * ) data - > buf ;
Player * plrReq = PlayerManager : : getPlayer ( sock ) ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC , resp ) ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
CNSocket * otherSock = sock ;
2020-09-19 19:07:09 +00:00
2020-10-19 17:26:14 +00:00
int sizeOfRes = sizeof ( pkt - > szFirstName ) / 9 ; // Maximum size of a player's first name
int sizeOfLNRes = sizeof ( pkt - > szLastName ) / 17 ; // Maximum size of a player's last name
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
for ( auto pair : PlayerManager : : players ) {
int sizeOfReq = sizeof ( pair . second . plr - > PCStyle . szFirstName ) / 9 ;
int sizeOfLNReq = sizeof ( pair . second . plr - > PCStyle . szLastName ) / 17 ;
2020-10-27 15:28:37 +00:00
if ( BuddyManager : : NameCheck ( pair . second . plr - > PCStyle . szFirstName , pkt - > szFirstName , sizeOfReq , sizeOfRes ) = = true & & BuddyManager : : NameCheck ( pair . second . plr - > PCStyle . szLastName , pkt - > szLastName , sizeOfLNReq , sizeOfLNRes ) = = true ) { // This long line of gorgeous parameters is to check if the player's name matches :eyes:
2020-10-05 00:03:13 +00:00
otherSock = pair . first ;
2020-09-26 22:16:15 +00:00
break ;
2020-10-05 00:03:13 +00:00
}
}
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
resp . iPCUID = plrReq - > PCStyle . iPC_UID ;
resp . iNameCheckFlag = plrReq - > PCStyle . iNameCheck ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
memcpy ( resp . szFirstName , plrReq - > PCStyle . szFirstName , sizeof ( plrReq - > PCStyle . szFirstName ) ) ;
memcpy ( resp . szLastName , plrReq - > PCStyle . szLastName , sizeof ( plrReq - > PCStyle . szLastName ) ) ;
otherSock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_PC_FIND_NAME_MAKE_BUDDY_SUCC ) ) ;
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Accepting buddy request
2020-09-19 19:07:09 +00:00
void BuddyManager : : reqAcceptBuddy ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_ACCEPT_MAKE_BUDDY ) )
return ; // malformed packet
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
sP_CL2FE_REQ_ACCEPT_MAKE_BUDDY * req = ( sP_CL2FE_REQ_ACCEPT_MAKE_BUDDY * ) data - > buf ;
Player * plr = PlayerManager : : getPlayer ( sock ) ;
Player * otherPlr = PlayerManager : : getPlayerFromID ( req - > iBuddyID ) ;
2020-09-19 19:07:09 +00:00
2020-10-27 15:28:37 +00:00
CNSocket * otherSock = PlayerManager : : getSockFromID ( otherPlr - > iID ) ;
2020-11-08 04:11:56 +00:00
int slotA = getAvailableBuddySlot ( plr ) ;
int slotB = getAvailableBuddySlot ( otherPlr ) ;
if ( slotA = = - 1 | | slotB = = - 1 )
return ; // sanity check
if ( req - > iAcceptFlag = = 1 & & plr - > iID ! = otherPlr - > iID )
2020-10-27 15:28:37 +00:00
{
2020-11-08 04:11:56 +00:00
INITSTRUCT ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , resp ) ;
// A to B
resp . iBuddySlot = slotA ;
resp . BuddyInfo . iID = otherPlr - > iID ;
resp . BuddyInfo . iPCUID = otherPlr - > PCStyle . iPC_UID ;
resp . BuddyInfo . iPCState = 1 ; // assumed to be online
resp . BuddyInfo . bBlocked = 0 ; // not blocked by default
resp . BuddyInfo . iGender = otherPlr - > PCStyle . iGender ; // shows the other player's gender
resp . BuddyInfo . bFreeChat = 1 ; // shows whether or not the other player has freechat on (hardcoded for now)
resp . BuddyInfo . iNameCheckFlag = otherPlr - > PCStyle . iNameCheck ;
memcpy ( resp . BuddyInfo . szFirstName , otherPlr - > PCStyle . szFirstName , sizeof ( resp . BuddyInfo . szFirstName ) ) ;
memcpy ( resp . BuddyInfo . szLastName , otherPlr - > PCStyle . szLastName , sizeof ( resp . BuddyInfo . szLastName ) ) ;
2020-10-05 00:03:13 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC ) ) ;
2020-11-08 04:11:56 +00:00
plr - > buddyIDs [ slotA ] = otherPlr - > PCStyle . iPC_UID ;
//std::cout << "Buddy's ID: " << plr->buddyIDs[slotA] << std::endl;
// B to A, using the same struct
resp . iBuddySlot = slotB ;
resp . BuddyInfo . iID = plr - > iID ;
resp . BuddyInfo . iPCUID = plr - > PCStyle . iPC_UID ;
resp . BuddyInfo . iPCState = 1 ;
resp . BuddyInfo . bBlocked = 0 ;
resp . BuddyInfo . iGender = plr - > PCStyle . iGender ;
resp . BuddyInfo . bFreeChat = 1 ;
resp . BuddyInfo . iNameCheckFlag = plr - > PCStyle . iNameCheck ;
memcpy ( resp . BuddyInfo . szFirstName , plr - > PCStyle . szFirstName , sizeof ( resp . BuddyInfo . szFirstName ) ) ;
memcpy ( resp . BuddyInfo . szLastName , plr - > PCStyle . szLastName , sizeof ( resp . BuddyInfo . szLastName ) ) ;
otherSock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC ) ) ;
otherPlr - > buddyIDs [ slotB ] = plr - > PCStyle . iPC_UID ;
//std::cout << "Buddy's ID: " << plr->buddyIDs[slotB] << std::endl;
2020-10-27 15:28:37 +00:00
}
else
{
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_FAIL , declineResp ) ;
2020-10-19 17:26:14 +00:00
declineResp . iErrorCode = 6 ; // Buddy declined notification
2020-10-27 15:28:37 +00:00
declineResp . iBuddyID = req - > iBuddyID ;
declineResp . iBuddyPCUID = req - > iBuddyPCUID ;
2020-10-05 00:03:13 +00:00
2020-10-27 15:28:37 +00:00
otherSock - > sendPacket ( ( void * ) & declineResp , P_FE2CL_REP_ACCEPT_MAKE_BUDDY_FAIL , sizeof ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_FAIL ) ) ;
2020-10-05 00:03:13 +00:00
}
2020-10-27 15:28:37 +00:00
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Accepting buddy request from the find name request
2020-09-19 19:07:09 +00:00
void BuddyManager : : reqFindNameBuddyAccept ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_FIND_NAME_ACCEPT_BUDDY ) ) {
return ; // malformed packet
}
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
sP_CL2FE_REQ_PC_FIND_NAME_ACCEPT_BUDDY * pkt = ( sP_CL2FE_REQ_PC_FIND_NAME_ACCEPT_BUDDY * ) data - > buf ;
2020-09-19 19:07:09 +00:00
2020-11-08 04:11:56 +00:00
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-09-28 18:11:13 +00:00
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , resp ) ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
CNSocket * otherSock = sock ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
int sizeOfRes = sizeof ( pkt - > szFirstName ) / 9 ;
int sizeOfLNRes = sizeof ( pkt - > szLastName ) / 17 ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
for ( auto pair : PlayerManager : : players ) {
int sizeOfReq = sizeof ( pair . second . plr - > PCStyle . szFirstName ) / 9 ;
int sizeOfLNReq = sizeof ( pair . second . plr - > PCStyle . szLastName ) / 17 ;
2020-10-27 15:28:37 +00:00
if ( BuddyManager : : NameCheck ( pair . second . plr - > PCStyle . szFirstName , pkt - > szFirstName , sizeOfReq , sizeOfRes ) = = true & & BuddyManager : : NameCheck ( pair . second . plr - > PCStyle . szLastName , pkt - > szLastName , sizeOfLNReq , sizeOfLNRes ) = = true ) {
2020-10-05 00:03:13 +00:00
otherSock = pair . first ;
2020-09-26 22:16:15 +00:00
break ;
2020-10-05 00:03:13 +00:00
}
}
2020-11-08 04:11:56 +00:00
Player * otherPlr = PlayerManager : : getPlayer ( otherSock ) ;
int slotA = getAvailableBuddySlot ( plr ) ;
int slotB = getAvailableBuddySlot ( otherPlr ) ;
if ( slotA = = - 1 | | slotB = = - 1 )
return ; // sanity check
if ( pkt - > iAcceptFlag = = 1 & & plr - > iID ! = otherPlr - > iID ) {
INITSTRUCT ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , resp ) ;
// A to B
resp . iBuddySlot = slotA ;
resp . BuddyInfo . iID = otherPlr - > iID ;
resp . BuddyInfo . iPCUID = otherPlr - > PCStyle . iPC_UID ;
resp . BuddyInfo . iPCState = 1 ; // assumed to be online
resp . BuddyInfo . bBlocked = 0 ; // not blocked by default
resp . BuddyInfo . iGender = otherPlr - > PCStyle . iGender ; // shows the other player's gender
resp . BuddyInfo . bFreeChat = 1 ; // shows whether or not the other player has freechat on (hardcoded for now)
resp . BuddyInfo . iNameCheckFlag = otherPlr - > PCStyle . iNameCheck ;
memcpy ( resp . BuddyInfo . szFirstName , otherPlr - > PCStyle . szFirstName , sizeof ( resp . BuddyInfo . szFirstName ) ) ;
memcpy ( resp . BuddyInfo . szLastName , otherPlr - > PCStyle . szLastName , sizeof ( resp . BuddyInfo . szLastName ) ) ;
2020-10-05 00:03:13 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC ) ) ;
2020-11-08 04:11:56 +00:00
plr - > buddyIDs [ slotA ] = otherPlr - > PCStyle . iPC_UID ;
//std::cout << "Buddy's ID: " << plr->buddyIDs[slotA] << std::endl;
// B to A, using the same struct
resp . iBuddySlot = slotB ;
resp . BuddyInfo . iID = plr - > iID ;
resp . BuddyInfo . iPCUID = plr - > PCStyle . iPC_UID ;
resp . BuddyInfo . iPCState = 1 ;
resp . BuddyInfo . bBlocked = 0 ;
resp . BuddyInfo . iGender = plr - > PCStyle . iGender ;
resp . BuddyInfo . bFreeChat = 1 ;
resp . BuddyInfo . iNameCheckFlag = plr - > PCStyle . iNameCheck ;
memcpy ( resp . BuddyInfo . szFirstName , plr - > PCStyle . szFirstName , sizeof ( resp . BuddyInfo . szFirstName ) ) ;
memcpy ( resp . BuddyInfo . szLastName , plr - > PCStyle . szLastName , sizeof ( resp . BuddyInfo . szLastName ) ) ;
otherSock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_SUCC ) ) ;
otherPlr - > buddyIDs [ slotB ] = plr - > PCStyle . iPC_UID ;
//std::cout << "Buddy's ID: " << plr->buddyIDs[slotB] << std::endl;
}
2020-10-27 15:28:37 +00:00
else
{
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_FAIL , declineResp ) ;
2020-10-19 17:26:14 +00:00
declineResp . iErrorCode = 6 ; // Buddy declined notification
2020-10-05 00:03:13 +00:00
declineResp . iBuddyPCUID = pkt - > iBuddyPCUID ;
otherSock - > sendPacket ( ( void * ) & declineResp , P_FE2CL_REP_ACCEPT_MAKE_BUDDY_FAIL , sizeof ( sP_FE2CL_REP_ACCEPT_MAKE_BUDDY_FAIL ) ) ;
}
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Buddy freechatting
2020-09-19 19:07:09 +00:00
void BuddyManager : : reqBuddyFreechat ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_SEND_BUDDY_FREECHAT_MESSAGE ) )
return ; // malformed packet
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
sP_CL2FE_REQ_SEND_BUDDY_FREECHAT_MESSAGE * pkt = ( sP_CL2FE_REQ_SEND_BUDDY_FREECHAT_MESSAGE * ) data - > buf ;
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC , resp ) ;
2020-09-19 19:07:09 +00:00
2020-11-08 04:11:56 +00:00
CNSocket * otherSock = PlayerManager : : getSockFromID ( pkt - > iBuddyPCUID ) ;
if ( otherSock = = nullptr )
return ; // buddy offline
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
resp . iFromPCUID = plr - > PCStyle . iPC_UID ;
resp . iToPCUID = pkt - > iBuddyPCUID ;
resp . iEmoteCode = pkt - > iEmoteCode ;
2020-11-08 18:31:10 +00:00
std : : string fullChat = ChatManager : : sanitizeText ( U16toU8 ( pkt - > szFreeChat ) ) ;
U8toU16 ( fullChat , ( char16_t * ) & resp . szFreeChat , sizeof ( resp . szFreeChat ) ) ;
2020-11-08 04:11:56 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC , sizeof ( sP_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC ) ) ; // confirm send to sender
otherSock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC , sizeof ( sP_FE2CL_REP_SEND_BUDDY_FREECHAT_MESSAGE_SUCC ) ) ; // broadcast send to receiver
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Buddy menuchat
2020-09-19 19:07:09 +00:00
void BuddyManager : : reqBuddyMenuchat ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_SEND_BUDDY_MENUCHAT_MESSAGE ) )
return ; // malformed packet
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
sP_CL2FE_REQ_SEND_BUDDY_MENUCHAT_MESSAGE * pkt = ( sP_CL2FE_REQ_SEND_BUDDY_MENUCHAT_MESSAGE * ) data - > buf ;
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-09-19 19:07:09 +00:00
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC , resp ) ;
2020-09-19 19:07:09 +00:00
2020-11-08 04:11:56 +00:00
CNSocket * otherSock = PlayerManager : : getSockFromID ( pkt - > iBuddyPCUID ) ;
if ( otherSock = = nullptr )
return ; // buddy offline
2020-09-21 18:28:04 +00:00
2020-10-05 00:03:13 +00:00
resp . iFromPCUID = plr - > PCStyle . iPC_UID ;
resp . iToPCUID = pkt - > iBuddyPCUID ;
resp . iEmoteCode = pkt - > iEmoteCode ;
2020-11-08 18:31:10 +00:00
std : : string fullChat = ChatManager : : sanitizeText ( U16toU8 ( pkt - > szFreeChat ) ) ;
U8toU16 ( fullChat , ( char16_t * ) & resp . szFreeChat , sizeof ( resp . szFreeChat ) ) ;
2020-11-08 04:11:56 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC , sizeof ( sP_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC ) ) ; // confirm send to sender
otherSock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC , sizeof ( sP_FE2CL_REP_SEND_BUDDY_MENUCHAT_MESSAGE_SUCC ) ) ; // broadcast send to receiver
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Getting buddy state
2020-09-19 19:07:09 +00:00
void BuddyManager : : reqPktGetBuddyState ( CNSocket * sock , CNPacketData * data ) {
2020-10-27 15:28:37 +00:00
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_GET_BUDDY_STATE_SUCC , resp ) ;
2020-10-27 15:28:37 +00:00
2020-11-08 04:11:56 +00:00
for ( int slot = 0 ; slot < 50 ; slot + + ) {
resp . aBuddyState [ slot ] = PlayerManager : : getPlayerFromID ( plr - > buddyIDs [ slot ] ) ! = nullptr ? 1 : 0 ;
resp . aBuddyID [ slot ] = plr - > buddyIDs [ slot ] ;
2020-10-05 00:03:13 +00:00
}
2020-11-08 04:11:56 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_GET_BUDDY_STATE_SUCC , sizeof ( sP_FE2CL_REP_GET_BUDDY_STATE_SUCC ) ) ;
2020-09-19 19:07:09 +00:00
}
2020-10-19 17:26:14 +00:00
// Blocking the buddy
2020-09-21 18:28:04 +00:00
void BuddyManager : : reqBuddyBlock ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_SET_BUDDY_BLOCK ) )
return ; // malformed packet
2020-09-21 18:28:04 +00:00
2020-10-05 00:03:13 +00:00
sP_CL2FE_REQ_SET_BUDDY_BLOCK * pkt = ( sP_CL2FE_REQ_SET_BUDDY_BLOCK * ) data - > buf ;
2020-09-21 18:28:04 +00:00
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_SET_BUDDY_BLOCK_SUCC , resp ) ;
2020-09-21 18:28:04 +00:00
2020-10-05 00:03:13 +00:00
resp . iBuddyPCUID = pkt - > iBuddyPCUID ;
resp . iBuddySlot = pkt - > iBuddySlot ;
2020-09-21 18:28:04 +00:00
2020-11-08 04:11:56 +00:00
// TODO: handle this?
2020-10-05 00:03:13 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_SET_BUDDY_BLOCK_SUCC , sizeof ( sP_FE2CL_REP_SET_BUDDY_BLOCK_SUCC ) ) ;
2020-09-21 18:28:04 +00:00
}
2020-10-19 17:26:14 +00:00
// Deleting the buddy
2020-09-21 18:28:04 +00:00
void BuddyManager : : reqBuddyDelete ( CNSocket * sock , CNPacketData * data ) {
2020-10-05 00:03:13 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_REMOVE_BUDDY ) )
2020-10-19 17:26:14 +00:00
return ; // malformed packet
2020-09-21 18:28:04 +00:00
2020-10-05 00:03:13 +00:00
sP_CL2FE_REQ_REMOVE_BUDDY * pkt = ( sP_CL2FE_REQ_REMOVE_BUDDY * ) data - > buf ;
2020-09-21 18:28:04 +00:00
2020-10-27 15:28:37 +00:00
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-11-08 17:42:27 +00:00
// remove buddy on our side
2020-10-05 00:03:13 +00:00
INITSTRUCT ( sP_FE2CL_REP_REMOVE_BUDDY_SUCC , resp ) ;
resp . iBuddyPCUID = pkt - > iBuddyPCUID ;
resp . iBuddySlot = pkt - > iBuddySlot ;
2020-11-08 04:11:56 +00:00
if ( pkt - > iBuddySlot < 0 | | pkt - > iBuddySlot > = 50 )
return ; // sanity check
plr - > buddyIDs [ resp . iBuddySlot ] = 0 ;
2020-10-05 00:03:13 +00:00
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_REMOVE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_REMOVE_BUDDY_SUCC ) ) ;
2020-11-08 17:42:27 +00:00
// remove buddy on their side, reusing the struct
CNSocket * otherSock = PlayerManager : : getSockFromID ( pkt - > iBuddyPCUID ) ;
if ( otherSock = = nullptr )
return ; // other player isn't online, no broadcast needed
Player * otherPlr = PlayerManager : : getPlayer ( otherSock ) ;
// search for the slot with the requesting player's ID
resp . iBuddyPCUID = plr - > PCStyle . iPC_UID ;
for ( int i = 0 ; i < 50 ; i + + ) {
if ( otherPlr - > buddyIDs [ i ] = = plr - > PCStyle . iPC_UID ) {
// remove buddy
otherPlr - > buddyIDs [ i ] = 0 ;
// broadcast
resp . iBuddySlot = i ;
otherSock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_REMOVE_BUDDY_SUCC , sizeof ( sP_FE2CL_REP_REMOVE_BUDDY_SUCC ) ) ;
return ;
}
}
2020-09-21 18:28:04 +00:00
}
2020-10-19 17:26:14 +00:00
// Warping to buddy
2020-11-08 17:54:05 +00:00
void BuddyManager : : reqBuddyWarp ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_BUDDY_WARP ) )
return ; // malformed packet
sP_CL2FE_REQ_PC_BUDDY_WARP * pkt = ( sP_CL2FE_REQ_PC_BUDDY_WARP * ) data - > buf ;
if ( pkt - > iSlotNum < 0 | | pkt - > iSlotNum > = 50 )
return ; // sanity check
Player * otherPlr = PlayerManager : : getPlayerFromID ( pkt - > iBuddyPCUID ) ;
if ( otherPlr = = nullptr )
return ; // buddy offline
if ( otherPlr - > instanceID ! = INSTANCE_OVERWORLD ) {
// player is instanced; no warp allowed
INITSTRUCT ( sP_FE2CL_REP_PC_BUDDY_WARP_FAIL , resp ) ;
resp . iBuddyPCUID = pkt - > iBuddyPCUID ;
resp . iErrorCode = 0 ;
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_PC_BUDDY_WARP_FAIL , sizeof ( sP_FE2CL_REP_PC_BUDDY_WARP_FAIL ) ) ;
return ;
}
PlayerManager : : sendPlayerTo ( sock , otherPlr - > x , otherPlr - > y , otherPlr - > z ) ;
}
2020-09-22 17:02:00 +00:00
2020-09-19 19:07:09 +00:00
# pragma region Helper methods
2020-11-08 04:11:56 +00:00
int BuddyManager : : getAvailableBuddySlot ( Player * plr ) {
int slot = - 1 ;
for ( int i = 0 ; i < 50 ; i + + ) {
if ( plr - > buddyIDs [ i ] = = 0 )
return i ;
}
return slot ;
}
2020-10-27 15:28:37 +00:00
bool BuddyManager : : NameCheck ( char16_t reqName [ ] , char16_t resName [ ] , int sizeOfLNReq , int sizeOfLNRes ) {
2020-10-05 00:03:13 +00:00
// If lengths of array are not equal means
// array are not equal
if ( sizeOfLNReq ! = sizeOfLNRes )
return false ;
// Sort both arrays
2020-10-27 15:28:37 +00:00
std : : sort ( reqName , reqName + sizeOfLNReq ) ;
std : : sort ( resName , resName + sizeOfLNRes ) ;
2020-10-05 00:03:13 +00:00
// Linearly compare elements
for ( int i = 0 ; i < sizeOfLNReq ; i + + )
2020-10-27 15:28:37 +00:00
if ( reqName [ i ] ! = resName [ i ] )
2020-10-05 00:03:13 +00:00
return false ;
// If all elements were same.
return true ;
2020-09-19 19:07:09 +00:00
}
# pragma endregion