This commit is contained in:
Ladebeze66 2024-06-06 21:13:37 +02:00
parent d345c1127d
commit 3386ad9772
13 changed files with 170 additions and 139 deletions

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 18:09:05 by fgras-ca #+# #+# */ /* Created: 2024/05/21 18:09:05 by fgras-ca #+# #+# */
/* Updated: 2024/06/01 18:48:32 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 18:41:04 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -23,6 +23,7 @@
#include "InviteHandler.hpp" #include "InviteHandler.hpp"
#include "TopicHandler.hpp" #include "TopicHandler.hpp"
#include "KickHandler.hpp" #include "KickHandler.hpp"
#include "BotFilter.hpp"
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -31,6 +32,7 @@
class Server; class Server;
class Client; class Client;
class Channel; class Channel;
class BotFilter;
class AdditionalCommands class AdditionalCommands
{ {
private: private:

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/06 11:44:44 by fgras-ca #+# #+# */ /* Created: 2024/06/06 11:44:44 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 13:41:41 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 18:50:12 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -25,21 +25,24 @@
#include "Client.hpp" #include "Client.hpp"
#include "Channel.hpp" #include "Channel.hpp"
class Server;
class Client;
class Channel;
class BotFilter class BotFilter
{ {
public: public:
BotFilter(Server *server); BotFilter(Server* server);
void loadBadWords(const std::string &fileName); void loadBadWords(const std::string& fileName);
bool checkMessage(Client *client, Channel *channel, const std::string &message); bool checkMessage(Client* client, Channel* channel, const std::string& message);
void warnClient(Client* client, Channel* channel);
void kickClient(Client* client, Channel* channel);
private: private:
Server *_server; bool containsBadWords(const std::string& message);
Server* _server;
std::vector<std::string> _badWords; std::vector<std::string> _badWords;
std::map<int, int> _warnings; std::map<int, int> _warnings;
bool containsBadWords(const std::string &message);
void warnClient(Client *client, Channel *channel);
void kickClient(Client *client, Channel *channel);
}; };
#endif #endif

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:41:35 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:41:35 by fgras-ca #+# #+# */
/* Updated: 2024/06/04 16:12:23 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 21:03:34 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -28,54 +28,55 @@ class Client;
class Channel class Channel
{ {
public: public:
Channel(const std::string &name); Channel(const std::string &name);
~Channel(); ~Channel();
const std::string &getName() const; const std::string &getName() const;
void addClient(Client *client); void addClient(Client *client);
void removeClient(Client *client); void removeClient(Client *client);
bool isEmpty() const; bool isEmpty() const;
const std::vector<Client *> &getClients() const; const std::vector<Client *> &getClients() const;
void addOperator(Client *client); void addOperator(Client *client);
bool isOperator(Client *client) const; bool isOperator(Client *client) const;
void removeOperator(Client *client); // Ajouté void removeOperator(Client *client);
bool hasClient(Client *client) const; bool hasClient(Client *client) const;
void broadcast(const std::string &message, Client *_client, Server *_server); void broadcast(const std::string &message, Client *_client, Server *_server);
bool isBanned(Client *client) const; bool isBanned(Client *client) const;
bool isFull() const; void banClient(Client *client, Channel *channel);
bool isInviteOnly() const; bool isFull() const;
bool isInvited(Client *client) const; bool isInviteOnly() const;
bool checkKey(const std::string &key) const; bool isInvited(Client *client) const;
const std::string &getTopic() const; bool checkKey(const std::string &key) const;
const std::string &getTopicSetter() const; const std::string &getTopic() const;
time_t getTopicTime() const; const std::string &getTopicSetter() const;
void setTopic(const std::string &topic, const std::string &setter); time_t getTopicTime() const;
std::string getKey(); void setTopic(const std::string &topic, const std::string &setter);
std::string getKey();
void setClientLimit(size_t limit); void setClientLimit(size_t limit);
size_t getClientLimit() const; size_t getClientLimit() const;
void setInviteOnly(bool inviteOnly); void setInviteOnly(bool inviteOnly);
void setKey(const std::string &key); void setKey(const std::string &key);
void setTopicProtection(bool protection); void setTopicProtection(bool protection);
std::string getModes() const; std::string getModes() const;
bool getTopicProtection() const; bool getTopicProtection() const;
void addInvitedClient(Client* client); void addInvitedClient(Client* client);
private:
std::string _name;
std::vector<Client *> _clients;
std::vector<Client *> _operators;
std::set<Client *> _bannedClients;
std::set<Client *> _invitedClients;
std::string _key;
std::string _topic;
std::string _topicSetter;
time_t _topicTime;
size_t _clientLimit;
bool _inviteOnly;
bool _topicProtection;
private:
Server *_server;
std::string _name;
std::vector<Client *> _clients;
std::vector<Client *> _operators;
std::set<int> _bannedClients;
std::set<Client *> _invitedClients;
std::string _key;
std::string _topic;
std::string _topicSetter;
time_t _topicTime;
size_t _clientLimit;
bool _inviteOnly;
bool _topicProtection;
}; };
#endif #endif

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:15:42 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:15:42 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 13:23:23 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 19:59:39 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/19 15:12:47 by fgras-ca #+# #+# */ /* Created: 2024/05/19 15:12:47 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 12:28:50 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 19:36:05 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -541,11 +541,10 @@ inline std::string MODEACCEPTMESSAGE(Client *client, std::string channel, const
return oss.str(); return oss.str();
} }
inline std::string BOTMESSAGE(Client *client, const std::string &channel, const std::string& message)
inline std::string BOTMESSAGE(Client *client, std::string channel, const std::string& message)
{ {
std::ostringstream oss; std::ostringstream oss;
oss << ":" << client->getNickname() << " WARNING " << channel << " " << message << " :" << "\r\n"; oss << ":" << client->getNickname() << " NOTICE " << channel << " :" << message << "\r\n";
return oss.str(); return oss.str();
} }

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:15:13 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:15:13 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 12:04:58 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 18:51:31 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -64,6 +64,7 @@ class Server
void disconnectClient(int clientFd); void disconnectClient(int clientFd);
bool MatchFd(const pollfd& pfd, int clientFd); bool MatchFd(const pollfd& pfd, int clientFd);
void removePollFd(int clientFd); void removePollFd(int clientFd);
BotFilter* getBotFilter() const;
protected: protected:
int _server_fd; int _server_fd;

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/16 15:27:29 by fgras-ca #+# #+# */ /* Created: 2024/05/16 15:27:29 by fgras-ca #+# #+# */
/* Updated: 2024/06/04 13:55:09 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 18:41:08 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -124,7 +124,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
iss >> cmd >> target; iss >> cmd >> target;
getline(iss, message); getline(iss, message);
// Enlever le ':' initial dans le message si présent // Remove the initial ':' in the message if present
if (!message.empty() && message[0] == ':') if (!message.empty() && message[0] == ':')
message = message.substr(1); message = message.substr(1);
@ -142,6 +142,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
std::map<std::string, Channel *> &channels = server->getChannels(); std::map<std::string, Channel *> &channels = server->getChannels();
// Check if the target is a channel
if (channels.find(target) != channels.end()) if (channels.find(target) != channels.end())
{ {
Channel *channel = channels[target]; Channel *channel = channels[target];
@ -152,6 +153,13 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
return; return;
} }
// Check the message with the bot filter before sending it
if (!server->getBotFilter()->checkMessage(client, channel, message))
{
// If the message is inappropriate, the bot filter will handle warnings or kicks
return;
}
std::vector<Client *> channelClients = channel->getClients(); std::vector<Client *> channelClients = channel->getClients();
for (size_t i = 0; i < channelClients.size(); ++i) for (size_t i = 0; i < channelClients.size(); ++i)
@ -159,7 +167,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
if (channelClients[i] != client) if (channelClients[i] != client)
{ {
std::stringstream privMsg; std::stringstream privMsg;
privMsg << ":" << client->getNickname() << " PRIVMSG " << target << message << "\r\n"; privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n";
server->sendToClient(channelClients[i]->getFd(), privMsg.str()); server->sendToClient(channelClients[i]->getFd(), privMsg.str());
} }
} }
@ -170,8 +178,15 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
if (targetClient) if (targetClient)
{ {
// Check the message with the bot filter before sending it
if (!server->getBotFilter()->checkMessage(client, NULL, message))
{
// If the message is inappropriate, the bot filter will handle warnings or kicks
return;
}
std::stringstream privMsg; std::stringstream privMsg;
privMsg << ":" << client->getNickname() << " PRIVMSG " << target << message << "\r\n"; privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n";
server->sendToClient(targetClient->getFd(), privMsg.str()); server->sendToClient(targetClient->getFd(), privMsg.str());
if (targetClient->isAway()) if (targetClient->isAway())
@ -181,7 +196,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
} }
else else
{ {
// Si la cible n'est ni un canal ni un utilisateur existant, envoyer un message d'erreur // If the target is neither a channel nor an existing user, send an error message
server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, target)); server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, target));
} }
} }

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/06 11:45:43 by fgras-ca #+# #+# */ /* Created: 2024/06/06 11:45:43 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 13:37:24 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 21:08:25 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -29,9 +29,9 @@ bool BotFilter::checkMessage(Client *client, Channel *channel, const std::string
if (containsBadWords(message)) if (containsBadWords(message))
{ {
warnClient(client, channel); warnClient(client, channel);
return true; return false; // Message is not allowed
} }
return false; return true; // Message is allowed
} }
bool BotFilter::containsBadWords(const std::string &message) bool BotFilter::containsBadWords(const std::string &message)
@ -52,8 +52,7 @@ void BotFilter::warnClient(Client* client, Channel *channel)
_warnings[fd] += 1; _warnings[fd] += 1;
if (_warnings[fd] >= 3) if (_warnings[fd] >= 3)
{ {
_server->sendToClient(fd, BOTMESSAGE(client, channel->getName(), "You have been kicked from the server for inappropriate language.\r\n")); kickClient(client, channel);
_server->disconnectClient(fd);
} }
else else
{ {
@ -65,6 +64,7 @@ void BotFilter::warnClient(Client* client, Channel *channel)
void BotFilter::kickClient(Client *client, Channel *channel) void BotFilter::kickClient(Client *client, Channel *channel)
{ {
channel->banClient(client, channel); // Ensure the client is banned
_server->sendToClient(client->getFd(), BOTMESSAGE(client, channel->getName(), "You have been kicked for inappropriate language.\r\n")); _server->sendToClient(client->getFd(), BOTMESSAGE(client, channel->getName(), "You have been kicked for inappropriate language.\r\n"));
_server->disconnectClient(client->getFd()); _server->disconnectClient(client->getFd());
} }

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:42:57 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:42:57 by fgras-ca #+# #+# */
/* Updated: 2024/06/04 16:12:22 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 21:03:16 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -68,17 +68,23 @@ void Channel::broadcast(const std::string &message, Client *_client, Server *_se
{ {
if (*it != _client) if (*it != _client)
{ {
// Send message to each client except the sender
_server->sendToClient((*it)->getFd(), message); _server->sendToClient((*it)->getFd(), message);
} }
} }
} }
bool Channel::isBanned(Client *client) const void Channel::banClient(Client *client, Channel *channel)
{ {
return _bannedClients.find(client) != _bannedClients.end(); _bannedClients.insert(client->getFd());
removeClient(client);
_server->sendToClient(client->getFd(), ERR_BANNEDFROMCHAN(client, channel->_name));
_server->log("Client " + client->getNickname() + " Banni", RED);
} }
bool Channel::isBanned(Client *client) const
{
return _bannedClients.find(client->getFd()) != _bannedClients.end();
}
bool Channel::isFull() const bool Channel::isFull() const
{ {
return _clients.size() >= _clientLimit; return _clients.size() >= _clientLimit;

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:17:42 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:17:42 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 13:23:32 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 20:06:29 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 18:32:23 by fgras-ca #+# #+# */ /* Created: 2024/05/15 18:32:23 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 14:09:52 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 19:59:09 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -55,47 +55,49 @@ void ClientManager::handleClient(int client_fd)
return; return;
} }
std::cout << "Received data (" << bytes_received << " bytes): " << client->buffer << std::endl; std::cout << std::string(client->buffer).size() << " client->buffer " << std::string(client->buffer).find('\n') << std::endl;
for (size_t i = 0; client->buffer[i]; i++)
{
std::cout << client->buffer[i] << " .. ";
}
std::cout << std::endl;
if (std::string(client->buffer).find('\n') != std::string::npos) if (std::string(client->buffer).find('\n') != std::string::npos)
{ {
strcat(client->buffer2, client->buffer); strcat(client->buffer2, client->buffer);
std::string fullMessage(client->buffer2);
// Log the combined message
std::cout << "Complete message: " << fullMessage << std::endl;
bool messageAllowed = true; bool messageAllowed = true;
std::set<std::string>::const_iterator it;
if (!client->getChannels().empty()) for (it = client->getChannels().begin(); it != client->getChannels().end(); ++it)
{ {
for (std::set<std::string>::const_iterator it = client->getChannels().begin(); it != client->getChannels().end(); ++it) const std::string& channelName = *it;
Channel* channel = _server->getChannelByName(channelName);
if (channel && !_botFilter->checkMessage(client, channel, std::string(client->buffer2)))
{ {
const std::string& channelName = *it; messageAllowed = false;
Channel* channel = _server->getChannelByName(channelName); break;
if (channel && !_botFilter->checkMessage(client, channel, fullMessage))
{
messageAllowed = false;
break;
}
} }
} }
if (messageAllowed) if (messageAllowed)
{ {
handleClientNext(client_fd, client->buffer2, fullMessage.size()); handleClientNext(client_fd, client->buffer2, std::string(client->buffer2).size());
} }
std::memset(client->buffer2, 0, sizeof(client->buffer2)); std::memset(client->buffer2, 0, std::string(client->buffer2).size());
} }
else else
{ {
strcat(client->buffer2, client->buffer); strcat(client->buffer2, client->buffer);
for (size_t i = 0; client->buffer2[i]; i++)
{
std::cout << client->buffer2[i] << " . ";
}
} }
std::cout << std::endl;
} }
void ClientManager::handleClientNext(int client_fd, char * buffer, int bytes_received) void ClientManager::handleClientNext(int client_fd, char * buffer, int bytes_received)
{ {
std::string message(buffer, bytes_received); std::string message(buffer, bytes_received);

View File

@ -15,19 +15,12 @@
void JoinHandler::handleJoinCommand(Client* client, const std::string& params, Server* server) void JoinHandler::handleJoinCommand(Client* client, const std::string& params, Server* server)
{ {
std::map<std::string, Channel*>& channels = server->getChannels(); std::map<std::string, Channel*>& channels = server->getChannels();
Channel* channel; Channel* channel = NULL;
server->log("Received JOIN command with params: " + params, RED); server->log("Received JOIN command with params: " + params, RED);
// Split params into channel names and keys // Split params into channel names and keys
std::vector<std::string> parts = split(params, " "); std::vector<std::string> parts = split(params, " ");
server->log("Split parts: ", RED);
for (size_t i = 0; i < parts.size(); ++i)
{
std::ostringstream oss;
oss << "Part " << i << ": " << parts[i];
server->log(oss.str(), RED);
}
if (parts.empty()) if (parts.empty())
{ {
server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "JOIN")); server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "JOIN"));
@ -37,23 +30,9 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
std::string channelNames = parts[0]; std::string channelNames = parts[0];
std::string keys = (parts.size() > 1) ? parts[1] : ""; std::string keys = (parts.size() > 1) ? parts[1] : "";
server->log("Split params: channelNames = " + channelNames + ", keys = " + keys, RED);
std::vector<std::string> channelList = split(channelNames, ","); std::vector<std::string> channelList = split(channelNames, ",");
std::vector<std::string> keyList = split(keys, ","); std::vector<std::string> keyList = split(keys, ",");
server->log("channelList: ", RED);
for (size_t i = 0; i < channelList.size(); ++i)
{
server->log(channelList[i], RED);
}
server->log("keyList: ", RED);
for (size_t i = 0; i < keyList.size(); ++i)
{
server->log(keyList[i], RED);
}
for (size_t i = 0; i < channelList.size(); ++i) for (size_t i = 0; i < channelList.size(); ++i)
{ {
const std::string& channelName = channelList[i]; const std::string& channelName = channelList[i];
@ -77,6 +56,17 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
return; return;
} }
if (channels.find(channelName) != channels.end())
{
channel = channels[channelName];
if (channel->isBanned(client))
{
server->sendToClient(client->getFd(), ERR_BANNEDFROMCHAN(client, channelName));
return;
}
}
if (channels.find(channelName) == channels.end()) if (channels.find(channelName) == channels.end())
{ {
channel = new Channel(channelName); channel = new Channel(channelName);
@ -88,9 +78,9 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
channel = channels[channelName]; channel = channels[channelName];
} }
if (channel->isBanned(client)) if (channel == NULL)
{ {
server->sendToClient(client->getFd(), ERR_BANNEDFROMCHAN(client, channelName)); server->log("Channel is NULL after search or creation. This should not happen.", RED);
return; return;
} }
@ -123,28 +113,28 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
void JoinHandler::sendJoinSuccess(Client* client, Channel* channel, Server* server) void JoinHandler::sendJoinSuccess(Client* client, Channel* channel, Server* server)
{ {
std::vector<Client*> clients = channel->getClients(); // Construct the join message and notify all clients in the channel
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it) std::string joinMsg = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n";
{ server->sendToClient(client->getFd(), joinMsg);
std::string joinMsg = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n"; channel->broadcast(joinMsg, client, server);
server->sendToClient((*it)->getFd(), joinMsg);
}
if (!channel->getTopic().empty()) // Send topic information to the new client
{ if (channel->getTopic().empty())
server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
server->sendToClient(client->getFd(), RPL_TOPICWHOTIME(client, channel->getName(), channel->getTopicSetter(), channel->getTopicTime()));
}
else
{ {
server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName())); server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
} }
else
{
server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
}
std::ostringstream oss; // Send channel mode and creation time
oss << RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes()); std::string channelModes = RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes());
oss << RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime()); std::string channelCreationTime = RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
server->sendToClient(client->getFd(), oss.str());
server->sendToClient(client->getFd(), channelModes + channelCreationTime);
// Get the users list and send the names reply
std::string usersList = getUsersList(channel); std::string usersList = getUsersList(channel);
server->sendToClient(client->getFd(), usersList); server->sendToClient(client->getFd(), usersList);
} }
@ -160,6 +150,13 @@ std::string JoinHandler::getUsersList(Channel* channel)
users += (*it)->getNickname() + " "; users += (*it)->getNickname() + " ";
} }
// Remove trailing space
if (!users.empty() && users[users.size() - 1] == ' ')
{
users = users.substr(0, users.size() - 1);
}
// Construct the names reply message
std::ostringstream oss; std::ostringstream oss;
oss << RPL_NAMREPLY(clients[0], channel->getName(), users); oss << RPL_NAMREPLY(clients[0], channel->getName(), users);
oss << RPL_ENDOFNAMES(clients[0], channel->getName()); oss << RPL_ENDOFNAMES(clients[0], channel->getName());

View File

@ -6,14 +6,14 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */
/* Updated: 2024/06/06 13:00:25 by fgras-ca ### ########.fr */ /* Updated: 2024/06/06 18:44:57 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "Server.hpp" #include "Server.hpp"
Server::Server(int port, const std::string &password) Server::Server(int port, const std::string &password)
: _port(port), _password(password), _clientManager(new ClientManager(this)), _commandHandler(new CommandHandler(this)), _modeHandler(new ModeHandler(this)), _topicHandler(new TopicHandler(this)) : _port(port), _password(password), _clientManager(new ClientManager(this)), _commandHandler(new CommandHandler(this)), _modeHandler(new ModeHandler(this)), _topicHandler(new TopicHandler(this)), _botFilter(new BotFilter(this))
{ {
initServer(); initServer();
_botFilter = new BotFilter(this); _botFilter = new BotFilter(this);
@ -249,4 +249,9 @@ void Server::disconnectClient(int clientFd)
std::ostringstream oss; std::ostringstream oss;
oss << "Client disconnected: " << clientFd; oss << "Client disconnected: " << clientFd;
log(oss.str(), YELLOW); log(oss.str(), YELLOW);
}
BotFilter* Server::getBotFilter() const
{
return _botFilter;
} }