feat: server, client 디렉토리 조정 및 client 헤더 파일 추가. 시나리오

혹은 대화형 클라이언트로 수정
This commit is contained in:
bumpsoo 2026-02-04 13:16:36 +00:00
parent b887f15662
commit 1d103d7f16
12 changed files with 281 additions and 112 deletions

View file

@ -1,132 +0,0 @@
#include "PacketHandler.h"
#include "DatabaseManager.h"
#include "Logger.h"
#include "SessionManager.h"
#include "SwordLogic.h"
#include <boost/asio/use_awaitable.hpp>
#include <cstring>
#include <string>
boost::asio::awaitable<void>
PacketHandler::HandlePacket(std::shared_ptr<Session> session,
const Packet packet) {
switch (static_cast<PacketID>(packet.header.id)) {
case PacketID::Ping: {
Logger::Log("Ping 수신됨");
session->Send(std::span<const uint8_t>(
reinterpret_cast<const uint8_t *>(&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<const PKT_CS_Login *>(packet.payload.data());
std::string nickname(loginPkt->nickname);
// DB에서 유저 정보 로드 (co_await 활용!)
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<uint16_t>(PacketID::SC_UpgradeResult);
header.size = sizeof(PKT_SC_UpgradeResult);
std::vector<uint8_t> 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<uint16_t>(PacketID::SC_SellResult);
header.size = sizeof(PKT_SC_SellResult);
std::vector<uint8_t> 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;
}