2020-08-18 20:42:30 +00:00
# include "CNLoginServer.hpp"
# include "CNShared.hpp"
# include "CNStructs.hpp"
# include "settings.hpp"
/*
This is * not * connected to any database , so i ' m sending dummy data just to get the client to work & connect to the shard < 3
*/
std : : map < CNSocket * , CNLoginData > CNLoginServer : : loginSessions ;
CNLoginServer : : CNLoginServer ( uint16_t p ) {
port = p ;
pHandler = & CNLoginServer : : handlePacket ;
init ( ) ;
}
void CNLoginServer : : handlePacket ( CNSocket * sock , CNPacketData * data ) {
2020-08-23 21:09:31 +00:00
printPacket ( data , CL2LS ) ;
2020-08-22 17:39:13 +00:00
2020-08-18 20:42:30 +00:00
switch ( data - > type ) {
case P_CL2LS_REQ_LOGIN : {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2LS_REQ_LOGIN ) )
return ; // ignore the malformed packet
2020-08-18 20:42:30 +00:00
sP_CL2LS_REQ_LOGIN * login = ( sP_CL2LS_REQ_LOGIN * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_LS2CL_REP_LOGIN_SUCC , resp ) ;
2020-08-18 20:42:30 +00:00
int charCount = 2 ; // send 4 randomly generated characters for now
DEBUGLOG (
std : : cout < < " P_CL2LS_REQ_LOGIN: " < < std : : endl ;
std : : cout < < " \t Client version: " < < login - > iClientVerA < < " . " < < login - > iClientVerB < < " . " < < login - > iClientVerC < < std : : endl ;
std : : cout < < " \t Login type: " < < login - > iLoginType < < std : : endl ;
std : : cout < < " \t ID: " < < U16toU8 ( login - > szID ) < < " Password: " < < U16toU8 ( login - > szPassword ) < < std : : endl ;
)
2020-08-22 23:31:09 +00:00
resp . iCharCount = charCount ;
resp . iSlotNum = 1 ;
resp . iPaymentFlag = 1 ;
resp . iOpenBetaFlag = 0 ;
resp . uiSvrTime = getTime ( ) ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
// set username in resp packet
memcpy ( resp . szID , login - > szID , sizeof ( char16_t ) * 33 ) ;
// send the resp in with original key
sock - > sendPacket ( ( void * ) & resp , P_LS2CL_REP_LOGIN_SUCC , sizeof ( sP_LS2CL_REP_LOGIN_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
// update keys
2020-08-22 23:31:09 +00:00
sock - > setEKey ( CNSocketEncryption : : createNewKey ( resp . uiSvrTime , resp . iCharCount + 1 , resp . iSlotNum + 1 ) ) ;
2020-08-18 20:42:30 +00:00
sock - > setFEKey ( CNSocketEncryption : : createNewKey ( ( uint64_t ) ( * ( uint64_t * ) & CNSocketEncryption : : defaultKey [ 0 ] ) , login - > iClientVerC , 1 ) ) ;
loginSessions [ sock ] = CNLoginData ( ) ;
if ( settings : : LOGINRANDCHARACTERS ) {
// now send the characters :)
for ( int i = 0 ; i < charCount ; i + + ) {
2020-08-22 23:31:09 +00:00
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO ( ) ;
charInfo . iSlot = ( int8_t ) i + 1 ;
2020-08-25 02:17:47 +00:00
charInfo . iLevel = ( int16_t ) 36 ;
2020-08-22 23:31:09 +00:00
charInfo . sPC_Style . iPC_UID = rand ( ) ; // unique identifier for the character
charInfo . sPC_Style . iNameCheck = 1 ;
charInfo . sPC_Style . iGender = ( i % 2 ) + 1 ; // can be 1(boy) or 2(girl)
charInfo . sPC_Style . iFaceStyle = 1 ;
charInfo . sPC_Style . iHairStyle = 1 ;
charInfo . sPC_Style . iHairColor = ( rand ( ) % 19 ) + 1 ; // 1 - 19
charInfo . sPC_Style . iSkinColor = ( rand ( ) % 13 ) + 1 ; // 1 - 13
charInfo . sPC_Style . iEyeColor = ( rand ( ) % 6 ) + 1 ; // 1 - 6
charInfo . sPC_Style . iHeight = ( rand ( ) % 6 ) ; // 0 -5
charInfo . sPC_Style . iBody = ( rand ( ) % 4 ) ; // 0 - 3
charInfo . sPC_Style . iClass = 0 ;
charInfo . sPC_Style2 . iAppearanceFlag = 1 ;
charInfo . sPC_Style2 . iPayzoneFlag = 1 ;
charInfo . sPC_Style2 . iTutorialFlag = 1 ;
2020-08-18 20:42:30 +00:00
// past's town hall
2020-08-22 23:31:09 +00:00
charInfo . iX = settings : : SPAWN_X ;
charInfo . iY = settings : : SPAWN_Y ;
charInfo . iZ = settings : : SPAWN_Z ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
U8toU16 ( std : : string ( " Player " ) , charInfo . sPC_Style . szFirstName ) ;
U8toU16 ( std : : to_string ( i + 1 ) , charInfo . sPC_Style . szLastName ) ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
int64_t UID = charInfo . sPC_Style . iPC_UID ;
2020-08-18 20:42:30 +00:00
loginSessions [ sock ] . characters [ UID ] = Player ( ) ;
2020-08-22 23:31:09 +00:00
loginSessions [ sock ] . characters [ UID ] . level = charInfo . iLevel ;
2020-08-26 17:40:10 +00:00
loginSessions [ sock ] . characters [ UID ] . money = 9001 ;
2020-08-22 23:31:09 +00:00
loginSessions [ sock ] . characters [ UID ] . slot = charInfo . iSlot ;
2020-08-18 20:42:30 +00:00
loginSessions [ sock ] . characters [ UID ] . FEKey = sock - > getFEKey ( ) ;
2020-08-22 23:31:09 +00:00
loginSessions [ sock ] . characters [ UID ] . x = charInfo . iX ;
loginSessions [ sock ] . characters [ UID ] . y = charInfo . iY ;
loginSessions [ sock ] . characters [ UID ] . z = charInfo . iZ ;
loginSessions [ sock ] . characters [ UID ] . PCStyle = charInfo . sPC_Style ;
loginSessions [ sock ] . characters [ UID ] . PCStyle2 = charInfo . sPC_Style2 ;
2020-08-25 02:28:42 +00:00
loginSessions [ sock ] . characters [ UID ] . IsGM = settings : : GM ;
2020-08-18 20:42:30 +00:00
for ( int i = 0 ; i < AEQUIP_COUNT ; i + + ) {
2020-08-21 02:10:14 +00:00
// setup equips
2020-08-22 23:31:09 +00:00
charInfo . aEquip [ i ] . iID = 0 ;
charInfo . aEquip [ i ] . iType = i ;
charInfo . aEquip [ i ] . iOpt = 0 ;
loginSessions [ sock ] . characters [ UID ] . Equip [ i ] = charInfo . aEquip [ i ] ;
2020-08-18 20:42:30 +00:00
}
2020-08-21 02:10:14 +00:00
for ( int i = 0 ; i < AINVEN_COUNT ; i + + ) {
// setup inventories
loginSessions [ sock ] . characters [ UID ] . Inven [ i ] . iID = 0 ;
loginSessions [ sock ] . characters [ UID ] . Inven [ i ] . iType = 0 ;
loginSessions [ sock ] . characters [ UID ] . Inven [ i ] . iOpt = 0 ;
}
2020-08-18 20:42:30 +00:00
// set default to the first character
if ( i = = 0 )
loginSessions [ sock ] . selectedChar = UID ;
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & charInfo , P_LS2CL_REP_CHAR_INFO , sizeof ( sP_LS2CL_REP_CHAR_INFO ) ) ;
2020-08-18 20:42:30 +00:00
}
}
break ;
}
case P_CL2LS_REP_LIVE_CHECK : {
// stubbed, the client really doesn't care LOL
break ;
}
case P_CL2LS_REQ_CHECK_CHAR_NAME : {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2LS_REQ_CHECK_CHAR_NAME ) )
return ;
2020-08-18 20:42:30 +00:00
// naughty words allowed!!!!!!!! (also for some reason, the client will always show 'Player 0' if you manually type a name. It will show up for other connected players though)
sP_CL2LS_REQ_CHECK_CHAR_NAME * nameCheck = ( sP_CL2LS_REQ_CHECK_CHAR_NAME * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC , resp ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2LS_REQ_CHECK_CHAR_NAME: " < < std : : endl ;
std : : cout < < " \t FirstName: " < < U16toU8 ( nameCheck - > szFirstName ) < < " LastName: " < < U16toU8 ( nameCheck - > szLastName ) < < std : : endl ;
)
2020-08-22 23:31:09 +00:00
memcpy ( resp . szFirstName , nameCheck - > szFirstName , sizeof ( char16_t ) * 9 ) ;
memcpy ( resp . szLastName , nameCheck - > szLastName , sizeof ( char16_t ) * 17 ) ;
2020-08-18 20:42:30 +00:00
// fr*ck allowed!!!
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & resp , P_LS2CL_REP_CHECK_CHAR_NAME_SUCC , sizeof ( sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
break ;
}
case P_CL2LS_REQ_SAVE_CHAR_NAME : {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2LS_REQ_SAVE_CHAR_NAME ) )
return ;
2020-08-18 20:42:30 +00:00
sP_CL2LS_REQ_SAVE_CHAR_NAME * save = ( sP_CL2LS_REQ_SAVE_CHAR_NAME * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC , resp ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2LS_REQ_SAVE_CHAR_NAME: " < < std : : endl ;
std : : cout < < " \t Slot: " < < ( int ) save - > iSlotNum < < std : : endl ;
std : : cout < < " \t Gender: " < < ( int ) save - > iGender < < std : : endl ;
std : : cout < < " \t Name: " < < U16toU8 ( save - > szFirstName ) < < " " < < U16toU8 ( save - > szLastName ) < < std : : endl ;
)
2020-08-22 23:31:09 +00:00
resp . iSlotNum = save - > iSlotNum ;
resp . iGender = save - > iGender ;
memcpy ( resp . szFirstName , save - > szFirstName , sizeof ( char16_t ) * 9 ) ;
memcpy ( resp . szLastName , save - > szLastName , sizeof ( char16_t ) * 17 ) ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & resp , P_LS2CL_REP_SAVE_CHAR_NAME_SUCC , sizeof ( sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
break ;
}
case P_CL2LS_REQ_CHAR_CREATE : {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2LS_REQ_CHAR_CREATE ) )
return ;
2020-08-18 20:42:30 +00:00
sP_CL2LS_REQ_CHAR_CREATE * character = ( sP_CL2LS_REQ_CHAR_CREATE * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_LS2CL_REP_CHAR_CREATE_SUCC , resp ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2LS_REQ_CHAR_CREATE: " < < std : : endl ;
std : : cout < < " \t PC_UID: " < < character - > PCStyle . iPC_UID < < std : : endl ;
std : : cout < < " \t NameCheck: " < < ( int ) character - > PCStyle . iNameCheck < < std : : endl ;
std : : cout < < " \t Name: " < < U16toU8 ( character - > PCStyle . szFirstName ) < < " " < < U16toU8 ( character - > PCStyle . szLastName ) < < std : : endl ;
std : : cout < < " \t Gender: " < < ( int ) character - > PCStyle . iGender < < std : : endl ;
std : : cout < < " \t Face: " < < ( int ) character - > PCStyle . iFaceStyle < < std : : endl ;
std : : cout < < " \t Hair: " < < ( int ) character - > PCStyle . iHairStyle < < std : : endl ;
std : : cout < < " \t Hair Color: " < < ( int ) character - > PCStyle . iHairColor < < std : : endl ;
std : : cout < < " \t Skin Color: " < < ( int ) character - > PCStyle . iSkinColor < < std : : endl ;
std : : cout < < " \t Eye Color: " < < ( int ) character - > PCStyle . iEyeColor < < std : : endl ;
std : : cout < < " \t Height: " < < ( int ) character - > PCStyle . iHeight < < std : : endl ;
std : : cout < < " \t Body: " < < ( int ) character - > PCStyle . iBody < < std : : endl ;
std : : cout < < " \t Class: " < < ( int ) character - > PCStyle . iClass < < std : : endl ;
std : : cout < < " \t iEquipUBID: " < < ( int ) character - > sOn_Item . iEquipUBID < < std : : endl ;
std : : cout < < " \t iEquipLBID: " < < ( int ) character - > sOn_Item . iEquipLBID < < std : : endl ;
std : : cout < < " \t iEquipFootID: " < < ( int ) character - > sOn_Item . iEquipFootID < < std : : endl ;
)
2020-08-21 20:09:52 +00:00
int64_t UID = character - > PCStyle . iPC_UID ;
2020-08-22 00:38:10 +00:00
// commented and disabled for now
//bool BecomeGM;
2020-08-21 20:09:52 +00:00
2020-08-22 00:38:10 +00:00
//if (U16toU8(character->PCStyle.szFirstName) == settings::GMPASS) {
// BecomeGM = true;
// U8toU16("GM",character->PCStyle.szFirstName);
//} else {
// BecomeGM = false;
//}
2020-08-18 20:42:30 +00:00
character - > PCStyle . iNameCheck = 1 ;
2020-08-22 23:31:09 +00:00
resp . sPC_Style = character - > PCStyle ;
resp . sPC_Style2 . iAppearanceFlag = 1 ;
resp . sPC_Style2 . iTutorialFlag = 1 ;
resp . sPC_Style2 . iPayzoneFlag = 1 ;
2020-08-24 08:07:51 +00:00
resp . iLevel = 36 ;
2020-08-22 23:31:09 +00:00
resp . sOn_Item = character - > sOn_Item ;
2020-08-18 20:42:30 +00:00
loginSessions [ sock ] . characters [ UID ] = Player ( ) ;
2020-08-24 08:07:51 +00:00
loginSessions [ sock ] . characters [ UID ] . level = 36 ;
2020-08-26 17:40:10 +00:00
loginSessions [ sock ] . characters [ UID ] . money = 9001 ;
2020-08-18 20:42:30 +00:00
loginSessions [ sock ] . characters [ UID ] . FEKey = sock - > getFEKey ( ) ;
loginSessions [ sock ] . characters [ UID ] . PCStyle = character - > PCStyle ;
2020-08-19 20:00:39 +00:00
loginSessions [ sock ] . characters [ UID ] . PCStyle2 . iAppearanceFlag = 1 ;
loginSessions [ sock ] . characters [ UID ] . PCStyle2 . iPayzoneFlag = 1 ;
loginSessions [ sock ] . characters [ UID ] . PCStyle2 . iTutorialFlag = 1 ;
2020-08-18 20:42:30 +00:00
loginSessions [ sock ] . characters [ UID ] . x = settings : : SPAWN_X ;
loginSessions [ sock ] . characters [ UID ] . y = settings : : SPAWN_Y ;
loginSessions [ sock ] . characters [ UID ] . z = settings : : SPAWN_Z ;
loginSessions [ sock ] . characters [ UID ] . Equip [ 1 ] . iID = character - > sOn_Item . iEquipUBID ; // upper body
loginSessions [ sock ] . characters [ UID ] . Equip [ 1 ] . iType = 1 ;
loginSessions [ sock ] . characters [ UID ] . Equip [ 2 ] . iID = character - > sOn_Item . iEquipLBID ; // lower body
loginSessions [ sock ] . characters [ UID ] . Equip [ 2 ] . iType = 2 ;
loginSessions [ sock ] . characters [ UID ] . Equip [ 3 ] . iID = character - > sOn_Item . iEquipFootID ; // foot!
loginSessions [ sock ] . characters [ UID ] . Equip [ 3 ] . iType = 3 ;
2020-08-25 02:28:42 +00:00
loginSessions [ sock ] . characters [ UID ] . IsGM = settings : : GM ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & resp , P_LS2CL_REP_CHAR_CREATE_SUCC , sizeof ( sP_LS2CL_REP_CHAR_CREATE_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
break ;
}
case P_CL2LS_REQ_CHAR_SELECT : {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2LS_REQ_CHAR_SELECT ) )
return ;
2020-08-18 20:42:30 +00:00
// character selected
sP_CL2LS_REQ_CHAR_SELECT * chararacter = ( sP_CL2LS_REQ_CHAR_SELECT * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_LS2CL_REP_CHAR_SELECT_SUCC , resp ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2LS_REQ_CHAR_SELECT: " < < std : : endl ;
std : : cout < < " \t PC_UID: " < < chararacter - > iPC_UID < < std : : endl ;
)
loginSessions [ sock ] . selectedChar = chararacter - > iPC_UID ;
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & resp , P_LS2CL_REP_CHAR_SELECT_SUCC , sizeof ( sP_LS2CL_REP_CHAR_SELECT_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
break ;
}
case P_CL2LS_REQ_SHARD_SELECT : {
2020-08-19 00:11:31 +00:00
if ( data - > size ! = sizeof ( sP_CL2LS_REQ_SHARD_SELECT ) )
return ;
2020-08-18 20:42:30 +00:00
// tell client to connect to the shard server
sP_CL2LS_REQ_SHARD_SELECT * shard = ( sP_CL2LS_REQ_SHARD_SELECT * ) data - > buf ;
2020-08-23 00:26:18 +00:00
INITSTRUCT ( sP_LS2CL_REP_SHARD_SELECT_SUCC , resp ) ;
2020-08-18 20:42:30 +00:00
DEBUGLOG (
std : : cout < < " P_CL2LS_REQ_SHARD_SELECT: " < < std : : endl ;
2020-08-19 20:00:39 +00:00
std : : cout < < " \t Shard: " < < ( int ) shard - > ShardNum < < std : : endl ;
2020-08-18 20:42:30 +00:00
)
const char * SHARD_IP = settings : : SHARDSERVERIP . c_str ( ) ;
2020-08-22 23:31:09 +00:00
resp . iEnterSerialKey = rand ( ) ;
resp . g_FE_ServerPort = settings : : SHARDPORT ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
// copy IP to resp (this struct uses ASCII encoding so we don't have to goof around converting encodings)
memcpy ( resp . g_FE_ServerIP , SHARD_IP , strlen ( SHARD_IP ) ) ;
resp . g_FE_ServerIP [ strlen ( SHARD_IP ) ] = ' \0 ' ;
2020-08-18 20:42:30 +00:00
// pass player to CNSharedData
2020-08-22 23:31:09 +00:00
CNSharedData : : setPlayer ( resp . iEnterSerialKey , loginSessions [ sock ] . characters [ loginSessions [ sock ] . selectedChar ] ) ;
2020-08-18 20:42:30 +00:00
2020-08-22 23:31:09 +00:00
sock - > sendPacket ( ( void * ) & resp , P_LS2CL_REP_SHARD_SELECT_SUCC , sizeof ( sP_LS2CL_REP_SHARD_SELECT_SUCC ) ) ;
2020-08-18 20:42:30 +00:00
break ;
}
default :
2020-08-23 21:09:31 +00:00
if ( settings : : VERBOSITY )
std : : cerr < < " OpenFusion: LOGIN UNIMPLM ERR. PacketType: " < < Defines : : p2str ( CL2LS , data - > type ) < < " ( " < < data - > type < < " ) " < < std : : endl ;
2020-08-18 20:42:30 +00:00
break ;
}
}
2020-08-22 23:31:09 +00:00
void CNLoginServer : : newConnection ( CNSocket * cns ) {
cns - > setActiveKey ( SOCKETKEY_E ) ; // by default they accept keys encrypted with the default key
}
2020-08-18 20:42:30 +00:00
void CNLoginServer : : killConnection ( CNSocket * cns ) {
loginSessions . erase ( cns ) ;
2020-08-22 17:19:46 +00:00
}