2020-08-18 20:42:30 +00:00
# include "CNProtocol.hpp"
# include "PlayerManager.hpp"
2020-08-20 21:43:48 +00:00
# include "NPCManager.hpp"
2020-08-18 20:42:30 +00:00
# include "CNShardServer.hpp"
# include "CNShared.hpp"
# include "settings.hpp"
2020-09-11 23:22:58 +00:00
# include <assert.h>
2020-08-18 20:42:30 +00:00
# include <algorithm>
# include <vector>
# include <cmath>
std : : map < CNSocket * , PlayerView > PlayerManager : : players ;
void PlayerManager : : init ( ) {
// register packet types
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_ENTER , PlayerManager : : enterPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_LOADING_COMPLETE , PlayerManager : : loadPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_MOVE , PlayerManager : : movePlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_STOP , PlayerManager : : stopPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_JUMP , PlayerManager : : jumpPlayer ) ;
2020-08-20 16:26:26 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_JUMPPAD , PlayerManager : : jumppadPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_LAUNCHER , PlayerManager : : launchPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_ZIPLINE , PlayerManager : : ziplinePlayer ) ;
2020-08-18 20:42:30 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_MOVEPLATFORM , PlayerManager : : movePlatformPlayer ) ;
2020-08-20 16:26:26 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_SLOPE , PlayerManager : : moveSlopePlayer ) ;
2020-08-18 20:42:30 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_GOTO , PlayerManager : : gotoPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_GM_REQ_PC_SET_VALUE , PlayerManager : : setSpecialPlayer ) ;
2020-08-19 01:34:39 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REP_LIVE_CHECK , PlayerManager : : heartbeatPlayer ) ;
2020-08-24 21:04:56 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_REGEN , PlayerManager : : revivePlayer ) ;
2020-08-19 17:22:54 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_EXIT , PlayerManager : : exitGame ) ;
2020-08-24 21:04:56 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH , PlayerManager : : setSpecialSwitchPlayer ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_VEHICLE_ON , PlayerManager : : enterPlayerVehicle ) ;
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_VEHICLE_OFF , PlayerManager : : exitPlayerVehicle ) ;
2020-08-28 19:42:00 +00:00
REGISTER_SHARD_PACKET ( P_CL2FE_REQ_PC_CHANGE_MENTOR , PlayerManager : : changePlayerGuide ) ;
2020-08-18 20:42:30 +00:00
}
void PlayerManager : : addPlayer ( CNSocket * key , Player plr ) {
2020-08-24 22:02:07 +00:00
Player * p = new Player ( ) ;
memcpy ( p , & plr , sizeof ( Player ) ) ;
2020-08-18 20:42:30 +00:00
players [ key ] = PlayerView ( ) ;
players [ key ] . viewable = std : : list < CNSocket * > ( ) ;
2020-08-24 22:02:07 +00:00
players [ key ] . plr = p ;
2020-08-19 01:34:39 +00:00
players [ key ] . lastHeartbeat = 0 ;
2020-08-19 00:11:31 +00:00
2020-09-11 23:22:58 +00:00
key - > plr = p ;
2020-08-21 17:38:45 +00:00
std : : cout < < U16toU8 ( plr . PCStyle . szFirstName ) < < " " < < U16toU8 ( plr . PCStyle . szLastName ) < < " has joined! " < < std : : endl ;
2020-08-19 00:11:31 +00:00
std : : cout < < players . size ( ) < < " players " < < std : : endl ;
2020-08-18 20:42:30 +00:00
}
void PlayerManager : : removePlayer ( CNSocket * key ) {
PlayerView cachedView = players [ key ] ;
// if players have them in their viewable lists, remove it
for ( CNSocket * otherSock : players [ key ] . viewable ) {
players [ otherSock ] . viewable . remove ( key ) ; // gone
2020-08-25 22:09:31 +00:00
// now send PC_EXIT packet
2020-08-22 23:31:09 +00:00
sP_FE2CL_PC_EXIT exitPacket ;
2020-08-24 22:02:07 +00:00
exitPacket . iID = players [ key ] . plr - > iID ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
otherSock - > sendPacket ( ( void * ) & exitPacket , P_FE2CL_PC_EXIT , sizeof ( sP_FE2CL_PC_EXIT ) ) ;
2020-08-18 20:42:30 +00:00
}
2020-08-29 11:14:21 +00:00
std : : cout < < U16toU8 ( cachedView . plr - > PCStyle . szFirstName ) < < " " < < U16toU8 ( cachedView . plr - > PCStyle . szLastName ) < < " has left! " < < std : : endl ;
2020-08-19 00:11:31 +00:00
std : : cout < < players . size ( ) < < " players " < < std : : endl ;
2020-08-25 22:09:31 +00:00
2020-09-11 23:22:58 +00:00
key - > plr = nullptr ;
2020-08-25 22:09:31 +00:00
delete cachedView . plr ;
players . erase ( key ) ;
2020-08-18 20:42:30 +00:00
}
2020-09-02 22:22:00 +00:00
void PlayerManager : : updatePlayerPosition ( CNSocket * sock , int X , int Y , int Z , int angle ) {
players [ sock ] . plr - > angle = angle ;
updatePlayerPosition ( sock , X , Y , Z ) ;
}
2020-08-18 20:42:30 +00:00
void PlayerManager : : updatePlayerPosition ( CNSocket * sock , int X , int Y , int Z ) {
2020-08-24 22:02:07 +00:00
players [ sock ] . plr - > x = X ;
players [ sock ] . plr - > y = Y ;
players [ sock ] . plr - > z = Z ;
2020-08-18 20:42:30 +00:00
std : : vector < CNSocket * > noView ;
std : : vector < CNSocket * > yesView ;
// TODO: oh god this is sooooo perfomance heavy the more players you have
for ( auto pair : players ) {
if ( pair . first = = sock )
continue ; // ignore our own connection
2020-08-24 22:02:07 +00:00
int diffX = abs ( pair . second . plr - > x - X ) ; // the map is like a grid, X and Y are your position on the map, Z is the height. very different from other games...
int diffY = abs ( pair . second . plr - > y - Y ) ;
2020-08-18 20:42:30 +00:00
2020-08-26 02:53:27 +00:00
if ( diffX < settings : : PLAYERDISTANCE & & diffY < settings : : PLAYERDISTANCE ) {
2020-08-18 20:42:30 +00:00
yesView . push_back ( pair . first ) ;
2020-08-22 18:02:08 +00:00
}
else {
2020-08-20 18:19:03 +00:00
noView . push_back ( pair . first ) ;
2020-08-18 20:42:30 +00:00
}
}
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_EXIT , exitPacket ) ;
2020-08-20 21:59:32 +00:00
std : : list < CNSocket * > : : iterator i = players [ sock ] . viewable . begin ( ) ;
while ( i ! = players [ sock ] . viewable . end ( ) ) {
CNSocket * otherSock = * i ;
2020-08-18 20:42:30 +00:00
if ( std : : find ( noView . begin ( ) , noView . end ( ) , otherSock ) ! = noView . end ( ) ) {
2020-08-22 23:31:09 +00:00
// sock shouldn't be visible, send PC_EXIT packet
2020-08-24 22:02:07 +00:00
exitPacket . iID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
otherSock - > sendPacket ( ( void * ) & exitPacket , P_FE2CL_PC_EXIT , sizeof ( sP_FE2CL_PC_EXIT ) ) ;
2020-08-24 22:02:07 +00:00
exitPacket . iID = players [ otherSock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & exitPacket , P_FE2CL_PC_EXIT , sizeof ( sP_FE2CL_PC_EXIT ) ) ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
// remove them from the viewable list
2020-08-20 21:59:32 +00:00
players [ sock ] . viewable . erase ( i + + ) ;
2020-08-18 20:42:30 +00:00
players [ otherSock ] . viewable . remove ( sock ) ;
2020-08-20 21:59:32 +00:00
continue ;
2020-08-18 20:42:30 +00:00
}
2020-08-20 21:59:32 +00:00
+ + i ;
}
2020-08-18 20:42:30 +00:00
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_NEW , newPlayer ) ;
2020-08-18 20:42:30 +00:00
for ( CNSocket * otherSock : yesView ) {
2020-08-20 21:59:32 +00:00
if ( std : : find ( players [ sock ] . viewable . begin ( ) , players [ sock ] . viewable . end ( ) , otherSock ) = = players [ sock ] . viewable . end ( ) ) {
2020-08-18 20:42:30 +00:00
// this needs to be added to the viewable players, send PC_ENTER
2020-08-24 22:02:07 +00:00
Player * otherPlr = players [ otherSock ] . plr ;
Player * plr = players [ sock ] . plr ;
newPlayer . PCAppearanceData . iID = plr - > iID ;
newPlayer . PCAppearanceData . iHP = plr - > HP ;
newPlayer . PCAppearanceData . iLv = plr - > level ;
newPlayer . PCAppearanceData . iX = plr - > x ;
newPlayer . PCAppearanceData . iY = plr - > y ;
newPlayer . PCAppearanceData . iZ = plr - > z ;
newPlayer . PCAppearanceData . iAngle = plr - > angle ;
newPlayer . PCAppearanceData . PCStyle = plr - > PCStyle ;
newPlayer . PCAppearanceData . Nano = plr - > Nanos [ plr - > activeNano ] ;
newPlayer . PCAppearanceData . iPCState = plr - > iPCState ;
memcpy ( newPlayer . PCAppearanceData . ItemEquip , plr - > Equip , sizeof ( sItemBase ) * AEQUIP_COUNT ) ;
2020-08-22 23:31:09 +00:00
otherSock - > sendPacket ( ( void * ) & newPlayer , P_FE2CL_PC_NEW , sizeof ( sP_FE2CL_PC_NEW ) ) ;
2020-08-24 22:02:07 +00:00
newPlayer . PCAppearanceData . iID = otherPlr - > iID ;
newPlayer . PCAppearanceData . iHP = otherPlr - > HP ;
newPlayer . PCAppearanceData . iLv = otherPlr - > level ;
newPlayer . PCAppearanceData . iX = otherPlr - > x ;
newPlayer . PCAppearanceData . iY = otherPlr - > y ;
newPlayer . PCAppearanceData . iZ = otherPlr - > z ;
newPlayer . PCAppearanceData . iAngle = otherPlr - > angle ;
newPlayer . PCAppearanceData . PCStyle = otherPlr - > PCStyle ;
newPlayer . PCAppearanceData . Nano = otherPlr - > Nanos [ otherPlr - > activeNano ] ;
newPlayer . PCAppearanceData . iPCState = otherPlr - > iPCState ;
memcpy ( newPlayer . PCAppearanceData . ItemEquip , otherPlr - > Equip , sizeof ( sItemBase ) * AEQUIP_COUNT ) ;
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & newPlayer , P_FE2CL_PC_NEW , sizeof ( sP_FE2CL_PC_NEW ) ) ;
2020-08-18 20:42:30 +00:00
players [ sock ] . viewable . push_back ( otherSock ) ;
players [ otherSock ] . viewable . push_back ( sock ) ;
}
}
2020-08-20 21:43:48 +00:00
NPCManager : : updatePlayerNPCS ( sock , players [ sock ] ) ;
2020-08-18 20:42:30 +00:00
}
2020-09-02 22:22:00 +00:00
2020-08-23 15:42:37 +00:00
std : : list < CNSocket * > PlayerManager : : getNearbyPlayers ( int x , int y , int dist ) {
std : : list < CNSocket * > plrs ;
for ( auto pair : players ) {
2020-08-24 22:02:07 +00:00
int diffX = abs ( pair . second . plr - > x - x ) ;
int diffY = abs ( pair . second . plr - > x - x ) ;
2020-08-23 15:42:37 +00:00
if ( diffX < dist & & diffY < dist )
plrs . push_back ( pair . first ) ;
}
return plrs ;
}
2020-08-18 20:42:30 +00:00
void PlayerManager : : enterPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_ENTER ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_ENTER * enter = ( sP_CL2FE_REQ_PC_ENTER * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_REP_PC_ENTER_SUCC , response ) ;
INITSTRUCT ( sP_FE2CL_PC_MOTD_LOGIN , motd ) ;
2020-08-18 20:42:30 +00:00
// TODO: check if serialkey exists, if it doesn't send sP_FE2CL_REP_PC_ENTER_FAIL
Player plr = CNSharedData : : getPlayer ( enter - > iEnterSerialKey ) ;
DEBUGLOG (
std : : cout < < " P_CL2FE_REQ_PC_ENTER: " < < std : : endl ;
2020-08-24 23:08:02 +00:00
std : : cout < < " \t ID: " < < U16toU8 ( enter - > szID ) < < std : : endl ;
std : : cout < < " \t Serial: " < < enter - > iEnterSerialKey < < std : : endl ;
std : : cout < < " \t Temp: " < < enter - > iTempValue < < std : : endl ;
std : : cout < < " \t PC_UID: " < < plr . PCStyle . iPC_UID < < std : : endl ;
2020-09-14 13:20:55 +00:00
)
2020-08-18 20:42:30 +00:00
2020-09-02 22:22:00 +00:00
response . iID = plr . iID ;
2020-08-22 23:31:09 +00:00
response . uiSvrTime = getTime ( ) ;
2020-09-07 00:16:44 +00:00
response . PCLoadData2CL . iUserLevel = plr . level ;
2020-09-02 22:22:00 +00:00
response . PCLoadData2CL . iHP = plr . HP ;
2020-08-22 23:31:09 +00:00
response . PCLoadData2CL . iLevel = plr . level ;
2020-08-26 17:40:10 +00:00
response . PCLoadData2CL . iCandy = plr . money ;
2020-09-09 22:31:09 +00:00
response . PCLoadData2CL . iMentor = 5 ; // Computress
2020-09-12 20:43:04 +00:00
response . PCLoadData2CL . iMentorCount = 1 ; // how many guides the player has had
2020-08-22 23:31:09 +00:00
response . PCLoadData2CL . iMapNum = 0 ;
response . PCLoadData2CL . iX = plr . x ;
response . PCLoadData2CL . iY = plr . y ;
response . PCLoadData2CL . iZ = plr . z ;
2020-09-02 22:22:00 +00:00
response . PCLoadData2CL . iAngle = plr . angle ;
2020-09-07 00:16:44 +00:00
response . PCLoadData2CL . iActiveNanoSlotNum = - 1 ;
2020-08-22 23:31:09 +00:00
response . PCLoadData2CL . iFatigue = 50 ;
response . PCLoadData2CL . PCStyle = plr . PCStyle ;
response . PCLoadData2CL . PCStyle2 = plr . PCStyle2 ;
2020-09-07 00:16:44 +00:00
//inventory
2020-08-18 20:42:30 +00:00
for ( int i = 0 ; i < AEQUIP_COUNT ; i + + )
2020-08-22 23:31:09 +00:00
response . PCLoadData2CL . aEquip [ i ] = plr . Equip [ i ] ;
2020-08-24 21:04:56 +00:00
for ( int i = 0 ; i < AINVEN_COUNT ; i + + )
2020-08-22 23:31:09 +00:00
response . PCLoadData2CL . aInven [ i ] = plr . Inven [ i ] ;
2020-09-14 13:53:48 +00:00
//nanos
2020-09-07 00:16:44 +00:00
for ( int i = 1 ; i < SIZEOF_NANO_BANK_SLOT ; i + + ) {
2020-09-02 22:22:00 +00:00
response . PCLoadData2CL . aNanoBank [ i ] = plr . Nanos [ i ] ;
2020-08-18 20:42:30 +00:00
}
2020-09-07 00:16:44 +00:00
for ( int i = 0 ; i < 3 ; i + + ) {
response . PCLoadData2CL . aNanoSlots [ i ] = plr . equippedNanos [ i ] ;
}
2020-08-18 20:42:30 +00:00
2020-09-13 18:45:51 +00:00
//missions
for ( int i = 0 ; i < 16 ; i + + ) {
response . PCLoadData2CL . aQuestFlag [ i ] = plr . aQuestFlag [ i ] ;
}
2020-09-12 20:43:04 +00:00
// shut Computress up
2020-08-25 01:42:52 +00:00
response . PCLoadData2CL . iFirstUseFlag1 = UINT64_MAX ;
response . PCLoadData2CL . iFirstUseFlag2 = UINT64_MAX ;
2020-08-18 20:42:30 +00:00
plr . SerialKey = enter - > iEnterSerialKey ;
2020-08-22 23:31:09 +00:00
motd . iType = 1 ;
U8toU16 ( settings : : MOTDSTRING , ( char16_t * ) motd . szSystemMsg ) ;
2020-08-21 17:38:45 +00:00
2020-08-22 23:31:09 +00:00
sock - > setEKey ( CNSocketEncryption : : createNewKey ( response . uiSvrTime , response . iID + 1 , response . PCLoadData2CL . iFusionMatter + 1 ) ) ;
2020-08-18 20:42:30 +00:00
sock - > setFEKey ( plr . FEKey ) ;
2020-08-22 23:31:09 +00:00
sock - > setActiveKey ( SOCKETKEY_FE ) ; // send all packets using the FE key from now on
sock - > sendPacket ( ( void * ) & response , P_FE2CL_REP_PC_ENTER_SUCC , sizeof ( sP_FE2CL_REP_PC_ENTER_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
2020-08-21 17:38:45 +00:00
// transmit MOTD after entering the game, so the client hopefully changes modes on time
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & motd , P_FE2CL_PC_MOTD_LOGIN , sizeof ( sP_FE2CL_PC_MOTD_LOGIN ) ) ;
2020-08-18 20:42:30 +00:00
addPlayer ( sock , plr ) ;
}
void PlayerManager : : loadPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_LOADING_COMPLETE ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_LOADING_COMPLETE * complete = ( sP_CL2FE_REQ_PC_LOADING_COMPLETE * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC , response ) ;
2020-08-25 18:42:52 +00:00
Player * plr = getPlayer ( sock ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2FE_REQ_PC_LOADING_COMPLETE: " < < std : : endl ;
2020-08-24 23:08:02 +00:00
std : : cout < < " \t PC_ID: " < < complete - > iPC_ID < < std : : endl ;
2020-08-18 20:42:30 +00:00
)
2020-08-24 23:08:02 +00:00
response . iPC_ID = complete - > iPC_ID ;
2020-08-18 20:42:30 +00:00
2020-08-25 18:42:52 +00:00
// reload players & NPCs
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , plr - > x , plr - > y , plr - > z , plr - > angle ) ;
2020-08-25 18:42:52 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & response , P_FE2CL_REP_PC_LOADING_COMPLETE_SUCC , sizeof ( sP_FE2CL_REP_PC_LOADING_COMPLETE_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
}
void PlayerManager : : movePlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_MOVE ) )
return ; // ignore the malformed packet
2020-08-22 18:02:08 +00:00
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_MOVE * moveData = ( sP_CL2FE_REQ_PC_MOVE * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , moveData - > iX , moveData - > iY , moveData - > iZ , moveData - > iAngle ) ;
2020-08-18 20:42:30 +00:00
2020-08-24 22:02:07 +00:00
players [ sock ] . plr - > angle = moveData - > iAngle ;
2020-08-18 20:42:30 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_MOVE , moveResponse ) ;
2020-08-18 20:42:30 +00:00
2020-08-24 22:02:07 +00:00
moveResponse . iID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
moveResponse . cKeyValue = moveData - > cKeyValue ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
moveResponse . iX = moveData - > iX ;
moveResponse . iY = moveData - > iY ;
moveResponse . iZ = moveData - > iZ ;
moveResponse . iAngle = moveData - > iAngle ;
moveResponse . fVX = moveData - > fVX ;
moveResponse . fVY = moveData - > fVY ;
moveResponse . fVZ = moveData - > fVZ ;
2020-08-22 18:02:08 +00:00
2020-08-22 23:31:09 +00:00
moveResponse . iSpeed = moveData - > iSpeed ;
moveResponse . iCliTime = moveData - > iCliTime ; // maybe don't send this??? seems unneeded...
moveResponse . iSvrTime = tm ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & moveResponse , P_FE2CL_PC_MOVE , sizeof ( sP_FE2CL_PC_MOVE ) ) ;
2020-08-18 20:42:30 +00:00
}
}
void PlayerManager : : stopPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_STOP ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_STOP * stopData = ( sP_CL2FE_REQ_PC_STOP * ) data - > buf ;
updatePlayerPosition ( sock , stopData - > iX , stopData - > iY , stopData - > iZ ) ;
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_STOP , stopResponse ) ;
2020-08-18 20:42:30 +00:00
2020-08-24 22:02:07 +00:00
stopResponse . iID = players [ sock ] . plr - > iID ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
stopResponse . iX = stopData - > iX ;
stopResponse . iY = stopData - > iY ;
stopResponse . iZ = stopData - > iZ ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
stopResponse . iCliTime = stopData - > iCliTime ; // maybe don't send this??? seems unneeded...
stopResponse . iSvrTime = tm ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & stopResponse , P_FE2CL_PC_STOP , sizeof ( sP_FE2CL_PC_STOP ) ) ;
2020-08-18 20:42:30 +00:00
}
}
void PlayerManager : : jumpPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_JUMP ) )
return ; // ignore the malformed packet
2020-08-22 18:02:08 +00:00
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_JUMP * jumpData = ( sP_CL2FE_REQ_PC_JUMP * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , jumpData - > iX , jumpData - > iY , jumpData - > iZ , jumpData - > iAngle ) ;
2020-08-18 20:42:30 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_JUMP , jumpResponse ) ;
2020-08-18 20:42:30 +00:00
2020-08-24 22:02:07 +00:00
jumpResponse . iID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
jumpResponse . cKeyValue = jumpData - > cKeyValue ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
jumpResponse . iX = jumpData - > iX ;
jumpResponse . iY = jumpData - > iY ;
jumpResponse . iZ = jumpData - > iZ ;
jumpResponse . iAngle = jumpData - > iAngle ;
jumpResponse . iVX = jumpData - > iVX ;
jumpResponse . iVY = jumpData - > iVY ;
jumpResponse . iVZ = jumpData - > iVZ ;
2020-08-22 18:02:08 +00:00
2020-08-22 23:31:09 +00:00
jumpResponse . iSpeed = jumpData - > iSpeed ;
jumpResponse . iCliTime = jumpData - > iCliTime ; // maybe don't send this??? seems unneeded...
jumpResponse . iSvrTime = tm ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & jumpResponse , P_FE2CL_PC_JUMP , sizeof ( sP_FE2CL_PC_JUMP ) ) ;
2020-08-18 20:42:30 +00:00
}
}
2020-08-20 16:26:26 +00:00
void PlayerManager : : jumppadPlayer ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_JUMPPAD ) )
return ; // ignore the malformed packet
2020-08-22 18:02:08 +00:00
2020-08-20 16:26:26 +00:00
sP_CL2FE_REQ_PC_JUMPPAD * jumppadData = ( sP_CL2FE_REQ_PC_JUMPPAD * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , jumppadData - > iX , jumppadData - > iY , jumppadData - > iZ , jumppadData - > iAngle ) ;
2020-08-20 16:26:26 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_JUMPPAD , jumppadResponse ) ;
2020-08-20 16:26:26 +00:00
2020-08-24 22:02:07 +00:00
jumppadResponse . iPC_ID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
jumppadResponse . cKeyValue = jumppadData - > cKeyValue ;
2020-08-20 16:26:26 +00:00
2020-08-22 23:31:09 +00:00
jumppadResponse . iX = jumppadData - > iX ;
jumppadResponse . iY = jumppadData - > iY ;
jumppadResponse . iZ = jumppadData - > iZ ;
jumppadResponse . iVX = jumppadData - > iVX ;
jumppadResponse . iVY = jumppadData - > iVY ;
jumppadResponse . iVZ = jumppadData - > iVZ ;
2020-08-22 18:02:08 +00:00
2020-08-22 23:31:09 +00:00
jumppadResponse . iCliTime = jumppadData - > iCliTime ;
jumppadResponse . iSvrTime = tm ;
2020-08-20 16:26:26 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & jumppadResponse , P_FE2CL_PC_JUMPPAD , sizeof ( sP_FE2CL_PC_JUMPPAD ) ) ;
2020-08-20 16:26:26 +00:00
}
}
void PlayerManager : : launchPlayer ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_LAUNCHER ) )
return ; // ignore the malformed packet
2020-08-22 18:02:08 +00:00
2020-08-20 16:26:26 +00:00
sP_CL2FE_REQ_PC_LAUNCHER * launchData = ( sP_CL2FE_REQ_PC_LAUNCHER * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , launchData - > iX , launchData - > iY , launchData - > iZ , launchData - > iAngle ) ;
2020-08-20 16:26:26 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_LAUNCHER , launchResponse ) ;
2020-08-20 16:26:26 +00:00
2020-08-24 22:02:07 +00:00
launchResponse . iPC_ID = players [ sock ] . plr - > iID ;
2020-08-20 16:26:26 +00:00
2020-08-22 23:31:09 +00:00
launchResponse . iX = launchData - > iX ;
launchResponse . iY = launchData - > iY ;
launchResponse . iZ = launchData - > iZ ;
launchResponse . iVX = launchData - > iVX ;
launchResponse . iVY = launchData - > iVY ;
launchResponse . iVZ = launchData - > iVZ ;
launchResponse . iSpeed = launchData - > iSpeed ;
launchResponse . iAngle = launchData - > iAngle ;
2020-08-22 18:02:08 +00:00
2020-08-22 23:31:09 +00:00
launchResponse . iCliTime = launchData - > iCliTime ;
launchResponse . iSvrTime = tm ;
2020-08-20 16:26:26 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & launchResponse , P_FE2CL_PC_LAUNCHER , sizeof ( sP_FE2CL_PC_LAUNCHER ) ) ;
2020-08-20 16:26:26 +00:00
}
}
void PlayerManager : : ziplinePlayer ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_ZIPLINE ) )
return ; // ignore the malformed packet
sP_CL2FE_REQ_PC_ZIPLINE * ziplineData = ( sP_CL2FE_REQ_PC_ZIPLINE * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , ziplineData - > iX , ziplineData - > iY , ziplineData - > iZ , ziplineData - > iAngle ) ;
2020-08-20 16:26:26 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_ZIPLINE , ziplineResponse ) ;
2020-08-22 23:31:09 +00:00
2020-08-24 22:02:07 +00:00
ziplineResponse . iPC_ID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
ziplineResponse . iCliTime = ziplineData - > iCliTime ;
ziplineResponse . iSvrTime = tm ;
ziplineResponse . iX = ziplineData - > iX ;
ziplineResponse . iY = ziplineData - > iY ;
ziplineResponse . iZ = ziplineData - > iZ ;
ziplineResponse . fVX = ziplineData - > fVX ;
ziplineResponse . fVY = ziplineData - > fVY ;
ziplineResponse . fVZ = ziplineData - > fVZ ;
ziplineResponse . fMovDistance = ziplineData - > fMovDistance ;
ziplineResponse . fMaxDistance = ziplineData - > fMaxDistance ;
ziplineResponse . fDummy = ziplineData - > fDummy ; //wtf is this for?
ziplineResponse . iStX = ziplineData - > iStX ;
ziplineResponse . iStY = ziplineData - > iStY ;
ziplineResponse . iStZ = ziplineData - > iStZ ;
ziplineResponse . bDown = ziplineData - > bDown ;
ziplineResponse . iSpeed = ziplineData - > iSpeed ;
ziplineResponse . iAngle = ziplineData - > iAngle ;
ziplineResponse . iRollMax = ziplineData - > iRollMax ;
ziplineResponse . iRoll = ziplineData - > iRoll ;
2020-08-20 16:26:26 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & ziplineResponse , P_FE2CL_PC_ZIPLINE , sizeof ( sP_FE2CL_PC_ZIPLINE ) ) ;
2020-08-20 16:26:26 +00:00
}
}
2020-08-18 20:42:30 +00:00
void PlayerManager : : movePlatformPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_MOVEPLATFORM ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_MOVEPLATFORM * platformData = ( sP_CL2FE_REQ_PC_MOVEPLATFORM * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , platformData - > iX , platformData - > iY , platformData - > iZ , platformData - > iAngle ) ;
2020-08-18 20:42:30 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_MOVEPLATFORM , platResponse ) ;
2020-08-22 23:31:09 +00:00
2020-08-24 22:02:07 +00:00
platResponse . iPC_ID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
platResponse . iCliTime = platformData - > iCliTime ;
platResponse . iSvrTime = tm ;
platResponse . iX = platformData - > iX ;
platResponse . iY = platformData - > iY ;
platResponse . iZ = platformData - > iZ ;
platResponse . iAngle = platformData - > iAngle ;
platResponse . fVX = platformData - > fVX ;
platResponse . fVY = platformData - > fVY ;
platResponse . fVZ = platformData - > fVZ ;
platResponse . iLcX = platformData - > iLcX ;
platResponse . iLcY = platformData - > iLcY ;
platResponse . iLcZ = platformData - > iLcZ ;
platResponse . iSpeed = platformData - > iSpeed ;
platResponse . bDown = platformData - > bDown ;
platResponse . cKeyValue = platformData - > cKeyValue ;
platResponse . iPlatformID = platformData - > iPlatformID ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & platResponse , P_FE2CL_PC_MOVEPLATFORM , sizeof ( sP_FE2CL_PC_MOVEPLATFORM ) ) ;
2020-08-18 20:42:30 +00:00
}
}
2020-08-20 16:26:26 +00:00
void PlayerManager : : moveSlopePlayer ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_SLOPE ) )
return ; // ignore the malformed packet
sP_CL2FE_REQ_PC_SLOPE * slopeData = ( sP_CL2FE_REQ_PC_SLOPE * ) data - > buf ;
2020-09-02 22:22:00 +00:00
updatePlayerPosition ( sock , slopeData - > iX , slopeData - > iY , slopeData - > iZ , slopeData - > iAngle ) ;
2020-08-20 16:26:26 +00:00
uint64_t tm = getTime ( ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_PC_SLOPE , slopeResponse ) ;
2020-08-22 23:31:09 +00:00
2020-08-24 22:02:07 +00:00
slopeResponse . iPC_ID = players [ sock ] . plr - > iID ;
2020-08-22 23:31:09 +00:00
slopeResponse . iCliTime = slopeData - > iCliTime ;
slopeResponse . iSvrTime = tm ;
slopeResponse . iX = slopeData - > iX ;
slopeResponse . iY = slopeData - > iY ;
slopeResponse . iZ = slopeData - > iZ ;
slopeResponse . iAngle = slopeData - > iAngle ;
slopeResponse . fVX = slopeData - > fVX ;
slopeResponse . fVY = slopeData - > fVY ;
slopeResponse . fVZ = slopeData - > fVZ ;
slopeResponse . iSpeed = slopeData - > iSpeed ;
slopeResponse . cKeyValue = slopeData - > cKeyValue ;
slopeResponse . iSlopeID = slopeData - > iSlopeID ;
2020-08-20 16:26:26 +00:00
2020-08-22 23:31:09 +00:00
for ( CNSocket * otherSock : players [ sock ] . viewable ) {
otherSock - > sendPacket ( ( void * ) & slopeResponse , P_FE2CL_PC_SLOPE , sizeof ( sP_FE2CL_PC_SLOPE ) ) ;
2020-08-20 16:26:26 +00:00
}
}
2020-08-18 20:42:30 +00:00
void PlayerManager : : gotoPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_GOTO ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2FE_REQ_PC_GOTO * gotoData = ( sP_CL2FE_REQ_PC_GOTO * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_REP_PC_GOTO_SUCC , response ) ;
2020-09-12 20:43:04 +00:00
PlayerView & plrv = players [ sock ] ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2FE_REQ_PC_GOTO: " < < std : : endl ;
2020-08-24 23:08:02 +00:00
std : : cout < < " \t X: " < < gotoData - > iToX < < std : : endl ;
std : : cout < < " \t Y: " < < gotoData - > iToY < < std : : endl ;
std : : cout < < " \t Z: " < < gotoData - > iToZ < < std : : endl ;
2020-08-18 20:42:30 +00:00
)
2020-09-12 20:43:04 +00:00
response . iX = plrv . plr - > x = gotoData - > iToX ;
response . iY = plrv . plr - > y = gotoData - > iToY ;
response . iZ = plrv . plr - > z = gotoData - > iToZ ;
// force player & NPC reload
plrv . viewable . clear ( ) ;
plrv . viewableNPCs . clear ( ) ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & response , P_FE2CL_REP_PC_GOTO_SUCC , sizeof ( sP_FE2CL_REP_PC_GOTO_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
}
void PlayerManager : : setSpecialPlayer ( CNSocket * sock , CNPacketData * data ) {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_GM_REQ_PC_SET_VALUE ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2FE_GM_REQ_PC_SET_VALUE * setData = ( sP_CL2FE_GM_REQ_PC_SET_VALUE * ) data - > buf ;
2020-09-09 01:15:25 +00:00
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_GM_REP_PC_SET_VALUE , response ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2FE_GM_REQ_PC_SET_VALUE: " < < std : : endl ;
2020-08-24 23:08:02 +00:00
std : : cout < < " \t PC_ID: " < < setData - > iPC_ID < < std : : endl ;
std : : cout < < " \t SetValueType: " < < setData - > iSetValueType < < std : : endl ;
std : : cout < < " \t SetValue: " < < setData - > iSetValue < < std : : endl ;
2020-08-18 20:42:30 +00:00
)
2020-09-09 01:15:25 +00:00
// Handle serverside value-changes
switch ( setData - > iSetValueType ) {
case 1 :
plr - > HP = setData - > iSetValue ;
break ;
case 2 :
// TODO: batteryW
break ;
case 3 :
// TODO: batteryN nanopotion
break ;
case 4 :
plr - > fusionmatter = setData - > iSetValue ;
break ;
case 5 :
plr - > money = setData - > iSetValue ;
break ;
default :
break ;
}
2020-08-24 23:08:02 +00:00
response . iPC_ID = setData - > iPC_ID ;
2020-08-22 23:31:09 +00:00
response . iSetValue = setData - > iSetValue ;
response . iSetValueType = setData - > iSetValueType ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & response , P_FE2CL_GM_REP_PC_SET_VALUE , sizeof ( sP_FE2CL_GM_REP_PC_SET_VALUE ) ) ;
2020-08-19 01:34:39 +00:00
}
void PlayerManager : : heartbeatPlayer ( CNSocket * sock , CNPacketData * data ) {
players [ sock ] . lastHeartbeat = getTime ( ) ;
2020-08-19 17:22:54 +00:00
}
void PlayerManager : : exitGame ( CNSocket * sock , CNPacketData * data ) {
2020-08-22 18:08:37 +00:00
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_EXIT ) )
return ;
2020-08-24 21:04:56 +00:00
2020-08-19 17:22:54 +00:00
sP_CL2FE_REQ_PC_EXIT * exitData = ( sP_CL2FE_REQ_PC_EXIT * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_FE2CL_REP_PC_EXIT_SUCC , response ) ;
2020-08-19 17:22:54 +00:00
2020-08-22 23:31:09 +00:00
response . iID = exitData - > iID ;
response . iExitCode = 1 ;
2020-08-19 17:22:54 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & response , P_FE2CL_REP_PC_EXIT_SUCC , sizeof ( sP_FE2CL_REP_PC_EXIT_SUCC ) ) ;
2020-08-19 17:22:54 +00:00
}
2020-08-22 18:02:08 +00:00
2020-08-24 21:04:56 +00:00
void PlayerManager : : revivePlayer ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_REGEN ) )
return ;
2020-08-24 22:02:07 +00:00
Player * plr = PlayerManager : : getPlayer ( sock ) ;
2020-08-25 01:34:53 +00:00
WarpLocation target = PlayerManager : : getRespawnPoint ( plr ) ;
2020-08-24 21:04:56 +00:00
sP_CL2FE_REQ_PC_REGEN * reviveData = ( sP_CL2FE_REQ_PC_REGEN * ) data - > buf ;
INITSTRUCT ( sP_FE2CL_REP_PC_REGEN_SUCC , response ) ;
2020-09-12 20:43:04 +00:00
INITSTRUCT ( sP_FE2CL_PC_REGEN , resp2 ) ;
2020-09-12 18:21:36 +00:00
// Nanos
for ( int n = 0 ; n < 3 ; n + + ) {
int nanoID = plr - > equippedNanos [ n ] ;
2020-09-12 20:43:04 +00:00
plr - > Nanos [ nanoID ] . iStamina = 75 ; // max is 150, so 75 is half
response . PCRegenData . Nanos [ n ] = plr - > Nanos [ nanoID ] ;
2020-09-12 18:21:36 +00:00
}
2020-09-12 20:43:04 +00:00
// Update player
2020-09-12 18:21:36 +00:00
plr - > x = target . x ;
plr - > y = target . y ;
plr - > z = target . z ;
plr - > HP = 1000 * plr - > level ;
// Response parameters
response . PCRegenData . iActiveNanoSlotNum = plr - > activeNano ;
response . PCRegenData . iX = plr - > x ;
response . PCRegenData . iY = plr - > y ;
response . PCRegenData . iZ = plr - > z ;
response . PCRegenData . iHP = plr - > HP ;
response . iFusionMatter = plr - > fusionmatter ;
2020-08-24 21:04:56 +00:00
response . bMoveLocation = reviveData - > eIL ;
response . PCRegenData . iMapNum = reviveData - > iIndex ;
sock - > sendPacket ( ( void * ) & response , P_FE2CL_REP_PC_REGEN_SUCC , sizeof ( sP_FE2CL_REP_PC_REGEN_SUCC ) ) ;
2020-09-12 20:43:04 +00:00
// Update other players
resp2 . PCRegenDataForOtherPC . iPC_ID = plr - > iID ;
resp2 . PCRegenDataForOtherPC . iX = plr - > x ;
resp2 . PCRegenDataForOtherPC . iY = plr - > y ;
resp2 . PCRegenDataForOtherPC . iZ = plr - > z ;
resp2 . PCRegenDataForOtherPC . iHP = plr - > HP ;
resp2 . PCRegenDataForOtherPC . iAngle = plr - > angle ;
resp2 . PCRegenDataForOtherPC . Nano = plr - > Nanos [ plr - > activeNano ] ;
for ( CNSocket * s : players [ sock ] . viewable )
s - > sendPacket ( ( void * ) & resp2 , P_FE2CL_PC_REGEN , sizeof ( sP_FE2CL_PC_REGEN ) ) ;
2020-08-24 21:04:56 +00:00
}
void PlayerManager : : enterPlayerVehicle ( CNSocket * sock , CNPacketData * data ) {
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
PlayerView & plr = PlayerManager : : players [ sock ] ;
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
if ( plr . plr - > Equip [ 8 ] . iID > 0 ) {
INITSTRUCT ( sP_FE2CL_PC_VEHICLE_ON_SUCC , response ) ;
sock - > sendPacket ( ( void * ) & response , P_FE2CL_PC_VEHICLE_ON_SUCC , sizeof ( sP_FE2CL_PC_VEHICLE_ON_SUCC ) ) ;
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
//send to other players
plr . plr - > iPCState = 8 ;
INITSTRUCT ( sP_FE2CL_PC_STATE_CHANGE , response2 ) ;
response2 . iPC_ID = plr . plr - > iID ;
response2 . iState = 8 ;
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
for ( CNSocket * otherSock : plr . viewable ) {
otherSock - > sendPacket ( ( void * ) & response2 , P_FE2CL_PC_STATE_CHANGE , sizeof ( sP_FE2CL_PC_STATE_CHANGE ) ) ;
}
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
} else {
INITSTRUCT ( sP_FE2CL_PC_VEHICLE_ON_FAIL , response ) ;
sock - > sendPacket ( ( void * ) & response , P_FE2CL_PC_VEHICLE_ON_FAIL , sizeof ( sP_FE2CL_PC_VEHICLE_ON_FAIL ) ) ;
2020-08-24 21:04:56 +00:00
}
}
void PlayerManager : : exitPlayerVehicle ( CNSocket * sock , CNPacketData * data ) {
2020-09-14 13:53:48 +00:00
2020-08-24 21:04:56 +00:00
INITSTRUCT ( sP_FE2CL_PC_VEHICLE_OFF_SUCC , response ) ;
2020-08-27 02:35:13 +00:00
sock - > sendPacket ( ( void * ) & response , P_FE2CL_PC_VEHICLE_OFF_SUCC , sizeof ( sP_FE2CL_PC_VEHICLE_OFF_SUCC ) ) ;
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
PlayerView plr = PlayerManager : : players [ sock ] ;
2020-08-24 21:04:56 +00:00
//send to other players
2020-08-27 02:35:13 +00:00
plr . plr - > iPCState = 0 ;
INITSTRUCT ( sP_FE2CL_PC_STATE_CHANGE , response2 ) ;
response2 . iPC_ID = plr . plr - > iID ;
response2 . iState = 0 ;
2020-09-14 13:53:48 +00:00
2020-08-27 02:35:13 +00:00
for ( CNSocket * otherSock : plr . viewable ) {
otherSock - > sendPacket ( ( void * ) & response2 , P_FE2CL_PC_STATE_CHANGE , sizeof ( sP_FE2CL_PC_STATE_CHANGE ) ) ;
2020-09-14 13:53:48 +00:00
}
2020-08-24 21:04:56 +00:00
}
void PlayerManager : : setSpecialSwitchPlayer ( CNSocket * sock , CNPacketData * data ) {
sP_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH * specialData = ( sP_CL2FE_REQ_PC_SPECIAL_STATE_SWITCH * ) data - > buf ;
INITSTRUCT ( sP_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC , response ) ;
response . iPC_ID = specialData - > iPC_ID ;
response . iReqSpecialStateFlag = specialData - > iSpecialStateFlag ;
sock - > sendPacket ( ( void * ) & response , P_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC , sizeof ( sP_FE2CL_REP_PC_SPECIAL_STATE_SWITCH_SUCC ) ) ;
}
2020-08-28 19:42:00 +00:00
void PlayerManager : : changePlayerGuide ( CNSocket * sock , CNPacketData * data ) {
if ( data - > size ! = sizeof ( sP_CL2FE_REQ_PC_CHANGE_MENTOR ) )
return ;
sP_CL2FE_REQ_PC_CHANGE_MENTOR * pkt = ( sP_CL2FE_REQ_PC_CHANGE_MENTOR * ) data - > buf ;
INITSTRUCT ( sP_FE2CL_REP_PC_CHANGE_MENTOR_SUCC , resp ) ;
Player * plr = getPlayer ( sock ) ;
resp . iMentor = pkt - > iMentor ;
resp . iMentorCnt = 1 ;
resp . iFusionMatter = plr - > fusionmatter ; // no cost
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_PC_CHANGE_MENTOR_SUCC , sizeof ( sP_FE2CL_REP_PC_CHANGE_MENTOR_SUCC ) ) ;
}
2020-08-24 21:04:56 +00:00
# pragma region Helper methods
2020-08-24 22:02:07 +00:00
Player * PlayerManager : : getPlayer ( CNSocket * key ) {
2020-09-11 23:22:58 +00:00
assert ( key - > plr ! = nullptr ) ;
return key - > plr ;
2020-08-24 21:04:56 +00:00
}
2020-08-25 01:34:53 +00:00
WarpLocation PlayerManager : : getRespawnPoint ( Player * plr ) {
WarpLocation best ;
uint32_t curDist , bestDist = UINT32_MAX ;
for ( auto targ : NPCManager : : RespawnPoints ) {
curDist = sqrt ( pow ( plr - > x - targ . x , 2 ) + pow ( plr - > y - targ . y , 2 ) ) ;
if ( curDist < bestDist ) {
best = targ ;
bestDist = curDist ;
}
}
return best ;
}
2020-09-01 22:37:09 +00:00
bool PlayerManager : : isAccountInUse ( int accountId ) {
std : : map < CNSocket * , PlayerView > : : iterator it ;
for ( it = PlayerManager : : players . begin ( ) ; it ! = PlayerManager : : players . end ( ) ; it + + )
{
if ( it - > second . plr - > accountId = = accountId )
return true ;
}
return false ;
}
void PlayerManager : : exitDuplicate ( int accountId ) {
std : : map < CNSocket * , PlayerView > : : iterator it ;
for ( it = PlayerManager : : players . begin ( ) ; it ! = PlayerManager : : players . end ( ) ; it + + )
{
if ( it - > second . plr - > accountId = = accountId )
{
CNSocket * sock = it - > first ;
INITSTRUCT ( sP_FE2CL_REP_PC_EXIT_DUPLICATE , resp ) ;
resp . iErrorCode = 0 ;
sock - > sendPacket ( ( void * ) & resp , P_FE2CL_REP_PC_EXIT_DUPLICATE , sizeof ( sP_FE2CL_REP_PC_EXIT_DUPLICATE ) ) ;
sock - > kill ( ) ;
}
}
}
2020-08-24 22:02:07 +00:00
# pragma endregion