From 741da38c8dfb427a07bc63ac5c14d107505fcb08 Mon Sep 17 00:00:00 2001 From: server Date: Mon, 13 Apr 2026 23:36:41 +0200 Subject: [PATCH] db: prepare item award manager queries --- src/db/ItemAwardManager.cpp | 133 +++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 9 deletions(-) diff --git a/src/db/ItemAwardManager.cpp b/src/db/ItemAwardManager.cpp index b119699..feb477b 100644 --- a/src/db/ItemAwardManager.cpp +++ b/src/db/ItemAwardManager.cpp @@ -5,6 +5,33 @@ #include "Peer.h" #include "ClientManager.h" +#include "libsql/Statement.h" + +#include + +namespace +{ + bool PrepareItemAwardStmt(CStmt& stmt, const std::string& query) + { + CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(SQL_PLAYER); + + if (!sql) + { + sys_err("item award SQL handle is not initialized"); + return false; + } + + return stmt.Prepare(sql, query.c_str()); + } + + void NullTerminateAwardResult(char* value, size_t valueLen, size_t capacity) + { + if (!value || capacity == 0) + return; + + value[std::min(valueLen, capacity - 1)] = '\0'; + } +} @@ -19,9 +46,91 @@ ItemAwardManager::~ItemAwardManager() void ItemAwardManager::RequestLoad() { - char szQuery[QUERY_MAX_LEN]; - snprintf(szQuery, sizeof(szQuery), "SELECT id,login,vnum,count,socket0,socket1,socket2,mall,why FROM item_award WHERE taken_time IS NULL and id > %d", g_dwLastCachedItemAwardID); - CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_LOAD, 0, NULL); + CStmt stmt; + const std::string query = + "SELECT id, login, vnum, count, socket0, socket1, socket2, mall, why " + "FROM item_award WHERE taken_time IS NULL AND id > ?"; + DWORD awardId = 0; + char login[LOGIN_MAX_LEN + 1]; + DWORD vnum = 0; + DWORD count = 0; + DWORD socket0 = 0; + DWORD socket1 = 0; + DWORD socket2 = 0; + uint8_t mall = 0; + char why[ITEM_AWARD_WHY_MAX_LEN + 1]; + + if (!PrepareItemAwardStmt(stmt, query)) + return; + + memset(login, 0, sizeof(login)); + memset(why, 0, sizeof(why)); + + if (!stmt.BindParam(MYSQL_TYPE_LONG, &g_dwLastCachedItemAwardID) + || !stmt.BindResult(MYSQL_TYPE_LONG, &awardId) + || !stmt.BindResult(MYSQL_TYPE_STRING, login, sizeof(login)) + || !stmt.BindResult(MYSQL_TYPE_LONG, &vnum) + || !stmt.BindResult(MYSQL_TYPE_LONG, &count) + || !stmt.BindResult(MYSQL_TYPE_LONG, &socket0) + || !stmt.BindResult(MYSQL_TYPE_LONG, &socket1) + || !stmt.BindResult(MYSQL_TYPE_LONG, &socket2) + || !stmt.BindResult(MYSQL_TYPE_TINY, &mall) + || !stmt.BindResult(MYSQL_TYPE_STRING, why, sizeof(why))) + { + return; + } + + if (!stmt.Execute()) + return; + + while (stmt.Fetch()) + { + if (m_map_award.find(awardId) != m_map_award.end()) + continue; + + NullTerminateAwardResult(login, stmt.GetResultLength(1), sizeof(login)); + NullTerminateAwardResult(why, stmt.GetResultLength(8), sizeof(why)); + + TItemAward* kData = new TItemAward; + memset(kData, 0, sizeof(TItemAward)); + + kData->dwID = awardId; + trim_and_lower(login, kData->szLogin, sizeof(kData->szLogin)); + kData->dwVnum = vnum; + kData->dwCount = count; + kData->dwSocket0 = socket0; + kData->dwSocket1 = socket1; + kData->dwSocket2 = socket2; + kData->bMall = mall != 0; + + if (why[0] != '\0') + { + strlcpy(kData->szWhy, why, sizeof(kData->szWhy)); + char cmdStr[100] = ""; + strlcpy(cmdStr, kData->szWhy, sizeof(cmdStr)); + char command[20] = ""; + strlcpy(command, CClientManager::instance().GetCommand(cmdStr), sizeof(command)); + if (!strcmp(command, "GIFT")) + { + TPacketItemAwardInfromer giftData; + memset(&giftData, 0, sizeof(giftData)); + strlcpy(giftData.login, kData->szLogin, sizeof(giftData.login)); + strlcpy(giftData.command, command, sizeof(giftData.command)); + giftData.vnum = kData->dwVnum; + CClientManager::instance().ForwardPacket(DG::ITEMAWARD_INFORMER, &giftData, sizeof(TPacketItemAwardInfromer)); + } + } + + m_map_award.insert(std::make_pair(awardId, kData)); + + printf("ITEM_AWARD load id %u bMall %d \n", kData->dwID, kData->bMall); + sys_log(0, "ITEM_AWARD: load id %lu login %s vnum %lu count %u socket %lu", kData->dwID, kData->szLogin, kData->dwVnum, kData->dwCount, kData->dwSocket0); + std::set& kSet = m_map_kSetAwardByLogin[kData->szLogin]; + kSet.insert(kData); + + if (awardId > g_dwLastCachedItemAwardID) + g_dwLastCachedItemAwardID = awardId; + } } void ItemAwardManager::Load(SQLMsg * pMsg) @@ -109,13 +218,19 @@ void ItemAwardManager::Taken(DWORD dwAwardID, DWORD dwItemID) // // Update taken_time in database to prevent not to give him again. // - char szQuery[QUERY_MAX_LEN]; + CStmt stmt; + const std::string query = "UPDATE item_award SET taken_time=NOW(), item_id=? WHERE id=? AND taken_time IS NULL"; - snprintf(szQuery, sizeof(szQuery), - "UPDATE item_award SET taken_time=NOW(),item_id=%u WHERE id=%u AND taken_time IS NULL", - dwItemID, dwAwardID); + if (!PrepareItemAwardStmt(stmt, query)) + return; - CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_TAKEN, 0, NULL); + if (!stmt.BindParam(MYSQL_TYPE_LONG, &dwItemID) + || !stmt.BindParam(MYSQL_TYPE_LONG, &dwAwardID)) + { + return; + } + + stmt.Execute(); } std::map& ItemAwardManager::GetMapAward() @@ -126,4 +241,4 @@ std::map& ItemAwardManager::GetMapAward() std::map >& ItemAwardManager::GetMapkSetAwardByLogin() { return m_map_kSetAwardByLogin; -} \ No newline at end of file +}