diff --git a/ft_irc3/includes/Channel.hpp b/ft_irc3/includes/Channel.hpp index fb1276f..623f7b8 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/05/21 19:26:51 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 11:13:12 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ #include #include #include +#include #include "RPL.hpp" #include "Client.hpp" @@ -38,13 +39,33 @@ public: const std::vector &getClients() const; void addOperator(Client *client); bool isOperator(Client *client) const; - bool hasClient(Client *client) const; // Ajouté - void broadcast(const std::string &message, Client *_client, Server *_server); // Ajouté + bool hasClient(Client *client) const; + void broadcast(const std::string &message, Client *_client, Server *_server); + + // Ajouts + bool isBanned(Client *client) const; + bool isFull() const; + bool isInviteOnly() const; + bool isInvited(Client *client) const; + bool checkKey(const std::string &key) const; + const std::string &getTopic() const; + const std::string &getTopicSetter() const; + time_t getTopicTime() const; + void setTopic(const std::string &topic, const std::string &setter); private: std::string _name; std::vector _clients; std::vector _operators; + std::set _bannedClients; + std::set _invitedClients; + std::string _key; + std::string _topic; + std::string _topicSetter; + time_t _topicTime; + size_t _clientLimit; + bool _inviteOnly; }; #endif // CHANNEL_HPP + diff --git a/ft_irc3/includes/Join.hpp b/ft_irc3/includes/Join.hpp index d48ea70..6dd9449 100644 --- a/ft_irc3/includes/Join.hpp +++ b/ft_irc3/includes/Join.hpp @@ -6,28 +6,26 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/21 19:51:08 by fgras-ca #+# #+# */ -/* Updated: 2024/05/21 20:13:15 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 11:09:22 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef JOIN_HPP #define JOIN_HPP -#include "Server.hpp" +#include #include "Client.hpp" +#include "Server.hpp" #include "Channel.hpp" #include "RPL.hpp" -class Server; -class Client; -class Channel; - class JoinHandler { public: void handleJoinCommand(Client *client, const std::string &channelName, Server *server); private: + void sendJoinSuccess(Client *client, Channel *channel, Server *server); std::string getUsersList(Channel *channel); }; diff --git a/ft_irc3/src/Channel.cpp b/ft_irc3/src/Channel.cpp index 82b91b4..86d739e 100644 --- a/ft_irc3/src/Channel.cpp +++ b/ft_irc3/src/Channel.cpp @@ -6,13 +6,14 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 12:42:57 by fgras-ca #+# #+# */ -/* Updated: 2024/05/21 19:27:42 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 13:06:02 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ #include "Channel.hpp" -Channel::Channel(const std::string &name) : _name(name) {} +Channel::Channel(const std::string &name) + : _name(name), _clients(), _operators(), _bannedClients(), _invitedClients(), _key(""), _topic(""), _topicSetter(""), _topicTime(0), _clientLimit(50), _inviteOnly(false) {} Channel::~Channel() {} @@ -56,14 +57,63 @@ bool Channel::hasClient(Client *client) const return std::find(_clients.begin(), _clients.end(), client) != _clients.end(); } -void Channel::broadcast(const std::string &message, Client *_client, Server *server) +void Channel::broadcast(const std::string &message, Client *_client, Server *_server) { for (std::vector::iterator it = _clients.begin(); it != _clients.end(); ++it) { if (*it != _client) { // Send message to each client except the sender - server->sendToClient((*it)->getFd(), message); + _server->sendToClient((*it)->getFd(), message); } } } + +bool Channel::isBanned(Client *client) const +{ + return _bannedClients.find(client) != _bannedClients.end(); +} + +bool Channel::isFull() const +{ + return _clients.size() >= _clientLimit; +} + +bool Channel::isInviteOnly() const +{ + return _inviteOnly; +} + +bool Channel::isInvited(Client *client) const +{ + return _invitedClients.find(client) != _invitedClients.end(); +} + +bool Channel::checkKey(const std::string &key) const +{ + return _key.empty() || _key == key; +} + +const std::string &Channel::getTopic() const +{ + return _topic; +} + +const std::string &Channel::getTopicSetter() const +{ + return _topicSetter; +} + +time_t Channel::getTopicTime() const +{ + return _topicTime; +} + +void Channel::setTopic(const std::string &topic, const std::string &setter) +{ + _topic = topic; + _topicSetter = setter; + _topicTime = std::time(NULL); +} + + diff --git a/ft_irc3/src/CommandHandler.cpp b/ft_irc3/src/CommandHandler.cpp index 633eae2..53e922e 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/05/21 20:24:52 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 13:07:17 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/ft_irc3/src/Join.cpp b/ft_irc3/src/Join.cpp index da1bca5..d38b3d6 100644 --- a/ft_irc3/src/Join.cpp +++ b/ft_irc3/src/Join.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/21 19:51:31 by fgras-ca #+# #+# */ -/* Updated: 2024/05/21 20:13:30 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 13:07:53 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,34 +14,66 @@ void JoinHandler::handleJoinCommand(Client *client, const std::string &channelName, Server *server) { + if (channelName.empty()) { + server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "JOIN")); + return; + } + std::map &channels = server->getChannels(); Channel *channel; - if (channels.find(channelName) == channels.end()) - { + + if (channels.find(channelName) == channels.end()) { channel = new Channel(channelName); channels[channelName] = channel; - } - else - { + } else { channel = channels[channelName]; } + if (channel->isBanned(client)) { + server->sendToClient(client->getFd(), ERR_BANNEDFROMCHAN(client, channelName)); + return; + } + + if (channel->isFull()) { + server->sendToClient(client->getFd(), ERR_CHANNELISFULL(client, channelName)); + return; + } + + if (channel->isInviteOnly() && !channel->isInvited(client)) { + server->sendToClient(client->getFd(), ERR_INVITEONLYCHAN(client, channelName)); + return; + } + channel->addClient(client); - std::string joinMessage = ":" + client->getNickname() + " JOIN " + channelName + "\r\n"; + sendJoinSuccess(client, channel, server); +} + +void JoinHandler::sendJoinSuccess(Client *client, Channel *channel, Server *server) +{ + std::string joinMessage = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n"; server->sendToClient(client->getFd(), joinMessage); + if (!channel->getTopic().empty()) { + server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic())); + server->sendToClient(client->getFd(), RPL_TOPICWHOTIME(client, channel->getName(), channel->getTopicSetter(), channel->getTopicTime())); + } + std::string usersList = getUsersList(channel); server->sendToClient(client->getFd(), usersList); + + channel->broadcast(joinMessage, client, server); } std::string JoinHandler::getUsersList(Channel *channel) { std::vector clients = channel->getClients(); - std::string usersList = ":server 353 " + clients[0]->getNickname() + " = " + channel->getName() + " :"; - for (std::vector::iterator it = clients.begin(); it != clients.end(); ++it) - { - usersList += (*it)->getNickname() + " "; + std::string users; + for (std::vector::iterator it = clients.begin(); it != clients.end(); ++it) { + users += (*it)->getNickname() + " "; } - usersList += "\r\n:server 366 " + clients[0]->getNickname() + " " + channel->getName() + " :End of /NAMES list.\r\n"; - return usersList; + + std::ostringstream oss; + oss << RPL_NAMREPLY(clients[0], channel->getName(), users); + oss << RPL_ENDOFNAMES(clients[0], channel->getName()); + return oss.str(); } diff --git a/ft_irc3/src/Who.cpp b/ft_irc3/src/Who.cpp index 2ca487a..e26c9f9 100644 --- a/ft_irc3/src/Who.cpp +++ b/ft_irc3/src/Who.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/17 16:09:20 by fgras-ca #+# #+# */ -/* Updated: 2024/05/21 18:03:56 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/28 13:08:30 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */