#include "PacketHandler.h" #include "DatabaseManager.h" #include "Logger.h" #include "SessionManager.h" #include "SwordLogic.h" #include #include #include boost::asio::awaitable PacketHandler::HandlePacket(std::shared_ptr session, const Packet packet) { switch (static_cast(packet.header.id)) { case PacketID::Ping: { Logger::Log("Ping 수신됨"); session->Send(std::span( reinterpret_cast(&packet.header), sizeof(PacketHeader))); } break; case PacketID::Login: { if (packet.payload.size() < sizeof(PKT_CS_Login)) { Logger::Log("로그인 패킷 크기가 올바르지 않습니다."); co_return; } const PKT_CS_Login *loginPkt = reinterpret_cast(packet.payload.data()); std::string nickname(loginPkt->nickname); auto userData = co_await DatabaseManager::GetInstance().LoadUser(nickname); session->SetNickname(userData.nickname); session->SetGold(userData.gold); session->SetSwordLevel(userData.swordLevel); Logger::Log("클라이언트 로그인: ", nickname, " (Gold: ", session->GetGold(), ", Level: ", session->GetSwordLevel(), ")"); SessionManager::GetInstance().Join(session); } break; case PacketID::CS_UpgradeSword: { uint32_t currentLevel = session->GetSwordLevel(); uint64_t cost = SwordLogic::GetUpgradeCost(currentLevel); uint64_t currentGold = session->GetGold(); PKT_SC_UpgradeResult res; if (currentGold < cost) { // 골드 부족 res.result = 2; } else { session->SetGold(currentGold - cost); uint8_t result = SwordLogic::TryUpgrade(currentLevel); res.result = result; // 성공 if (result == 1) { session->SetSwordLevel(currentLevel + 1); // 파괴 } else if (result == 0) { session->SetSwordLevel(0); } co_await DatabaseManager::GetInstance().SaveUser( session->GetNickname(), session->GetGold(), session->GetSwordLevel()); } res.currentLevel = session->GetSwordLevel(); res.currentGold = session->GetGold(); PacketHeader header; header.id = static_cast(PacketID::SC_UpgradeResult); header.size = sizeof(PKT_SC_UpgradeResult); std::vector buffer(sizeof(PacketHeader) + sizeof(PKT_SC_UpgradeResult)); std::memcpy(buffer.data(), &header, sizeof(PacketHeader)); std::memcpy(buffer.data() + sizeof(PacketHeader), &res, sizeof(PKT_SC_UpgradeResult)); session->Send(buffer); Logger::Log("강화 시도 [", session->GetNickname(), "]: ", (int)res.result, " (레벨: ", currentLevel, "->", res.currentLevel, ")"); } break; case PacketID::CS_SellSword: { uint32_t currentLevel = session->GetSwordLevel(); uint64_t price = SwordLogic::GetSellPrice(currentLevel); uint64_t newGold = session->GetGold() + price; session->SetGold(newGold); session->SetSwordLevel(0); co_await DatabaseManager::GetInstance().SaveUser( session->GetNickname(), session->GetGold(), session->GetSwordLevel()); PKT_SC_SellResult res; res.earnedGold = price; res.totalGold = newGold; PacketHeader header; header.id = static_cast(PacketID::SC_SellResult); header.size = sizeof(PKT_SC_SellResult); std::vector buffer(sizeof(PacketHeader) + sizeof(PKT_SC_SellResult)); std::memcpy(buffer.data(), &header, sizeof(PacketHeader)); std::memcpy(buffer.data() + sizeof(PacketHeader), &res, sizeof(PKT_SC_SellResult)); session->Send(buffer); Logger::Log("검 판매 [", session->GetNickname(), "]: ", price, " 골드 획득"); } break; case PacketID::Chat: { std::string msg(packet.payload.begin(), packet.payload.end()); Logger::Log("채팅 [", session->GetNickname(), "]: ", msg); SessionManager::GetInstance().Broadcast(packet.header, packet.payload); } break; default: Logger::Log("알 수 없는 패킷 ID: ", packet.header.id); break; } co_return; }