refactored and cleaned up login function

This commit is contained in:
Kamil 2020-11-17 23:51:39 +01:00 committed by Gent S
parent 5c6d7d6055
commit eee8aab888
3 changed files with 102 additions and 94 deletions

View File

@ -78,6 +78,16 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) {
} }
#pragma region packets #pragma region packets
void loginFail(LoginError errorCode, std::string userLogin, CNSocket* sock) {
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp);
U8toU16(userLogin, resp.szID, sizeof(resp.szID));
resp.iErrorCode = (int)errorCode;
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_FAIL, sizeof(sP_LS2CL_REP_LOGIN_FAIL));
return;
}
void CNLoginServer::login(CNSocket* sock, CNPacketData* data) { 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
@ -100,53 +110,33 @@ void CNLoginServer::login(CNSocket* sock, CNPacketData* data) {
userPassword = std::string(U16toU8(login->szPassword).c_str()); userPassword = std::string(U16toU8(login->szPassword).c_str());
} }
bool success = false; // check regex
int errorCode = 0; if (!CNLoginServer::isLoginDataGood(userLogin, userPassword))
return loginFail(LoginError::LOGIN_ERROR, userLogin, sock);
// checking regex
if (!CNLoginServer::isLoginDataGood(userLogin, userPassword)) {
errorCode = (int)LoginError::LOGIN_ERROR;
}
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 (findUser == nullptr)
if (findUser == nullptr) { return newAccount(sock, userLogin, userPassword, login->iClientVerC);
loginSessions[sock] = CNLoginData();
loginSessions[sock].userID = Database::addAccount(userLogin, userPassword); if (!CNLoginServer::isPasswordCorrect(findUser->Password, userPassword))
loginSessions[sock].slot = 1; return loginFail(LoginError::ID_AND_PASSWORD_DO_NOT_MATCH, userLogin, sock);
loginSessions[sock].lastHeartbeat = getTime();
success = true;
// if user exists, check if password is correct
}
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
if (CNLoginServer::isAccountInUse(findUser->AccountID)) { if (CNLoginServer::isAccountInUse(findUser->AccountID))
errorCode = (int)LoginError::ID_ALREADY_IN_USE; return loginFail(LoginError::ID_ALREADY_IN_USE, userLogin, sock);
}
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;
}
}
else {
errorCode = (int)LoginError::ID_AND_PASSWORD_DO_NOT_MATCH;
}
}
if (success) {
std::vector<Player> characters = Database::getCharacters(loginSessions[sock].userID); std::vector<Player> characters = Database::getCharacters(loginSessions[sock].userID);
int charCount = characters.size(); int charCount = characters.size();
INITSTRUCT(sP_LS2CL_REP_LOGIN_SUCC, resp); INITSTRUCT(sP_LS2CL_REP_LOGIN_SUCC, resp);
// 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;
@ -194,12 +184,28 @@ void CNLoginServer::login(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 {
INITSTRUCT(sP_LS2CL_REP_LOGIN_FAIL, resp); void CNLoginServer::newAccount(CNSocket* sock, std::string userLogin, std::string userPassword, int32_t clientVerC) {
loginSessions[sock] = CNLoginData();
loginSessions[sock].userID = Database::addAccount(userLogin, userPassword);
loginSessions[sock].slot = 1;
loginSessions[sock].lastHeartbeat = getTime();
INITSTRUCT(sP_LS2CL_REP_LOGIN_SUCC, resp);
U8toU16(userLogin, resp.szID, sizeof(resp.szID)); U8toU16(userLogin, resp.szID, sizeof(resp.szID));
resp.iErrorCode = errorCode;
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_FAIL, sizeof(sP_LS2CL_REP_LOGIN_FAIL)); resp.iCharCount = 0;
} resp.iSlotNum = loginSessions[sock].slot;
resp.iPaymentFlag = 1;
resp.iOpenBetaFlag = 0;
resp.uiSvrTime = getTime();
// send the resp in with original key
sock->sendPacket((void*)&resp, P_LS2CL_REP_LOGIN_SUCC, sizeof(sP_LS2CL_REP_LOGIN_SUCC));
// update keys
sock->setEKey(CNSocketEncryption::createNewKey(resp.uiSvrTime, resp.iCharCount + 1, resp.iSlotNum + 1));
sock->setFEKey(CNSocketEncryption::createNewKey((uint64_t)(*(uint64_t*)&CNSocketEncryption::defaultKey[0]), clientVerC, 1));
} }
void CNLoginServer::nameCheck(CNSocket* sock, CNPacketData* data) { void CNLoginServer::nameCheck(CNSocket* sock, CNPacketData* data) {

View File

@ -46,6 +46,7 @@ private:
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);
static bool isCharacterNameGood(std::string Firstname, std::string Lastname); static bool isCharacterNameGood(std::string Firstname, std::string Lastname);
static void newAccount(CNSocket* sock, std::string userLogin, std::string userPassword, int32_t clientVerC);
// returns true if success // returns true if success
static bool exitDuplicate(int accountId); static bool exitDuplicate(int accountId);
public: public:

View File

@ -166,6 +166,7 @@ int Database::addAccount(std::string login, std::string password) {
account.Password = password; account.Password = password;
account.Selected = 1; account.Selected = 1;
account.Created = getTimestamp(); account.Created = getTimestamp();
account.LastLogin = account.Created;
return db.insert(account); return db.insert(account);
} }