diff --git a/README.md b/README.md index 7431282..5c6b5a7 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,6 @@ cmake --build build - SessionManager: 글로벌 세션 관리 및 브로드캐스팅 - DatabaseManager: 비동기 데이터베이스 작업 및 락 제어 - Packet: 바이너리 프로토콜 정의 (pragma pack(1)) + +## TODO: 완성도 위한 개선 +- 진행중인 검 상태 저장 후 재접속 시 복구 \ No newline at end of file diff --git a/include/NetworkService.h b/include/NetworkService.h index 4a3d27a..a187b7b 100644 --- a/include/NetworkService.h +++ b/include/NetworkService.h @@ -8,7 +8,8 @@ using boost::asio::ip::tcp; class NetworkService { public: - NetworkService(uint16_t port, int threadCount); + NetworkService(boost::asio::io_context &io_context, uint16_t port, + int threadCount); ~NetworkService(); void Run(); @@ -17,7 +18,7 @@ public: private: void DoAccept(); - boost::asio::io_context io_context_; + boost::asio::io_context &io_context_; std::vector threads_; tcp::acceptor acceptor_; boost::asio::executor_work_guard diff --git a/include/Session.h b/include/Session.h index b360056..9a25f19 100644 --- a/include/Session.h +++ b/include/Session.h @@ -16,6 +16,20 @@ public: void Start(); void Send(std::span data); + template void SendPacket(PacketID id, const T &payload) { + PacketHeader header; + header.id = static_cast(id); + header.size = sizeof(T); + + std::vector buffer(sizeof(PacketHeader) + sizeof(T)); + std::memcpy(buffer.data(), &header, sizeof(PacketHeader)); + std::memcpy(buffer.data() + sizeof(PacketHeader), &payload, sizeof(T)); + + Send(buffer); + } + + void SendPacket(PacketID id); + void SetNickname(const std::string &nickname); const std::string &GetNickname() const; diff --git a/include/SessionManager.h b/include/SessionManager.h index 82c6ed1..bc1ceb3 100644 --- a/include/SessionManager.h +++ b/include/SessionManager.h @@ -10,7 +10,6 @@ class SessionManager { public: static SessionManager &GetInstance(); - void Join(std::shared_ptr session); bool TryJoin(std::shared_ptr session, const std::string &nickname); void Leave(std::shared_ptr session); void Broadcast(PacketHeader header, std::span body); diff --git a/server/NetworkService.cpp b/server/NetworkService.cpp index 2a13784..f126266 100644 --- a/server/NetworkService.cpp +++ b/server/NetworkService.cpp @@ -2,8 +2,10 @@ #include "Logger.h" #include "Session.h" -NetworkService::NetworkService(uint16_t port, int threadCount) - : acceptor_(io_context_, tcp::endpoint(tcp::v4(), port)), +NetworkService::NetworkService(boost::asio::io_context &io_context, + uint16_t port, int threadCount) + : io_context_(io_context), + acceptor_(io_context_, tcp::endpoint(tcp::v4(), port)), work_guard_(boost::asio::make_work_guard(io_context_)) { threads_.reserve(threadCount); for (int i = 0; i < threadCount; ++i) { diff --git a/server/PacketHandler.cpp b/server/PacketHandler.cpp index b4a3dd0..c294e33 100644 --- a/server/PacketHandler.cpp +++ b/server/PacketHandler.cpp @@ -13,9 +13,7 @@ PacketHandler::HandlePacket(std::shared_ptr session, switch (static_cast(packet.header.id)) { case PacketID::Ping: { Logger::Log("Ping 수신됨"); - session->Send(std::span( - reinterpret_cast(&packet.header), - sizeof(PacketHeader))); + session->SendPacket(PacketID::Ping); } break; case PacketID::CS_Login: { @@ -40,18 +38,7 @@ PacketHandler::HandlePacket(std::shared_ptr session, if (!SessionManager::GetInstance().TryJoin(session, userData.nickname)) { Logger::Log("중복 로그인 거부: ", nickname); loginResult.result = 0; - - PacketHeader header; - header.id = static_cast(PacketID::SC_LoginResult); - header.size = sizeof(PKT_SC_LoginResult); - - std::vector buffer(sizeof(PacketHeader) + - sizeof(PKT_SC_LoginResult)); - std::memcpy(buffer.data(), &header, sizeof(PacketHeader)); - std::memcpy(buffer.data() + sizeof(PacketHeader), &loginResult, - sizeof(PKT_SC_LoginResult)); - - session->Send(buffer); + session->SendPacket(PacketID::SC_LoginResult, loginResult); co_return; } @@ -60,18 +47,7 @@ PacketHandler::HandlePacket(std::shared_ptr session, ", Level: ", session->GetSwordLevel(), ")"); loginResult.result = 1; - - PacketHeader header; - header.id = static_cast(PacketID::SC_LoginResult); - header.size = sizeof(PKT_SC_LoginResult); - - std::vector buffer(sizeof(PacketHeader) + - sizeof(PKT_SC_LoginResult)); - std::memcpy(buffer.data(), &header, sizeof(PacketHeader)); - std::memcpy(buffer.data() + sizeof(PacketHeader), &loginResult, - sizeof(PKT_SC_LoginResult)); - - session->Send(buffer); + session->SendPacket(PacketID::SC_LoginResult, loginResult); } break; case PacketID::CS_UpgradeSword: { @@ -104,16 +80,7 @@ PacketHandler::HandlePacket(std::shared_ptr session, 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); + session->SendPacket(PacketID::SC_UpgradeResult, res); // 브로드캐스트 if (currentGold >= cost) { @@ -158,17 +125,7 @@ PacketHandler::HandlePacket(std::shared_ptr session, 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); + session->SendPacket(PacketID::SC_SellResult, res); Logger::Log("검 판매 [", session->GetNickname(), "]: ", price, " 골드 획득"); diff --git a/server/Session.cpp b/server/Session.cpp index eaf67b3..7e1f091 100644 --- a/server/Session.cpp +++ b/server/Session.cpp @@ -3,6 +3,7 @@ #include "SessionManager.h" #include #include +#include Session::Session(tcp::socket socket) : socket_(std::move(socket)) {} @@ -21,6 +22,15 @@ uint32_t Session::GetSwordLevel() const { return swordLevel_; } void Session::Start() { DoReadHeader(); } +void Session::SendPacket(PacketID id) { + PacketHeader header; + header.id = static_cast(id); + header.size = 0; + std::vector buffer(sizeof(PacketHeader)); + std::memcpy(buffer.data(), &header, sizeof(PacketHeader)); + Send(buffer); +} + void Session::Send(std::span data) { auto self(shared_from_this()); boost::asio::post( diff --git a/server/SessionManager.cpp b/server/SessionManager.cpp index 3f4e5be..35c19ba 100644 --- a/server/SessionManager.cpp +++ b/server/SessionManager.cpp @@ -6,13 +6,6 @@ SessionManager &SessionManager::GetInstance() { return instance; } -void SessionManager::Join(std::shared_ptr session) { - std::lock_guard lock(mutex_); - sessions_.insert(session); - Logger::Log("클라이언트[", session->GetNickname(), - "]가 입장했습니다. 총 세션 수: ", sessions_.size()); -} - void SessionManager::Leave(std::shared_ptr session) { std::lock_guard lock(mutex_); if (sessions_.erase(session) > 0) { diff --git a/server/main.cpp b/server/main.cpp index 3270f08..9abedd4 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -32,7 +32,7 @@ int main() { return 1; } - NetworkService server(port, threadCount); + NetworkService server(main_context, port, threadCount); server.Run(); boost::asio::signal_set signals(main_context, SIGINT, SIGTERM);