diff --git a/.vscode/settings.json b/.vscode/settings.json index b203ac2..8cf91fe 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -86,17 +86,17 @@ "vcpkg.target.useManifest": false, "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "cmake.configureArgs": [ - "-DVCPKG_MANIFEST_MODE=OFF", "-DVCPKG_APPLOCAL_DEPS=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.target.hostTriplet": "x64-linux", "vcpkg.target.defaultTriplet": "x64-linux", "vcpkg.target.useStaticLib": false, "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.preferSystemLibs": false diff --git a/src/db/src/GuildManager.cpp b/src/db/src/GuildManager.cpp index a29389a..cfa9478 100644 --- a/src/db/src/GuildManager.cpp +++ b/src/db/src/GuildManager.cpp @@ -140,23 +140,21 @@ TGuild &CGuildManager::TouchGuild(DWORD GID) return m_map_kGuild[GID]; } -void CGuildManager::ParseResult(SQLResult *pRes) +void CGuildManager::ParseResult(pqxx::result result) { - MYSQL_ROW row; - - while ((row = mysql_fetch_row(pRes->pSQLResult))) + for (auto row : result) { - DWORD GID = strtoul(row[0], NULL, 10); + DWORD GID = strtoul(row[0].c_str(), NULL, 10); TGuild &r_info = TouchGuild(GID); - strlcpy(r_info.szName, row[1], sizeof(r_info.szName)); - str_to_number(r_info.ladder_point, row[2]); - str_to_number(r_info.win, row[3]); - str_to_number(r_info.draw, row[4]); - str_to_number(r_info.loss, row[5]); - str_to_number(r_info.gold, row[6]); - str_to_number(r_info.level, row[7]); + strlcpy(r_info.szName, row[1].c_str(), sizeof(r_info.szName)); + str_to_number(r_info.ladder_point, row[2].c_str()); + str_to_number(r_info.win, row[3].c_str()); + str_to_number(r_info.draw, row[4].c_str()); + str_to_number(r_info.loss, row[5].c_str()); + str_to_number(r_info.gold, row[6].c_str()); + str_to_number(r_info.level, row[7].c_str()); SPDLOG_DEBUG( "GuildWar: {:24} ladder {:<5} win {:<3} draw {:<3} loss {:<3}", @@ -170,12 +168,25 @@ void CGuildManager::ParseResult(SQLResult *pRes) void CGuildManager::Initialize() { - char szQuery[1024]; - snprintf(szQuery, sizeof(szQuery), "SELECT id, name, ladder_point, win, draw, loss, gold, level FROM guild%s", GetTablePostfix()); - std::unique_ptr pmsg(CDBManager::instance().DirectQuery(szQuery)); + auto pool = CDBManager::instance().GetConnectionPool(); + auto conn = pool->acquire(); - if (pmsg->Get()->uiNumRows) - ParseResult(pmsg->Get()); + try + { + 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]; @@ -200,21 +211,39 @@ void CGuildManager::Initialize() 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); - std::unique_ptr pmsg(CDBManager::instance().DirectQuery(szQuery)); + try + { + 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) - ParseResult(pmsg->Get()); + if (result.size()) + ParseResult(result); + + txn.commit(); + } + catch (const std::exception &e) + { + SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what()); + return; + } } void CGuildManager::QueryRanking() { - char szQuery[256]; - snprintf(szQuery, sizeof(szQuery), "SELECT id,name,ladder_point FROM guild%s ORDER BY ladder_point DESC LIMIT 20", GetTablePostfix()); + CDBManager::instance().AsyncQuery("SELECT id, name, ladder_point FROM player.guild ORDER BY ladder_point DESC LIMIT 20", pqxx::params{}, + [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) @@ -227,24 +256,19 @@ int CGuildManager::GetRanking(DWORD dwGID) 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 iRank = 0; map_kLadderPointRankingByGID.clear(); - MYSQL_ROW row; - - while ((row = mysql_fetch_row(pRes))) + for (auto row : result) { DWORD dwGID = 0; - str_to_number(dwGID, row[0]); + str_to_number(dwGID, row[0].c_str()); int iLadderPoint = 0; - str_to_number(iLadderPoint, row[2]); + str_to_number(iLadderPoint, row[2].c_str()); if (iLadderPoint != iLastLadderPoint) ++iRank; @@ -970,36 +994,50 @@ void CGuildManager::BootReserveWar() int GetAverageGuildMemberLevel(DWORD dwGID) { - char szQuery[QUERY_MAX_LEN]; + auto pool = CDBManager::instance().GetConnectionPool(); + auto conn = pool->acquire(); - snprintf(szQuery, sizeof(szQuery), - "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()); + try + { + 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 msg(CDBManager::instance().DirectQuery(szQuery)); + int nAverageLevel = 0; + str_to_number(nAverageLevel, row[0].c_str()); - MYSQL_ROW row; - row = mysql_fetch_row(msg->Get()->pSQLResult); + txn.commit(); - int nAverageLevel = 0; - str_to_number(nAverageLevel, row[0]); - return nAverageLevel; + return nAverageLevel; + } + catch (const std::exception &e) + { + SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what()); + return; + } } 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 + { + pqxx::work txn{*conn}; + pqxx::row row = txn.exec_params1("SELECT COUNT(*) FROM player.guild_member WHERE guild_id=$1", pqxx::params{dwGID}); - std::unique_ptr msg(CDBManager::instance().DirectQuery(szQuery)); + DWORD dwCount = 0; + str_to_number(dwCount, row[0].c_str()); - MYSQL_ROW row; - row = mysql_fetch_row(msg->Get()->pSQLResult); + txn.commit(); - DWORD dwCount = 0; - str_to_number(dwCount, row[0]); - return dwCount; + return dwCount; + } + catch (const std::exception &e) + { + SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what()); + return; + } } bool CGuildManager::ReserveWar(TPacketGuildWar *p) @@ -1029,7 +1067,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar *p) // 파워 계산 TGuild &k1 = TouchGuild(GID1); - lvp = c_aiScoreByLevel[std::min(GUILD_MAX_LEVEL, k1.level)]; + lvp = c_aiScoreByLevel[std::min(GUILD_MAX_LEVEL, k1.level)]; rkp = c_aiScoreByRanking[GetRanking(GID1)]; alv = GetAverageGuildMemberLevel(GID1); mc = GetGuildMemberCount(GID1); @@ -1045,7 +1083,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar *p) // 파워 계산 TGuild &k2 = TouchGuild(GID2); - lvp = c_aiScoreByLevel[std::min(GUILD_MAX_LEVEL, k2.level)]; + lvp = c_aiScoreByLevel[std::min(GUILD_MAX_LEVEL, k2.level)]; rkp = c_aiScoreByRanking[GetRanking(GID2)]; alv = GetAverageGuildMemberLevel(GID2); mc = GetGuildMemberCount(GID2); @@ -1074,27 +1112,37 @@ bool CGuildManager::ReserveWar(TPacketGuildWar *p) SPDLOG_DEBUG("GuildWar: handicap {}", t.lHandicap); // 쿼리 - char szQuery[512]; + auto pool = CDBManager::instance().GetConnectionPool(); + auto conn = pool->acquire(); - snprintf(szQuery, sizeof(szQuery), - "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)", - GID1, GID2, p->bType, p->lWarPrice, p->lInitialScore, t.lPowerFrom, t.lPowerTo, t.lHandicap); - - std::unique_ptr pmsg(CDBManager::instance().DirectQuery(szQuery)); - - if (pmsg->Get()->uiAffectedRows == 0 || pmsg->Get()->uiInsertID == 0 || pmsg->Get()->uiAffectedRows == (uint32_t)-1) + try { - SPDLOG_ERROR("GuildWar: Cannot insert row"); - return false; + pqxx::work txn{*conn}; + 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}); + + txn.commit(); + + if (result.size() == 0) + { + SPDLOG_ERROR("GuildWar: Cannot insert row"); + return false; + } + + t.dwID = result.at(0)[0].as(); + + m_map_kWarReserve.insert(std::make_pair(t.dwID, new CGuildWarReserve(t))); + + CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_ADD, &t, sizeof(TGuildWarReserve)); + return true; + } + catch (const std::exception &e) + { + SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what()); + false; } - - t.dwID = pmsg->Get()->uiInsertID; - - m_map_kWarReserve.insert(std::make_pair(t.dwID, new CGuildWarReserve(t))); - - CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR_RESERVE_ADD, &t, sizeof(TGuildWarReserve)); - return true; } void CGuildManager::ProcessReserveWar() diff --git a/src/db/src/GuildManager.h b/src/db/src/GuildManager.h index 91bec82..ee8d688 100644 --- a/src/db/src/GuildManager.h +++ b/src/db/src/GuildManager.h @@ -199,7 +199,7 @@ public: void MoneyChange(DWORD dwGuild, DWORD dwGold); void QueryRanking(); - void ResultRanking(MYSQL_RES *pRes); + void ResultRanking(pqxx::result pRes); int GetRanking(DWORD dwGID); // @@ -215,7 +215,7 @@ public: bool ChangeMaster(DWORD dwGID, DWORD dwFrom, DWORD dwTo); 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