mirror of
https://github.com/Ladebeze66/ft_irc.git
synced 2025-12-16 05:58:09 +01:00
fef
This commit is contained in:
parent
0dc9f5c940
commit
9fea48a546
@ -5,8 +5,8 @@
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/16 15:23:58 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/19 19:18:11 by fgras-ca ### ########.fr */
|
||||
/* Created: 2024/05/21 18:09:05 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 19:46:40 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -16,8 +16,11 @@
|
||||
#include "Client.hpp"
|
||||
#include "Server.hpp"
|
||||
#include "Channel.hpp"
|
||||
#include "CommandHandler.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "RPL.hpp"
|
||||
#include "Who.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
@ -26,12 +29,20 @@
|
||||
class Server;
|
||||
class Client;
|
||||
class Channel;
|
||||
class CommandHandler;
|
||||
|
||||
void sendWelcomeMessages(Client *client, Server *server);
|
||||
void sendMotd(Client *client, Server *server);
|
||||
void broadcastChannelList(Client *client, Server *server);
|
||||
void handlePartCommand(Server *server, Client *client, const std::string &command);
|
||||
void handleNickCommand(Server *server, Client *client, const std::string &command);
|
||||
void handlePrivmsgCommand(Server *server, Client *client, const std::string &command);
|
||||
class AdditionalCommands
|
||||
{
|
||||
private:
|
||||
Server *_server;
|
||||
CommandHandler *_commandhandler;
|
||||
public:
|
||||
AdditionalCommands(Server *server);
|
||||
void processCommand(Client *client, const std::string &command);
|
||||
void broadcastChannelList(Client *client, Server *server);
|
||||
void handlePartCommand(Server *server, Client *client, const std::string &command);
|
||||
void handleNickCommand(Server *server, Client *client, const std::string &command);
|
||||
void handlePrivmsgCommand(Server *server, Client *client, const std::string &command);
|
||||
};
|
||||
|
||||
#endif // ADDITIONALCOMMANDS_HPP
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 12:41:35 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/19 15:14:50 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 19:26:51 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -17,11 +17,16 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include "RPL.hpp"
|
||||
|
||||
#include "RPL.hpp"
|
||||
#include "Client.hpp"
|
||||
#include "Server.hpp"
|
||||
|
||||
class Server;
|
||||
class Client;
|
||||
|
||||
class Channel {
|
||||
class Channel
|
||||
{
|
||||
public:
|
||||
Channel(const std::string &name);
|
||||
~Channel();
|
||||
@ -33,6 +38,8 @@ public:
|
||||
const std::vector<Client *> &getClients() const;
|
||||
void addOperator(Client *client);
|
||||
bool isOperator(Client *client) const;
|
||||
bool hasClient(Client *client) const; // Ajouté
|
||||
void broadcast(const std::string &message, Client *_client, Server *_server); // Ajouté
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
@ -40,4 +47,4 @@ private:
|
||||
std::vector<Client *> _operators;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // CHANNEL_HPP
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 12:15:42 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/19 15:38:28 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 18:03:09 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 18:30:07 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/19 18:56:44 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 18:01:47 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "Channel.hpp"
|
||||
#include "Server.hpp"
|
||||
#include "CommandHandler.hpp"
|
||||
#include "AdditionalCommands.hpp"
|
||||
#include "RPL.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 18:14:12 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 13:47:12 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 20:15:58 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -17,23 +17,27 @@
|
||||
#include "Server.hpp"
|
||||
#include "Client.hpp"
|
||||
#include "Channel.hpp"
|
||||
#include "AdditionalCommands.hpp"
|
||||
#include "Who.hpp"
|
||||
#include "CommandHandler.hpp"
|
||||
#include "AdditionalCommands.hpp"
|
||||
#include "RPL.hpp"
|
||||
#include "Join.hpp"
|
||||
#include "Welcome.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
class Server;
|
||||
class ModeWhoHandler;
|
||||
class AdditinalCommands;
|
||||
class Client;
|
||||
class Channel;
|
||||
class WhoHandler;
|
||||
class AdditionalCommands;
|
||||
|
||||
class CommandHandler
|
||||
{
|
||||
private:
|
||||
Server *_server;
|
||||
AdditionalCommands *_additionalCommands;
|
||||
|
||||
public:
|
||||
CommandHandler(Server *server);
|
||||
@ -46,10 +50,9 @@ public:
|
||||
void handleCommand(Client *client, const std::string &command);
|
||||
void handleCapCommand(Client* client, const std::vector<std::string>& tokens);
|
||||
void handlePassCommand(Client* client, const std::vector<std::string>& tokens);
|
||||
void handleQuitCommand(Client* client, const std::vector<std::string>& tokens);
|
||||
void handleErrorCommand(Client* client, const std::string &message);
|
||||
|
||||
void processCommand(Client *client, const std::string &command);
|
||||
void handleJoinCommand(Client *client, const std::string &channelName);
|
||||
std::string getUsersList(Channel *channel);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // COMMANDHANDLER_HPP
|
||||
34
ft_irc3/includes/Join.hpp
Normal file
34
ft_irc3/includes/Join.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Join.hpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/21 19:51:08 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 20:13:15 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef JOIN_HPP
|
||||
#define JOIN_HPP
|
||||
|
||||
#include "Server.hpp"
|
||||
#include "Client.hpp"
|
||||
#include "Channel.hpp"
|
||||
#include "RPL.hpp"
|
||||
|
||||
class Server;
|
||||
class Client;
|
||||
class Channel;
|
||||
|
||||
class JoinHandler
|
||||
{
|
||||
public:
|
||||
void handleJoinCommand(Client *client, const std::string &channelName, Server *server);
|
||||
|
||||
private:
|
||||
std::string getUsersList(Channel *channel);
|
||||
};
|
||||
|
||||
#endif // JOIN_HPP
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 12:15:13 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/19 21:13:24 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 19:44:24 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -38,6 +38,7 @@ class Client;
|
||||
class Channel;
|
||||
class ClientManager;
|
||||
class CommandHandler;
|
||||
class AdditionalCommands;
|
||||
|
||||
class Server
|
||||
{
|
||||
@ -56,6 +57,8 @@ public:
|
||||
Client* getClientByName(const std::string &name); // Ajoutez cette méthode
|
||||
void sendChannelListToClient(Client *client);
|
||||
void disconnectClient(int clientFd);
|
||||
bool MatchFd(const pollfd& pfd, int clientFd);
|
||||
void removePollFd(int clientFd);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
27
ft_irc3/includes/Welcome.hpp
Normal file
27
ft_irc3/includes/Welcome.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Welcome.hpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/21 19:53:17 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 19:53:24 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef WELCOME_HPP
|
||||
#define WELCOME_HPP
|
||||
|
||||
#include "Client.hpp"
|
||||
#include "Server.hpp"
|
||||
#include <string>
|
||||
|
||||
class WelcomeHandler
|
||||
{
|
||||
public:
|
||||
void sendWelcomeMessages(Client *client, Server *server);
|
||||
void sendMotd(Client *client, Server *server);
|
||||
};
|
||||
|
||||
#endif // WELCOME_HPP
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/17 16:08:48 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 13:47:28 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 18:04:10 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
||||
BIN
ft_irc3/ircserv
Executable file
BIN
ft_irc3/ircserv
Executable file
Binary file not shown.
0
ft_irc3/logs/irc_server.log
Normal file
0
ft_irc3/logs/irc_server.log
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
ft_irc3/obj/Join.o
Normal file
BIN
ft_irc3/obj/Join.o
Normal file
Binary file not shown.
BIN
ft_irc3/obj/Server.o
Normal file
BIN
ft_irc3/obj/Server.o
Normal file
Binary file not shown.
BIN
ft_irc3/obj/Utils.o
Normal file
BIN
ft_irc3/obj/Utils.o
Normal file
Binary file not shown.
BIN
ft_irc3/obj/Welcome.o
Normal file
BIN
ft_irc3/obj/Welcome.o
Normal file
Binary file not shown.
BIN
ft_irc3/obj/Who.o
Normal file
BIN
ft_irc3/obj/Who.o
Normal file
Binary file not shown.
@ -6,44 +6,47 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/16 15:27:29 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 13:52:54 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 20:22:22 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "AdditionalCommands.hpp"
|
||||
|
||||
void sendWelcomeMessages(Client *client, Server *server)
|
||||
{
|
||||
server->sendToClient(client->getFd(), RPL_WELCOME(client));
|
||||
server->sendToClient(client->getFd(), RPL_YOURHOST(client));
|
||||
server->sendToClient(client->getFd(), RPL_CREATED(client));
|
||||
server->sendToClient(client->getFd(), RPL_MYINFO(client));
|
||||
server->sendToClient(client->getFd(), RPL_ISUPPORT(client, "MODES=EXAMPLE"));
|
||||
AdditionalCommands::AdditionalCommands(Server *server) : _server(server)
|
||||
{}
|
||||
|
||||
sendMotd(client, server);
|
||||
}
|
||||
|
||||
void sendMotd(Client *client, Server *server)
|
||||
void AdditionalCommands::processCommand(Client *client, const std::string &command)
|
||||
{
|
||||
std::ifstream motdFile("motd.txt");
|
||||
if (motdFile.is_open())
|
||||
if (command.find("PART") == 0)
|
||||
{
|
||||
std::string line;
|
||||
server->sendToClient(client->getFd(), RPL_MOTDSTART(client));
|
||||
while (std::getline(motdFile, line))
|
||||
{
|
||||
server->sendToClient(client->getFd(), RPL_MOTD(client, line));
|
||||
handlePartCommand(_server, client, command);
|
||||
}
|
||||
server->sendToClient(client->getFd(), RPL_ENDOFMOTD(client));
|
||||
motdFile.close();
|
||||
else if (command.find("PRIVMSG") == 0)
|
||||
{
|
||||
handlePrivmsgCommand(_server, client, command);
|
||||
}
|
||||
else if (command.find("WHO") == 0)
|
||||
{
|
||||
WhoHandler whoHandler(_server);
|
||||
whoHandler.handleWhoCommand(client, command);
|
||||
}
|
||||
else if (command.find("WHOIS") == 0)
|
||||
{
|
||||
WhoHandler whoHandler(_server);
|
||||
whoHandler.handleWhoisCommand(client, command);
|
||||
}
|
||||
else if (command.find("LIST") == 0)
|
||||
{
|
||||
broadcastChannelList(client, _server);
|
||||
}
|
||||
else
|
||||
{
|
||||
server->sendToClient(client->getFd(), ERR_NOMOTD(client));
|
||||
_server->sendToClient(client->getFd(), ERR_UNKNOWNCOMMAND(client, command));
|
||||
_server->log("Message from client " + client->getNickname() + ": " + command, MAGENTA);
|
||||
}
|
||||
}
|
||||
|
||||
void broadcastChannelList(Client *client, Server *server)
|
||||
void AdditionalCommands::broadcastChannelList(Client *client, Server *server)
|
||||
{
|
||||
std::map<std::string, Channel *> &channels = server->getChannels();
|
||||
for (std::map<std::string, Channel *>::iterator it = channels.begin(); it != channels.end(); ++it)
|
||||
@ -54,7 +57,7 @@ void broadcastChannelList(Client *client, Server *server)
|
||||
}
|
||||
|
||||
// Fonction pour gérer la commande PART
|
||||
void handlePartCommand(Server *server, Client *client, const std::string &command)
|
||||
void AdditionalCommands::handlePartCommand(Server *server, Client *client, const std::string &command)
|
||||
{
|
||||
std::istringstream iss(command);
|
||||
std::string cmd, channelName;
|
||||
@ -87,25 +90,7 @@ void handlePartCommand(Server *server, Client *client, const std::string &comman
|
||||
}
|
||||
}
|
||||
|
||||
// Fonction pour gérer la commande NICK
|
||||
void handleNickCommand(Server *server, Client *client, const std::string &command)
|
||||
{
|
||||
std::istringstream iss(command);
|
||||
std::string cmd, newNick;
|
||||
iss >> cmd >> newNick;
|
||||
|
||||
std::stringstream nickMsg;
|
||||
nickMsg << ":" << client->getNickname() << " NICK " << newNick << "\r\n";
|
||||
server->sendToClient(client->getFd(), nickMsg.str());
|
||||
|
||||
client->setNickname(newNick);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Client " << client->getFd() << " changed nickname to " << newNick;
|
||||
server->log(ss.str(), GREEN);
|
||||
}
|
||||
|
||||
void handlePrivmsgCommand(Server *server, Client *client, const std::string &command)
|
||||
void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, const std::string &command)
|
||||
{
|
||||
std::istringstream iss(command);
|
||||
std::string cmd, target, message;
|
||||
|
||||
@ -6,21 +6,15 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 12:42:57 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/17 20:08:28 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 19:27:42 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "Channel.hpp"
|
||||
#include "Client.hpp"
|
||||
|
||||
Channel::Channel(const std::string &name)
|
||||
: _name(name)
|
||||
{
|
||||
}
|
||||
Channel::Channel(const std::string &name) : _name(name) {}
|
||||
|
||||
Channel::~Channel()
|
||||
{
|
||||
}
|
||||
Channel::~Channel() {}
|
||||
|
||||
const std::string &Channel::getName() const
|
||||
{
|
||||
@ -49,13 +43,27 @@ const std::vector<Client *> &Channel::getClients() const
|
||||
|
||||
void Channel::addOperator(Client *client)
|
||||
{
|
||||
if (std::find(_operators.begin(), _operators.end(), client) == _operators.end())
|
||||
{
|
||||
_operators.push_back(client);
|
||||
}
|
||||
}
|
||||
|
||||
bool Channel::isOperator(Client *client) const
|
||||
{
|
||||
return std::find(_operators.begin(), _operators.end(), client) != _operators.end();
|
||||
}
|
||||
|
||||
bool Channel::hasClient(Client *client) const
|
||||
{
|
||||
return std::find(_clients.begin(), _clients.end(), client) != _clients.end();
|
||||
}
|
||||
|
||||
void Channel::broadcast(const std::string &message, Client *_client, Server *server)
|
||||
{
|
||||
for (std::vector<Client *>::iterator it = _clients.begin(); it != _clients.end(); ++it)
|
||||
{
|
||||
if (*it != _client)
|
||||
{
|
||||
// Send message to each client except the sender
|
||||
server->sendToClient((*it)->getFd(), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 18:32:23 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 14:09:07 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 20:28:41 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -43,30 +43,50 @@ void ClientManager::handleClient(int client_fd)
|
||||
char buffer[1024];
|
||||
std::memset(buffer, 0, sizeof(buffer));
|
||||
int bytes_received = recv(client_fd, buffer, sizeof(buffer), 0);
|
||||
|
||||
if (bytes_received <= 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Client disconnected: " << client_fd;
|
||||
_server->log(oss.str(), RED);
|
||||
removeClient(client_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string message(buffer);
|
||||
std::stringstream ss;
|
||||
ss << "Received from client " << client_fd << ": " << message;
|
||||
_server->log(ss.str(), BLUE);
|
||||
std::string message(buffer, bytes_received);
|
||||
std::ostringstream oss;
|
||||
oss << "Received from client " << client_fd << ": " << message;
|
||||
_server->log(oss.str(), BLUE);
|
||||
|
||||
Client* client = _server->getClients()[client_fd];
|
||||
if (!client)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Client not found for fd: " << client_fd;
|
||||
_server->log(oss.str(), RED);
|
||||
return;
|
||||
}
|
||||
|
||||
Client *client = _server->_clients[client_fd];
|
||||
std::istringstream message_stream(message);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(message_stream, line))
|
||||
{
|
||||
// Remove trailing '\r' and '\n'
|
||||
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
|
||||
line.erase(std::remove(line.begin(), line.end(), '\n'), line.end());
|
||||
|
||||
if (!line.empty())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Processing command from client " << client_fd << ": " << line;
|
||||
_server->log(oss.str(), BLUE);
|
||||
_server->_commandHandler->handleCommand(client, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClientManager::removeClient(int clientFd)
|
||||
{
|
||||
Client* client = _server->_clients[clientFd];
|
||||
@ -109,4 +129,3 @@ void ClientManager::removeClient(int clientFd)
|
||||
ss << "Client disconnected: " << clientFd;
|
||||
_server->log(ss.str(), YELLOW);
|
||||
}
|
||||
|
||||
|
||||
@ -6,16 +6,22 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 18:26:34 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 14:19:19 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 20:24:52 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "CommandHandler.hpp"
|
||||
|
||||
CommandHandler::CommandHandler(Server *server)
|
||||
: _server(server)
|
||||
{
|
||||
}
|
||||
: _server(server), _additionalCommands(new AdditionalCommands(server))
|
||||
{
|
||||
// Ensure that _server is not null
|
||||
if (!_server)
|
||||
{
|
||||
std::cerr << "Server pointer is null in CommandHandler constructor." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandHandler::handleCommand(Client* client, const std::string& command)
|
||||
{
|
||||
@ -34,12 +40,27 @@ void CommandHandler::handleCommand(Client* client, const std::string& command)
|
||||
handleNick(client, tokens);
|
||||
} else if (commandType == "USER") {
|
||||
handleUser(client, tokens);
|
||||
} else {
|
||||
} else if (commandType == "QUIT") {
|
||||
handleQuitCommand(client, tokens);
|
||||
} else if (commandType == "PING")
|
||||
{
|
||||
handlePingCommand(client, tokens);
|
||||
}
|
||||
else if (commandType == "ERROR") {
|
||||
if (tokens.size() > 1) {
|
||||
handleErrorCommand(client, tokens[1]);
|
||||
}
|
||||
}
|
||||
else if (commandType == "JOIN") {
|
||||
JoinHandler joinHandler;
|
||||
joinHandler.handleJoinCommand(client, tokens[1], _server);
|
||||
}
|
||||
else {
|
||||
if (!client->isAuthenticated()) {
|
||||
_server->sendToClient(client->getFd(), ERR_NOTREGISTERED(client));
|
||||
_server->log("Client " + client->getNickname() + " attempted to send a command before registering.", RED);
|
||||
} else {
|
||||
processCommand(client, command);
|
||||
_additionalCommands->processCommand(client, command);
|
||||
}
|
||||
}
|
||||
std::cout << "Client " << client->getFd() << " " << client->getNickname() << " " << client->getUser() << " " << client->getPassword() << " " << client->getRealName() << std::endl;
|
||||
@ -146,144 +167,105 @@ void CommandHandler::handleNick(Client* client, const std::vector<std::string>&
|
||||
return;
|
||||
}
|
||||
|
||||
std::string oldNick = client->getNickname();
|
||||
client->setNickname(newNick);
|
||||
|
||||
_server->sendToClient(client->getFd(), ":" + newNick + " NICK " + newNick + "\r\n");
|
||||
// Envoyer le message NICK à tous les clients connectés
|
||||
std::string nickMessage = ":" + oldNick + " NICK " + newNick + "\r\n";
|
||||
for (std::map<int, Client*>::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it) {
|
||||
_server->sendToClient(it->second->getFd(), nickMessage);
|
||||
}
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Client " << client->getFd() << " changed nickname to " << newNick;
|
||||
oss << "Client " << client->getFd() << " changed nickname from " << oldNick << " to " << newNick;
|
||||
_server->log(oss.str(), GREEN);
|
||||
}
|
||||
|
||||
|
||||
void CommandHandler::handleUser(Client* client, const std::vector<std::string>& tokens)
|
||||
{
|
||||
// Set the user and realname fields
|
||||
client->setUser(tokens[1]);
|
||||
std::string realname = tokens[4];
|
||||
if (realname[0] == ':')
|
||||
{
|
||||
realname = realname.substr(1); // Remove leading ':'
|
||||
if (tokens.size() < 5) {
|
||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client->getFd(), "USER"));
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Client " << client->getFd() << ": USER command failed - not enough parameters.";
|
||||
_server->log(oss.str(), RED);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->isAuthenticated()) {
|
||||
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Client " << client->getFd() << ": USER command failed - already registered.";
|
||||
_server->log(oss.str(), RED);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string username = tokens[1];
|
||||
std::string realname = tokens[4].substr(1); // remove leading ':'
|
||||
|
||||
client->setUser(username);
|
||||
client->setRealName(realname);
|
||||
|
||||
// Log the values for debugging
|
||||
std::ostringstream logMsg;
|
||||
logMsg << "Client " << client->getFd() << ": USER command set username to " << tokens[1] << " and real name to " << realname;
|
||||
_server->log(logMsg.str(), BLUE);
|
||||
std::ostringstream oss;
|
||||
oss << "Client " << client->getFd() << ": USER command set username to " << username << " and real name to " << realname;
|
||||
_server->log(oss.str(), BLUE);
|
||||
|
||||
// Authenticate if password and nickname are already set
|
||||
if (client->getPassword() == _server->_password && !client->getNickname().empty())
|
||||
{
|
||||
if (client->getPassword() == _server->_password && !client->getNickname().empty()) {
|
||||
client->authenticate();
|
||||
sendWelcomeMessages(client, _server);
|
||||
_server->log("Client " + client->getNickname() + " authenticated successfully.", GREEN);
|
||||
WelcomeHandler welcomeHandler;
|
||||
welcomeHandler.sendWelcomeMessages(client, _server);
|
||||
_server->log("Client " + client->getNickname() + " authenticated.", GREEN);
|
||||
} else {
|
||||
std::ostringstream oss;
|
||||
oss << "Client " << client->getFd() << ": USER command failed - authentication conditions not met.";
|
||||
_server->log(oss.str(), RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream authFailMsg;
|
||||
authFailMsg << "Client " << client->getFd() << ": USER command failed - authentication conditions not met.";
|
||||
_server->log(authFailMsg.str(), RED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CommandHandler::processCommand(Client *client, const std::string &command)
|
||||
{
|
||||
if (command.find("JOIN") == 0)
|
||||
{
|
||||
std::string channelName = command.substr(5);
|
||||
handleJoinCommand(client, channelName);
|
||||
}
|
||||
else if (command.find("PART") == 0)
|
||||
{
|
||||
handlePartCommand(_server, client, command);
|
||||
}
|
||||
/*else if (command.find("NICK") == 0)
|
||||
{
|
||||
handleNickCommand(_server, client, command);
|
||||
}*/
|
||||
else if (command.find("PRIVMSG") == 0)
|
||||
{
|
||||
handlePrivmsgCommand(_server, client, command);
|
||||
}
|
||||
else if (command.find("WHO") == 0)
|
||||
{
|
||||
WhoHandler whoHandler(_server);
|
||||
whoHandler.handleWhoCommand(client, command);
|
||||
}
|
||||
else if (command.find("WHOIS") == 0)
|
||||
{
|
||||
WhoHandler whoHandler(_server);
|
||||
whoHandler.handleWhoisCommand(client, command);
|
||||
}
|
||||
else if (command.find("PING") == 0)
|
||||
{
|
||||
std::vector<std::string> tokens = split(command, " ");
|
||||
handlePingCommand(client, tokens);
|
||||
}
|
||||
else if (command.find("LIST") == 0)
|
||||
{
|
||||
broadcastChannelList(client, _server);
|
||||
}
|
||||
else
|
||||
{
|
||||
_server->sendToClient(client->getFd(), ERR_UNKNOWNCOMMAND(client, command));
|
||||
_server->log("Message from client " + client->getNickname() + ": " + command, MAGENTA);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandHandler::handleJoinCommand(Client *client, const std::string &channelName)
|
||||
{
|
||||
if (_server->getChannels().find(channelName) == _server->getChannels().end())
|
||||
{
|
||||
_server->getChannels()[channelName] = new Channel(channelName);
|
||||
_server->log("Channel created: " + channelName, GREEN);
|
||||
|
||||
// Notifier tous les clients de la création du canal
|
||||
_server->broadcast(":server NOTICE * :New channel created: " + channelName + "\r\n");
|
||||
}
|
||||
Channel *channel = _server->getChannels()[channelName];
|
||||
channel->addClient(client);
|
||||
|
||||
std::stringstream joinMsg;
|
||||
joinMsg << ":" << client->getNickname() << " JOIN :" << channelName << "\r\n";
|
||||
_server->sendToClient(client->getFd(), joinMsg.str());
|
||||
|
||||
std::string usersList = getUsersList(channel);
|
||||
_server->sendToClient(client->getFd(), usersList);
|
||||
|
||||
std::stringstream endOfNamesMsg;
|
||||
endOfNamesMsg << ":server 366 " << client->getNickname() << " " << channelName << " :End of /NAMES list.\r\n";
|
||||
_server->sendToClient(client->getFd(), endOfNamesMsg.str());
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Client " << client->getNickname() << " joined channel " << channelName;
|
||||
_server->log(ss.str(), MAGENTA);
|
||||
}
|
||||
|
||||
std::string CommandHandler::getUsersList(Channel *channel)
|
||||
{
|
||||
std::vector<Client *> clients = channel->getClients();
|
||||
std::stringstream ss;
|
||||
ss << ":server 353 " << clients[0]->getNickname() << " = " << channel->getName() << " :";
|
||||
for (size_t i = 0; i < clients.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
ss << " ";
|
||||
ss << clients[i]->getNickname();
|
||||
}
|
||||
ss << "\r\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void CommandHandler::handlePingCommand(Client* client, const std::vector<std::string>& tokens)
|
||||
{
|
||||
if (tokens.size() < 2) {
|
||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PING"));
|
||||
if (tokens.size() < 2)
|
||||
{
|
||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client->getFd(), "PING"));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string token = tokens[1];
|
||||
_server->sendToClient(client->getFd(), RPL_PONG(token));
|
||||
std::string serverName = tokens[1];
|
||||
std::string pongMessage = ":" + serverName + " PONG " + serverName + "\r\n";
|
||||
_server->sendToClient(client->getFd(), pongMessage);
|
||||
}
|
||||
|
||||
|
||||
void CommandHandler::handleQuitCommand(Client* client, const std::vector<std::string>& tokens)
|
||||
{
|
||||
std::string reason = "Quit: ";
|
||||
if (tokens.size() > 1)
|
||||
{
|
||||
reason += tokens[1];
|
||||
}
|
||||
|
||||
std::string quitMessage = ":" + client->getNickname() + " QUIT :" + reason + "\r\n";
|
||||
|
||||
std::map<std::string, Channel*>::iterator it;
|
||||
for (it = _server->getChannels().begin(); it != _server->getChannels().end(); ++it)
|
||||
{
|
||||
if (it->second->hasClient(client))
|
||||
{
|
||||
it->second->broadcast(quitMessage, client, _server);
|
||||
it->second->removeClient(client);
|
||||
}
|
||||
}
|
||||
|
||||
_server->sendToClient(client->getFd(), "ERROR :" + reason + "\r\n");
|
||||
_server->disconnectClient(client->getFd());
|
||||
}
|
||||
|
||||
void CommandHandler::handleErrorCommand(Client* client, const std::string &message)
|
||||
{
|
||||
_server->sendToClient(client->getFd(), "ERROR :" + message + "\r\n");
|
||||
_server->disconnectClient(client->getFd());
|
||||
}
|
||||
|
||||
47
ft_irc3/src/Join.cpp
Normal file
47
ft_irc3/src/Join.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Join.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/21 19:51:31 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 20:13:30 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "Join.hpp"
|
||||
|
||||
void JoinHandler::handleJoinCommand(Client *client, const std::string &channelName, Server *server)
|
||||
{
|
||||
std::map<std::string, Channel *> &channels = server->getChannels();
|
||||
Channel *channel;
|
||||
if (channels.find(channelName) == channels.end())
|
||||
{
|
||||
channel = new Channel(channelName);
|
||||
channels[channelName] = channel;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = channels[channelName];
|
||||
}
|
||||
|
||||
channel->addClient(client);
|
||||
std::string joinMessage = ":" + client->getNickname() + " JOIN " + channelName + "\r\n";
|
||||
server->sendToClient(client->getFd(), joinMessage);
|
||||
|
||||
std::string usersList = getUsersList(channel);
|
||||
server->sendToClient(client->getFd(), usersList);
|
||||
}
|
||||
|
||||
std::string JoinHandler::getUsersList(Channel *channel)
|
||||
{
|
||||
std::vector<Client *> clients = channel->getClients();
|
||||
std::string usersList = ":server 353 " + clients[0]->getNickname() + " = " + channel->getName() + " :";
|
||||
for (std::vector<Client *>::iterator it = clients.begin(); it != clients.end(); ++it)
|
||||
{
|
||||
usersList += (*it)->getNickname() + " ";
|
||||
}
|
||||
usersList += "\r\n:server 366 " + clients[0]->getNickname() + " " + channel->getName() + " :End of /NAMES list.\r\n";
|
||||
return usersList;
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 14:18:03 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 20:31:51 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -183,6 +183,10 @@ void Server::sendToClient(int client_fd, const std::string &message)
|
||||
log(ss.str(), BLUE);
|
||||
}
|
||||
}
|
||||
std::map<int, Client *> &Server::getClients()
|
||||
{
|
||||
return _clients;
|
||||
}
|
||||
|
||||
void Server::broadcast(const std::string &message)
|
||||
{
|
||||
@ -214,24 +218,29 @@ void Server::sendChannelListToClient(Client *client)
|
||||
sendToClient(client->getFd(), RPL_LISTEND(client->getFd()));
|
||||
}
|
||||
|
||||
bool Server::MatchFd(const pollfd& pfd, int clientFd)
|
||||
{
|
||||
return pfd.fd == clientFd;
|
||||
}
|
||||
|
||||
void Server::removePollFd(int clientFd)
|
||||
{
|
||||
for (std::vector<struct pollfd>::iterator it = _poll_fds.begin(); it != _poll_fds.end(); ++it)
|
||||
{
|
||||
if (MatchFd(*it, clientFd))
|
||||
{
|
||||
_poll_fds.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Server::disconnectClient(int clientFd)
|
||||
{
|
||||
Client* client = _clients[clientFd];
|
||||
if (client)
|
||||
{
|
||||
log("Disconnecting client: " + client->getNickname(), YELLOW);
|
||||
close(clientFd);
|
||||
|
||||
_clients.erase(clientFd);
|
||||
delete client;
|
||||
}
|
||||
|
||||
struct MatchFd
|
||||
{
|
||||
int fd;
|
||||
MatchFd(int fd) : fd(fd) {}
|
||||
bool operator()(const pollfd& pfd) const { return pfd.fd == fd; }
|
||||
};
|
||||
|
||||
_poll_fds.erase(std::remove_if(_poll_fds.begin(), _poll_fds.end(), MatchFd(clientFd)), _poll_fds.end());
|
||||
removePollFd(clientFd);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Client disconnected: " << clientFd;
|
||||
|
||||
44
ft_irc3/src/Welcome.cpp
Normal file
44
ft_irc3/src/Welcome.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Welcome.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/21 17:53:52 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 19:54:48 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "Welcome.hpp"
|
||||
|
||||
void WelcomeHandler::sendWelcomeMessages(Client *client, Server *server)
|
||||
{
|
||||
server->sendToClient(client->getFd(), RPL_WELCOME(client));
|
||||
server->sendToClient(client->getFd(), RPL_YOURHOST(client));
|
||||
server->sendToClient(client->getFd(), RPL_CREATED(client));
|
||||
server->sendToClient(client->getFd(), RPL_MYINFO(client));
|
||||
server->sendToClient(client->getFd(), RPL_ISUPPORT(client, "MODES=EXAMPLE"));
|
||||
|
||||
sendMotd(client, server);
|
||||
}
|
||||
|
||||
void WelcomeHandler::sendMotd(Client *client, Server *server)
|
||||
{
|
||||
std::ifstream motdFile("motd.txt");
|
||||
if (motdFile.is_open())
|
||||
{
|
||||
std::string line;
|
||||
server->sendToClient(client->getFd(), RPL_MOTDSTART(client));
|
||||
while (std::getline(motdFile, line))
|
||||
{
|
||||
server->sendToClient(client->getFd(), RPL_MOTD(client, line));
|
||||
}
|
||||
server->sendToClient(client->getFd(), RPL_ENDOFMOTD(client));
|
||||
motdFile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
server->sendToClient(client->getFd(), ERR_NOMOTD(client));
|
||||
}
|
||||
}
|
||||
@ -6,14 +6,11 @@
|
||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/05/17 16:09:20 by fgras-ca #+# #+# */
|
||||
/* Updated: 2024/05/21 13:48:51 by fgras-ca ### ########.fr */
|
||||
/* Updated: 2024/05/21 18:03:56 by fgras-ca ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "Who.hpp"
|
||||
#include "Channel.hpp"
|
||||
#include "RPL.hpp"
|
||||
#include <sstream>
|
||||
|
||||
WhoHandler::WhoHandler(Server *server)
|
||||
: _server(server)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user