diff --git a/README.md b/README.md index 5c6b5a7..7431282 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,3 @@ 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 a187b7b..4a3d27a 100644 --- a/include/NetworkService.h +++ b/include/NetworkService.h @@ -8,8 +8,7 @@ using boost::asio::ip::tcp; class NetworkService { public: - NetworkService(boost::asio::io_context &io_context, uint16_t port, - int threadCount); + NetworkService(uint16_t port, int threadCount); ~NetworkService(); void Run(); @@ -18,7 +17,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 9a25f19..b360056 100644 --- a/include/Session.h +++ b/include/Session.h @@ -16,20 +16,6 @@ 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 bc1ceb3..82c6ed1 100644 --- a/include/SessionManager.h +++ b/include/SessionManager.h @@ -10,6 +10,7 @@ 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 f126266..2a13784 100644 --- a/server/NetworkService.cpp +++ b/server/NetworkService.cpp @@ -2,10 +2,8 @@ #include "Logger.h" #include "Session.h" -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)), +NetworkService::NetworkService(uint16_t port, int threadCount) + : 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 c294e33..b4a3dd0 100644 --- a/server/PacketHandler.cpp +++ b/server/PacketHandler.cpp @@ -13,7 +13,9 @@ PacketHandler::HandlePacket(std::shared_ptr session, switch (static_cast(packet.header.id)) { case PacketID::Ping: { Logger::Log("Ping 수신됨"); - session->SendPacket(PacketID::Ping); + session->Send(std::span( + reinterpret_cast(&packet.header), + sizeof(PacketHeader))); } break; case PacketID::CS_Login: { @@ -38,7 +40,18 @@ PacketHandler::HandlePacket(std::shared_ptr session, if (!SessionManager::GetInstance().TryJoin(session, userData.nickname)) { Logger::Log("중복 로그인 거부: ", nickname); loginResult.result = 0; - session->SendPacket(PacketID::SC_LoginResult, loginResult); + + 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); co_return; } @@ -47,7 +60,18 @@ PacketHandler::HandlePacket(std::shared_ptr session, ", Level: ", session->GetSwordLevel(), ")"); loginResult.result = 1; - session->SendPacket(PacketID::SC_LoginResult, loginResult); + + 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); } break; case PacketID::CS_UpgradeSword: { @@ -80,7 +104,16 @@ PacketHandler::HandlePacket(std::shared_ptr session, res.currentGold = session->GetGold(); // 결과 패킷 전송 - session->SendPacket(PacketID::SC_UpgradeResult, res); + 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); // 브로드캐스트 if (currentGold >= cost) { @@ -125,7 +158,17 @@ PacketHandler::HandlePacket(std::shared_ptr session, res.earnedGold = price; res.totalGold = newGold; - session->SendPacket(PacketID::SC_SellResult, res); + 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, " 골드 획득"); diff --git a/server/Session.cpp b/server/Session.cpp index 7e1f091..eaf67b3 100644 --- a/server/Session.cpp +++ b/server/Session.cpp @@ -3,7 +3,6 @@ #include "SessionManager.h" #include #include -#include Session::Session(tcp::socket socket) : socket_(std::move(socket)) {} @@ -22,15 +21,6 @@ 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 35c19ba..3f4e5be 100644 --- a/server/SessionManager.cpp +++ b/server/SessionManager.cpp @@ -6,6 +6,13 @@ 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 9abedd4..3270f08 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -32,7 +32,7 @@ int main() { return 1; } - NetworkService server(main_context, port, threadCount); + NetworkService server(port, threadCount); server.Run(); boost::asio::signal_set signals(main_context, SIGINT, SIGTERM);