From 993d41736d2f7589d062d5574e1c2a2522fa53ee Mon Sep 17 00:00:00 2001 From: HappyTanuki Date: Sun, 4 May 2025 23:43:04 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B3=BC=EC=A0=9C=20=EC=A0=9C=EC=B6=9C?= =?UTF-8?q?=EB=B3=B8..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- .../include/ClientManager/ClientManager.hpp | 27 +- Client/src/ClientManager/ClientManager.cpp | 416 +++++++----------- Server/src/ServerManager/ServerManager.cpp | 17 +- include/Packet/Packet.hpp | 11 +- include/Socket/IOCP.hpp | 2 +- 6 files changed, 185 insertions(+), 291 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 18ad11c..c986040 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -84,6 +84,7 @@ "ranges": "cpp", "valarray": "cpp", "__tree": "cpp", - "map": "cpp" + "map": "cpp", + "iostream": "cpp" } } \ No newline at end of file diff --git a/Client/include/ClientManager/ClientManager.hpp b/Client/include/ClientManager/ClientManager.hpp index 5f8228e..776bbda 100644 --- a/Client/include/ClientManager/ClientManager.hpp +++ b/Client/include/ClientManager/ClientManager.hpp @@ -31,7 +31,7 @@ public: if (sock_.connect(serveraddr) == INVALID_SOCKET) { spdlog::error("{}", strerror(errno)); - return; + std::exit(EXIT_FAILURE); } data_ = new IOCPPASSINDATA; @@ -52,7 +52,7 @@ public: }); } - void processresponsePacket(ResponsePacket responsePacket, IOCPPASSINDATA* data); + void processResponsePacket(ResponsePacket responsePacket, IOCPPASSINDATA* data); void processLoginResponsePacket(LoginResponsePacket loginResponsePacket, IOCPPASSINDATA* data); void processRoomCreateResponsePacket(RoomCreateResponsePacket roomCreateResponsePacket, IOCPPASSINDATA* data); void processRoomListResponse(RoomListResponsePacket roomListResponsePacket, IOCPPASSINDATA* data); @@ -62,13 +62,15 @@ public: void processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data); void processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data); + void sendMessage(Snowflake ID, std::string message); + void registerUser(std::string userName); void deleteUser(Snowflake UID); - std::vector> getUserList(); + void getUserList(); - Snowflake createRoom(std::string roomName); + void createRoom(std::string roomName); void deleteRoom(Snowflake RID); - std::vector> getRoomList(); + void getRoomList(); void joinRoom(Snowflake UID, Snowflake RID); void exitRoom(Snowflake UID, Snowflake RID); @@ -85,18 +87,21 @@ private: bool inRoom_ = false; + std::future lastResponsePacket_; + TCPSocket sock_; std::mutex resourceMutex_; + std::mutex screenMutex_; - std::unordered_map roomNames_; + std::queue messageQueue_; + std::vector messageHistory_; - std::unordered_map>> rooms_; + std::future> roomNames_; + std::future> findRoomId_; - std::unordered_map> UID2userSocket_; - std::unordered_map, Snowflake> userSocket2UID_; - - std::unordered_map userNames_; + std::future> userNames_; + std::future> findUserId_; }; } \ No newline at end of file diff --git a/Client/src/ClientManager/ClientManager.cpp b/Client/src/ClientManager/ClientManager.cpp index fb31d15..11dff29 100644 --- a/Client/src/ClientManager/ClientManager.cpp +++ b/Client/src/ClientManager/ClientManager.cpp @@ -35,6 +35,12 @@ void ClientManager::_IOCPClient(Chattr::ThreadPool* thread, Chattr::IOCPPASSINDA LoginResponsePacket loginResponsePacket; std::memcpy(&loginResponsePacket.serialized, &pack.serialized, 8 + packetLength); loginResponsePacket.convToH(); + + lastResponsePacket_ = std::future(); + auto promise = std::promise(); + lastResponsePacket_ = promise.get_future(); + promise.set_value(loginResponsePacket); + processLoginResponsePacket(loginResponsePacket, data); } break; @@ -47,7 +53,13 @@ void ClientManager::_IOCPClient(Chattr::ThreadPool* thread, Chattr::IOCPPASSINDA ResponsePacket responsePacket; std::memcpy(&responsePacket.serialized, &pack.serialized, 8 + packetLength); responsePacket.convToH(); - processresponsePacket(responsePacket, data); + + lastResponsePacket_ = std::future(); + auto promise = std::promise(); + lastResponsePacket_ = promise.get_future(); + promise.set_value(responsePacket); + + processResponsePacket(responsePacket, data); } break; case PacketSet::DATAPOST: { @@ -135,27 +147,8 @@ PacketSet ClientManager::packetParser(Packet Packet) { return PacketSet::INVALID; } -void ClientManager::processresponsePacket(ResponsePacket responsePacket, IOCPPASSINDATA* data) { +void ClientManager::processResponsePacket(ResponsePacket responsePacket, IOCPPASSINDATA* data) { responsePacket; - // std::string userName( - // (char*)loginResponsePacket.__data.data, - // loginResponsePacket.__data.packetLength); - // registerUser(userName); - - // LoginResponsePacket loginResponsePacket; - // loginResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - // loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN; - // loginResponsePacket.__data.dataType = Chattr::DataType::BINARY; - // loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake); - // loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - // Snowflake yourId = userSocket2UID_[data->socket]; - // ::memcpy(loginResponsePacket.__data.yourId, &yourId, sizeof(Snowflake)); - - // loginResponsePacket.convToN(); - // memcpy(data->wsabuf.buf, loginResponsePacket.serialized, 18); - // data->sendbytes = 18; - // data->wsabuf.len = 18; - // data->IOCPInstance->send(data, 1, 0); } @@ -164,236 +157,74 @@ void ClientManager::processLoginResponsePacket(LoginResponsePacket loginResponse } void ClientManager::processRoomCreateResponsePacket(RoomCreateResponsePacket roomCreateResponsePacket, Chattr::IOCPPASSINDATA* data) { - // std::string roomName( - // (char*)roomCreateResponsePacket.__data.data, - // roomCreateResponsePacket.__data.packetLength); - // Snowflake RID = createRoom(roomName); - - // RoomCreateResponsePacket roomCreateResponsePacket; - // roomCreateResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - // roomCreateResponsePacket.__data.requestType = Chattr::RequestType::ROOM_CREATE; - // roomCreateResponsePacket.__data.dataType = Chattr::DataType::BINARY; - // roomCreateResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake); - // roomCreateResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - // ::memcpy(roomCreateResponsePacket.__data.createdRoomId, &RID, sizeof(Snowflake)); - - // roomCreateResponsePacket.convToN(); - // memcpy(data->wsabuf.buf, roomCreateResponsePacket.serialized, 18); - // data->sendbytes = 18; - // data->wsabuf.len = 18; - // data->IOCPInstance->send(data, 1, 0); } void ClientManager::processRoomListResponse(RoomListResponsePacket roomListResponsePacket, Chattr::IOCPPASSINDATA* data) { - // auto roomsList = getRoomList(); - - // for (auto room : roomsList) { - // RoomListResponsePacket roomListResponsePacket; - // roomListResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - // roomListResponsePacket.__data.requestType = Chattr::RequestType::ROOM_LIST; - // roomListResponsePacket.__data.dataType = Chattr::DataType::BINARY; - // roomListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + room.second.size(); - // roomListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - // roomListResponsePacket.__data.roomCount = roomsList.size(); - // ::memcpy(roomListResponsePacket.__data.roomId, &room.first, sizeof(Snowflake)); - // ::memcpy(roomListResponsePacket.__data.name, room.second.c_str(), room.second.size()); - - // int packetLength = roomListResponsePacket.__data.packetLength; - - // Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - // ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); - // ptr->socket = data->socket; - // ptr->recvbytes = ptr->sendbytes = 0; - // ptr->wsabuf.buf = ptr->buf; - // ptr->wsabuf.len = packetLength + 8; - // ptr->IOCPInstance = data->IOCPInstance; - - // roomListResponsePacket.convToN(); - // memcpy(ptr->wsabuf.buf, roomListResponsePacket.serialized, packetLength + 8); - // data->sendbytes = packetLength + 8; - // data->IOCPInstance->send(ptr, 1, 0); - // } } void ClientManager::processRoomJoinResponsePacket(RoomJoinResponsePacket roomJoinResponsePacket, Chattr::IOCPPASSINDATA* data) { - // Snowflake myID, roomID; - // ::memcpy(&myID.snowflake, roomJoinResponsePacket.__data.myId, sizeof(Snowflake)); - // ::memcpy(&roomID.snowflake, roomJoinResponsePacket.__data.roomId, sizeof(Snowflake)); - - // joinRoom(myID, roomID); - - // RoomJoinResponsePacket roomJoinResponsePacket; - // roomJoinResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - // roomJoinResponsePacket.__data.requestType = Chattr::RequestType::ROOM_JOIN; - // roomJoinResponsePacket.__data.dataType = Chattr::DataType::BINARY; - // roomJoinResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - // roomJoinResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - - // int packetLength = roomJoinResponsePacket.__data.packetLength; - - // roomJoinResponsePacket.convToN(); - // ::memcpy(data->wsabuf.buf, roomJoinResponsePacket.serialized, 10); - // data->sendbytes = 10; - // data->wsabuf.len = 10; - // data->IOCPInstance->send(data, 1, 0); } void ClientManager::processRoomExitResponsePacket(RoomExitResponsePacket roomExitResponsePacket, Chattr::IOCPPASSINDATA* data) { - // Snowflake myID, roomID; - // ::memcpy(&myID.snowflake, roomExitResponsePacket.__data.myId, sizeof(Snowflake)); - // ::memcpy(&roomID.snowflake, roomExitResponsePacket.__data.roomId, sizeof(Snowflake)); - - // exitRoom(myID, roomID); - - // RoomExitResponsePacket roomExitResponsePacket; - // roomExitResponsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - // roomExitResponsePacket.__data.requestType = Chattr::RequestType::ROOM_EXIT; - // roomExitResponsePacket.__data.dataType = Chattr::DataType::BINARY; - // roomExitResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - // roomExitResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - - // int packetLength = roomExitResponsePacket.__data.packetLength; - - // roomExitResponsePacket.convToN(); - // ::memcpy(data->wsabuf.buf, roomExitResponsePacket.serialized, 10); - // data->sendbytes = 10; - // data->wsabuf.len = 10; - // data->IOCPInstance->send(data, 1, 0); } void ClientManager::processUsersListResponsePacket(UsersListResponsePacket usersListResponsePacket, Chattr::IOCPPASSINDATA* data) { - // auto usersList = getUserList(); + std::unordered_map userNames; - // 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::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()); + if (userNames_.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + userNames = userNames_.get(); - // int packetLength = usersListResponsePacket.__data.packetLength; + auto promise = std::promise>(); + userNames_ = promise.get_future(); - // Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - // ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); - // ptr->socket = data->socket; - // ptr->recvbytes = ptr->sendbytes = 0; - // ptr->wsabuf.buf = ptr->buf; - // ptr->wsabuf.len = packetLength + 8; - // ptr->IOCPInstance = data->IOCPInstance; + Snowflake userId; + ::memcpy(&userId.snowflake, usersListResponsePacket.__data.userId, sizeof(Snowflake)); + std::string userName((char*)usersListResponsePacket.__data.name, usersListResponsePacket.__data.packetLength - (sizeof(std::uint16_t) * 7)); + userNames[userId] = userName; - // usersListResponsePacket.convToN(); - // memcpy(ptr->wsabuf.buf, usersListResponsePacket.serialized, packetLength + 8); - // data->sendbytes = packetLength + 8; - // data->IOCPInstance->send(ptr, 1, 0); - // } + promise.set_value(userNames); + + spdlog::info("{}", userName); } void ClientManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPASSINDATA* data) { - Snowflake destID; - ::memcpy(&destID.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake)); + Snowflake sentUserId; + ::memcpy(&sentUserId.snowflake, dataPostPacket.__data.destId, sizeof(Snowflake)); + auto UNames = userNames_.get(); + std::string sentUserName = UNames[sentUserId]; + std::string message((char*)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t) * 5)); - std::vector> destinationSockets; - - if (userNames_.find(destID) != userNames_.end()) - destinationSockets.push_back(UID2userSocket_[destID]); - else - for (auto user : rooms_[destID]) - destinationSockets.push_back(user.second); - - spdlog::info("Received [{}] from : [{}] to : [{}]", - std::string((char*)dataPostPacket.__data.data, dataPostPacket.__data.packetLength - (sizeof(std::uint16_t) * 5)), - (std::string)data->socket->remoteAddr, - destID.snowflake); - - ResponsePacket responsePacket; - responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - responsePacket.__data.requestType = Chattr::RequestType::DATA; - responsePacket.__data.dataType = Chattr::DataType::TEXT; - responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - - responsePacket.convToN(); - memcpy(data->wsabuf.buf, responsePacket.serialized, 10); - data->sendbytes = 10; - data->wsabuf.len = 10; - data->IOCPInstance->send(data, 1, 0); - - int packetLength = dataPostPacket.__data.packetLength; - - for (auto dest : destinationSockets) { - - Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); - ptr->socket = dest; - ptr->recvbytes = ptr->sendbytes = 0; - ptr->wsabuf.buf = ptr->buf; - ptr->wsabuf.len = packetLength + 6; - ptr->IOCPInstance = data->IOCPInstance; - - dataPostPacket.convToN(); - memcpy(ptr->wsabuf.buf, dataPostPacket.serialized, packetLength + 6); - data->sendbytes = packetLength + 6; - data->IOCPInstance->send(ptr, 1, 0); - } + spdlog::info("[{}] {}", sentUserName, message); // todo: pass data to main thread } void ClientManager::processContinuePacket(ContinuePacket continuePacket, IOCPPASSINDATA* data) { - Snowflake destID; - ::memcpy(&destID.snowflake, continuePacket.__data.destId, sizeof(Snowflake)); +} - std::vector> destinationSockets; +void ClientManager::sendMessage(Snowflake ID, std::string message) { + DataPostPacket dataPostPacket; + dataPostPacket.__data.packetType = PacketCategory::PACKET_POST; + dataPostPacket.__data.requestType = RequestType::DATA; + dataPostPacket.__data.dataType = DataType::TEXT; + dataPostPacket.__data.packetLength = message.size() + sizeof(Snowflake) * 2; + memcpy(dataPostPacket.__data.sourceId, &myID_.snowflake, sizeof(Snowflake)); + memcpy(dataPostPacket.__data.destId, &ID.snowflake, sizeof(Snowflake)); + memcpy(dataPostPacket.__data.data, message.c_str(), message.size()); - if (userNames_.find(destID) != userNames_.end()) - destinationSockets.push_back(UID2userSocket_[destID]); - else - for (auto user : rooms_[destID]) - destinationSockets.push_back(user.second); + int packetLength = dataPostPacket.__data.packetLength; - spdlog::info("Received [{}] from : [{}] to : [{}]", - std::string((char*)continuePacket.__data.data, continuePacket.__data.packetLength - (sizeof(std::uint16_t) * 5)), - (std::string)data->socket->remoteAddr, - destID.snowflake); + data_->recvbytes = data_->sendbytes = 0; + data_->wsabuf.len = data_->sendbytes = packetLength + 8; - ResponsePacket responsePacket; - responsePacket.__data.packetType = Chattr::PacketCategory::PACKET_RESPONSE; - responsePacket.__data.requestType = Chattr::RequestType::DATA; - responsePacket.__data.dataType = Chattr::DataType::TEXT; - responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; - - responsePacket.convToN(); - memcpy(data->wsabuf.buf, responsePacket.serialized, 10); - data->sendbytes = 10; - data->wsabuf.len = 10; - data->IOCPInstance->send(data, 1, 0); - - int packetLength = continuePacket.__data.packetLength; - - for (auto dest : destinationSockets) { - Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; - ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); - ptr->socket = dest; - ptr->recvbytes = ptr->sendbytes = 0; - ptr->wsabuf.buf = ptr->buf; - ptr->wsabuf.len = packetLength + 6; - ptr->IOCPInstance = data->IOCPInstance; - - continuePacket.convToN(); - memcpy(ptr->wsabuf.buf, continuePacket.serialized, packetLength + 6); - data->sendbytes = packetLength + 6; - data->IOCPInstance->send(ptr, 1, 0); - } + dataPostPacket.convToN(); + memcpy(data_->wsabuf.buf, dataPostPacket.serialized, packetLength + 8); + iocp_.send(data_, 1, 0, true); } void ClientManager::registerUser(std::string userName) { - Chattr::LoginRequestPacket loginRequestPacket; - loginRequestPacket.__data.packetType = Chattr::PacketCategory::PACKET_REQUEST; - loginRequestPacket.__data.requestType = Chattr::RequestType::LOGIN; - loginRequestPacket.__data.dataType = Chattr::DataType::BINARY; + LoginRequestPacket loginRequestPacket; + loginRequestPacket.__data.packetType = PacketCategory::PACKET_REQUEST; + loginRequestPacket.__data.requestType = RequestType::LOGIN; + loginRequestPacket.__data.dataType = DataType::BINARY; loginRequestPacket.__data.packetLength = userName.size(); memcpy(loginRequestPacket.__data.data, userName.c_str(), userName.size()); @@ -408,59 +239,36 @@ void ClientManager::registerUser(std::string userName) { iocp_.send(data_, 1, 0, true); } -void ClientManager::deleteUser(Snowflake UID) { - std::lock_guard lock(resourceMutex_); - userNames_.erase(UID); - std::shared_ptr sock = UID2userSocket_[UID]; - UID2userSocket_.erase(UID); - userSocket2UID_.erase(sock); +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; + + int packetLength = usersListRequestPacket.__data.packetLength; + + data_->recvbytes = data_->sendbytes = 0; + data_->wsabuf.len = packetLength + 8; + + usersListRequestPacket.convToN(); + memcpy(data_->wsabuf.buf, usersListRequestPacket.serialized, packetLength + 8); + iocp_.send(data_, 1, 0, true); } -std::vector> ClientManager::getUserList() { - std::lock_guard lock(resourceMutex_); - std::vector> userList; - userList.reserve(userNames_.size()); - - for (auto user : userNames_) - userList.push_back(user); - - return userList; -} - -Snowflake ClientManager::createRoom(std::string roomName) { - std::lock_guard lock(resourceMutex_); - Snowflake RID = GenerateID(); - roomNames_[RID] = roomName; - rooms_[RID] = std::unordered_map>(); - return RID; +void ClientManager::createRoom(std::string roomName) { } void ClientManager::deleteRoom(Snowflake RID) { - std::lock_guard lock(resourceMutex_); - roomNames_.erase(RID); - rooms_.erase(RID); } -std::vector> ClientManager::getRoomList() { - std::lock_guard lock(resourceMutex_); - std::vector> roomList; - roomList.reserve(roomNames_.size()); - - for (auto user : roomNames_) - roomList.push_back(user); - - return roomList; +void ClientManager::getRoomList() { } void ClientManager::joinRoom(Snowflake UID, Snowflake RID) { - std::lock_guard lock(resourceMutex_); - std::shared_ptr sock = UID2userSocket_[UID]; - rooms_[RID][UID] = sock; } void ClientManager::exitRoom(Snowflake UID, Snowflake RID) { - std::lock_guard lock(resourceMutex_); - rooms_[RID].erase(UID); } void ClientManager::run() { @@ -476,23 +284,99 @@ void ClientManager::run() { std::cout << "Commads:" << std::endl; std::cout << "/w : Send direct message to specified user" << std::endl; std::cout << "/join : Enter specified room" << std::endl; - std::cout << "/exit : Exit current room" << std::endl; + std::cout << "/leave : Exit current room" << std::endl; std::cout << "/create : Create room" << std::endl; - std::cout << "/list : Print all registred users" << std::endl; - std::cout << "/exit : Terminate this program (When you are not in room)" << std::endl; + std::cout << "/userlist : Print all registred users" << std::endl; + std::cout << "/roomlist : Print all registred rooms" << std::endl; + std::cout << "/exit : Terminate this program" << std::endl; while (true) { std::string input; + std::unique_lock lock2(screenMutex_); if (inRoom_) { - std::cout << "[" << nickname << "@" << roomNames_[myRoomID_] << "]" << " "; + auto RNames = roomNames_.get(); + std::cout << "[" + nickname + "@" + RNames[myRoomID_] + "]" + " "; } else { - std::cout << "[" << nickname << "]" << " "; + std::cout << "[" + nickname + "]" + " "; } + lock2.unlock(); std::getline(std::cin, input); tokenizer.set(input.c_str(), input.size()); + auto tokens = tokenizer.get(); + if (tokens.size() == 0) + continue; + + if (tokens[0] == "/w") { + auto findUserId = findUserId_.get(); + + if (findUserId.find(tokens[1]) == findUserId.end()) { + resourceMutex_.lock(); + messageQueue_.push("User not found"); + resourceMutex_.unlock(); + continue; + } + + Snowflake destId = findUserId[tokens[1]]; + + auto tokens = tokenizer.get(); + std::string message; + for (int i = 2; i < tokens.size(); i++) + message += tokens[i]; + + sendMessage(destId, message); + } + else if (tokens[0] == "/join") { + std::string roomName; + for (int i = 1; i < tokens.size(); i++) + roomName += tokens[i]; + if (findRoomId_.wait_for(std::chrono::seconds(0)) != std::future_status::ready) { + resourceMutex_.lock(); + messageQueue_.push("Request room list first"); + resourceMutex_.unlock(); + continue; + } + auto findRoomId = findRoomId_.get(); + if (findRoomId.find(roomName) == findRoomId.end()) { + resourceMutex_.lock(); + messageQueue_.push("Room not found"); + resourceMutex_.unlock(); + continue; + } + joinRoom(myID_, findRoomId[roomName]); + } + else if (tokens[0] == "/leave") { + if (!inRoom_) { + resourceMutex_.lock(); + messageQueue_.push("You are not in any room"); + resourceMutex_.unlock(); + continue; + } + exitRoom(myID_, myRoomID_); + } + else if (tokens[0] == "/create") { + std::string roomName = tokenizer.get()[1]; + createRoom(roomName); + } + else if (tokens[0] == "/userlist") + getUserList(); + else if (tokens[0] == "/roomlist") + getRoomList(); + else if (tokens[0] == "/exit") + break; + else if (inRoom_) { + std::string message; + for (int i = 0; i < tokens.size(); i++) + message += tokens[i]; + sendMessage(myRoomID_, message); + } + else { + resourceMutex_.lock(); + messageQueue_.push("Command not found"); + resourceMutex_.unlock(); + } } } diff --git a/Server/src/ServerManager/ServerManager.cpp b/Server/src/ServerManager/ServerManager.cpp index ea9f8aa..e062122 100644 --- a/Server/src/ServerManager/ServerManager.cpp +++ b/Server/src/ServerManager/ServerManager.cpp @@ -177,7 +177,7 @@ void ServerManager::processLoginRequestPacket(LoginRequestPacket loginRequestPac loginResponsePacket.__data.requestType = Chattr::RequestType::LOGIN; loginResponsePacket.__data.dataType = Chattr::DataType::BINARY; loginResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake); - loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + loginResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; Snowflake yourId = userSocket2UID_[data->socket]; ::memcpy(loginResponsePacket.__data.yourId, &yourId, sizeof(Snowflake)); @@ -199,7 +199,7 @@ void ServerManager::processRoomCreateRequestPacket(RoomCreateRequestPacket roomC roomCreateResponsePacket.__data.requestType = Chattr::RequestType::ROOM_CREATE; roomCreateResponsePacket.__data.dataType = Chattr::DataType::BINARY; roomCreateResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(Snowflake); - roomCreateResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + roomCreateResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; ::memcpy(roomCreateResponsePacket.__data.createdRoomId, &RID, sizeof(Snowflake)); roomCreateResponsePacket.convToN(); @@ -218,7 +218,7 @@ void ServerManager::processRoomListRequest(RoomListRequestPacket roomListRequest roomListResponsePacket.__data.requestType = Chattr::RequestType::ROOM_LIST; roomListResponsePacket.__data.dataType = Chattr::DataType::BINARY; roomListResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode) + sizeof(std::uint32_t) + sizeof(Snowflake) + room.second.size(); - roomListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + roomListResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; roomListResponsePacket.__data.roomCount = roomsList.size(); ::memcpy(roomListResponsePacket.__data.roomId, &room.first, sizeof(Snowflake)); ::memcpy(roomListResponsePacket.__data.name, room.second.c_str(), room.second.size()); @@ -252,7 +252,7 @@ void ServerManager::processRoomJoinRequestPacket(RoomJoinRequestPacket roomJoinR roomJoinResponsePacket.__data.requestType = Chattr::RequestType::ROOM_JOIN; roomJoinResponsePacket.__data.dataType = Chattr::DataType::BINARY; roomJoinResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - roomJoinResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + roomJoinResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; int packetLength = roomJoinResponsePacket.__data.packetLength; @@ -275,7 +275,7 @@ void ServerManager::processRoomExitRequestPacket(RoomExitRequestPacket roomExitR roomExitResponsePacket.__data.requestType = Chattr::RequestType::ROOM_EXIT; roomExitResponsePacket.__data.dataType = Chattr::DataType::BINARY; roomExitResponsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - roomExitResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + roomExitResponsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; int packetLength = roomExitResponsePacket.__data.packetLength; @@ -295,7 +295,7 @@ void ServerManager::processUsersListRequestPacket(UsersListRequestPacket usersLi 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::OK; + 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()); @@ -339,7 +339,7 @@ void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPAS responsePacket.__data.requestType = Chattr::RequestType::DATA; responsePacket.__data.dataType = Chattr::DataType::TEXT; responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; responsePacket.convToN(); memcpy(data->wsabuf.buf, responsePacket.serialized, 10); @@ -350,7 +350,6 @@ void ServerManager::processDataPostPacket(DataPostPacket dataPostPacket, IOCPPAS int packetLength = dataPostPacket.__data.packetLength; for (auto dest : destinationSockets) { - Chattr::IOCPPASSINDATA* ptr = new Chattr::IOCPPASSINDATA; ::memset(&ptr->overlapped, 0, sizeof(OVERLAPPED)); ptr->socket = dest; @@ -388,7 +387,7 @@ void ServerManager::processContinuePacket(ContinuePacket continuePacket, IOCPPAS responsePacket.__data.requestType = Chattr::RequestType::DATA; responsePacket.__data.dataType = Chattr::DataType::TEXT; responsePacket.__data.packetLength = sizeof(Chattr::ResponseStatusCode); - responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::OK; + responsePacket.__data.responseStatusCode = Chattr::ResponseStatusCode::RES_OK; responsePacket.convToN(); memcpy(data->wsabuf.buf, responsePacket.serialized, 10); diff --git a/include/Packet/Packet.hpp b/include/Packet/Packet.hpp index 4dca98f..3177ec6 100644 --- a/include/Packet/Packet.hpp +++ b/include/Packet/Packet.hpp @@ -150,6 +150,7 @@ public: RequestType requestType; DataType dataType; std::uint16_t packetLength; + std::uint16_t sourceId[4]; std::uint16_t destId[4]; std::uint8_t data[]; } __data; @@ -157,14 +158,18 @@ public: }; std::uint8_t* convToN() { __data.packetLength = ::htons(__data.packetLength); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { + __data.sourceId[i] = ::htons(__data.sourceId[i]); __data.destId[i] = ::htons(__data.destId[i]); + } return serialized; } std::uint8_t* convToH() { __data.packetLength = ::ntohs(__data.packetLength); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { + __data.sourceId[i] = ::ntohs(__data.sourceId[i]); __data.destId[i] = ::ntohs(__data.destId[i]); + } return serialized; } }; @@ -197,7 +202,7 @@ public: }; enum class ResponseStatusCode : std::uint16_t { - OK = 200, + RES_OK = 200, CREATED = 201, ACCEPTED = 202, BAD_REQUEST = 400, diff --git a/include/Socket/IOCP.hpp b/include/Socket/IOCP.hpp index 38b6337..124f855 100644 --- a/include/Socket/IOCP.hpp +++ b/include/Socket/IOCP.hpp @@ -27,7 +27,7 @@ namespace Chattr { class IOCP; enum class IOCPEVENT { - ERR, + ERROR_, READ, WRITE };