diff --git a/.vscode/settings.json b/.vscode/settings.json index 1d2e293..2af5a10 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -57,53 +57,53 @@ "C_Cpp_Runner.useLinkTimeOptimization": false, "C_Cpp_Runner.msvcSecureNoWarnings": false, "files.associations": { - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "random": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "typeinfo": "cpp", - "ctime": "cpp", - "map": "cpp" -} + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp", + "ctime": "cpp", + "map": "cpp" + } } \ No newline at end of file diff --git a/ft_irc/Makefile b/ft_irc/Makefile index f454d7a..2b1e7a2 100644 --- a/ft_irc/Makefile +++ b/ft_irc/Makefile @@ -6,7 +6,7 @@ # By: fgras-ca +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2024/05/09 13:54:36 by fgras-ca #+# #+# # -# Updated: 2024/05/09 13:54:48 by fgras-ca ### ########.fr # +# Updated: 2024/05/12 18:19:36 by fgras-ca ### ########.fr # # # # **************************************************************************** # @@ -36,7 +36,7 @@ $(NAME): $(OBJECTS) # Compilation des fichiers source en fichiers objet $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp @mkdir -p $(OBJ_DIR) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -g -c $< -o $@ # Commande pour nettoyer le projet (supprimer les fichiers objet et l'exécutable) clean: diff --git a/ft_irc/build/Channel.o b/ft_irc/build/Channel.o index 4457dab..7ea8f38 100644 Binary files a/ft_irc/build/Channel.o and b/ft_irc/build/Channel.o differ diff --git a/ft_irc/build/Client.o b/ft_irc/build/Client.o index b8346e7..9394c62 100644 Binary files a/ft_irc/build/Client.o and b/ft_irc/build/Client.o differ diff --git a/ft_irc/build/CommandHandler.o b/ft_irc/build/CommandHandler.o index baeca9c..89ea189 100644 Binary files a/ft_irc/build/CommandHandler.o and b/ft_irc/build/CommandHandler.o differ diff --git a/ft_irc/build/Server.o b/ft_irc/build/Server.o index f460d38..a9b3a58 100644 Binary files a/ft_irc/build/Server.o and b/ft_irc/build/Server.o differ diff --git a/ft_irc/build/main.o b/ft_irc/build/main.o index dad8106..75ee419 100644 Binary files a/ft_irc/build/main.o and b/ft_irc/build/main.o differ diff --git a/ft_irc/build/utilities.o b/ft_irc/build/utilities.o index 6f59157..9d392e5 100644 Binary files a/ft_irc/build/utilities.o and b/ft_irc/build/utilities.o differ diff --git a/ft_irc/include/Client.hpp b/ft_irc/include/Client.hpp index 844db13..ad81e52 100644 --- a/ft_irc/include/Client.hpp +++ b/ft_irc/include/Client.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:07:00 by fgras-ca #+# #+# */ -/* Updated: 2024/05/11 19:14:26 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/13 17:48:53 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/ft_irc/include/CommandHandler.hpp b/ft_irc/include/CommandHandler.hpp index 8e14428..cd0ed1d 100644 --- a/ft_irc/include/CommandHandler.hpp +++ b/ft_irc/include/CommandHandler.hpp @@ -6,21 +6,27 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:19:30 by fgras-ca #+# #+# */ -/* Updated: 2024/05/12 17:09:20 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/12 17:48:14 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef COMMANDHANDLER_HPP #define COMMANDHANDLER_HPP -#include "Client.hpp" -#include "Channel.hpp" -#include "Utilities.hpp" +#include +#include +#include +#include #include #include #include #include +#include "Client.hpp" +#include "Channel.hpp" +#include "Utilities.hpp" + + class Client; class Channel; diff --git a/ft_irc/include/Server.hpp b/ft_irc/include/Server.hpp index 47bf8eb..cb2057e 100644 --- a/ft_irc/include/Server.hpp +++ b/ft_irc/include/Server.hpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:01:12 by fgras-ca #+# #+# */ -/* Updated: 2024/05/12 17:14:30 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/13 19:00:18 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,6 +27,9 @@ #include #include #include +#include // Include this for fcntl and O_NONBLOCK +#include + #include "color.hpp" #include "Client.hpp" @@ -51,6 +54,8 @@ private: bool running; // État d'exécution du serveur int listener; // Socket d'écoute du serveur int fdmax; + int epoll_fd; // Descripteur pour l'instance epoll + static const int MAX_EVENTS = 10; // Nombre maximal d'événements traités à chaque appel à epoll_wait fd_set master_set; // Ensemble principal des descripteurs de fichiers pour select std::map clients; // Mapping de socket à Client std::map handlers; // CommandHandler pour chaque client @@ -60,6 +65,8 @@ private: bool getlineFromClient(Client* client, std::string& line); void handleIRCMessages(Client* client, CommandHandler& cmdHandler); bool processInitialCommands(Client* client); + void handleNickAndUserCommands(const std::string& line, size_t passEnd, Client* client); + void setNonBlocking(int sockfd); }; #endif // SERVER_HPP diff --git a/ft_irc/ircserv b/ft_irc/ircserv index 1505a2c..406f5f6 100755 Binary files a/ft_irc/ircserv and b/ft_irc/ircserv differ diff --git a/ft_irc/src/Channel.cpp b/ft_irc/src/Channel.cpp index 71b5d82..d50b9d1 100644 --- a/ft_irc/src/Channel.cpp +++ b/ft_irc/src/Channel.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:08:13 by fgras-ca #+# #+# */ -/* Updated: 2024/05/09 14:38:23 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/12 17:56:26 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,17 +16,20 @@ Channel::Channel(const std::string& name) : name(name) {} void Channel::addClient(Client* client) { + std::cout << "Adding client to channel " << name << std::endl; clients.push_back(client); + std::cout << "Client added. Total clients: " << clients.size() << std::endl; } - void Channel::removeClient(Client* client) { clients.erase(std::remove(clients.begin(), clients.end(), client), clients.end()); } void Channel::broadcastMessage(const std::string& message, Client* sender) { - for (std::vector::iterator it = clients.begin(); it != clients.end(); ++it) { - if (*it != sender) { // Ensure we don't send the message back to the sender - (*it)->sendMessage(message); + std::cout << "Broadcasting message in channel " << name << " from " << sender->getNickname() << std::endl; + for (size_t i = 0; i < clients.size(); ++i) { + if (clients[i] != sender) { + std::cout << "Sending message to " << clients[i]->getNickname() << std::endl; + clients[i]->sendMessage(message); } } } diff --git a/ft_irc/src/Client.cpp b/ft_irc/src/Client.cpp index 44365da..b693821 100644 --- a/ft_irc/src/Client.cpp +++ b/ft_irc/src/Client.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:07:27 by fgras-ca #+# #+# */ -/* Updated: 2024/05/11 16:11:10 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/13 16:59:32 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,15 +33,16 @@ std::string Client::receiveMessage() { std::memset(buffer, 0, sizeof(buffer)); int len = recv(socket, buffer, sizeof(buffer) - 1, 0); if (len > 0) { - buffer[len] = '\0'; // Ensure null termination + buffer[len] = '\0'; std::string received(buffer); - // Erase newline and carriage return characters - size_t pos; - while ((pos = received.find_first_of("\r\n")) != std::string::npos) { - received.erase(pos, 1); - } + received.erase(std::remove(received.begin(), received.end(), '\r'), received.end()); + received.erase(std::remove(received.begin(), received.end(), '\n'), received.end()); std::cout << "Received message: [" << received << "]" << std::endl; return received; + } else if (len == 0) { + std::cout << "Connection closed by the peer." << std::endl; + } else { + std::cerr << "recv error: " << strerror(errno) << std::endl; } return ""; } diff --git a/ft_irc/src/CommandHandler.cpp b/ft_irc/src/CommandHandler.cpp index a4a5a60..db38271 100644 --- a/ft_irc/src/CommandHandler.cpp +++ b/ft_irc/src/CommandHandler.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:19:15 by fgras-ca #+# #+# */ -/* Updated: 2024/05/12 17:11:00 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/12 18:07:48 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,60 +14,64 @@ CommandHandler::CommandHandler() {} -CommandHandler::~CommandHandler() -{ - for (std::map::iterator it = channels.begin(); it != channels.end(); ++it) - { +CommandHandler::~CommandHandler() { + for (std::map::iterator it = channels.begin(); it != channels.end(); ++it) { delete it->second; } channels.clear(); } -void CommandHandler::handleCommand(const std::string& commandLine, Client* client) -{ +void CommandHandler::handleCommand(const std::string& commandLine, Client* client) { std::istringstream stream(commandLine); std::string command; stream >> command; if (command == "JOIN") { - std::cout << "Commande Join reconnue" << std::endl; handleJoin(commandLine, client); } else if (command == "PART") { - std::cout << "Commande part reconnue" << std::endl; handlePart(commandLine, client); } else if (command == "NICK") { - std::cout << "Commande nick reconnue" << std::endl; handleNick(commandLine, client); } else if (command == "PRIVMSG") { - std::cout << "Commande privmsg reconnue" << std::endl; handlePrivmsg(commandLine, client); - } /*else if (command == "QUIT") { - std::cout << "Commande quit reconnue" << std::endl; - handleQuit(client); - }*/ - // Ajoutez d'autres commandes IRC ici + } } void CommandHandler::handleJoin(const std::string& command, Client* client) { - std::cout << "Lancement fonction Join reconnue" << std::endl; + std::cout << "Entering handleJoin with command: " << command << std::endl; std::vector tokens = split(command, ' '); if (tokens.size() > 1) { std::string channelName = tokens[1]; - if (channels.find(channelName) == channels.end()) { + + // Log before accessing the map + std::cout << "Checking if channel exists: " << channelName << std::endl; + + // Check if channel exists + std::map::iterator it = channels.find(channelName); + if (it == channels.end()) { + // If not, create a new channel + std::cout << "Creating new channel: " << channelName << std::endl; channels[channelName] = new Channel(channelName); + } else { + std::cout << "Channel already exists: " << channelName << std::endl; } + + // Add client to channel and send join message channels[channelName]->addClient(client); channels[channelName]->broadcastMessage("JOIN " + channelName, client); + } else { + std::cerr << "Invalid JOIN command format." << std::endl; } } + + void CommandHandler::handlePart(const std::string& command, Client* client) { std::vector tokens = split(command, ' '); if (tokens.size() > 1) { std::string channelName = tokens[1]; if (channels.find(channelName) != channels.end()) { channels[channelName]->removeClient(client); - channels[channelName]->broadcastMessage("PART " + channelName, client); } } } @@ -76,34 +80,26 @@ void CommandHandler::handleNick(const std::string& command, Client* client) { std::vector tokens = split(command, ' '); if (tokens.size() > 1) { client->setNickname(tokens[1]); - std::cout << "Nickname set to: " << tokens[1] << std::endl; // Afficher et enregistrer l'action } } - void CommandHandler::handlePrivmsg(const std::string& command, Client* client) { std::vector tokens = split(command, ' '); if (tokens.size() > 2) { std::string target = tokens[1]; - std::string message = command.substr(command.find(" :") + 2); + std::string message = command.substr(command.find(':') + 1); if (channels.find(target) != channels.end()) { - channels[target]->broadcastMessage("PRIVMSG " + message, client); + channels[target]->broadcastMessage("PRIVMSG " + target + " :" + message, client); } } } -/*void CommandHandler::handleQuit(Client* client) { - for (std::map::iterator it = channels.begin(); it != channels.end(); ++it) { - it->second->removeClient(client); - } -}*/ - std::vector CommandHandler::split(const std::string& s, char delimiter) { std::vector tokens; - std::stringstream ss(s); - std::string item; - while (getline(ss, item, delimiter)) { - tokens.push_back(item); + std::string token; + std::istringstream tokenStream(s); + while (std::getline(tokenStream, token, delimiter)) { + tokens.push_back(token); } return tokens; } diff --git a/ft_irc/src/Server.cpp b/ft_irc/src/Server.cpp index 7dd6f6a..0ba6f90 100644 --- a/ft_irc/src/Server.cpp +++ b/ft_irc/src/Server.cpp @@ -6,7 +6,7 @@ /* By: fgras-ca +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/09 14:01:34 by fgras-ca #+# #+# */ -/* Updated: 2024/05/12 17:07:02 by fgras-ca ### ########.fr */ +/* Updated: 2024/05/13 19:19:46 by fgras-ca ### ########.fr */ /* */ /* ************************************************************************** */ @@ -79,96 +79,99 @@ bool Server::initialize() return true; } -bool Server::getlineFromClient(Client* client, std::string& line) -{ - char buffer[1024]; - memset(buffer, 0, sizeof(buffer)); - int len = recv(client->getSocket(), buffer, sizeof(buffer) - 1, 0); +bool Server::getlineFromClient(Client* client, std::string& line) { + char buffer[1024]; + while (true) { + memset(buffer, 0, sizeof(buffer)); + int len = recv(client->getSocket(), buffer, sizeof(buffer) - 1, 0); - if (len > 0) - { - buffer[len] = '\0'; // Ensure null termination - line = std::string(buffer); - line.erase(std::remove(line.begin(), line.end(), '\r'), line.end()); - line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); - return true; - } - else if (len == 0) - { - std::cout << RED << "Client disconnected." << RESET << std::endl; - return false; // Connection is closed - } - else - { - std::cerr << RED << "Error reading from client socket: " << strerror(errno) << RESET << std::endl; - return false; // An error occurred - } + if (len > 0) { + buffer[len] = '\0'; + line = std::string(buffer); + line.erase(std::remove(line.begin(), line.end(), '\r'), line.end()); + line.erase(std::remove(line.begin(), line.end(), '\n'), line.end()); + std::cout << GREEN << "Received line: " << line << RESET << std::endl; + return true; + } else if (len == 0) { + std::cout << RED << "Client disconnected." << RESET << std::endl; + return false; + } else { + if (errno == EWOULDBLOCK || errno == EAGAIN) { + // Si non-bloquant et aucune donnée n'est disponible, attendez un peu et réessayez + std::cout << YELLOW << "No data available yet, non-blocking mode." << RESET << std::endl; + usleep(100000); // attendre 100 ms + continue; // Continuez à essayer de lire + } else { + std::cerr << RED << "Error reading from client socket: " << strerror(errno) << RESET << std::endl; + return false; + } + } + } } -bool Server::processInitialCommands(Client* client) -{ - std::string line; - bool isAuthenticated = false; // Pour garder une trace de l'authentification - while (getlineFromClient(client, line) && !line.empty()) - { - std::cout << MAGENTA << "Processing line: " << RESET << line << std::endl; - // Extraction et traitement de la commande PASS - size_t passEnd = line.find("NICK"); - if (passEnd != std::string::npos) - { - std::string passCommand = line.substr(0, passEnd); - std::istringstream passIss(passCommand); - std::string passToken, extractedPassword; - passIss >> passToken >> extractedPassword; - if (extractedPassword != this->password) - { - client->sendMessage("ERROR :Wrong password\r\n"); - std::cout << RED << "Authentication failed for password: " << RESET << extractedPassword << std::endl; - return false; - } - else - { - std::cout << "CLIENT Socket: " << client->getSocket() << GREEN << " :Authentication successful." << RESET << std::endl; - isAuthenticated = true; - } - } - // Traitement des commandes NICK et USER - if (isAuthenticated) - { // Seulement si authentifié - size_t nickEnd = line.find("USER"); - if (nickEnd != std::string::npos) - { - std::string nickCommand = line.substr(passEnd, nickEnd - passEnd); - std::istringstream nickIss(nickCommand); - std::string nickToken, nickname; - nickIss >> nickToken >> nickname; - client->setNickname(nickname); - std::cout << BLUE << "NickName SET: " << RESET << nickname << std::endl; - std::string userCommand = line.substr(nickEnd); - std::istringstream userIss(userCommand); - std::string userToken, username, realname; - userIss >> userToken >> username; - size_t realnameStart = userCommand.find(":"); - if (realnameStart != std::string::npos) - { - realname = userCommand.substr(realnameStart + 1); - client->setUsername(username); - client->setRealname(realname); - std::cout << GREEN << "CLIENT: " << "SET NickName: " << nickname << "; UserName: " << username << "; Socket: " << client->getSocket() << RESET << std::endl; - break; - } - } - } - } - // Après une authentification réussie, passez à la gestion des messages IRC - if (isAuthenticated) - { - handleIRCMessages(client, *new CommandHandler()); // Attention à la gestion de la mémoire ici - } - return isAuthenticated; + +bool Server::processInitialCommands(Client* client) { + std::string line; + bool isAuthenticated = false; + + if (!getlineFromClient(client, line) || line.empty()) { + std::cout << RED << "No initial commands received or connection lost." << RESET << std::endl; + return false; + } + + std::cout << MAGENTA << "Processing initial line: " << RESET << line << std::endl; + + // Extrait les parties nécessaires de la ligne + size_t passIndex = line.find("PASS"); + size_t nickIndex = line.find("NICK"); + size_t userIndex = line.find("USER"); + + if (passIndex == std::string::npos || nickIndex == std::string::npos || userIndex == std::string::npos) { + std::cerr << "Command format error." << std::endl; + return false; + } + + // Extraction des données + std::string password = line.substr(passIndex + 4, nickIndex - (passIndex + 4)); + std::string nickname = line.substr(nickIndex + 4, userIndex - (nickIndex + 4)); + std::string userAndRealName = line.substr(userIndex + 4); // Contient le username et le realname + size_t spaceIndex = userAndRealName.find(' '); + std::string username = userAndRealName.substr(0, spaceIndex); + std::string realname = userAndRealName.substr(spaceIndex + 1); + + // Retire les espaces potentiels autour des informations + password.erase(remove(password.begin(), password.end(), ' '), password.end()); + nickname.erase(remove(nickname.begin(), nickname.end(), ' '), nickname.end()); + username.erase(remove(username.begin(), username.end(), ' '), username.end()); + + // Validation du mot de passe + if (password != this->password) { + client->sendMessage("ERROR :Wrong password\r\n"); + std::cout << RED << "Authentication failed for password: " << password << RESET << std::endl; + return false; + } + + // Set up client details if password is correct + client->setNickname(nickname); + client->setUsername(username); + client->setRealname(realname); + isAuthenticated = true; + + std::cout << GREEN << "Authentication successful, client setup complete." << RESET << std::endl; + std::cout << GREEN << "Client details - Nickname: " << nickname << ", Username: " << username << ", Realname: " << realname << RESET << std::endl; + + // Proceed to handle IRC messages if authenticated + if (isAuthenticated) { + handleIRCMessages(client, *new CommandHandler()); + } + return isAuthenticated; } + + + + // Handle IRC commands void Server::handleIRCMessages(Client* client, CommandHandler& cmdHandler) { @@ -243,53 +246,75 @@ void Server::run() } } -void Server::acceptNewClient() -{ - struct sockaddr_in client_addr; - socklen_t addrlen = sizeof(client_addr); - std::cout << CYAN << "Ready to accept new connection..." << RESET << std::endl; - int newfd = accept(listener, (struct sockaddr *)&client_addr, &addrlen); +void Server::acceptNewClient() { + struct sockaddr_in client_addr; + socklen_t addrlen = sizeof(client_addr); + std::cout << CYAN << "Prêt à accepter une nouvelle connexion..." << RESET << std::endl; + int newfd = accept(listener, (struct sockaddr *)&client_addr, &addrlen); - if (newfd == -1) - { - perror("Accept failed"); - return; - } + if (newfd == -1) { + perror("Échec de l'acceptation"); + return; + } - clients[newfd] = new Client(newfd); - FD_SET(newfd, &master_set); - if (newfd > fdmax) - { - fdmax = newfd; - } + int flags = fcntl(newfd, F_GETFL, 0); + if (flags == -1) flags = 0; + fcntl(newfd, F_SETFL, flags | O_NONBLOCK); - std::cout << GREEN << "Accepted new client: " << inet_ntoa(client_addr.sin_addr) << " on fd: " << newfd << RESET << std::endl; + Client* newClient = new Client(newfd); + if (!newClient) { + std::cerr << RED << "Échec de la création d'une nouvelle instance Client." << RESET << std::endl; + close(newfd); + return; + } + + CommandHandler* newHandler = new CommandHandler(); + if (!newHandler) { + std::cerr << RED << "Échec de la création d'une nouvelle instance de CommandHandler." << RESET << std::endl; + delete newClient; + close(newfd); + return; + } + + clients[newfd] = newClient; + handlers[newfd] = newHandler; + FD_SET(newfd, &master_set); + if (newfd > fdmax) { + fdmax = newfd; + } + + std::cout << GREEN << "Nouveau client accepté: " << inet_ntoa(client_addr.sin_addr) << " sur fd: " << newfd << RESET << std::endl; + + if (!processInitialCommands(newClient)) { + std::cerr << "Échec du traitement des commandes initiales, fermeture de la connexion." << std::endl; + closeClient(newfd); + } } -bool Server::handleClientActivity(int sockfd) -{ - Client* client = clients[sockfd]; - if (!client) - { - std::cerr << RED << "Client not found for socket " << RESET << sockfd << std::endl; - return false; - } - std::string line; - if (getlineFromClient(client, line) && !line.empty()) - { - std::cout << GREEN << "Received message: [" << line << "]" << RESET << std::endl; - CommandHandler* cmdHandler = handlers[sockfd]; - cmdHandler->handleCommand(line, client); - return true; - } - else - { - std::cerr << RED << "Client disconnected or error on socket: " << RESET << sockfd << std::endl; - return false; - } + + +bool Server::handleClientActivity(int sockfd) { + Client* client = clients[sockfd]; + CommandHandler* cmdHandler = handlers[sockfd]; // Assurez-vous que cmdHandler est récupéré correctement + + if (!client || !cmdHandler) { + std::cerr << RED << "Client or CommandHandler not found for socket " << RESET << sockfd << std::endl; + return false; + } + + std::string line; + if (getlineFromClient(client, line) && !line.empty()) { + std::cout << GREEN << "Received message: [" << line << "]" << RESET << std::endl; + cmdHandler->handleCommand(line, client); + return true; + } else { + std::cerr << RED << "Client disconnected or error on socket: " << RESET << sockfd << std::endl; + return false; + } } + void Server::closeClient(int sockfd) { std::map::iterator it = clients.find(sockfd);