mirror of
https://github.com/Ladebeze66/ft_irc.git
synced 2025-12-17 06:28:03 +01:00
174 lines
5.1 KiB
C++
174 lines
5.1 KiB
C++
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* ClientManager.cpp :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* 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 */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include "ClientManager.hpp"
|
|
|
|
ClientManager::ClientManager(Server *server)
|
|
: _server(server)
|
|
{
|
|
_botFilter = new BotFilter(server);
|
|
_botFilter->loadBadWords("badwords.txt");
|
|
}
|
|
|
|
void ClientManager::acceptClient()
|
|
{
|
|
int client_fd = accept(_server->_server_fd, NULL, NULL);
|
|
if (client_fd < 0)
|
|
{
|
|
_server->log("Failed to accept client.", RED);
|
|
return;
|
|
}
|
|
|
|
Client *newClient = new Client(client_fd, "", "", "", "", "");
|
|
_server->_clients[client_fd] = newClient;
|
|
struct pollfd client_pollfd;
|
|
client_pollfd.fd = client_fd;
|
|
client_pollfd.events = POLLIN;
|
|
_server->_poll_fds.push_back(client_pollfd);
|
|
|
|
std::stringstream ss;
|
|
ss << "Client attempting connection: " << client_fd;
|
|
_server->log(ss.str(), YELLOW);
|
|
}
|
|
|
|
void ClientManager::handleClient(int client_fd)
|
|
{
|
|
Client* client = _server->getClients()[client_fd];
|
|
std::memset(client->buffer, 0, sizeof(client->buffer));
|
|
int bytes_received = recv(client_fd, client->buffer, sizeof(client->buffer), 0);
|
|
|
|
if (bytes_received <= 0)
|
|
{
|
|
std::ostringstream oss;
|
|
oss << "Client disconnected: " << client_fd;
|
|
_server->log(oss.str(), RED);
|
|
removeClient(client_fd);
|
|
return;
|
|
}
|
|
|
|
std::cout << "Received data (" << bytes_received << " bytes): " << client->buffer << 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())
|
|
{
|
|
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, fullMessage))
|
|
{
|
|
messageAllowed = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (messageAllowed)
|
|
{
|
|
handleClientNext(client_fd, client->buffer2, fullMessage.size());
|
|
}
|
|
|
|
std::memset(client->buffer2, 0, sizeof(client->buffer2));
|
|
}
|
|
else
|
|
{
|
|
strcat(client->buffer2, client->buffer);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ClientManager::handleClientNext(int client_fd, char * buffer, int bytes_received)
|
|
{
|
|
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;
|
|
}
|
|
|
|
std::istringstream message_stream(message);
|
|
std::string line;
|
|
|
|
while (std::getline(message_stream, line))
|
|
{
|
|
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];
|
|
if (client)
|
|
{
|
|
_server->log("Removing client: " + client->getNickname(), YELLOW);
|
|
|
|
std::map<std::string, Channel*>::iterator it = _server->_channels.begin();
|
|
while (it != _server->_channels.end())
|
|
{
|
|
it->second->removeClient(client);
|
|
if (it->second->isEmpty())
|
|
{
|
|
delete it->second;
|
|
std::map<std::string, Channel*>::iterator it_to_delete = it++;
|
|
_server->_channels.erase(it_to_delete);
|
|
}
|
|
else
|
|
{
|
|
++it;
|
|
}
|
|
}
|
|
delete client;
|
|
_server->_clients.erase(clientFd);
|
|
}
|
|
|
|
std::vector<struct pollfd>::iterator it_poll = _server->_poll_fds.begin();
|
|
while (it_poll != _server->_poll_fds.end())
|
|
{
|
|
if (it_poll->fd == clientFd)
|
|
{
|
|
_server->_poll_fds.erase(it_poll);
|
|
break;
|
|
}
|
|
++it_poll;
|
|
}
|
|
|
|
std::stringstream ss;
|
|
ss << "Client disconnected: " << clientFd;
|
|
_server->log(ss.str(), YELLOW);
|
|
}
|