#include "PacketHandler.h" #include "DatabaseManager.h" #include "Logger.h" #include "Protocol.pb.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->SendPacket(PacketID::Ping); } break; case PacketID::CS_Login: { Protocol::CS_Login pkt; if (!pkt.ParseFromArray(packet.payload.data(), packet.payload.size())) { Logger::Log("로그인 패킷 파싱 실패"); co_return; } std::string nickname = pkt.nickname(); auto userData = co_await DatabaseManager::GetInstance().LoadUser(nickname); // 골드와 검 레벨 설정 (닉네임은 TryJoin에서 설정) session->SetGold(userData.gold); session->SetSwordLevel(userData.swordLevel); Protocol::SC_LoginResult loginResult; // 중복 체크 if (!SessionManager::GetInstance().TryJoin(session, userData.nickname)) { Logger::Log("중복 로그인 거부: ", nickname); loginResult.set_success(false); session->SendPacket(PacketID::SC_LoginResult, loginResult); co_return; } Logger::Log("클라이언트 로그인 성공: ", nickname, " (Gold: ", session->GetGold(), ", Level: ", session->GetSwordLevel(), ")"); loginResult.set_success(true); session->SendPacket(PacketID::SC_LoginResult, loginResult); } break; case PacketID::CS_UpgradeSword: { uint32_t currentLevel = session->GetSwordLevel(); uint64_t cost = SwordLogic::GetUpgradeCost(currentLevel); uint64_t currentGold = session->GetGold(); Protocol::SC_UpgradeResult res; if (currentGold < cost) { // 골드 부족 res.set_result(2); } else { session->SetGold(currentGold - cost); uint8_t result = SwordLogic::TryUpgrade(currentLevel); res.set_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.set_current_level(session->GetSwordLevel()); res.set_current_gold(session->GetGold()); // 결과 패킷 전송 session->SendPacket(PacketID::SC_UpgradeResult, res); // 브로드캐스트 if (currentGold >= cost) { uint32_t attemptedLevel = currentLevel + 1; std::string resultText; if (res.result() == 1) { resultText = "를 달성했습니다!"; } else if (res.result() == 0) { resultText = " 시도 중 검이 파괴되었습니다!"; } else { resultText = " 달성에 실패했습니다!"; } std::string chatMsg = "채팅] " + session->GetNickname() + " 님이 검 강화 단계 " + std::to_string(attemptedLevel) + resultText; PacketHeader chatHeader; chatHeader.id = static_cast(PacketID::Chat); chatHeader.size = static_cast(chatMsg.size()); std::vector chatPayload(chatMsg.begin(), chatMsg.end()); SessionManager::GetInstance().Broadcast(chatHeader, chatPayload); Logger::Log("강화 시도 [", session->GetNickname(), "]: ", (int)res.result(), " (레벨: ", currentLevel, "->", res.current_level(), ")"); } } 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()); Protocol::SC_SellResult res; res.set_earned_gold(price); res.set_total_gold(newGold); session->SendPacket(PacketID::SC_SellResult, res); 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; }