modif3005soir

This commit is contained in:
Ladebeze66 2024-05-30 18:50:56 +02:00
parent 7f71877981
commit 4f8d1f3d1f
19 changed files with 436 additions and 244 deletions

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 18:09:05 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 13:10:51 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:10:18 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -21,6 +21,7 @@
#include "RPL.hpp"
#include "Who.hpp"
#include "InviteHandler.hpp"
#include "TopicHandler.hpp"
#include <sstream>
#include <string>

View File

@ -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/30 13:09:11 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 18:32:18 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -39,6 +39,7 @@ public:
const std::vector<Client *> &getClients() const;
void addOperator(Client *client);
bool isOperator(Client *client) const;
void removeOperator(Client *client); // Ajouté
bool hasClient(Client *client) const;
void broadcast(const std::string &message, Client *_client, Server *_server);
@ -59,8 +60,10 @@ public:
void setKey(const std::string &key); // Ajouté
void setTopicProtection(bool protection); // Ajouté
std::string getModes() const; // Ajouté
bool getTopicProtection() const;
void addInvitedClient(Client* client);
private:
std::string _name;
std::vector<Client *> _clients;
@ -74,7 +77,8 @@ private:
size_t _clientLimit;
bool _inviteOnly;
bool _topicProtection; // Ajouté
};
#endif // CHANNEL_HPP

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* InviteHanndler.hpp :+: :+: :+: */
/* InviteHandler.hpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/30 13:01:50 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 13:03:04 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:48:41 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -21,6 +21,7 @@
#include "Client.hpp"
#include "Channel.hpp"
#include "RPL.hpp"
#include "Utils.hpp"
class Server;
class Client;

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 19:51:08 by fgras-ca #+# #+# */
/* Updated: 2024/05/28 14:17:52 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:48:55 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -18,6 +18,7 @@
#include "Server.hpp"
#include "Channel.hpp"
#include "RPL.hpp"
#include "Utils.hpp"
class JoinHandler
{

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/30 11:12:57 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 12:50:39 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 18:40:48 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -41,12 +41,13 @@ private:
void handleUserMode(Client* client, const std::vector<std::string>& tokens);
void handleChannelMode(Client* client, const std::vector<std::string>& tokens);
void setChannelMode(Channel* channel, const std::string& mode, bool adding, const std::string& argument);
void setChannelMode(Client *client, Channel* channel, const std::string& mode, bool adding, const std::string& argument);
//void applyModeB(Channel* channel, bool adding, const std::string& argument);
void applyModeL(Channel* channel, bool adding, const std::string& argument);
void applyModeI(Channel* channel, bool adding);
void applyModeK(Channel* channel, bool adding, const std::string& argument);
void applyModeT(Channel* channel, bool adding);
void applyModeO(Client *client, Channel* channel, bool adding, const std::string& argument);
};
#endif // MODEHANDLER_HPP

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/19 15:12:47 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 13:27:52 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:49:15 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,11 +16,12 @@
#include <string>
#include <sstream>
#include "Client.hpp"
#include "Utils.hpp"
#define SERVER_NAME "IRC_Server"
#define SERVER_VERSION "1.0"
#define USER_MODES "+o"
#define CHANNEL_MODES "i/t/k/o/l"
#define USER_MODES "+o/-o"
#define CHANNEL_MODES "none"
#define CHANNEL_MODES_WITH_PARAMS "None"
@ -43,21 +44,21 @@ inline std::string RPL_WELCOME(Client* client) {
inline std::string RPL_YOURHOST(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 002 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 002 " << CLIENT_NICK(client)
<< " :Your host is " << SERVER_NAME << ", running version " << SERVER_VERSION << "\r\n";
return oss.str();
}
inline std::string RPL_CREATED(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 003 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 003 " << CLIENT_NICK(client)
<< " :This server was created " << __DATE__ << "\r\n";
return oss.str();
}
inline std::string RPL_MYINFO(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 004 " << CLIENT_FD(client) << " "
oss << ":" << SERVER_NAME << " 004 " << CLIENT_NICK(client) << " "
<< SERVER_NAME << " " << SERVER_VERSION << " "
<< USER_MODES << " " << CHANNEL_MODES << " "
<< CHANNEL_MODES_WITH_PARAMS << "\r\n";
@ -66,111 +67,110 @@ inline std::string RPL_MYINFO(Client* client) {
inline std::string RPL_ISUPPORT(Client* client, const std::string& tokens) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 005 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 005 " << CLIENT_NICK(client)
<< " " << tokens << " :are supported by this server\r\n";
return oss.str();
}
inline std::string RPL_UMODEIS(int clientFd, const std::string& modes) {
inline std::string RPL_UMODEIS(Client* client, const std::string& modes) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 221 " << clientFd << " :" << modes << "\r\n";
oss << ":" << SERVER_NAME << " 221 " << CLIENT_NICK(client) << " :" << modes << "\r\n";
return oss.str();
}
inline std::string RPL_AWAY(int clientFd, const std::string& target, const std::string& message) {
inline std::string RPL_AWAY(Client *client, const std::string& target, const std::string& message) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 301 " << clientFd << " " << target << " :" << message << "\r\n";
oss << ":" << SERVER_NAME << " 301 " << CLIENT_NICK(client) << " " << target << " :" << message << "\r\n";
return oss.str();
}
// WHOIS Command RPLs
inline std::string RPL_WHOISUSER(int clientFd, Client* target)
inline std::string RPL_WHOISUSER(Client *client, Client* target)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 311 " << clientFd << " " << CLIENT_NICK(target) << " "
oss << ":" << SERVER_NAME << " 311 " << CLIENT_NICK(client) << " " << CLIENT_NICK(target) << " "
<< CLIENT_USER(target) << " " << CLIENT_HOST(target) << " * :" << CLIENT_REALNAME(target) << "\r\n";
return oss.str();
}
inline std::string RPL_WHOISSERVER(int clientFd, const std::string& targetNick, const std::string& serverInfo)
inline std::string RPL_WHOISSERVER(Client *client, const std::string& targetNick, const std::string& serverInfo)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 312 " << clientFd << " " << targetNick << " " << SERVER_NAME
oss << ":" << SERVER_NAME << " 312 " << CLIENT_NICK(client) << " " << targetNick << " " << SERVER_NAME
<< " :" << serverInfo << "\r\n";
return oss.str();
}
inline std::string RPL_ENDOFWHO(int clientFd, const std::string& channel)
inline std::string RPL_ENDOFWHO(Client *client, const std::string& channel)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 315 " << clientFd << " " << channel << " :End of /WHO list.\r\n";
oss << ":" << SERVER_NAME << " 315 " << CLIENT_NICK(client) << " " << channel << " :End of /WHO list.\r\n";
return oss.str();
}
inline std::string RPL_ENDOFWHOIS(int clientFd, const std::string& targetNick)
inline std::string RPL_ENDOFWHOIS(Client *client, const std::string& targetNick)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 318 " << clientFd << " " << targetNick << " :End of /WHOIS list.\r\n";
oss << ":" << SERVER_NAME << " 318 " << CLIENT_NICK(client) << " " << targetNick << " :End of /WHOIS list.\r\n";
return oss.str();
}
// RPL Channel List Messages
inline std::string RPL_LIST(int clientFd, const std::string& channel, int numVisible, const std::string& topic)
inline std::string RPL_LIST(Client *client, const std::string& channel, int numVisible, const std::string& topic)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 322 " << clientFd << " " << channel << " " << numVisible << " :" << topic << "\r\n";
oss << ":" << SERVER_NAME << " 322 " << CLIENT_NICK(client) << " " << channel << " " << numVisible << " :" << topic << "\r\n";
return oss.str();
}
inline std::string RPL_LISTEND(int clientFd)
inline std::string RPL_LISTEND(Client *client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 323 " << clientFd << " :End of /LIST\r\n";
oss << ":" << SERVER_NAME << " 323 " << CLIENT_NICK(client) << " :End of /LIST\r\n";
return oss.str();
}
// RPL Mode Messages
inline std::string RPL_CHANNELMODEIS(int clientFd, const std::string& channel, const std::string& mode)
inline std::string RPL_CHANNELMODEIS(Client *client, const std::string& channel, const std::string& mode)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 324 " << clientFd << " " << channel << " " << mode << "\r\n";
oss << ":" << SERVER_NAME << " 324 " << CLIENT_NICK(client) << " " << channel << " " << mode << "\r\n";
return oss.str();
}
inline std::string RPL_CREATIONTIME(int clientFd, const std::string& channel, time_t creationTime) {
inline std::string RPL_CREATIONTIME(Client *client, const std::string& channel, time_t creationTime) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 329 " << clientFd << " " << channel << " " << creationTime << "\r\n";
oss << ":" << SERVER_NAME << " 329 " << CLIENT_NICK(client) << " " << channel << " " << creationTime << "\r\n";
return oss.str();
}
inline std::string RPL_NOTOPIC(Client* client, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 331 " << CLIENT_NICK(client) << " " << channel
<< " :No topic is set\r\n";
oss << ":" << SERVER_NAME << " 331 " << CLIENT_NICK(client) << " " << channel << " :No topic is set\r\n";
return oss.str();
}
inline std::string RPL_TOPIC(Client* client, const std::string& channel, const std::string& topic) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 332 " << CLIENT_NICK(client) << " " << channel << " :" << topic << "\r\n";
return oss.str();
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 332 " << CLIENT_NICK(client) << " " << channel << " :" << topic << "\r\n";
return oss.str();
}
inline std::string RPL_TOPICWHOTIME(Client* client, const std::string& channel, const std::string& setter, time_t setTime) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 333 " << CLIENT_NICK(client) << " " << channel << " " << setter << " " << setTime << "\r\n";
return oss.str();
}
inline std::string RPL_INVITELIST(Client *client, const std::string& channel, const std::string& inviteMask) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 333 " << CLIENT_NICK(client) << " " << channel << " " << setter << " " << setTime << "\r\n";
oss << ":" << SERVER_NAME << " 336 " << CLIENT_NICK(client) << " " << channel << " " << inviteMask << "\r\n";
return oss.str();
}
inline std::string RPL_INVITELIST(int clientFd, const std::string& channel, const std::string& inviteMask) {
inline std::string RPL_ENDOFINVITELIST(Client *client, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 336 " << clientFd << " " << channel << " " << inviteMask << "\r\n";
return oss.str();
}
inline std::string RPL_ENDOFINVITELIST(int clientFd, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 337 " << clientFd << " " << channel << " :End of channel invite list\r\n";
oss << ":" << SERVER_NAME << " 337 " << CLIENT_NICK(client) << " " << channel << " :End of channel invite list\r\n";
return oss.str();
}
@ -181,15 +181,15 @@ inline std::string RPL_INVITING(Client* client, const std::string& channel, cons
return oss.str();
}
inline std::string RPL_EXCEPTLIST(int clientFd, const std::string& channel, const std::string& exceptionMask) {
inline std::string RPL_EXCEPTLIST(Client *client, const std::string& channel, const std::string& exceptionMask) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 348 " << clientFd << " " << channel << " " << exceptionMask << "\r\n";
oss << ":" << SERVER_NAME << " 348 " << CLIENT_NICK(client) << " " << channel << " " << exceptionMask << "\r\n";
return oss.str();
}
inline std::string RPL_ENDOFEXCEPTLIST(int clientFd, const std::string& channel) {
inline std::string RPL_ENDOFEXCEPTLIST(Client *client, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 349 " << clientFd << " " << channel << " :End of channel exception list\r\n";
oss << ":" << SERVER_NAME << " 349 " << CLIENT_NICK(client) << " " << channel << " :End of channel exception list\r\n";
return oss.str();
}
@ -214,56 +214,56 @@ inline std::string RPL_ENDOFNAMES(Client* client, const std::string& channel) {
return oss.str();
}
inline std::string RPL_BANLIST(int clientFd, const std::string& channel, const std::string& banMask) {
inline std::string RPL_BANLIST(Client *client, const std::string& channel, const std::string& banMask) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 367 " << clientFd << " " << channel << " " << banMask << "\r\n";
oss << ":" << SERVER_NAME << " 367 " << CLIENT_NICK(client) << " " << channel << " " << banMask << "\r\n";
return oss.str();
}
inline std::string RPL_ENDOFBANLIST(int clientFd, const std::string& channel) {
inline std::string RPL_ENDOFBANLIST(Client *client, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 368 " << clientFd << " " << channel << " :End of channel ban list\r\n";
oss << ":" << SERVER_NAME << " 368 " << CLIENT_NICK(client) << " " << channel << " :End of channel ban list\r\n";
return oss.str();
}
inline std::string RPL_MOTD(Client* client, const std::string& line) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 372 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 372 " << CLIENT_NICK(client)
<< " :- " << line << "\r\n";
return oss.str();
}
inline std::string RPL_MOTDSTART(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 375 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 375 " << CLIENT_NICK(client)
<< " :- " << SERVER_NAME << " Message of the day - \r\n";
return oss.str();
}
inline std::string RPL_ENDOFMOTD(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 376 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 376 " << CLIENT_NICK(client)
<< " :End of /MOTD command.\r\n";
return oss.str();
}
inline std::string ERR_NOSUCHNICK(int clientFd, const std::string& nick)
inline std::string ERR_NOSUCHNICK(Client *client, const std::string& nick)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 401 " << clientFd << " " << nick << " :No such nick/channel\r\n";
oss << ":" << SERVER_NAME << " 401 " << CLIENT_NICK(client) << " " << nick << " :No such nick/channel\r\n";
return oss.str();
}
inline std::string ERR_NOSUCHCHANNEL(int clientFd, const std::string& channel)
inline std::string ERR_NOSUCHCHANNEL(Client *client, const std::string& channel)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 403 " << clientFd << " " << channel << " :No such channel\r\n";
oss << ":" << SERVER_NAME << " 403 " << CLIENT_NICK(client) << " " << channel << " :No such channel\r\n";
return oss.str();
}
inline std::string ERR_CANNOTSENDTOCHAN(int clientFd, const std::string& channel) {
inline std::string ERR_CANNOTSENDTOCHAN(Client *client, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 404 " << clientFd << " " << channel << " :Cannot send to channel\r\n";
oss << ":" << SERVER_NAME << " 404 " << CLIENT_NICK(client) << " " << channel << " :Cannot send to channel\r\n";
return oss.str();
}
@ -277,19 +277,19 @@ inline std::string ERR_TOOMANYCHANNELS(Client* client, const std::string& channe
inline std::string ERR_NOORIGIN(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 409 " << CLIENT_FD(client) << " :No origin specified\r\n";
oss << ":" << SERVER_NAME << " 409 " << CLIENT_NICK(client) << " :No origin specified\r\n";
return oss.str();
}
inline std::string ERR_NORECIPIENT(int clientFd, const std::string& command) {
inline std::string ERR_NORECIPIENT(Client *client, const std::string& command) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 411 " << clientFd << " :No recipient given (" << command << ")\r\n";
oss << ":" << SERVER_NAME << " 411 " << CLIENT_NICK(client) << " :No recipient given (" << command << ")\r\n";
return oss.str();
}
inline std::string ERR_NOTEXTTOSEND(int clientFd) {
inline std::string ERR_NOTEXTTOSEND(Client *client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 412 " << clientFd << " :No text to send\r\n";
oss << ":" << SERVER_NAME << " 412 " << CLIENT_NICK(client) << " :No text to send\r\n";
return oss.str();
}
@ -301,7 +301,7 @@ inline std::string ERR_UNKNOWNCOMMAND(Client* client, const std::string& command
inline std::string ERR_NOMOTD(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 422 " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " 422 " << CLIENT_NICK(client)
<< " :MOTD File is missing\r\n";
return oss.str();
}
@ -309,34 +309,34 @@ inline std::string ERR_NOMOTD(Client* client) {
inline std::string ERR_NONICKNAMEGIVEN(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 431 " << CLIENT_FD(client) << " :No nickname given\r\n";
oss << ":" << SERVER_NAME << " 431 " << CLIENT_NICK(client) << " :No nickname given\r\n";
return oss.str();
}
inline std::string ERR_ERRONEUSNICKNAME(Client* client, const std::string& nickname)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 432 " << CLIENT_FD(client) << " " << nickname << " :Erroneous nickname\r\n";
oss << ":" << SERVER_NAME << " 432 " << CLIENT_NICK(client) << " " << nickname << " :Erroneous nickname\r\n";
return oss.str();
}
inline std::string ERR_NICKNAMEINUSE(Client* client, const std::string& nickname)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 433 " << CLIENT_FD(client) << " " << nickname << " :Nickname is already in use\r\n";
oss << ":" << SERVER_NAME << " 433 " << CLIENT_NICK(client) << " " << nickname << " :Nickname is already in use\r\n";
return oss.str();
}
inline std::string ERR_USERNOTINCHANNEL(int clientFd, const std::string& nick, const std::string& channel) {
inline std::string ERR_USERNOTINCHANNEL(Client *client, const std::string& nick, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 441 " << clientFd << " " << nick << " " << channel
oss << ":" << SERVER_NAME << " 441 " << CLIENT_NICK(client) << " " << nick << " " << channel
<< " :They aren't on that channel\r\n";
return oss.str();
}
inline std::string ERR_NOTONCHANNEL(int clientFd, const std::string& channel) {
inline std::string ERR_NOTONCHANNEL(Client *client, const std::string& channel) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 442 " << clientFd << " " << channel << " :You're not on that channel\r\n";
oss << ":" << SERVER_NAME << " 442 " << CLIENT_NICK(client) << " " << channel << " :You're not on that channel\r\n";
return oss.str();
}
@ -351,7 +351,7 @@ inline std::string ERR_USERONCHANNEL(Client* client, const std::string& nick, co
inline std::string ERR_NOTREGISTERED(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 451 " << CLIENT_FD(client) << " :You have not registered\r\n";
oss << ":" << SERVER_NAME << " 451 " << CLIENT_NICK(client) << " :You have not registered\r\n";
return oss.str();
}
@ -360,21 +360,21 @@ inline std::string ERR_NOTREGISTERED(Client* client)
inline std::string ERR_NEEDMOREPARAMS(Client* client, const std::string& command)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 461 " << CLIENT_FD(client) << " " << command << " :Not enough parameters\r\n";
oss << ":" << SERVER_NAME << " 461 " << CLIENT_NICK(client) << " " << command << " :Not enough parameters\r\n";
return oss.str();
}
inline std::string ERR_ALREADYREGISTERED(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 462 " << CLIENT_FD(client) << " :You may not reregister\r\n";
oss << ":" << SERVER_NAME << " 462 " << CLIENT_NICK(client) << " :You may not reregister\r\n";
return oss.str();
}
inline std::string ERR_PASSWDMISMATCH(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 464 " << CLIENT_FD(client) << " :Password incorrect\r\n";
oss << ":" << SERVER_NAME << " 464 " << CLIENT_NICK(client) << " :Password incorrect\r\n";
return oss.str();
}
@ -414,29 +414,29 @@ inline std::string ERR_BADCHANMASK(Client* client, const std::string& channel) {
return oss.str();
}
inline std::string RPL_NOCHANMODES(int clientFd, const std::string& channel)
inline std::string RPL_NOCHANMODES(Client *client, const std::string& channel)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 477 " << clientFd << " " << channel << " :Channel doesn't support modes\r\n";
oss << ":" << SERVER_NAME << " 477 " << CLIENT_NICK(client) << " " << channel << " :Channel doesn't support modes\r\n";
return oss.str();
}
inline std::string ERR_CHANOPRIVSNEEDED(int clientFd, const std::string& channel)
inline std::string ERR_CHANOPRIVSNEEDED(Client *client, const std::string& channel)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 482 " << clientFd << " " << channel << " :You're not channel operator\r\n";
oss << ":" << SERVER_NAME << " 482 " << CLIENT_NICK(client) << " " << channel << " :You're not channel operator\r\n";
return oss.str();
}
inline std::string ERR_UMODEUNKNOWNFLAG(int clientFd) {
inline std::string ERR_UMODEUNKNOWNFLAG(Client *client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 501 " << clientFd << " :Unknown MODE flag\r\n";
oss << ":" << SERVER_NAME << " 501 " << CLIENT_NICK(client) << " :Unknown MODE flag\r\n";
return oss.str();
}
inline std::string ERR_USERSDONTMATCH(int clientFd) {
inline std::string ERR_USERSDONTMATCH(Client *client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 502 " << clientFd << " :Cannot change mode for other users\r\n";
oss << ":" << SERVER_NAME << " 502 " << CLIENT_NICK(client) << " :Cannot change mode for other users\r\n";
return oss.str();
}
@ -449,26 +449,26 @@ inline std::string RPL_PONG(const std::string& token)
}
// CAP Command RPLs
inline std::string RPL_CAP(int clientFd, const std::string& subcommand, const std::string& capabilities)
inline std::string RPL_CAP(Client *client, const std::string& subcommand, const std::string& capabilities)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " CAP " << clientFd << " " << subcommand << " :" << capabilities << "\r\n";
oss << ":" << SERVER_NAME << " CAP " << CLIENT_NICK(client) << " " << subcommand << " :" << capabilities << "\r\n";
return oss.str();
}
inline std::string RPL_PASSACCEPTED(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " NOTICE " << CLIENT_FD(client)
oss << ":" << SERVER_NAME << " NOTICE " << CLIENT_NICK(client)
<< " :Password accepted!\r\n";
return oss.str();
}
// Add this function to handle the CAP END response
inline std::string RPL_CAPEND(int clientFd)
inline std::string RPL_CAPEND(Client *client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " CAP " << clientFd << " END\r\n";
oss << ":" << SERVER_NAME << " CAP " << CLIENT_NICK(client) << " END\r\n";
return oss.str();
}

View File

@ -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/30 12:20:53 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:13:41 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -21,6 +21,7 @@
#include "AdditionalCommands.hpp"
#include "RPL.hpp"
#include "ModeHandler.hpp"
#include "TopicHandler.hpp"
#include <sys/socket.h>
#include <netinet/in.h>
@ -41,6 +42,7 @@ class ClientManager;
class CommandHandler;
class AdditionalCommands;
class ModeHandler;
class TopicHandler;
class Server
{
@ -74,10 +76,12 @@ protected:
ClientManager *_clientManager;
CommandHandler *_commandHandler;
ModeHandler *_modeHandler;
TopicHandler *_topicHandler;
friend class ClientManager;
friend class CommandHandler;
friend class ModeHandler;
friend class TopicHandler;
private:
void initServer();

View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* TopicHandler.hpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/30 17:04:33 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 17:47:56 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef TOPIC_HANDLER_HPP
#define TOPIC_HANDLER_HPP
#include <string>
#include <vector>
#include <sstream>
#include "Server.hpp"
#include "Client.hpp"
#include "Channel.hpp"
#include "Utils.hpp"
class TopicHandler
{
public:
TopicHandler(Server* server);
void handleTopicCommand(Client* client, const std::string& command);
private:
void viewTopic(Client* client, Channel* channel);
void changeTopic(Client* client, Channel* channel, const std::string& topic);
Server* _server;
};
#endif

View File

@ -6,7 +6,7 @@
/* 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 */
/* Updated: 2024/05/30 17:48:13 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -15,6 +15,7 @@
#include "Client.hpp"
#include "Server.hpp"
#include "Utils.hpp"
#include <string>
class WelcomeHandler

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/05/30 13:07:33 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:12:30 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -40,6 +40,11 @@ void AdditionalCommands::processCommand(Client *client, const std::string &comma
InviteHandler inviteHandler(_server);
inviteHandler.handleInviteCommand(client, command);
}
else if (command.find("TOPIC") == 0)
{
TopicHandler topichandler(_server);
topichandler.handleTopicCommand(client, command);
}
else if (command.find("LIST") == 0)
{
broadcastChannelList(client, _server);
@ -57,9 +62,9 @@ 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)
{
server->sendToClient(client->getFd(), RPL_LIST(client->getFd(), it->first, it->second->getClients().size(), "Existing channel"));
server->sendToClient(client->getFd(), RPL_LIST(client, it->first, it->second->getClients().size(), "Existing channel"));
}
server->sendToClient(client->getFd(), RPL_LISTEND(client->getFd()));
server->sendToClient(client->getFd(), RPL_LISTEND(client));
}
// Fonction pour gérer la commande PART
@ -80,13 +85,13 @@ void AdditionalCommands::handlePartCommand(Server *server, Client *client, const
for (size_t i = 0; i < channels.size(); ++i) {
std::string &channelName = channels[i];
if (channelMap.find(channelName) == channelMap.end()) {
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client->getFd(), channelName));
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
continue;
}
Channel *channel = channelMap[channelName];
if (!channel->hasClient(client)) {
server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client->getFd(), channelName));
server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
continue;
}
@ -119,12 +124,12 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
message = message.substr(1);
if (target.empty()) {
server->sendToClient(client->getFd(), ERR_NORECIPIENT(client->getFd(), "PRIVMSG"));
server->sendToClient(client->getFd(), ERR_NORECIPIENT(client, "PRIVMSG"));
return;
}
if (message.empty()) {
server->sendToClient(client->getFd(), ERR_NOTEXTTOSEND(client->getFd()));
server->sendToClient(client->getFd(), ERR_NOTEXTTOSEND(client));
return;
}
@ -138,7 +143,7 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
// Vérifier les conditions spéciales du canal (ex: ban, modération)
if (channel->isBanned(client)) {
server->sendToClient(client->getFd(), ERR_CANNOTSENDTOCHAN(client->getFd(), target));
server->sendToClient(client->getFd(), ERR_CANNOTSENDTOCHAN(client, target));
return;
}
@ -167,13 +172,13 @@ void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, co
server->sendToClient(targetClient->getFd(), privMsg.str());
if (targetClient->isAway()) {
server->sendToClient(client->getFd(), RPL_AWAY(client->getFd(), targetClient->getNickname(), targetClient->getAwayMessage()));
server->sendToClient(client->getFd(), RPL_AWAY(client, targetClient->getNickname(), targetClient->getAwayMessage()));
}
}
else
{
// Si la cible n'est ni un canal ni un utilisateur existant, envoyer un message d'erreur
server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client->getFd(), target));
server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, target));
}
}
}

View File

@ -6,14 +6,14 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:42:57 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 13:09:45 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 18:33:19 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "Channel.hpp"
Channel::Channel(const std::string &name)
: _name(name), _clients(), _operators(), _bannedClients(), _invitedClients(), _key(""), _topic(""), _topicSetter(""), _topicTime(0), _clientLimit(50), _inviteOnly(false) {}
: _name(name), _clients(), _operators(), _bannedClients(), _invitedClients(), _key(""), _topic(""), _topicSetter(""), _topicTime(0), _clientLimit(50), _inviteOnly(false), _topicProtection(false) {}
Channel::~Channel() {}
@ -52,6 +52,11 @@ bool Channel::isOperator(Client *client) const
return std::find(_operators.begin(), _operators.end(), client) != _operators.end();
}
void Channel::removeOperator(Client *client)
{
_operators.erase(std::remove(_operators.begin(), _operators.end(), client), _operators.end());
}
bool Channel::hasClient(Client *client) const
{
return std::find(_clients.begin(), _clients.end(), client) != _clients.end();
@ -148,3 +153,8 @@ std::string Channel::getModes() const {
if (_topicProtection) modes += 't';
return modes;
}
bool Channel::getTopicProtection() const
{
return _topicProtection;
}

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 18:26:34 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 12:39:58 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 16:53:35 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -83,11 +83,11 @@ void CommandHandler::handleCapCommand(Client* client, const std::vector<std::str
if (subcommand == "LS")
{
_server->sendToClient(client->getFd(), RPL_CAP(client->getFd(), "LS", capabilities));
_server->sendToClient(client->getFd(), RPL_CAP(client, "LS", capabilities));
}
else if (subcommand == "LIST")
{
_server->sendToClient(client->getFd(), RPL_CAP(client->getFd(), "LIST", capabilities));
_server->sendToClient(client->getFd(), RPL_CAP(client, "LIST", capabilities));
}
else if (subcommand == "REQ")
{
@ -98,11 +98,11 @@ void CommandHandler::handleCapCommand(Client* client, const std::vector<std::str
}
std::string requestedCapabilities = tokens[2];
// For simplicity, we assume all requested capabilities are accepted
_server->sendToClient(client->getFd(), RPL_CAP(client->getFd(), "ACK", requestedCapabilities));
_server->sendToClient(client->getFd(), RPL_CAP(client, "ACK", requestedCapabilities));
}
else if (subcommand == "END")
{
_server->sendToClient(client->getFd(), RPL_CAPEND(client->getFd()));
_server->sendToClient(client->getFd(), RPL_CAPEND(client));
}
else
{

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/30 13:02:09 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 13:08:33 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 16:53:59 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -26,23 +26,23 @@ void InviteHandler::handleInviteCommand(Client* client, const std::string& comma
Channel* channel = _server->getChannelByName(channelName);
if (!channel) {
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client->getFd(), channelName));
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
return;
}
if (!channel->hasClient(client)) {
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client->getFd(), channelName));
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
return;
}
if (!channel->isOperator(client) && channel->isInviteOnly()) {
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client->getFd(), channelName));
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
return;
}
Client* targetClient = _server->getClientByName(nickname);
if (!targetClient) {
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client->getFd(), nickname));
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, nickname));
return;
}

View File

@ -113,7 +113,7 @@ void JoinHandler::handleJoinCommand(Client *client, const std::string &channelNa
if (channelName[0] != '#' && channelName[0] != '&')
{
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client->getFd(), channelName));
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
return;
}
@ -191,4 +191,3 @@ std::string JoinHandler::getUsersList(Channel *channel)
oss << RPL_ENDOFNAMES(clients[0], channel->getName());
return oss.str();
}

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/30 11:13:08 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 13:33:36 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 18:46:37 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,141 +14,184 @@
ModeHandler::ModeHandler(Server* server) : _server(server) {}
void ModeHandler::handleModeCommand(Client* client, const std::string& command) {
void ModeHandler::handleModeCommand(Client* client, const std::string& command)
{
_server->log("Received MODE command: " + command, "\033[1;34m");
std::vector<std::string> tokens = split(command, " \n\r\t");
std::vector<std::string> tokens = split(command, " \n\r\t");
if (tokens.size() < 2) {
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "MODE"));
if (tokens.size() < 2) {
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "MODE"));
_server->log("MODE command error: Need more parameters", "\033[1;31m");
return;
}
return;
}
std::string target = tokens[1];
if (target[0] == '#' || target[0] == '&') {
std::string target = tokens[1];
if (target[0] == '#' || target[0] == '&') {
_server->log("Handling channel mode for target: " + target, "\033[1;34m");
handleChannelMode(client, tokens);
} else {
handleChannelMode(client, tokens);
} else {
_server->log("Handling user mode for target: " + target, "\033[1;34m");
handleUserMode(client, tokens);
}
handleUserMode(client, tokens);
}
}
void ModeHandler::handleUserMode(Client* client, const std::vector<std::string>& tokens) {
std::string target = tokens[1];
if (target != client->getNickname()) {
_server->sendToClient(client->getFd(), ERR_USERSDONTMATCH(client->getFd()));
void ModeHandler::handleUserMode(Client* client, const std::vector<std::string>& tokens)
{
_server->log("Entered handleUserMode", "\033[1;34m");
std::string target = tokens[1];
_server->log("User mode target: " + target, "\033[1;34m");
if (target != client->getNickname()) {
_server->sendToClient(client->getFd(), ERR_USERSDONTMATCH(client));
_server->log("User mode error: Users don't match", "\033[1;31m");
return;
}
return;
}
if (tokens.size() == 2) {
_server->sendToClient(client->getFd(), RPL_UMODEIS(client->getFd(), "")); // Ajout de la chaîne vide pour les modes utilisateur
_server->log("Sent user modes to client", "\033[1;32m");
} else {
std::string modeString = tokens[2];
// Gestion des modes utilisateur (ajout ou suppression)
// Par exemple, vous pouvez gérer l'ajout ou la suppression du mode invisible ici
_server->log("Updating user modes: " + modeString, "\033[1;34m");
}
if (tokens.size() == 2) {
_server->sendToClient(client->getFd(), RPL_UMODEIS(client, ""));
_server->log("Sent user modes to client", "\033[1;32m");
} else {
std::string modeString = tokens[2];
_server->log("Updating user modes: " + modeString, "\033[1;34m");
// Additional logging or mode handling logic can be added here
}
}
void ModeHandler::handleChannelMode(Client* client, const std::vector<std::string>& tokens) {
std::string channelName = tokens[1];
Channel* channel = _server->getChannelByName(channelName);
if (!channel) {
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client->getFd(), channelName));
void ModeHandler::handleChannelMode(Client* client, const std::vector<std::string>& tokens)
{
_server->log("Entered handleChannelMode", "\033[1;34m");
std::string channelName = tokens[1];
_server->log("Channel mode target: " + channelName, "\033[1;34m");
Channel* channel = _server->getChannelByName(channelName);
if (!channel) {
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
_server->log("Channel mode error: No such channel " + channelName, "\033[1;31m");
return;
}
return;
}
if (tokens.size() == 2) {
// Retourner les modes actuels du canal
std::ostringstream oss;
oss << RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes());
oss << RPL_CREATIONTIME(client->getFd(), channel->getName(), channel->getTopicTime());
_server->sendToClient(client->getFd(), oss.str());
_server->log("Sent channel modes to client", "\033[1;32m");
return;
}
if (tokens.size() == 2) {
std::ostringstream oss;
oss << RPL_CHANNELMODEIS(client, channel->getName(), channel->getModes());
oss << RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
_server->sendToClient(client->getFd(), oss.str());
_server->log("Sent channel modes to client", "\033[1;32m");
return;
}
if (!channel->isOperator(client)) {
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client->getFd(), channelName));
if (!channel->isOperator(client)) {
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
_server->log("Channel mode error: Channel operator privileges needed for " + channelName, "\033[1;31m");
return;
}
return;
}
std::string modeString = tokens[2];
bool adding = true;
size_t argIndex = 3;
std::string modeString = tokens[2];
bool adding = true;
size_t argIndex = 3;
for (size_t i = 0; i < modeString.length(); ++i) {
char mode = modeString[i];
if (mode == '+') {
adding = true;
} else if (mode == '-') {
adding = false;
} else if (mode == 'b' || mode == 'l' || mode == 'i' || mode == 'k' || mode == 't') {
std::string argument;
if (argIndex < tokens.size()) {
argument = tokens[argIndex++];
}
setChannelMode(channel, std::string(1, mode), adding, argument);
} else {
_server->sendToClient(client->getFd(), ERR_UNKNOWNMODE(client, mode, channelName));
}
}
for (size_t i = 0; i < modeString.length(); ++i) {
char mode = modeString[i];
if (mode == '+') {
adding = true;
_server->log("Adding mode: " + std::string(1, mode), "\033[1;34m");
} else if (mode == '-') {
adding = false;
_server->log("Removing mode: " + std::string(1, mode), "\033[1;34m");
} else if (mode == 'b' || mode == 'l' || mode == 'i' || mode == 'k' || mode == 't') {
std::string argument;
if (argIndex < tokens.size()) {
argument = tokens[argIndex++];
}
setChannelMode(client, channel, std::string(1, mode), adding, argument);
} else {
_server->sendToClient(client->getFd(), ERR_UNKNOWNMODE(client, mode, channelName));
_server->log("Unknown mode: " + std::string(1, mode), "\033[1;31m");
}
}
}
void ModeHandler::setChannelMode(Channel* channel, const std::string& mode, bool adding, const std::string& argument) {
/*if (mode == "b") {
applyModeB(channel, adding, argument);
}*/
if (mode == "l") {
applyModeL(channel, adding, argument);
} else if (mode == "i") {
applyModeI(channel, adding);
} else if (mode == "k") {
applyModeK(channel, adding, argument);
} else if (mode == "t") {
applyModeT(channel, adding);
}
void ModeHandler::setChannelMode(Client *client, Channel* channel, const std::string& mode, bool adding, const std::string& argument)
{
_server->log("Setting channel mode: " + mode + " Adding: " + (adding ? "true" : "false") + " Argument: " + argument, "\033[1;32m");
if (mode == "l")
{
applyModeL(channel, adding, argument);
}
else if (mode == "i")
{
applyModeI(channel, adding);
}
else if (mode == "k")
{
applyModeK(channel, adding, argument);
}
else if (mode == "t")
{
applyModeT(channel, adding);
}
else if (mode == "o")
applyModeO(client, channel, adding, argument);
}
/*void ModeHandler::applyModeB(Channel* channel, bool adding, const std::string& argument) {
// Implémentation de l'ajout ou de la suppression de bannissements
// Note : Vous pouvez ajouter des méthodes à la classe Channel pour gérer la liste des bannissements
if (adding) {
// Ajouter le masque à la liste des bannissements
// channel->banClient(argument);
} else {
// Supprimer le masque de la liste des bannissements
// channel->unbanClient(argument);
}
}*/
void ModeHandler::applyModeL(Channel* channel, bool adding, const std::string& argument) {
if (adding) {
int limit = std::atoi(argument.c_str());
channel->setClientLimit(limit);
} else {
channel->setClientLimit(0); // Retirer la limite
}
void ModeHandler::applyModeL(Channel* channel, bool adding, const std::string& argument)
{
if (adding) {
int limit = std::atoi(argument.c_str());
std::ostringstream oss;
oss << limit;
_server->log("Applying mode L: Setting limit to " + oss.str(), "\033[1;32m");
channel->setClientLimit(limit);
} else {
_server->log("Applying mode L: Removing limit", "\033[1;31m");
channel->setClientLimit(0);
}
}
void ModeHandler::applyModeI(Channel* channel, bool adding) {
channel->setInviteOnly(adding);
void ModeHandler::applyModeI(Channel* channel, bool adding)
{
_server->log("Applying mode I: " + std::string(adding ? "Setting invite-only" : "Removing invite-only"), "\033[1;32m");
channel->setInviteOnly(adding);
}
void ModeHandler::applyModeK(Channel* channel, bool adding, const std::string& argument) {
if (adding) {
channel->setKey(argument);
} else {
channel->setKey("");
}
void ModeHandler::applyModeK(Channel* channel, bool adding, const std::string& argument)
{
if (adding) {
_server->log("Applying mode K: Setting key to " + argument, "\033[1;32m");
channel->setKey(argument);
} else {
_server->log("Applying mode K: Removing key", "\033[1;31m");
channel->setKey("");
}
}
void ModeHandler::applyModeT(Channel* channel, bool adding) {
channel->setTopicProtection(adding);
void ModeHandler::applyModeT(Channel* channel, bool adding)
{
_server->log("Applying mode T: " + std::string(adding ? "Setting topic protection" : "Removing topic protection"), "\033[1;32m");
channel->setTopicProtection(adding);
}
void ModeHandler::applyModeO(Client* client, Channel* channel, bool adding, const std::string& argument)
{
Client* targetClient = _server->getClientByName(argument);
if (!targetClient) {
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, argument));
_server->log("Mode o error: No such client " + argument, "\033[1;31m");
return;
}
if (!channel->hasClient(targetClient)) {
_server->sendToClient(client->getFd(), ERR_USERNOTINCHANNEL(client, argument, channel->getName()));
_server->log("Mode o error: Client " + argument + " not in channel " + channel->getName(), "\033[1;31m");
return;
}
if (adding) {
_server->log("Applying mode o: Adding operator " + argument, "\033[1;32m");
channel->addOperator(targetClient);
std::string message = ":" + client->getNickname() + " MODE " + channel->getName() + " +o " + targetClient->getNickname() + "\r\n";
channel->broadcast(message, NULL, _server);
} else {
_server->log("Applying mode o: Removing operator " + argument, "\033[1;31m");
channel->removeOperator(targetClient);
std::string message = ":" + client->getNickname() + " MODE " + channel->getName() + " -o " + targetClient->getNickname() + "\r\n";
channel->broadcast(message, NULL, _server);
}
}

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/05/30 12:18:40 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 17:14:19 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))
: _port(port), _password(password), _clientManager(new ClientManager(this)), _commandHandler(new CommandHandler(this)), _modeHandler(new ModeHandler(this)), _topicHandler(new TopicHandler(this))
{
initServer();
}
@ -164,7 +164,7 @@ void Server::handleServerCommands()
void Server::log(const std::string &message, const std::string &color)
{
std::cout << color << message << "\033[0m" << std::endl;
std::cout << color << message << std::endl;
}
void Server::sendToClient(int client_fd, const std::string &message)
@ -221,9 +221,9 @@ void Server::sendChannelListToClient(Client *client)
std::map<std::string, Channel *> &channels = getChannels();
for (std::map<std::string, Channel *>::iterator it = channels.begin(); it != channels.end(); ++it)
{
sendToClient(client->getFd(), RPL_LIST(client->getFd(), it->first, it->second->getClients().size(), "Existing channel"));
sendToClient(client->getFd(), RPL_LIST(client, it->first, it->second->getClients().size(), "Existing channel"));
}
sendToClient(client->getFd(), RPL_LISTEND(client->getFd()));
sendToClient(client->getFd(), RPL_LISTEND(client));
}
bool Server::MatchFd(const pollfd& pfd, int clientFd)

View File

@ -0,0 +1,84 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* TopicHandler.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/30 17:04:58 by fgras-ca #+# #+# */
/* Updated: 2024/05/30 18:05:42 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "TopicHandler.hpp"
TopicHandler::TopicHandler(Server* server) : _server(server) {}
void TopicHandler::handleTopicCommand(Client* client, const std::string& command)
{
_server->log("Received TOPIC command: " + command, "\033[1;34m");
std::vector<std::string> tokens = split(command, " \n\r\t");
if (tokens.size() < 2) {
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "TOPIC"));
_server->log("TOPIC command error: Need more parameters", "\033[1;31m");
return;
}
std::string channelName = tokens[1];
Channel* channel = _server->getChannelByName(channelName);
if (!channel) {
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
_server->log("TOPIC command error: No such channel " + channelName, "\033[1;31m");
return;
}
if (!channel->hasClient(client)) {
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
_server->log("TOPIC command error: Client not on channel " + channelName, "\033[1;31m");
return;
}
if (tokens.size() == 2) {
viewTopic(client, channel);
} else {
size_t topicStart = command.find(" :");
std::string topic = (topicStart != std::string::npos) ? command.substr(topicStart + 2) : "";
changeTopic(client, channel, topic);
}
}
void TopicHandler::viewTopic(Client* client, Channel* channel)
{
if (channel->getTopic().empty()) {
_server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
_server->log("No topic set for channel " + channel->getName(), "\033[1;32m");
} else {
_server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
_server->sendToClient(client->getFd(), RPL_TOPICWHOTIME(client, channel->getName(), channel->getTopicSetter(), channel->getTopicTime()));
_server->log("Sent topic info for channel " + channel->getName(), "\033[1;32m");
}
}
void TopicHandler::changeTopic(Client* client, Channel* channel, const std::string& topic)
{
if (channel->getTopicProtection() && !channel->isOperator(client)) {
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channel->getName()));
_server->log("TOPIC command error: Channel operator privileges needed for " + channel->getName(), "\033[1;31m");
return;
}
if (topic == channel->getTopic()) {
_server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
_server->log("TOPIC unchanged for channel " + channel->getName(), "\033[1;32m");
return;
}
channel->setTopic(topic, client->getNickname());
std::vector<Client*> clients = channel->getClients();
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it) {
_server->sendToClient((*it)->getFd(), ":" + client->getNickname() + " TOPIC " + channel->getName() + " :" + topic + "\r\n");
}
_server->log("Changed topic for channel " + channel->getName() + " to: " + topic, GREEN);
}

View File

@ -6,7 +6,7 @@
/* 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 */
/* Updated: 2024/05/30 16:43:14 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -18,7 +18,7 @@ void WelcomeHandler::sendWelcomeMessages(Client *client, Server *server)
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"));
server->sendToClient(client->getFd(), RPL_ISUPPORT(client, "i/t/k/o/l"));
sendMotd(client, server);
}

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/17 16:09:20 by fgras-ca #+# #+# */
/* Updated: 2024/05/28 14:33:29 by fgras-ca ### ########.fr */
/* Updated: 2024/05/30 16:56:03 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -43,7 +43,7 @@ void WhoHandler::handleWhoCommand(Client *client, const std::string &command)
}
}
_server->sendToClient(client->getFd(), RPL_ENDOFWHO(client->getFd(), mask));
_server->sendToClient(client->getFd(), RPL_ENDOFWHO(client, mask));
}
void WhoHandler::handleWhoisCommand(Client *client, const std::string &command)
@ -61,11 +61,11 @@ void WhoHandler::handleWhoisCommand(Client *client, const std::string &command)
Client *targetClient = _server->getClientByName(target);
if (!targetClient)
{
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client->getFd(), target));
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, target));
return;
}
_server->sendToClient(client->getFd(), RPL_WHOISUSER(client->getFd(), targetClient));
_server->sendToClient(client->getFd(), RPL_WHOISSERVER(client->getFd(), target, "IRC server info"));
_server->sendToClient(client->getFd(), RPL_ENDOFWHOIS(client->getFd(), target));
_server->sendToClient(client->getFd(), RPL_WHOISUSER(client, targetClient));
_server->sendToClient(client->getFd(), RPL_WHOISSERVER(client, target, "IRC server info"));
_server->sendToClient(client->getFd(), RPL_ENDOFWHOIS(client, target));
}