db: prepare item award manager queries
This commit is contained in:
@@ -3,12 +3,83 @@
|
||||
#include "DBManager.h"
|
||||
#include "ItemAwardManager.h"
|
||||
#include "Peer.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
#include "ClientManager.h"
|
||||
|
||||
|
||||
|
||||
DWORD g_dwLastCachedItemAwardID = 0;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool FallbackItemAwardLoadQuery()
|
||||
{
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FallbackItemAwardTakenQuery(DWORD dwAwardID, DWORD dwItemID)
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"UPDATE item_award SET taken_time=NOW(),item_id=%u WHERE id=%u AND taken_time IS NULL",
|
||||
dwItemID, dwAwardID);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_TAKEN, 0, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessItemAwardRow(DWORD dwID, const char* login, DWORD dwVnum, DWORD dwCount,
|
||||
DWORD dwSocket0, DWORD dwSocket1, DWORD dwSocket2, bool bMall, const char* why)
|
||||
{
|
||||
if (ItemAwardManager::instance().GetMapAward().find(dwID) != ItemAwardManager::instance().GetMapAward().end())
|
||||
return;
|
||||
|
||||
TItemAward* kData = new TItemAward;
|
||||
memset(kData, 0, sizeof(TItemAward));
|
||||
|
||||
kData->dwID = dwID;
|
||||
trim_and_lower(login, kData->szLogin, sizeof(kData->szLogin));
|
||||
kData->dwVnum = dwVnum;
|
||||
kData->dwCount = dwCount;
|
||||
kData->dwSocket0 = dwSocket0;
|
||||
kData->dwSocket1 = dwSocket1;
|
||||
kData->dwSocket2 = dwSocket2;
|
||||
kData->bMall = bMall;
|
||||
|
||||
if (why && *why)
|
||||
{
|
||||
strlcpy(kData->szWhy, why, sizeof(kData->szWhy));
|
||||
char* whyStr = kData->szWhy;
|
||||
char cmdStr[100] = "";
|
||||
strcpy(cmdStr, whyStr);
|
||||
char command[20] = "";
|
||||
strcpy(command, CClientManager::instance().GetCommand(cmdStr));
|
||||
if (!(strcmp(command, "GIFT")))
|
||||
{
|
||||
TPacketItemAwardInfromer giftData;
|
||||
strcpy(giftData.login, kData->szLogin);
|
||||
strcpy(giftData.command, command);
|
||||
giftData.vnum = kData->dwVnum;
|
||||
CClientManager::instance().ForwardPacket(DG::ITEMAWARD_INFORMER, &giftData, sizeof(TPacketItemAwardInfromer));
|
||||
}
|
||||
}
|
||||
|
||||
ItemAwardManager::instance().GetMapAward().insert(std::make_pair(dwID, 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<TItemAward*>& kSet = ItemAwardManager::instance().GetMapkSetAwardByLogin()[kData->szLogin];
|
||||
kSet.insert(kData);
|
||||
|
||||
if (dwID > g_dwLastCachedItemAwardID)
|
||||
g_dwLastCachedItemAwardID = dwID;
|
||||
}
|
||||
}
|
||||
|
||||
ItemAwardManager::ItemAwardManager()
|
||||
{
|
||||
}
|
||||
@@ -19,9 +90,45 @@ 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);
|
||||
static const char* query =
|
||||
"SELECT id, login, vnum, count, socket0, socket1, socket2, mall, COALESCE(why, '') "
|
||||
"FROM item_award WHERE taken_time IS NULL AND id > ?";
|
||||
|
||||
CStmt stmt;
|
||||
DWORD dwID = 0;
|
||||
DWORD dwVnum = 0;
|
||||
DWORD dwCount = 0;
|
||||
DWORD dwSocket0 = 0;
|
||||
DWORD dwSocket1 = 0;
|
||||
DWORD dwSocket2 = 0;
|
||||
char login[LOGIN_MAX_LEN + 1] = {};
|
||||
char why[ITEM_AWARD_WHY_MAX_LEN + 1] = {};
|
||||
DWORD dwMall = 0;
|
||||
|
||||
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(), query) ||
|
||||
!stmt.BindParam(MYSQL_TYPE_LONG, &g_dwLastCachedItemAwardID) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwID) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_STRING, login, sizeof(login)) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwVnum) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwCount) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwSocket0) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwSocket1) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwSocket2) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_LONG, &dwMall) ||
|
||||
!stmt.BindResult(MYSQL_TYPE_STRING, why, sizeof(why)) ||
|
||||
!stmt.Execute())
|
||||
{
|
||||
sys_err("ITEM_AWARD: prepared load failed, falling back to legacy query path");
|
||||
FallbackItemAwardLoadQuery();
|
||||
return;
|
||||
}
|
||||
|
||||
while (stmt.Fetch())
|
||||
{
|
||||
ProcessItemAwardRow(dwID, login, dwVnum, dwCount, dwSocket0, dwSocket1, dwSocket2, dwMall != 0, why);
|
||||
memset(login, 0, sizeof(login));
|
||||
memset(why, 0, sizeof(why));
|
||||
}
|
||||
}
|
||||
|
||||
void ItemAwardManager::Load(SQLMsg * pMsg)
|
||||
@@ -35,51 +142,22 @@ void ItemAwardManager::Load(SQLMsg * pMsg)
|
||||
|
||||
DWORD dwID = 0;
|
||||
str_to_number(dwID, row[col++]);
|
||||
const char* login = row[col++];
|
||||
|
||||
if (m_map_award.find(dwID) != m_map_award.end())
|
||||
continue;
|
||||
DWORD dwVnum = 0;
|
||||
DWORD dwCount = 0;
|
||||
DWORD dwSocket0 = 0;
|
||||
DWORD dwSocket1 = 0;
|
||||
DWORD dwSocket2 = 0;
|
||||
DWORD dwMall = 0;
|
||||
str_to_number(dwVnum, row[col++]);
|
||||
str_to_number(dwCount, row[col++]);
|
||||
str_to_number(dwSocket0, row[col++]);
|
||||
str_to_number(dwSocket1, row[col++]);
|
||||
str_to_number(dwSocket2, row[col++]);
|
||||
str_to_number(dwMall, row[col++]);
|
||||
|
||||
TItemAward * kData = new TItemAward;
|
||||
memset(kData, 0, sizeof(TItemAward));
|
||||
|
||||
kData->dwID = dwID;
|
||||
trim_and_lower(row[col++], kData->szLogin, sizeof(kData->szLogin));
|
||||
str_to_number(kData->dwVnum, row[col++]);
|
||||
str_to_number(kData->dwCount, row[col++]);
|
||||
str_to_number(kData->dwSocket0, row[col++]);
|
||||
str_to_number(kData->dwSocket1, row[col++]);
|
||||
str_to_number(kData->dwSocket2, row[col++]);
|
||||
str_to_number(kData->bMall, row[col++]);
|
||||
|
||||
if (row[col])
|
||||
{
|
||||
strlcpy(kData->szWhy, row[col], sizeof(kData->szWhy));
|
||||
//게임 중에 why콜룸에 변동이 생기면
|
||||
char* whyStr = kData->szWhy; //why 콜룸 읽기
|
||||
char cmdStr[100] = ""; //why콜룸에서 읽은 값을 임시 문자열에 복사해둠
|
||||
strcpy(cmdStr,whyStr); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
|
||||
char command[20] = "";
|
||||
strcpy(command,CClientManager::instance().GetCommand(cmdStr)); // command 얻기
|
||||
//sys_err("%d, %s",pItemAward->dwID,command);
|
||||
if( !(strcmp(command,"GIFT") )) // command 가 GIFT이면
|
||||
{
|
||||
TPacketItemAwardInfromer giftData;
|
||||
strcpy(giftData.login, kData->szLogin); //로그인 아이디 복사
|
||||
strcpy(giftData.command, command); //명령어 복사
|
||||
giftData.vnum = kData->dwVnum; //아이템 vnum도 복사
|
||||
CClientManager::instance().ForwardPacket(DG::ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
|
||||
}
|
||||
}
|
||||
|
||||
m_map_award.insert(std::make_pair(dwID, 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<TItemAward *> & kSet = m_map_kSetAwardByLogin[kData->szLogin];
|
||||
kSet.insert(kData);
|
||||
|
||||
if (dwID > g_dwLastCachedItemAwardID)
|
||||
g_dwLastCachedItemAwardID = dwID;
|
||||
ProcessItemAwardRow(dwID, login, dwVnum, dwCount, dwSocket0, dwSocket1, dwSocket2, dwMall != 0, row[col] ? row[col] : "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,13 +187,18 @@ void ItemAwardManager::Taken(DWORD dwAwardID, DWORD dwItemID)
|
||||
//
|
||||
// Update taken_time in database to prevent not to give him again.
|
||||
//
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
static const char* 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);
|
||||
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_TAKEN, 0, NULL);
|
||||
CStmt stmt;
|
||||
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(), query) ||
|
||||
!stmt.BindParam(MYSQL_TYPE_LONG, &dwItemID) ||
|
||||
!stmt.BindParam(MYSQL_TYPE_LONG, &dwAwardID) ||
|
||||
!stmt.Execute())
|
||||
{
|
||||
sys_err("ITEM_AWARD: prepared taken update failed, falling back to legacy query path");
|
||||
FallbackItemAwardTakenQuery(dwAwardID, dwItemID);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<DWORD, TItemAward *>& ItemAwardManager::GetMapAward()
|
||||
@@ -126,4 +209,4 @@ std::map<DWORD, TItemAward *>& ItemAwardManager::GetMapAward()
|
||||
std::map<std::string, std::set<TItemAward *> >& ItemAwardManager::GetMapkSetAwardByLogin()
|
||||
{
|
||||
return m_map_kSetAwardByLogin;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user