change: Guild manager stuff

This commit is contained in:
2025-06-16 22:30:53 +01:00
parent 42fd697dac
commit 729a956397
3 changed files with 125 additions and 77 deletions

View File

@ -86,17 +86,17 @@
"vcpkg.target.useManifest": false, "vcpkg.target.useManifest": false,
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"cmake.configureArgs": [ "cmake.configureArgs": [
"-DVCPKG_MANIFEST_MODE=OFF",
"-DVCPKG_APPLOCAL_DEPS=ON", "-DVCPKG_APPLOCAL_DEPS=ON",
"-DX_VCPKG_APPLOCAL_DEPS_INSTALL=ON", "-DX_VCPKG_APPLOCAL_DEPS_INSTALL=ON",
"-DVCPKG_TARGET_TRIPLET=x64-linux" "-DVCPKG_TARGET_TRIPLET=x64-linux",
"-DVCPKG_MANIFEST_MODE=OFF"
], ],
"vcpkg.general.enable": true, "vcpkg.general.enable": true,
"vcpkg.target.hostTriplet": "x64-linux", "vcpkg.target.hostTriplet": "x64-linux",
"vcpkg.target.defaultTriplet": "x64-linux", "vcpkg.target.defaultTriplet": "x64-linux",
"vcpkg.target.useStaticLib": false, "vcpkg.target.useStaticLib": false,
"cmake.configureSettings": { "cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "~/.vcpkg/scripts/buildsystems/vcpkg.cmake" "CMAKE_TOOLCHAIN_FILE": "~/.local/share/vcpkg/scripts/buildsystems/vcpkg.cmake"
}, },
"vcpkg.target.installDependencies": true, "vcpkg.target.installDependencies": true,
"vcpkg.target.preferSystemLibs": false "vcpkg.target.preferSystemLibs": false

View File

@ -140,23 +140,21 @@ TGuild &CGuildManager::TouchGuild(DWORD GID)
return m_map_kGuild[GID]; return m_map_kGuild[GID];
} }
void CGuildManager::ParseResult(SQLResult *pRes) void CGuildManager::ParseResult(pqxx::result result)
{ {
MYSQL_ROW row; for (auto row : result)
while ((row = mysql_fetch_row(pRes->pSQLResult)))
{ {
DWORD GID = strtoul(row[0], NULL, 10); DWORD GID = strtoul(row[0].c_str(), NULL, 10);
TGuild &r_info = TouchGuild(GID); TGuild &r_info = TouchGuild(GID);
strlcpy(r_info.szName, row[1], sizeof(r_info.szName)); strlcpy(r_info.szName, row[1].c_str(), sizeof(r_info.szName));
str_to_number(r_info.ladder_point, row[2]); str_to_number(r_info.ladder_point, row[2].c_str());
str_to_number(r_info.win, row[3]); str_to_number(r_info.win, row[3].c_str());
str_to_number(r_info.draw, row[4]); str_to_number(r_info.draw, row[4].c_str());
str_to_number(r_info.loss, row[5]); str_to_number(r_info.loss, row[5].c_str());
str_to_number(r_info.gold, row[6]); str_to_number(r_info.gold, row[6].c_str());
str_to_number(r_info.level, row[7]); str_to_number(r_info.level, row[7].c_str());
SPDLOG_DEBUG( SPDLOG_DEBUG(
"GuildWar: {:24} ladder {:<5} win {:<3} draw {:<3} loss {:<3}", "GuildWar: {:24} ladder {:<5} win {:<3} draw {:<3} loss {:<3}",
@ -170,12 +168,25 @@ void CGuildManager::ParseResult(SQLResult *pRes)
void CGuildManager::Initialize() void CGuildManager::Initialize()
{ {
char szQuery[1024]; auto pool = CDBManager::instance().GetConnectionPool();
snprintf(szQuery, sizeof(szQuery), "SELECT id, name, ladder_point, win, draw, loss, gold, level FROM guild%s", GetTablePostfix()); auto conn = pool->acquire();
std::unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
if (pmsg->Get()->uiNumRows) try
ParseResult(pmsg->Get()); {
pqxx::work txn{*conn};
pqxx::result result = txn.exec("SELECT id, name, ladder_point, win, draw, loss, gold, level FROM player.guild");
std::size_t const numRows = std::size(result);
if (result.size())
ParseResult(result);
txn.commit();
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what());
return;
}
char str[128 + 1]; char str[128 + 1];
@ -200,21 +211,39 @@ void CGuildManager::Initialize()
void CGuildManager::Load(DWORD dwGuildID) void CGuildManager::Load(DWORD dwGuildID)
{ {
char szQuery[1024]; auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
snprintf(szQuery, sizeof(szQuery), "SELECT id, name, ladder_point, win, draw, loss, gold, level FROM guild%s WHERE id=%u", GetTablePostfix(), dwGuildID); try
std::unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery)); {
pqxx::work txn{*conn};
pqxx::result result = txn.exec_params("SELECT id, name, ladder_point, win, draw, loss, gold, level FROM player.guild WHERE id=$1", pqxx::params{dwGuildID});
std::size_t const numRows = std::size(result);
if (pmsg->Get()->uiNumRows) if (result.size())
ParseResult(pmsg->Get()); ParseResult(result);
txn.commit();
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what());
return;
}
} }
void CGuildManager::QueryRanking() void CGuildManager::QueryRanking()
{ {
char szQuery[256]; CDBManager::instance().AsyncQuery("SELECT id, name, ladder_point FROM player.guild ORDER BY ladder_point DESC LIMIT 20", pqxx::params{},
snprintf(szQuery, sizeof(szQuery), "SELECT id,name,ladder_point FROM guild%s ORDER BY ladder_point DESC LIMIT 20", GetTablePostfix()); [this](const pqxx::result &result, const std::string &error)
{
if (!error.empty())
{
return;
}
CDBManager::instance().ReturnQuery(szQuery, QID_GUILD_RANKING, 0, 0); CGuildManager::ResultRanking(result);
});
} }
int CGuildManager::GetRanking(DWORD dwGID) int CGuildManager::GetRanking(DWORD dwGID)
@ -227,24 +256,19 @@ int CGuildManager::GetRanking(DWORD dwGID)
return std::clamp(it->second, 0, GUILD_RANK_MAX_NUM); return std::clamp(it->second, 0, GUILD_RANK_MAX_NUM);
} }
void CGuildManager::ResultRanking(MYSQL_RES *pRes) void CGuildManager::ResultRanking(pqxx::result result)
{ {
if (!pRes)
return;
int iLastLadderPoint = -1; int iLastLadderPoint = -1;
int iRank = 0; int iRank = 0;
map_kLadderPointRankingByGID.clear(); map_kLadderPointRankingByGID.clear();
MYSQL_ROW row; for (auto row : result)
while ((row = mysql_fetch_row(pRes)))
{ {
DWORD dwGID = 0; DWORD dwGID = 0;
str_to_number(dwGID, row[0]); str_to_number(dwGID, row[0].c_str());
int iLadderPoint = 0; int iLadderPoint = 0;
str_to_number(iLadderPoint, row[2]); str_to_number(iLadderPoint, row[2].c_str());
if (iLadderPoint != iLastLadderPoint) if (iLadderPoint != iLastLadderPoint)
++iRank; ++iRank;
@ -970,36 +994,50 @@ void CGuildManager::BootReserveWar()
int GetAverageGuildMemberLevel(DWORD dwGID) int GetAverageGuildMemberLevel(DWORD dwGID)
{ {
char szQuery[QUERY_MAX_LEN]; auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
snprintf(szQuery, sizeof(szQuery), try
"SELECT AVG(level) FROM guild_member%s, player%s AS p WHERE guild_id=%u AND guild_member%s.pid=p.id", {
GetTablePostfix(), GetTablePostfix(), dwGID, GetTablePostfix()); pqxx::work txn{*conn};
pqxx::row row = txn.exec_params1("SELECT AVG(level) FROM player.guild_member, player.player AS p WHERE guild_id=$1 AND player.guild_member.pid=p.id", pqxx::params{dwGID});
std::unique_ptr<SQLMsg> msg(CDBManager::instance().DirectQuery(szQuery));
MYSQL_ROW row;
row = mysql_fetch_row(msg->Get()->pSQLResult);
int nAverageLevel = 0; int nAverageLevel = 0;
str_to_number(nAverageLevel, row[0]); str_to_number(nAverageLevel, row[0].c_str());
txn.commit();
return nAverageLevel; return nAverageLevel;
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what());
return;
}
} }
int GetGuildMemberCount(DWORD dwGID) int GetGuildMemberCount(DWORD dwGID)
{ {
char szQuery[QUERY_MAX_LEN]; auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM guild_member%s WHERE guild_id=%u", GetTablePostfix(), dwGID); try
{
std::unique_ptr<SQLMsg> msg(CDBManager::instance().DirectQuery(szQuery)); pqxx::work txn{*conn};
pqxx::row row = txn.exec_params1("SELECT COUNT(*) FROM player.guild_member WHERE guild_id=$1", pqxx::params{dwGID});
MYSQL_ROW row;
row = mysql_fetch_row(msg->Get()->pSQLResult);
DWORD dwCount = 0; DWORD dwCount = 0;
str_to_number(dwCount, row[0]); str_to_number(dwCount, row[0].c_str());
txn.commit();
return dwCount; return dwCount;
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what());
return;
}
} }
bool CGuildManager::ReserveWar(TPacketGuildWar *p) bool CGuildManager::ReserveWar(TPacketGuildWar *p)
@ -1029,7 +1067,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar *p)
// 파워 계산 // 파워 계산
TGuild &k1 = TouchGuild(GID1); TGuild &k1 = TouchGuild(GID1);
lvp = c_aiScoreByLevel[std::min<size_t>(GUILD_MAX_LEVEL, k1.level)]; lvp = c_aiScoreByLevel[std::min<std::size_t>(GUILD_MAX_LEVEL, k1.level)];
rkp = c_aiScoreByRanking[GetRanking(GID1)]; rkp = c_aiScoreByRanking[GetRanking(GID1)];
alv = GetAverageGuildMemberLevel(GID1); alv = GetAverageGuildMemberLevel(GID1);
mc = GetGuildMemberCount(GID1); mc = GetGuildMemberCount(GID1);
@ -1045,7 +1083,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar *p)
// 파워 계산 // 파워 계산
TGuild &k2 = TouchGuild(GID2); TGuild &k2 = TouchGuild(GID2);
lvp = c_aiScoreByLevel[std::min<size_t>(GUILD_MAX_LEVEL, k2.level)]; lvp = c_aiScoreByLevel[std::min<std::size_t>(GUILD_MAX_LEVEL, k2.level)];
rkp = c_aiScoreByRanking[GetRanking(GID2)]; rkp = c_aiScoreByRanking[GetRanking(GID2)];
alv = GetAverageGuildMemberLevel(GID2); alv = GetAverageGuildMemberLevel(GID2);
mc = GetGuildMemberCount(GID2); mc = GetGuildMemberCount(GID2);
@ -1074,27 +1112,37 @@ bool CGuildManager::ReserveWar(TPacketGuildWar *p)
SPDLOG_DEBUG("GuildWar: handicap {}", t.lHandicap); SPDLOG_DEBUG("GuildWar: handicap {}", t.lHandicap);
// 쿼리 // 쿼리
char szQuery[512]; auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
snprintf(szQuery, sizeof(szQuery), try
"INSERT INTO guild_war_reservation (guild1, guild2, time, type, warprice, initscore, power1, power2, handicap) " {
"VALUES(%u, %u, DATE_ADD(NOW(), INTERVAL 180 SECOND), %u, %d, %d, %d, %d, %d)", pqxx::work txn{*conn};
GID1, GID2, p->bType, p->lWarPrice, p->lInitialScore, t.lPowerFrom, t.lPowerTo, t.lHandicap); pqxx::result result = txn.exec_params(
"INSERT INTO player.guild_war_reservation (guild1, guild2, time, type, warprice, initscore, power1, power2, handicap) "
"VALUES($1, $2, DATE_ADD(NOW(), INTERVAL 180 SECOND), $3, $4, $5, $6, $7, $8) RETURNING id",
pqxx::params{GID1, GID2, p->bType, p->lWarPrice, p->lInitialScore, t.lPowerFrom, t.lPowerTo, t.lHandicap});
std::unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery)); txn.commit();
if (pmsg->Get()->uiAffectedRows == 0 || pmsg->Get()->uiInsertID == 0 || pmsg->Get()->uiAffectedRows == (uint32_t)-1) if (result.size() == 0)
{ {
SPDLOG_ERROR("GuildWar: Cannot insert row"); SPDLOG_ERROR("GuildWar: Cannot insert row");
return false; return false;
} }
t.dwID = pmsg->Get()->uiInsertID; t.dwID = result.at(0)[0].as<DWORD>();
m_map_kWarReserve.insert(std::make_pair(t.dwID, new CGuildWarReserve(t))); m_map_kWarReserve.insert(std::make_pair(t.dwID, new CGuildWarReserve(t)));
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_ADD, &t, sizeof(TGuildWarReserve)); CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_ADD, &t, sizeof(TGuildWarReserve));
return true; return true;
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what());
false;
}
} }
void CGuildManager::ProcessReserveWar() void CGuildManager::ProcessReserveWar()

View File

@ -199,7 +199,7 @@ public:
void MoneyChange(DWORD dwGuild, DWORD dwGold); void MoneyChange(DWORD dwGuild, DWORD dwGold);
void QueryRanking(); void QueryRanking();
void ResultRanking(MYSQL_RES *pRes); void ResultRanking(pqxx::result pRes);
int GetRanking(DWORD dwGID); int GetRanking(DWORD dwGID);
// //
@ -215,7 +215,7 @@ public:
bool ChangeMaster(DWORD dwGID, DWORD dwFrom, DWORD dwTo); bool ChangeMaster(DWORD dwGID, DWORD dwFrom, DWORD dwTo);
private: private:
void ParseResult(SQLResult *pRes); void ParseResult(pqxx::result pRes);
void RemoveWar(DWORD GID1, DWORD GID2); // erase war from m_WarMap and set end on priority queue void RemoveWar(DWORD GID1, DWORD GID2); // erase war from m_WarMap and set end on priority queue