This commit is contained in:
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> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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;
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] == ':')
message = message.substr(1);
@@ -142,6 +142,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
std::map<std::string, Channel *> &channels = server->getChannels();
// Check if the target is a channel
if (channels.find(target) != channels.end())
{
Channel *channel = channels[target];
@@ -152,6 +153,13 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
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();
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)
{
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());
}
}
@@ -170,8 +178,15 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
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;
privMsg << ":" << client->getNickname() << " PRIVMSG " << target << message << "\r\n";
privMsg << ":" << client->getNickname() << " PRIVMSG " << target << " :" << message << "\r\n";
server->sendToClient(targetClient->getFd(), privMsg.str());
if (targetClient->isAway())
@@ -181,7 +196,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
}
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));
}
}

View File

@@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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))
{
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)
@@ -52,8 +52,7 @@ void BotFilter::warnClient(Client* client, Channel *channel)
_warnings[fd] += 1;
if (_warnings[fd] >= 3)
{
_server->sendToClient(fd, BOTMESSAGE(client, channel->getName(), "You have been kicked from the server for inappropriate language.\r\n"));
_server->disconnectClient(fd);
kickClient(client, channel);
}
else
{
@@ -65,6 +64,7 @@ void BotFilter::warnClient(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->disconnectClient(client->getFd());
}

View File

@@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)
{
// Send message to each client except the sender
_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
{
return _clients.size() >= _clientLimit;

View File

@@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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;
}
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)
{
strcat(client->buffer2, client->buffer);
std::string fullMessage(client->buffer2);
// Log the combined message
std::cout << "Complete message: " << fullMessage << std::endl;
bool messageAllowed = true;
if (!client->getChannels().empty())
std::set<std::string>::const_iterator it;
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;
Channel* channel = _server->getChannelByName(channelName);
if (channel && !_botFilter->checkMessage(client, channel, fullMessage))
{
messageAllowed = false;
break;
}
messageAllowed = false;
break;
}
}
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
{
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)
{
std::string message(buffer, bytes_received);

View File

@@ -15,19 +15,12 @@
void JoinHandler::handleJoinCommand(Client* client, const std::string& params, Server* server)
{
std::map<std::string, Channel*>& channels = server->getChannels();
Channel* channel;
Channel* channel = NULL;
server->log("Received JOIN command with params: " + params, RED);
// Split params into channel names and keys
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())
{
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 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> 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)
{
const std::string& channelName = channelList[i];
@@ -77,6 +56,17 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
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())
{
channel = new Channel(channelName);
@@ -88,9 +78,9 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
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;
}
@@ -123,28 +113,28 @@ void JoinHandler::handleJoinCommand(Client* client, const std::string& params, S
void JoinHandler::sendJoinSuccess(Client* client, Channel* channel, Server* server)
{
std::vector<Client*> clients = channel->getClients();
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it)
{
std::string joinMsg = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n";
server->sendToClient((*it)->getFd(), joinMsg);
}
// Construct the join message and notify all clients in the channel
std::string joinMsg = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n";
server->sendToClient(client->getFd(), joinMsg);
channel->broadcast(joinMsg, client, server);
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
// Send topic information to the new client
if (channel->getTopic().empty())
{
server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
}
else
{
server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
}
std::ostringstream oss;
oss << RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes());
oss << RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
server->sendToClient(client->getFd(), oss.str());
// Send channel mode and creation time
std::string channelModes = RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes());
std::string channelCreationTime = RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
server->sendToClient(client->getFd(), channelModes + channelCreationTime);
// Get the users list and send the names reply
std::string usersList = getUsersList(channel);
server->sendToClient(client->getFd(), usersList);
}
@@ -160,6 +150,13 @@ std::string JoinHandler::getUsersList(Channel* channel)
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;
oss << RPL_NAMREPLY(clients[0], channel->getName(), users);
oss << RPL_ENDOFNAMES(clients[0], channel->getName());

View File

@@ -6,14 +6,14 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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"
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();
_botFilter = new BotFilter(this);
@@ -249,4 +249,9 @@ void Server::disconnectClient(int clientFd)
std::ostringstream oss;
oss << "Client disconnected: " << clientFd;
log(oss.str(), YELLOW);
}
BotFilter* Server::getBotFilter() const
{
return _botFilter;
}