Merge pull request #19 from EniumRaphael/raph

Raph
This commit is contained in:
Raphaël 2025-06-17 16:02:14 +00:00 committed by GitHub
commit 0e0d2137a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 157 additions and 32 deletions

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */ /* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/20 22:18:17 by rparodi #+# #+# */ /* Created: 2025/05/20 22:18:17 by rparodi #+# #+# */
/* Updated: 2025/05/26 22:54:58 by rparodi ### ########.fr */ /* Updated: 2025/06/17 17:52:19 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -22,6 +22,8 @@ class Channel {
std::string _password; std::string _password;
std::string _topic; std::string _topic;
User *_owner; User *_owner;
bool _needInvite;
size_t _maxUsers;
std::list<User *> _operators; std::list<User *> _operators;
std::list<User *> _users; std::list<User *> _users;
std::list<User *> _invited; std::list<User *> _invited;
@ -29,15 +31,21 @@ class Channel {
// getters // getters
std::string getName() const; std::string getName() const;
std::string getTopic() const; std::string getTopic() const;
size_t getMaxUsers() const;
User *getOwner() const; User *getOwner() const;
std::list<User *> getOperators() const; std::list<User *> getOperators() const;
std::list<User *> getUsers() const; std::list<User *> getUsers() const;
std::list<User *> getInvited() const; std::list<User *> getInvited() const;
std::string getPassword() const;
bool isOperator(User *user) const; bool isOperator(User *user) const;
bool isUserInChannel(User *user) const; bool isUserInChannel(User *user) const;
bool getNeedInvite() const;
// setters // setters
void setMaxUser(size_t args);
void setNeedInvite(bool toSet);
void setTopic(const std::string &topic); void setTopic(const std::string &topic);
void setPassword(const std::string &newPass);
void addOperator(User *user); void addOperator(User *user);
void addUser(User *user); void addUser(User *user);
void removeUser(User *user); void removeUser(User *user);

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */ /* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/24 17:17:31 by rparodi #+# #+# */ /* Created: 2025/05/24 17:17:31 by rparodi #+# #+# */
/* Updated: 2025/06/10 13:32:34 by rparodi ### ########.fr */ /* Updated: 2025/06/17 16:37:07 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -20,15 +20,14 @@
enum e_mode { enum e_mode {
ERROR_MODE = 0, ERROR_MODE = 0,
CHAN_INVITE_ONLY, CHAN_INVITE_ONLY,
CHAN_SET_TOPIC,
CHAN_SET_KEY, CHAN_SET_KEY,
CHAN_SET_LIMIT, CHAN_SET_LIMIT,
CHAN_SET_OP, CHAN_SET_OP,
CHAN_SET_TOPIC,
}; };
typedef struct s_mode { typedef struct s_mode {
std::string arguments; std::string arguments;
e_mode mode;
bool add; bool add;
bool remove; bool remove;
} t_mode; } t_mode;
@ -40,5 +39,5 @@ class cmd::Mode : public ACommand {
virtual e_code checkArgs(); virtual e_code checkArgs();
void checkMode(); void checkMode();
private: private:
std::vector<std::pair<bool, s_mode> > _mode; std::vector<std::pair<e_mode, s_mode> > _mode;
}; };

View file

@ -6,7 +6,7 @@
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */ /* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/20 22:43:24 by rparodi #+# #+# */ /* Created: 2025/05/20 22:43:24 by rparodi #+# #+# */
/* Updated: 2025/05/26 22:55:45 by rparodi ### ########.fr */ /* Updated: 2025/06/17 17:22:09 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -58,6 +58,51 @@ std::list<User *> Channel::getOperators() const {
return this->_operators; return this->_operators;
} }
/**
* @brief Get the password of the channel
*
* @return string with the password
*/
std::string Channel::getPassword() const {
return this->_password;
}
/**
* @brief Get the max user allowd to be in the channel
*
* @return size_t max user
*/
size_t Channel::getMaxUsers() const {
return this->_maxUsers;
}
/**
* @brief Get if an invitation is needed for this channel
*
* @return the boolean to check if an invite is needed for the channel
*/
bool Channel::getNeedInvite() const {
return this->_needInvite;
}
/**
* @brief Setter got the NeedInvite channel
*
* @param toSet The new value for need Invite
*/
void Channel::setNeedInvite(bool toSet) {
this->_needInvite = toSet;
}
/**
* @brief Setter for the Max User for the channel
*
* @param arg the new number (integer / long)
*/
void Channel::setMaxUser(size_t arg) {
this->_maxUsers = arg;
}
/** /**
* @brief Get the list of the Invited in the channel * @brief Get the list of the Invited in the channel
* *
@ -106,6 +151,15 @@ void Channel::setTopic(const std::string &topic) {
this->_topic = topic; this->_topic = topic;
} }
/**
* @brief Setter for the Channel's password
*
* @param newPass the new password to set
*/
void Channel::setPassword(const std::string &newPass) {
this->_password = newPass;
}
/** /**
* @brief Setter to set a new operator in the channel * @brief Setter to set a new operator in the channel
* *

View file

@ -6,7 +6,7 @@
/* By: sben-tay <sben-tay@student.42.fr> +#+ +:+ +#+ */ /* By: sben-tay <sben-tay@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */
/* Updated: 2025/06/12 13:24:27 by sben-tay ### ########.fr */ /* Updated: 2025/06/17 18:00:26 by rparodi ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -14,6 +14,8 @@
#include "commands.hpp" #include "commands.hpp"
#include "core.hpp" #include "core.hpp"
#include "logs.hpp" #include "logs.hpp"
#include <cerrno>
#include <cstdlib>
#include <utility> #include <utility>
using namespace cmd; using namespace cmd;
@ -28,41 +30,41 @@ void Mode::checkMode() {
if (flags.empty() || (flags[0] != '+' && flags[0] != '-')) if (flags.empty() || (flags[0] != '+' && flags[0] != '-'))
{ {
m.mode = ERROR_MODE; m.add = false;
m.remove = false;
return; return;
} }
bool add = (flags[0] == '+'); bool add = (flags[0] == '+');
for (size_t i = 1; i < flags.size(); ++i) for (size_t i = 1; i < flags.size(); ++i)
{ {
e_mode tmp = ERROR_MODE;
s_mode m; s_mode m;
m.mode = ERROR_MODE;
m.add = add; m.add = add;
m.remove = !add; m.remove = !add;
m.arguments.clear(); m.arguments.clear();
switch (flags[i]) switch (flags[i])
{ {
case 'i': case 'i':
m.mode = CHAN_INVITE_ONLY; tmp = CHAN_INVITE_ONLY;
break; break;
case 't': case 't':
m.mode = CHAN_SET_TOPIC; tmp = CHAN_SET_TOPIC;
break; break;
case 'k': case 'k':
m.mode = CHAN_SET_KEY; tmp = CHAN_SET_KEY;
break; break;
case 'l': case 'l':
m.mode = CHAN_SET_LIMIT; tmp = CHAN_SET_LIMIT;
break; break;
case 'o': case 'o':
m.mode = CHAN_SET_OP; tmp = CHAN_SET_OP;
break; break;
default : default :
m.mode = ERROR_MODE;
break; break;
} }
if ((m.mode == CHAN_SET_KEY || m.mode == CHAN_SET_LIMIT || m.mode == CHAN_SET_OP) && argIndex < _args.size()) if ((this->_mode.back().first == CHAN_SET_KEY || this->_mode.back().first == CHAN_SET_LIMIT || this->_mode.back().first == CHAN_SET_OP) && argIndex < _args.size())
m.arguments = _args[argIndex++]; m.arguments = _args[argIndex++];
this->_mode.push_back(std::make_pair(true, m)); this->_mode.push_back(std::make_pair(tmp, m));
} }
} }
@ -72,34 +74,34 @@ void Mode::checkMode() {
* @return return the e_code if there is an error else return _PARSING_OK * @return return the e_code if there is an error else return _PARSING_OK
*/ */
e_code Mode::checkArgs() { e_code Mode::checkArgs() {
if (_args.size() < 2) if (this->_args.size() < 2)
return ERR_NEEDMOREPARAMS; return ERR_NEEDMOREPARAMS;
if (_args.at(1).at(0) != '#') { if (this->_args.at(1).at(0) != '#') {
WARNING_MSG("Invalid channel name for INVITE command"); WARNING_MSG("Invalid channel name for INVITE command");
INFO_MSG("Channel names must start with a '#' character"); INFO_MSG("Channel names must start with a '#' character");
return ERR_NOSUCHCHANNEL; return ERR_NOSUCHCHANNEL;
} else } else
_args.at(1).erase(0, 1); this->_args.at(1).erase(0, 1);
if (_cTarget == NULL) { if (this->_cTarget == NULL) {
WARNING_MSG("Channel not found for INVITE command"); WARNING_MSG("Channel not found for INVITE command");
INFO_MSG("You can only invite users to channels you are in"); INFO_MSG("You can only invite users to channels you are in");
return ERR_NOSUCHCHANNEL; return ERR_NOSUCHCHANNEL;
} }
if (_args.size() == 2) { if (this->_args.size() == 2) {
return RPL_CHANNELMODEIS; return RPL_CHANNELMODEIS;
} }
checkMode(); checkMode();
if (_mode.empty()) if (this->_mode.empty())
return ERR_UNKNOWNMODE; return ERR_UNKNOWNMODE;
for (size_t i = 0; i < _mode.size(); ++i) for (size_t i = 0; i < this->_mode.size(); ++i)
{ {
const s_mode &m = _mode[i].second; const e_mode &ret = this->_mode[i].first;
if (m.mode == ERROR_MODE) if (ret == ERROR_MODE)
return ERR_UNKNOWNMODE; return ERR_UNKNOWNMODE;
if (m.mode == CHAN_SET_KEY || m.mode == CHAN_SET_LIMIT || m.mode == CHAN_SET_OP) if ((ret == CHAN_SET_KEY && this->_mode[i].second.add) || (ret == CHAN_SET_TOPIC && this->_mode[i].second.add) || (ret == CHAN_SET_LIMIT && this->_mode[i].second.add) || ret == CHAN_SET_OP)
if (m.arguments.empty()) if (this->_mode[i].second.arguments.empty())
return ERR_NEEDMOREPARAMS; return ERR_NEEDMOREPARAMS;
if (searchList(_cTarget->getOperators(), _sender->getName()) != NULL) { if (searchList(this->_cTarget->getOperators(), this->_sender->getName()) != NULL) {
WARNING_MSG("You are not an operator in the channel for INVITE command"); WARNING_MSG("You are not an operator in the channel for INVITE command");
return ERR_CHANOPRIVSNEEDED; return ERR_CHANOPRIVSNEEDED;
} }
@ -108,13 +110,75 @@ e_code Mode::checkArgs() {
} }
/** /**
* @brief Execute the invite command * @brief Execute the mode command
* @note To invite a peapol to join a channel (from an operator) * @note To manipulate de moderation of a channel
*/ */
void Mode::execute() { void Mode::execute() {
if (checkArgs() != _PARSING_OK) { if (checkArgs() != _PARSING_OK) {
ERROR_MSG("Invalid arguments for INVITE command (see warning message)"); ERROR_MSG("Invalid arguments for INVITE command (see warning message)");
return; return;
} }
// check how the com if (searchList(this->_cTarget->getOperators(), this->_sender->getName()) == NULL) {
DEBUG_MSG("send is not an operator for MODE COMMAND");
}
for (size_t i = 0; i < this->_mode.size(); ++i) {
size_t tmp;
switch (this->_mode[i].first) {
case CHAN_INVITE_ONLY:
if (this->_mode[i].second.add) {
if (this->_cTarget->getNeedInvite() == true) {
DEBUG_MSG("Already as invite only");
}
this->_cTarget->setNeedInvite(true);
} else if (this->_mode[i].second.remove) {
if (this->_cTarget->getNeedInvite() == false) {
DEBUG_MSG("Already as not invite only");
}
this->_cTarget->setNeedInvite(false);
}
break;
case CHAN_SET_KEY:
if (this->_mode[i].second.add)
this->_cTarget->setPassword(this->_mode[i].second.arguments);
else if (this->_mode[i].second.remove)
this->_cTarget->setPassword("");
break;
case CHAN_SET_LIMIT:
if (this->_mode[i].second.add) {
errno = 0;
tmp = strtol(this->_mode[i].second.arguments.c_str(), NULL, 10);
if (tmp <= 0 || (this->_cTarget->getNeedInvite() && tmp >= this->_cTarget->getUsers().size()) || errno != ERANGE) {
DEBUG_MSG("Overflow / negative number on mode +l abort");
return;
}
this->_cTarget->setMaxUser(tmp);
} else if (this->_mode[i].second.remove) {
this->_cTarget->setMaxUser(0);
}
break;
case CHAN_SET_OP:
this->_uTarget = searchList(this->_cTarget->getUsers(), this->_mode[i].second.arguments);
if (this->_uTarget == NULL)
DEBUG_MSG("USER NOT FOUND");
if (this->_mode[i].second.add) {
this->_cTarget->getOperators().push_back(this->_uTarget);
} else if (this->_mode[i].second.add) {
if (searchList(this->_cTarget->getOperators(), this->_mode[i].second.arguments) == NULL) {
DEBUG_MSG("NOT OPERATOR");
} else {
this->_cTarget->getOperators().remove(this->_uTarget);
}
}
break;
case CHAN_SET_TOPIC:
if (this->_mode[i].second.add) {
this->_cTarget->setTopic(this->_mode[i].second.arguments);
} else if (this->_mode[i].second.remove) {
this->_cTarget->setTopic("");
}
break;
default:
return;
}
}
} }