db: prepare guild and flag lookups
This commit is contained in:
@@ -5,26 +5,104 @@
|
||||
#include "Config.h"
|
||||
#include "DBManager.h"
|
||||
#include "QID.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareEventFlagStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(SQL_PLAYER);
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("player SQL handle is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool LoadStoredEventFlags(std::vector<TPacketSetEventFlag>& flags)
|
||||
{
|
||||
CStmt stmt;
|
||||
char flagName[EVENT_FLAG_NAME_MAX_LEN + 1] = {};
|
||||
int32_t flagValue = 0;
|
||||
const std::string query = std::string("SELECT szName, lValue FROM quest") + GetTablePostfix() + " WHERE dwPID = 0";
|
||||
|
||||
flags.clear();
|
||||
|
||||
if (!PrepareEventFlagStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindResult(MYSQL_TYPE_STRING, flagName, sizeof(flagName))
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &flagValue)
|
||||
|| !stmt.Execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
flags.reserve(stmt.iRows);
|
||||
|
||||
for (int i = 0; i < stmt.iRows; ++i)
|
||||
{
|
||||
TPacketSetEventFlag packet = {};
|
||||
|
||||
memset(flagName, 0, sizeof(flagName));
|
||||
flagValue = 0;
|
||||
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
size_t flagNameLen = stmt.GetResultLength(0);
|
||||
if (flagNameLen >= sizeof(flagName))
|
||||
flagNameLen = sizeof(flagName) - 1;
|
||||
|
||||
flagName[flagNameLen] = '\0';
|
||||
strlcpy(packet.szFlagName, flagName, sizeof(packet.szFlagName));
|
||||
packet.lValue = flagValue;
|
||||
flags.push_back(packet);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplaceStoredEventFlag(const char* flagName, int32_t flagValue)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("REPLACE INTO quest") + GetTablePostfix()
|
||||
+ " (dwPID, szName, szState, lValue) VALUES(0, ?, '', ?)";
|
||||
|
||||
if (!PrepareEventFlagStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(flagName))
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &flagValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::LoadEventFlag()
|
||||
{
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT szName, lValue FROM quest%s WHERE dwPID = 0", GetTablePostfix());
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
std::vector<TPacketSetEventFlag> flags;
|
||||
|
||||
SQLResult* pRes = pmsg->Get();
|
||||
if (pRes->uiNumRows)
|
||||
if (!LoadStoredEventFlags(flags))
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(pRes->pSQLResult)))
|
||||
{
|
||||
TPacketSetEventFlag p;
|
||||
strlcpy(p.szFlagName, row[0], sizeof(p.szFlagName));
|
||||
str_to_number(p.lValue, row[1]);
|
||||
sys_log(0, "EventFlag Load %s %d", p.szFlagName, p.lValue);
|
||||
m_map_lEventFlag.insert(std::make_pair(std::string(p.szFlagName), p.lValue));
|
||||
ForwardPacket(DG::SET_EVENT_FLAG, &p, sizeof(TPacketSetEventFlag));
|
||||
}
|
||||
sys_err("failed to load event flags");
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& p : flags)
|
||||
{
|
||||
sys_log(0, "EventFlag Load %s %d", p.szFlagName, p.lValue);
|
||||
m_map_lEventFlag.insert(std::make_pair(std::string(p.szFlagName), p.lValue));
|
||||
ForwardPacket(DG::SET_EVENT_FLAG, &p, sizeof(TPacketSetEventFlag));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,14 +126,9 @@ void CClientManager::SetEventFlag(TPacketSetEventFlag* p)
|
||||
|
||||
if (bChanged)
|
||||
{
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"REPLACE INTO quest%s (dwPID, szName, szState, lValue) VALUES(0, '%s', '', %ld)",
|
||||
GetTablePostfix(), p->szFlagName, static_cast<long>(p->lValue));
|
||||
szQuery[1023] = '\0';
|
||||
if (!ReplaceStoredEventFlag(p->szFlagName, p->lValue))
|
||||
sys_err("failed to persist event flag %s", p->szFlagName);
|
||||
|
||||
//CDBManager::instance().ReturnQuery(szQuery, QID_QUEST_SAVE, 0, NULL);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
sys_log(0, "GD::SET_EVENT_FLAG : Changed CClientmanager::SetEventFlag(%s %d) ", p->szFlagName, p->lValue);
|
||||
return;
|
||||
}
|
||||
@@ -73,4 +146,3 @@ void CClientManager::SendEventFlagsOnSetup(CPeer* peer)
|
||||
peer->Encode(&p, sizeof(TPacketSetEventFlag));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,96 @@
|
||||
#include "DBManager.h"
|
||||
#include "QID.h"
|
||||
#include "GuildManager.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareGuildStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(SQL_PLAYER);
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("player SQL handle is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool InsertGuildMemberRow(uint32_t playerId, uint32_t guildId, uint8_t grade)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = std::string("INSERT INTO guild_member") + GetTablePostfix() + " VALUES(?, ?, ?, 0, 0)";
|
||||
|
||||
if (!PrepareGuildStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &playerId)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &guildId)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_TINY, &grade))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Execute();
|
||||
}
|
||||
|
||||
bool LoadGuildMemberData(uint32_t guildId, uint32_t playerId, TPacketDGGuildMember* packet)
|
||||
{
|
||||
CStmt stmt;
|
||||
uint32_t loadedPlayerId = 0;
|
||||
uint8_t grade = 0;
|
||||
uint8_t isGeneral = 0;
|
||||
uint32_t offer = 0;
|
||||
uint8_t level = 0;
|
||||
uint8_t job = 0;
|
||||
char name[CHARACTER_NAME_MAX_LEN + 1] = {};
|
||||
const std::string query = std::string("SELECT pid, grade, is_general, offer, level, job, name FROM guild_member")
|
||||
+ GetTablePostfix() + ", player" + GetTablePostfix() + " WHERE guild_id = ? and pid = id and pid = ?";
|
||||
|
||||
memset(packet, 0, sizeof(TPacketDGGuildMember));
|
||||
|
||||
if (!PrepareGuildStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &guildId)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_LONG, &playerId)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &loadedPlayerId)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_TINY, &grade)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_TINY, &isGeneral)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_LONG, &offer)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_TINY, &level)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_TINY, &job)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, name, sizeof(name)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stmt.Execute())
|
||||
return false;
|
||||
|
||||
if (stmt.iRows == 0 || !stmt.Fetch())
|
||||
return false;
|
||||
|
||||
size_t nameLen = stmt.GetResultLength(6);
|
||||
if (nameLen >= sizeof(name))
|
||||
nameLen = sizeof(name) - 1;
|
||||
|
||||
name[nameLen] = '\0';
|
||||
packet->dwGuild = guildId;
|
||||
packet->dwPID = loadedPlayerId;
|
||||
packet->bGrade = grade;
|
||||
packet->isGeneral = isGeneral;
|
||||
packet->dwOffer = offer;
|
||||
packet->bLevel = level;
|
||||
packet->bJob = job;
|
||||
strlcpy(packet->szName, name, sizeof(packet->szName));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CClientManager::GuildCreate(CPeer * peer, DWORD dwGuildID)
|
||||
@@ -27,40 +117,18 @@ void CClientManager::GuildAddMember(CPeer* peer, TPacketGDGuildAddMember * p)
|
||||
CGuildManager::instance().TouchGuild(p->dwGuild);
|
||||
sys_log(0, "GuildAddMember %u %u", p->dwGuild, p->dwPID);
|
||||
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"INSERT INTO guild_member%s VALUES(%u, %u, %d, 0, 0)",
|
||||
GetTablePostfix(), p->dwPID, p->dwGuild, p->bGrade);
|
||||
|
||||
auto pmsg_insert = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT pid, grade, is_general, offer, level, job, name FROM guild_member%s, player%s WHERE guild_id = %u and pid = id and pid = %u", GetTablePostfix(), GetTablePostfix(), p->dwGuild, p->dwPID);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
if (pmsg->Get()->uiNumRows == 0)
|
||||
if (!InsertGuildMemberRow(p->dwPID, p->dwGuild, p->bGrade))
|
||||
{
|
||||
sys_err("Query failed when getting guild member data %s", pmsg->stQuery.c_str());
|
||||
sys_err("failed to insert guild member %u for guild %u", p->dwPID, p->dwGuild);
|
||||
return;
|
||||
}
|
||||
|
||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
||||
|
||||
if (!row[0] || !row[1])
|
||||
return;
|
||||
|
||||
TPacketDGGuildMember dg;
|
||||
|
||||
dg.dwGuild = p->dwGuild;
|
||||
str_to_number(dg.dwPID, row[0]);
|
||||
str_to_number(dg.bGrade, row[1]);
|
||||
str_to_number(dg.isGeneral, row[2]);
|
||||
str_to_number(dg.dwOffer, row[3]);
|
||||
str_to_number(dg.bLevel, row[4]);
|
||||
str_to_number(dg.bJob, row[5]);
|
||||
strlcpy(dg.szName, row[6], sizeof(dg.szName));
|
||||
if (!LoadGuildMemberData(p->dwGuild, p->dwPID, &dg))
|
||||
{
|
||||
sys_err("failed to load guild member data for pid %u in guild %u", p->dwPID, p->dwGuild);
|
||||
return;
|
||||
}
|
||||
|
||||
ForwardPacket(DG::GUILD_ADD_MEMBER, &dg, sizeof(TPacketDGGuildMember));
|
||||
}
|
||||
@@ -241,4 +309,3 @@ void CClientManager::GuildChangeMaster(TPacketChangeGuildMaster* p)
|
||||
ForwardPacket(DG::ACK_CHANGE_GUILD_MASTER, &packet, sizeof(packet));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +1,94 @@
|
||||
// vim:ts=4 sw=4
|
||||
#include "stdafx.h"
|
||||
#include "ClientManager.h"
|
||||
#include "DBManager.h"
|
||||
#include "libsql/Statement.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool PrepareHorseStmt(CStmt& stmt, const std::string& query)
|
||||
{
|
||||
CAsyncSQL* sql = CDBManager::instance().GetDirectSQL(SQL_PLAYER);
|
||||
|
||||
if (!sql)
|
||||
{
|
||||
sys_err("player SQL handle is not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Prepare(sql, query.c_str());
|
||||
}
|
||||
|
||||
bool ReplaceHorseName(uint32_t playerId, const char* horseName)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "REPLACE INTO horse_name VALUES(?, ?)";
|
||||
|
||||
if (!PrepareHorseStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &playerId)
|
||||
|| !stmt.BindParam(MYSQL_TYPE_STRING, const_cast<char*>(horseName)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return stmt.Execute();
|
||||
}
|
||||
|
||||
bool LoadHorseName(uint32_t playerId, char* horseName, size_t horseNameSize)
|
||||
{
|
||||
CStmt stmt;
|
||||
const std::string query = "SELECT name FROM horse_name WHERE id=?";
|
||||
|
||||
horseName[0] = '\0';
|
||||
|
||||
if (!PrepareHorseStmt(stmt, query))
|
||||
return false;
|
||||
|
||||
if (!stmt.BindParam(MYSQL_TYPE_LONG, &playerId)
|
||||
|| !stmt.BindResult(MYSQL_TYPE_STRING, horseName, static_cast<int>(horseNameSize)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!stmt.Execute())
|
||||
return false;
|
||||
|
||||
if (stmt.iRows == 0)
|
||||
return true;
|
||||
|
||||
if (!stmt.Fetch())
|
||||
return false;
|
||||
|
||||
size_t horseNameLen = stmt.GetResultLength(0);
|
||||
if (horseNameLen >= horseNameSize)
|
||||
horseNameLen = horseNameSize - 1;
|
||||
|
||||
horseName[horseNameLen] = '\0';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::UpdateHorseName(TPacketUpdateHorseName* data, CPeer* peer)
|
||||
{
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO horse_name VALUES(%u, '%s')", data->dwPlayerID, data->szHorseName);
|
||||
|
||||
auto pmsg_insert = CDBManager::instance().DirectQuery(szQuery);
|
||||
if (!ReplaceHorseName(data->dwPlayerID, data->szHorseName))
|
||||
sys_err("failed to update horse name for player %u", data->dwPlayerID);
|
||||
|
||||
ForwardPacket(DG::UPDATE_HORSE_NAME, data, sizeof(TPacketUpdateHorseName), 0, peer);
|
||||
}
|
||||
|
||||
void CClientManager::AckHorseName(DWORD dwPID, CPeer* peer)
|
||||
{
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT name FROM horse_name WHERE id = %u", dwPID);
|
||||
|
||||
auto pmsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
TPacketUpdateHorseName packet;
|
||||
packet.dwPlayerID = dwPID;
|
||||
memset(packet.szHorseName, 0, sizeof(packet.szHorseName));
|
||||
|
||||
if (pmsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
memset(packet.szHorseName, 0, sizeof (packet.szHorseName));
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
||||
strlcpy(packet.szHorseName, row[0], sizeof(packet.szHorseName));
|
||||
}
|
||||
if (!LoadHorseName(dwPID, packet.szHorseName, sizeof(packet.szHorseName)))
|
||||
sys_err("failed to load horse name for player %u", dwPID);
|
||||
|
||||
peer->EncodeHeader(DG::ACK_HORSE_NAME, 0, sizeof(TPacketUpdateHorseName));
|
||||
peer->Encode(&packet, sizeof(TPacketUpdateHorseName));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user