From 0fa9a1b3ea9807ff84bd2c2df4d4f85fb0a54498 Mon Sep 17 00:00:00 2001 From: Ladebeze66 Date: Tue, 28 May 2024 14:15:39 +0200 Subject: [PATCH] miseajour --- ft_irc3/includes/Client.hpp | 11 +- ft_irc3/includes/RPL.hpp | 40 +++++-- ft_irc3/{motd => motd.txt} | 0 ft_irc3/src/AdditionalCommands.cpp | 166 +++++++++++++++++------------ ft_irc3/src/Client.cpp | 103 ++++-------------- 5 files changed, 160 insertions(+), 160 deletions(-) rename ft_irc3/{motd => motd.txt} (100%) diff --git a/ft_irc3/includes/Client.hpp b/ft_irc3/includes/Client.hpp index 15d589b..350fb8f 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/05/21 18:03:09 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 14:09:24 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,6 +35,12 @@ public: void authenticate(); bool isOperator() const; void setOperator(bool isOperator); + + // Ajout des méthodes pour la gestion du statut "away" + bool isAway() const; + const std::string &getAwayMessage() const; + void setAwayMessage(const std::string &message); + void setAway(bool away); private: int _fd; @@ -45,6 +51,9 @@ private: std::string _realname; bool _authenticated; bool _operator; + bool _away; + std::string _awayMessage; }; #endif // CLIENT_HPP + diff --git a/ft_irc3/includes/RPL.hpp b/ft_irc3/includes/RPL.hpp index 275f558..de8758a 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/05/28 11:20:17 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 13:56:19 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -71,6 +71,12 @@ inline std::string RPL_ISUPPORT(Client* client, const std::string& tokens) { return oss.str(); } +inline std::string RPL_AWAY(int clientFd, const std::string& target, const std::string& message) { + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 301 " << clientFd << " " << target << " :" << message << "\r\n"; + return oss.str(); +} + // WHOIS Command RPLs inline std::string RPL_WHOISUSER(int clientFd, Client* target) { @@ -193,6 +199,12 @@ inline std::string ERR_NOSUCHCHANNEL(int clientFd, const std::string& channel) return oss.str(); } +inline std::string ERR_CANNOTSENDTOCHAN(int clientFd, const std::string& channel) { + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 404 " << clientFd << " " << channel << " :Cannot send to channel\r\n"; + return oss.str(); +} + inline std::string ERR_TOOMANYCHANNELS(Client* client, const std::string& channel) { std::ostringstream oss; oss << ":" << SERVER_NAME << " 405 " << CLIENT_NICK(client) << " " << channel << " :You have joined too many channels\r\n"; @@ -207,6 +219,18 @@ inline std::string ERR_NOORIGIN(Client* client) return oss.str(); } +inline std::string ERR_NORECIPIENT(int clientFd, const std::string& command) { + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 411 " << clientFd << " :No recipient given (" << command << ")\r\n"; + return oss.str(); +} + +inline std::string ERR_NOTEXTTOSEND(int clientFd) { + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 412 " << clientFd << " :No text to send\r\n"; + return oss.str(); +} + inline std::string ERR_UNKNOWNCOMMAND(Client* client, const std::string& command) { std::ostringstream oss; oss << ":" << SERVER_NAME << " 421 " << CLIENT_NICK(client) << " " << command << " :Unknown command\r\n"; @@ -241,6 +265,12 @@ inline std::string ERR_NICKNAMEINUSE(Client* client, const std::string& nickname return oss.str(); } +inline std::string ERR_NOTONCHANNEL(int clientFd, const std::string& channel) { + std::ostringstream oss; + oss << ":" << SERVER_NAME << " 442 " << clientFd << " " << channel << " :You're not on that channel\r\n"; + return oss.str(); +} + inline std::string ERR_NOTREGISTERED(Client* client) { std::ostringstream oss; @@ -331,14 +361,6 @@ inline std::string RPL_CAP(int clientFd, const std::string& subcommand, const st return oss.str(); } -// ERR_NOTREGISTERED -inline std::string ERR_NOTREGISTERED(int clientFd) -{ - std::ostringstream oss; - oss << ":" << SERVER_NAME << " 451 " << clientFd << " :You have not registered\r\n"; - return oss.str(); -} - inline std::string RPL_PASSACCEPTED(Client* client) { std::ostringstream oss; diff --git a/ft_irc3/motd b/ft_irc3/motd.txt similarity index 100% rename from ft_irc3/motd rename to ft_irc3/motd.txt diff --git a/ft_irc3/src/AdditionalCommands.cpp b/ft_irc3/src/AdditionalCommands.cpp index 6790b51..e465e0a 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/05/21 20:22:22 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 13:56:56 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,85 +59,115 @@ void AdditionalCommands::broadcastChannelList(Client *client, Server *server) // Fonction pour gérer la commande PART void AdditionalCommands::handlePartCommand(Server *server, Client *client, const std::string &command) { - std::istringstream iss(command); - std::string cmd, channelName; - iss >> cmd >> channelName; + std::istringstream iss(command); + std::string cmd, channelNames; + iss >> cmd >> channelNames; - std::map &channels = server->getChannels(); + if (channelNames.empty()) { + server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PART")); + return; + } - if (channels.find(channelName) != channels.end()) - { - Channel *channel = channels[channelName]; - channel->removeClient(client); + std::vector channels = split(channelNames, ","); + std::map &channelMap = server->getChannels(); - std::stringstream partMsg; - partMsg << ":" << client->getNickname() << " PART " << channelName << "\r\n"; - server->sendToClient(client->getFd(), partMsg.str()); + for (size_t i = 0; i < channels.size(); ++i) { + std::string &channelName = channels[i]; + if (channelMap.find(channelName) == channelMap.end()) { + server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client->getFd(), channelName)); + continue; + } - if (channel->isEmpty()) - { - delete channel; - channels.erase(channelName); - } + Channel *channel = channelMap[channelName]; + if (!channel->hasClient(client)) { + server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client->getFd(), channelName)); + continue; + } - server->log("Client " + client->getNickname() + " left channel " + channelName, MAGENTA); - } - else - { - std::stringstream ss; - ss << ":server 403 " << client->getNickname() << " " << channelName << " :No such channel\r\n"; - server->sendToClient(client->getFd(), ss.str()); - } + channel->removeClient(client); + + std::ostringstream partMsg; + partMsg << ":" << client->getNickname() << " PART " << channelName << "\r\n"; + server->sendToClient(client->getFd(), partMsg.str()); + + if (channel->isEmpty()) { + delete channel; + channelMap.erase(channelName); + } + + server->log("Client " + client->getNickname() + " left channel " + channelName, MAGENTA); + } } + +// Fonction pour gérer la commande PRIVMSG void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, const std::string &command) { - std::istringstream iss(command); - std::string cmd, target, message; - iss >> cmd >> target; - getline(iss, message); + std::istringstream iss(command); + std::string cmd, target, message; + iss >> cmd >> target; + getline(iss, message); - // Enlever le ':' initial dans le message si présent - if (!message.empty() && message[0] == ':') - message = message.substr(1); + // Enlever le ':' initial dans le message si présent + if (!message.empty() && message[0] == ':') + message = message.substr(1); - // Récupérer les canaux du serveur - std::map &channels = server->getChannels(); + if (target.empty()) { + server->sendToClient(client->getFd(), ERR_NORECIPIENT(client->getFd(), "PRIVMSG")); + return; + } - // Si la cible est un canal - if (channels.find(target) != channels.end()) - { - Channel *channel = channels[target]; - std::vector channelClients = channel->getClients(); + if (message.empty()) { + server->sendToClient(client->getFd(), ERR_NOTEXTTOSEND(client->getFd())); + return; + } - for (size_t i = 0; i < channelClients.size(); ++i) - { - // Envoyer le message à tous les clients du canal sauf l'émetteur - if (channelClients[i] != client) - { - std::stringstream privMsg; - privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n"; - server->sendToClient(channelClients[i]->getFd(), privMsg.str()); - } - } - } - // Si la cible est un utilisateur - else - { - Client *targetClient = server->getClientByName(target); // Utiliser getClientByName pour trouver le client par nom + // Récupérer les canaux du serveur + std::map &channels = server->getChannels(); - if (targetClient) - { - std::stringstream privMsg; - privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n"; - server->sendToClient(targetClient->getFd(), privMsg.str()); - } - else - { - // Si la cible n'est ni un canal ni un utilisateur existant, envoyer un message d'erreur - std::stringstream errorMsg; - errorMsg << ":server 401 " << client->getNickname() << " " << target << " :No such nick/channel\r\n"; - server->sendToClient(client->getFd(), errorMsg.str()); - } - } + // Si la cible est un canal + if (channels.find(target) != channels.end()) + { + Channel *channel = channels[target]; + + // Vérifier les conditions spéciales du canal (ex: ban, modération) + if (channel->isBanned(client)) { + server->sendToClient(client->getFd(), ERR_CANNOTSENDTOCHAN(client->getFd(), target)); + return; + } + + std::vector channelClients = channel->getClients(); + + for (size_t i = 0; i < channelClients.size(); ++i) + { + // Envoyer le message à tous les clients du canal sauf l'émetteur + if (channelClients[i] != client) + { + std::stringstream privMsg; + privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n"; + server->sendToClient(channelClients[i]->getFd(), privMsg.str()); + } + } + } + // Si la cible est un utilisateur + else + { + Client *targetClient = server->getClientByName(target); // Utiliser getClientByName pour trouver le client par nom + + if (targetClient) + { + std::stringstream privMsg; + privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n"; + server->sendToClient(targetClient->getFd(), privMsg.str()); + + if (targetClient->isAway()) { + server->sendToClient(client->getFd(), RPL_AWAY(client->getFd(), targetClient->getNickname(), targetClient->getAwayMessage())); + } + } + else + { + // Si la cible n'est ni un canal ni un utilisateur existant, envoyer un message d'erreur + server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client->getFd(), target)); + } + } } diff --git a/ft_irc3/src/Client.cpp b/ft_irc3/src/Client.cpp index 8216760..de47398 100644 --- a/ft_irc3/src/Client.cpp +++ b/ft_irc3/src/Client.cpp @@ -6,96 +6,35 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:17:42 by fgras-ca #+# #+# */ -/* Updated: 2024/05/19 15:38:46 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 14:10:21 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ #include "Client.hpp" Client::Client(int fd, const std::string &nickname, const std::string &user, const std::string &host, const std::string &password, const std::string &realname) - : _fd(fd), _nickname(nickname), _user(user), _host(host), _password(password), _realname(realname), _authenticated(false), _operator(false) -{ -} -int Client::getFd() const -{ - return _fd; -} - -const std::string &Client::getNickname() const -{ - return _nickname; -} - -void Client::setNickname(const std::string &nickname) -{ - _nickname = nickname; -} - -const std::string &Client::getUser() const -{ - return _user; -} - -void Client::setUser(const std::string &user) -{ - _user = user; -} - -const std::string &Client::getHost() const -{ - return _host; -} - -void Client::setHost(const std::string &host) -{ - _host = host; -} - -const std::string &Client::getPassword() const -{ - return _password; -} - -void Client::setPassword(const std::string &password) -{ - _password = password; -} - -const std::string &Client::getRealName() const -{ - return _realname; -} - -void Client::setRealName(const std::string &realname) -{ - _realname = realname; -} - -bool Client::isAuthenticated() const -{ - return _authenticated; -} - -void Client::authenticate() -{ - _authenticated = true; -} - -bool Client::isOperator() const -{ - return _operator; -} - -void Client::setOperator(bool isOperator) -{ - _operator = isOperator; -} - - - - + : _fd(fd), _nickname(nickname), _user(user), _host(host), _password(password), _realname(realname), _authenticated(false), _operator(false), _away(false) {} +int Client::getFd() const { return _fd; } +const std::string &Client::getNickname() const { return _nickname; } +void Client::setNickname(const std::string &nickname) { _nickname = nickname; } +const std::string &Client::getUser() const { return _user; } +void Client::setUser(const std::string &user) { _user = user; } +const std::string &Client::getHost() const { return _host; } +void Client::setHost(const std::string &host) { _host = host; } +const std::string &Client::getPassword() const { return _password; } +void Client::setPassword(const std::string &password) { _password = password; } +const std::string &Client::getRealName() const { return _realname; } +void Client::setRealName(const std::string &realname) { _realname = realname; } +bool Client::isAuthenticated() const { return _authenticated; } +void Client::authenticate() { _authenticated = true; } +bool Client::isOperator() const { return _operator; } +void Client::setOperator(bool isOperator) { _operator = isOperator; } +bool Client::isAway() const { return _away; } +const std::string &Client::getAwayMessage() const { return _awayMessage; } +void Client::setAwayMessage(const std::string &message) { _awayMessage = message; } +void Client::setAway(bool away) { _away = away; } /*Client::Client(int fd)