From 7c382bead0dd51b9f4d8eef2e8b8ca9f4ec3db10 Mon Sep 17 00:00:00 2001 From: HappyTanuki Date: Sat, 10 May 2025 17:40:58 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A3=B8=20=EB=82=B4=EC=9D=98=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=EB=A7=8C=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Client/src/ClientManager/ClientManager.cpp | 50 ++++++++++++++----- .../include/ServerManager/ServerManager.hpp | 2 + Server/src/ServerManager/ServerManager.cpp | 50 ++++++++++++++++++- include/Packet/Packet.hpp | 32 ++++++++++++ include/Socket/IOCP.hpp | 18 ++++--- 5 files changed, 131 insertions(+), 21 deletions(-) diff --git a/Client/src/ClientManager/ClientManager.cpp b/Client/src/ClientManager/ClientManager.cpp index 9e5e119..087846f 100644 --- a/Client/src/ClientManager/ClientManager.cpp +++ b/Client/src/ClientManager/ClientManager.cpp @@ -142,6 +142,8 @@ PacketSet ClientManager::packetParser(Packet Packet) { return PacketSet::ROOMEXITREQUEST; case RequestType::USERS_LIST: return PacketSet::USERSLISTREQUEST; + case RequestType::ROOM_USERS_LIST: + return PacketSet::ROOMUSERSLISTREQUEST; case RequestType::DATA: return PacketSet::INVALID; } @@ -160,6 +162,8 @@ PacketSet ClientManager::packetParser(Packet Packet) { return PacketSet::ROOMEXITRESPONSE; case RequestType::USERS_LIST: return PacketSet::USERSLISTRESPONSE; + case RequestType::ROOM_USERS_LIST: + return PacketSet::ROOMUSERSLISTRESPONSE; case RequestType::DATA: return PacketSet::RESPONSE; default: @@ -215,7 +219,7 @@ void ClientManager::processUsersListResponsePacket(UsersListResponsePacket users void ClientManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data) { Snowflake sentUserId; - ::memcpy(&sentUserId.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake)); + ::memcpy(&sentUserId.snowflake, dataPostPacket.__data.sourceId, sizeof(Snowflake)); std::string sentUserName = userNames_[sentUserId]; std::string message((char*)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t) * 5)); @@ -267,21 +271,41 @@ void ClientManager::registerUser(std::string userName) { } void ClientManager::getUserList() { - UsersListRequestPacket usersListRequestPacket; - usersListRequestPacket.__data.packetType = PacketCategory::PACKET_REQUEST; - usersListRequestPacket.__data.requestType = RequestType::USERS_LIST; - usersListRequestPacket.__data.dataType = DataType::BINARY; - usersListRequestPacket.__data.packetLength = 0; + if (inRoom_) { + RoomUsersListRequestPacket roomUsersListRequestPacket; + roomUsersListRequestPacket.__data.packetType = PacketCategory::PACKET_REQUEST; + roomUsersListRequestPacket.__data.requestType = RequestType::ROOM_USERS_LIST; + roomUsersListRequestPacket.__data.dataType = DataType::BINARY; + roomUsersListRequestPacket.__data.packetLength = sizeof(Snowflake); + memcpy(roomUsersListRequestPacket.__data.roomId, &myRoomID_.snowflake, sizeof(Snowflake)); - int packetLength = usersListRequestPacket.__data.packetLength; + int packetLength = roomUsersListRequestPacket.__data.packetLength; - data_->recvbytes = data_->sendbytes = 0; - data_->transferredbytes = 0; - data_->wsabuf.len = packetLength + 8; + data_->recvbytes = data_->sendbytes = 0; + data_->transferredbytes = 0; + data_->wsabuf.len = packetLength + 8; - usersListRequestPacket.convToN(); - memcpy(data_->wsabuf.buf, usersListRequestPacket.serialized, packetLength + 8); - iocp_.send(data_, 1, 0); + roomUsersListRequestPacket.convToN(); + memcpy(data_->wsabuf.buf, roomUsersListRequestPacket.serialized, packetLength + 8); + iocp_.send(data_, 1, 0); + } + else { + UsersListRequestPacket usersListRequestPacket; + usersListRequestPacket.__data.packetType = PacketCategory::PACKET_REQUEST; + usersListRequestPacket.__data.requestType = RequestType::USERS_LIST; + usersListRequestPacket.__data.dataType = DataType::BINARY; + usersListRequestPacket.__data.packetLength = 0; + + int packetLength = usersListRequestPacket.__data.packetLength; + + data_->recvbytes = data_->sendbytes = 0; + data_->transferredbytes = 0; + data_->wsabuf.len = packetLength + 8; + + usersListRequestPacket.convToN(); + memcpy(data_->wsabuf.buf, usersListRequestPacket.serialized, packetLength + 8); + iocp_.send(data_, 1, 0); + } } void ClientManager::createRoom(std::string roomName) { diff --git a/Server/include/ServerManager/ServerManager.hpp b/Server/include/ServerManager/ServerManager.hpp index e3fd8ca..3b1672b 100644 --- a/Server/include/ServerManager/ServerManager.hpp +++ b/Server/include/ServerManager/ServerManager.hpp @@ -48,12 +48,14 @@ public: void processRoomJoinRequestPacket(RoomJoinRequestPacket roomJoinRequestPacket, IOCPPASSINDATA* data); void processRoomExitRequestPacket(RoomExitRequestPacket roomExitRequestPacket, IOCPPASSINDATA* data); void processUsersListRequestPacket(UsersListRequestPacket usersListRequestPacket, IOCPPASSINDATA* data); + void processUsersListInRoomRequestPacket(RoomUsersListRequestPacket roomUsersListRequestPacket, IOCPPASSINDATA* data); void processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data); void processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data); bool registerUser(std::string userName, std::shared_ptr sock); void deleteUser(Snowflake UID); std::vector> getUserList(); + std::vector> getUserListInRoom(Snowflake RID); Snowflake createRoom(std::string roomName); void deleteRoom(Snowflake RID); diff --git a/Server/src/ServerManager/ServerManager.cpp b/Server/src/ServerManager/ServerManager.cpp index b207cc2..b970b54 100644 --- a/Server/src/ServerManager/ServerManager.cpp +++ b/Server/src/ServerManager/ServerManager.cpp @@ -148,6 +148,8 @@ PacketSet ServerManager::packetParser(Packet Packet) { return PacketSet::ROOMEXITREQUEST; case RequestType::USERS_LIST: return PacketSet::USERSLISTREQUEST; + case RequestType::ROOM_USERS_LIST: + return PacketSet::ROOMUSERSLISTREQUEST; case RequestType::DATA: return PacketSet::INVALID; } @@ -166,6 +168,8 @@ PacketSet ServerManager::packetParser(Packet Packet) { return PacketSet::ROOMEXITRESPONSE; case RequestType::USERS_LIST: return PacketSet::USERSLISTRESPONSE; + case RequestType::ROOM_USERS_LIST: + return PacketSet::ROOMUSERSLISTRESPONSE; case RequestType::DATA: return PacketSet::INVALID; } @@ -340,7 +344,37 @@ void ServerManager::processUsersListRequestPacket(UsersListRequestPacket usersLi } } -void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data) { +void ServerManager::processUsersListInRoomRequestPacket(RoomUsersListRequestPacket roomUsersListRequestPacket, IOCPPASSINDATA *data) { + std::unique_lock lock(resourceMutex_); + Snowflake roomID; + ::memcpy(&roomID.snowflake, roomUsersListRequestPacket.__data.roomId, sizeof(Snowflake)); + auto usersList = getUserListInRoom(roomID); + + for (auto user : usersList) { + UsersListResponsePacket usersListResponsePacket; + usersListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; + usersListResponsePacket.__data.requestType = Chattr::RequestType::USERS_LIST; + usersListResponsePacket.__data.dataType = Chattr::DataType::BINARY; + usersListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + user.second.size(); + usersListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; + usersListResponsePacket.__data.usersCount = usersList.size(); + ::memcpy(usersListResponsePacket.__data.userId, &user.first, sizeof(Snowflake)); + ::memcpy(usersListResponsePacket.__data.name, user.second.c_str(), user.second.size()); + + int packetLength = usersListResponsePacket.__data.packetLength; + + Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA(*data); + ptr->wsabuf.len = packetLength + 8; + + usersListResponsePacket.convToN(); + memcpy(ptr->wsabuf.buf, usersListResponsePacket.serialized, packetLength + 8); + data->sendbytes = packetLength + 8; + data->IOCPInstance->send(ptr, 1, 0); + } +} + +void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA *data) +{ std::unique_lock lock(resourceMutex_); Snowflake destID; ::memcpy(&destID.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake)); @@ -373,12 +407,12 @@ void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPAS int packetLength = dataPostPacket.__data.packetLength; + dataPostPacket.convToN(); for (auto dest : destinationSockets) { Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA(*data); ptr->socket = dest; ptr->wsabuf.len = packetLength + 8; - dataPostPacket.convToN(); memcpy(ptr->wsabuf.buf, dataPostPacket.serialized, packetLength + 8); data->sendbytes = packetLength + 8; data->IOCPInstance->send(ptr, 1, 0); @@ -459,6 +493,17 @@ std::vector> ServerManager::getUserList() { return userList; } +std::vector> ServerManager::getUserListInRoom(Snowflake RID) { + std::vector> userList; + userList.reserve(rooms_[RID].size()); + + for (auto user : rooms_[RID]) + userList.push_back({ user.first, userNames_[user.first] }); + + return userList; + +} + Snowflake ServerManager::createRoom(std::string roomName) { Snowflake RID = GenerateID(); roomNames_[RID] = roomName; @@ -494,6 +539,7 @@ void ServerManager::run() { while (true) { spdlog::info("Waiting for connection..."); listenSock_.accept(clientSock_, clientAddr_); + spdlog::trace("Accepted connection from {}, [{}]", clientSock_.sock, (std::string)clientAddr_); Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; ptr->socket = std::make_shared(std::move(clientSock_)); ptr->wsabuf.len = 1500; diff --git a/include/Packet/Packet.hpp b/include/Packet/Packet.hpp index 3177ec6..ded0b4b 100644 --- a/include/Packet/Packet.hpp +++ b/include/Packet/Packet.hpp @@ -12,6 +12,7 @@ enum class PacketSet { ROOMJOINREQUEST, ROOMEXITREQUEST, USERSLISTREQUEST, + ROOMUSERSLISTREQUEST, DATAPOST, CONTINUE, RESPONSE, @@ -21,6 +22,7 @@ enum class PacketSet { ROOMJOINRESPONSE, ROOMEXITRESPONSE, USERSLISTRESPONSE, + ROOMUSERSLISTRESPONSE, INVALID }; @@ -38,6 +40,7 @@ enum class RequestType : std::uint8_t { ROOM_JOIN, ROOM_EXIT, USERS_LIST, + ROOM_USERS_LIST, DATA }; @@ -142,6 +145,35 @@ public: class alignas(4) UsersListRequestPacket : public Packet {}; +class alignas(4) RoomUsersListRequestPacket : public Packet { +public: + union { + struct { + PacketCategory packetType; + RequestType requestType; + DataType dataType; + std::uint16_t packetLength; + std::uint16_t roomId[4]; + std::uint8_t data[]; + } __data; + std::uint8_t serialized[1500] = ""; + }; + std::uint8_t* convToN() { + __data.packetLength = ::htons(__data.packetLength); + for (int i = 0; i < 4; i++) { + __data.roomId[i] = ::htons(__data.roomId[i]); + } + return serialized; + } + std::uint8_t* convToH() { + __data.packetLength = ::ntohs(__data.packetLength); + for (int i = 0; i < 4; i++) { + __data.roomId[i] = ::ntohs(__data.roomId[i]); + } + return serialized; + } +}; + class alignas(4) DataPostPacket : public Packet { public: union { diff --git a/include/Socket/IOCP.hpp b/include/Socket/IOCP.hpp index 2b3267a..d8ef7ed 100644 --- a/include/Socket/IOCP.hpp +++ b/include/Socket/IOCP.hpp @@ -151,9 +151,11 @@ public: return; } else { - spdlog::error("recv() [{}]", strerror(errno)); + rootIocpData->event = IOCPEVENT::QUIT; + spdlog::debug("Disconnected. [{}]", (std::string)(rootIocpData->socket->remoteAddr)); ::epoll_ctl(epollfd, EPOLL_CTL_DEL, rootIocpData->socket->sock, NULL); - delete rootIocpData; + threadPool->enqueueJob(callback, rootIocpData); + // delete rootIocpData; return; } } @@ -168,9 +170,11 @@ public: redSize = ptr->socket->recv(ptr->buf + totalRedSize, headerSize - totalRedSize, 0); if (redSize == SOCKET_ERROR) { - spdlog::error("recv() [{}]", strerror(errno)); + ptr->event = IOCPEVENT::QUIT; + spdlog::debug("Disconnected. [{}]", (std::string)(ptr->socket->remoteAddr)); ::epoll_ctl(epollfd, EPOLL_CTL_DEL, ptr->socket->sock, NULL); - delete ptr; + threadPool->enqueueJob(callback, ptr); + // delete ptr; return; } else if (redSize == 0) { @@ -198,9 +202,11 @@ public: spdlog::trace("No data to read on {}", tid); return; } - spdlog::error("recv() [{}]", strerror(errno)); + ptr->event = IOCPEVENT::QUIT; + spdlog::debug("Disconnected. [{}]", (std::string)(ptr->socket->remoteAddr)); ::epoll_ctl(epollfd, EPOLL_CTL_DEL, ptr->socket->sock, NULL); - delete ptr; + threadPool->enqueueJob(callback, ptr); + // delete ptr; return; } else if (redSize == 0) {