From 4cc8efaac8e03c6ca3be95ca238b7d22b85298e9 Mon Sep 17 00:00:00 2001 From: server Date: Mon, 13 Apr 2026 23:42:49 +0200 Subject: [PATCH] db: prepare highscore register flow --- src/db/ClientManager.cpp | 5 -- src/db/ClientManager.h | 1 - src/db/ClientManagerPlayer.cpp | 126 ++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/db/ClientManager.cpp b/src/db/ClientManager.cpp index 48b904a..4a30917 100644 --- a/src/db/ClientManager.cpp +++ b/src/db/ClientManager.cpp @@ -2710,11 +2710,6 @@ int CClientManager::AnalyzeQueryResult(SQLMsg * msg) RESULT_SAFEBOX_CHANGE_PASSWORD_SECOND(peer, msg); break; - case QID_HIGHSCORE_REGISTER: - sys_log(0, "QUERY_RESULT: GD::HIGHSCORE_REGISTER %p", msg); - RESULT_HIGHSCORE_REGISTER(peer, msg); - break; - case QID_SAFEBOX_SAVE: case QID_ITEM_SAVE: case QID_ITEM_DESTROY: diff --git a/src/db/ClientManager.h b/src/db/ClientManager.h index b110780..5a9f897 100644 --- a/src/db/ClientManager.h +++ b/src/db/ClientManager.h @@ -299,7 +299,6 @@ class CClientManager : public CNetBase, public singleton void SendPartyOnSetup(CPeer * peer); void QUERY_HIGHSCORE_REGISTER(CPeer * peer, TPacketGDHighscore* data); - void RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg); void QUERY_FLUSH_CACHE(CPeer * pkPeer, const char * c_pData); diff --git a/src/db/ClientManagerPlayer.cpp b/src/db/ClientManagerPlayer.cpp index 45478eb..be92ce1 100644 --- a/src/db/ClientManagerPlayer.cpp +++ b/src/db/ClientManagerPlayer.cpp @@ -30,6 +30,57 @@ namespace return stmt.Prepare(sql, query.c_str()); } + + bool LoadHighscoreValue(const char* board, uint32_t playerId, int& value, bool& found) + { + CStmt stmt; + const std::string query = + "SELECT value FROM highscore" + std::string(GetTablePostfix()) + " WHERE board=? AND pid=?"; + + found = false; + value = 0; + + if (!PreparePlayerStmt(stmt, query)) + return false; + + if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast(board)) + || !stmt.BindParam(MYSQL_TYPE_LONG, &playerId) + || !stmt.BindResult(MYSQL_TYPE_LONG, &value)) + { + return false; + } + + if (!stmt.Execute()) + return false; + + if (stmt.iRows == 0) + return true; + + if (!stmt.Fetch()) + return false; + + found = true; + return true; + } + + bool WriteHighscoreValue(const char* board, uint32_t playerId, int value, bool replaceExisting) + { + CStmt stmt; + const std::string query = std::string(replaceExisting ? "REPLACE INTO highscore" : "INSERT INTO highscore") + + std::string(GetTablePostfix()) + " (board, pid, value) VALUES(?, ?, ?)"; + + if (!PreparePlayerStmt(stmt, query)) + return false; + + if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast(board)) + || !stmt.BindParam(MYSQL_TYPE_LONG, &playerId) + || !stmt.BindParam(MYSQL_TYPE_LONG, &value)) + { + return false; + } + + return stmt.Execute(); + } } // @@ -1272,73 +1323,30 @@ void CClientManager::QUERY_REMOVE_AFFECT(CPeer * peer, TPacketGDRemoveAffect * p void CClientManager::QUERY_HIGHSCORE_REGISTER(CPeer* peer, TPacketGDHighscore * data) { - char szQuery[128]; - const std::string escapedBoard = CDBManager::instance().EscapeStringCopy(data->szBoard, strnlen(data->szBoard, sizeof(data->szBoard))); - snprintf(szQuery, sizeof(szQuery), "SELECT value FROM highscore%s WHERE board='%s' AND pid = %u", GetTablePostfix(), escapedBoard.c_str(), data->dwPID); - + (void)peer; sys_log(0, "GD::HIGHSCORE_REGISTER: PID %u", data->dwPID); + char board[sizeof(data->szBoard)]; + int currentValue = 0; + bool found = false; + const bool higherIsBetter = data->cDir > 0; + const int value = static_cast(data->lValue); - ClientHandleInfo * pi = new ClientHandleInfo(0); - strlcpy(pi->login, data->szBoard, sizeof(pi->login)); - pi->account_id = (DWORD)data->lValue; - pi->player_id = data->dwPID; - pi->account_index = (data->cDir > 0); + strlcpy(board, data->szBoard, sizeof(board)); - CDBManager::instance().ReturnQuery(szQuery, QID_HIGHSCORE_REGISTER, peer->GetHandle(), pi); -} - -void CClientManager::RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg) -{ - CQueryInfo * qi = (CQueryInfo *) msg->pvUserData; - ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData; - //DWORD dwHandle = pi->dwHandle; - - char szBoard[21]; - strlcpy(szBoard, pi->login, sizeof(szBoard)); - const std::string escapedBoard = CDBManager::instance().EscapeStringCopy(szBoard, strnlen(szBoard, sizeof(szBoard))); - int value = (int)pi->account_id; - - SQLResult * res = msg->Get(); - - if (res->uiNumRows == 0) + if (!LoadHighscoreValue(board, data->dwPID, currentValue, found)) { - // 새로운 하이스코어를 삽입 - char buf[256]; - snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), escapedBoard.c_str(), pi->player_id, value); - CDBManager::instance().AsyncQuery(buf); + sys_err("failed to load highscore for board %s pid %u", board, data->dwPID); + return; } - else + + if (found) { - if (!res->pSQLResult) - { - delete pi; + if ((higherIsBetter && currentValue >= value) || (!higherIsBetter && currentValue <= value)) return; - } - - MYSQL_ROW row = mysql_fetch_row(res->pSQLResult); - if (row && row[0]) - { - int current_value = 0; str_to_number(current_value, row[0]); - if (pi->account_index && current_value >= value || !pi->account_index && current_value <= value) - { - value = current_value; - } - else - { - char buf[256]; - snprintf(buf, sizeof(buf), "REPLACE INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), escapedBoard.c_str(), pi->player_id, value); - CDBManager::instance().AsyncQuery(buf); - } - } - else - { - char buf[256]; - snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), escapedBoard.c_str(), pi->player_id, value); - CDBManager::instance().AsyncQuery(buf); - } } - // TODO: 이곳에서 하이스코어가 업데이트 되었는지 체크하여 공지를 뿌려야한다. - delete pi; + + if (!WriteHighscoreValue(board, data->dwPID, value, found)) + sys_err("failed to write highscore for board %s pid %u", board, data->dwPID); } void CClientManager::InsertLogoutPlayer(DWORD pid)