mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 05:20:05 +00:00
Add NPC barking, seeing saved characters
This commit is contained in:
parent
50431024c9
commit
b239fb9331
@ -17,155 +17,82 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
printPacket(data, CL2LS);
|
printPacket(data, CL2LS);
|
||||||
|
|
||||||
switch (data->type) {
|
switch (data->type) {
|
||||||
case P_CL2LS_REQ_LOGIN: {
|
case P_CL2LS_REQ_LOGIN: {
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_LOGIN))
|
if (data->size != sizeof(sP_CL2LS_REQ_LOGIN))
|
||||||
return; // ignore the malformed packet
|
return; // ignore the malformed packet
|
||||||
|
|
||||||
sP_CL2LS_REQ_LOGIN* login = (sP_CL2LS_REQ_LOGIN*)data->buf;
|
sP_CL2LS_REQ_LOGIN* login = (sP_CL2LS_REQ_LOGIN*)data->buf;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
int errorCode = 0;
|
int errorCode = 0;
|
||||||
std::string userLogin = U16toU8(login->szID);
|
std::string userLogin = U16toU8(login->szID);
|
||||||
std::string userPassword = U16toU8(login->szPassword);
|
std::string userPassword = U16toU8(login->szPassword);
|
||||||
//checking regex
|
//checking regex
|
||||||
if (!Database::isLoginDataGood(userLogin, userPassword)) {
|
if (!Database::isLoginDataGood(userLogin, userPassword)) {
|
||||||
errorCode = (int)LOGINERRORID::login_error;
|
errorCode = (int)LOGINERRORID::login_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if user does not exist in db, add him to and send succ
|
//if user does not exist in db, add him to and send succ
|
||||||
else if (!Database::doesUserExist(U16toU8(login->szID))) {
|
else if (!Database::doesUserExist(U16toU8(login->szID))) {
|
||||||
Database::addAccount(U16toU8(login->szID), U16toU8(login->szPassword));
|
Database::addAccount(U16toU8(login->szID), U16toU8(login->szPassword));
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
//if user exists, check if password is correct
|
//if user exists, check if password is correct
|
||||||
else if (Database::isPasswordCorrect((U16toU8(login->szID)), U16toU8(login->szPassword))) {
|
else if (Database::isPasswordCorrect((U16toU8(login->szID)), U16toU8(login->szPassword))) {
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
errorCode = (int)LOGINERRORID::id_and_password_do_not_match;
|
errorCode = (int)LOGINERRORID::id_and_password_do_not_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
int userID = Database::getUserID(userLogin);
|
int userID = Database::getUserID(userLogin);
|
||||||
int charCount = Database::getUserSlotsNum(userID);
|
int charCount = Database::getUserSlotsNum(userID);
|
||||||
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_LOGIN_SUCC, resp);
|
INITSTRUCT(sP_LS2CL_REP_LOGIN_SUCC, resp);
|
||||||
// set username in resp packet
|
// set username in resp packet
|
||||||
memcpy(resp.szID, login->szID, sizeof(char16_t) * 33);
|
memcpy(resp.szID, login->szID, sizeof(char16_t) * 33);
|
||||||
|
|
||||||
resp.iCharCount = charCount;
|
resp.iCharCount = charCount;
|
||||||
resp.iSlotNum = 1;
|
resp.iSlotNum = 1;
|
||||||
resp.iPaymentFlag = 1;
|
resp.iPaymentFlag = 1;
|
||||||
resp.iOpenBetaFlag = 0;
|
resp.iOpenBetaFlag = 0;
|
||||||
resp.uiSvrTime = getTime();
|
resp.uiSvrTime = getTime();
|
||||||
|
|
||||||
// send the resp in with original key
|
// send the resp in with original key
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_SUCC, sizeof(sP_LS2CL_REP_LOGIN_SUCC));
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_SUCC, sizeof(sP_LS2CL_REP_LOGIN_SUCC));
|
||||||
|
|
||||||
// update keys
|
// update keys
|
||||||
sock->setEKey(CNSocketEncryption::createNewKey(resp.uiSvrTime, resp.iCharCount + 1, resp.iSlotNum + 1));
|
sock->setEKey(CNSocketEncryption::createNewKey(resp.uiSvrTime, resp.iCharCount + 1, resp.iSlotNum + 1));
|
||||||
sock->setFEKey(CNSocketEncryption::createNewKey((uint64_t)(*(uint64_t*)&CNSocketEncryption::defaultKey[0]), login->iClientVerC, 1));
|
sock->setFEKey(CNSocketEncryption::createNewKey((uint64_t)(*(uint64_t*)&CNSocketEncryption::defaultKey[0]), login->iClientVerC, 1));
|
||||||
|
|
||||||
loginSessions[sock] = CNLoginData();
|
loginSessions[sock] = CNLoginData();
|
||||||
loginSessions[sock].userID = userID;
|
loginSessions[sock].userID = userID;
|
||||||
|
|
||||||
// now send the characters :)
|
// now send the characters :)
|
||||||
|
|
||||||
/*if (charCount > 0) {
|
|
||||||
|
|
||||||
std::list<Player> characters = Database::getCharacters(loginSessions[sock].userID);
|
if (charCount > 0) {
|
||||||
std::list<Player>::iterator it;
|
|
||||||
for (it = characters.begin(); it != characters.end(); it++)
|
|
||||||
{
|
|
||||||
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
|
|
||||||
|
|
||||||
charInfo.iSlot = (int8_t)it->slot;
|
std::list<Player> characters = Database::getCharacters(loginSessions[sock].userID);
|
||||||
charInfo.iLevel = (int16_t)it->level;
|
std::list<Player>::iterator it;
|
||||||
charInfo.sPC_Style = it->PCStyle;
|
for (it = characters.begin(); it != characters.end(); it++)
|
||||||
charInfo.sPC_Style2 = it->PCStyle2;
|
{
|
||||||
|
|
||||||
// position
|
|
||||||
charInfo.iX = it->x;
|
|
||||||
charInfo.iY = it->y;
|
|
||||||
charInfo.iZ = it->z;
|
|
||||||
|
|
||||||
//save character in session (for char select)
|
|
||||||
int64_t UID = charInfo.sPC_Style.iPC_UID;
|
|
||||||
loginSessions[sock].characters[UID] = Player();
|
|
||||||
loginSessions[sock].characters[UID].level = charInfo.iLevel;
|
|
||||||
loginSessions[sock].characters[UID].slot = charInfo.iSlot;
|
|
||||||
loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
|
|
||||||
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;
|
|
||||||
loginSessions[sock].characters[UID].IsGM = false;
|
|
||||||
loginSessions[sock].characters[UID].money = 9001;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Player test = loginSessions[sock].characters[UID];
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
//equip char creation clothes and lightning rifle
|
|
||||||
charInfo.aEquip[i] = it->Equip[i];
|
|
||||||
loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 5; i < AEQUIP_COUNT; i++) {
|
|
||||||
// empty equips
|
|
||||||
charInfo.aEquip[i].iID = 0;
|
|
||||||
charInfo.aEquip[i].iType = i;
|
|
||||||
charInfo.aEquip[i].iOpt = 0;
|
|
||||||
loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set default to the first character
|
|
||||||
if (it == characters.begin())
|
|
||||||
loginSessions[sock].selectedChar = UID;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
|
|
||||||
|
|
||||||
for (int i = 0; i < charCount; i++) {
|
|
||||||
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
|
sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
|
||||||
charInfo.iSlot = (int8_t)i + 1;
|
|
||||||
charInfo.iLevel = (int16_t)36;
|
|
||||||
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;
|
|
||||||
|
|
||||||
// past's town hall
|
charInfo.iSlot = (int8_t)it->slot;
|
||||||
charInfo.iX = settings::SPAWN_X;
|
charInfo.iLevel = (int16_t)it->level;
|
||||||
charInfo.iY = settings::SPAWN_Y;
|
charInfo.sPC_Style = it->PCStyle;
|
||||||
charInfo.iZ = settings::SPAWN_Z;
|
charInfo.sPC_Style2 = it->PCStyle2;
|
||||||
|
|
||||||
U8toU16(std::string("Player"), charInfo.sPC_Style.szFirstName);
|
// position
|
||||||
U8toU16(std::to_string(i + 1), charInfo.sPC_Style.szLastName);
|
charInfo.iX = it->x;
|
||||||
|
charInfo.iY = it->y;
|
||||||
|
charInfo.iZ = it->z;
|
||||||
|
|
||||||
|
//save character in session (for char select)
|
||||||
int64_t UID = charInfo.sPC_Style.iPC_UID;
|
int64_t UID = charInfo.sPC_Style.iPC_UID;
|
||||||
loginSessions[sock].characters[UID] = Player();
|
loginSessions[sock].characters[UID] = Player();
|
||||||
loginSessions[sock].characters[UID].level = charInfo.iLevel;
|
loginSessions[sock].characters[UID].level = charInfo.iLevel;
|
||||||
loginSessions[sock].characters[UID].money = 9001;
|
|
||||||
loginSessions[sock].characters[UID].slot = charInfo.iSlot;
|
loginSessions[sock].characters[UID].slot = charInfo.iSlot;
|
||||||
loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
|
loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
|
||||||
loginSessions[sock].characters[UID].x = charInfo.iX;
|
loginSessions[sock].characters[UID].x = charInfo.iX;
|
||||||
@ -173,258 +100,334 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
|
|||||||
loginSessions[sock].characters[UID].z = charInfo.iZ;
|
loginSessions[sock].characters[UID].z = charInfo.iZ;
|
||||||
loginSessions[sock].characters[UID].PCStyle = charInfo.sPC_Style;
|
loginSessions[sock].characters[UID].PCStyle = charInfo.sPC_Style;
|
||||||
loginSessions[sock].characters[UID].PCStyle2 = charInfo.sPC_Style2;
|
loginSessions[sock].characters[UID].PCStyle2 = charInfo.sPC_Style2;
|
||||||
loginSessions[sock].characters[UID].isTrading = false;
|
loginSessions[sock].characters[UID].IsGM = false;
|
||||||
loginSessions[sock].characters[UID].isTradeConfirm = false;
|
loginSessions[sock].characters[UID].money = 9001;
|
||||||
loginSessions[sock].characters[UID].IsGM = settings::GM;
|
|
||||||
|
|
||||||
for (int i = 0; i < AEQUIP_COUNT; i++) {
|
|
||||||
// setup equips
|
|
||||||
|
Player test = loginSessions[sock].characters[UID];
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
//equip char creation clothes and lightning rifle
|
||||||
|
charInfo.aEquip[i] = it->Equip[i];
|
||||||
|
loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 5; i < AEQUIP_COUNT; i++) {
|
||||||
|
// empty equips
|
||||||
charInfo.aEquip[i].iID = 0;
|
charInfo.aEquip[i].iID = 0;
|
||||||
charInfo.aEquip[i].iType = i;
|
charInfo.aEquip[i].iType = i;
|
||||||
charInfo.aEquip[i].iOpt = 0;
|
charInfo.aEquip[i].iOpt = 0;
|
||||||
loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
|
loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < AINVEN_COUNT; i++) {
|
for (int i = 0; i < AINVEN_COUNT; i++) {
|
||||||
// setup inventories
|
// setup inventories
|
||||||
loginSessions[sock].characters[UID].Inven[i].iID = 0;
|
loginSessions[sock].characters[UID].Inven[i].iID = 0;
|
||||||
loginSessions[sock].characters[UID].Inven[i].iType = 0;
|
loginSessions[sock].characters[UID].Inven[i].iType = 0;
|
||||||
loginSessions[sock].characters[UID].Inven[i].iOpt = 0;
|
loginSessions[sock].characters[UID].Inven[i].iOpt = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
// set default to the first character
|
||||||
|
if (it == characters.begin())
|
||||||
|
loginSessions[sock].selectedChar = UID;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Failure
|
//for (int i = 0; i < charCount; i++) {
|
||||||
else {
|
// sP_LS2CL_REP_CHAR_INFO charInfo = sP_LS2CL_REP_CHAR_INFO();
|
||||||
|
// charInfo.iSlot = (int8_t)i + 1;
|
||||||
|
// charInfo.iLevel = (int16_t)36;
|
||||||
|
// 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;
|
||||||
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp);
|
// // past's town hall
|
||||||
|
// charInfo.iX = settings::SPAWN_X;
|
||||||
|
// charInfo.iY = settings::SPAWN_Y;
|
||||||
|
// charInfo.iZ = settings::SPAWN_Z;
|
||||||
|
|
||||||
memcpy(resp.szID, login->szID, sizeof(char16_t) * 33);
|
// U8toU16(std::string("Player"), charInfo.sPC_Style.szFirstName);
|
||||||
resp.iErrorCode = errorCode;
|
// U8toU16(std::to_string(i + 1), charInfo.sPC_Style.szLastName);
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_FAIL, sizeof(sP_LS2CL_REP_LOGIN_FAIL));
|
// int64_t UID = charInfo.sPC_Style.iPC_UID;
|
||||||
}
|
// loginSessions[sock].characters[UID] = Player();
|
||||||
|
// loginSessions[sock].characters[UID].level = charInfo.iLevel;
|
||||||
|
// loginSessions[sock].characters[UID].money = 9001;
|
||||||
|
// loginSessions[sock].characters[UID].slot = charInfo.iSlot;
|
||||||
|
// loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
|
||||||
|
// 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;
|
||||||
|
// loginSessions[sock].characters[UID].isTrading = false;
|
||||||
|
// loginSessions[sock].characters[UID].isTradeConfirm = false;
|
||||||
|
// loginSessions[sock].characters[UID].IsGM = settings::GM;
|
||||||
|
|
||||||
break;
|
// for (int i = 0; i < AEQUIP_COUNT; i++) {
|
||||||
|
// // setup equips
|
||||||
|
// charInfo.aEquip[i].iID = 0;
|
||||||
|
// charInfo.aEquip[i].iType = i;
|
||||||
|
// charInfo.aEquip[i].iOpt = 0;
|
||||||
|
// loginSessions[sock].characters[UID].Equip[i] = charInfo.aEquip[i];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
case P_CL2LS_REP_LIVE_CHECK: {
|
//Failure
|
||||||
// stubbed, the client really doesn't care LOL
|
else {
|
||||||
break;
|
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp);
|
||||||
|
|
||||||
|
memcpy(resp.szID, login->szID, sizeof(char16_t) * 33);
|
||||||
|
resp.iErrorCode = errorCode;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_FAIL, sizeof(sP_LS2CL_REP_LOGIN_FAIL));
|
||||||
}
|
}
|
||||||
case P_CL2LS_REQ_CHECK_CHAR_NAME: {
|
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_CHECK_CHAR_NAME))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
//check if name is occupied
|
|
||||||
if (Database::isNameFree(U16toU8(nameCheck->szFirstName), U16toU8(nameCheck->szLastName)))
|
|
||||||
{
|
|
||||||
|
|
||||||
// naughty words allowed!!!!!!!! (also for some reason, the client will always show 'Player + ID' if you manually type a name. It will show up for other connected players though)
|
break;
|
||||||
|
}
|
||||||
|
case P_CL2LS_REP_LIVE_CHECK: {
|
||||||
|
// stubbed, the client really doesn't care LOL
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case P_CL2LS_REQ_CHECK_CHAR_NAME: {
|
||||||
|
if (data->size != sizeof(sP_CL2LS_REQ_CHECK_CHAR_NAME))
|
||||||
|
return;
|
||||||
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC, resp);
|
// 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;
|
||||||
|
//check if name is occupied
|
||||||
|
if (Database::isNameFree(U16toU8(nameCheck->szFirstName), U16toU8(nameCheck->szLastName)))
|
||||||
|
{
|
||||||
|
|
||||||
DEBUGLOG(
|
// naughty words allowed!!!!!!!! (also for some reason, the client will always show 'Player + ID' if you manually type a name. It will show up for other connected players though)
|
||||||
std::cout << "P_CL2LS_REQ_CHECK_CHAR_NAME:" << std::endl;
|
|
||||||
std::cout << "\tFirstName: " << U16toU8(nameCheck->szFirstName) << " LastName: " << U16toU8(nameCheck->szLastName) << std::endl;
|
|
||||||
)
|
|
||||||
|
|
||||||
memcpy(resp.szFirstName, nameCheck->szFirstName, sizeof(char16_t) * 9);
|
INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC, resp);
|
||||||
memcpy(resp.szLastName, nameCheck->szLastName, sizeof(char16_t) * 17);
|
|
||||||
|
|
||||||
// fr*ck allowed!!!
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL, resp);
|
|
||||||
resp.iErrorCode = 1;
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_FAIL, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
case P_CL2LS_REQ_SAVE_CHAR_NAME: {
|
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_NAME))
|
|
||||||
return;
|
|
||||||
|
|
||||||
sP_CL2LS_REQ_SAVE_CHAR_NAME* save = (sP_CL2LS_REQ_SAVE_CHAR_NAME*)data->buf;
|
|
||||||
Database::createCharacter(save, loginSessions[sock].userID);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC, resp);
|
|
||||||
|
|
||||||
DEBUGLOG(
|
DEBUGLOG(
|
||||||
std::cout << "P_CL2LS_REQ_SAVE_CHAR_NAME:" << std::endl;
|
std::cout << "P_CL2LS_REQ_CHECK_CHAR_NAME:" << std::endl;
|
||||||
std::cout << "\tSlot: " << (int)save->iSlotNum << std::endl;
|
std::cout << "\tFirstName: " << U16toU8(nameCheck->szFirstName) << " LastName: " << U16toU8(nameCheck->szLastName) << std::endl;
|
||||||
std::cout << "\tName: " << U16toU8(save->szFirstName) << " " << U16toU8(save->szLastName) << std::endl;
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
memcpy(resp.szFirstName, nameCheck->szFirstName, sizeof(char16_t) * 9);
|
||||||
|
memcpy(resp.szLastName, nameCheck->szLastName, sizeof(char16_t) * 17);
|
||||||
|
|
||||||
|
// fr*ck allowed!!!
|
||||||
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL, resp);
|
||||||
|
resp.iErrorCode = 1;
|
||||||
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_FAIL, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
case P_CL2LS_REQ_SAVE_CHAR_NAME: {
|
||||||
|
if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_NAME))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2LS_REQ_SAVE_CHAR_NAME* save = (sP_CL2LS_REQ_SAVE_CHAR_NAME*)data->buf;
|
||||||
|
Database::createCharacter(save, loginSessions[sock].userID);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC, resp);
|
||||||
|
|
||||||
|
DEBUGLOG(
|
||||||
|
std::cout << "P_CL2LS_REQ_SAVE_CHAR_NAME:" << std::endl;
|
||||||
|
std::cout << "\tSlot: " << (int)save->iSlotNum << std::endl;
|
||||||
|
std::cout << "\tName: " << U16toU8(save->szFirstName) << " " << U16toU8(save->szLastName) << std::endl;
|
||||||
|
)
|
||||||
|
|
||||||
resp.iSlotNum = save->iSlotNum;
|
resp.iSlotNum = save->iSlotNum;
|
||||||
resp.iGender = save->iGender;
|
resp.iGender = save->iGender;
|
||||||
resp.iPC_UID = Database::getCharacterID(loginSessions[sock].userID, save->iSlotNum);
|
resp.iPC_UID = Database::getCharacterID(loginSessions[sock].userID, save->iSlotNum);
|
||||||
memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t) * 9);
|
memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t) * 9);
|
||||||
memcpy(resp.szLastName, save->szLastName, sizeof(char16_t) * 17);
|
memcpy(resp.szLastName, save->szLastName, sizeof(char16_t) * 17);
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_SAVE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC));
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_SAVE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_SAVE_CHAR_NAME_SUCC));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P_CL2LS_REQ_CHAR_CREATE: {
|
case P_CL2LS_REQ_CHAR_CREATE: {
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_CREATE))
|
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_CREATE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sP_CL2LS_REQ_CHAR_CREATE* character = (sP_CL2LS_REQ_CHAR_CREATE*)data->buf;
|
|
||||||
Database::finishCharacter(character);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHAR_CREATE_SUCC, resp);
|
sP_CL2LS_REQ_CHAR_CREATE* character = (sP_CL2LS_REQ_CHAR_CREATE*)data->buf;
|
||||||
|
Database::finishCharacter(character);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_CHAR_CREATE_SUCC, resp);
|
||||||
|
|
||||||
|
DEBUGLOG(
|
||||||
|
std::cout << "P_CL2LS_REQ_CHAR_CREATE:" << std::endl;
|
||||||
|
std::cout << "\tPC_UID: " << character->PCStyle.iPC_UID << std::endl;
|
||||||
|
std::cout << "\tNameCheck: " << (int)character->PCStyle.iNameCheck << std::endl;
|
||||||
|
std::cout << "\tName: " << U16toU8(character->PCStyle.szFirstName) << " " << U16toU8(character->PCStyle.szLastName) << std::endl;
|
||||||
|
std::cout << "\tGender: " << (int)character->PCStyle.iGender << std::endl;
|
||||||
|
std::cout << "\tFace: " << (int)character->PCStyle.iFaceStyle << std::endl;
|
||||||
|
std::cout << "\tHair: " << (int)character->PCStyle.iHairStyle << std::endl;
|
||||||
|
std::cout << "\tHair Color: " << (int)character->PCStyle.iHairColor << std::endl;
|
||||||
|
std::cout << "\tSkin Color: " << (int)character->PCStyle.iSkinColor << std::endl;
|
||||||
|
std::cout << "\tEye Color: " << (int)character->PCStyle.iEyeColor << std::endl;
|
||||||
|
std::cout << "\tHeight: " << (int)character->PCStyle.iHeight << std::endl;
|
||||||
|
std::cout << "\tBody: " << (int)character->PCStyle.iBody << std::endl;
|
||||||
|
std::cout << "\tClass: " << (int)character->PCStyle.iClass << std::endl;
|
||||||
|
std::cout << "\tiEquipUBID: " << (int)character->sOn_Item.iEquipUBID << std::endl;
|
||||||
|
std::cout << "\tiEquipLBID: " << (int)character->sOn_Item.iEquipLBID << std::endl;
|
||||||
|
std::cout << "\tiEquipFootID: " << (int)character->sOn_Item.iEquipFootID << std::endl;
|
||||||
|
)
|
||||||
|
|
||||||
DEBUGLOG(
|
|
||||||
std::cout << "P_CL2LS_REQ_CHAR_CREATE:" << std::endl;
|
|
||||||
std::cout << "\tPC_UID: " << character->PCStyle.iPC_UID << std::endl;
|
|
||||||
std::cout << "\tNameCheck: " << (int)character->PCStyle.iNameCheck << std::endl;
|
|
||||||
std::cout << "\tName: " << U16toU8(character->PCStyle.szFirstName) << " " << U16toU8(character->PCStyle.szLastName) << std::endl;
|
|
||||||
std::cout << "\tGender: " << (int)character->PCStyle.iGender << std::endl;
|
|
||||||
std::cout << "\tFace: " << (int)character->PCStyle.iFaceStyle << std::endl;
|
|
||||||
std::cout << "\tHair: " << (int)character->PCStyle.iHairStyle << std::endl;
|
|
||||||
std::cout << "\tHair Color: " << (int)character->PCStyle.iHairColor << std::endl;
|
|
||||||
std::cout << "\tSkin Color: " << (int)character->PCStyle.iSkinColor << std::endl;
|
|
||||||
std::cout << "\tEye Color: " << (int)character->PCStyle.iEyeColor << std::endl;
|
|
||||||
std::cout << "\tHeight: " << (int)character->PCStyle.iHeight << std::endl;
|
|
||||||
std::cout << "\tBody: " << (int)character->PCStyle.iBody << std::endl;
|
|
||||||
std::cout << "\tClass: " << (int)character->PCStyle.iClass << std::endl;
|
|
||||||
std::cout << "\tiEquipUBID: " << (int)character->sOn_Item.iEquipUBID << std::endl;
|
|
||||||
std::cout << "\tiEquipLBID: " << (int)character->sOn_Item.iEquipLBID << std::endl;
|
|
||||||
std::cout << "\tiEquipFootID: " << (int)character->sOn_Item.iEquipFootID << std::endl;
|
|
||||||
)
|
|
||||||
|
|
||||||
int64_t UID = character->PCStyle.iPC_UID;
|
int64_t UID = character->PCStyle.iPC_UID;
|
||||||
|
|
||||||
// commented and disabled for now
|
|
||||||
//bool BecomeGM;
|
|
||||||
|
|
||||||
//if (U16toU8(character->PCStyle.szFirstName) == settings::GMPASS) {
|
|
||||||
// BecomeGM = true;
|
|
||||||
// U8toU16("GM",character->PCStyle.szFirstName);
|
|
||||||
//} else {
|
|
||||||
// BecomeGM = false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
character->PCStyle.iNameCheck = 1;
|
// commented and disabled for now
|
||||||
resp.sPC_Style = character->PCStyle;
|
//bool BecomeGM;
|
||||||
resp.sPC_Style2.iAppearanceFlag = 1;
|
|
||||||
resp.sPC_Style2.iTutorialFlag = 0;
|
|
||||||
resp.sPC_Style2.iPayzoneFlag = 1;
|
|
||||||
resp.iLevel = 36;
|
|
||||||
resp.sOn_Item = character->sOn_Item;
|
|
||||||
|
|
||||||
loginSessions[sock].characters[UID] = Player();
|
//if (U16toU8(character->PCStyle.szFirstName) == settings::GMPASS) {
|
||||||
loginSessions[sock].characters[UID].level = 36;
|
// BecomeGM = true;
|
||||||
loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
|
// U8toU16("GM",character->PCStyle.szFirstName);
|
||||||
loginSessions[sock].characters[UID].PCStyle = character->PCStyle;
|
//} else {
|
||||||
loginSessions[sock].characters[UID].PCStyle2.iAppearanceFlag = 1;
|
// BecomeGM = false;
|
||||||
loginSessions[sock].characters[UID].PCStyle2.iPayzoneFlag = 1;
|
//}
|
||||||
loginSessions[sock].characters[UID].PCStyle2.iTutorialFlag = 1;
|
|
||||||
loginSessions[sock].characters[UID].x = settings::SPAWN_X;
|
character->PCStyle.iNameCheck = 1;
|
||||||
loginSessions[sock].characters[UID].y = settings::SPAWN_Y;
|
resp.sPC_Style = character->PCStyle;
|
||||||
loginSessions[sock].characters[UID].z = settings::SPAWN_Z;
|
resp.sPC_Style2.iAppearanceFlag = 1;
|
||||||
loginSessions[sock].characters[UID].Equip[1].iID = character->sOn_Item.iEquipUBID; // upper body
|
resp.sPC_Style2.iTutorialFlag = 0;
|
||||||
loginSessions[sock].characters[UID].Equip[1].iType = 1;
|
resp.sPC_Style2.iPayzoneFlag = 1;
|
||||||
loginSessions[sock].characters[UID].Equip[2].iID = character->sOn_Item.iEquipLBID; // lower body
|
resp.iLevel = 36;
|
||||||
loginSessions[sock].characters[UID].Equip[2].iType = 2;
|
resp.sOn_Item = character->sOn_Item;
|
||||||
loginSessions[sock].characters[UID].Equip[3].iID = character->sOn_Item.iEquipFootID; // foot!
|
|
||||||
loginSessions[sock].characters[UID].Equip[3].iType = 3;
|
loginSessions[sock].characters[UID] = Player();
|
||||||
loginSessions[sock].characters[UID].IsGM = false;
|
loginSessions[sock].characters[UID].level = 36;
|
||||||
loginSessions[sock].characters[UID].Equip[3].iType = 3;
|
loginSessions[sock].characters[UID].FEKey = sock->getFEKey();
|
||||||
loginSessions[sock].characters[UID].isTrading = false;
|
loginSessions[sock].characters[UID].PCStyle = character->PCStyle;
|
||||||
loginSessions[sock].characters[UID].isTradeConfirm = false;
|
loginSessions[sock].characters[UID].PCStyle2.iAppearanceFlag = 1;
|
||||||
loginSessions[sock].characters[UID].IsGM = settings::GM;
|
loginSessions[sock].characters[UID].PCStyle2.iPayzoneFlag = 1;
|
||||||
|
loginSessions[sock].characters[UID].PCStyle2.iTutorialFlag = 1;
|
||||||
|
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;
|
||||||
|
loginSessions[sock].characters[UID].IsGM = false;
|
||||||
|
loginSessions[sock].characters[UID].Equip[3].iType = 3;
|
||||||
|
loginSessions[sock].characters[UID].isTrading = false;
|
||||||
|
loginSessions[sock].characters[UID].isTradeConfirm = false;
|
||||||
|
loginSessions[sock].characters[UID].IsGM = settings::GM;
|
||||||
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_CREATE_SUCC, sizeof(sP_LS2CL_REP_CHAR_CREATE_SUCC));
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_CREATE_SUCC, sizeof(sP_LS2CL_REP_CHAR_CREATE_SUCC));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case P_CL2LS_REQ_CHAR_DELETE: {
|
||||||
|
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_DELETE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sP_CL2LS_REQ_CHAR_DELETE* del = (sP_CL2LS_REQ_CHAR_DELETE*)data->buf;
|
||||||
|
int operationResult = Database::deleteCharacter(del->iPC_UID, loginSessions[sock].userID);
|
||||||
|
|
||||||
|
// success
|
||||||
|
if (operationResult > 0) {
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_SUCC, resp);
|
||||||
|
resp.iSlotNum = operationResult;
|
||||||
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC));
|
||||||
}
|
}
|
||||||
case P_CL2LS_REQ_CHAR_DELETE: {
|
else {
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_DELETE))
|
// failure
|
||||||
return;
|
// client doesnt't care about this packet and softlocks
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_FAIL, resp);
|
||||||
sP_CL2LS_REQ_CHAR_DELETE* del = (sP_CL2LS_REQ_CHAR_DELETE*)data->buf;
|
resp.iErrorCode = 0;
|
||||||
int operationResult = Database::deleteCharacter(del->iPC_UID, loginSessions[sock].userID);
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_FAIL, sizeof(sP_LS2CL_REP_CHAR_DELETE_FAIL));
|
||||||
|
|
||||||
// success
|
|
||||||
if (operationResult > 0) {
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_SUCC, resp);
|
|
||||||
resp.iSlotNum = operationResult;
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC));
|
|
||||||
} else {
|
|
||||||
// failure
|
|
||||||
// client doesnt't care about this packet and softlocks
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHAR_DELETE_FAIL, resp);
|
|
||||||
resp.iErrorCode = 0;
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_FAIL, sizeof(sP_LS2CL_REP_CHAR_DELETE_FAIL));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case P_CL2LS_REQ_CHAR_SELECT: {
|
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_SELECT))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// character selected
|
|
||||||
sP_CL2LS_REQ_CHAR_SELECT* chararacter = (sP_CL2LS_REQ_CHAR_SELECT*)data->buf;
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_CHAR_SELECT_SUCC, resp);
|
|
||||||
|
|
||||||
DEBUGLOG(
|
break;
|
||||||
std::cout << "P_CL2LS_REQ_CHAR_SELECT:" << std::endl;
|
}
|
||||||
std::cout << "\tPC_UID: " << chararacter->iPC_UID << std::endl;
|
case P_CL2LS_REQ_CHAR_SELECT: {
|
||||||
)
|
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_SELECT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// character selected
|
||||||
|
sP_CL2LS_REQ_CHAR_SELECT* chararacter = (sP_CL2LS_REQ_CHAR_SELECT*)data->buf;
|
||||||
|
INITSTRUCT(sP_LS2CL_REP_CHAR_SELECT_SUCC, resp);
|
||||||
|
|
||||||
|
DEBUGLOG(
|
||||||
|
std::cout << "P_CL2LS_REQ_CHAR_SELECT:" << std::endl;
|
||||||
|
std::cout << "\tPC_UID: " << chararacter->iPC_UID << std::endl;
|
||||||
|
)
|
||||||
|
|
||||||
loginSessions[sock].selectedChar = chararacter->iPC_UID;
|
loginSessions[sock].selectedChar = chararacter->iPC_UID;
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_SELECT_SUCC, sizeof(sP_LS2CL_REP_CHAR_SELECT_SUCC));
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_SELECT_SUCC, sizeof(sP_LS2CL_REP_CHAR_SELECT_SUCC));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P_CL2LS_REQ_SHARD_SELECT: {
|
case P_CL2LS_REQ_SHARD_SELECT: {
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_SHARD_SELECT))
|
if (data->size != sizeof(sP_CL2LS_REQ_SHARD_SELECT))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// tell client to connect to the shard server
|
|
||||||
sP_CL2LS_REQ_SHARD_SELECT* shard = (sP_CL2LS_REQ_SHARD_SELECT*)data->buf;
|
|
||||||
INITSTRUCT(sP_LS2CL_REP_SHARD_SELECT_SUCC, resp);
|
|
||||||
|
|
||||||
DEBUGLOG(
|
// tell client to connect to the shard server
|
||||||
std::cout << "P_CL2LS_REQ_SHARD_SELECT:" << std::endl;
|
sP_CL2LS_REQ_SHARD_SELECT* shard = (sP_CL2LS_REQ_SHARD_SELECT*)data->buf;
|
||||||
std::cout << "\tShard: " << (int)shard->ShardNum << std::endl;
|
INITSTRUCT(sP_LS2CL_REP_SHARD_SELECT_SUCC, resp);
|
||||||
)
|
|
||||||
|
DEBUGLOG(
|
||||||
|
std::cout << "P_CL2LS_REQ_SHARD_SELECT:" << std::endl;
|
||||||
|
std::cout << "\tShard: " << (int)shard->ShardNum << std::endl;
|
||||||
|
)
|
||||||
|
|
||||||
const char* SHARD_IP = settings::SHARDSERVERIP.c_str();
|
const char* SHARD_IP = settings::SHARDSERVERIP.c_str();
|
||||||
resp.iEnterSerialKey = rand();
|
resp.iEnterSerialKey = rand();
|
||||||
resp.g_FE_ServerPort = settings::SHARDPORT;
|
resp.g_FE_ServerPort = settings::SHARDPORT;
|
||||||
|
|
||||||
// copy IP to resp (this struct uses ASCII encoding so we don't have to goof around converting encodings)
|
// 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));
|
memcpy(resp.g_FE_ServerIP, SHARD_IP, strlen(SHARD_IP));
|
||||||
resp.g_FE_ServerIP[strlen(SHARD_IP)] = '\0';
|
resp.g_FE_ServerIP[strlen(SHARD_IP)] = '\0';
|
||||||
|
|
||||||
// pass player to CNSharedData
|
// pass player to CNSharedData
|
||||||
CNSharedData::setPlayer(resp.iEnterSerialKey, loginSessions[sock].characters[loginSessions[sock].selectedChar]);
|
CNSharedData::setPlayer(resp.iEnterSerialKey, loginSessions[sock].characters[loginSessions[sock].selectedChar]);
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_LS2CL_REP_SHARD_SELECT_SUCC, sizeof(sP_LS2CL_REP_SHARD_SELECT_SUCC));
|
sock->sendPacket((void*)&resp, P_LS2CL_REP_SHARD_SELECT_SUCC, sizeof(sP_LS2CL_REP_SHARD_SELECT_SUCC));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case P_CL2LS_REQ_SAVE_CHAR_TUTOR: {
|
case P_CL2LS_REQ_SAVE_CHAR_TUTOR: {
|
||||||
if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_TUTOR))
|
if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_TUTOR))
|
||||||
return;
|
return;
|
||||||
sP_CL2LS_REQ_SAVE_CHAR_TUTOR* save = (sP_CL2LS_REQ_SAVE_CHAR_TUTOR*)data->buf;
|
sP_CL2LS_REQ_SAVE_CHAR_TUTOR* save = (sP_CL2LS_REQ_SAVE_CHAR_TUTOR*)data->buf;
|
||||||
Database::finishTutorial(save->iPC_UID);
|
Database::finishTutorial(save->iPC_UID);
|
||||||
loginSessions[sock].characters[save->iPC_UID].PCStyle2.iTutorialFlag = 1;
|
loginSessions[sock].characters[save->iPC_UID].PCStyle2.iTutorialFlag = 1;
|
||||||
loginSessions[sock].characters[save->iPC_UID].Equip[0].iID = 328;
|
loginSessions[sock].characters[save->iPC_UID].Equip[0].iID = 328;
|
||||||
loginSessions[sock].characters[save->iPC_UID].Equip[0].iType = 0;
|
loginSessions[sock].characters[save->iPC_UID].Equip[0].iType = 0;
|
||||||
loginSessions[sock].characters[save->iPC_UID].Equip[0].iOpt = 1;
|
loginSessions[sock].characters[save->iPC_UID].Equip[0].iOpt = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (settings::VERBOSITY)
|
if (settings::VERBOSITY)
|
||||||
std::cerr << "OpenFusion: LOGIN UNIMPLM ERR. PacketType: " << Defines::p2str(CL2LS, data->type) << " (" << data->type << ")" << std::endl;
|
std::cerr << "OpenFusion: LOGIN UNIMPLM ERR. PacketType: " << Defines::p2str(CL2LS, data->type) << " (" << data->type << ")" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
633
src/Database.cpp
633
src/Database.cpp
@ -15,409 +15,410 @@
|
|||||||
sqlite3pp::database db;
|
sqlite3pp::database db;
|
||||||
|
|
||||||
void Database::open() {
|
void Database::open() {
|
||||||
//checking if database file exists
|
//checking if database file exists
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
file.open("data.db");
|
file.open("data.db");
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
file.close();
|
file.close();
|
||||||
// if exists, assign it
|
// if exists, assign it
|
||||||
db = sqlite3pp::database("data.db");
|
db = sqlite3pp::database("data.db");
|
||||||
DEBUGLOG(std::cout << "Database in operation" << std::endl; )
|
DEBUGLOG(std::cout << "Database in operation" << std::endl; )
|
||||||
} else {
|
}
|
||||||
// if doesn't, create all the tables
|
else {
|
||||||
DEBUGLOG(std::cout << "Creating new database" << std::endl;)
|
// if doesn't, create all the tables
|
||||||
db = sqlite3pp::database("data.db");
|
DEBUGLOG(std::cout << "Creating new database" << std::endl;)
|
||||||
|
db = sqlite3pp::database("data.db");
|
||||||
// creates accounts
|
|
||||||
db.execute("CREATE TABLE Accounts(AccountID INTEGER PRIMARY KEY AUTOINCREMENT, Login TEXT NOT NULL, Password TEXT NOT NULL);");
|
// creates accounts
|
||||||
// creates characters
|
db.execute("CREATE TABLE Accounts(AccountID INTEGER PRIMARY KEY AUTOINCREMENT, Login TEXT NOT NULL, Password TEXT NOT NULL);");
|
||||||
db.execute("CREATE TABLE Players(PlayerID INTEGER PRIMARY KEY AUTOINCREMENT, AccountID INTEGER NOT NULL, Slot INTEGER NOT NULL, FirstName TEXT NOT NULL, LastName TEXT NOT NULL, CharData TEXT NOT NULL);");
|
// creates characters
|
||||||
|
db.execute("CREATE TABLE Players(PlayerID INTEGER PRIMARY KEY AUTOINCREMENT, AccountID INTEGER NOT NULL, Slot INTEGER NOT NULL, FirstName TEXT NOT NULL, LastName TEXT NOT NULL, CharData TEXT NOT NULL);");
|
||||||
DEBUGLOG(std::cout << "Done" << std::endl;)
|
|
||||||
}
|
DEBUGLOG(std::cout << "Done" << std::endl;)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifies that the username & passwords are valid
|
// verifies that the username & passwords are valid
|
||||||
bool Database::isLoginDataGood(std::string login, std::string password) {
|
bool Database::isLoginDataGood(std::string login, std::string password) {
|
||||||
std::regex loginRegex("^([A-Za-z\\d_\\-]){5,20}$");
|
std::regex loginRegex("^([A-Za-z\\d_\\-]){5,20}$");
|
||||||
std::regex passwordRegex("^([A-Za-z\\d_\\-@$!%*#?&,.+:;<=>]){2,20}$");
|
std::regex passwordRegex("^([A-Za-z\\d_\\-@$!%*#?&,.+:;<=>]){2,20}$");
|
||||||
return (std::regex_match(login, loginRegex) && std::regex_match(password, passwordRegex));
|
return (std::regex_match(login, loginRegex) && std::regex_match(password, passwordRegex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::addAccount(std::string login, std::string password) {
|
void Database::addAccount(std::string login, std::string password) {
|
||||||
// generates prepared statment
|
// generates prepared statment
|
||||||
sqlite3pp::command cmd(db, "INSERT INTO Accounts (Login, Password) VALUES (:login, :password)");
|
sqlite3pp::command cmd(db, "INSERT INTO Accounts (Login, Password) VALUES (:login, :password)");
|
||||||
|
|
||||||
// generates a hashed password!
|
// generates a hashed password!
|
||||||
password = BCrypt::generateHash(password);
|
password = BCrypt::generateHash(password);
|
||||||
|
|
||||||
// binds args to the command
|
// binds args to the command
|
||||||
cmd.bind(":login", login, sqlite3pp::nocopy);
|
cmd.bind(":login", login, sqlite3pp::nocopy);
|
||||||
cmd.bind(":password", password, sqlite3pp::nocopy);
|
cmd.bind(":password", password, sqlite3pp::nocopy);
|
||||||
cmd.execute();
|
cmd.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::doesUserExist(std::string login) {
|
bool Database::doesUserExist(std::string login) {
|
||||||
// generates prepared statement
|
// generates prepared statement
|
||||||
sqlite3pp::query qry(db, "SELECT COUNT(AccountID) FROM Accounts WHERE Login = :login");
|
sqlite3pp::query qry(db, "SELECT COUNT(AccountID) FROM Accounts WHERE Login = :login");
|
||||||
// binds to the query
|
// binds to the query
|
||||||
qry.bind(":login", login, sqlite3pp::nocopy);
|
qry.bind(":login", login, sqlite3pp::nocopy);
|
||||||
|
|
||||||
// executes
|
// executes
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// grabs the first result (the count)
|
// grabs the first result (the count)
|
||||||
int result;
|
int result;
|
||||||
std::tie(result) = (*i).get_columns<int>(0);
|
std::tie(result) = (*i).get_columns<int>(0);
|
||||||
|
|
||||||
// if there is more than 0 results, the user exists :eyes:
|
// if there is more than 0 results, the user exists :eyes:
|
||||||
return (result > 0);
|
return (result > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::isPasswordCorrect(std::string login, std::string password) {
|
bool Database::isPasswordCorrect(std::string login, std::string password) {
|
||||||
// generates prepared statement
|
// generates prepared statement
|
||||||
sqlite3pp::query qry(db, "SELECT Password FROM Accounts WHERE Login = :login");
|
sqlite3pp::query qry(db, "SELECT Password FROM Accounts WHERE Login = :login");
|
||||||
// binds username to the query
|
// binds username to the query
|
||||||
qry.bind(":login", login, sqlite3pp::nocopy);
|
qry.bind(":login", login, sqlite3pp::nocopy);
|
||||||
|
|
||||||
// executes
|
// executes
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// grabs the first result
|
// grabs the first result
|
||||||
const char* actual;
|
const char* actual;
|
||||||
std::tie(actual) = (*i).get_columns<const char*>(0);
|
std::tie(actual) = (*i).get_columns<const char*>(0);
|
||||||
|
|
||||||
// validate password hash with provded password
|
// validate password hash with provded password
|
||||||
return BCrypt::validatePassword(password, actual);
|
return BCrypt::validatePassword(password, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getUserID(std::string login) {
|
int Database::getUserID(std::string login) {
|
||||||
// generates prep statement
|
// generates prep statement
|
||||||
sqlite3pp::query qry(db, "SELECT AccountID FROM Accounts WHERE Login = :login");
|
sqlite3pp::query qry(db, "SELECT AccountID FROM Accounts WHERE Login = :login");
|
||||||
// binds the username to the login param
|
// binds the username to the login param
|
||||||
qry.bind(":login", login, sqlite3pp::nocopy);
|
qry.bind(":login", login, sqlite3pp::nocopy);
|
||||||
|
|
||||||
// executes the query
|
// executes the query
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// grabs the first result of the query
|
// grabs the first result of the query
|
||||||
int result;
|
int result;
|
||||||
std::tie(result) = (*i).get_columns<int>(0);
|
std::tie(result) = (*i).get_columns<int>(0);
|
||||||
|
|
||||||
// returns the result
|
// returns the result
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getUserSlotsNum(int AccountId) {
|
int Database::getUserSlotsNum(int AccountId) {
|
||||||
// generates the prepared statement
|
// generates the prepared statement
|
||||||
sqlite3pp::query qry(db, "SELECT COUNT(PlayerID) FROM Players WHERE AccountID = :ID");
|
sqlite3pp::query qry(db, "SELECT COUNT(PlayerID) FROM Players WHERE AccountID = :ID");
|
||||||
|
|
||||||
// binds the ID to the param
|
// binds the ID to the param
|
||||||
qry.bind(":ID", AccountId);
|
qry.bind(":ID", AccountId);
|
||||||
|
|
||||||
// executes
|
// executes
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// grabs the first result
|
// grabs the first result
|
||||||
int result;
|
int result;
|
||||||
std::tie(result) = (*i).get_columns<int>(0);
|
std::tie(result) = (*i).get_columns<int>(0);
|
||||||
|
|
||||||
// returns the result
|
// returns the result
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::isNameFree(std::string First, std::string Second) {
|
bool Database::isNameFree(std::string First, std::string Second) {
|
||||||
// generates the prepared statement
|
// generates the prepared statement
|
||||||
sqlite3pp::query qry(db, "SELECT COUNT(PlayerID) FROM Players WHERE FirstName = :First COLLATE nocase AND LastName = :Second COLLATE nocase");
|
sqlite3pp::query qry(db, "SELECT COUNT(PlayerID) FROM Players WHERE FirstName = :First COLLATE nocase AND LastName = :Second COLLATE nocase");
|
||||||
|
|
||||||
// binds the params
|
// binds the params
|
||||||
qry.bind(":First", First, sqlite3pp::nocopy);
|
qry.bind(":First", First, sqlite3pp::nocopy);
|
||||||
qry.bind(":Second", Second, sqlite3pp::nocopy);
|
qry.bind(":Second", Second, sqlite3pp::nocopy);
|
||||||
|
|
||||||
// executes the query
|
// executes the query
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// grabs the result
|
// grabs the result
|
||||||
int result;
|
int result;
|
||||||
std::tie(result) = (*i).get_columns<int>(0);
|
std::tie(result) = (*i).get_columns<int>(0);
|
||||||
|
|
||||||
// if no results return, the the username is unused
|
// if no results return, the the username is unused
|
||||||
return (result == 0);
|
return (result == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID) {
|
void Database::createCharacter(sP_CL2LS_REQ_SAVE_CHAR_NAME* save, int AccountID) {
|
||||||
// generate the command
|
// generate the command
|
||||||
sqlite3pp::command cmd(db, "INSERT INTO Players (AccountID, Slot, FirstName, LastName, CharData) VALUES (:AccountID, :Slot, :FirstName, :LastName, :CharData)");
|
sqlite3pp::command cmd(db, "INSERT INTO Players (AccountID, Slot, FirstName, LastName, CharData) VALUES (:AccountID, :Slot, :FirstName, :LastName, :CharData)");
|
||||||
|
|
||||||
// generate character data
|
// generate character data
|
||||||
std::string charData = CharacterToJson(save);
|
std::string charData = CharacterToJson(save);
|
||||||
std::string first = U16toU8(save->szFirstName);
|
std::string first = U16toU8(save->szFirstName);
|
||||||
std::string last = U16toU8(save->szLastName);
|
std::string last = U16toU8(save->szLastName);
|
||||||
|
|
||||||
// bind to command
|
// bind to command
|
||||||
cmd.bind(":AccountID", AccountID);
|
cmd.bind(":AccountID", AccountID);
|
||||||
cmd.bind(":Slot", save->iSlotNum);
|
cmd.bind(":Slot", save->iSlotNum);
|
||||||
cmd.bind(":CharData", charData, sqlite3pp::nocopy);
|
cmd.bind(":CharData", charData, sqlite3pp::nocopy);
|
||||||
cmd.bind(":FirstName", first, sqlite3pp::nocopy);
|
cmd.bind(":FirstName", first, sqlite3pp::nocopy);
|
||||||
cmd.bind(":LastName", last, sqlite3pp::nocopy);
|
cmd.bind(":LastName", last, sqlite3pp::nocopy);
|
||||||
|
|
||||||
// run
|
// run
|
||||||
cmd.execute();
|
cmd.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::finishCharacter(sP_CL2LS_REQ_CHAR_CREATE* character) {
|
void Database::finishCharacter(sP_CL2LS_REQ_CHAR_CREATE* character) {
|
||||||
sqlite3pp::command cmd(db, "UPDATE Players SET CharData = :data WHERE PlayerID = :id");
|
sqlite3pp::command cmd(db, "UPDATE Players SET CharData = :data WHERE PlayerID = :id");
|
||||||
|
|
||||||
// grab the data to add to the command
|
// grab the data to add to the command
|
||||||
int id = character->PCStyle.iPC_UID;
|
int id = character->PCStyle.iPC_UID;
|
||||||
std::string charData = CharacterToJson(character);
|
std::string charData = CharacterToJson(character);
|
||||||
|
|
||||||
// bind to the command & execute
|
// bind to the command & execute
|
||||||
cmd.bind(":data", charData, sqlite3pp::nocopy);
|
cmd.bind(":data", charData, sqlite3pp::nocopy);
|
||||||
cmd.bind(":id", id);
|
cmd.bind(":id", id);
|
||||||
cmd.execute();
|
cmd.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::finishTutorial(int PlayerID) {
|
void Database::finishTutorial(int PlayerID) {
|
||||||
sqlite3pp::query qry(db, "SELECT CharData FROM Players WHERE PlayerID = :ID");
|
sqlite3pp::query qry(db, "SELECT CharData FROM Players WHERE PlayerID = :ID");
|
||||||
|
|
||||||
// bind to the query and execute
|
|
||||||
qry.bind(":ID", PlayerID);
|
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
|
||||||
|
|
||||||
// grab the player json from the database
|
|
||||||
std::string json;
|
|
||||||
std::tie(json) = (*i).get_columns<std::string>(0);
|
|
||||||
|
|
||||||
// parse the json into a Player
|
// bind to the query and execute
|
||||||
Player player = JsonToPlayer(json, PlayerID);
|
qry.bind(":ID", PlayerID);
|
||||||
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// set the tutorial flag & equip lightning gun
|
// grab the player json from the database
|
||||||
player.PCStyle2.iTutorialFlag = 1;
|
std::string json;
|
||||||
player.Equip[0].iID = 328;
|
std::tie(json) = (*i).get_columns<std::string>(0);
|
||||||
json = PlayerToJson(player);
|
|
||||||
|
|
||||||
// update the database
|
// parse the json into a Player
|
||||||
sqlite3pp::command cmd(db, "UPDATE Players SET CharData = :data WHERE PlayerID = :id");
|
Player player = JsonToPlayer(json, PlayerID);
|
||||||
cmd.bind(":data", json, sqlite3pp::nocopy);
|
|
||||||
cmd.bind(":id", PlayerID);
|
// set the tutorial flag & equip lightning gun
|
||||||
cmd.execute();
|
player.PCStyle2.iTutorialFlag = 1;
|
||||||
|
player.Equip[0].iID = 328;
|
||||||
|
json = PlayerToJson(player);
|
||||||
|
|
||||||
|
// update the database
|
||||||
|
sqlite3pp::command cmd(db, "UPDATE Players SET CharData = :data WHERE PlayerID = :id");
|
||||||
|
cmd.bind(":data", json, sqlite3pp::nocopy);
|
||||||
|
cmd.bind(":id", PlayerID);
|
||||||
|
cmd.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getCharacterID(int AccountID, int slot) {
|
int Database::getCharacterID(int AccountID, int slot) {
|
||||||
// make the query
|
// make the query
|
||||||
sqlite3pp::query qry(db, "SELECT PlayerID FROM Players WHERE AccountID = :ID AND Slot = :Slot");
|
sqlite3pp::query qry(db, "SELECT PlayerID FROM Players WHERE AccountID = :ID AND Slot = :Slot");
|
||||||
|
|
||||||
// bind the params & execute
|
// bind the params & execute
|
||||||
qry.bind(":ID", AccountID);
|
qry.bind(":ID", AccountID);
|
||||||
qry.bind(":Slot", slot);
|
qry.bind(":Slot", slot);
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// grab the result
|
// grab the result
|
||||||
int result;
|
int result;
|
||||||
std::tie(result) = (*i).get_columns<int>(0);
|
std::tie(result) = (*i).get_columns<int>(0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::deleteCharacter(int characterID, int accountID) {
|
int Database::deleteCharacter(int characterID, int accountID) {
|
||||||
// checking if requested player exist and is bound to the account
|
// checking if requested player exist and is bound to the account
|
||||||
|
|
||||||
sqlite3pp::query qry(db, "SELECT COUNT(AccountID) FROM Players WHERE AccountID = :AccID AND PlayerID = :PID");
|
sqlite3pp::query qry(db, "SELECT COUNT(AccountID) FROM Players WHERE AccountID = :AccID AND PlayerID = :PID");
|
||||||
|
|
||||||
qry.bind(":AccID", accountID);
|
|
||||||
qry.bind(":PID", characterID);
|
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
|
||||||
|
|
||||||
int result;
|
|
||||||
std::tie(result) = (*i).get_columns<int>(0);
|
|
||||||
|
|
||||||
if (result > 0) {
|
|
||||||
// get player character slot
|
|
||||||
sqlite3pp::query qry(db, "SELECT Slot FROM Players WHERE PlayerID = :PID");
|
|
||||||
|
|
||||||
// bind & execute
|
|
||||||
qry.bind(":PID", characterID);
|
|
||||||
sqlite3pp::query::iterator i = qry.begin();
|
|
||||||
|
|
||||||
// grab the slot to return
|
qry.bind(":AccID", accountID);
|
||||||
int slot;
|
qry.bind(":PID", characterID);
|
||||||
std::tie(slot) = (*i).get_columns<int>(0);
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
// actually delete the record
|
|
||||||
sqlite3pp::command cmd(db, "DELETE FROM Players WHERE PlayerID = :ID");
|
|
||||||
cmd.bind(":ID", characterID);
|
|
||||||
cmd.execute();
|
|
||||||
|
|
||||||
// finally, return the grabbed slot
|
int result;
|
||||||
return slot;
|
std::tie(result) = (*i).get_columns<int>(0);
|
||||||
}
|
|
||||||
|
if (result > 0) {
|
||||||
return -1;
|
// get player character slot
|
||||||
|
sqlite3pp::query qry(db, "SELECT Slot FROM Players WHERE PlayerID = :PID");
|
||||||
|
|
||||||
|
// bind & execute
|
||||||
|
qry.bind(":PID", characterID);
|
||||||
|
sqlite3pp::query::iterator i = qry.begin();
|
||||||
|
|
||||||
|
// grab the slot to return
|
||||||
|
int slot;
|
||||||
|
std::tie(slot) = (*i).get_columns<int>(0);
|
||||||
|
|
||||||
|
// actually delete the record
|
||||||
|
sqlite3pp::command cmd(db, "DELETE FROM Players WHERE PlayerID = :ID");
|
||||||
|
cmd.bind(":ID", characterID);
|
||||||
|
cmd.execute();
|
||||||
|
|
||||||
|
// finally, return the grabbed slot
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this should really be std::vector, but for the sake of compatibility with PRs, I'll change this after merging
|
// TODO: this should really be std::vector, but for the sake of compatibility with PRs, I'll change this after merging
|
||||||
std::list<Player> Database::getCharacters(int userID) {
|
std::list<Player> Database::getCharacters(int userID) {
|
||||||
std::list<Player> result = std::list<Player>();
|
std::list<Player> result = std::list<Player>();
|
||||||
|
|
||||||
sqlite3pp::query qry(db, "SELECT * FROM Players WHERE AccountID = :ID");
|
sqlite3pp::query qry(db, "SELECT * FROM Players WHERE AccountID = :ID");
|
||||||
|
|
||||||
qry.bind(":ID", userID);
|
qry.bind(":ID", userID);
|
||||||
|
|
||||||
// for each character owned by the account,
|
// for each character owned by the account,
|
||||||
for (sqlite3pp::query::iterator i = qry.begin(); i != qry.end(); ++i) {
|
for (sqlite3pp::query::iterator i = qry.begin(); i != qry.end(); ++i) {
|
||||||
// grab the data
|
// grab the data
|
||||||
int ID, AccountID, slot;
|
int ID, AccountID, slot;
|
||||||
char const* charData, * first, * second;
|
char const* charData, * first, * second;
|
||||||
std::tie(ID, AccountID, slot, first, second, charData) =
|
std::tie(ID, AccountID, slot, first, second, charData) =
|
||||||
(*i).get_columns<int, int, int, char const*, char const*, char const*>(0, 1, 2, 3, 4, 5);
|
(*i).get_columns<int, int, int, char const*, char const*, char const*>(0, 1, 2, 3, 4, 5);
|
||||||
|
|
||||||
// convert to player
|
|
||||||
Player toadd = JsonToPlayer(charData, ID);
|
|
||||||
toadd.slot = slot;
|
|
||||||
|
|
||||||
// add it to the results
|
// convert to player
|
||||||
result.push_back(toadd);
|
Player toadd = JsonToPlayer(charData, ID);
|
||||||
}
|
toadd.slot = slot;
|
||||||
return result;
|
|
||||||
|
// add it to the results
|
||||||
|
result.push_back(toadd);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database::CharacterToJson(sP_CL2LS_REQ_SAVE_CHAR_NAME* save) {
|
std::string Database::CharacterToJson(sP_CL2LS_REQ_SAVE_CHAR_NAME* save) {
|
||||||
nlohmann::json json = {
|
nlohmann::json json = {
|
||||||
{"Level",1},
|
{"Level",36},
|
||||||
//to check
|
//to check
|
||||||
{"HP",1000},
|
{"HP",1000},
|
||||||
{"NameCheck", 1},
|
{"NameCheck", 1},
|
||||||
{"FirstName",U16toU8(save->szFirstName)},
|
{"FirstName",U16toU8(save->szFirstName)},
|
||||||
{"LastName",U16toU8(save->szLastName)},
|
{"LastName",U16toU8(save->szLastName)},
|
||||||
{"Gender",rand() % 2 + 1 },
|
{"Gender",rand() % 2 + 1 },
|
||||||
{"FaceStyle",1},
|
{"FaceStyle",1},
|
||||||
{"HairStyle",1},
|
{"HairStyle",1},
|
||||||
{"HairColor",(rand() % 19) + 1},
|
{"HairColor",(rand() % 19) + 1},
|
||||||
{"SkinColor",(rand() % 13) + 1},
|
{"SkinColor",(rand() % 13) + 1},
|
||||||
{"EyeColor",(rand() % 6) + 1},
|
{"EyeColor",(rand() % 6) + 1},
|
||||||
{"Height",(rand() % 6)},
|
{"Height",(rand() % 6)},
|
||||||
{"Body",(rand() % 4)},
|
{"Body",(rand() % 4)},
|
||||||
{"Class",0},
|
{"Class",0},
|
||||||
{"AppearanceFlag",0},
|
{"AppearanceFlag",0},
|
||||||
{"PayzoneFlag",1},
|
{"PayzoneFlag",1},
|
||||||
{"TutorialFlag",0},
|
{"TutorialFlag",0},
|
||||||
{"EquipUB", 217},
|
{"EquipUB", 217},
|
||||||
{"EquipLB", 203},
|
{"EquipLB", 203},
|
||||||
{"EquipFoot", 314},
|
{"EquipFoot", 314},
|
||||||
{"EquipWeapon", 0},
|
{"EquipWeapon", 0},
|
||||||
{"x",settings::SPAWN_X},
|
{"x",settings::SPAWN_X},
|
||||||
{"y",settings::SPAWN_Y},
|
{"y",settings::SPAWN_Y},
|
||||||
{"z",settings::SPAWN_Z},
|
{"z",settings::SPAWN_Z},
|
||||||
{"isGM",false},
|
{"isGM",false},
|
||||||
};
|
};
|
||||||
return json.dump();
|
return json.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database::PlayerToJson(Player player) {
|
std::string Database::PlayerToJson(Player player) {
|
||||||
nlohmann::json json = {
|
nlohmann::json json = {
|
||||||
{"Level",1},
|
{"Level",player.level},
|
||||||
//to check
|
//to check
|
||||||
{"HP",1000},
|
{"HP",player.HP},
|
||||||
{"NameCheck", 1},
|
{"NameCheck", 1},
|
||||||
{"FirstName",U16toU8(player.PCStyle.szFirstName)},
|
{"FirstName",U16toU8(player.PCStyle.szFirstName)},
|
||||||
{"LastName",U16toU8(player.PCStyle.szLastName)},
|
{"LastName",U16toU8(player.PCStyle.szLastName)},
|
||||||
{"Gender",player.PCStyle.iGender},
|
{"Gender",player.PCStyle.iGender},
|
||||||
{"FaceStyle",player.PCStyle.iFaceStyle},
|
{"FaceStyle",player.PCStyle.iFaceStyle},
|
||||||
{"HairStyle",player.PCStyle.iHairStyle},
|
{"HairStyle",player.PCStyle.iHairStyle},
|
||||||
{"HairColor",player.PCStyle.iHairColor},
|
{"HairColor",player.PCStyle.iHairColor},
|
||||||
{"SkinColor",player.PCStyle.iSkinColor},
|
{"SkinColor",player.PCStyle.iSkinColor},
|
||||||
{"EyeColor",player.PCStyle.iEyeColor},
|
{"EyeColor",player.PCStyle.iEyeColor},
|
||||||
{"Height",player.PCStyle.iHeight},
|
{"Height",player.PCStyle.iHeight},
|
||||||
{"Body",player.PCStyle.iBody},
|
{"Body",player.PCStyle.iBody},
|
||||||
{"Class",player.PCStyle.iClass},
|
{"Class",player.PCStyle.iClass},
|
||||||
{"AppearanceFlag",player.PCStyle2.iAppearanceFlag},
|
{"AppearanceFlag",player.PCStyle2.iAppearanceFlag},
|
||||||
{"PayzoneFlag",player.PCStyle2.iPayzoneFlag},
|
{"PayzoneFlag",player.PCStyle2.iPayzoneFlag},
|
||||||
{"TutorialFlag",player.PCStyle2.iTutorialFlag},
|
{"TutorialFlag",player.PCStyle2.iTutorialFlag},
|
||||||
{"EquipUB", player.Equip[1].iID},
|
{"EquipUB", player.Equip[1].iID},
|
||||||
{"EquipLB", player.Equip[2].iID},
|
{"EquipLB", player.Equip[2].iID},
|
||||||
{"EquipFoot", player.Equip[3].iID},
|
{"EquipFoot", player.Equip[3].iID},
|
||||||
{"EquipWeapon", player.Equip[0].iID},
|
{"EquipWeapon", player.Equip[0].iID},
|
||||||
{"x",player.x},
|
{"x",player.x},
|
||||||
{"y",player.y},
|
{"y",player.y},
|
||||||
{"z",player.z},
|
{"z",player.z},
|
||||||
{"isGM",false},
|
{"isGM",false},
|
||||||
};
|
};
|
||||||
return json.dump();
|
return json.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
Player Database::JsonToPlayer(std::string input, int PC_UID) {
|
Player Database::JsonToPlayer(std::string input, int PC_UID) {
|
||||||
std::string err;
|
std::string err;
|
||||||
const auto json = nlohmann::json::parse(input);
|
const auto json = nlohmann::json::parse(input);
|
||||||
Player player;
|
Player player;
|
||||||
player.PCStyle.iPC_UID = (int64_t)PC_UID;
|
player.PCStyle.iPC_UID = (int64_t)PC_UID;
|
||||||
player.level = std::stoi(json["Level"].dump());
|
player.level = std::stoi(json["Level"].dump());
|
||||||
player.HP = std::stoi(json["HP"].dump());
|
player.HP = std::stoi(json["HP"].dump());
|
||||||
player.PCStyle.iNameCheck = std::stoi(json["NameCheck"].dump());
|
player.PCStyle.iNameCheck = std::stoi(json["NameCheck"].dump());
|
||||||
U8toU16(json["FirstName"].get<std::string>(), player.PCStyle.szFirstName);
|
U8toU16(json["FirstName"].get<std::string>(), player.PCStyle.szFirstName);
|
||||||
U8toU16(json["LastName"].get<std::string>(), player.PCStyle.szLastName);
|
U8toU16(json["LastName"].get<std::string>(), player.PCStyle.szLastName);
|
||||||
player.PCStyle.iGender = std::stoi(json["Gender"].dump());
|
player.PCStyle.iGender = std::stoi(json["Gender"].dump());
|
||||||
player.PCStyle.iFaceStyle = std::stoi(json["FaceStyle"].dump());
|
player.PCStyle.iFaceStyle = std::stoi(json["FaceStyle"].dump());
|
||||||
player.PCStyle.iHairStyle = std::stoi(json["HairStyle"].dump());
|
player.PCStyle.iHairStyle = std::stoi(json["HairStyle"].dump());
|
||||||
player.PCStyle.iHairColor = std::stoi(json["HairColor"].dump());
|
player.PCStyle.iHairColor = std::stoi(json["HairColor"].dump());
|
||||||
player.PCStyle.iSkinColor = std::stoi(json["SkinColor"].dump());
|
player.PCStyle.iSkinColor = std::stoi(json["SkinColor"].dump());
|
||||||
player.PCStyle.iEyeColor = std::stoi(json["EyeColor"].dump());
|
player.PCStyle.iEyeColor = std::stoi(json["EyeColor"].dump());
|
||||||
player.PCStyle.iHeight = std::stoi(json["Height"].dump());
|
player.PCStyle.iHeight = std::stoi(json["Height"].dump());
|
||||||
player.PCStyle.iBody = std::stoi(json["Body"].dump());
|
player.PCStyle.iBody = std::stoi(json["Body"].dump());
|
||||||
player.PCStyle.iClass = std::stoi(json["Class"].dump());
|
player.PCStyle.iClass = std::stoi(json["Class"].dump());
|
||||||
player.PCStyle2.iAppearanceFlag = std::stoi(json["AppearanceFlag"].dump());
|
player.PCStyle2.iAppearanceFlag = std::stoi(json["AppearanceFlag"].dump());
|
||||||
player.PCStyle2.iPayzoneFlag = std::stoi(json["PayzoneFlag"].dump());
|
player.PCStyle2.iPayzoneFlag = std::stoi(json["PayzoneFlag"].dump());
|
||||||
player.PCStyle2.iTutorialFlag = std::stoi(json["TutorialFlag"].dump());
|
player.PCStyle2.iTutorialFlag = std::stoi(json["TutorialFlag"].dump());
|
||||||
player.Equip[0].iID = std::stoi(json["EquipWeapon"].dump());
|
player.Equip[0].iID = std::stoi(json["EquipWeapon"].dump());
|
||||||
if (player.Equip[0].iID != 0)
|
if (player.Equip[0].iID != 0)
|
||||||
player.Equip[0].iOpt = 1;
|
player.Equip[0].iOpt = 1;
|
||||||
else
|
else
|
||||||
player.Equip[0].iOpt = 0;
|
player.Equip[0].iOpt = 0;
|
||||||
player.Equip[0].iType = 0;
|
player.Equip[0].iType = 0;
|
||||||
player.Equip[1].iID = std::stoi(json["EquipUB"].dump());
|
player.Equip[1].iID = std::stoi(json["EquipUB"].dump());
|
||||||
player.Equip[1].iOpt = 1;
|
player.Equip[1].iOpt = 1;
|
||||||
player.Equip[1].iType = 1;
|
player.Equip[1].iType = 1;
|
||||||
player.Equip[2].iID = std::stoi(json["EquipLB"].dump());
|
player.Equip[2].iID = std::stoi(json["EquipLB"].dump());
|
||||||
player.Equip[2].iOpt = 1;
|
player.Equip[2].iOpt = 1;
|
||||||
player.Equip[2].iType = 2;
|
player.Equip[2].iType = 2;
|
||||||
player.Equip[3].iID = std::stoi(json["EquipFoot"].dump());
|
player.Equip[3].iID = std::stoi(json["EquipFoot"].dump());
|
||||||
player.Equip[3].iOpt = 1;
|
player.Equip[3].iOpt = 1;
|
||||||
player.Equip[3].iType = 3;
|
player.Equip[3].iType = 3;
|
||||||
player.x = std::stoi(json["x"].dump());
|
player.x = std::stoi(json["x"].dump());
|
||||||
player.y = std::stoi(json["y"].dump());
|
player.y = std::stoi(json["y"].dump());
|
||||||
player.z = std::stoi(json["z"].dump());
|
player.z = std::stoi(json["z"].dump());
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Database::CharacterToJson(sP_CL2LS_REQ_CHAR_CREATE* character) {
|
std::string Database::CharacterToJson(sP_CL2LS_REQ_CHAR_CREATE* character) {
|
||||||
nlohmann::json json = {
|
nlohmann::json json = {
|
||||||
{"Level",1},
|
{"Level",36},
|
||||||
//to check
|
//to check
|
||||||
{"HP",1000},
|
{"HP",1000},
|
||||||
{"NameCheck", 1},
|
{"NameCheck", 1},
|
||||||
{"FirstName",U16toU8(character->PCStyle.szFirstName)},
|
{"FirstName",U16toU8(character->PCStyle.szFirstName)},
|
||||||
{"LastName",U16toU8(character->PCStyle.szLastName)},
|
{"LastName",U16toU8(character->PCStyle.szLastName)},
|
||||||
{"Gender",character->PCStyle.iGender},
|
{"Gender",character->PCStyle.iGender},
|
||||||
{"FaceStyle",character->PCStyle.iFaceStyle},
|
{"FaceStyle",character->PCStyle.iFaceStyle},
|
||||||
{"HairStyle",character->PCStyle.iHairStyle},
|
{"HairStyle",character->PCStyle.iHairStyle},
|
||||||
{"HairColor",character->PCStyle.iHairColor},
|
{"HairColor",character->PCStyle.iHairColor},
|
||||||
{"SkinColor",character->PCStyle.iSkinColor},
|
{"SkinColor",character->PCStyle.iSkinColor},
|
||||||
{"EyeColor",character->PCStyle.iEyeColor},
|
{"EyeColor",character->PCStyle.iEyeColor},
|
||||||
{"Height",character->PCStyle.iHeight},
|
{"Height",character->PCStyle.iHeight},
|
||||||
{"Body",character->PCStyle.iBody},
|
{"Body",character->PCStyle.iBody},
|
||||||
{"Class",character->PCStyle.iClass},
|
{"Class",character->PCStyle.iClass},
|
||||||
{"AppearanceFlag",1},
|
{"AppearanceFlag",1},
|
||||||
{"PayzoneFlag",1},
|
{"PayzoneFlag",1},
|
||||||
{"TutorialFlag",0},
|
{"TutorialFlag",0},
|
||||||
{"EquipUB", character->sOn_Item.iEquipUBID},
|
{"EquipUB", character->sOn_Item.iEquipUBID},
|
||||||
{"EquipLB", character->sOn_Item.iEquipLBID},
|
{"EquipLB", character->sOn_Item.iEquipLBID},
|
||||||
{"EquipFoot", character->sOn_Item.iEquipFootID},
|
{"EquipFoot", character->sOn_Item.iEquipFootID},
|
||||||
{"EquipWeapon", 0},
|
{"EquipWeapon", 0},
|
||||||
{"x",settings::SPAWN_X},
|
{"x",settings::SPAWN_X},
|
||||||
{"y",settings::SPAWN_Y},
|
{"y",settings::SPAWN_Y},
|
||||||
{"z",settings::SPAWN_Z},
|
{"z",settings::SPAWN_Z},
|
||||||
{"isGM",false},
|
{"isGM",false},
|
||||||
};
|
};
|
||||||
return json.dump();
|
return json.dump();
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,11 @@ void NPCManager::init() {
|
|||||||
NPCs[tmp.appearanceData.iNPC_ID] = tmp;
|
NPCs[tmp.appearanceData.iNPC_ID] = tmp;
|
||||||
|
|
||||||
if (npc.value()["id"] == 641 || npc.value()["id"] == 642)
|
if (npc.value()["id"] == 641 || npc.value()["id"] == 642)
|
||||||
RespawnPoints.push_back({npc.value()["x"], npc.value()["y"], ((int)npc.value()["z"]) + RESURRECT_HEIGHT});
|
RespawnPoints.push_back({ npc.value()["x"], npc.value()["y"], ((int)npc.value()["z"]) + RESURRECT_HEIGHT });
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const std::exception& err) {
|
}
|
||||||
|
catch (const std::exception& err) {
|
||||||
std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
std::cerr << "[WARN] Malformed NPCs.json file! Reason:" << err.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,13 +46,14 @@ void NPCManager::init() {
|
|||||||
|
|
||||||
for (nlohmann::json::iterator npc = npcData.begin(); npc != npcData.end(); npc++) {
|
for (nlohmann::json::iterator npc = npcData.begin(); npc != npcData.end(); npc++) {
|
||||||
BaseNPC tmp(npc.value()["iX"], npc.value()["iY"], npc.value()["iZ"], npc.value()["iNPCType"],
|
BaseNPC tmp(npc.value()["iX"], npc.value()["iY"], npc.value()["iZ"], npc.value()["iNPCType"],
|
||||||
npc.value()["iHP"], npc.value()["iConditionBitFlag"], npc.value()["iAngle"], npc.value()["iBarkerType"]);
|
npc.value()["iHP"], npc.value()["iConditionBitFlag"], npc.value()["iAngle"], npc.value()["iBarkerType"]);
|
||||||
|
|
||||||
NPCs[tmp.appearanceData.iNPC_ID] = tmp;
|
NPCs[tmp.appearanceData.iNPC_ID] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[INFO] populated " << NPCs.size() << " NPCs" << std::endl;
|
std::cout << "[INFO] populated " << NPCs.size() << " NPCs" << std::endl;
|
||||||
} catch (const std::exception& err) {
|
}
|
||||||
|
catch (const std::exception& err) {
|
||||||
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
std::cerr << "[WARN] Malformed mobs.json file! Reason:" << err.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,19 +65,21 @@ void NPCManager::init() {
|
|||||||
infile >> warpData;
|
infile >> warpData;
|
||||||
|
|
||||||
for (nlohmann::json::iterator warp = warpData.begin(); warp != warpData.end(); warp++) {
|
for (nlohmann::json::iterator warp = warpData.begin(); warp != warpData.end(); warp++) {
|
||||||
WarpLocation warpLoc = {warp.value()["m_iToX"], warp.value()["m_iToY"], warp.value()["m_iToZ"]};
|
WarpLocation warpLoc = { warp.value()["m_iToX"], warp.value()["m_iToY"], warp.value()["m_iToZ"] };
|
||||||
int warpID = atoi(warp.key().c_str());
|
int warpID = atoi(warp.key().c_str());
|
||||||
Warps[warpID] = warpLoc;
|
Warps[warpID] = warpLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[INFO] populated " << Warps.size() << " Warps" << std::endl;
|
std::cout << "[INFO] populated " << Warps.size() << " Warps" << std::endl;
|
||||||
} catch (const std::exception& err) {
|
}
|
||||||
|
catch (const std::exception& err) {
|
||||||
std::cerr << "[WARN] Malformed warps.json file! Reason:" << err.what() << std::endl;
|
std::cerr << "[WARN] Malformed warps.json file! Reason:" << err.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_WARP_USE_NPC, npcWarpHandler);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_NPC_SUMMON, npcSummonHandler);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_BARKER, npcBarkHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
|
void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
|
||||||
@ -88,7 +92,8 @@ void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
|
|||||||
|
|
||||||
if (diffX < settings::NPCDISTANCE && diffY < settings::NPCDISTANCE) {
|
if (diffX < settings::NPCDISTANCE && diffY < settings::NPCDISTANCE) {
|
||||||
yesView.push_back(pair.first);
|
yesView.push_back(pair.first);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
noView.push_back(pair.first);
|
noView.push_back(pair.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +111,8 @@ void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
|
|||||||
|
|
||||||
// remove from view
|
// remove from view
|
||||||
view.viewableNPCs.erase(i++);
|
view.viewableNPCs.erase(i++);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +133,45 @@ void NPCManager::updatePlayerNPCS(CNSocket* sock, PlayerView& view) {
|
|||||||
PlayerManager::players[sock].viewableNPCs = view.viewableNPCs;
|
PlayerManager::players[sock].viewableNPCs = view.viewableNPCs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NPCManager::npcBarkHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
|
sP_CL2FE_REQ_BARKER* bark = (sP_CL2FE_REQ_BARKER*)data->buf;
|
||||||
|
PlayerView& plr = PlayerManager::players[sock];
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_BARKER, resp);
|
||||||
|
resp.iMissionStringID = bark->iMissionTaskID;
|
||||||
|
resp.iNPC_ID = bark->iNPC_ID;
|
||||||
|
|
||||||
|
// Send bark to other players.
|
||||||
|
for (CNSocket* otherSock : plr.viewable) {
|
||||||
|
otherSock->sendPacket((void*)&resp, P_FE2CL_REP_BARKER, sizeof(sP_FE2CL_REP_BARKER));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then ourself.
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_BARKER, sizeof(sP_FE2CL_REP_BARKER));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NPCManager::npcSummonHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_NPC_SUMMON))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_NPC_SUMMON* req = (sP_CL2FE_REQ_NPC_SUMMON*)data->buf;
|
||||||
|
INITSTRUCT(sP_FE2CL_NPC_ENTER, resp);
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
// permission & sanity check
|
||||||
|
if (!plr->IsGM || req->iNPCType >= 3314)
|
||||||
|
return;
|
||||||
|
|
||||||
|
resp.NPCAppearanceData.iNPC_ID = rand(); // cpunch-style
|
||||||
|
resp.NPCAppearanceData.iNPCType = req->iNPCType;
|
||||||
|
resp.NPCAppearanceData.iHP = 1000; // TODO: placeholder
|
||||||
|
resp.NPCAppearanceData.iX = plr->x;
|
||||||
|
resp.NPCAppearanceData.iY = plr->y;
|
||||||
|
resp.NPCAppearanceData.iZ = plr->z;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER));
|
||||||
|
}
|
||||||
|
|
||||||
void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
|
void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_WARP_USE_NPC))
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_WARP_USE_NPC))
|
||||||
return; // malformed packet
|
return; // malformed packet
|
||||||
@ -149,27 +194,4 @@ void NPCManager::npcWarpHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
plrv.viewableNPCs.clear();
|
plrv.viewableNPCs.clear();
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC));
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC));
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void NPCManager::npcSummonHandler(CNSocket *sock, CNPacketData *data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_NPC_SUMMON))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_NPC_SUMMON* req = (sP_CL2FE_REQ_NPC_SUMMON*)data->buf;
|
|
||||||
INITSTRUCT(sP_FE2CL_NPC_ENTER, resp);
|
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
|
||||||
|
|
||||||
// permission & sanity check
|
|
||||||
if (!plr->IsGM || req->iNPCType >= 3314)
|
|
||||||
return;
|
|
||||||
|
|
||||||
resp.NPCAppearanceData.iNPC_ID = rand(); // cpunch-style
|
|
||||||
resp.NPCAppearanceData.iNPCType = req->iNPCType;
|
|
||||||
resp.NPCAppearanceData.iHP = 1000; // TODO: placeholder
|
|
||||||
resp.NPCAppearanceData.iX = plr->x;
|
|
||||||
resp.NPCAppearanceData.iY = plr->y;
|
|
||||||
resp.NPCAppearanceData.iZ = plr->z;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_NPC_ENTER, sizeof(sP_FE2CL_NPC_ENTER));
|
|
||||||
}
|
|
@ -20,7 +20,9 @@ namespace NPCManager {
|
|||||||
extern std::vector<WarpLocation> RespawnPoints;
|
extern std::vector<WarpLocation> RespawnPoints;
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void updatePlayerNPCS(CNSocket* sock, PlayerView& plr);
|
void npcBarkHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void npcWarpHandler(CNSocket* sock, CNPacketData* data);
|
|
||||||
void npcSummonHandler(CNSocket* sock, CNPacketData* data);
|
void npcSummonHandler(CNSocket* sock, CNPacketData* data);
|
||||||
|
void npcWarpHandler(CNSocket* sock, CNPacketData* data);
|
||||||
|
|
||||||
|
void updatePlayerNPCS(CNSocket* sock, PlayerView& plr);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ void PlayerManager::removePlayer(CNSocket* key) {
|
|||||||
otherSock->sendPacket((void*)&exitPacket, P_FE2CL_PC_EXIT, sizeof(sP_FE2CL_PC_EXIT));
|
otherSock->sendPacket((void*)&exitPacket, P_FE2CL_PC_EXIT, sizeof(sP_FE2CL_PC_EXIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << U16toU8(cachedView.plr->PCStyle.szFirstName) << U16toU8(cachedView.plr->PCStyle.szLastName) << " has left!" << std::endl;
|
std::cout << U16toU8(cachedView.plr->PCStyle.szFirstName) << " " << U16toU8(cachedView.plr->PCStyle.szLastName) << " has left!" << std::endl;
|
||||||
std::cout << players.size() << " players" << std::endl;
|
std::cout << players.size() << " players" << std::endl;
|
||||||
|
|
||||||
delete cachedView.plr;
|
delete cachedView.plr;
|
||||||
|
Loading…
Reference in New Issue
Block a user