diff --git a/include/server.hpp b/include/server.hpp index fea3efc..c07fe61 100644 --- a/include/server.hpp +++ b/include/server.hpp @@ -1,14 +1,14 @@ -/******************************************************************************/ +/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* server.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: omoudni +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/20 21:50:32 by rparodi #+# #+# */ -/* Updated: 2025/05/29 12:17:55 by rparodi ### ########.fr */ +/* Updated: 2025/06/14 23:08:11 by sben-tay ### ########.fr */ /* */ -/******************************************************************************/ +/* ************************************************************************** */ #pragma once @@ -21,6 +21,7 @@ class User; class Channel; class Server + { private: int _port; diff --git a/sources/commands/cap.cpp b/sources/commands/cap.cpp index 15c86ca..7a0418c 100644 --- a/sources/commands/cap.cpp +++ b/sources/commands/cap.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/06/08 22:10:24 by sben-tay #+# #+# */ -/* Updated: 2025/06/09 14:05:55 by rparodi ### ########.fr */ +/* Updated: 2025/06/14 22:26:07 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,13 +16,19 @@ using namespace cmd; e_code Cap::checkArgs() { - return _PARSING_OK; + if (_args.size() < 2){ + return ERR_NEEDMOREPARAMS; + + _sender->appendToReadBuffer(_command); + + } + return (_PARSING_OK); } void cmd::Cap::execute() { if (this->checkArgs() != _PARSING_OK) return; - if (_args.size() >= 2 && _args[1] == "LS") { + if (_args.size() >= 2 && _args[1] == "ls") { std::string reply = "CAP * LS :\r\n"; _sender->appendToWriteBuffer(reply); DEBUG_MSG("Replied to CAP LS"); diff --git a/sources/commands/commands.cpp b/sources/commands/commands.cpp index 5652e75..d0358cd 100644 --- a/sources/commands/commands.cpp +++ b/sources/commands/commands.cpp @@ -77,7 +77,7 @@ void cmd::dispatch(::User *user, Channel *channel, Server *server, std::string & WARNING_MSG("No command found in line: " << line); return; } - std::cout << command_name << std::endl; + DEBUG_MSG("Command Name = [" << command_name << "]"); switch (command_name[0]) { case 'c': if (command_name == "cap") { @@ -110,10 +110,10 @@ void cmd::dispatch(::User *user, Channel *channel, Server *server, std::string & } break; case 'n': - if (command_name == "NICK") { - Nick(user, channel, server, line).execute(); + if (command_name == "nick") { + Nick(user, channel, server, line).execute(); } else if (command_name == "notice") { - Notice(user, channel, server, line).execute(); + Notice(user, channel, server, line).execute(); } break; case 'p': diff --git a/sources/commands/invite.cpp b/sources/commands/invite.cpp index 509bbaf..e1996d8 100644 --- a/sources/commands/invite.cpp +++ b/sources/commands/invite.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* invite.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/05 11:10:36 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:24:05 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -61,7 +61,7 @@ e_code Invite::checkArgs() { * @note To invite a peapol to join a channel (from an operator) */ void Invite::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for INVITE command (see warning message)"); return; } diff --git a/sources/commands/join.cpp b/sources/commands/join.cpp index ed68167..a4ae66d 100644 --- a/sources/commands/join.cpp +++ b/sources/commands/join.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* join.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/05 22:34:07 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:23:58 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,7 +49,7 @@ e_code Join::checkArgs() { * @note To join a new channel */ void Join::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for Join command (see warning message)"); return; } diff --git a/sources/commands/kick.cpp b/sources/commands/kick.cpp index 02d79a4..2bce2e9 100644 --- a/sources/commands/kick.cpp +++ b/sources/commands/kick.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* kick.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/09 14:37:11 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:24:16 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -61,7 +61,7 @@ e_code Kick::checkArgs() { * @note To kick a user from a channel */ void Kick::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for INVITE command (see warning message)"); return; } diff --git a/sources/commands/list.cpp b/sources/commands/list.cpp index 314615f..132e025 100644 --- a/sources/commands/list.cpp +++ b/sources/commands/list.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* list.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/09 15:33:52 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:24:21 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -47,7 +47,7 @@ e_code List::checkArgs() { * @note To list the channel */ void List::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for LIST command (see warning message)"); return; } diff --git a/sources/commands/modes.cpp b/sources/commands/modes.cpp index 984b351..555b870 100644 --- a/sources/commands/modes.cpp +++ b/sources/commands/modes.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* modes.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/10 16:29:52 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:24:27 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -112,7 +112,7 @@ e_code Mode::checkArgs() { * @note To invite a peapol to join a channel (from an operator) */ void Mode::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for INVITE command (see warning message)"); return; } diff --git a/sources/commands/nick.cpp b/sources/commands/nick.cpp index c54fd10..f125b4b 100644 --- a/sources/commands/nick.cpp +++ b/sources/commands/nick.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/08 22:18:49 by sben-tay ### ########.fr */ +/* Updated: 2025/06/12 17:52:12 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,12 +20,9 @@ e_code cmd::Nick::checkArgs() { WARNING_MSG("Nick: Not enough arguments"); return ERR_NONICKNAMEGIVEN; } - if (_sender->isRegistered()) { - WARNING_MSG(_sender->getName() << " is already registered"); - return ERR_ALREADYREGISTERED; - } User* existing = searchList(_users, _args[1]); // à adapter si besoin if (existing != NULL) { + WARNING_MSG("Nick already in use: " << _args[1]); return ERR_NICKNAMEINUSE; } @@ -37,7 +34,7 @@ e_code cmd::Nick::checkArgs() { * @note To change the nickname of the user */ void cmd::Nick::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for Nick command (see warning message)"); return; } diff --git a/sources/commands/notice.cpp b/sources/commands/notice.cpp index 8642d25..b9d42ee 100644 --- a/sources/commands/notice.cpp +++ b/sources/commands/notice.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* notice.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/05 22:49:09 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:24:35 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,7 +49,7 @@ e_code Notice::checkArgs() { * @note To send a private message to a user / a channel (like privmsg but without error) */ void Notice::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for NOTICE command (see warning message)"); return; } diff --git a/sources/commands/part.cpp b/sources/commands/part.cpp index 8e69256..6532dbd 100644 --- a/sources/commands/part.cpp +++ b/sources/commands/part.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* part.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/05 22:50:21 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:24:39 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -48,7 +48,7 @@ e_code Part::checkArgs() { * @note To leave a channel givent in parameter */ void Part::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for Part command (see warning message)"); return; } diff --git a/sources/commands/pass.cpp b/sources/commands/pass.cpp index c7a2ac5..7777167 100644 --- a/sources/commands/pass.cpp +++ b/sources/commands/pass.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/10 16:27:03 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 17:52:35 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,7 +30,7 @@ e_code Pass::checkArgs() { */ void Pass::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for Pass command (see warning message)"); DEBUG_MSG("skill issues"); return; @@ -41,4 +41,5 @@ void Pass::execute() { return; } _sender->setHasPass(true); + _sender->checkRegistration(); } diff --git a/sources/commands/ping.cpp b/sources/commands/ping.cpp index 9ef7b27..c6c442e 100644 --- a/sources/commands/ping.cpp +++ b/sources/commands/ping.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/08 20:13:52 by sben-tay ### ########.fr */ +/* Updated: 2025/06/14 23:25:45 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,7 +19,7 @@ using namespace cmd; e_code Ping::checkArgs() { - if (_args.size() < 3) { + if (_args.size() < 2) { WARNING_MSG("Not enough arguments for PING command"); return ERR_NEEDMOREPARAMS; } @@ -32,11 +32,10 @@ e_code Ping::checkArgs() { */ void Ping::execute() { - clock_t start = clock() / CLOCKS_PER_SEC; - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for PRIVMSG command (see warning message)"); return; } - clock_t diff = Pong().answer(start); - INFO_MSG(diff); + _sender->appendToWriteBuffer("PONG " + _args[1] + "\r\n"); + DEBUG_MSG(_sender->getWriteBuffer()); } diff --git a/sources/commands/privmsg.cpp b/sources/commands/privmsg.cpp index 8137061..c13e52a 100644 --- a/sources/commands/privmsg.cpp +++ b/sources/commands/privmsg.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* privmsg.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: rparodi +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/24 17:29:48 by rparodi #+# #+# */ -/* Updated: 2025/06/05 22:46:54 by rparodi ### ########.fr */ +/* Updated: 2025/06/12 13:25:02 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,7 +49,7 @@ e_code PrivMsg::checkArgs() { * @note To send a private message to a user / a channel */ void PrivMsg::execute() { - if (checkArgs() == _PARSING_OK) { + if (checkArgs() != _PARSING_OK) { ERROR_MSG("Invalid arguments for PRIVMSG command (see warning message)"); return; } diff --git a/sources/commands/userCmd.cpp b/sources/commands/userCmd.cpp index d29f57a..ac20202 100644 --- a/sources/commands/userCmd.cpp +++ b/sources/commands/userCmd.cpp @@ -6,7 +6,7 @@ /* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/06/08 19:16:10 by sben-tay #+# #+# */ -/* Updated: 2025/06/08 22:19:02 by sben-tay ### ########.fr */ +/* Updated: 2025/06/12 17:55:06 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,10 +20,6 @@ e_code cmd::userCmd::checkArgs() { WARNING_MSG("USER: Not enough parameters"); return ERR_NEEDMOREPARAMS; } - if (_sender->isRegistered()) { - WARNING_MSG(_sender->getName() << " is already registered"); - return ERR_ALREADYREGISTERED; - } return _PARSING_OK; } diff --git a/sources/core/Server.cpp b/sources/core/Server.cpp index 4c707ad..c465308 100644 --- a/sources/core/Server.cpp +++ b/sources/core/Server.cpp @@ -1,14 +1,14 @@ -/******************************************************************************/ +/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* Server.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: omoudni +#+ +:+ +#+ */ +/* By: sben-tay +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/13 11:11:07 by rparodi #+# #+# */ -/* Updated: 2025/06/03 14:56:06 by rparodi ### ########.fr */ +/* Updated: 2025/06/14 23:16:54 by sben-tay ### ########.fr */ /* */ -/******************************************************************************/ +/* ************************************************************************** */ #include "color.hpp" #include "server.hpp" @@ -22,6 +22,7 @@ #include #include #include +#include /** * @brief The constructor of the Server class. @@ -48,6 +49,8 @@ Server::~Server() } } +std::vector splitLines(const std::string& input); + void Server::start() { _serverFd = socket(AF_INET, SOCK_STREAM, 0); @@ -84,7 +87,6 @@ void Server::start() readyClients.clear(); _pollManager.pollLoop(_serverFd, newClients, disconnected, readyClients); - std::cout << "Poll loop finished" << std::endl; std::cout << "New clients: " << newClients.size() << std::endl; for (size_t i = 0; i < newClients.size(); ++i) { @@ -103,17 +105,36 @@ void Server::start() if (_users.count(fd)) { _users[fd]->appendToReadBuffer(data); - std::string cmd; - while (!(cmd = _users[fd]->extractFullCommand()).empty()) + std::string rawCmd; + while (!(rawCmd = _users[fd]->extractFullCommand()).empty()) { + std::vector lines = splitLines(rawCmd); + for (size_t i = 0; i < lines.size(); ++i) { + std::cout << "Client " << fd << " says: " << lines[i] << std::endl; + cmd::dispatch(_users[fd], NULL, this, lines[i]); + } // This prints every command/message received from any client - std::cout << "Client " << fd << " says: " << cmd << std::endl; - cmd::dispatch(_users[fd], NULL, this, cmd); } } } - - // Optionally: handle server shutdown, signals, etc. + for (std::vector > ::iterator it = readyClients.begin(); it != readyClients.end(); ++it) + { + int fd = it->first; + if (_users.count(fd) && _users[fd]->isReadyToSend()) + { + std::string writeBuffer = _users[fd]->getWriteBuffer(); + ssize_t bytesSent = send(fd, writeBuffer.c_str(), writeBuffer.size(), 0); + if (bytesSent < 0) + { + std::cerr << "Erreur send" << std::endl; + } + else { + _users[fd]->clearWriteBuffer(); + } + } + + } + std::cout << "Poll loop finished" << std::endl; } close(_serverFd); } @@ -170,3 +191,16 @@ std::list Server::getUsersList() const { std::list Server::getChannelsList() const { return this->_channels; } + +std::vector splitLines(const std::string& input) { + std::vector lines; + std::istringstream stream(input); + std::string line; + + while (std::getline(stream, line)) { + if (!line.empty() && line[line.length() - 1] == '\r') + line.erase(line.length() - 1); // retirer le \r final + lines.push_back(line); + } + return lines; +} \ No newline at end of file diff --git a/sources/user/user.cpp b/sources/user/user.cpp index e17cd32..bb8fc5f 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/08 21:41:26 by sben-tay ### ########.fr */ +/* Updated: 2025/06/14 23:27:43 by sben-tay ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,6 +85,7 @@ void User::checkRegistration() { if (!_registered && _hasNick && _hasUser && _hasPass) { + std::cout << "JE SUIS ENREGISTRE" << std::endl; _registered = true; std::string welcome = ":localhost 001 " + _nickname + " :Welcome to the IRC server " + getPrefix() + "\r\n"; @@ -101,18 +102,19 @@ bool User::isReadyToSend() const // Extract full command from read buffer std::string User::extractFullCommand() { - std::string command; size_t pos = _read_buffer.find("\r\n"); if (pos == std::string::npos) pos = _read_buffer.find("\n"); // fallback if (pos != std::string::npos) { - command = _read_buffer.substr(0, pos); - _read_buffer.erase(0, pos + 1); - if (_read_buffer[pos] == '\r') // clean up stray \r - _read_buffer.erase(0, 1); + 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); + return command; } - return command; + return ""; } void User::setHasNick(bool value) { _hasNick = value; }