refactored giant switch to smaller functions

This commit is contained in:
Kamil 2020-11-17 01:00:10 +01:00 committed by Gent S
parent db98af9775
commit 4760d91ccd
2 changed files with 370 additions and 308 deletions

View File

@ -21,6 +21,64 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
switch (data->type) { switch (data->type) {
case P_CL2LS_REQ_LOGIN: { case P_CL2LS_REQ_LOGIN: {
login(sock, data);
break;
}
case P_CL2LS_REP_LIVE_CHECK: {
loginSessions[sock].lastHeartbeat = getTime();
break;
}
case P_CL2LS_REQ_CHECK_CHAR_NAME: {
nameCheck(sock, data);
break;
}
case P_CL2LS_REQ_SAVE_CHAR_NAME: {
nameSave(sock, data);
break;
}
case P_CL2LS_REQ_CHAR_CREATE: {
characterCreate(sock, data);
break;
}
case P_CL2LS_REQ_CHAR_DELETE: {
characterDelete(sock, data);
break;
}
case P_CL2LS_REQ_CHAR_SELECT: {
characterSelect(sock, data);
break;
}
case P_CL2LS_REQ_SHARD_SELECT: {
shardSelect(sock, data);
break;
}
case P_CL2LS_REQ_SAVE_CHAR_TUTOR: {
finishTutorial(sock, data);
break;
}
case P_CL2LS_REQ_CHANGE_CHAR_NAME: {
changeName(sock, data);
break;
}
case P_CL2LS_REQ_PC_EXIT_DUPLICATE:{
duplicateExit(sock, data);
break;
}
default:
if (settings::VERBOSITY)
std::cerr << "OpenFusion: LOGIN UNIMPLM ERR. PacketType: " << Defines::p2str(CL2LS, data->type) << " (" << data->type << ")" << std::endl;
break;
/*
* Unimplemented CL2LS packets:
* P_CL2LS_CHECK_NAME_LIST - unused by the client
* P_CL2LS_REQ_SERVER_SELECT
* P_CL2LS_REQ_SHARD_LIST_INFO - dev commands, useless as we only run 1 server
*/
}
}
#pragma region packets
void CNLoginServer::login(CNSocket* sock, CNPacketData* data) {
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
@ -48,7 +106,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
// checking regex // checking regex
if (!CNLoginServer::isLoginDataGood(userLogin, userPassword)) { if (!CNLoginServer::isLoginDataGood(userLogin, userPassword)) {
errorCode = (int)LoginError::LOGIN_ERROR; errorCode = (int)LoginError::LOGIN_ERROR;
} else { }
else {
std::unique_ptr<Database::Account> findUser = Database::findAccount(userLogin); std::unique_ptr<Database::Account> findUser = Database::findAccount(userLogin);
// if account not found, make new one // if account not found, make new one
if (findUser == nullptr) { if (findUser == nullptr) {
@ -59,21 +118,24 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
success = true; success = true;
// if user exists, check if password is correct // if user exists, check if password is correct
} else if (CNLoginServer::isPasswordCorrect(findUser->Password, userPassword)) { }
else if (CNLoginServer::isPasswordCorrect(findUser->Password, userPassword)) {
/*calling this here to timestamp login attempt, /*calling this here to timestamp login attempt,
* in order to make duplicate exit sanity check work*/ * in order to make duplicate exit sanity check work*/
Database::updateSelected(findUser->AccountID, findUser->Selected); Database::updateSelected(findUser->AccountID, findUser->Selected);
// check if account isn't currently in use // check if account isn't currently in use
if (CNLoginServer::isAccountInUse(findUser->AccountID)) { if (CNLoginServer::isAccountInUse(findUser->AccountID)) {
errorCode = (int)LoginError::ID_ALREADY_IN_USE; errorCode = (int)LoginError::ID_ALREADY_IN_USE;
} else { // if not, login success }
else { // if not, login success
loginSessions[sock] = CNLoginData(); loginSessions[sock] = CNLoginData();
loginSessions[sock].userID = findUser->AccountID; loginSessions[sock].userID = findUser->AccountID;
loginSessions[sock].slot = findUser->Selected; loginSessions[sock].slot = findUser->Selected;
loginSessions[sock].lastHeartbeat = getTime(); loginSessions[sock].lastHeartbeat = getTime();
success = true; success = true;
} }
} else { }
else {
errorCode = (int)LoginError::ID_AND_PASSWORD_DO_NOT_MATCH; errorCode = (int)LoginError::ID_AND_PASSWORD_DO_NOT_MATCH;
} }
} }
@ -131,20 +193,16 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO)); sock->sendPacket((void*)&charInfo, P_LS2CL_REP_CHAR_INFO, sizeof(sP_LS2CL_REP_CHAR_INFO));
} }
} else { }
else {
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp); INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp);
U8toU16(userLogin, resp.szID, sizeof(resp.szID)); U8toU16(userLogin, resp.szID, sizeof(resp.szID));
resp.iErrorCode = errorCode; resp.iErrorCode = errorCode;
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_FAIL, sizeof(sP_LS2CL_REP_LOGIN_FAIL)); sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_FAIL, sizeof(sP_LS2CL_REP_LOGIN_FAIL));
} }
}
break; void CNLoginServer::nameCheck(CNSocket* sock, CNPacketData* data) {
}
case P_CL2LS_REP_LIVE_CHECK: {
loginSessions[sock].lastHeartbeat = getTime();
break;
}
case P_CL2LS_REQ_CHECK_CHAR_NAME: {
if (data->size != sizeof(sP_CL2LS_REQ_CHECK_CHAR_NAME)) if (data->size != sizeof(sP_CL2LS_REQ_CHECK_CHAR_NAME))
return; return;
@ -156,7 +214,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
if (!CNLoginServer::isCharacterNameGood(U16toU8(nameCheck->szFirstName), U16toU8(nameCheck->szLastName))) { if (!CNLoginServer::isCharacterNameGood(U16toU8(nameCheck->szFirstName), U16toU8(nameCheck->szLastName))) {
success = false; success = false;
errorcode = 4; errorcode = 4;
} else if (!Database::isNameFree(nameCheck)){ // check if name isn't already occupied }
else if (!Database::isNameFree(nameCheck)) { // check if name isn't already occupied
success = false; success = false;
errorcode = 1; errorcode = 1;
} }
@ -175,14 +234,15 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
memcpy(resp.szLastName, nameCheck->szLastName, sizeof(char16_t) * 17); memcpy(resp.szLastName, nameCheck->szLastName, sizeof(char16_t) * 17);
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC)); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC));
} else { }
else {
INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL, resp); INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL, resp);
resp.iErrorCode = errorcode; resp.iErrorCode = errorcode;
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHECK_CHAR_NAME_FAIL, sizeof(sP_LS2CL_REP_CHECK_CHAR_NAME_FAIL)); 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: { void CNLoginServer::nameSave(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_NAME)) if (data->size != sizeof(sP_CL2LS_REQ_SAVE_CHAR_NAME))
return; return;
@ -206,9 +266,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
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));
Database::updateSelected(loginSessions[sock].userID, save->iSlotNum); Database::updateSelected(loginSessions[sock].userID, save->iSlotNum);
break; }
}
case P_CL2LS_REQ_CHAR_CREATE: { void CNLoginServer::characterCreate(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_CREATE)) if (data->size != sizeof(sP_CL2LS_REQ_CHAR_CREATE))
return; return;
@ -251,9 +311,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
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));
Database::updateSelected(loginSessions[sock].userID, player.slot); Database::updateSelected(loginSessions[sock].userID, player.slot);
break; }
}
case P_CL2LS_REQ_CHAR_DELETE: { void CNLoginServer::characterDelete(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_DELETE)) if (data->size != sizeof(sP_CL2LS_REQ_CHAR_DELETE))
return; return;
@ -264,9 +324,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
resp.iSlotNum = operationResult; resp.iSlotNum = operationResult;
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC)); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_DELETE_SUCC, sizeof(sP_LS2CL_REP_CHAR_DELETE_SUCC));
loginSessions[sock].lastHeartbeat = getTime(); loginSessions[sock].lastHeartbeat = getTime();
break; }
}
case P_CL2LS_REQ_CHAR_SELECT: { void CNLoginServer::characterSelect(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_CHAR_SELECT)) if (data->size != sizeof(sP_CL2LS_REQ_CHAR_SELECT))
return; return;
@ -284,9 +344,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
loginSessions[sock].selectedChar = chararacter->iPC_UID; loginSessions[sock].selectedChar = chararacter->iPC_UID;
Database::updateSelected(loginSessions[sock].userID, loginSessions[sock].characters[chararacter->iPC_UID].slot); Database::updateSelected(loginSessions[sock].userID, loginSessions[sock].characters[chararacter->iPC_UID].slot);
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; }
}
case P_CL2LS_REQ_SHARD_SELECT: { void CNLoginServer::shardSelect(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_SHARD_SELECT)) if (data->size != sizeof(sP_CL2LS_REQ_SHARD_SELECT))
return; return;
@ -311,9 +371,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
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; }
}
case P_CL2LS_REQ_SAVE_CHAR_TUTOR: { void CNLoginServer::finishTutorial(CNSocket* sock, CNPacketData* data) {
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;
@ -325,9 +385,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
loginSessions[sock].lastHeartbeat = getTime(); loginSessions[sock].lastHeartbeat = getTime();
// no response here // no response here
break; }
}
case P_CL2LS_REQ_CHANGE_CHAR_NAME: { void CNLoginServer::changeName(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_CHANGE_CHAR_NAME)) if (data->size != sizeof(sP_CL2LS_REQ_CHANGE_CHAR_NAME))
return; return;
@ -336,16 +396,16 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
INITSTRUCT(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, resp); INITSTRUCT(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, resp);
resp.iPC_UID = save->iPCUID; resp.iPC_UID = save->iPCUID;
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);
resp.iSlotNum = save->iSlotNum; resp.iSlotNum = save->iSlotNum;
loginSessions[sock].lastHeartbeat = getTime(); loginSessions[sock].lastHeartbeat = getTime();
sock->sendPacket((void*)&resp, P_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC)); sock->sendPacket((void*)&resp, P_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC));
break; }
}
case P_CL2LS_REQ_PC_EXIT_DUPLICATE:{ void CNLoginServer::duplicateExit(CNSocket* sock, CNPacketData* data) {
if (data->size != sizeof(sP_CL2LS_REQ_PC_EXIT_DUPLICATE)) if (data->size != sizeof(sP_CL2LS_REQ_PC_EXIT_DUPLICATE))
return; return;
@ -355,25 +415,14 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
// sanity check // sanity check
if (account == nullptr) { if (account == nullptr) {
std::cout << "[WARN] P_CL2LS_REQ_PC_EXIT_DUPLICATE submitted unknown username: " << exit->szID << std::endl; std::cout << "[WARN] P_CL2LS_REQ_PC_EXIT_DUPLICATE submitted unknown username: " << exit->szID << std::endl;
break; return;
} }
exitDuplicate(account->AccountID); exitDuplicate(account->AccountID);
break;
}
default:
if (settings::VERBOSITY)
std::cerr << "OpenFusion: LOGIN UNIMPLM ERR. PacketType: " << Defines::p2str(CL2LS, data->type) << " (" << data->type << ")" << std::endl;
break;
/*
* Unimplemented CL2LS packets:
* P_CL2LS_CHECK_NAME_LIST - unused by the client
* P_CL2LS_REQ_SERVER_SELECT
* P_CL2LS_REQ_SHARD_LIST_INFO - dev commands, useless as we only run 1 server
*/
}
} }
#pragma endregion
#pragma region connections
void CNLoginServer::newConnection(CNSocket* cns) { void CNLoginServer::newConnection(CNSocket* cns) {
cns->setActiveKey(SOCKETKEY_E); // by default they accept keys encrypted with the default key cns->setActiveKey(SOCKETKEY_E); // by default they accept keys encrypted with the default key
} }
@ -401,6 +450,8 @@ void CNLoginServer::onStep() {
} }
} }
#pragma endregion
#pragma region helperMethods #pragma region helperMethods
bool CNLoginServer::isAccountInUse(int accountId) { bool CNLoginServer::isAccountInUse(int accountId) {
std::map<CNSocket*, CNLoginData>::iterator it; std::map<CNSocket*, CNLoginData>::iterator it;
@ -443,4 +494,4 @@ bool CNLoginServer::isCharacterNameGood(std::string Firstname, std::string Lastn
std::regex lastnamecheck(R"(((?! )(?!\.)[a-zA-Z0-9]*\.{0,1}(?!\.+ +)[a-zA-Z0-9]* {0,1}(?! +))*$)"); std::regex lastnamecheck(R"(((?! )(?!\.)[a-zA-Z0-9]*\.{0,1}(?!\.+ +)[a-zA-Z0-9]* {0,1}(?! +))*$)");
return (std::regex_match(Firstname, firstnamecheck) && std::regex_match(Lastname, lastnamecheck)); return (std::regex_match(Firstname, firstnamecheck) && std::regex_match(Lastname, lastnamecheck));
} }
#pragma endregion helperMethods #pragma endregion

View File

@ -31,6 +31,17 @@ private:
static void handlePacket(CNSocket* sock, CNPacketData* data); static void handlePacket(CNSocket* sock, CNPacketData* data);
static std::map<CNSocket*, CNLoginData> loginSessions; static std::map<CNSocket*, CNLoginData> loginSessions;
static void login(CNSocket* sock, CNPacketData* data);
static void nameCheck(CNSocket* sock, CNPacketData* data);
static void nameSave(CNSocket* sock, CNPacketData* data);
static void characterCreate(CNSocket* sock, CNPacketData* data);
static void characterDelete(CNSocket* sock, CNPacketData* data);
static void characterSelect(CNSocket* sock, CNPacketData* data);
static void shardSelect(CNSocket* sock, CNPacketData* data);
static void finishTutorial(CNSocket* sock, CNPacketData* data);
static void changeName(CNSocket* sock, CNPacketData* data);
static void duplicateExit(CNSocket* sock, CNPacketData* data);
static bool isLoginDataGood(std::string login, std::string password); static bool isLoginDataGood(std::string login, std::string password);
static bool isPasswordCorrect(std::string actualPassword, std::string tryPassword); static bool isPasswordCorrect(std::string actualPassword, std::string tryPassword);
static bool isAccountInUse(int accountId); static bool isAccountInUse(int accountId);