db: prepare client manager queries
This commit is contained in:
@@ -40,19 +40,39 @@ int g_query_count[2];
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareClientPlayerStmt(CStmt& stmt, const std::string& query)
|
||||
bool PrepareClientStmt(CStmt& stmt, const std::string& query, int slot)
|
||||
{
|
||||
CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(SQL_PLAYER);
|
||||
CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(slot);
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("player SQL handle is not initialized");
|
||||
sys_err("SQL handle is not initialized for slot %d", slot);
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool PrepareClientPlayerStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
return PrepareClientStmt(stmt, query, SQL_PLAYER);
|
||||
}
|
||||
|
||||
bool PrepareClientCommonStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
return PrepareClientStmt(stmt, query, SQL_COMMON);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void NullTerminateClientResult(char (&buffer)[N], unsigned long length)
|
||||
{
|
||||
size_t finalLength = length;
|
||||
if (finalLength >= N)
|
||||
finalLength = N - 1;
|
||||
|
||||
buffer[finalLength] = '\0';
|
||||
}
|
||||
|
||||
bool LoadSafeboxPassword(uint32_t accountId, char* password, size_t passwordSize, bool* foundRow)
|
||||
{
|
||||
CStmt stmt;
|
||||
@@ -711,8 +731,10 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
|
||||
std::vector<std::pair<DWORD, DWORD> > vec_dwFinishedAwardID;
|
||||
|
||||
__typeof(pSet->begin()) it = pSet->begin();
|
||||
|
||||
char szQuery[512];
|
||||
const char* itemWindowName = pi->ip[0] == 0 ? "SAFEBOX" : "MALL";
|
||||
const std::string insertAwardItemQuery = std::string(
|
||||
"INSERT INTO item") + GetTablePostfix()
|
||||
+ " (id, owner_id, window, pos, vnum, count, socket0, socket1, socket2) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
while (it != pSet->end())
|
||||
{
|
||||
@@ -841,25 +863,37 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"INSERT INTO item%s (id, owner_id, window, pos, vnum, count, socket0, socket1, socket2) "
|
||||
"VALUES(%u, %u, '%s', %d, %u, %u, %u, %u, %u)",
|
||||
GetTablePostfix(),
|
||||
GainItemID(),
|
||||
pi->account_id,
|
||||
pi->ip[0] == 0 ? "SAFEBOX" : "MALL",
|
||||
iPos,
|
||||
pItemAward->dwVnum, pItemAward->dwCount, pItemAward->dwSocket0, pItemAward->dwSocket1, dwSocket2);
|
||||
uint32_t itemId = GainItemID();
|
||||
int32_t pos = iPos;
|
||||
uint32_t ownerId = pi->account_id;
|
||||
uint32_t vnum = pItemAward->dwVnum;
|
||||
uint32_t count = pItemAward->dwCount;
|
||||
uint32_t socket0 = pItemAward->dwSocket0;
|
||||
uint32_t socket1 = pItemAward->dwSocket1;
|
||||
uint32_t socket2 = dwSocket2;
|
||||
CStmt insertAwardItemStmt;
|
||||
|
||||
if (!PrepareClientPlayerStmt(insertAwardItemStmt, insertAwardItemQuery)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &itemId)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &ownerId)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(itemWindowName), static_cast<int>(strlen(itemWindowName)))
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &pos)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &vnum)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &count)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &socket0)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &socket1)
|
||||
|| !insertAwardItemStmt.BindParam(MYSQL_TYPE_LONG, &socket2)
|
||||
|| !insertAwardItemStmt.Execute())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
sys_log(0, "SAFEBOX insert: owner=%u window=%s pos=%d vnum=%u count=%u id=%u",
|
||||
ownerId, itemWindowName, pos, vnum, count, itemId);
|
||||
|
||||
item.id = itemId;
|
||||
}
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
SQLResult * pRes = pmsg->Get();
|
||||
sys_log(0, "SAFEBOX Query : [%s]", szQuery);
|
||||
|
||||
if (pRes->uiAffectedRows == 0 || pRes->uiInsertID == 0 || pRes->uiAffectedRows == (uint32_t)-1)
|
||||
break;
|
||||
|
||||
item.id = pmsg->Get()->uiInsertID;
|
||||
item.window = pi->ip[0] == 0 ? SAFEBOX : MALL,
|
||||
item.pos = iPos;
|
||||
item.count = pItemAward->dwCount;
|
||||
@@ -1100,7 +1134,6 @@ void CClientManager::QUERY_EMPIRE_SELECT(CPeer * pkPeer, DWORD dwHandle, TEmpire
|
||||
}
|
||||
else if (playerIndexStmt.iRows && playerIndexStmt.Fetch())
|
||||
{
|
||||
CStmt moveEmpirePlayerStmt;
|
||||
const std::string moveEmpirePlayerQuery = std::string("UPDATE player") + GetTablePostfix()
|
||||
+ " SET map_index=?,x=?,y=? WHERE id=?";
|
||||
|
||||
@@ -1121,11 +1154,7 @@ void CClientManager::QUERY_EMPIRE_SELECT(CPeer * pkPeer, DWORD dwHandle, TEmpire
|
||||
{ 969600, 278400 } // 진노국
|
||||
};
|
||||
|
||||
if (!PrepareClientPlayerStmt(moveEmpirePlayerStmt, moveEmpirePlayerQuery))
|
||||
{
|
||||
sys_err("EmpireSelect: failed to prepare player move query");
|
||||
}
|
||||
else for (int i = 0; i < 3; ++i)
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
sys_log(0, "EMPIRE PIDS[%u]", pids[i]);
|
||||
|
||||
@@ -1138,8 +1167,10 @@ void CClientManager::QUERY_EMPIRE_SELECT(CPeer * pkPeer, DWORD dwHandle, TEmpire
|
||||
uint32_t x = g_start_position[p->bEmpire][0];
|
||||
uint32_t y = g_start_position[p->bEmpire][1];
|
||||
uint32_t playerId = pids[i];
|
||||
CStmt moveEmpirePlayerStmt;
|
||||
|
||||
if (!moveEmpirePlayerStmt.BindParam(MYSQL_TYPE_LONG, &mapIndex)
|
||||
if (!PrepareClientPlayerStmt(moveEmpirePlayerStmt, moveEmpirePlayerQuery)
|
||||
|| !moveEmpirePlayerStmt.BindParam(MYSQL_TYPE_LONG, &mapIndex)
|
||||
|| !moveEmpirePlayerStmt.BindParam(MYSQL_TYPE_LONG, &x)
|
||||
|| !moveEmpirePlayerStmt.BindParam(MYSQL_TYPE_LONG, &y)
|
||||
|| !moveEmpirePlayerStmt.BindParam(MYSQL_TYPE_LONG, &playerId)
|
||||
@@ -1883,15 +1914,21 @@ void CClientManager::CreateObject(TPacketGDCreateObject * p)
|
||||
{
|
||||
using namespace building;
|
||||
|
||||
char szQuery[512];
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("INSERT INTO object") + GetTablePostfix()
|
||||
+ " (land_id, vnum, map_index, x, y, x_rot, y_rot, z_rot) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"INSERT INTO object%s (land_id, vnum, map_index, x, y, x_rot, y_rot, z_rot) VALUES(%u, %u, %d, %d, %d, %f, %f, %f)",
|
||||
GetTablePostfix(), p->dwLandID, p->dwVnum, p->lMapIndex, p->x, p->y, p->xRot, p->yRot, p->zRot);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
if (pmsg->Get()->uiInsertID == 0)
|
||||
if (!PrepareClientPlayerStmt(stmt, query)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &p->dwLandID)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &p->dwVnum)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &p->lMapIndex)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &p->x)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &p->y)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_FLOAT, &p->xRot)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_FLOAT, &p->yRot)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_FLOAT, &p->zRot)
|
||||
|| !stmt.Execute()
|
||||
|| stmt.GetInsertId() == 0)
|
||||
{
|
||||
sys_err("cannot insert object");
|
||||
return;
|
||||
@@ -1901,7 +1938,7 @@ void CClientManager::CreateObject(TPacketGDCreateObject * p)
|
||||
|
||||
memset(pkObj, 0, sizeof(TObject));
|
||||
|
||||
pkObj->dwID = pmsg->Get()->uiInsertID;
|
||||
pkObj->dwID = static_cast<uint32_t>(stmt.GetInsertId());
|
||||
pkObj->dwVnum = p->dwVnum;
|
||||
pkObj->dwLandID = p->dwLandID;
|
||||
pkObj->lMapIndex = p->lMapIndex;
|
||||
@@ -1919,13 +1956,14 @@ void CClientManager::CreateObject(TPacketGDCreateObject * p)
|
||||
|
||||
void CClientManager::DeleteObject(DWORD dwID)
|
||||
{
|
||||
char szQuery[128];
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("DELETE FROM object") + GetTablePostfix() + " WHERE id=?";
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM object%s WHERE id=%u", GetTablePostfix(), dwID);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
if (pmsg->Get()->uiAffectedRows == 0 || pmsg->Get()->uiAffectedRows == (uint32_t)-1)
|
||||
if (!PrepareClientPlayerStmt(stmt, query)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &dwID)
|
||||
|| !stmt.Execute()
|
||||
|| stmt.GetAffectedRows() == 0
|
||||
|| stmt.GetAffectedRows() == static_cast<unsigned long long>(-1))
|
||||
{
|
||||
sys_err("no object by id %u", dwID);
|
||||
return;
|
||||
@@ -3067,29 +3105,31 @@ DWORD CClientManager::GetItemID()
|
||||
|
||||
bool CClientManager::InitializeLocalization()
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT mValue, mKey FROM locale");
|
||||
auto pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_COMMON);
|
||||
CStmt stmt;
|
||||
tLocale locale;
|
||||
const std::string query = "SELECT COALESCE(mValue, ''), COALESCE(mKey, '') FROM locale";
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
memset(&locale, 0, sizeof(locale));
|
||||
|
||||
if (!PrepareClientCommonStmt(stmt, query)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, locale.szValue, sizeof(locale.szValue))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, locale.szKey, sizeof(locale.szKey))
|
||||
|| !stmt.Execute()
|
||||
|| stmt.iRows == 0)
|
||||
{
|
||||
sys_err("InitializeLocalization() ==> DirectQuery failed(%s)", szQuery);
|
||||
sys_err("InitializeLocalization() ==> DirectQuery failed(%s)", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
sys_log(0, "InitializeLocalization() - LoadLocaleTable(count:%d)", pMsg->Get()->uiNumRows);
|
||||
sys_log(0, "InitializeLocalization() - LoadLocaleTable(count:%d)", stmt.iRows);
|
||||
|
||||
m_vec_Locale.clear();
|
||||
m_vec_Locale.reserve(stmt.iRows);
|
||||
|
||||
MYSQL_ROW row = NULL;
|
||||
|
||||
for (int n = 0; (row = mysql_fetch_row(pMsg->Get()->pSQLResult)) != NULL; ++n)
|
||||
while (stmt.Fetch())
|
||||
{
|
||||
int col = 0;
|
||||
tLocale locale;
|
||||
|
||||
strlcpy(locale.szValue, row[col++], sizeof(locale.szValue));
|
||||
strlcpy(locale.szKey, row[col++], sizeof(locale.szKey));
|
||||
NullTerminateClientResult(locale.szValue, stmt.GetResultLength(0));
|
||||
NullTerminateClientResult(locale.szKey, stmt.GetResultLength(1));
|
||||
|
||||
//DB_NAME_COLUMN Setting
|
||||
if (strcmp(locale.szKey, "LOCALE") == 0)
|
||||
@@ -3450,7 +3490,9 @@ bool CClientManager::InitializeLocalization()
|
||||
{
|
||||
sys_log(0, "locale[UNKNOWN_KEY(%s)] = %s", locale.szKey, locale.szValue);
|
||||
}
|
||||
|
||||
m_vec_Locale.push_back(locale);
|
||||
memset(&locale, 0, sizeof(locale));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -3461,33 +3503,52 @@ bool CClientManager::InitializeLocalization()
|
||||
bool CClientManager::__GetAdminInfo(const char *szIP, std::vector<tAdminInfo> & rAdminVec)
|
||||
{
|
||||
//szIP == NULL 일경우 모든서버에 운영자 권한을 갖는다.
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT mID,mAccount,mName,mContactIP,mServerIP,mAuthority FROM gmlist WHERE mServerIP='ALL' or mServerIP='%s'",
|
||||
szIP ? szIP : "ALL");
|
||||
CStmt stmt;
|
||||
int32_t adminId = 0;
|
||||
char account[sizeof(tAdminInfo::m_szAccount)] = {};
|
||||
char name[sizeof(tAdminInfo::m_szName)] = {};
|
||||
char contactIP[sizeof(tAdminInfo::m_szContactIP)] = {};
|
||||
char serverIP[sizeof(tAdminInfo::m_szServerIP)] = {};
|
||||
char authority[32] = {};
|
||||
const char* requestedServerIp = szIP ? szIP : "ALL";
|
||||
const std::string query =
|
||||
"SELECT mID, COALESCE(mAccount, ''), COALESCE(mName, ''), COALESCE(mContactIP, ''), COALESCE(mServerIP, ''), COALESCE(mAuthority, '') "
|
||||
"FROM gmlist WHERE mServerIP='ALL' or mServerIP=?";
|
||||
|
||||
auto pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_COMMON);
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
if (!PrepareClientCommonStmt(stmt, query)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(requestedServerIp), static_cast<int>(strlen(requestedServerIp)))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &adminId)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, account, sizeof(account))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, name, sizeof(name))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, contactIP, sizeof(contactIP))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, serverIP, sizeof(serverIP))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, authority, sizeof(authority))
|
||||
|| !stmt.Execute()
|
||||
|| stmt.iRows == 0)
|
||||
{
|
||||
sys_err("__GetAdminInfo() ==> DirectQuery failed(%s)", szQuery);
|
||||
sys_err("__GetAdminInfo() ==> DirectQuery failed(%s)", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
MYSQL_ROW row;
|
||||
rAdminVec.reserve(pMsg->Get()->uiNumRows);
|
||||
rAdminVec.reserve(stmt.iRows);
|
||||
|
||||
while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
|
||||
while (stmt.Fetch())
|
||||
{
|
||||
int idx = 0;
|
||||
tAdminInfo Info;
|
||||
memset(&Info, 0, sizeof(Info));
|
||||
|
||||
str_to_number(Info.m_ID, row[idx++]);
|
||||
trim_and_lower(row[idx++], Info.m_szAccount, sizeof(Info.m_szAccount));
|
||||
strlcpy(Info.m_szName, row[idx++], sizeof(Info.m_szName));
|
||||
strlcpy(Info.m_szContactIP, row[idx++], sizeof(Info.m_szContactIP));
|
||||
strlcpy(Info.m_szServerIP, row[idx++], sizeof(Info.m_szServerIP));
|
||||
std::string stAuth = row[idx++];
|
||||
NullTerminateClientResult(account, stmt.GetResultLength(1));
|
||||
NullTerminateClientResult(name, stmt.GetResultLength(2));
|
||||
NullTerminateClientResult(contactIP, stmt.GetResultLength(3));
|
||||
NullTerminateClientResult(serverIP, stmt.GetResultLength(4));
|
||||
NullTerminateClientResult(authority, stmt.GetResultLength(5));
|
||||
|
||||
Info.m_ID = adminId;
|
||||
trim_and_lower(account, Info.m_szAccount, sizeof(Info.m_szAccount));
|
||||
strlcpy(Info.m_szName, name, sizeof(Info.m_szName));
|
||||
strlcpy(Info.m_szContactIP, contactIP, sizeof(Info.m_szContactIP));
|
||||
strlcpy(Info.m_szServerIP, serverIP, sizeof(Info.m_szServerIP));
|
||||
std::string stAuth = authority;
|
||||
|
||||
if (!stAuth.compare("IMPLEMENTOR"))
|
||||
Info.m_Authority = GM_IMPLEMENTOR;
|
||||
@@ -3506,6 +3567,12 @@ bool CClientManager::__GetAdminInfo(const char *szIP, std::vector<tAdminInfo> &
|
||||
|
||||
sys_log(0, "GM: PID %u Login %s Character %s ContactIP %s ServerIP %s Authority %d[%s]",
|
||||
Info.m_ID, Info.m_szAccount, Info.m_szName, Info.m_szContactIP, Info.m_szServerIP, Info.m_Authority, stAuth.c_str());
|
||||
|
||||
memset(account, 0, sizeof(account));
|
||||
memset(name, 0, sizeof(name));
|
||||
memset(contactIP, 0, sizeof(contactIP));
|
||||
memset(serverIP, 0, sizeof(serverIP));
|
||||
memset(authority, 0, sizeof(authority));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -3513,27 +3580,32 @@ bool CClientManager::__GetAdminInfo(const char *szIP, std::vector<tAdminInfo> &
|
||||
|
||||
bool CClientManager::__GetHostInfo(std::vector<std::string> & rIPVec)
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT mIP FROM gmhost");
|
||||
auto pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_COMMON);
|
||||
CStmt stmt;
|
||||
char hostIP[16] = {};
|
||||
const std::string query = "SELECT COALESCE(mIP, '') FROM gmhost";
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
if (!PrepareClientCommonStmt(stmt, query)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, hostIP, sizeof(hostIP))
|
||||
|| !stmt.Execute()
|
||||
|| stmt.iRows == 0)
|
||||
{
|
||||
sys_err("__GetHostInfo() ==> DirectQuery failed(%s)", szQuery);
|
||||
sys_err("__GetHostInfo() ==> DirectQuery failed(%s)", query.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
rIPVec.reserve(pMsg->Get()->uiNumRows);
|
||||
rIPVec.reserve(stmt.iRows);
|
||||
|
||||
MYSQL_ROW row;
|
||||
|
||||
while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult)))
|
||||
while (stmt.Fetch())
|
||||
{
|
||||
if (row[0] && *row[0])
|
||||
NullTerminateClientResult(hostIP, stmt.GetResultLength(0));
|
||||
|
||||
if (hostIP[0])
|
||||
{
|
||||
rIPVec.push_back(row[0]);
|
||||
sys_log(0, "GMHOST: %s", row[0]);
|
||||
rIPVec.push_back(hostIP);
|
||||
sys_log(0, "GMHOST: %s", hostIP);
|
||||
}
|
||||
|
||||
memset(hostIP, 0, sizeof(hostIP));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user