From ed9fe61faf955438f50d3c6bf7a53906a354cd8d Mon Sep 17 00:00:00 2001 From: Gent Semaj Date: Sat, 23 Nov 2024 11:29:55 -0800 Subject: [PATCH] Auth cookie refresh on PC_EXIT --- src/PlayerManager.cpp | 8 ++++++++ src/db/Database.hpp | 1 + src/db/login.cpp | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 3a4e5bb..efcaeec 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -396,6 +396,14 @@ static void heartbeatPlayer(CNSocket* sock, CNPacketData* data) { static void exitGame(CNSocket* sock, CNPacketData* data) { auto exitData = (sP_CL2FE_REQ_PC_EXIT*)data->buf; + + // Refresh any auth cookie, in case "change character" was used + Player* plr = getPlayer(sock); + if (plr != nullptr) { + // 5 seconds should be enough to log in again + Database::refreshCookie(plr->accountId, 5); + } + INITSTRUCT(sP_FE2CL_REP_PC_EXIT_SUCC, response); response.iID = exitData->iID; diff --git a/src/db/Database.hpp b/src/db/Database.hpp index 3bd1a0a..151d595 100644 --- a/src/db/Database.hpp +++ b/src/db/Database.hpp @@ -56,6 +56,7 @@ namespace Database { // return true if cookie is valid for the account. // invalidates the stored cookie afterwards bool checkCookie(int accountId, const char *cookie); + void refreshCookie(int accountId, int durationSec); // interface for the /ban command bool banPlayer(int playerId, std::string& reason); diff --git a/src/db/login.cpp b/src/db/login.cpp index b7afd29..fd80a17 100644 --- a/src/db/login.cpp +++ b/src/db/login.cpp @@ -151,6 +151,27 @@ bool Database::checkCookie(int accountId, const char *tryCookie) { return match; } +void Database::refreshCookie(int accountId, int durationSec) { + std::lock_guard lock(dbCrit); + + const char* sql = R"( + UPDATE Auth + SET Expires = ? + WHERE AccountID = ?; + )"; + + int expires = getTimestamp() + durationSec; + + sqlite3_stmt* stmt; + sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + sqlite3_bind_int(stmt, 1, expires); + sqlite3_bind_int(stmt, 2, accountId); + int rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if (rc != SQLITE_DONE) + std::cout << "[WARN] Database fail on refreshCookie(): " << sqlite3_errmsg(db) << std::endl; +} + void Database::updateSelected(int accountId, int slot) { std::lock_guard lock(dbCrit);