diff --git a/src/CNLoginServer.cpp b/src/CNLoginServer.cpp index f14d991..91c75e2 100644 --- a/src/CNLoginServer.cpp +++ b/src/CNLoginServer.cpp @@ -55,6 +55,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { loginSessions[sock] = CNLoginData(); loginSessions[sock].userID = Database::addAccount(userLogin, userPassword); loginSessions[sock].slot = 1; + loginSessions[sock].lastHeartbeat = getTime(); success = true; } // if user exists, check if password is correct @@ -72,6 +73,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { loginSessions[sock] = CNLoginData(); loginSessions[sock].userID = findUser->AccountID; loginSessions[sock].slot = findUser->Selected; + loginSessions[sock].lastHeartbeat = getTime(); success = true; } } @@ -143,7 +145,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { break; } case P_CL2LS_REP_LIVE_CHECK: { - // stubbed, the client really doesn't care LOL + loginSessions[sock].lastHeartbeat = getTime(); break; } case P_CL2LS_REQ_CHECK_CHAR_NAME: { @@ -163,6 +165,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { errorcode = 1; } + loginSessions[sock].lastHeartbeat = getTime(); + if (success) { INITSTRUCT(sP_LS2CL_REP_CHECK_CHAR_NAME_SUCC, resp); @@ -201,6 +205,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { memcpy(resp.szFirstName, save->szFirstName, sizeof(char16_t) * 9); memcpy(resp.szLastName, save->szLastName, sizeof(char16_t) * 17); + loginSessions[sock].lastHeartbeat = getTime(); + 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); @@ -245,6 +251,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { loginSessions[sock].characters[UID] = Player(player); loginSessions[sock].characters[UID].FEKey = sock->getFEKey(); + loginSessions[sock].lastHeartbeat = getTime(); + sock->sendPacket((void*)&resp, P_LS2CL_REP_CHAR_CREATE_SUCC, sizeof(sP_LS2CL_REP_CHAR_CREATE_SUCC)); Database::updateSelected(loginSessions[sock].userID, player.slot); break; @@ -259,7 +267,7 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { 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)); - + loginSessions[sock].lastHeartbeat = getTime(); break; } case P_CL2LS_REQ_CHAR_SELECT: { @@ -274,6 +282,9 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { std::cout << "P_CL2LS_REQ_CHAR_SELECT:" << std::endl; std::cout << "\tPC_UID: " << chararacter->iPC_UID << std::endl; ) + + loginSessions[sock].lastHeartbeat = getTime(); + loginSessions[sock].selectedChar = chararacter->iPC_UID; 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)); @@ -315,6 +326,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { auto key = loginSessions[sock].characters[save->iPC_UID].FEKey; loginSessions[sock].characters[save->iPC_UID] = Player(Database::getPlayer(save->iPC_UID)); loginSessions[sock].characters[save->iPC_UID].FEKey = key; + + loginSessions[sock].lastHeartbeat = getTime(); // no response here break; } @@ -331,6 +344,8 @@ void CNLoginServer::handlePacket(CNSocket* sock, CNPacketData* data) { memcpy(resp.szLastName, save->szLastName, sizeof(char16_t) * 17); resp.iSlotNum = save->iSlotNum; + loginSessions[sock].lastHeartbeat = getTime(); + sock->sendPacket((void*)&resp, P_LS2CL_REP_CHANGE_CHAR_NAME_SUCC, sizeof(sP_LS2CL_REP_CHANGE_CHAR_NAME_SUCC)); break; } @@ -370,6 +385,25 @@ void CNLoginServer::killConnection(CNSocket* cns) { loginSessions.erase(cns); } +void CNLoginServer::onStep() { + time_t currTime = getTime(); + static time_t lastCheck = 0; + + if (currTime - lastCheck < 16000) + return; + lastCheck = currTime; + + for (auto& pair : loginSessions) { + if (pair.second.lastHeartbeat != 0 && currTime - pair.second.lastHeartbeat > 32000) { + pair.first->kill(); + continue; + } + + INITSTRUCT(sP_LS2CL_REQ_LIVE_CHECK, pkt); + pair.first->sendPacket((void*)&pkt, P_LS2CL_REQ_LIVE_CHECK, sizeof(sP_LS2CL_REQ_LIVE_CHECK)); + } +} + #pragma region helperMethods bool CNLoginServer::isAccountInUse(int accountId) { std::map::iterator it; diff --git a/src/CNLoginServer.hpp b/src/CNLoginServer.hpp index 6ab12cb..6727e98 100644 --- a/src/CNLoginServer.hpp +++ b/src/CNLoginServer.hpp @@ -10,6 +10,7 @@ struct CNLoginData { std::map characters; int64_t selectedChar; int userID; int slot; + time_t lastHeartbeat; }; enum class LoginError { @@ -41,4 +42,5 @@ public: void newConnection(CNSocket* cns); void killConnection(CNSocket* cns); + void onStep(); }; diff --git a/src/MobManager.cpp b/src/MobManager.cpp index f73e940..819fde3 100644 --- a/src/MobManager.cpp +++ b/src/MobManager.cpp @@ -419,7 +419,8 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) { } // if we got there - if (distance <= mob->data["m_iIdleRange"]) { + //if (distance <= mob->data["m_iIdleRange"]) { + if (distance <= 10) { // retreat back to the spawn point mob->state = MobState::ROAMING; mob->appearanceData.iHP = mob->maxHealth; mob->killedTime = 0;