feat: 최대 강화 단계, 현재 골드 기반 랭크 추가

This commit is contained in:
bumpsoo 2026-02-08 17:08:37 +09:00
parent 30debc44f5
commit 71e09915b7
6 changed files with 197 additions and 9 deletions

View file

@ -87,7 +87,8 @@ DatabaseManager::LoadUser(std::string nickname) {
boost::mysql::results result;
boost::mysql::statement stmt = co_await conn_->async_prepare_statement(
"SELECT username, gold, sword_level FROM users WHERE username = ?",
"SELECT username, gold, sword_level, max_sword_level FROM users WHERE "
"username = ?",
boost::asio::use_awaitable);
co_await conn_->async_execute(stmt.bind(nickname), result,
boost::asio::use_awaitable);
@ -109,6 +110,7 @@ DatabaseManager::LoadUser(std::string nickname) {
data.nickname = row.at(0).as_string();
data.gold = row.at(1).as_uint64();
data.swordLevel = (uint32_t)row.at(2).as_int64();
data.maxSwordLevel = (uint32_t)row.at(3).as_int64();
Unlock();
co_return data;
}
@ -132,11 +134,12 @@ boost::asio::awaitable<void> DatabaseManager::SaveUser(std::string nickname,
boost::mysql::results result;
boost::mysql::statement stmt = co_await conn_->async_prepare_statement(
"UPDATE users SET gold = ?, sword_level = ? WHERE username = ?",
"UPDATE users SET gold = ?, sword_level = ?, max_sword_level = "
"GREATEST(max_sword_level, ?) WHERE username = ?",
boost::asio::use_awaitable);
co_await conn_->async_execute(
stmt.bind(gold, (int64_t)swordLevel, nickname), result,
boost::asio::use_awaitable);
stmt.bind(gold, (int64_t)swordLevel, (int64_t)swordLevel, nickname),
result, boost::asio::use_awaitable);
} catch (const std::exception &e) {
Logger::Log("SaveUser 에러: ", e.what());
}
@ -144,3 +147,67 @@ boost::asio::awaitable<void> DatabaseManager::SaveUser(std::string nickname,
Unlock();
co_return;
}
boost::asio::awaitable<DatabaseManager::RankingResult>
DatabaseManager::GetRanking(int type, std::string nickname) {
co_await Lock();
RankingResult res;
res.myRank = -1;
res.myValue = 0;
try {
if (!conn_) {
Unlock();
co_return res;
}
std::string columnName = (type == 0) ? "max_sword_level" : "gold";
boost::mysql::results topResult;
std::string topQuery = "SELECT username, " + columnName +
" FROM users ORDER BY " + columnName +
" DESC LIMIT 10";
co_await conn_->async_execute(topQuery, topResult,
boost::asio::use_awaitable);
uint32_t rank = 1;
for (auto row : topResult.rows()) {
RankingResult::Entry entry;
entry.rank = rank++;
entry.nickname = row.at(0).as_string();
// DB 타입이 달라 분기처리..
if (type == 0) {
entry.value = (uint64_t)row.at(1).as_int64();
} else {
entry.value = row.at(1).as_uint64();
}
res.topEntries.push_back(entry);
}
boost::mysql::results myResult;
std::string myQuery =
"SELECT " + columnName + ", (SELECT COUNT(*) + 1 FROM users WHERE " +
columnName + " > u." + columnName + ") FROM users u WHERE username = ?";
boost::mysql::statement stmt = co_await conn_->async_prepare_statement(
myQuery, boost::asio::use_awaitable);
co_await conn_->async_execute(stmt.bind(nickname), myResult,
boost::asio::use_awaitable);
if (!myResult.rows().empty()) {
auto row = myResult.rows().at(0);
if (type == 0) {
res.myValue = (uint64_t)row.at(0).as_int64();
} else {
res.myValue = row.at(0).as_uint64();
}
res.myRank = (int32_t)row.at(1).as_int64();
}
} catch (const std::exception &e) {
Logger::Log("GetRanking 에러: ", e.what());
}
Unlock();
co_return res;
}

View file

@ -139,6 +139,31 @@ PacketHandler::HandlePacket(std::shared_ptr<Session> session,
SessionManager::GetInstance().Broadcast(packet.header, packet.payload);
} break;
case PacketID::CS_RankingRequest: {
Protocol::CS_RankingRequest pkt;
if (!pkt.ParseFromArray(packet.payload.data(), packet.payload.size())) {
Logger::Log("랭킹 요청 패킷 파싱 실패");
co_return;
}
auto rankResult = co_await DatabaseManager::GetInstance().GetRanking(
(int)pkt.type(), session->GetNickname());
Protocol::SC_RankingList res;
res.set_type(pkt.type());
res.set_my_rank(rankResult.myRank);
res.set_my_value(rankResult.myValue);
for (const auto &entry : rankResult.topEntries) {
auto *newEntry = res.add_entries();
newEntry->set_rank(entry.rank);
newEntry->set_nickname(entry.nickname);
newEntry->set_value(entry.value);
}
session->SendPacket(PacketID::SC_RankingList, res);
} break;
default:
Logger::Log("알 수 없는 패킷 ID: ", packet.header.id);
break;