db: prepare highscore register flow
This commit is contained in:
@@ -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<char*>(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<char*>(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<int>(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)
|
||||
|
||||
Reference in New Issue
Block a user