diff --git a/Makefile b/Makefile index 9831d4c..c16f1b5 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: sben-tay +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2025/05/02 15:40:00 by rparodi #+# #+# # -# Updated: 2025/06/17 17:06:04 by sben-tay ### ########.fr # +# Updated: 2025/06/19 11:29:58 by rparodi ### ########.fr # # # # **************************************************************************** # @@ -39,6 +39,7 @@ SRC = sources/channel/channel.cpp \ sources/commands/ping.cpp \ sources/commands/pong.cpp \ sources/commands/privmsg.cpp \ + sources/commands/topic.cpp \ sources/commands/userCmd.cpp \ sources/commands/whois.cpp \ sources/commands/whowas.cpp \ diff --git a/include/channel.hpp b/include/channel.hpp index f2e30d6..bab998d 100644 --- a/include/channel.hpp +++ b/include/channel.hpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/20 22:18:17 by rparodi #+# #+# */ -/* Updated: 2025/06/19 01:15:59 by sben-tay ### ########.fr */ +/* Updated: 2025/06/19 13:42:03 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,7 +26,7 @@ class Channel { std::string getTopic() const; size_t getMaxUsers() const; User *getOwner() const; - std::list getOperators() const; + std::list& getOperators(); std::list& getUsers(); std::list getInvited() const; std::string getPassword() const; @@ -43,6 +43,8 @@ class Channel { void setPassword(const std::string &newPass); void addOperator(User *user); void addUser(User *user); + void addInvited(User *user); + bool isInvited(User *user) const; void removeUser(User *user); void removeOperator(User *user); diff --git a/include/commands.hpp b/include/commands.hpp index 438c8db..ed7434c 100644 --- a/include/commands.hpp +++ b/include/commands.hpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/20 23:31:58 by rparodi #+# #+# */ -/* Updated: 2025/06/17 23:14:07 by sben-tay ### ########.fr */ +/* Updated: 2025/06/19 13:00:30 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,7 +23,7 @@ namespace cmd { void dispatch(User *user, Channel *channel, Server *server, std::string &line); - std::vector split(std::string &line); + std::vector split(std::string &line, char sep); template T searchList(const std::list &list, const std::string &name); diff --git a/sources/channel/channel.cpp b/sources/channel/channel.cpp index 8aa492c..0480080 100644 --- a/sources/channel/channel.cpp +++ b/sources/channel/channel.cpp @@ -6,15 +6,19 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/20 22:43:24 by rparodi #+# #+# */ -/* Updated: 2025/06/19 01:16:03 by sben-tay ### ########.fr */ +/* Updated: 2025/06/19 13:58:39 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ #include "channel.hpp" #include +#include -Channel::Channel(const std::string &name, User *owner, size_t maxUsers, bool needInvite) - :_name(name), _owner(owner), _maxUsers(maxUsers), _needInvite(needInvite) {} +Channel::Channel(const std::string &name, User *owner, size_t maxUsers, bool needInvite) : _name(name), _owner(owner), _maxUsers(maxUsers), _needInvite(needInvite) { + this->_protectTopic = false; + this->_maxUsers = ~0; + this->_topic = ""; +} /** * @brief Get the name of the channel @@ -57,7 +61,7 @@ std::list& Channel::getUsers() { * * @return list of Operators in the channel */ -std::list Channel::getOperators() const { +std::list& Channel::getOperators() { return this->_operators; } @@ -239,3 +243,18 @@ void Channel::sendAllClientInAChannel(const std::string &toSend, User *exclude) (*it)->appendToWriteBuffer(toSend); } } + +void Channel::addInvited(User *user) { + if (user && !isInvited(user)) + _invited.push_back(user); +} + +bool Channel::isInvited(User *user) const { + if (user) + { + if (std::find(_invited.begin(), _invited.end(), user) != _invited.end()) + return true; + } + std::cerr << user->getName() << " is not invited to the channel " << this->_name << std::endl; + return false; +} diff --git a/sources/commands/commands.cpp b/sources/commands/commands.cpp index a26543a..99c4c3c 100644 --- a/sources/commands/commands.cpp +++ b/sources/commands/commands.cpp @@ -6,25 +6,26 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 16:11:56 by rparodi #+# #+# */ -/* Updated: 2025/06/10 16:25:57 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 13:02:11 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ #include "commands.hpp" #include -#include "join.hpp" -#include "privmsg.hpp" -#include "nick.hpp" -#include "invite.hpp" -#include "list.hpp" #include "cap.hpp" -#include "modes.hpp" -#include "ping.hpp" -#include "notice.hpp" +#include "invite.hpp" +#include "join.hpp" #include "kick.hpp" -#include "userCmd.hpp" -#include "pass.hpp" +#include "list.hpp" +#include "modes.hpp" +#include "nick.hpp" +#include "notice.hpp" #include "part.hpp" +#include "pass.hpp" +#include "ping.hpp" +#include "privmsg.hpp" +#include "topic.hpp" +#include "userCmd.hpp" #include "whois.hpp" #include "whowas.hpp" #include @@ -37,7 +38,7 @@ * @param line line send by the user */ -std::vector cmd::split(std::string &line) { +std::vector cmd::split(std::string &line, char sep) { std::vector args; size_t start = 0; size_t end; @@ -48,7 +49,7 @@ std::vector cmd::split(std::string &line) { args.push_back(arg); break; } - end = line.find(' ', start); + end = line.find(sep, start); if (end == std::string::npos) end = line.length(); std::string arg = line.substr(start, end - start); @@ -71,7 +72,7 @@ std::vector cmd::split(std::string &line) { * @param line input line from the user */ void cmd::dispatch(::User *user, Channel *channel, Server *server, std::string &line) { - std::vector args = cmd::split(line); + std::vector args = cmd::split(line, ' '); if (args.empty()) { DEBUG_MSG("Empty line"); return; @@ -139,6 +140,11 @@ void cmd::dispatch(::User *user, Channel *channel, Server *server, std::string & userCmd(user, channel, server, line).execute(); } break; + case 't': + if (command_name == "topic") { + Topic(user, channel, server, line).execute(); + } + break; case 'w': if (command_name == "whois") { Whois(user, channel, server, line).execute(); @@ -157,7 +163,7 @@ void cmd::dispatch(::User *user, Channel *channel, Server *server, std::string & cmd::ACommand::ACommand(::User *user, ::Channel *channel, ::Server *server, std::string &line) : _sender(user), _channel(channel), _server(server) { DEBUG_MSG("ACommand constructor called"); - _args = split(line); + _args = split(line, ' '); _command = _args.at(0); _channels = server->getChannelsList(); _users = server->getUsersList(); diff --git a/sources/commands/invite.cpp b/sources/commands/invite.cpp index a4a3545..39994ce 100644 --- a/sources/commands/invite.cpp +++ b/sources/commands/invite.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:52:35 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 13:53:17 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,14 +28,13 @@ e_code Invite::checkArgs() { return ERR_NOSUCHCHANNEL; } else _args.at(1).erase(0, 1); - _cTarget = searchList(_channels, _args.at(1)); + _cTarget = searchList(_server->getChannelsList(), _args.at(1)); if (_cTarget == NULL) { WARNING_MSG("Channel not found for INVITE command"); INFO_MSG("You can only invite users to channels you are in"); return ERR_NOSUCHCHANNEL; - } else - _args.at(1).erase(0, 1); - if (searchList(_cTarget->getOperators(), _sender->getName()) != NULL) { + } + if (searchList(_cTarget->getOperators(), _sender->getName()) == NULL) { WARNING_MSG("You are not an operator in the channel for INVITE command"); return ERR_NOPRIVILEGES; } @@ -61,10 +60,18 @@ e_code Invite::checkArgs() { * @brief Execute the invite command * @note To invite a peapol to join a channel (from an operator) */ + void Invite::execute() { if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for INVITE command (see warning message)"); return; } - // check how the com + + _cTarget->addInvited(_uTarget); + + std::string msgToInvited = ":" + _sender->getPrefix() + " INVITE " + _uTarget->getNickname() + " #" + _cTarget->getName() + "\r\n"; + _uTarget->appendToWriteBuffer(msgToInvited); + + std::string msg341 = ":localhost 341 " + _sender->getNickname() + " " + _uTarget->getNickname() + " #" + _cTarget->getName() + "\r\n"; + _sender->appendToWriteBuffer(msg341); } diff --git a/sources/commands/list.cpp b/sources/commands/list.cpp index 026df47..104cf2b 100644 --- a/sources/commands/list.cpp +++ b/sources/commands/list.cpp @@ -6,18 +6,20 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:52:13 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 13:50:09 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ #include "list.hpp" +#include "channel.hpp" #include "commands.hpp" #include "logs.hpp" +#include using namespace cmd; e_code List::checkArgs() { - if (_args.size() < 3) { + if (_args.size() < 1) { std::string msg461 = ":localhost 461 " + this->_sender->getNickname() + " " + this->_command + " :Not enough parameters\r\n"; this->_sender->appendToWriteBuffer(msg461); return ERR_NEEDMOREPARAMS; @@ -27,19 +29,15 @@ e_code List::checkArgs() { INFO_MSG("You can only LIST registered users"); return ERR_NOSUCHNICK; } - if (_args.at(1).at(0) != '#') { - WARNING_MSG("Invalid channel name for LIST command"); - INFO_MSG("Channel names must start with a '#' character"); - return ERR_NOSUCHCHANNEL; - } else - _args.at(1).erase(0, 1); - _cTarget = searchList(_channels, _args.at(1)); - if (_cTarget == NULL) { - WARNING_MSG("Channel not found for LIST command"); - INFO_MSG("You can only LIST users to channels you are in"); - return ERR_NOSUCHCHANNEL; - } else - _args.at(1).erase(0, 1); + if (this->_args.size() == 2) { + std::string tmp_line = this->_args.back(); + this->_args.pop_back(); + std::vector tmp = split(tmp_line, ','); + for (size_t i = 0; i < tmp.size(); i++) { + this->_args.push_back(tmp.back()); + tmp.pop_back(); + } + } return _PARSING_OK; } @@ -52,5 +50,49 @@ void List::execute() { ERROR_MSG("Invalid arguments for LIST command (see warning message)"); return; } - // check how the com + std::string msg321 = ":localhost 321 " + _sender->getNickname() + " Channel :Users Name\r\n"; + this->_sender->appendToWriteBuffer(msg321); + if (this->_args.size() > 1) { + std::vector vec_tmp; + bool to_print = true; + for (size_t i = 1; i < this->_args.size(); ++i) { + DEBUG_MSG("[" << i << "] " << this->_args[i]); + if (this->_args[i][0] == '#') + this->_args[i].erase(0, 1); + else { + WARNING_MSG("Thanks to check if all the Channel have an '#' at the start of the name !"); + to_print = false; + break; + } + this->_cTarget = searchList(this->_server->getChannelsList(), this->_args[i]); + if (this->_cTarget == NULL) { + WARNING_MSG("Channel not found, aborting the command !"); + to_print = false; + break; + } else { + std::ostringstream tmp; + tmp << ":localhost 322 " << _sender->getNickname() + << " " << this->_cTarget->getName() << " " << + this->_cTarget->getUsers().size() << + " :" << this->_cTarget->getTopic() << "\r\n"; + vec_tmp.push_back(tmp.str()); + } + } + if (to_print) { + for (size_t j = 0; j < vec_tmp.size(); j++) { + DEBUG_MSG(vec_tmp[j]); + this->_sender->appendToWriteBuffer(vec_tmp[j]); + } + } + } else { + for (std::list::iterator it = this->_server->getChannelsList().begin(); it != this->_server->getChannelsList().end(); it++) { + std::ostringstream msg322; msg322 << ":localhost 322 " << _sender->getNickname() + << " " << (*it)->getName() << " " << + (*it)->getUsers().size() << + " :" << (*it)->getTopic() << "\r\n"; + this->_sender->appendToWriteBuffer(msg322.str()); + } + } + std::string msg323 = ":localhost 323 " + _sender->getNickname() + " :End of /LIST\r\n"; + this->_sender->appendToWriteBuffer(msg323); } diff --git a/sources/commands/modes.cpp b/sources/commands/modes.cpp index c9be75a..d5175e5 100644 --- a/sources/commands/modes.cpp +++ b/sources/commands/modes.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:53:44 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 14:02:08 by rparodi ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,6 +85,7 @@ e_code Mode::checkArgs() { return ERR_NOSUCHCHANNEL; } else this->_args.at(1).erase(0, 1); + _cTarget = searchList(_server->getChannelsList(), _args.at(1)); if (this->_cTarget == NULL) { WARNING_MSG("Channel not found for INVITE command"); INFO_MSG("You can only invite users to channels you are in");