diff --git a/include/channel.hpp b/include/channel.hpp index c8dcd67..f2e30d6 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/18 12:24:15 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 01:15:59 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -47,7 +47,7 @@ class Channel { void removeOperator(User *user); // utility functions - void sendAllClientInAChannel(const std::string toSend, User *sender); + void sendAllClientInAChannel(const std::string &toSend, User *exclude = NULL); private: std::string _name; diff --git a/include/user.hpp b/include/user.hpp index a1fa57f..4cf642e 100644 --- a/include/user.hpp +++ b/include/user.hpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/20 21:57:49 by rparodi #+# #+# */ -/* Updated: 2025/06/18 01:19:32 by sben-tay ### ########.fr */ +/* Updated: 2025/06/19 02:22:55 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -70,6 +70,7 @@ class User bool hasDataToSend() const; std::string getWriteBuffer() const; void clearWriteBuffer(); + void consumeWriteBuffer(size_t len); std::string getPrefix() const; }; diff --git a/sources/channel/channel.cpp b/sources/channel/channel.cpp index c746077..8aa492c 100644 --- a/sources/channel/channel.cpp +++ b/sources/channel/channel.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/20 22:43:24 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:20:01 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 01:16:03 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -190,10 +190,17 @@ void Channel::addOperator(User *user) { * @param user to add in the channel */ void Channel::addUser(User *user) { + if (!user) { + std::cerr << "Error: Attempt to add a null user to the channel " << this->_name << std::endl; + DEBUG_MSG("Attempt to add a null user to the channel " << this->_name); + return; + } if (this->isUserInChannel(user) == false) { + DEBUG_MSG("Adding user " << user->getName() << " to channel " << this->_name); this->_users.push_back(user); } else { + DEBUG_MSG("User " << user->getName() << " is already in channel " << this->_name); std::cerr << user->getName() << " is already in the channel " << this->_name << std::endl; } } @@ -226,11 +233,9 @@ void Channel::removeOperator(User *user) { } } -void Channel::sendAllClientInAChannel(const std::string toSend, User *sender) { - for(std::list::iterator it = this->_users.begin(); it != this->_users.end(); ++it) { - if (*it == sender) { - continue; - } - (*it)->appendToWriteBuffer(toSend); - } +void Channel::sendAllClientInAChannel(const std::string &toSend, User *exclude) { + for (std::list::iterator it = _users.begin(); it != _users.end(); ++it) { + if (*it != exclude) + (*it)->appendToWriteBuffer(toSend); + } } diff --git a/sources/commands/join.cpp b/sources/commands/join.cpp index ebc4667..1613f16 100644 --- a/sources/commands/join.cpp +++ b/sources/commands/join.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:51:54 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 02:27:50 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -89,5 +89,5 @@ void Join::execute() { for (std::list::iterator it = _cTarget->getUsers().begin(); it != _cTarget->getUsers().end(); ++it) { msg353 += (*it)->getNickname() + " "; } - _cTarget->sendAllClientInAChannel(msgJoin + msg332 + msg353 + "\r\n", _sender); + _cTarget->sendAllClientInAChannel(msgJoin + msg332 + msg353 + "\r\n"); } diff --git a/sources/commands/part.cpp b/sources/commands/part.cpp index d8fde2c..6c4014d 100644 --- a/sources/commands/part.cpp +++ b/sources/commands/part.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:55:38 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 01:13:28 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,24 +19,29 @@ using namespace cmd; e_code Part::checkArgs() { if (_args.size() < 2) { + DEBUG_MSG("Not enough arguments for Part command"); std::string msg461 = ":localhost 461 " + this->_sender->getNickname() + " " + this->_command + " :Not enough parameters\r\n"; this->_sender->appendToWriteBuffer(msg461); return ERR_NEEDMOREPARAMS; } + DEBUG_MSG("Arguments size is valid for Part command"); if (_args.at(1).at(0) != '#') { + DEBUG_MSG("Invalid channel name for Part command: " << _args.at(1)); WARNING_MSG("Invalid channel name for PART command"); INFO_MSG("Channel names must start with a '#' character"); return ERR_NOSUCHCHANNEL; - } else + } else { _args.at(1).erase(0, 1); - _cTarget = searchList(_channels, _args.at(1)); + } + _cTarget = searchList(_server->getChannelsList(), _args.at(1)); if (_cTarget == NULL) { + DEBUG_MSG("Channel not found for Part command: " << _args.at(1)); WARNING_MSG("Channel not found for PART command"); INFO_MSG("You can only Part users to channels you are in"); return ERR_NOSUCHCHANNEL; - } else - _args.at(1).erase(0, 1); - if (searchList(this->_cTarget->getUsers(), this->_uTarget->getName())) { + } + if (_cTarget->isUserInChannel(_sender) == false) { + DEBUG_MSG("sender is : " << _sender->getName()); WARNING_MSG("User is not in the channel he wants to leave"); INFO_MSG("You cannot leave a channel where ur not a member"); return ERR_USERNOTINCHANNEL; @@ -48,10 +53,28 @@ e_code Part::checkArgs() { * @brief Execute the Part command * @note To leave a channel givent in parameter */ + void Part::execute() { if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for Part command (see warning message)"); return; } - // check how the com + DEBUG_MSG("EXECUTING PART COMMAND"); + + std::string msgPart = ":" + _sender->getPrefix() + " PART #" + _cTarget->getName(); + if (_args.size() > 2) + msgPart += " :" + _args.at(2); + msgPart += "\r\n"; + + _cTarget->sendAllClientInAChannel(msgPart); + _cTarget->removeUser(_sender); + _cTarget->removeOperator(_sender); + // remove invited list + + if (_cTarget->getUsers().empty()) { + std::list& allChannels = _server->getChannelsList(); + allChannels.remove(_cTarget); + delete _cTarget; + DEBUG_MSG("Channel supprimé car vide."); + } } diff --git a/sources/commands/privmsg.cpp b/sources/commands/privmsg.cpp index 16d9dbb..10c7b70 100644 --- a/sources/commands/privmsg.cpp +++ b/sources/commands/privmsg.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/18 12:51:56 by rparodi ### ########.fr */ +/* Updated: 2025/06/19 02:28:16 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -63,7 +63,7 @@ void PrivMsg::execute() { // Envoi vers un channel if (target[0] == '#') { - target.erase(0, 1); // Enlève le # + target.erase(0, 1); if (_cTarget) _cTarget->sendAllClientInAChannel(msg, _sender); // Optionnel: évite d'envoyer au sender } diff --git a/sources/core/Server.cpp b/sources/core/Server.cpp index 8ef76b7..0523a54 100644 --- a/sources/core/Server.cpp +++ b/sources/core/Server.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/13 11:11:07 by rparodi #+# #+# */ -/* Updated: 2025/06/18 01:34:56 by sben-tay ### ########.fr */ +/* Updated: 2025/06/19 02:24:05 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -126,8 +126,9 @@ void Server::start() std::cerr << "Erreur send sur fd " << fd << std::endl; disconnectClient(fd); } else { - _users[fd]->clearWriteBuffer(); - _pollManager.setWritable(fd, false); + _users[fd]->consumeWriteBuffer(bytesSent); + if (_users[fd]->getWriteBuffer().empty()) + _pollManager.setWritable(fd, false); } } } diff --git a/sources/user/user.cpp b/sources/user/user.cpp index 30b6b34..11224da 100644 --- a/sources/user/user.cpp +++ b/sources/user/user.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/21 20:37:12 by omoudni #+# #+# */ -/* Updated: 2025/06/18 01:19:52 by sben-tay ### ########.fr */ +/* Updated: 2025/06/19 02:23:06 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -117,21 +117,26 @@ bool User::isReadyToSend() const // Extract full command from read buffer std::string User::extractFullCommand() { + size_t pos = _read_buffer.find("\r\n"); - if (pos == std::string::npos) - pos = _read_buffer.find("\n"); // fallback if (pos != std::string::npos) { std::string command = _read_buffer.substr(0, pos); - if (_read_buffer.substr(pos, 2) == "\r\n") - _read_buffer.erase(0, pos + 2); - else - _read_buffer.erase(0, pos + 1); + _read_buffer.erase(0, pos + 2); return command; } + + pos = _read_buffer.find('\n'); + if (pos != std::string::npos) { + std::string command = _read_buffer.substr(0, pos); + _read_buffer.erase(0, pos + 1); + return command; + } + return ""; } + void User::setHasNick(bool value) { _hasNick = value; } void User::setHasUser(bool value) { _hasUser = value; } @@ -187,3 +192,10 @@ void User::resolveHostInfo() void User::setRealname(const std::string &realname) { _realname = realname; } std::string User::getRealname(void) const { return _realname; } + +void User::consumeWriteBuffer(size_t len) { + if (len >= _write_buffer.size()) + _write_buffer.clear(); + else + _write_buffer.erase(0, len); +} \ No newline at end of file