game: prepare name lookup queries
This commit is contained in:
@@ -15,9 +15,55 @@
|
||||
#include "locale_service.h"
|
||||
#include "guild_manager.h"
|
||||
#include "MarkManager.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareGameStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
CAsyncSQL* sql = DBManager::instance().GetDirectSQL();
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("game direct SQL handle is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool GuildNameExists(const char* guildName, bool& exists)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("SELECT COUNT(*) FROM guild") + get_table_postfix() + " WHERE name=?";
|
||||
uint32_t count = 0;
|
||||
|
||||
exists = false;
|
||||
|
||||
if (!PrepareGameStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(guildName))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stmt.Execute())
|
||||
return false;
|
||||
|
||||
if (stmt.iRows == 0)
|
||||
return true;
|
||||
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
exists = count != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
struct FGuildNameSender
|
||||
{
|
||||
@@ -81,25 +127,20 @@ DWORD CGuildManager::CreateGuild(TGuildCreateParameter& gcp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto pmsg = DBManager::instance().DirectQuery("SELECT COUNT(*) FROM guild%s WHERE name = '%s'",
|
||||
get_table_postfix(), gcp.name);
|
||||
bool guildNameExists = false;
|
||||
|
||||
if (pmsg->Get()->uiNumRows > 0)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
||||
|
||||
if (!(row[0] && row[0][0] == '0'))
|
||||
{
|
||||
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 같은 이름의 길드가 있습니다."));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!GuildNameExists(gcp.name, guildNameExists))
|
||||
{
|
||||
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 길드를 생성할 수 없습니다."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (guildNameExists)
|
||||
{
|
||||
gcp.master->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<길드> 이미 같은 이름의 길드가 있습니다."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// new CGuild(gcp) queries guild tables and tell dbcache to notice other game servers.
|
||||
// other game server calls CGuildManager::LoadGuild to load guild.
|
||||
CGuild * pg = M2_NEW CGuild(gcp);
|
||||
@@ -956,4 +997,3 @@ void CGuildManager::ChangeMaster(DWORD dwGID)
|
||||
"SELECT 1");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
#include "desc_client.h"
|
||||
#include "messenger_manager.h"
|
||||
#include "log.h"
|
||||
#include "db.h"
|
||||
#include "utils.h"
|
||||
#include "unique_item.h"
|
||||
#include "mob_manager.h"
|
||||
#include "libsql/Statement.h"
|
||||
#include <cctype>
|
||||
|
||||
#undef sys_err
|
||||
@@ -31,6 +33,69 @@ extern int g_nPortalLimitTime;
|
||||
extern LPCLIENT_DESC db_clientdesc;
|
||||
const int ITEM_BROKEN_METIN_VNUM = 28960;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareGameStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
CAsyncSQL* sql = DBManager::instance().GetDirectSQL();
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("game direct SQL handle is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool CharacterNameExists(const char* name, bool& exists)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("SELECT COUNT(*) FROM player") + get_table_postfix() + " WHERE name=?";
|
||||
uint32_t count = 0;
|
||||
|
||||
exists = false;
|
||||
|
||||
if (!PrepareGameStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(name))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stmt.Execute())
|
||||
return false;
|
||||
|
||||
if (stmt.iRows == 0)
|
||||
return true;
|
||||
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
exists = count != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UpdateCharacterName(uint32_t playerId, const char* name)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("UPDATE player") + get_table_postfix() + " SET name=? WHERE id=?";
|
||||
|
||||
if (!PrepareGameStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(name))
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &playerId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
namespace quest
|
||||
{
|
||||
//
|
||||
@@ -2114,23 +2179,19 @@ teleport_area:
|
||||
return 1;
|
||||
}
|
||||
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM player%s WHERE name='%s'", get_table_postfix(), szName);
|
||||
auto pmsg = DBManager::instance().DirectQuery(szQuery);
|
||||
bool characterNameExists = false;
|
||||
|
||||
if ( pmsg->Get()->uiNumRows > 0 )
|
||||
if (!CharacterNameExists(szName, characterNameExists))
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
||||
lua_pushnumber(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
str_to_number(count, row[0]);
|
||||
|
||||
// 이미 해당 이름을 가진 캐릭터가 있음
|
||||
if ( count != 0 )
|
||||
{
|
||||
lua_pushnumber(L, 3);
|
||||
return 1;
|
||||
}
|
||||
// 이미 해당 이름을 가진 캐릭터가 있음
|
||||
if (characterNameExists)
|
||||
{
|
||||
lua_pushnumber(L, 3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD pid = ch->GetPlayerID();
|
||||
@@ -2144,8 +2205,11 @@ teleport_area:
|
||||
/* change_name_log */
|
||||
LogManager::instance().ChangeNameLog(pid, ch->GetName(), szName, ch->GetDesc()->GetHostName());
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE player%s SET name='%s' WHERE id=%u", get_table_postfix(), szName, pid);
|
||||
DBManager::instance().DirectQuery(szQuery);
|
||||
if (!UpdateCharacterName(pid, szName))
|
||||
{
|
||||
lua_pushnumber(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ch->SetNewName(szName);
|
||||
lua_pushnumber(L, 4);
|
||||
|
||||
Reference in New Issue
Block a user