db: prepare guild and rename queries
Some checks failed
build / Linux asan (push) Has been cancelled
build / Linux release (push) Has been cancelled
build / FreeBSD build (push) Has been cancelled

This commit is contained in:
server
2026-04-14 09:58:34 +02:00
parent 14e084d691
commit 58273bc116
7 changed files with 207 additions and 106 deletions

View File

@@ -7,12 +7,62 @@
#include "Config.h"
#include "QID.h"
#include "Cache.h"
#include "libsql/Statement.h"
extern std::string g_stLocale;
extern bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab);
extern int g_test_server;
extern int g_log;
namespace
{
bool CountPlayersByNameExcludingId(const char* player_name, DWORD player_id, unsigned long long* count)
{
char query[QUERY_MAX_LEN];
if (g_stLocale == "sjis")
snprintf(query, sizeof(query), "SELECT COUNT(*) FROM player%s WHERE name = ? COLLATE sjis_japanese_ci AND id <> ?", GetTablePostfix());
else
snprintf(query, sizeof(query), "SELECT COUNT(*) FROM player%s WHERE name = ? AND id <> ?", GetTablePostfix());
CStmt stmt;
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(SQL_PLAYER), query))
return false;
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) player_name, CHARACTER_NAME_MAX_LEN))
return false;
if (!stmt.BindParam(MYSQL_TYPE_LONG, &player_id))
return false;
if (!stmt.BindResult(MYSQL_TYPE_LONGLONG, count))
return false;
if (!stmt.Execute() || !stmt.Fetch())
return false;
return true;
}
bool UpdatePlayerName(DWORD player_id, const char* player_name)
{
char query[QUERY_MAX_LEN];
snprintf(query, sizeof(query), "UPDATE player%s SET name = ?, change_name = 0 WHERE id = ?", GetTablePostfix());
CStmt stmt;
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(SQL_PLAYER), query))
return false;
if (!stmt.BindParam(MYSQL_TYPE_STRING, (void*) player_name, CHARACTER_NAME_MAX_LEN))
return false;
if (!stmt.BindParam(MYSQL_TYPE_LONG, &player_id))
return false;
return stmt.Execute() != 0;
}
}
bool CClientManager::InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle, const char * c_pszIP)
{
char szLogin[LOGIN_MAX_LEN + 1];
@@ -464,44 +514,24 @@ void CClientManager::QUERY_LOGOUT(CPeer * peer, DWORD dwHandle,const char * data
void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p)
{
char queryStr[QUERY_MAX_LEN];
if (g_stLocale == "sjis")
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci AND id <> %u",
GetTablePostfix(), p->name, p->pid);
else
snprintf(queryStr, sizeof(queryStr),
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' AND id <> %u", GetTablePostfix(), p->name, p->pid);
auto pMsg = CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER);
if (pMsg->Get()->uiNumRows)
{
if (!pMsg->Get()->pSQLResult)
{
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
if (*row[0] != '0')
{
peer->EncodeHeader(DG::PLAYER_CREATE_ALREADY, dwHandle, 0);
return;
}
}
else
unsigned long long count = 0;
if (!CountPlayersByNameExcludingId(p->name, p->pid, &count))
{
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
snprintf(queryStr, sizeof(queryStr),
"UPDATE player%s SET name='%s',change_name=0 WHERE id=%u", GetTablePostfix(), p->name, p->pid);
if (count != 0)
{
peer->EncodeHeader(DG::PLAYER_CREATE_ALREADY, dwHandle, 0);
return;
}
auto pMsg0 = CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER);
if (!UpdatePlayerName(p->pid, p->name))
{
peer->EncodeHeader(DG::PLAYER_CREATE_FAILED, dwHandle, 0);
return;
}
TPacketDGChangeName pdg;
peer->EncodeHeader(DG::CHANGE_NAME, dwHandle, sizeof(TPacketDGChangeName));
@@ -509,4 +539,3 @@ void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDCh
strlcpy(pdg.name, p->name, sizeof(pdg.name));
peer->Encode(&pdg, sizeof(TPacketDGChangeName));
}

View File

@@ -43,6 +43,7 @@ class CDBManager : public singleton<CDBManager>
void ReturnQuery(const char * c_pszQuery, int iType, IDENT dwIdent, void * pvData, int iSlot = SQL_PLAYER);
void AsyncQuery(const char * c_pszQuery, int iSlot = SQL_PLAYER);
std::unique_ptr<SQLMsg> DirectQuery(const char* c_pszQuery, int iSlot = SQL_PLAYER);
CAsyncSQL* GetDirectSQL(int iSlot = SQL_PLAYER) { return m_directSQL[iSlot].get(); }
SQLMsg * PopResult();
SQLMsg * PopResult(eSQL_SLOT slot );