mirror of
https://github.com/Ladebeze66/ft_irc.git
synced 2025-12-17 06:28:03 +01:00
ajoutKick
This commit is contained in:
parent
49537a7282
commit
0c3c24a2f1
@ -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/05/30 17:10:18 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:48:32 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -22,30 +22,27 @@
|
|||||||
#include "Who.hpp"
|
#include "Who.hpp"
|
||||||
#include "InviteHandler.hpp"
|
#include "InviteHandler.hpp"
|
||||||
#include "TopicHandler.hpp"
|
#include "TopicHandler.hpp"
|
||||||
|
#include "KickHandler.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
// Forward declarations
|
|
||||||
class Server;
|
class Server;
|
||||||
class Client;
|
class Client;
|
||||||
class Channel;
|
class Channel;
|
||||||
class CommandHandler;
|
|
||||||
|
|
||||||
class AdditionalCommands
|
class AdditionalCommands
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Server *_server;
|
Server *_server;
|
||||||
CommandHandler *_commandhandler;
|
|
||||||
//InviteHandler *_inviteHandler;
|
public:
|
||||||
public:
|
AdditionalCommands(Server *server);
|
||||||
AdditionalCommands(Server *server);
|
void processCommand(Client *client, const std::string &command);
|
||||||
void processCommand(Client *client, const std::string &command);
|
void broadcastChannelList(Client *client, Server *server);
|
||||||
void broadcastChannelList(Client *client, Server *server);
|
void handlePartCommand(Server *server, Client *client, const std::string &command);
|
||||||
void handlePartCommand(Server *server, Client *client, const std::string &command);
|
void handleNickCommand(Server *server, Client *client, const std::string &command);
|
||||||
void handleNickCommand(Server *server, Client *client, const std::string &command);
|
void handlePrivmsgCommand(Server *server, Client *client, const std::string &command);
|
||||||
void handlePrivmsgCommand(Server *server, Client *client, const std::string &command);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ADDITIONALCOMMANDS_HPP
|
#endif
|
||||||
|
|||||||
@ -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/05/30 18:32:18 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:49:53 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -28,57 +28,53 @@ 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); // Ajouté
|
||||||
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 isFull() const;
|
||||||
|
bool isInviteOnly() const;
|
||||||
|
bool isInvited(Client *client) const;
|
||||||
|
bool checkKey(const std::string &key) const;
|
||||||
|
const std::string &getTopic() const;
|
||||||
|
const std::string &getTopicSetter() const;
|
||||||
|
time_t getTopicTime() const;
|
||||||
|
void setTopic(const std::string &topic, const std::string &setter);
|
||||||
|
|
||||||
// Ajouts
|
void setClientLimit(size_t limit);
|
||||||
bool isBanned(Client *client) const;
|
size_t getClientLimit() const;
|
||||||
bool isFull() const;
|
void setInviteOnly(bool inviteOnly);
|
||||||
bool isInviteOnly() const;
|
void setKey(const std::string &key);
|
||||||
bool isInvited(Client *client) const;
|
void setTopicProtection(bool protection);
|
||||||
bool checkKey(const std::string &key) const;
|
std::string getModes() const;
|
||||||
const std::string &getTopic() const;
|
bool getTopicProtection() const;
|
||||||
const std::string &getTopicSetter() const;
|
void addInvitedClient(Client* client);
|
||||||
time_t getTopicTime() const;
|
|
||||||
void setTopic(const std::string &topic, const std::string &setter);
|
|
||||||
|
|
||||||
void setClientLimit(size_t limit); // Ajouté
|
|
||||||
size_t getClientLimit() const; // Ajouté
|
|
||||||
void setInviteOnly(bool inviteOnly); // Ajouté
|
|
||||||
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;
|
|
||||||
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; // Ajouté
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHANNEL_HPP
|
#endif
|
||||||
|
|||||||
@ -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/05/31 11:31:54 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:47:36 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -35,13 +35,13 @@ public:
|
|||||||
void authenticate();
|
void authenticate();
|
||||||
bool isOperator() const;
|
bool isOperator() const;
|
||||||
void setOperator(bool isOperator);
|
void setOperator(bool isOperator);
|
||||||
|
|
||||||
// Ajout des méthodes pour la gestion du statut "away"
|
// Ajout des méthodes pour la gestion du statut "away"
|
||||||
bool isAway() const;
|
bool isAway() const;
|
||||||
const std::string &getAwayMessage() const;
|
const std::string &getAwayMessage() const;
|
||||||
void setAwayMessage(const std::string &message);
|
void setAwayMessage(const std::string &message);
|
||||||
void setAway(bool away);
|
void setAway(bool away);
|
||||||
const std::string &getkey() const;
|
std::string getKey() const;
|
||||||
void setkey(const std::string &key);
|
void setkey(const std::string &key);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -58,5 +58,4 @@ private:
|
|||||||
std::string _key;
|
std::string _key;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIENT_HPP
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -6,15 +6,13 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/15 18:30:07 by fgras-ca #+# #+# */
|
/* Created: 2024/05/15 18:30:07 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/28 14:17:28 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:50:30 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef CLIENTMANAGER_HPP
|
#ifndef CLIENTMANAGER_HPP
|
||||||
#define CLIENTMANAGER_HPP
|
#define CLIENTMANAGER_HPP
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include "Client.hpp"
|
#include "Client.hpp"
|
||||||
#include "Channel.hpp"
|
#include "Channel.hpp"
|
||||||
#include "Server.hpp"
|
#include "Server.hpp"
|
||||||
@ -33,21 +31,22 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Server;
|
class Server;
|
||||||
class Client;
|
class Client;
|
||||||
|
|
||||||
class ClientManager
|
class ClientManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClientManager(Server *server);
|
ClientManager(Server *server);
|
||||||
void acceptClient();
|
void acceptClient();
|
||||||
void handleClient(int client_fd);
|
void handleClient(int client_fd);
|
||||||
void removeClient(int client_fd);
|
void removeClient(int client_fd);
|
||||||
|
|
||||||
|
private:
|
||||||
private:
|
Server *_server;
|
||||||
Server *_server;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -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:14:12 by fgras-ca #+# #+# */
|
/* Created: 2024/05/15 18:14:12 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 12:42:22 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:47:51 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -59,4 +59,4 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COMMANDHANDLER_HPP
|
#endif
|
||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/30 13:01:50 by fgras-ca #+# #+# */
|
/* Created: 2024/05/30 13:01:50 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 17:48:41 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:51:00 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -27,13 +27,14 @@ class Server;
|
|||||||
class Client;
|
class Client;
|
||||||
class Channel;
|
class Channel;
|
||||||
|
|
||||||
class InviteHandler {
|
class InviteHandler
|
||||||
public:
|
{
|
||||||
InviteHandler(Server* server);
|
public:
|
||||||
void handleInviteCommand(Client* client, const std::string& command);
|
InviteHandler(Server* server);
|
||||||
|
void handleInviteCommand(Client* client, const std::string& command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Server* _server;
|
Server* _server;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INVITEHANDLER_HPP
|
#endif
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/21 19:51:08 by fgras-ca #+# #+# */
|
/* Created: 2024/05/21 19:51:08 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 17:48:55 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:51:10 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -19,15 +19,22 @@
|
|||||||
#include "Channel.hpp"
|
#include "Channel.hpp"
|
||||||
#include "RPL.hpp"
|
#include "RPL.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
#include "Server.hpp"
|
||||||
|
#include "Channel.hpp"
|
||||||
|
#include "Client.hpp"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
class JoinHandler
|
class JoinHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void handleJoinCommand(Client *client, const std::string &channelName, Server *server);
|
void handleJoinCommand(Client *client, const std::string &channelName, Server *server);
|
||||||
|
void sendJoinSuccess(Client *client, Channel *channel, Server *server);
|
||||||
|
std::string getUsersList(Channel *channel);
|
||||||
|
|
||||||
private:
|
|
||||||
void sendJoinSuccess(Client *client, Channel *channel, Server *server);
|
|
||||||
std::string getUsersList(Channel *channel);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // JOIN_HPP
|
#endif
|
||||||
|
|||||||
35
ft_irc3/includes/KickHandler.hpp
Normal file
35
ft_irc3/includes/KickHandler.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* KickHandler.hpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2024/06/01 16:59:42 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2024/06/01 18:51:26 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef KICKHANDLER_HPP
|
||||||
|
#define KICKHANDLER_HPP
|
||||||
|
|
||||||
|
#include "Server.hpp"
|
||||||
|
#include "Client.hpp"
|
||||||
|
#include "Channel.hpp"
|
||||||
|
#include "Utils.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
class KickHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KickHandler(Server* server);
|
||||||
|
void handleKickCommand(Client* client, const std::string& command);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Server* _server;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/30 11:12:57 by fgras-ca #+# #+# */
|
/* Created: 2024/05/30 11:12:57 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/31 11:21:04 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:52:10 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -31,23 +31,22 @@ class Channel;
|
|||||||
|
|
||||||
class ModeHandler
|
class ModeHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ModeHandler(Server* server);
|
ModeHandler(Server* server);
|
||||||
void handleModeCommand(Client* client, const std::string& command);
|
void handleModeCommand(Client* client, const std::string& command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Server* _server;
|
Server* _server;
|
||||||
|
|
||||||
void handleUserMode(Client* client, const std::vector<std::string>& tokens);
|
void handleUserMode(Client* client, const std::vector<std::string>& tokens);
|
||||||
void handleChannelMode(Client* client, const std::vector<std::string>& tokens);
|
void handleChannelMode(Client* client, const std::vector<std::string>& tokens);
|
||||||
|
|
||||||
void setChannelMode(Client *client, 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(Client *client, 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 applyModeI(Channel* channel, bool adding);
|
void applyModeK(Client *client, Channel* channel, bool adding, const std::string& argument);
|
||||||
void applyModeK(Client *client, Channel* channel, bool adding, const std::string& argument);
|
void applyModeT(Channel* channel, bool adding);
|
||||||
void applyModeT(Channel* channel, bool adding);
|
void applyModeO(Client *client, Channel* channel, bool adding, const std::string& argument);
|
||||||
void applyModeO(Client *client, Channel* channel, bool adding, const std::string& argument);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MODEHANDLER_HPP
|
#endif
|
||||||
|
|||||||
@ -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/05/31 11:18:49 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 18:58:37 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "Client.hpp"
|
#include "Client.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
@ -25,16 +26,14 @@
|
|||||||
#define CHANNEL_MODES_WITH_PARAMS "l"
|
#define CHANNEL_MODES_WITH_PARAMS "l"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Macros pour accéder aux champs du client
|
|
||||||
#define CLIENT_FD(client) (client->getFd())
|
#define CLIENT_FD(client) (client->getFd())
|
||||||
#define CLIENT_NICK(client) ((client)->getNickname())
|
#define CLIENT_NICK(client) ((client)->getNickname())
|
||||||
#define CLIENT_USER(client) ((client)->getUser())
|
#define CLIENT_USER(client) ((client)->getUser())
|
||||||
#define CLIENT_HOST(client) ((client)->getHost())
|
#define CLIENT_HOST(client) ((client)->getHost())
|
||||||
#define CLIENT_REALNAME(client) ((client)->getRealName())
|
#define CLIENT_REALNAME(client) ((client)->getRealName())
|
||||||
|
|
||||||
// Fonctions pour générer les réponses RPL
|
inline std::string RPL_WELCOME(Client* client)
|
||||||
inline std::string RPL_WELCOME(Client* client) {
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 001 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 001 " << CLIENT_NICK(client)
|
||||||
<< " :Welcome to the Internet Relay Network " << CLIENT_NICK(client)
|
<< " :Welcome to the Internet Relay Network " << CLIENT_NICK(client)
|
||||||
@ -42,21 +41,24 @@ inline std::string RPL_WELCOME(Client* client) {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_YOURHOST(Client* client) {
|
inline std::string RPL_YOURHOST(Client* client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 002 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 002 " << CLIENT_NICK(client)
|
||||||
<< " :Your host is " << SERVER_NAME << ", running version " << SERVER_VERSION << "\r\n";
|
<< " :Your host is " << SERVER_NAME << ", running version " << SERVER_VERSION << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_CREATED(Client* client) {
|
inline std::string RPL_CREATED(Client* client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 003 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 003 " << CLIENT_NICK(client)
|
||||||
<< " :This server was created " << __DATE__ << "\r\n";
|
<< " :This server was created " << __DATE__ << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_MYINFO(Client* client) {
|
inline std::string RPL_MYINFO(Client* client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 004 " << CLIENT_NICK(client) << " "
|
oss << ":" << SERVER_NAME << " 004 " << CLIENT_NICK(client) << " "
|
||||||
<< SERVER_NAME << " " << SERVER_VERSION << " "
|
<< SERVER_NAME << " " << SERVER_VERSION << " "
|
||||||
@ -65,26 +67,28 @@ inline std::string RPL_MYINFO(Client* client) {
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_ISUPPORT(Client* client, const std::string& tokens) {
|
inline std::string RPL_ISUPPORT(Client* client, const std::string& tokens)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 005 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 005 " << CLIENT_NICK(client)
|
||||||
<< " " << tokens << " :are supported by this server\r\n";
|
<< " " << tokens << " :are supported by this server\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_UMODEIS(Client* client, const std::string& modes) {
|
inline std::string RPL_UMODEIS(Client* client, const std::string& modes)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 221 " << CLIENT_NICK(client) << " :" << modes << "\r\n";
|
oss << ":" << SERVER_NAME << " 221 " << CLIENT_NICK(client) << " :" << modes << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_AWAY(Client *client, 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;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 301 " << CLIENT_NICK(client) << " " << target << " :" << message << "\r\n";
|
oss << ":" << SERVER_NAME << " 301 " << CLIENT_NICK(client) << " " << target << " :" << message << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// WHOIS Command RPLs
|
|
||||||
inline std::string RPL_WHOISUSER(Client *client, Client* target)
|
inline std::string RPL_WHOISUSER(Client *client, Client* target)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -115,7 +119,6 @@ inline std::string RPL_ENDOFWHOIS(Client *client, const std::string& targetNick)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPL Channel List Messages
|
|
||||||
inline std::string RPL_LIST(Client *client, 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;
|
std::ostringstream oss;
|
||||||
@ -130,75 +133,83 @@ inline std::string RPL_LISTEND(Client *client)
|
|||||||
return oss.str();
|
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;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 324 " << CLIENT_NICK(client) << " " << channel << " " << mode << "\r\n";
|
oss << ":" << SERVER_NAME << " 324 " << clientFd << " " << channel << " " << mode << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_CREATIONTIME(Client *client, const std::string& channel, time_t creationTime) {
|
inline std::string RPL_CREATIONTIME(Client *client, const std::string& channel, time_t creationTime)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 329 " << CLIENT_NICK(client) << " " << channel << " " << creationTime << "\r\n";
|
oss << ":" << SERVER_NAME << " 329 " << CLIENT_NICK(client) << " " << channel << " " << creationTime << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_NOTOPIC(Client* client, const std::string& channel) {
|
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";
|
std::ostringstream oss;
|
||||||
return oss.str();
|
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) {
|
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";
|
std::ostringstream oss;
|
||||||
return oss.str();
|
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) {
|
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";
|
std::ostringstream oss;
|
||||||
return oss.str();
|
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) {
|
inline std::string RPL_INVITELIST(Client *client, const std::string& channel, const std::string& inviteMask)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 336 " << CLIENT_NICK(client) << " " << channel << " " << inviteMask << "\r\n";
|
oss << ":" << SERVER_NAME << " 336 " << CLIENT_NICK(client) << " " << channel << " " << inviteMask << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_ENDOFINVITELIST(Client *client, const std::string& channel) {
|
inline std::string RPL_ENDOFINVITELIST(Client *client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 337 " << CLIENT_NICK(client) << " " << 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();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ajoutez cette fonction pour RPL_INVITING
|
inline std::string RPL_INVITING(Client* client, const std::string& channel)
|
||||||
inline std::string RPL_INVITING(Client* client, const std::string& channel, const std::string& nick) {
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 341 " << CLIENT_NICK(client) << " " << nick << " " << channel << "\r\n";
|
oss << ":" << SERVER_NAME << " 341 " << CLIENT_NICK(client) << " " << CLIENT_NICK(client) << " " << channel << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_EXCEPTLIST(Client *client, 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;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 348 " << CLIENT_NICK(client) << " " << channel << " " << exceptionMask << "\r\n";
|
oss << ":" << SERVER_NAME << " 348 " << CLIENT_NICK(client) << " " << channel << " " << exceptionMask << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_ENDOFEXCEPTLIST(Client *client, const std::string& channel) {
|
inline std::string RPL_ENDOFEXCEPTLIST(Client *client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 349 " << CLIENT_NICK(client) << " " << 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();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_NAMREPLY(Client* client, const std::string& channel, const std::string& users) {
|
inline std::string RPL_NAMREPLY(Client* client, const std::string& channel, const std::string& users)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 353 " << CLIENT_NICK(client) << " = " << channel << " :" << users << "\r\n";
|
oss << ":" << SERVER_NAME << " 353 " << CLIENT_NICK(client) << " = " << channel << " :" << users << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
// WHO Command RPLs
|
|
||||||
inline std::string RPL_WHOREPLY(const std::string& channel, Client* target)
|
inline std::string RPL_WHOREPLY(const std::string& channel, Client* target)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -208,39 +219,45 @@ inline std::string RPL_WHOREPLY(const std::string& channel, Client* target)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_ENDOFNAMES(Client* client, const std::string& channel) {
|
inline std::string RPL_ENDOFNAMES(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 366 " << CLIENT_NICK(client) << " " << channel << " :End of /NAMES list\r\n";
|
oss << ":" << SERVER_NAME << " 366 " << CLIENT_NICK(client) << " " << channel << " :End of /NAMES list\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_BANLIST(Client *client, 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;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 367 " << CLIENT_NICK(client) << " " << channel << " " << banMask << "\r\n";
|
oss << ":" << SERVER_NAME << " 367 " << CLIENT_NICK(client) << " " << channel << " " << banMask << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_ENDOFBANLIST(Client *client, const std::string& channel) {
|
inline std::string RPL_ENDOFBANLIST(Client *client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 368 " << CLIENT_NICK(client) << " " << 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();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_MOTD(Client* client, const std::string& line) {
|
inline std::string RPL_MOTD(Client* client, const std::string& line)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 372 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 372 " << CLIENT_NICK(client)
|
||||||
<< " :- " << line << "\r\n";
|
<< " :- " << line << "\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_MOTDSTART(Client* client) {
|
inline std::string RPL_MOTDSTART(Client* client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 375 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 375 " << CLIENT_NICK(client)
|
||||||
<< " :- " << SERVER_NAME << " Message of the day - \r\n";
|
<< " :- " << SERVER_NAME << " Message of the day - \r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string RPL_ENDOFMOTD(Client* client) {
|
inline std::string RPL_ENDOFMOTD(Client* client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 376 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 376 " << CLIENT_NICK(client)
|
||||||
<< " :End of /MOTD command.\r\n";
|
<< " :End of /MOTD command.\r\n";
|
||||||
@ -261,13 +278,15 @@ inline std::string ERR_NOSUCHCHANNEL(Client *client, const std::string& channel)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_CANNOTSENDTOCHAN(Client *client, const std::string& channel) {
|
inline std::string ERR_CANNOTSENDTOCHAN(Client *client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 404 " << CLIENT_NICK(client) << " " << channel << " :Cannot send to channel\r\n";
|
oss << ":" << SERVER_NAME << " 404 " << CLIENT_NICK(client) << " " << channel << " :Cannot send to channel\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_TOOMANYCHANNELS(Client* client, const std::string& channel) {
|
inline std::string ERR_TOOMANYCHANNELS(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 405 " << CLIENT_NICK(client) << " " << channel << " :You have joined too many channels\r\n";
|
oss << ":" << SERVER_NAME << " 405 " << CLIENT_NICK(client) << " " << channel << " :You have joined too many channels\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
@ -281,25 +300,29 @@ inline std::string ERR_NOORIGIN(Client* client)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_NORECIPIENT(Client *client, const std::string& command) {
|
inline std::string ERR_NORECIPIENT(Client *client, const std::string& command)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 411 " << CLIENT_NICK(client) << " :No recipient given (" << command << ")\r\n";
|
oss << ":" << SERVER_NAME << " 411 " << CLIENT_NICK(client) << " :No recipient given (" << command << ")\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_NOTEXTTOSEND(Client *client) {
|
inline std::string ERR_NOTEXTTOSEND(Client *client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 412 " << CLIENT_NICK(client) << " :No text to send\r\n";
|
oss << ":" << SERVER_NAME << " 412 " << CLIENT_NICK(client) << " :No text to send\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_UNKNOWNCOMMAND(Client* client, const std::string& command) {
|
inline std::string ERR_UNKNOWNCOMMAND(Client* client, const std::string& command)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 421 " << CLIENT_NICK(client) << " " << command << " :Unknown command\r\n";
|
oss << ":" << SERVER_NAME << " 421 " << CLIENT_NICK(client) << " " << command << " :Unknown command\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_NOMOTD(Client* client) {
|
inline std::string ERR_NOMOTD(Client* client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 422 " << CLIENT_NICK(client)
|
oss << ":" << SERVER_NAME << " 422 " << CLIENT_NICK(client)
|
||||||
<< " :MOTD File is missing\r\n";
|
<< " :MOTD File is missing\r\n";
|
||||||
@ -327,25 +350,28 @@ inline std::string ERR_NICKNAMEINUSE(Client* client, const std::string& nickname
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_USERNOTINCHANNEL(Client *client, 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;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 441 " << CLIENT_NICK(client) << " " << nick << " " << channel
|
oss << ":" << SERVER_NAME << " 441 " << CLIENT_NICK(client) << " " << nick << " " << channel
|
||||||
<< " :They aren't on that channel\r\n";
|
<< " :They aren't on that channel\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_NOTONCHANNEL(Client *client, const std::string& channel) {
|
inline std::string ERR_NOTONCHANNEL(Client *client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 442 " << CLIENT_NICK(client) << " " << 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();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ajoutez cette fonction pour ERR_USERONCHANNEL
|
// Ajoutez cette fonction pour ERR_USERONCHANNEL
|
||||||
inline std::string ERR_USERONCHANNEL(Client* client, const std::string& nick, const std::string& channel) {
|
inline std::string ERR_USERONCHANNEL(Client* client, const std::string& nick, const std::string& channel)
|
||||||
std::ostringstream oss;
|
{
|
||||||
oss << ":" << SERVER_NAME << " 443 " << CLIENT_NICK(client) << " " << nick << " " << channel
|
std::ostringstream oss;
|
||||||
<< " :is already on channel\r\n";
|
oss << ":" << SERVER_NAME << " 443 " << CLIENT_NICK(client) << " " << nick << " " << channel
|
||||||
return oss.str();
|
<< " :is already on channel\r\n";
|
||||||
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_NOTREGISTERED(Client* client)
|
inline std::string ERR_NOTREGISTERED(Client* client)
|
||||||
@ -378,43 +404,50 @@ inline std::string ERR_PASSWDMISMATCH(Client* client)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_INVALIDKEY(Client* client, const std::string& channel) {
|
inline std::string ERR_INVALIDKEY(Client* client, const std::string& channel)
|
||||||
std::ostringstream oss;
|
{
|
||||||
oss << ":" << SERVER_NAME << " 467 " << CLIENT_NICK(client) << " " << channel << " :Invalid key\r\n";
|
std::ostringstream oss;
|
||||||
return oss.str();
|
oss << ":" << SERVER_NAME << " 467 " << CLIENT_NICK(client) << " " << channel << " :Invalid key\r\n";
|
||||||
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_CHANNELISFULL(Client* client, const std::string& channel) {
|
inline std::string ERR_CHANNELISFULL(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 471 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (channel is full)\r\n";
|
oss << ":" << SERVER_NAME << " 471 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (channel is full)\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_UNKNOWNMODE(Client* client, char mode, const std::string& channelName) {
|
inline std::string ERR_UNKNOWNMODE(Client* client, char mode, const std::string& channelName)
|
||||||
std::ostringstream oss;
|
{
|
||||||
oss << ":" << SERVER_NAME << " 472 " << CLIENT_NICK(client) << " " << mode << " :is unknown mode char to me for " << channelName << "\r\n";
|
std::ostringstream oss;
|
||||||
return oss.str();
|
oss << ":" << SERVER_NAME << " 472 " << CLIENT_NICK(client) << " " << mode << " :is unknown mode char to me for " << channelName << "\r\n";
|
||||||
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_INVITEONLYCHAN(Client* client, const std::string& channel) {
|
inline std::string ERR_INVITEONLYCHAN(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 473 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (invite only)\r\n";
|
oss << ":" << SERVER_NAME << " 473 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (invite only)\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_BANNEDFROMCHAN(Client* client, const std::string& channel) {
|
inline std::string ERR_BANNEDFROMCHAN(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 474 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (banned)\r\n";
|
oss << ":" << SERVER_NAME << " 474 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (banned)\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_BADCHANNELKEY(Client* client, const std::string& channel) {
|
inline std::string ERR_BADCHANNELKEY(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 475 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (incorrect key)\r\n";
|
oss << ":" << SERVER_NAME << " 475 " << CLIENT_NICK(client) << " " << channel << " :Cannot join channel (incorrect key)\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_BADCHANMASK(Client* client, const std::string& channel) {
|
inline std::string ERR_BADCHANMASK(Client* client, const std::string& channel)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 476 " << CLIENT_NICK(client) << " " << channel << " :Bad channel mask\r\n";
|
oss << ":" << SERVER_NAME << " 476 " << CLIENT_NICK(client) << " " << channel << " :Bad channel mask\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
@ -434,25 +467,27 @@ inline std::string ERR_CHANOPRIVSNEEDED(Client *client, const std::string& chann
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_UMODEUNKNOWNFLAG(Client *client) {
|
inline std::string ERR_UMODEUNKNOWNFLAG(Client *client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 501 " << CLIENT_NICK(client) << " :Unknown MODE flag\r\n";
|
oss << ":" << SERVER_NAME << " 501 " << CLIENT_NICK(client) << " :Unknown MODE flag\r\n";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_USERSDONTMATCH(Client *client) {
|
inline std::string ERR_USERSDONTMATCH(Client *client)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << ":" << SERVER_NAME << " 502 " << CLIENT_NICK(client) << " :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();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ERR_INVALIDMODEPARAM(Client* client, const std::string& param) {
|
inline std::string ERR_INVALIDMODEPARAM(Client* client, const std::string& param)
|
||||||
std::ostringstream oss;
|
{
|
||||||
oss << ":" << SERVER_NAME << " 696 " << CLIENT_NICK(client) << " " << param << " :Invalid mode parameter\r\n";
|
std::ostringstream oss;
|
||||||
return oss.str();
|
oss << ":" << SERVER_NAME << " 696 " << CLIENT_NICK(client) << " " << param << " :Invalid mode parameter\r\n";
|
||||||
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PONG Reply
|
|
||||||
inline std::string RPL_PONG(const std::string& token)
|
inline std::string RPL_PONG(const std::string& token)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -460,7 +495,6 @@ inline std::string RPL_PONG(const std::string& token)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// CAP Command RPLs
|
|
||||||
inline std::string RPL_CAP(Client *client, 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;
|
std::ostringstream oss;
|
||||||
@ -476,7 +510,6 @@ inline std::string RPL_PASSACCEPTED(Client* client)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add this function to handle the CAP END response
|
|
||||||
inline std::string RPL_CAPEND(Client *client)
|
inline std::string RPL_CAPEND(Client *client)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -484,4 +517,4 @@ inline std::string RPL_CAPEND(Client *client)
|
|||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // RPL_HPP
|
#endif
|
||||||
|
|||||||
@ -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/05/30 17:13:41 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:01:40 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -46,48 +46,47 @@ class TopicHandler;
|
|||||||
|
|
||||||
class Server
|
class Server
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Server(int port, const std::string &password);
|
Server(int port, const std::string &password);
|
||||||
~Server();
|
~Server();
|
||||||
void run();
|
void run();
|
||||||
void log(const std::string &message, const std::string &color = "\033[0m");
|
void log(const std::string &message, const std::string &color = "\033[0m");
|
||||||
void sendToClient(int client_fd, const std::string &message);
|
void sendToClient(int client_fd, const std::string &message);
|
||||||
|
|
||||||
// Méthodes d'accès pour les canaux et les clients
|
std::map<std::string, Channel *> &getChannels();
|
||||||
std::map<std::string, Channel *> &getChannels();
|
std::map<int, Client *> &getClients();
|
||||||
std::map<int, Client *> &getClients();
|
const std::string &getPassword() const;
|
||||||
const std::string &getPassword() const;
|
void broadcast(const std::string &message);
|
||||||
void broadcast(const std::string &message);
|
Client* getClientByName(const std::string &name);
|
||||||
Client* getClientByName(const std::string &name); // Ajoutez cette méthode
|
Channel* getChannelByName(const std::string &name);
|
||||||
Channel* getChannelByName(const std::string &name); // Ajoutez cette méthode
|
void sendChannelListToClient(Client *client);
|
||||||
void sendChannelListToClient(Client *client);
|
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);
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _server_fd;
|
||||||
|
int _port;
|
||||||
|
std::string _password;
|
||||||
|
std::map<int, Client *> _clients;
|
||||||
|
std::map<std::string, Channel *> _channels;
|
||||||
|
std::vector<struct pollfd> _poll_fds;
|
||||||
|
ClientManager *_clientManager;
|
||||||
|
CommandHandler *_commandHandler;
|
||||||
|
ModeHandler *_modeHandler;
|
||||||
|
TopicHandler *_topicHandler;
|
||||||
|
|
||||||
protected:
|
friend class ClientManager;
|
||||||
int _server_fd;
|
friend class CommandHandler;
|
||||||
int _port;
|
friend class ModeHandler;
|
||||||
std::string _password;
|
friend class TopicHandler;
|
||||||
std::map<int, Client *> _clients;
|
|
||||||
std::map<std::string, Channel *> _channels;
|
|
||||||
std::vector<struct pollfd> _poll_fds;
|
|
||||||
ClientManager *_clientManager;
|
|
||||||
CommandHandler *_commandHandler;
|
|
||||||
ModeHandler *_modeHandler;
|
|
||||||
TopicHandler *_topicHandler;
|
|
||||||
|
|
||||||
friend class ClientManager;
|
private:
|
||||||
friend class CommandHandler;
|
void initServer();
|
||||||
friend class ModeHandler;
|
void handleServerCommands();
|
||||||
friend class TopicHandler;
|
void acceptClient();
|
||||||
|
void removeClient(int client_fd);
|
||||||
|
|
||||||
private:
|
|
||||||
void initServer();
|
|
||||||
void handleServerCommands();
|
|
||||||
void acceptClient();
|
|
||||||
void removeClient(int client_fd);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/30 17:04:33 by fgras-ca #+# #+# */
|
/* Created: 2024/05/30 17:04:33 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 17:47:56 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:02:10 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -24,15 +24,15 @@
|
|||||||
|
|
||||||
class TopicHandler
|
class TopicHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TopicHandler(Server* server);
|
TopicHandler(Server* server);
|
||||||
void handleTopicCommand(Client* client, const std::string& command);
|
void handleTopicCommand(Client* client, const std::string& command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void viewTopic(Client* client, Channel* channel);
|
void viewTopic(Client* client, Channel* channel);
|
||||||
void changeTopic(Client* client, Channel* channel, const std::string& topic);
|
void changeTopic(Client* client, Channel* channel, const std::string& topic);
|
||||||
|
|
||||||
Server* _server;
|
Server* _server;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -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:16:02 by fgras-ca #+# #+# */
|
/* Created: 2024/05/15 12:16:02 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/16 18:14:58 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 15:13:40 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -18,12 +18,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define RESET "\033[0m"
|
#define RESET "\033[0m"
|
||||||
#define RED "\033[31m"
|
#define RED "\033[1;31m"
|
||||||
#define GREEN "\033[32m"
|
#define GREEN "\033[1;32m"
|
||||||
#define YELLOW "\033[33m"
|
#define YELLOW "\033[1;33m"
|
||||||
#define BLUE "\033[34m"
|
#define BLUE "\033[1;34m"
|
||||||
#define MAGENTA "\033[35m"
|
#define MAGENTA "\033[1;35m"
|
||||||
#define CYAN "\033[36m"
|
#define CYAN "\033[1;36m"
|
||||||
|
|
||||||
std::vector<std::string> split(const std::string &input, const std::string &delimiters);
|
std::vector<std::string> split(const std::string &input, const std::string &delimiters);
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/21 19:53:17 by fgras-ca #+# #+# */
|
/* Created: 2024/05/21 19:53:17 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 17:48:13 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:02:40 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -16,13 +16,14 @@
|
|||||||
#include "Client.hpp"
|
#include "Client.hpp"
|
||||||
#include "Server.hpp"
|
#include "Server.hpp"
|
||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class WelcomeHandler
|
class WelcomeHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void sendWelcomeMessages(Client *client, Server *server);
|
void sendWelcomeMessages(Client *client, Server *server);
|
||||||
void sendMotd(Client *client, Server *server);
|
void sendMotd(Client *client, Server *server);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WELCOME_HPP
|
#endif
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/17 16:08:48 by fgras-ca #+# #+# */
|
/* Created: 2024/05/17 16:08:48 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/21 18:04:10 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:03:06 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -23,16 +23,16 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
class Server;
|
class Server;
|
||||||
|
|
||||||
class WhoHandler
|
class WhoHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WhoHandler(Server *server);
|
WhoHandler(Server *server);
|
||||||
void handleWhoCommand(Client *client, const std::string &command);
|
void handleWhoCommand(Client *client, const std::string &command);
|
||||||
void handleWhoisCommand(Client *client, const std::string &command);
|
void handleWhoisCommand(Client *client, const std::string &command);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Server *_server;
|
||||||
|
|
||||||
private:
|
|
||||||
Server *_server;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,35 +6,34 @@
|
|||||||
/* 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/05/30 17:12:30 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:05:15 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "AdditionalCommands.hpp"
|
#include "AdditionalCommands.hpp"
|
||||||
|
|
||||||
AdditionalCommands::AdditionalCommands(Server *server) : _server(server)
|
AdditionalCommands::AdditionalCommands(Server *server) : _server(server) {}
|
||||||
{}
|
|
||||||
|
|
||||||
void AdditionalCommands::processCommand(Client *client, const std::string &command)
|
void AdditionalCommands::processCommand(Client *client, const std::string &command)
|
||||||
{
|
{
|
||||||
if (command.find("PART") == 0)
|
if (command.find("PART") == 0)
|
||||||
{
|
{
|
||||||
handlePartCommand(_server, client, command);
|
handlePartCommand(_server, client, command);
|
||||||
}
|
}
|
||||||
else if (command.find("PRIVMSG") == 0)
|
else if (command.find("PRIVMSG") == 0)
|
||||||
{
|
{
|
||||||
handlePrivmsgCommand(_server, client, command);
|
handlePrivmsgCommand(_server, client, command);
|
||||||
}
|
}
|
||||||
else if (command.find("WHO") == 0)
|
else if (command.find("WHO") == 0)
|
||||||
{
|
{
|
||||||
WhoHandler whoHandler(_server);
|
WhoHandler whoHandler(_server);
|
||||||
whoHandler.handleWhoCommand(client, command);
|
whoHandler.handleWhoCommand(client, command);
|
||||||
}
|
}
|
||||||
else if (command.find("WHOIS") == 0)
|
else if (command.find("WHOIS") == 0)
|
||||||
{
|
{
|
||||||
WhoHandler whoHandler(_server);
|
WhoHandler whoHandler(_server);
|
||||||
whoHandler.handleWhoisCommand(client, command);
|
whoHandler.handleWhoisCommand(client, command);
|
||||||
}
|
}
|
||||||
else if (command.find("INVITE") == 0)
|
else if (command.find("INVITE") == 0)
|
||||||
{
|
{
|
||||||
InviteHandler inviteHandler(_server);
|
InviteHandler inviteHandler(_server);
|
||||||
@ -46,17 +45,21 @@ void AdditionalCommands::processCommand(Client *client, const std::string &comma
|
|||||||
topichandler.handleTopicCommand(client, command);
|
topichandler.handleTopicCommand(client, command);
|
||||||
}
|
}
|
||||||
else if (command.find("LIST") == 0)
|
else if (command.find("LIST") == 0)
|
||||||
{
|
{
|
||||||
broadcastChannelList(client, _server);
|
broadcastChannelList(client, _server);
|
||||||
}
|
}
|
||||||
else
|
else if (command.find("KICK") == 0)
|
||||||
{
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_UNKNOWNCOMMAND(client, command));
|
KickHandler kickHandler(_server);
|
||||||
_server->log("Message from client " + client->getNickname() + ": " + command, MAGENTA);
|
kickHandler.handleKickCommand(client, command);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_UNKNOWNCOMMAND(client, command));
|
||||||
|
_server->log("Message from client " + client->getNickname() + ": " + command, MAGENTA);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AdditionalCommands::broadcastChannelList(Client *client, Server *server)
|
void AdditionalCommands::broadcastChannelList(Client *client, Server *server)
|
||||||
{
|
{
|
||||||
std::map<std::string, Channel *> &channels = server->getChannels();
|
std::map<std::string, Channel *> &channels = server->getChannels();
|
||||||
@ -70,115 +73,116 @@ void AdditionalCommands::broadcastChannelList(Client *client, Server *server)
|
|||||||
// Fonction pour gérer la commande PART
|
// Fonction pour gérer la commande PART
|
||||||
void AdditionalCommands::handlePartCommand(Server *server, Client *client, const std::string &command)
|
void AdditionalCommands::handlePartCommand(Server *server, Client *client, const std::string &command)
|
||||||
{
|
{
|
||||||
std::istringstream iss(command);
|
std::istringstream iss(command);
|
||||||
std::string cmd, channelNames;
|
std::string cmd, channelNames;
|
||||||
iss >> cmd >> channelNames;
|
iss >> cmd >> channelNames;
|
||||||
|
|
||||||
if (channelNames.empty()) {
|
if (channelNames.empty())
|
||||||
server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PART"));
|
{
|
||||||
return;
|
server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PART"));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> channels = split(channelNames, ",");
|
std::vector<std::string> channels = split(channelNames, ",");
|
||||||
std::map<std::string, Channel *> &channelMap = server->getChannels();
|
std::map<std::string, Channel *> &channelMap = server->getChannels();
|
||||||
|
|
||||||
for (size_t i = 0; i < channels.size(); ++i) {
|
for (size_t i = 0; i < channels.size(); ++i)
|
||||||
std::string &channelName = channels[i];
|
{
|
||||||
if (channelMap.find(channelName) == channelMap.end()) {
|
std::string &channelName = channels[i];
|
||||||
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
if (channelMap.find(channelName) == channelMap.end())
|
||||||
continue;
|
{
|
||||||
}
|
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Channel *channel = channelMap[channelName];
|
Channel *channel = channelMap[channelName];
|
||||||
if (!channel->hasClient(client)) {
|
if (!channel->hasClient(client)) {
|
||||||
server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->removeClient(client);
|
channel->removeClient(client);
|
||||||
|
|
||||||
std::ostringstream partMsg;
|
std::ostringstream partMsg;
|
||||||
partMsg << ":" << client->getNickname() << " PART " << channelName << "\r\n";
|
partMsg << ":" << client->getNickname() << " PART " << channelName << "\r\n";
|
||||||
server->sendToClient(client->getFd(), partMsg.str());
|
server->sendToClient(client->getFd(), partMsg.str());
|
||||||
|
|
||||||
if (channel->isEmpty()) {
|
if (channel->isEmpty())
|
||||||
delete channel;
|
{
|
||||||
channelMap.erase(channelName);
|
delete channel;
|
||||||
}
|
channelMap.erase(channelName);
|
||||||
|
}
|
||||||
|
|
||||||
server->log("Client " + client->getNickname() + " left channel " + channelName, MAGENTA);
|
server->log("Client " + client->getNickname() + " left channel " + channelName, MAGENTA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fonction pour gérer la commande PRIVMSG
|
|
||||||
void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, const std::string &command)
|
void AdditionalCommands::handlePrivmsgCommand(Server *server, Client *client, const std::string &command)
|
||||||
{
|
{
|
||||||
std::istringstream iss(command);
|
std::istringstream iss(command);
|
||||||
std::string cmd, target, message;
|
std::string cmd, target, message;
|
||||||
iss >> cmd >> target;
|
iss >> cmd >> target;
|
||||||
getline(iss, message);
|
getline(iss, message);
|
||||||
|
|
||||||
// Enlever le ':' initial dans le message si présent
|
// Enlever le ':' initial dans le message si présent
|
||||||
if (!message.empty() && message[0] == ':')
|
if (!message.empty() && message[0] == ':')
|
||||||
message = message.substr(1);
|
message = message.substr(1);
|
||||||
|
|
||||||
if (target.empty()) {
|
if (target.empty())
|
||||||
server->sendToClient(client->getFd(), ERR_NORECIPIENT(client, "PRIVMSG"));
|
{
|
||||||
return;
|
server->sendToClient(client->getFd(), ERR_NORECIPIENT(client, "PRIVMSG"));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (message.empty()) {
|
if (message.empty())
|
||||||
server->sendToClient(client->getFd(), ERR_NOTEXTTOSEND(client));
|
{
|
||||||
return;
|
server->sendToClient(client->getFd(), ERR_NOTEXTTOSEND(client));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Récupérer les canaux du serveur
|
std::map<std::string, Channel *> &channels = server->getChannels();
|
||||||
std::map<std::string, Channel *> &channels = server->getChannels();
|
|
||||||
|
|
||||||
// Si la cible est un canal
|
if (channels.find(target) != channels.end())
|
||||||
if (channels.find(target) != channels.end())
|
{
|
||||||
{
|
Channel *channel = channels[target];
|
||||||
Channel *channel = channels[target];
|
|
||||||
|
|
||||||
// Vérifier les conditions spéciales du canal (ex: ban, modération)
|
if (channel->isBanned(client))
|
||||||
if (channel->isBanned(client)) {
|
{
|
||||||
server->sendToClient(client->getFd(), ERR_CANNOTSENDTOCHAN(client, target));
|
server->sendToClient(client->getFd(), ERR_CANNOTSENDTOCHAN(client, target));
|
||||||
return;
|
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)
|
||||||
{
|
{
|
||||||
// Envoyer le message à tous les clients du canal sauf l'émetteur
|
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());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
// Si la cible est un utilisateur
|
{
|
||||||
else
|
Client *targetClient = server->getClientByName(target);
|
||||||
{
|
|
||||||
Client *targetClient = server->getClientByName(target); // Utiliser getClientByName pour trouver le client par nom
|
|
||||||
|
|
||||||
if (targetClient)
|
if (targetClient)
|
||||||
{
|
{
|
||||||
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())
|
||||||
server->sendToClient(client->getFd(), RPL_AWAY(client, targetClient->getNickname(), targetClient->getAwayMessage()));
|
{
|
||||||
}
|
server->sendToClient(client->getFd(), RPL_AWAY(client, targetClient->getNickname(), targetClient->getAwayMessage()));
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
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, target));
|
// Si la cible n'est ni un canal ni un utilisateur existant, envoyer un message d'erreur
|
||||||
}
|
server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, target));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,50 +6,50 @@
|
|||||||
/* 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/05/30 18:33:19 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:06:40 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "Channel.hpp"
|
#include "Channel.hpp"
|
||||||
|
|
||||||
Channel::Channel(const std::string &name)
|
Channel::Channel(const std::string &name)
|
||||||
: _name(name), _clients(), _operators(), _bannedClients(), _invitedClients(), _key(""), _topic(""), _topicSetter(""), _topicTime(0), _clientLimit(50), _inviteOnly(false), _topicProtection(false) {}
|
: _name(name), _clients(), _operators(), _bannedClients(), _invitedClients(), _key(""), _topic(""), _topicSetter(""), _topicTime(time(NULL)), _clientLimit(50), _inviteOnly(false), _topicProtection(false) {}
|
||||||
|
|
||||||
Channel::~Channel() {}
|
Channel::~Channel() {}
|
||||||
|
|
||||||
const std::string &Channel::getName() const
|
const std::string &Channel::getName() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::addClient(Client *client)
|
void Channel::addClient(Client *client)
|
||||||
{
|
{
|
||||||
_clients.push_back(client);
|
_clients.push_back(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::removeClient(Client *client)
|
void Channel::removeClient(Client *client)
|
||||||
{
|
{
|
||||||
_clients.erase(std::remove(_clients.begin(), _clients.end(), client), _clients.end());
|
_clients.erase(std::remove(_clients.begin(), _clients.end(), client), _clients.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::isEmpty() const
|
bool Channel::isEmpty() const
|
||||||
{
|
{
|
||||||
return _clients.empty();
|
return _clients.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Client *> &Channel::getClients() const
|
const std::vector<Client *> &Channel::getClients() const
|
||||||
{
|
{
|
||||||
return _clients;
|
return _clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::addOperator(Client *client)
|
void Channel::addOperator(Client *client)
|
||||||
{
|
{
|
||||||
_operators.push_back(client);
|
_operators.push_back(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::isOperator(Client *client) const
|
bool Channel::isOperator(Client *client) const
|
||||||
{
|
{
|
||||||
return std::find(_operators.begin(), _operators.end(), client) != _operators.end();
|
return std::find(_operators.begin(), _operators.end(), client) != _operators.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::removeOperator(Client *client)
|
void Channel::removeOperator(Client *client)
|
||||||
@ -59,99 +59,106 @@ void Channel::removeOperator(Client *client)
|
|||||||
|
|
||||||
bool Channel::hasClient(Client *client) const
|
bool Channel::hasClient(Client *client) const
|
||||||
{
|
{
|
||||||
return std::find(_clients.begin(), _clients.end(), client) != _clients.end();
|
return std::find(_clients.begin(), _clients.end(), client) != _clients.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::broadcast(const std::string &message, Client *_client, Server *_server)
|
void Channel::broadcast(const std::string &message, Client *_client, Server *_server)
|
||||||
{
|
{
|
||||||
for (std::vector<Client *>::iterator it = _clients.begin(); it != _clients.end(); ++it)
|
for (std::vector<Client *>::iterator it = _clients.begin(); it != _clients.end(); ++it)
|
||||||
{
|
{
|
||||||
if (*it != _client)
|
if (*it != _client)
|
||||||
{
|
{
|
||||||
// Send message to each client except the sender
|
// Send message to each client except the sender
|
||||||
_server->sendToClient((*it)->getFd(), message);
|
_server->sendToClient((*it)->getFd(), message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::isBanned(Client *client) const
|
bool Channel::isBanned(Client *client) const
|
||||||
{
|
{
|
||||||
return _bannedClients.find(client) != _bannedClients.end();
|
return _bannedClients.find(client) != _bannedClients.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::isFull() const
|
bool Channel::isFull() const
|
||||||
{
|
{
|
||||||
return _clients.size() >= _clientLimit;
|
return _clients.size() >= _clientLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::isInviteOnly() const
|
bool Channel::isInviteOnly() const
|
||||||
{
|
{
|
||||||
return _inviteOnly;
|
return _inviteOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::isInvited(Client *client) const
|
bool Channel::isInvited(Client *client) const
|
||||||
{
|
{
|
||||||
return _invitedClients.find(client) != _invitedClients.end();
|
return _invitedClients.find(client) != _invitedClients.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::checkKey(const std::string &key) const
|
bool Channel::checkKey(const std::string &key) const
|
||||||
{
|
{
|
||||||
return _key.empty() || _key == key;
|
return _key.empty() || _key == key;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Channel::getTopic() const
|
const std::string &Channel::getTopic() const
|
||||||
{
|
{
|
||||||
return _topic;
|
return _topic;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Channel::getTopicSetter() const
|
const std::string &Channel::getTopicSetter() const
|
||||||
{
|
{
|
||||||
return _topicSetter;
|
return _topicSetter;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t Channel::getTopicTime() const
|
time_t Channel::getTopicTime() const
|
||||||
{
|
{
|
||||||
return _topicTime;
|
return _topicTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::setTopic(const std::string &topic, const std::string &setter)
|
void Channel::setTopic(const std::string &topic, const std::string &setter)
|
||||||
{
|
{
|
||||||
_topic = topic;
|
_topic = topic;
|
||||||
_topicSetter = setter;
|
_topicSetter = setter;
|
||||||
_topicTime = std::time(NULL);
|
_topicTime = std::time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::setClientLimit(size_t limit) {
|
void Channel::setClientLimit(size_t limit)
|
||||||
_clientLimit = limit;
|
{
|
||||||
|
_clientLimit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Channel::getClientLimit() const {
|
size_t Channel::getClientLimit() const
|
||||||
return _clientLimit;
|
{
|
||||||
|
return _clientLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::setInviteOnly(bool inviteOnly) {
|
void Channel::setInviteOnly(bool inviteOnly)
|
||||||
_inviteOnly = inviteOnly;
|
{
|
||||||
|
_inviteOnly = inviteOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::setKey(const std::string &key) {
|
void Channel::setKey(const std::string &key)
|
||||||
_key = key;
|
{
|
||||||
|
_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::setTopicProtection(bool protection) {
|
void Channel::setTopicProtection(bool protection)
|
||||||
_topicProtection = protection;
|
{
|
||||||
|
_topicProtection = protection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel::addInvitedClient(Client* client) {
|
void Channel::addInvitedClient(Client* client)
|
||||||
_invitedClients.insert(client);
|
{
|
||||||
|
_invitedClients.insert(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Channel::getModes() const {
|
std::string Channel::getModes() const
|
||||||
std::string modes;
|
{
|
||||||
if (_inviteOnly) modes += 'i';
|
std::string modes;
|
||||||
if (!_key.empty()) modes += 'k';
|
if (_inviteOnly) modes += 'i';
|
||||||
if (_clientLimit > 0) modes += 'l';
|
if (!_key.empty()) modes += 'k';
|
||||||
if (_topicProtection) modes += 't';
|
if (_clientLimit > 0) modes += 'l';
|
||||||
return modes;
|
if (_topicProtection) modes += 't';
|
||||||
|
return modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Channel::getTopicProtection() const
|
bool Channel::getTopicProtection() const
|
||||||
|
|||||||
@ -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:42 by fgras-ca #+# #+# */
|
/* Created: 2024/05/15 12:17:42 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/31 11:27:52 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:06:29 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "Client.hpp"
|
#include "Client.hpp"
|
||||||
|
|
||||||
Client::Client(int fd, const std::string &nickname, const std::string &user, const std::string &host, const std::string &password, const std::string &realname)
|
Client::Client(int fd, const std::string &nickname, const std::string &user, const std::string &host, const std::string &password, const std::string &realname)
|
||||||
: _fd(fd), _nickname(nickname), _user(user), _host(host), _password(password), _realname(realname), _authenticated(false), _operator(false), _away(false) {}
|
: _fd(fd), _nickname(nickname), _user(user), _host(host), _password(password), _realname(realname), _authenticated(false), _operator(false), _away(false) {}
|
||||||
|
|
||||||
int Client::getFd() const
|
int Client::getFd() const
|
||||||
{
|
{
|
||||||
@ -110,7 +110,7 @@ void Client::setAway(bool away)
|
|||||||
_away = away;
|
_away = away;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Client::getkey() const
|
std::string Client::getKey() const
|
||||||
{
|
{
|
||||||
return _key;
|
return _key;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,16 +6,14 @@
|
|||||||
/* 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/05/28 14:32:28 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:07:39 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ClientManager.hpp"
|
#include "ClientManager.hpp"
|
||||||
|
|
||||||
ClientManager::ClientManager(Server *server)
|
ClientManager::ClientManager(Server *server)
|
||||||
: _server(server)
|
: _server(server) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientManager::acceptClient()
|
void ClientManager::acceptClient()
|
||||||
{
|
{
|
||||||
@ -26,7 +24,7 @@ void ClientManager::acceptClient()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *newClient = new Client(client_fd, "", "", "", "", ""); // Fournir six arguments
|
Client *newClient = new Client(client_fd, "", "", "", "", "");
|
||||||
_server->_clients[client_fd] = newClient;
|
_server->_clients[client_fd] = newClient;
|
||||||
struct pollfd client_pollfd;
|
struct pollfd client_pollfd;
|
||||||
client_pollfd.fd = client_fd;
|
client_pollfd.fd = client_fd;
|
||||||
@ -72,7 +70,6 @@ void ClientManager::handleClient(int client_fd)
|
|||||||
|
|
||||||
while (std::getline(message_stream, line))
|
while (std::getline(message_stream, line))
|
||||||
{
|
{
|
||||||
// Remove trailing '\r' and '\n'
|
|
||||||
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
|
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
|
||||||
line.erase(std::remove(line.begin(), line.end(), '\n'), line.end());
|
line.erase(std::remove(line.begin(), line.end(), '\n'), line.end());
|
||||||
|
|
||||||
@ -86,13 +83,11 @@ void ClientManager::handleClient(int client_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClientManager::removeClient(int clientFd)
|
void ClientManager::removeClient(int clientFd)
|
||||||
{
|
{
|
||||||
Client* client = _server->_clients[clientFd];
|
Client* client = _server->_clients[clientFd];
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
// Log the nickname being freed
|
|
||||||
_server->log("Removing client: " + client->getNickname(), YELLOW);
|
_server->log("Removing client: " + client->getNickname(), YELLOW);
|
||||||
|
|
||||||
std::map<std::string, Channel*>::iterator it = _server->_channels.begin();
|
std::map<std::string, Channel*>::iterator it = _server->_channels.begin();
|
||||||
|
|||||||
@ -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:26:34 by fgras-ca #+# #+# */
|
/* Created: 2024/05/15 18:26:34 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 16:53:35 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:10:48 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -27,27 +27,40 @@ void CommandHandler::handleCommand(Client* client, const std::string& command)
|
|||||||
{
|
{
|
||||||
std::vector<std::string> tokens = split(command, " \n\r\t");
|
std::vector<std::string> tokens = split(command, " \n\r\t");
|
||||||
|
|
||||||
if (tokens.empty()) {
|
if (tokens.empty())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string commandType = tokens[0];
|
std::string commandType = tokens[0];
|
||||||
if (commandType == "CAP") {
|
if (commandType == "CAP")
|
||||||
|
{
|
||||||
handleCapCommand(client, tokens);
|
handleCapCommand(client, tokens);
|
||||||
} else if (commandType == "PASS") {
|
}
|
||||||
|
else if (commandType == "PASS")
|
||||||
|
{
|
||||||
handlePassCommand(client, tokens);
|
handlePassCommand(client, tokens);
|
||||||
} else if (commandType == "NICK") {
|
}
|
||||||
|
else if (commandType == "NICK")
|
||||||
|
{
|
||||||
handleNick(client, tokens);
|
handleNick(client, tokens);
|
||||||
} else if (commandType == "USER") {
|
}
|
||||||
|
else if (commandType == "USER")
|
||||||
|
{
|
||||||
handleUser(client, tokens);
|
handleUser(client, tokens);
|
||||||
} else if (commandType == "QUIT") {
|
}
|
||||||
|
else if (commandType == "QUIT")
|
||||||
|
{
|
||||||
handleQuitCommand(client, tokens);
|
handleQuitCommand(client, tokens);
|
||||||
} else if (commandType == "PING")
|
}
|
||||||
|
else if (commandType == "PING")
|
||||||
{
|
{
|
||||||
handlePingCommand(client, tokens);
|
handlePingCommand(client, tokens);
|
||||||
}
|
}
|
||||||
else if (commandType == "ERROR") {
|
else if (commandType == "ERROR")
|
||||||
if (tokens.size() > 1) {
|
{
|
||||||
|
if (tokens.size() > 1)
|
||||||
|
{
|
||||||
handleErrorCommand(client, tokens[1]);
|
handleErrorCommand(client, tokens[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,19 +68,24 @@ void CommandHandler::handleCommand(Client* client, const std::string& command)
|
|||||||
{
|
{
|
||||||
_modeHandler->handleModeCommand(client, command);
|
_modeHandler->handleModeCommand(client, command);
|
||||||
}
|
}
|
||||||
else if (commandType == "JOIN") {
|
else if (commandType == "JOIN")
|
||||||
|
{
|
||||||
|
std::string joinParams = command.substr(command.find(" ") + 1);
|
||||||
JoinHandler joinHandler;
|
JoinHandler joinHandler;
|
||||||
joinHandler.handleJoinCommand(client, tokens[1], _server);
|
joinHandler.handleJoinCommand(client, joinParams, _server);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
if (!client->isAuthenticated()) {
|
{
|
||||||
|
if (!client->isAuthenticated())
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NOTREGISTERED(client));
|
_server->sendToClient(client->getFd(), ERR_NOTREGISTERED(client));
|
||||||
_server->log("Client " + client->getNickname() + " attempted to send a command before registering.", RED);
|
_server->log("Client " + client->getNickname() + " attempted to send a command before registering.", RED);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_additionalCommands->processCommand(client, command);
|
_additionalCommands->processCommand(client, command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//std::cout << "Client " << client->getFd() << " " << client->getNickname() << " " << client->getUser() << " " << client->getPassword() << " " << client->getRealName() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandHandler::handleCapCommand(Client* client, const std::vector<std::string>& tokens)
|
void CommandHandler::handleCapCommand(Client* client, const std::vector<std::string>& tokens)
|
||||||
@ -97,7 +115,6 @@ void CommandHandler::handleCapCommand(Client* client, const std::vector<std::str
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string requestedCapabilities = tokens[2];
|
std::string requestedCapabilities = tokens[2];
|
||||||
// For simplicity, we assume all requested capabilities are accepted
|
|
||||||
_server->sendToClient(client->getFd(), RPL_CAP(client, "ACK", requestedCapabilities));
|
_server->sendToClient(client->getFd(), RPL_CAP(client, "ACK", requestedCapabilities));
|
||||||
}
|
}
|
||||||
else if (subcommand == "END")
|
else if (subcommand == "END")
|
||||||
@ -112,31 +129,33 @@ void CommandHandler::handleCapCommand(Client* client, const std::vector<std::str
|
|||||||
|
|
||||||
void CommandHandler::handlePassCommand(Client* client, const std::vector<std::string>& tokens)
|
void CommandHandler::handlePassCommand(Client* client, const std::vector<std::string>& tokens)
|
||||||
{
|
{
|
||||||
if (tokens.size() < 2) {
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PASS"));
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PASS"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->isAuthenticated()) {
|
if (client->isAuthenticated())
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
|
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens[1] == _server->_password) {
|
if (tokens[1] == _server->_password)
|
||||||
|
{
|
||||||
client->setPassword(tokens[1]);
|
client->setPassword(tokens[1]);
|
||||||
_server->sendToClient(client->getFd(), ":server NOTICE * :Password accepted\r\n");
|
_server->sendToClient(client->getFd(), ":server NOTICE * :Password accepted\r\n");
|
||||||
_server->log("Client " + client->getNickname() + " provided correct password.", GREEN);
|
_server->log("Client " + client->getNickname() + " provided correct password.", GREEN);
|
||||||
} else {
|
} else {
|
||||||
_server->sendToClient(client->getFd(), ERR_PASSWDMISMATCH(client));
|
_server->sendToClient(client->getFd(), ERR_PASSWDMISMATCH(client));
|
||||||
_server->log("Client " + client->getNickname() + " failed authentication password.", RED);
|
_server->log("Client " + client->getNickname() + " failed authentication password.", RED);
|
||||||
// Optionally disconnect the client here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandHandler::isValidNickname(const std::string& nickname)
|
bool CommandHandler::isValidNickname(const std::string& nickname)
|
||||||
{
|
{
|
||||||
// Implement nickname validation according to IRC protocol
|
if (nickname.empty() || nickname[0] == '#' || nickname[0] == ':' || nickname.find(' ') != std::string::npos)
|
||||||
if (nickname.empty() || nickname[0] == '#' || nickname[0] == ':' || nickname.find(' ') != std::string::npos) {
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -144,8 +163,10 @@ bool CommandHandler::isValidNickname(const std::string& nickname)
|
|||||||
|
|
||||||
bool CommandHandler::isNicknameInUse(const std::string& nickname)
|
bool CommandHandler::isNicknameInUse(const std::string& nickname)
|
||||||
{
|
{
|
||||||
for (std::map<int, Client*>::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it) {
|
for (std::map<int, Client*>::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it)
|
||||||
if (it->second->getNickname() == nickname) {
|
{
|
||||||
|
if (it->second->getNickname() == nickname)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,19 +175,22 @@ bool CommandHandler::isNicknameInUse(const std::string& nickname)
|
|||||||
|
|
||||||
void CommandHandler::handleNick(Client* client, const std::vector<std::string>& tokens)
|
void CommandHandler::handleNick(Client* client, const std::vector<std::string>& tokens)
|
||||||
{
|
{
|
||||||
if (tokens.size() < 2) {
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NONICKNAMEGIVEN(client));
|
_server->sendToClient(client->getFd(), ERR_NONICKNAMEGIVEN(client));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string newNick = tokens[1];
|
std::string newNick = tokens[1];
|
||||||
|
|
||||||
if (!isValidNickname(newNick)) {
|
if (!isValidNickname(newNick))
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_ERRONEUSNICKNAME(client, newNick));
|
_server->sendToClient(client->getFd(), ERR_ERRONEUSNICKNAME(client, newNick));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNicknameInUse(newNick)) {
|
if (isNicknameInUse(newNick))
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NICKNAMEINUSE(client, newNick));
|
_server->sendToClient(client->getFd(), ERR_NICKNAMEINUSE(client, newNick));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -174,9 +198,9 @@ void CommandHandler::handleNick(Client* client, const std::vector<std::string>&
|
|||||||
std::string oldNick = client->getNickname();
|
std::string oldNick = client->getNickname();
|
||||||
client->setNickname(newNick);
|
client->setNickname(newNick);
|
||||||
|
|
||||||
// Envoyer le message NICK à tous les clients connectés
|
|
||||||
std::string nickMessage = ":" + oldNick + " NICK " + newNick + "\r\n";
|
std::string nickMessage = ":" + oldNick + " NICK " + newNick + "\r\n";
|
||||||
for (std::map<int, Client*>::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it) {
|
for (std::map<int, Client*>::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it)
|
||||||
|
{
|
||||||
_server->sendToClient(it->second->getFd(), nickMessage);
|
_server->sendToClient(it->second->getFd(), nickMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +212,8 @@ void CommandHandler::handleNick(Client* client, const std::vector<std::string>&
|
|||||||
|
|
||||||
void CommandHandler::handleUser(Client* client, const std::vector<std::string>& tokens)
|
void CommandHandler::handleUser(Client* client, const std::vector<std::string>& tokens)
|
||||||
{
|
{
|
||||||
if (tokens.size() < 5) {
|
if (tokens.size() < 5)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "USER"));
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "USER"));
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -198,7 +223,8 @@ void CommandHandler::handleUser(Client* client, const std::vector<std::string>&
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->isAuthenticated()) {
|
if (client->isAuthenticated())
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
|
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
@ -209,7 +235,7 @@ void CommandHandler::handleUser(Client* client, const std::vector<std::string>&
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string username = tokens[1];
|
std::string username = tokens[1];
|
||||||
std::string realname = tokens[4].substr(1); // remove leading ':'
|
std::string realname = tokens[4].substr(1);
|
||||||
|
|
||||||
client->setUser(username);
|
client->setUser(username);
|
||||||
client->setRealName(realname);
|
client->setRealName(realname);
|
||||||
@ -218,12 +244,15 @@ void CommandHandler::handleUser(Client* client, const std::vector<std::string>&
|
|||||||
oss << "Client " << client->getFd() << ": USER command set username to " << username << " and real name to " << realname;
|
oss << "Client " << client->getFd() << ": USER command set username to " << username << " and real name to " << realname;
|
||||||
_server->log(oss.str(), BLUE);
|
_server->log(oss.str(), BLUE);
|
||||||
|
|
||||||
if (client->getPassword() == _server->_password && !client->getNickname().empty()) {
|
if (client->getPassword() == _server->_password && !client->getNickname().empty())
|
||||||
|
{
|
||||||
client->authenticate();
|
client->authenticate();
|
||||||
WelcomeHandler welcomeHandler;
|
WelcomeHandler welcomeHandler;
|
||||||
welcomeHandler.sendWelcomeMessages(client, _server);
|
welcomeHandler.sendWelcomeMessages(client, _server);
|
||||||
_server->log("Client " + client->getNickname() + " authenticated.", GREEN);
|
_server->log("Client " + client->getNickname() + " authenticated.", GREEN);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Client " << client->getFd() << ": USER command failed - authentication conditions not met.";
|
oss << "Client " << client->getFd() << ": USER command failed - authentication conditions not met.";
|
||||||
_server->log(oss.str(), RED);
|
_server->log(oss.str(), RED);
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/30 13:02:09 by fgras-ca #+# #+# */
|
/* Created: 2024/05/30 13:02:09 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 16:53:59 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:11:22 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -14,47 +14,54 @@
|
|||||||
|
|
||||||
InviteHandler::InviteHandler(Server* server) : _server(server) {}
|
InviteHandler::InviteHandler(Server* server) : _server(server) {}
|
||||||
|
|
||||||
void InviteHandler::handleInviteCommand(Client* client, const std::string& command) {
|
void InviteHandler::handleInviteCommand(Client* client, const std::string& command)
|
||||||
std::istringstream iss(command);
|
{
|
||||||
std::string cmd, nickname, channelName;
|
std::istringstream iss(command);
|
||||||
iss >> cmd >> nickname >> channelName;
|
std::string cmd, nickname, channelName;
|
||||||
|
iss >> cmd >> nickname >> channelName;
|
||||||
|
|
||||||
if (nickname.empty() || channelName.empty()) {
|
if (nickname.empty() || channelName.empty())
|
||||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "INVITE"));
|
{
|
||||||
return;
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "INVITE"));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Channel* channel = _server->getChannelByName(channelName);
|
Channel* channel = _server->getChannelByName(channelName);
|
||||||
if (!channel) {
|
if (!channel)
|
||||||
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
{
|
||||||
return;
|
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!channel->hasClient(client)) {
|
if (!channel->hasClient(client))
|
||||||
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
{
|
||||||
return;
|
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!channel->isOperator(client) && channel->isInviteOnly()) {
|
if (!channel->isOperator(client) && channel->isInviteOnly())
|
||||||
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
|
{
|
||||||
return;
|
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Client* targetClient = _server->getClientByName(nickname);
|
Client* targetClient = _server->getClientByName(nickname);
|
||||||
if (!targetClient) {
|
if (!targetClient)
|
||||||
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, nickname));
|
{
|
||||||
return;
|
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, nickname));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (channel->hasClient(targetClient)) {
|
if (channel->hasClient(targetClient))
|
||||||
_server->sendToClient(client->getFd(), ERR_USERONCHANNEL(client, nickname, channelName));
|
{
|
||||||
return;
|
_server->sendToClient(client->getFd(), ERR_USERONCHANNEL(client, nickname, channelName));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
channel->addInvitedClient(targetClient);
|
channel->addInvitedClient(targetClient);
|
||||||
_server->sendToClient(client->getFd(), RPL_INVITING(client, nickname, channelName));
|
_server->sendToClient(client->getFd(), RPL_INVITING(client, channel->getName()));
|
||||||
|
|
||||||
std::ostringstream inviteMsg;
|
std::ostringstream inviteMsg;
|
||||||
inviteMsg << ":" << client->getNickname() << " INVITE " << nickname << " " << channelName << "\r\n";
|
inviteMsg << ":" << client->getNickname() << " INVITE " << nickname << " " << channelName << "\r\n";
|
||||||
_server->sendToClient(targetClient->getFd(), inviteMsg.str());
|
_server->sendToClient(targetClient->getFd(), inviteMsg.str());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,113 +11,157 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "Join.hpp"
|
#include "Join.hpp"
|
||||||
void JoinHandler::handleJoinCommand(Client* client, const std::string& channelNames, 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;
|
||||||
|
|
||||||
std::vector<std::string> lst = split(channelNames, ",");
|
server->log("Received JOIN command with params: " + params, RED);
|
||||||
for (std::vector<std::string>::iterator itl = lst.begin(); itl != lst.end(); ++itl)
|
|
||||||
{
|
|
||||||
const std::string& channelName = *itl;
|
|
||||||
std::cout << "hjoincmd .. " << channelName << std::endl;
|
|
||||||
|
|
||||||
if (channelName.empty())
|
// Split params into channel names and keys
|
||||||
{
|
std::vector<std::string> parts = split(params, " ");
|
||||||
server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "JOIN"));
|
server->log("Split parts: ", RED);
|
||||||
return;
|
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"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (channelName[0] == '0' && channelName.size() == 1)
|
std::string channelNames = parts[0];
|
||||||
{
|
std::string keys = (parts.size() > 1) ? parts[1] : "";
|
||||||
// Leave all channels
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channelName[0] != '#' && channelName[0] != '&')
|
server->log("Split params: channelNames = " + channelNames + ", keys = " + keys, RED);
|
||||||
{
|
|
||||||
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channels.find(channelName) == channels.end())
|
std::vector<std::string> channelList = split(channelNames, ",");
|
||||||
{
|
std::vector<std::string> keyList = split(keys, ",");
|
||||||
channel = new Channel(channelName);
|
|
||||||
channels[channelName] = channel;
|
|
||||||
channel->addOperator(client); // Set client as operator for new channel
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
channel = channels[channelName];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel->isBanned(client))
|
server->log("channelList: ", RED);
|
||||||
{
|
for (size_t i = 0; i < channelList.size(); ++i)
|
||||||
server->sendToClient(client->getFd(), ERR_BANNEDFROMCHAN(client, channelName));
|
{
|
||||||
return;
|
server->log(channelList[i], RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->isFull())
|
server->log("keyList: ", RED);
|
||||||
{
|
for (size_t i = 0; i < keyList.size(); ++i)
|
||||||
server->sendToClient(client->getFd(), ERR_CHANNELISFULL(client, channelName));
|
{
|
||||||
return;
|
server->log(keyList[i], RED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->isInviteOnly() && !channel->isInvited(client))
|
for (size_t i = 0; i < channelList.size(); ++i)
|
||||||
{
|
{
|
||||||
server->sendToClient(client->getFd(), ERR_INVITEONLYCHAN(client, channelName));
|
const std::string& channelName = channelList[i];
|
||||||
return;
|
server->log("Processing channel: " + channelName, RED);
|
||||||
}
|
|
||||||
|
|
||||||
if (!channel->checkKey(client->getkey()))
|
if (channelName.empty())
|
||||||
{
|
{
|
||||||
server->sendToClient(client->getFd(), ERR_BADCHANNELKEY(client, channelName));
|
server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "JOIN"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->addClient(client);
|
if (channelName[0] == '0' && channelName.size() == 1)
|
||||||
sendJoinSuccess(client, channel, server);
|
{
|
||||||
}
|
// Leave all channels
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channelName[0] != '#' && channelName[0] != '&')
|
||||||
|
{
|
||||||
|
server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channels.find(channelName) == channels.end())
|
||||||
|
{
|
||||||
|
channel = new Channel(channelName);
|
||||||
|
channels[channelName] = channel;
|
||||||
|
channel->addOperator(client); // Set client as operator for new channel
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
channel = channels[channelName];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel->isBanned(client))
|
||||||
|
{
|
||||||
|
server->sendToClient(client->getFd(), ERR_BANNEDFROMCHAN(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel->isFull())
|
||||||
|
{
|
||||||
|
server->sendToClient(client->getFd(), ERR_CHANNELISFULL(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel->isInviteOnly() && !channel->isInvited(client))
|
||||||
|
{
|
||||||
|
server->sendToClient(client->getFd(), ERR_INVITEONLYCHAN(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the key for this channel, if provided
|
||||||
|
std::string key = (i < keyList.size()) ? keyList[i] : "";
|
||||||
|
server->log("Using key: " + key + " for channel: " + channelName, RED);
|
||||||
|
|
||||||
|
if (!channel->checkKey(key))
|
||||||
|
{
|
||||||
|
server->sendToClient(client->getFd(), ERR_BADCHANNELKEY(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel->addClient(client);
|
||||||
|
sendJoinSuccess(client, channel, server);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JoinHandler::sendJoinSuccess(Client* client, Channel* channel, Server* server)
|
||||||
void JoinHandler::sendJoinSuccess(Client *client, Channel *channel, Server *server)
|
|
||||||
{
|
{
|
||||||
std::vector<Client *> clients = channel->getClients();
|
std::vector<Client*> clients = channel->getClients();
|
||||||
for (std::vector<Client *>::iterator it = clients.begin(); it != clients.end(); ++it)
|
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it)
|
||||||
{
|
{
|
||||||
std::string joinMsg = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n";
|
std::string joinMsg = ":" + client->getNickname() + " JOIN " + channel->getName() + "\r\n";
|
||||||
server->sendToClient((*it)->getFd(), joinMsg);
|
server->sendToClient((*it)->getFd(), joinMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->getTopic().empty())
|
if (!channel->getTopic().empty())
|
||||||
{
|
{
|
||||||
server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
|
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->sendToClient(client->getFd(), RPL_TOPICWHOTIME(client, channel->getName(), channel->getTopicSetter(), channel->getTopicTime()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
|
server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string usersList = getUsersList(channel);
|
std::ostringstream oss;
|
||||||
server->sendToClient(client->getFd(), usersList);
|
oss << RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes());
|
||||||
}
|
oss << RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
|
||||||
|
server->sendToClient(client->getFd(), oss.str());
|
||||||
|
|
||||||
|
std::string usersList = getUsersList(channel);
|
||||||
|
server->sendToClient(client->getFd(), usersList);
|
||||||
|
}
|
||||||
|
|
||||||
std::string JoinHandler::getUsersList(Channel *channel)
|
std::string JoinHandler::getUsersList(Channel* channel)
|
||||||
{
|
{
|
||||||
std::vector<Client *> clients = channel->getClients();
|
std::vector<Client*> clients = channel->getClients();
|
||||||
std::string users;
|
std::string users;
|
||||||
for (std::vector<Client *>::iterator it = clients.begin(); it != clients.end(); ++it)
|
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it)
|
||||||
{
|
{
|
||||||
if (channel->isOperator((*it)))
|
if (channel->isOperator((*it)))
|
||||||
users += "@";
|
users += "@";
|
||||||
users += (*it)->getNickname() + " ";
|
users += (*it)->getNickname() + " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|||||||
68
ft_irc3/src/KickHandler.cpp
Normal file
68
ft_irc3/src/KickHandler.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* KickHandler.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2024/06/01 17:00:31 by fgras-ca #+# #+# */
|
||||||
|
/* Updated: 2024/06/01 19:12:13 by fgras-ca ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "KickHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KickHandler::KickHandler(Server* server) : _server(server) {}
|
||||||
|
|
||||||
|
void KickHandler::handleKickCommand(Client* client, const std::string& command)
|
||||||
|
{
|
||||||
|
std::vector<std::string> tokens = split(command, " ");
|
||||||
|
if (tokens.size() < 3)
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "KICK"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string channelName = tokens[1];
|
||||||
|
std::string targetNickname = tokens[2];
|
||||||
|
std::string comment = (tokens.size() > 3) ? tokens[3] : "Kicked by operator";
|
||||||
|
|
||||||
|
Channel* channel = _server->getChannelByName(channelName);
|
||||||
|
if (!channel)
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel->hasClient(client))
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel->isOperator(client))
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client* targetClient = _server->getClientByName(targetNickname);
|
||||||
|
if (!targetClient)
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, targetNickname));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel->hasClient(targetClient))
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_USERNOTINCHANNEL(client, targetNickname, channelName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel->removeClient(targetClient);
|
||||||
|
std::string kickMessage = ":" + client->getNickname() + " KICK " + channelName + " " + targetNickname + " :" + comment + "\r\n";
|
||||||
|
channel->broadcast(kickMessage, NULL, _server);
|
||||||
|
_server->sendToClient(targetClient->getFd(), kickMessage);
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/30 11:13:08 by fgras-ca #+# #+# */
|
/* Created: 2024/05/30 11:13:08 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/31 11:20:45 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:15:05 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -19,17 +19,21 @@ void ModeHandler::handleModeCommand(Client* client, const std::string& command)
|
|||||||
_server->log("Received MODE command: " + command, BLUE);
|
_server->log("Received MODE command: " + command, BLUE);
|
||||||
std::vector<std::string> tokens = split(command, " \n\r\t");
|
std::vector<std::string> tokens = split(command, " \n\r\t");
|
||||||
|
|
||||||
if (tokens.size() < 2) {
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "MODE"));
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "MODE"));
|
||||||
_server->log("MODE command error: Need more parameters", RED);
|
_server->log("MODE command error: Need more parameters", RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string target = tokens[1];
|
std::string target = tokens[1];
|
||||||
if (target[0] == '#' || target[0] == '&') {
|
if (target[0] == '#' || target[0] == '&')
|
||||||
|
{
|
||||||
_server->log("Handling channel mode for target: " + target, GREEN);
|
_server->log("Handling channel mode for target: " + target, GREEN);
|
||||||
handleChannelMode(client, tokens);
|
handleChannelMode(client, tokens);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_server->log("Handling user mode for target: " + target, GREEN);
|
_server->log("Handling user mode for target: " + target, GREEN);
|
||||||
handleUserMode(client, tokens);
|
handleUserMode(client, tokens);
|
||||||
}
|
}
|
||||||
@ -40,19 +44,22 @@ void ModeHandler::handleUserMode(Client* client, const std::vector<std::string>&
|
|||||||
_server->log("Entered handleUserMode", MAGENTA);
|
_server->log("Entered handleUserMode", MAGENTA);
|
||||||
std::string target = tokens[1];
|
std::string target = tokens[1];
|
||||||
_server->log("User mode target: " + target, CYAN);
|
_server->log("User mode target: " + target, CYAN);
|
||||||
if (target != client->getNickname()) {
|
if (target != client->getNickname())
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_USERSDONTMATCH(client));
|
_server->sendToClient(client->getFd(), ERR_USERSDONTMATCH(client));
|
||||||
_server->log("User mode error: Users don't match", RED);
|
_server->log("User mode error: Users don't match", RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens.size() == 2) {
|
if (tokens.size() == 2)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), RPL_UMODEIS(client, ""));
|
_server->sendToClient(client->getFd(), RPL_UMODEIS(client, ""));
|
||||||
_server->log("Sent user modes to client", GREEN);
|
_server->log("Sent user modes to client", GREEN);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
std::string modeString = tokens[2];
|
std::string modeString = tokens[2];
|
||||||
_server->log("Updating user modes: " + modeString, BLUE);
|
_server->log("Updating user modes: " + modeString, BLUE);
|
||||||
// Additional logging or mode handling logic can be added here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,22 +69,25 @@ void ModeHandler::handleChannelMode(Client* client, const std::vector<std::strin
|
|||||||
std::string channelName = tokens[1];
|
std::string channelName = tokens[1];
|
||||||
_server->log("Channel mode target: " + channelName, CYAN);
|
_server->log("Channel mode target: " + channelName, CYAN);
|
||||||
Channel* channel = _server->getChannelByName(channelName);
|
Channel* channel = _server->getChannelByName(channelName);
|
||||||
if (!channel) {
|
if (!channel)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
||||||
_server->log("Channel mode error: No such channel " + channelName, RED);
|
_server->log("Channel mode error: No such channel " + channelName, RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens.size() == 2) {
|
if (tokens.size() == 2)
|
||||||
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << RPL_CHANNELMODEIS(client, channel->getName(), channel->getModes());
|
oss << RPL_CHANNELMODEIS(client->getFd(), channel->getName(), channel->getModes());
|
||||||
oss << RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
|
oss << RPL_CREATIONTIME(client, channel->getName(), channel->getTopicTime());
|
||||||
_server->sendToClient(client->getFd(), oss.str());
|
_server->sendToClient(client->getFd(), oss.str());
|
||||||
_server->log("Sent channel modes to client", GREEN);
|
_server->log("Sent channel modes to client", GREEN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->isOperator(client)) {
|
if (!channel->isOperator(client))
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
|
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channelName));
|
||||||
_server->log("Channel mode error: Channel operator privileges needed for " + channelName, RED);
|
_server->log("Channel mode error: Channel operator privileges needed for " + channelName, RED);
|
||||||
return;
|
return;
|
||||||
@ -87,21 +97,28 @@ void ModeHandler::handleChannelMode(Client* client, const std::vector<std::strin
|
|||||||
bool adding = true;
|
bool adding = true;
|
||||||
size_t argIndex = 3;
|
size_t argIndex = 3;
|
||||||
|
|
||||||
for (size_t i = 0; i < modeString.length(); ++i) {
|
for (size_t i = 0; i < modeString.length(); ++i)
|
||||||
|
{
|
||||||
char mode = modeString[i];
|
char mode = modeString[i];
|
||||||
if (mode == '+') {
|
if (mode == '+')
|
||||||
|
{
|
||||||
adding = true;
|
adding = true;
|
||||||
_server->log("Adding mode: " + std::string(1, mode), GREEN);
|
_server->log("Adding mode: " + std::string(1, mode), GREEN);
|
||||||
} else if (mode == '-') {
|
} else if (mode == '-')
|
||||||
|
{
|
||||||
adding = false;
|
adding = false;
|
||||||
_server->log("Removing mode: " + std::string(1, mode), RED);
|
_server->log("Removing mode: " + std::string(1, mode), RED);
|
||||||
} else if (mode == 'b' || mode == 'l' || mode == 'i' || mode == 'k' || mode == 't') {
|
} else if (mode == 'b' || mode == 'l' || mode == 'i' || mode == 'k' || mode == 't' || mode == 'o')
|
||||||
|
{
|
||||||
std::string argument;
|
std::string argument;
|
||||||
if (argIndex < tokens.size()) {
|
if (argIndex < tokens.size())
|
||||||
|
{
|
||||||
argument = tokens[argIndex++];
|
argument = tokens[argIndex++];
|
||||||
}
|
}
|
||||||
setChannelMode(client, channel, std::string(1, mode), adding, argument);
|
setChannelMode(client, channel, std::string(1, mode), adding, argument);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_UNKNOWNMODE(client, mode, channelName));
|
_server->sendToClient(client->getFd(), ERR_UNKNOWNMODE(client, mode, channelName));
|
||||||
_server->log("Unknown mode: " + std::string(1, mode), RED);
|
_server->log("Unknown mode: " + std::string(1, mode), RED);
|
||||||
}
|
}
|
||||||
@ -113,7 +130,7 @@ void ModeHandler::setChannelMode(Client *client, Channel* channel, const std::st
|
|||||||
_server->log("Setting channel mode: " + mode + " Adding: " + (adding ? "true" : "false") + " Argument: " + argument, GREEN);
|
_server->log("Setting channel mode: " + mode + " Adding: " + (adding ? "true" : "false") + " Argument: " + argument, GREEN);
|
||||||
if (mode == "l")
|
if (mode == "l")
|
||||||
{
|
{
|
||||||
applyModeL(channel, adding, argument);
|
applyModeL(client, channel, adding, argument);
|
||||||
}
|
}
|
||||||
else if (mode == "i")
|
else if (mode == "i")
|
||||||
{
|
{
|
||||||
@ -131,15 +148,24 @@ void ModeHandler::setChannelMode(Client *client, Channel* channel, const std::st
|
|||||||
applyModeO(client, channel, adding, argument);
|
applyModeO(client, channel, adding, argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModeHandler::applyModeL(Channel* channel, bool adding, const std::string& argument)
|
void ModeHandler::applyModeL(Client *client, Channel* channel, bool adding, const std::string& argument)
|
||||||
{
|
{
|
||||||
if (adding) {
|
if (adding)
|
||||||
|
{
|
||||||
int limit = std::atoi(argument.c_str());
|
int limit = std::atoi(argument.c_str());
|
||||||
|
if (limit <= 0)
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_INVALIDMODEPARAM(client, argument));
|
||||||
|
_server->log("Invalid limit for mode +l: " + argument, RED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << limit;
|
oss << limit;
|
||||||
_server->log("Applying mode L: Setting limit to " + oss.str(), GREEN);
|
_server->log("Applying mode L: Setting limit to " + oss.str(), GREEN);
|
||||||
channel->setClientLimit(limit);
|
channel->setClientLimit(limit);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_server->log("Applying mode L: Removing limit", RED);
|
_server->log("Applying mode L: Removing limit", RED);
|
||||||
channel->setClientLimit(0);
|
channel->setClientLimit(0);
|
||||||
}
|
}
|
||||||
@ -153,16 +179,25 @@ void ModeHandler::applyModeI(Channel* channel, bool adding)
|
|||||||
|
|
||||||
void ModeHandler::applyModeK(Client *client, Channel* channel, bool adding, const std::string& argument)
|
void ModeHandler::applyModeK(Client *client, Channel* channel, bool adding, const std::string& argument)
|
||||||
{
|
{
|
||||||
if (adding) {
|
if (adding)
|
||||||
if (argument.find(' ') != std::string::npos) {
|
{
|
||||||
|
if (argument.empty())
|
||||||
|
{
|
||||||
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "MODE +k"));
|
||||||
|
_server->log("Mode +k error: No key provided", RED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argument.find(' ') != std::string::npos)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_INVALIDMODEPARAM(client, argument));
|
_server->sendToClient(client->getFd(), ERR_INVALIDMODEPARAM(client, argument));
|
||||||
_server->log("Invalid key for mode +k: contains spaces", RED);
|
_server->log("Invalid key for mode +k: contains spaces", RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// You can add more validation checks here if needed
|
|
||||||
_server->log("Applying mode K: Setting key to " + argument, GREEN);
|
_server->log("Applying mode K: Setting key to " + argument, GREEN);
|
||||||
channel->setKey(argument);
|
channel->setKey(argument);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_server->log("Applying mode K: Removing key", RED);
|
_server->log("Applying mode K: Removing key", RED);
|
||||||
channel->setKey("");
|
channel->setKey("");
|
||||||
}
|
}
|
||||||
@ -177,24 +212,29 @@ void ModeHandler::applyModeT(Channel* channel, bool adding)
|
|||||||
void ModeHandler::applyModeO(Client* client, Channel* channel, bool adding, const std::string& argument)
|
void ModeHandler::applyModeO(Client* client, Channel* channel, bool adding, const std::string& argument)
|
||||||
{
|
{
|
||||||
Client* targetClient = _server->getClientByName(argument);
|
Client* targetClient = _server->getClientByName(argument);
|
||||||
if (!targetClient) {
|
if (!targetClient)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, argument));
|
_server->sendToClient(client->getFd(), ERR_NOSUCHNICK(client, argument));
|
||||||
_server->log("Mode o error: No such client " + argument, RED);
|
_server->log("Mode o error: No such client " + argument, RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->hasClient(targetClient)) {
|
if (!channel->hasClient(targetClient))
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_USERNOTINCHANNEL(client, argument, channel->getName()));
|
_server->sendToClient(client->getFd(), ERR_USERNOTINCHANNEL(client, argument, channel->getName()));
|
||||||
_server->log("Mode o error: Client " + argument + " not in channel " + channel->getName(), RED);
|
_server->log("Mode o error: Client " + argument + " not in channel " + channel->getName(), RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adding) {
|
if (adding)
|
||||||
|
{
|
||||||
_server->log("Applying mode o: Adding operator " + argument, GREEN);
|
_server->log("Applying mode o: Adding operator " + argument, GREEN);
|
||||||
channel->addOperator(targetClient);
|
channel->addOperator(targetClient);
|
||||||
std::string message = ":" + client->getNickname() + " MODE " + channel->getName() + " +o " + targetClient->getNickname() + "\r\n";
|
std::string message = ":" + client->getNickname() + " MODE " + channel->getName() + " +o " + targetClient->getNickname() + "\r\n";
|
||||||
channel->broadcast(message, NULL, _server);
|
channel->broadcast(message, NULL, _server);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_server->log("Applying mode o: Removing operator " + argument, RED);
|
_server->log("Applying mode o: Removing operator " + argument, RED);
|
||||||
channel->removeOperator(targetClient);
|
channel->removeOperator(targetClient);
|
||||||
std::string message = ":" + client->getNickname() + " MODE " + channel->getName() + " -o " + targetClient->getNickname() + "\r\n";
|
std::string message = ":" + client->getNickname() + " MODE " + channel->getName() + " -o " + targetClient->getNickname() + "\r\n";
|
||||||
|
|||||||
@ -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:12 by fgras-ca #+# #+# */
|
/* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 17:14:19 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:16:36 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ Server::~Server()
|
|||||||
{
|
{
|
||||||
delete _clientManager;
|
delete _clientManager;
|
||||||
delete _commandHandler;
|
delete _commandHandler;
|
||||||
|
delete _topicHandler;
|
||||||
|
|
||||||
for (std::map<int, Client*>::iterator it = _clients.begin(); it != _clients.end(); ++it)
|
for (std::map<int, Client*>::iterator it = _clients.begin(); it != _clients.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -60,14 +61,14 @@ void Server::initServer()
|
|||||||
if (bind(_server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
|
if (bind(_server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
|
||||||
{
|
{
|
||||||
log("Failed to bind socket.", RED);
|
log("Failed to bind socket.", RED);
|
||||||
close(_server_fd); // Close the socket if bind fails
|
close(_server_fd);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(_server_fd, SOMAXCONN) == -1)
|
if (listen(_server_fd, SOMAXCONN) == -1)
|
||||||
{
|
{
|
||||||
log("Failed to listen on socket.", RED);
|
log("Failed to listen on socket.", RED);
|
||||||
close(_server_fd); // Close the socket if listen fails
|
close(_server_fd);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +83,6 @@ void Server::run()
|
|||||||
server_pollfd.revents = 0;
|
server_pollfd.revents = 0;
|
||||||
_poll_fds.push_back(server_pollfd);
|
_poll_fds.push_back(server_pollfd);
|
||||||
|
|
||||||
// Ajout de l'entrée pour les commandes serveur
|
|
||||||
struct pollfd stdin_pollfd;
|
struct pollfd stdin_pollfd;
|
||||||
stdin_pollfd.fd = STDIN_FILENO;
|
stdin_pollfd.fd = STDIN_FILENO;
|
||||||
stdin_pollfd.events = POLLIN;
|
stdin_pollfd.events = POLLIN;
|
||||||
@ -180,12 +180,12 @@ void Server::sendToClient(int client_fd, const std::string &message)
|
|||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Sent message to client " << client_fd << ": " << message;
|
ss << "Sent message to client " << client_fd << ": " << message;
|
||||||
log(ss.str(), BLUE);
|
log(ss.str(), YELLOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::map<int, Client *> &Server::getClients()
|
std::map<int, Client *> &Server::getClients()
|
||||||
{
|
{
|
||||||
return _clients;
|
return _clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::broadcast(const std::string &message)
|
void Server::broadcast(const std::string &message)
|
||||||
@ -205,15 +205,17 @@ Client* Server::getClientByName(const std::string &name)
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL; // Remplacez nullptr par NULL
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Channel* Server::getChannelByName(const std::string &name) {
|
Channel* Server::getChannelByName(const std::string &name)
|
||||||
std::map<std::string, Channel *>::iterator it = _channels.find(name);
|
{
|
||||||
if (it != _channels.end()) {
|
std::map<std::string, Channel *>::iterator it = _channels.find(name);
|
||||||
return it->second;
|
if (it != _channels.end())
|
||||||
}
|
{
|
||||||
return NULL;
|
return it->second;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendChannelListToClient(Client *client)
|
void Server::sendChannelListToClient(Client *client)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/05/30 17:04:58 by fgras-ca #+# #+# */
|
/* Created: 2024/05/30 17:04:58 by fgras-ca #+# #+# */
|
||||||
/* Updated: 2024/05/30 18:05:42 by fgras-ca ### ########.fr */
|
/* Updated: 2024/06/01 19:17:25 by fgras-ca ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -19,29 +19,35 @@ void TopicHandler::handleTopicCommand(Client* client, const std::string& command
|
|||||||
_server->log("Received TOPIC command: " + command, "\033[1;34m");
|
_server->log("Received TOPIC 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) {
|
if (tokens.size() < 2)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "TOPIC"));
|
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "TOPIC"));
|
||||||
_server->log("TOPIC command error: Need more parameters", "\033[1;31m");
|
_server->log("TOPIC command error: Need more parameters", RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string channelName = tokens[1];
|
std::string channelName = tokens[1];
|
||||||
Channel* channel = _server->getChannelByName(channelName);
|
Channel* channel = _server->getChannelByName(channelName);
|
||||||
if (!channel) {
|
if (!channel)
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
_server->sendToClient(client->getFd(), ERR_NOSUCHCHANNEL(client, channelName));
|
||||||
_server->log("TOPIC command error: No such channel " + channelName, "\033[1;31m");
|
_server->log("TOPIC command error: No such channel " + channelName, RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel->hasClient(client)) {
|
if (!channel->hasClient(client))
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
_server->sendToClient(client->getFd(), ERR_NOTONCHANNEL(client, channelName));
|
||||||
_server->log("TOPIC command error: Client not on channel " + channelName, "\033[1;31m");
|
_server->log("TOPIC command error: Client not on channel " + channelName, RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tokens.size() == 2) {
|
if (tokens.size() == 2)
|
||||||
|
{
|
||||||
viewTopic(client, channel);
|
viewTopic(client, channel);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
size_t topicStart = command.find(" :");
|
size_t topicStart = command.find(" :");
|
||||||
std::string topic = (topicStart != std::string::npos) ? command.substr(topicStart + 2) : "";
|
std::string topic = (topicStart != std::string::npos) ? command.substr(topicStart + 2) : "";
|
||||||
changeTopic(client, channel, topic);
|
changeTopic(client, channel, topic);
|
||||||
@ -50,33 +56,39 @@ void TopicHandler::handleTopicCommand(Client* client, const std::string& command
|
|||||||
|
|
||||||
void TopicHandler::viewTopic(Client* client, Channel* channel)
|
void TopicHandler::viewTopic(Client* client, Channel* channel)
|
||||||
{
|
{
|
||||||
if (channel->getTopic().empty()) {
|
if (channel->getTopic().empty())
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
|
_server->sendToClient(client->getFd(), RPL_NOTOPIC(client, channel->getName()));
|
||||||
_server->log("No topic set for channel " + channel->getName(), "\033[1;32m");
|
_server->log("No topic set for channel " + channel->getName(), GREEN);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
|
_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->sendToClient(client->getFd(), RPL_TOPICWHOTIME(client, channel->getName(), channel->getTopicSetter(), channel->getTopicTime()));
|
||||||
_server->log("Sent topic info for channel " + channel->getName(), "\033[1;32m");
|
_server->log("Sent topic info for channel " + channel->getName(), GREEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopicHandler::changeTopic(Client* client, Channel* channel, const std::string& topic)
|
void TopicHandler::changeTopic(Client* client, Channel* channel, const std::string& topic)
|
||||||
{
|
{
|
||||||
if (channel->getTopicProtection() && !channel->isOperator(client)) {
|
if (channel->getTopicProtection() && !channel->isOperator(client))
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channel->getName()));
|
_server->sendToClient(client->getFd(), ERR_CHANOPRIVSNEEDED(client, channel->getName()));
|
||||||
_server->log("TOPIC command error: Channel operator privileges needed for " + channel->getName(), "\033[1;31m");
|
_server->log("TOPIC command error: Channel operator privileges needed for " + channel->getName(), RED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topic == channel->getTopic()) {
|
if (topic == channel->getTopic())
|
||||||
|
{
|
||||||
_server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
|
_server->sendToClient(client->getFd(), RPL_TOPIC(client, channel->getName(), channel->getTopic()));
|
||||||
_server->log("TOPIC unchanged for channel " + channel->getName(), "\033[1;32m");
|
_server->log("TOPIC unchanged for channel " + channel->getName(), GREEN);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->setTopic(topic, client->getNickname());
|
channel->setTopic(topic, client->getNickname());
|
||||||
std::vector<Client*> clients = channel->getClients();
|
std::vector<Client*> clients = channel->getClients();
|
||||||
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it) {
|
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->sendToClient((*it)->getFd(), ":" + client->getNickname() + " TOPIC " + channel->getName() + " :" + topic + "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user