diff --git a/.vscode/settings.json b/.vscode/settings.json index 2af5a10..cddcf37 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -57,53 +57,55 @@ "C_Cpp_Runner.useLinkTimeOptimization": false, "C_Cpp_Runner.msvcSecureNoWarnings": false, "files.associations": { - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "random": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "typeinfo": "cpp", - "ctime": "cpp", - "map": "cpp" - } + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp", + "ctime": "cpp", + "map": "cpp", + "set": "cpp", + "fstream": "cpp" +} } \ No newline at end of file diff --git a/ft_irc3/includes/Channel.hpp b/ft_irc3/includes/Channel.hpp index fe35d5f..605618d 100644 --- a/ft_irc3/includes/Channel.hpp +++ b/ft_irc3/includes/Channel.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:41:35 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 18:49:53 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 16:12:23 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,6 +51,7 @@ class Channel const std::string &getTopicSetter() const; time_t getTopicTime() const; void setTopic(const std::string &topic, const std::string &setter); + std::string getKey(); void setClientLimit(size_t limit); size_t getClientLimit() const; diff --git a/ft_irc3/includes/Client.hpp b/ft_irc3/includes/Client.hpp index 364d67b..bbb59ec 100644 --- a/ft_irc3/includes/Client.hpp +++ b/ft_irc3/includes/Client.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:15:42 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 18:47:36 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/05 09:34:30 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,6 +43,8 @@ public: void setAway(bool away); std::string getKey() const; void setkey(const std::string &key); + char buffer[1024]; + char buffer2[1024]; private: int _fd; diff --git a/ft_irc3/includes/ClientManager.hpp b/ft_irc3/includes/ClientManager.hpp index ae6f457..7210e30 100644 --- a/ft_irc3/includes/ClientManager.hpp +++ b/ft_irc3/includes/ClientManager.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 18:30:07 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 18:50:30 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/05 09:37:10 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,6 +42,7 @@ class ClientManager public: ClientManager(Server *server); void acceptClient(); + void handleClientNext(int client_fd, char * buffer, int bytes_received); void handleClient(int client_fd); void removeClient(int client_fd); diff --git a/ft_irc3/includes/ModeHandler.hpp b/ft_irc3/includes/ModeHandler.hpp index 1505c4f..593def9 100644 --- a/ft_irc3/includes/ModeHandler.hpp +++ b/ft_irc3/includes/ModeHandler.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/30 11:12:57 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 18:52:10 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 14:00:47 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,7 +43,7 @@ class ModeHandler void setChannelMode(Client *client, Channel* channel, const std::string& mode, bool adding, const std::string& argument); void applyModeL(Client *client, Channel* channel, bool adding, const std::string& argument); - void applyModeI(Channel* channel, bool adding); + void applyModeI(Client *client, Channel* channel, bool adding); void applyModeK(Client *client, Channel* channel, bool adding, const std::string& argument); void applyModeT(Channel* channel, bool adding); void applyModeO(Client *client, Channel* channel, bool adding, const std::string& argument); diff --git a/ft_irc3/includes/RPL.hpp b/ft_irc3/includes/RPL.hpp index a3ec3d1..d2bd04d 100644 --- a/ft_irc3/includes/RPL.hpp +++ b/ft_irc3/includes/RPL.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/19 15:12:47 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 18:58:37 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 16:06:40 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,7 @@ #include "Client.hpp" #include "Utils.hpp" +#include "Channel.hpp" #define SERVER_NAME "IRC_Server" #define SERVER_VERSION "1.0" @@ -411,6 +412,22 @@ inline std::string ERR_INVALIDKEY(Client* client, const std::string& channel) return oss.str(); } +inline std::string ERR_KEYSET(Client* client, const std::string& channel) +{ + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 467 " << CLIENT_NICK(client) << " " << channel + << " :Channel key already set\r\n"; + return oss.str(); +} + +inline std::string ERR_LINKSET(Client* client, const std::string& channel) +{ + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 469 " << CLIENT_NICK(client) << " " << channel + << " :No key set\r\n"; + return oss.str(); +} + inline std::string ERR_CHANNELISFULL(Client* client, const std::string& channel) { std::ostringstream oss; @@ -517,4 +534,11 @@ inline std::string RPL_CAPEND(Client *client) return oss.str(); } +inline std::string MODEACCEPTMESSAGE(Client *client, std::string channel, const std::string& mode) +{ + std::ostringstream oss; + oss << ":" << client->getNickname() << " MODE " << channel << " " << mode << " :" << "\r\n"; + return oss.str(); +} + #endif diff --git a/ft_irc3/includes/Server.hpp b/ft_irc3/includes/Server.hpp index ba21a90..0f7d090 100644 --- a/ft_irc3/includes/Server.hpp +++ b/ft_irc3/includes/Server.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:15:13 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:01:40 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 15:03:28 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,7 +59,6 @@ class Server void broadcast(const std::string &message); Client* getClientByName(const std::string &name); Channel* getChannelByName(const std::string &name); - void sendChannelListToClient(Client *client); void disconnectClient(int clientFd); bool MatchFd(const pollfd& pfd, int clientFd); void removePollFd(int clientFd); @@ -84,9 +83,6 @@ class Server private: void initServer(); void handleServerCommands(); - void acceptClient(); - void removeClient(int client_fd); - }; #endif diff --git a/ft_irc3/src/AdditionalCommands.cpp b/ft_irc3/src/AdditionalCommands.cpp index 0106dcb..6c9740c 100644 --- a/ft_irc3/src/AdditionalCommands.cpp +++ b/ft_irc3/src/AdditionalCommands.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/16 15:27:29 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:05:15 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 13:55:09 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -65,7 +65,7 @@ void AdditionalCommands::broadcastChannelList(Client *client, Server *server) std::map &channels = server->getChannels(); for (std::map::iterator it = channels.begin(); it != channels.end(); ++it) { - server->sendToClient(client->getFd(), RPL_LIST(client, it->first, it->second->getClients().size(), "Existing channel")); + server->sendToClient(client->getFd(), RPL_LIST(client, it->first, it->second->getClients().size(), it->second->getTopic())); } server->sendToClient(client->getFd(), RPL_LISTEND(client)); } diff --git a/ft_irc3/src/Channel.cpp b/ft_irc3/src/Channel.cpp index cdd3220..a462fa4 100644 --- a/ft_irc3/src/Channel.cpp +++ b/ft_irc3/src/Channel.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:42:57 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:06:40 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 16:12:22 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -141,6 +141,11 @@ void Channel::setKey(const std::string &key) _key = key; } +std::string Channel::getKey() +{ + return _key; +} + void Channel::setTopicProtection(bool protection) { _topicProtection = protection; diff --git a/ft_irc3/src/ClientManager.cpp b/ft_irc3/src/ClientManager.cpp index d4e637a..6baeb81 100644 --- a/ft_irc3/src/ClientManager.cpp +++ b/ft_irc3/src/ClientManager.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 18:32:23 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:07:39 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/05 10:12:30 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,10 +38,13 @@ void ClientManager::acceptClient() void ClientManager::handleClient(int client_fd) { - char buffer[1024]; - std::memset(buffer, 0, sizeof(buffer)); - int bytes_received = recv(client_fd, buffer, sizeof(buffer), 0); - + Client* client = _server->getClients()[client_fd]; + // char buffer[1024]; + // char buffer2[1024]; + + std::memset(client->buffer, 0, sizeof(client->buffer)); + int bytes_received = recv(client_fd, client->buffer, sizeof(client->buffer), 0); + if (bytes_received <= 0) { std::ostringstream oss; @@ -51,6 +54,33 @@ void ClientManager::handleClient(int client_fd) return; } + std::cout << std::string(client->buffer).size() << " client->buffer " << std::string(client->buffer).find('\n') << std::endl; + + for (size_t i = 0; client->buffer[i];i++) + { + std::cout << client->buffer[i] << " .. "; + } + std::cout << std::endl; + + if (std::string(client->buffer).find('\n') != std::string::npos) + { + strcat(client->buffer2, client->buffer); + handleClientNext(client_fd, client->buffer2, std::string(client->buffer2).size()); + std::memset(client->buffer2, 0, std::string(client->buffer2).size()); + } + else + { + strcat(client->buffer2, client->buffer); + for (size_t i = 0; client->buffer2[i];i++) + { + std::cout << client->buffer2[i] << " . "; + } + } + std::cout << std::endl; +} + +void ClientManager::handleClientNext(int client_fd, char * buffer, int bytes_received) +{ std::string message(buffer, bytes_received); std::ostringstream oss; oss << "Received from client " << client_fd << ": " << message; diff --git a/ft_irc3/src/CommandHandler.cpp b/ft_irc3/src/CommandHandler.cpp index 99a4085..ad1a3a4 100644 --- a/ft_irc3/src/CommandHandler.cpp +++ b/ft_irc3/src/CommandHandler.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 18:26:34 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:10:48 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/05 09:57:55 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -201,7 +201,8 @@ void CommandHandler::handleNick(Client* client, const std::vector& std::string nickMessage = ":" + oldNick + " NICK " + newNick + "\r\n"; for (std::map::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it) { - _server->sendToClient(it->second->getFd(), nickMessage); + if (it->second->isAuthenticated()) + _server->sendToClient(it->second->getFd(), nickMessage); } std::ostringstream oss; diff --git a/ft_irc3/src/ModeHandler.cpp b/ft_irc3/src/ModeHandler.cpp index 0a0a9c9..c28f350 100644 --- a/ft_irc3/src/ModeHandler.cpp +++ b/ft_irc3/src/ModeHandler.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/30 11:13:08 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:15:05 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/04 16:12:50 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -134,7 +134,7 @@ void ModeHandler::setChannelMode(Client *client, Channel* channel, const std::st } else if (mode == "i") { - applyModeI(channel, adding); + applyModeI(client, channel, adding); } else if (mode == "k") { @@ -171,16 +171,34 @@ void ModeHandler::applyModeL(Client *client, Channel* channel, bool adding, cons } } -void ModeHandler::applyModeI(Channel* channel, bool adding) +void ModeHandler::applyModeI(Client *client, Channel *channel, bool adding) { - _server->log("Applying mode I: " + std::string(adding ? "Setting invite-only" : "Removing invite-only"), GREEN); - channel->setInviteOnly(adding); + std::string modeChange; + bool isAlreadySet; + + modeChange = adding ? "+i" : "-i"; + isAlreadySet = channel->isInviteOnly() == adding; + if (!isAlreadySet) + { + _server->sendToClient(client->getFd(), MODEACCEPTMESSAGE(client, channel->getName(), modeChange)); + _server->log("Applying mode I: " + std::string(adding ? "Setting invite-only" : "Removing invite-only"), GREEN); + channel->setInviteOnly(adding); + } } -void ModeHandler::applyModeK(Client *client, Channel* channel, bool adding, const std::string& argument) +void ModeHandler::applyModeK(Client *client, Channel *channel, bool adding, const std::string &argument) { + bool isAlreadyProtected; + + isAlreadyProtected = !channel->getKey().empty(); if (adding) { + if (isAlreadyProtected) + { + _server->sendToClient(client->getFd(), ERR_KEYSET(client, channel->getName())); + _server->log("Mode +k error: Channel already has a key set", RED); + return; + } if (argument.empty()) { _server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "MODE +k")); @@ -193,11 +211,19 @@ void ModeHandler::applyModeK(Client *client, Channel* channel, bool adding, cons _server->log("Invalid key for mode +k: contains spaces", RED); return; } + _server->sendToClient(client->getFd(), MODEACCEPTMESSAGE(client, channel->getName(), "+k " + argument)); _server->log("Applying mode K: Setting key to " + argument, GREEN); channel->setKey(argument); } else { + if (!isAlreadyProtected) + { + _server->sendToClient(client->getFd(), ERR_LINKSET(client, channel->getName())); + _server->log("Mode -k error: No key to remove", RED); + return; + } + _server->sendToClient(client->getFd(), MODEACCEPTMESSAGE(client, channel->getName(), "-k")); _server->log("Applying mode K: Removing key", RED); channel->setKey(""); } @@ -205,8 +231,16 @@ void ModeHandler::applyModeK(Client *client, Channel* channel, bool adding, cons void ModeHandler::applyModeT(Channel* channel, bool adding) { - _server->log("Applying mode T: " + std::string(adding ? "Setting topic protection" : "Removing topic protection"), GREEN); - channel->setTopicProtection(adding); + std::string modeChange; + bool isAlreadySet; + + modeChange = adding ? "+t" : "-t"; + isAlreadySet = channel->isInviteOnly() == adding; + if (!isAlreadySet) + { + _server->log("Applying mode T: " + std::string(adding ? "Setting topic protection" : "Removing topic protection"), GREEN); + channel->setTopicProtection(adding); + } } void ModeHandler::applyModeO(Client* client, Channel* channel, bool adding, const std::string& argument) diff --git a/ft_irc3/src/Server.cpp b/ft_irc3/src/Server.cpp index 5e4439c..1987761 100644 --- a/ft_irc3/src/Server.cpp +++ b/ft_irc3/src/Server.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */ -/* Updated: 2024/06/01 19:16:36 by fgras-ca ### ########.fr */ +/* Updated: 2024/06/05 10:18:02 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -218,16 +218,6 @@ Channel* Server::getChannelByName(const std::string &name) return NULL; } -void Server::sendChannelListToClient(Client *client) -{ - std::map &channels = getChannels(); - for (std::map::iterator it = channels.begin(); it != channels.end(); ++it) - { - sendToClient(client->getFd(), RPL_LIST(client, it->first, it->second->getClients().size(), "Existing channel")); - } - sendToClient(client->getFd(), RPL_LISTEND(client)); -} - bool Server::MatchFd(const pollfd& pfd, int clientFd) { return pfd.fd == clientFd; @@ -255,4 +245,4 @@ void Server::disconnectClient(int clientFd) std::ostringstream oss; oss << "Client disconnected: " << clientFd; log(oss.str(), YELLOW); -} +} \ No newline at end of file