db: prepare login-by-key player index bootstrap
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 10:11:11 +02:00
parent 58273bc116
commit 27c5742c11
3 changed files with 71 additions and 62 deletions

View File

@@ -2561,20 +2561,10 @@ int CClientManager::AnalyzeQueryResult(SQLMsg * msg)
case QID_ITEM_AWARD_TAKEN:
break;
// PLAYER_INDEX_CREATE_BUG_FIX
case QID_PLAYER_INDEX_CREATE:
RESULT_PLAYER_INDEX_CREATE(peer, msg);
break;
// END_PLAYER_INDEX_CREATE_BUG_FIX
case QID_PLAYER_DELETE:
__RESULT_PLAYER_DELETE(peer, msg);
break;
case QID_LOGIN_BY_KEY:
RESULT_LOGIN_BY_KEY(peer, msg);
break;
// MYSHOP_PRICE_LIST
case QID_ITEMPRICE_LOAD:
RESULT_PRICELIST_LOAD(peer, msg);

View File

@@ -244,7 +244,6 @@ class CClientManager : public CNetBase, public singleton<CClientManager>
void RESULT_AFFECT_LOAD(CPeer * pkPeer, MYSQL_RES * pRes, DWORD dwHandle);
// PLAYER_INDEX_CREATE_BUG_FIX
void RESULT_PLAYER_INDEX_CREATE(CPeer *pkPeer, SQLMsg *msg);
// END_PLAYER_INDEX_CREATE_BUG_FIX
// MYSHOP_PRICE_LIST
@@ -326,7 +325,6 @@ class CClientManager : public CNetBase, public singleton<CClientManager>
void QUERY_AUTH_LOGIN(CPeer * pkPeer, DWORD dwHandle, TPacketGDAuthLogin * p);
void QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketGDLoginByKey * p);
void RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg);
void ChargeCash(const TRequestChargeCash * p);

View File

@@ -16,6 +16,64 @@ extern int g_log;
namespace
{
bool LoadPlayerIndexByAccountId(DWORD account_id, TAccountTable* account_table, bool* found)
{
*found = false;
char query[QUERY_MAX_LEN];
snprintf(query, sizeof(query), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id = ?", GetTablePostfix());
CStmt stmt;
unsigned int player_ids[PLAYER_PER_ACCOUNT] = {};
unsigned int empire = 0;
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(SQL_PLAYER), query))
return false;
if (!stmt.BindParam(MYSQL_TYPE_LONG, &account_id))
return false;
for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
{
if (!stmt.BindResult(MYSQL_TYPE_LONG, &player_ids[i]))
return false;
}
if (!stmt.BindResult(MYSQL_TYPE_LONG, &empire))
return false;
if (!stmt.Execute())
return false;
if (stmt.iRows == 0)
return true;
if (!stmt.Fetch())
return false;
for (int i = 0; i < PLAYER_PER_ACCOUNT; ++i)
account_table->players[i].dwID = player_ids[i];
account_table->bEmpire = static_cast<BYTE>(empire);
*found = true;
return true;
}
bool CreatePlayerIndexForAccount(DWORD account_id)
{
char query[QUERY_MAX_LEN];
snprintf(query, sizeof(query), "INSERT IGNORE INTO player_index%s (id) VALUES(?)", GetTablePostfix());
CStmt stmt;
if (!stmt.Prepare(CDBManager::instance().GetDirectSQL(SQL_PLAYER), query))
return false;
if (!stmt.BindParam(MYSQL_TYPE_LONG, &account_id))
return false;
return stmt.Execute() != 0;
}
bool CountPlayersByNameExcludingId(const char* player_name, DWORD player_id, unsigned long long* count)
{
char query[QUERY_MAX_LEN];
@@ -174,55 +232,31 @@ void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketG
strlcpy(info->ip, p->szIP, sizeof(info->ip));
sys_log(0, "LOGIN_BY_KEY success %s %lu %s", r.login, p->dwLoginKey, info->ip);
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id=%u", GetTablePostfix(), r.id);
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN_BY_KEY, pkPeer->GetHandle(), info);
}
void CClientManager::RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
if (msg->uiSQLErrno != 0)
bool found = false;
if (!LoadPlayerIndexByAccountId(info->pAccountTable->id, info->pAccountTable, &found))
{
peer->EncodeReturn(DG::LOGIN_NOT_EXIST, info->dwHandle);
delete info->pAccountTable;
delete info;
return;
}
char szQuery[QUERY_MAX_LEN];
if (msg->Get()->uiNumRows == 0)
if (!found)
{
DWORD account_id = info->pAccountTable->id;
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id=%u", GetTablePostfix(), account_id);
auto pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER);
sys_log(0, "RESULT_LOGIN_BY_KEY FAIL player_index's NULL : ID:%d", info->pAccountTable->id);
sys_log(0, "RESULT_LOGIN_BY_KEY FAIL player_index's NULL : ID:%d", account_id);
if (pMsg->Get()->uiNumRows == 0)
if (!CreatePlayerIndexForAccount(info->pAccountTable->id) ||
!LoadPlayerIndexByAccountId(info->pAccountTable->id, info->pAccountTable, &found) ||
!found)
{
sys_log(0, "RESULT_LOGIN_BY_KEY FAIL player_index's NULL : ID:%d", account_id);
// PLAYER_INDEX_CREATE_BUG_FIX
//snprintf(szQuery, sizeof(szQuery), "INSERT IGNORE INTO player_index%s (id) VALUES(%lu)", GetTablePostfix(), info->pAccountTable->id);
snprintf(szQuery, sizeof(szQuery), "INSERT INTO player_index%s (id) VALUES(%u)", GetTablePostfix(), info->pAccountTable->id);
CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_INDEX_CREATE, peer->GetHandle(), info);
// END_PLAYER_INDEX_CREATE_BUF_FIX
peer->EncodeReturn(DG::LOGIN_NOT_EXIST, info->dwHandle);
delete info->pAccountTable;
delete info;
return;
}
return;
}
MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);
int col = 0;
for (; col < PLAYER_PER_ACCOUNT; ++col)
str_to_number(info->pAccountTable->players[col].dwID, row[col]);
str_to_number(info->pAccountTable->bEmpire, row[col++]);
char szQuery[QUERY_MAX_LEN];
info->account_index = 1;
extern std::string g_stLocale;
@@ -242,19 +276,6 @@ void CClientManager::RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg)
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN, peer->GetHandle(), info);
}
// PLAYER_INDEX_CREATE_BUG_FIX
void CClientManager::RESULT_PLAYER_INDEX_CREATE(CPeer * pkPeer, SQLMsg * msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id=%u", GetTablePostfix(),
info->pAccountTable->id);
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN_BY_KEY, pkPeer->GetHandle(), info);
}
// END_PLAYER_INDEX_CREATE_BUG_FIX
TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
{
char input_pwd[PASSWD_MAX_LEN + 1];