correctifs

This commit is contained in:
Ladebeze66 2024-05-19 19:30:11 +02:00
parent 3660d41dea
commit f2725946e0
26 changed files with 629 additions and 234 deletions

View File

@ -1,65 +1,65 @@
{ {
"files.associations": { "files.associations": {
"array": "cpp", "array": "cpp",
"atomic": "cpp", "atomic": "cpp",
"bit": "cpp", "bit": "cpp",
"*.tcc": "cpp", "*.tcc": "cpp",
"cctype": "cpp", "cctype": "cpp",
"clocale": "cpp", "clocale": "cpp",
"cmath": "cpp", "cmath": "cpp",
"compare": "cpp", "compare": "cpp",
"concepts": "cpp", "concepts": "cpp",
"cstdarg": "cpp", "cstdarg": "cpp",
"cstddef": "cpp", "cstddef": "cpp",
"cstdint": "cpp", "cstdint": "cpp",
"cstdio": "cpp", "cstdio": "cpp",
"cstdlib": "cpp", "cstdlib": "cpp",
"cstring": "cpp", "cstring": "cpp",
"cwchar": "cpp", "cwchar": "cpp",
"cwctype": "cpp", "cwctype": "cpp",
"deque": "cpp", "deque": "cpp",
"map": "cpp", "map": "cpp",
"string": "cpp", "string": "cpp",
"unordered_map": "cpp", "unordered_map": "cpp",
"vector": "cpp", "vector": "cpp",
"exception": "cpp", "exception": "cpp",
"algorithm": "cpp", "algorithm": "cpp",
"functional": "cpp", "functional": "cpp",
"iterator": "cpp", "iterator": "cpp",
"memory": "cpp", "memory": "cpp",
"memory_resource": "cpp", "memory_resource": "cpp",
"numeric": "cpp", "numeric": "cpp",
"random": "cpp", "random": "cpp",
"string_view": "cpp", "string_view": "cpp",
"system_error": "cpp", "system_error": "cpp",
"tuple": "cpp", "tuple": "cpp",
"type_traits": "cpp", "type_traits": "cpp",
"utility": "cpp", "utility": "cpp",
"fstream": "cpp", "fstream": "cpp",
"initializer_list": "cpp", "initializer_list": "cpp",
"iosfwd": "cpp", "iosfwd": "cpp",
"iostream": "cpp", "iostream": "cpp",
"istream": "cpp", "istream": "cpp",
"limits": "cpp", "limits": "cpp",
"new": "cpp", "new": "cpp",
"numbers": "cpp", "numbers": "cpp",
"ostream": "cpp", "ostream": "cpp",
"sstream": "cpp", "sstream": "cpp",
"stdexcept": "cpp", "stdexcept": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"typeinfo": "cpp", "typeinfo": "cpp",
"list": "cpp", "list": "cpp",
"chrono": "cpp", "chrono": "cpp",
"condition_variable": "cpp", "condition_variable": "cpp",
"ctime": "cpp", "ctime": "cpp",
"set": "cpp", "set": "cpp",
"ratio": "cpp", "ratio": "cpp",
"mutex": "cpp", "mutex": "cpp",
"semaphore": "cpp", "semaphore": "cpp",
"stop_token": "cpp", "stop_token": "cpp",
"thread": "cpp", "thread": "cpp",
"cinttypes": "cpp" "cinttypes": "cpp"
}, },
"C_Cpp_Runner.cCompilerPath": "gcc", "C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++", "C_Cpp_Runner.cppCompilerPath": "g++",
"C_Cpp_Runner.debuggerPath": "gdb", "C_Cpp_Runner.debuggerPath": "gdb",

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/16 15:23:58 by fgras-ca #+# #+# */ /* Created: 2024/05/16 15:23:58 by fgras-ca #+# #+# */
/* Updated: 2024/05/16 16:03:22 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 19:18:11 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -17,16 +17,21 @@
#include "Server.hpp" #include "Server.hpp"
#include "Channel.hpp" #include "Channel.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "RPL.hpp"
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <fstream>
// Forward declarations
class Server; class Server;
class Client; class Client;
class Channel; class Channel;
void sendWelcomeMessages(Client *client, Server *server);
void sendMotd(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 #endif // ADDITIONALCOMMANDS_HPP

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:41:35 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:41:35 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 20:08:13 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 15:14:50 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -17,6 +17,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <set> #include <set>
#include "RPL.hpp"
class Client; class Client;

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:15:42 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:15:42 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 17:21:39 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 15:38:28 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -18,13 +18,15 @@
class Client class Client
{ {
public: public:
Client(int fd, const std::string &nickname, const std::string &user); Client(int fd, const std::string &nickname, const std::string &user, const std::string &host, const std::string &password, const std::string &realname);
int getFd() const; int getFd() const;
const std::string &getNickname() const; const std::string &getNickname() const;
void setNickname(const std::string &nickname); void setNickname(const std::string &nickname);
const std::string &getUser() const; const std::string &getUser() const;
void setUser(const std::string &user); void setUser(const std::string &user);
const std::string &getHost() const;
void setHost(const std::string &host);
const std::string &getPassword() const; const std::string &getPassword() const;
void setPassword(const std::string &password); void setPassword(const std::string &password);
const std::string &getRealName() const; const std::string &getRealName() const;
@ -38,10 +40,11 @@ private:
int _fd; int _fd;
std::string _nickname; std::string _nickname;
std::string _user; std::string _user;
std::string _host;
std::string _password; std::string _password;
std::string _realname; std::string _realname;
bool _authenticated; bool _authenticated;
bool _operator; bool _operator;
}; };
#endif #endif // CLIENT_HPP

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 18:30:07 by fgras-ca #+# #+# */ /* Created: 2024/05/15 18:30:07 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 18:51:44 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 18:56:44 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -18,24 +18,31 @@
#include "Client.hpp" #include "Client.hpp"
#include "Channel.hpp" #include "Channel.hpp"
#include "Server.hpp" #include "Server.hpp"
#include <poll.h>
#include "CommandHandler.hpp" #include "CommandHandler.hpp"
#include "AdditionalCommands.hpp"
#include "RPL.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include <poll.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <fcntl.h> #include <fcntl.h>
#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>
#include <fstream>
class Server; class Server;
class Client;
class ClientManager class ClientManager
{ {
public: public:
ClientManager(Server *server); ClientManager(Server *server);
void acceptClient(); void acceptClient();
void broadcastChannelList(Client *client);
void handleClient(int client_fd); void handleClient(int client_fd);
void removeClient(int client_fd); void removeClient(int client_fd);

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 18:14:12 by fgras-ca #+# #+# */ /* Created: 2024/05/15 18:14:12 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 17:10:38 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 19:13:53 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -20,6 +20,7 @@
#include "AdditionalCommands.hpp" #include "AdditionalCommands.hpp"
#include "ModeWhoHandler.hpp" #include "ModeWhoHandler.hpp"
#include "CommandHandler.hpp" #include "CommandHandler.hpp"
#include "RPL.hpp"
#include <string> #include <string>
#include <sstream> #include <sstream>
@ -27,6 +28,7 @@
class Server; class Server;
class ModeWhoHandler; class ModeWhoHandler;
class AdditinalCommands;
class CommandHandler class CommandHandler
{ {
@ -35,7 +37,16 @@ private:
public: public:
CommandHandler(Server *server); CommandHandler(Server *server);
bool isValidNickname(const std::string& nickname);
bool isNicknameInUse(const std::string& nickname);
void handleNick(Client* client, const std::vector<std::string>& tokens);
void handleUser(Client* client, const std::vector<std::string>& tokens);
void handlePingCommand(Client* client, const std::vector<std::string>& tokens);
void handleCommand(Client *client, const std::string &command); void handleCommand(Client *client, const std::string &command);
void handleCapCommand(Client* client, const std::vector<std::string>& tokens);
void handlePassCommand(Client* client, const std::vector<std::string>& tokens);
void processCommand(Client *client, const std::string &command); void processCommand(Client *client, const std::string &command);
void handleJoinCommand(Client *client, const std::string &channelName); void handleJoinCommand(Client *client, const std::string &channelName);
std::string getUsersList(Channel *channel); std::string getUsersList(Channel *channel);

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/17 16:08:48 by fgras-ca #+# #+# */ /* Created: 2024/05/17 16:08:48 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 18:08:06 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 15:15:39 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -17,6 +17,10 @@
#include "Client.hpp" #include "Client.hpp"
#include "Channel.hpp" #include "Channel.hpp"
#include "Utils.hpp" #include "Utils.hpp"
#include "RPL.hpp"
#include <sstream>
#include <iostream>
class Server; class Server;

221
ft_irc3/includes/RPL.hpp Normal file
View File

@ -0,0 +1,221 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* RPL.hpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/19 15:12:47 by fgras-ca #+# #+# */
/* Updated: 2024/05/19 19:07:25 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef RPL_HPP
#define RPL_HPP
#include <string>
#include <sstream>
#include "Client.hpp"
#define SERVER_NAME "IRC_Server"
#define SERVER_VERSION "1.0"
#define USER_MODES "iw"
#define CHANNEL_MODES "nt"
#define CHANNEL_MODES_WITH_PARAMS "kl"
// Macros pour accéder aux champs du client
#define CLIENT_FD(client) (client->getFd())
#define CLIENT_NICK(client) ((client)->getNickname())
#define CLIENT_USER(client) ((client)->getUser())
#define CLIENT_HOST(client) ((client)->getHost())
// Fonctions pour générer les réponses RPL
inline std::string RPL_WELCOME(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 001 " << CLIENT_FD(client)
<< " :Welcome to the Internet Relay Network " << CLIENT_NICK(client)
<< "!" << CLIENT_USER(client) << "@" << CLIENT_HOST(client) << "\r\n";
return oss.str();
}
inline std::string RPL_YOURHOST(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 002 " << CLIENT_FD(client)
<< " :Your host is " << SERVER_NAME << ", running version " << SERVER_VERSION << "\r\n";
return oss.str();
}
inline std::string RPL_CREATED(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 003 " << CLIENT_FD(client)
<< " :This server was created " << __DATE__ << "\r\n";
return oss.str();
}
inline std::string RPL_MYINFO(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 004 " << CLIENT_FD(client) << " "
<< SERVER_NAME << " " << SERVER_VERSION << " "
<< USER_MODES << " " << CHANNEL_MODES << " "
<< CHANNEL_MODES_WITH_PARAMS << "\r\n";
return oss.str();
}
inline std::string RPL_ISUPPORT(Client* client, const std::string& tokens) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 005 " << CLIENT_FD(client)
<< " " << tokens << " :are supported by this server\r\n";
return oss.str();
}
inline std::string RPL_MOTDSTART(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 375 " << CLIENT_FD(client)
<< " :- " << SERVER_NAME << " Message of the day - \r\n";
return oss.str();
}
inline std::string RPL_MOTD(Client* client, const std::string& line) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 372 " << CLIENT_FD(client)
<< " :- " << line << "\r\n";
return oss.str();
}
inline std::string RPL_ENDOFMOTD(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 376 " << CLIENT_FD(client)
<< " :End of /MOTD command.\r\n";
return oss.str();
}
inline std::string ERR_NOMOTD(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 422 " << CLIENT_FD(client)
<< " :MOTD File is missing\r\n";
return oss.str();
}
// RPL Channel List Messages
inline std::string RPL_LIST(Client* client, const std::string& channel, int numVisible, const std::string& topic) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 322 " << CLIENT_FD(client) << " " << channel
<< " " << numVisible << " :" << topic << "\r\n";
return oss.str();
}
inline std::string RPL_LISTEND(Client* client) {
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 323 " << CLIENT_FD(client)
<< " :End of /LIST\r\n";
return oss.str();
}
//RPL Password
// RPL Error Messages
inline std::string ERR_NEEDMOREPARAMS(Client* client, const std::string& command)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 461 " << CLIENT_FD(client) << " " << command << " :Not enough parameters\r\n";
return oss.str();
}
inline std::string ERR_ALREADYREGISTERED(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 462 " << CLIENT_FD(client) << " :You may not reregister\r\n";
return oss.str();
}
inline std::string ERR_PASSWDMISMATCH(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 464 " << CLIENT_FD(client) << " :Password incorrect\r\n";
return oss.str();
}
inline std::string ERR_NOTREGISTERED(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 451 " << CLIENT_FD(client) << " :You have not registered\r\n";
return oss.str();
}
inline std::string ERR_NONICKNAMEGIVEN(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 431 " << CLIENT_FD(client) << " :No nickname given\r\n";
return oss.str();
}
inline std::string ERR_ERRONEUSNICKNAME(Client* client, const std::string& nickname)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 432 " << CLIENT_FD(client) << " " << nickname << " :Erroneous nickname\r\n";
return oss.str();
}
inline std::string ERR_NICKNAMEINUSE(Client* client, const std::string& nickname)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 433 " << CLIENT_FD(client) << " " << nickname << " :Nickname is already in use\r\n";
return oss.str();
}
// RPL Error Messages
inline std::string ERR_NOORIGIN(Client* client)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 409 " << CLIENT_FD(client) << " :No origin specified\r\n";
return oss.str();
}
// PONG Reply
inline std::string RPL_PONG(const std::string& token)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " PONG " << SERVER_NAME << " " << token << "\r\n";
return oss.str();
}
// ERR_UNKNOWNCOMMAND (421)
inline std::string ERR_UNKNOWNCOMMAND(Client* client, const std::string& command)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 421 " << CLIENT_FD(client) << " " << command << " :Unknown command\r\n";
return oss.str();
}
// RPL Channel List Messages
inline std::string RPL_LIST(int clientFd, const std::string& channel, int numVisible, const std::string& topic)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 322 " << clientFd << " " << channel << " " << numVisible << " :" << topic << "\r\n";
return oss.str();
}
inline std::string RPL_LISTEND(int clientFd)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 323 " << clientFd << " :End of /LIST\r\n";
return oss.str();
}
inline std::string ERR_NEEDMOREPARAMS(int clientFd, const std::string& command)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 461 " << clientFd << " " << command << " :Not enough parameters\r\n";
return oss.str();
}
inline std::string ERR_UNKNOWNCOMMAND(int clientFd, const std::string& command)
{
std::ostringstream oss;
oss << ":" << SERVER_NAME << " 421 " << clientFd << " " << command << " :Unknown command\r\n";
return oss.str();
}
#endif // RPL_HPP

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:15:13 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:15:13 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 20:03:06 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 16:30:56 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -19,6 +19,7 @@
#include "ClientManager.hpp" #include "ClientManager.hpp"
#include "CommandHandler.hpp" #include "CommandHandler.hpp"
#include "AdditionalCommands.hpp" #include "AdditionalCommands.hpp"
#include "RPL.hpp"
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>

BIN
ft_irc3/ircserv Executable file

Binary file not shown.

View File

Binary file not shown.

BIN
ft_irc3/obj/Channel.o Normal file

Binary file not shown.

BIN
ft_irc3/obj/Client.o Normal file

Binary file not shown.

BIN
ft_irc3/obj/ClientManager.o Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
ft_irc3/obj/Server.o Normal file

Binary file not shown.

BIN
ft_irc3/obj/Utils.o Normal file

Binary file not shown.

BIN
ft_irc3/obj/main.o Normal file

Binary file not shown.

View File

@ -6,12 +6,47 @@
/* 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/17 20:15:14 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 19:22:28 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "AdditionalCommands.hpp" #include "AdditionalCommands.hpp"
void sendWelcomeMessages(Client *client, Server *server) {
server->sendToClient(client->getFd(), RPL_WELCOME(client));
server->sendToClient(client->getFd(), RPL_YOURHOST(client));
server->sendToClient(client->getFd(), RPL_CREATED(client));
server->sendToClient(client->getFd(), RPL_MYINFO(client));
server->sendToClient(client->getFd(), RPL_ISUPPORT(client, "MODES=EXAMPLE"));
sendMotd(client, server);
}
void sendMotd(Client *client, Server *server) {
std::ifstream motdFile("motd.txt");
if (motdFile.is_open()) {
std::string line;
server->sendToClient(client->getFd(), RPL_MOTDSTART(client));
while (std::getline(motdFile, line)) {
server->sendToClient(client->getFd(), RPL_MOTD(client, line));
}
server->sendToClient(client->getFd(), RPL_ENDOFMOTD(client));
motdFile.close();
} else {
server->sendToClient(client->getFd(), ERR_NOMOTD(client));
}
}
void broadcastChannelList(Client *client, Server *server)
{
std::map<std::string, Channel *> &channels = server->getChannels();
for (std::map<std::string, Channel *>::iterator it = channels.begin(); it != channels.end(); ++it)
{
server->sendToClient(client->getFd(), RPL_LIST(client->getFd(), it->first, it->second->getClients().size(), "Existing channel"));
}
server->sendToClient(client->getFd(), RPL_LISTEND(client->getFd()));
}
// Fonction pour gérer la commande PART // Fonction pour gérer la commande PART
void handlePartCommand(Server *server, Client *client, const std::string &command) void handlePartCommand(Server *server, Client *client, const std::string &command)
{ {

View File

@ -6,17 +6,16 @@
/* 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/17 17:20:02 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 15:38:46 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "Client.hpp" #include "Client.hpp"
Client::Client(int fd, const std::string &nickname, const std::string &user) 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), _authenticated(false), _operator(false) : _fd(fd), _nickname(nickname), _user(user), _host(host), _password(password), _realname(realname), _authenticated(false), _operator(false)
{ {
} }
int Client::getFd() const int Client::getFd() const
{ {
return _fd; return _fd;
@ -42,6 +41,16 @@ void Client::setUser(const std::string &user)
_user = user; _user = user;
} }
const std::string &Client::getHost() const
{
return _host;
}
void Client::setHost(const std::string &host)
{
_host = host;
}
const std::string &Client::getPassword() const const std::string &Client::getPassword() const
{ {
return _password; return _password;
@ -86,6 +95,8 @@ void Client::setOperator(bool isOperator)
/*Client::Client(int fd) /*Client::Client(int fd)
Description: Constructeur de la classe Client. Initialise le client avec le descripteur de fichier fourni. Description: Constructeur de la classe Client. Initialise le client avec le descripteur de fichier fourni.

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 18:32:23 by fgras-ca #+# #+# */ /* Created: 2024/05/15 18:32:23 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 18:53:09 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 18:55:55 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -26,7 +26,8 @@ void ClientManager::acceptClient()
return; return;
} }
_server->_clients[client_fd] = new Client(client_fd, "", ""); // Initialize with default values Client *newClient = new Client(client_fd, "", "", "", "", ""); // Fournir six arguments
_server->_clients[client_fd] = newClient;
struct pollfd client_pollfd; struct pollfd client_pollfd;
client_pollfd.fd = client_fd; client_pollfd.fd = client_fd;
client_pollfd.events = POLLIN; client_pollfd.events = POLLIN;
@ -35,16 +36,8 @@ void ClientManager::acceptClient()
std::stringstream ss; std::stringstream ss;
ss << "Client connected: " << client_fd; ss << "Client connected: " << client_fd;
_server->log(ss.str(), GREEN); _server->log(ss.str(), GREEN);
}
void ClientManager::broadcastChannelList(Client *client) { sendWelcomeMessages(newClient, _server);
std::map<std::string, Channel *> &channels = _server->getChannels();
for (std::map<std::string, Channel *>::iterator it = channels.begin(); it != channels.end(); ++it) {
std::stringstream channelMsg;
channelMsg << ":server 322 " << client->getNickname() << " " << it->first << " :Existing channel\r\n";
_server->sendToClient(client->getFd(), channelMsg.str());
}
_server->sendToClient(client->getFd(), ":server 323 " + client->getNickname() + " :End of /LIST\r\n");
} }
void ClientManager::handleClient(int client_fd) void ClientManager::handleClient(int client_fd)
@ -69,12 +62,10 @@ void ClientManager::handleClient(int client_fd)
while (std::getline(message_stream, line)) while (std::getline(message_stream, line))
{ {
// Suppression des caractères de fin de ligne
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());
_server->_commandHandler->handleCommand(client, line); _server->_commandHandler->handleCommand(client, line);
broadcastChannelList(_server->_clients[client_fd]);
} }
} }
@ -83,7 +74,6 @@ void ClientManager::removeClient(int client_fd)
Client *client = _server->_clients[client_fd]; Client *client = _server->_clients[client_fd];
if (client) if (client)
{ {
// Retirer le client de tous les canaux auxquels il appartient
std::map<std::string, Channel *>::iterator it = _server->_channels.begin(); std::map<std::string, Channel *>::iterator it = _server->_channels.begin();
while (it != _server->_channels.end()) while (it != _server->_channels.end())
{ {

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 18:26:34 by fgras-ca #+# #+# */ /* Created: 2024/05/15 18:26:34 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 20:05:16 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 19:13:14 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -17,77 +17,191 @@ CommandHandler::CommandHandler(Server *server)
{ {
} }
void CommandHandler::handleCommand(Client *client, const std::string &command) 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);
else if (commandType == "PASS") } else if (commandType == "PASS") {
{ handlePassCommand(client, tokens);
if (tokens.size() > 1 && tokens[1] == _server->_password) } else if (commandType == "NICK") {
{ handleNick(client, tokens);
client->setPassword(tokens[1]); } else if (commandType == "USER") {
_server->sendToClient(client->getFd(), ":server 001 " + client->getNickname() + " :Password accepted!\r\n"); handleUser(client, tokens);
_server->log("Client " + client->getNickname() + " provided correct password.", GREEN); } else {
_server->sendChannelListToClient(client); if (!client->isAuthenticated()) {
} _server->sendToClient(client->getFd(), ERR_NOTREGISTERED(client));
else _server->log("Client " + client->getNickname() + " attempted to send a command before registering.", RED);
{ } else {
_server->sendToClient(client->getFd(), ":server 464 " + client->getNickname() + " :Invalid password\r\n");
_server->log("Client " + client->getNickname() + " failed authentication password.", RED);
}
}
else if (commandType == "NICK")
{
if (tokens.size() > 1)
{
client->setNickname(tokens[1]);
std::stringstream ss;
ss << "Client " << client->getFd() << " Nickname: " << tokens[1];
_server->log(ss.str(), GREEN);
_server->sendToClient(client->getFd(), ":" + tokens[1] + " NICK " + tokens[1] + "\r\n");
}
}
else if (commandType == "USER")
{
if (tokens.size() > 4)
{
client->setUser(tokens[1]);
client->setRealName(tokens[4].substr(1)); // remove leading ':'
if (client->getPassword() == _server->_password && !client->getNickname().empty())
{
client->authenticate();
std::stringstream welcomeMsg;
welcomeMsg << ":server 001 " << client->getNickname() << " :Welcome to the IRC server!\r\n";
_server->sendToClient(client->getFd(), welcomeMsg.str());
_server->log("Client " + client->getNickname() + " authenticated.", GREEN);
_server->sendChannelListToClient(client);
}
}
}
else
{
if (!client->isAuthenticated())
{
_server->sendToClient(client->getFd(), ":server 451 " + client->getNickname() + " :Please provide the password first\r\n");
_server->log("Client " + client->getNickname() + " failed authentication.", RED);
}
else
{
processCommand(client, command); processCommand(client, command);
} }
} }
std::cout << "Client " << client->getFd() << " " << client->getNickname() << " " << client->getUser() << " " << client->getPassword() << " " << client->getRealName() << std::endl; 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)
{
if (tokens.size() < 2)
{
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client->getFd(), "CAP"));
return;
}
std::string subcommand = tokens[1];
if (subcommand == "LS")
{
// Example for CAP LS response
std::vector<std::string> capLines;
capLines.push_back("multi-prefix extended-join account-notify batch invite-notify tls");
capLines.push_back("cap-notify server-time example.org/dummy-cap=dummyvalue example.org/second-dummy-cap");
capLines.push_back("userhost-in-names sasl=EXTERNAL,DH-AES,DH-BLOWFISH,ECDSA-NIST256P-CHALLENGE,PLAIN");
for (size_t i = 0; i < capLines.size(); ++i)
{
std::ostringstream oss;
oss << ":irc.example.com CAP " << client->getNickname() << " LS";
if (i != capLines.size() - 1)
oss << " * :";
else
oss << " :";
oss << capLines[i] << "\r\n";
_server->sendToClient(client->getFd(), oss.str());
}
}
else if (subcommand == "LIST")
{
// Example for CAP LIST response
std::ostringstream oss;
oss << ":irc.example.com CAP " << client->getNickname() << " LIST :example.org/example-cap example.org/second-example-cap account-notify invite-notify batch example.org/third-example-cap\r\n";
_server->sendToClient(client->getFd(), oss.str());
}
else if (subcommand == "REQ")
{
if (tokens.size() < 3)
{
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client->getFd(), "CAP"));
return;
}
// Example for CAP REQ response
std::string requestedCaps = tokens[2];
std::ostringstream ackResponse;
ackResponse << ":irc.example.com CAP " << client->getNickname() << " ACK :" << requestedCaps << "\r\n";
_server->sendToClient(client->getFd(), ackResponse.str());
}
else if (subcommand == "END")
{
// Example for CAP END response
_server->sendToClient(client->getFd(), ":irc.example.com CAP " + client->getNickname() + " END\r\n");
}
else
{
// Unknown CAP subcommand
_server->sendToClient(client->getFd(), ERR_UNKNOWNCOMMAND(client->getFd(), "CAP"));
}
}
void CommandHandler::handlePassCommand(Client* client, const std::vector<std::string>& tokens)
{
if (tokens.size() < 2) {
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PASS"));
return;
}
if (client->isAuthenticated()) {
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
return;
}
if (tokens[1] == _server->_password) {
client->setPassword(tokens[1]);
_server->sendToClient(client->getFd(), ":server NOTICE * :Password accepted\r\n");
_server->log("Client " + client->getNickname() + " provided correct password.", GREEN);
} else {
_server->sendToClient(client->getFd(), ERR_PASSWDMISMATCH(client));
_server->log("Client " + client->getNickname() + " failed authentication password.", RED);
// Optionally disconnect the client here
}
}
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) {
return false;
}
return true;
}
bool CommandHandler::isNicknameInUse(const std::string& nickname)
{
for (std::map<int, Client*>::iterator it = _server->_clients.begin(); it != _server->_clients.end(); ++it) {
if (it->second->getNickname() == nickname) {
return true;
}
}
return false;
}
void CommandHandler::handleNick(Client* client, const std::vector<std::string>& tokens)
{
if (tokens.size() < 2) {
_server->sendToClient(client->getFd(), ERR_NONICKNAMEGIVEN(client));
return;
}
std::string newNick = tokens[1];
if (!isValidNickname(newNick)) {
_server->sendToClient(client->getFd(), ERR_ERRONEUSNICKNAME(client, newNick));
return;
}
if (isNicknameInUse(newNick)) {
_server->sendToClient(client->getFd(), ERR_NICKNAMEINUSE(client, newNick));
return;
}
std::string oldNick = client->getNickname();
client->setNickname(newNick);
if (!oldNick.empty()) {
_server->broadcast(":" + oldNick + " NICK " + newNick + "\r\n");
}
_server->sendToClient(client->getFd(), ":" + newNick + " NICK " + newNick + "\r\n");
_server->log("Client " + oldNick + " changed nickname to " + newNick, GREEN);
}
void CommandHandler::handleUser(Client* client, const std::vector<std::string>& tokens)
{
if (tokens.size() < 5) {
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "USER"));
return;
}
if (client->isAuthenticated()) {
_server->sendToClient(client->getFd(), ERR_ALREADYREGISTERED(client));
return;
}
client->setUser(tokens[1]);
client->setRealName(tokens[4].substr(1)); // remove leading ':'
if (client->getPassword() == _server->_password && !client->getNickname().empty()) {
client->authenticate();
sendWelcomeMessages(client, _server);
_server->log("Client " + client->getNickname() + " authenticated.", GREEN);
}
}
void CommandHandler::processCommand(Client *client, const std::string &command) void CommandHandler::processCommand(Client *client, const std::string &command)
{ {
if (command.find("JOIN") == 0) if (command.find("JOIN") == 0)
@ -116,12 +230,19 @@ void CommandHandler::processCommand(Client *client, const std::string &command)
{ {
ModeWhoHandler whoHandler(_server); ModeWhoHandler whoHandler(_server);
whoHandler.handleWhoCommand(client, command); whoHandler.handleWhoCommand(client, command);
}
else if (command.find("PING") == 0)
{
std::vector<std::string> tokens = split(command, " ");
handlePingCommand(client, tokens);
}
else if (command.find("LIST") == 0)
{
broadcastChannelList(client, _server);
} }
else else
{ {
std::stringstream ss; _server->sendToClient(client->getFd(), ERR_UNKNOWNCOMMAND(client, command));
ss << ":server 421 " << client->getNickname() << " " << command << " :Unknown command\r\n";
_server->sendToClient(client->getFd(), ss.str());
_server->log("Message from client " + client->getNickname() + ": " + command, MAGENTA); _server->log("Message from client " + client->getNickname() + ": " + command, MAGENTA);
} }
} }
@ -155,9 +276,6 @@ void CommandHandler::handleJoinCommand(Client *client, const std::string &channe
_server->log(ss.str(), MAGENTA); _server->log(ss.str(), MAGENTA);
} }
std::string CommandHandler::getUsersList(Channel *channel) std::string CommandHandler::getUsersList(Channel *channel)
{ {
std::vector<Client *> clients = channel->getClients(); std::vector<Client *> clients = channel->getClients();
@ -172,3 +290,14 @@ std::string CommandHandler::getUsersList(Channel *channel)
ss << "\r\n"; ss << "\r\n";
return ss.str(); return ss.str();
} }
void CommandHandler::handlePingCommand(Client* client, const std::vector<std::string>& tokens)
{
if (tokens.size() < 2) {
_server->sendToClient(client->getFd(), ERR_NEEDMOREPARAMS(client, "PING"));
return;
}
std::string token = tokens[1];
_server->sendToClient(client->getFd(), RPL_PONG(token));
}

View File

@ -6,22 +6,12 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/17 16:09:20 by fgras-ca #+# #+# */ /* Created: 2024/05/17 16:09:20 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 18:24:34 by fgras-ca ### ########.fr */ /* Updated: 2024/05/18 16:41:10 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "ModeWhoHandler.hpp" #include "ModeWhoHandler.hpp"
#include "Channel.hpp" #include "Channel.hpp"
#include <sstream>
#include <iostream>
// Couleurs ANSI pour les logs
#define RESET "\033[0m"
#define GREEN "\033[32m"
#define YELLOW "\033[33m"
#define RED "\033[31m"
#define BLUE "\033[34m"
#define MAGENTA "\033[35m"
ModeWhoHandler::ModeWhoHandler(Server *server) ModeWhoHandler::ModeWhoHandler(Server *server)
: _server(server) : _server(server)
@ -37,7 +27,7 @@ void ModeWhoHandler::handleModeCommand(Client *client, const std::string &comman
std::map<std::string, Channel *> &channels = _server->getChannels(); std::map<std::string, Channel *> &channels = _server->getChannels();
if (channels.find(channelName) == channels.end()) if (channels.find(channelName) == channels.end())
{ {
_server->sendToClient(client->getFd(), ":server 403 " + client->getNickname() + " " + channelName + " :No such channel\r\n"); _server->sendToClient(client->getFd(), ":" SERVER_NAME " 403 " + client->getNickname() + " " + channelName + " :No such channel\r\n");
return; return;
} }
@ -55,12 +45,12 @@ void ModeWhoHandler::handleModeCommand(Client *client, const std::string &comman
} }
else else
{ {
_server->sendToClient(client->getFd(), ":server 401 " + client->getNickname() + " " + user + " :No such nick/channel\r\n"); _server->sendToClient(client->getFd(), ":" SERVER_NAME " 401 " + client->getNickname() + " " + user + " :No such nick/channel\r\n");
} }
} }
else else
{ {
_server->sendToClient(client->getFd(), ":server 482 " + client->getNickname() + " " + channelName + " :You're not channel operator\r\n"); _server->sendToClient(client->getFd(), ":" SERVER_NAME " 482 " + client->getNickname() + " " + channelName + " :You're not channel operator\r\n");
} }
} }
} }
@ -74,7 +64,7 @@ void ModeWhoHandler::handleWhoCommand(Client *client, const std::string &command
std::map<std::string, Channel *> &channels = _server->getChannels(); std::map<std::string, Channel *> &channels = _server->getChannels();
if (channels.find(channelName) == channels.end()) if (channels.find(channelName) == channels.end())
{ {
_server->sendToClient(client->getFd(), ":server 403 " + client->getNickname() + " " + channelName + " :No such channel\r\n"); _server->sendToClient(client->getFd(), ":" SERVER_NAME " 403 " + client->getNickname() + " " + channelName + " :No such channel\r\n");
return; return;
} }
@ -84,12 +74,12 @@ void ModeWhoHandler::handleWhoCommand(Client *client, const std::string &command
for (size_t i = 0; i < channelClients.size(); ++i) for (size_t i = 0; i < channelClients.size(); ++i)
{ {
std::stringstream whoMsg; std::stringstream whoMsg;
whoMsg << ":server 352 " << client->getNickname() << " " << channelName << " " << channelClients[i]->getNickname() << " " whoMsg << ":" SERVER_NAME " 352 " << client->getNickname() << " " << channelName << " " << channelClients[i]->getNickname() << " "
<< channelClients[i]->getUser() << " " << _server->getPassword() << " " << channelClients[i]->getRealName() << "\r\n"; << channelClients[i]->getUser() << " " << channelClients[i]->getHost() << " " << _server->getPassword() << " " << channelClients[i]->getRealName() << "\r\n";
_server->sendToClient(client->getFd(), whoMsg.str()); _server->sendToClient(client->getFd(), whoMsg.str());
} }
std::stringstream endOfWhoMsg; std::stringstream endOfWhoMsg;
endOfWhoMsg << ":server 315 " << client->getNickname() << " " << channelName << " :End of /WHO list.\r\n"; endOfWhoMsg << ":" SERVER_NAME " 315 " << client->getNickname() << " " << channelName << " :End of /WHO list.\r\n";
_server->sendToClient(client->getFd(), endOfWhoMsg.str()); _server->sendToClient(client->getFd(), endOfWhoMsg.str());
} }

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */ /* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */ /* Created: 2024/05/15 12:17:12 by fgras-ca #+# #+# */
/* Updated: 2024/05/17 20:03:44 by fgras-ca ### ########.fr */ /* Updated: 2024/05/19 19:21:54 by fgras-ca ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -72,6 +72,13 @@ 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;
stdin_pollfd.fd = STDIN_FILENO;
stdin_pollfd.events = POLLIN;
stdin_pollfd.revents = 0;
_poll_fds.push_back(stdin_pollfd);
while (true) while (true)
{ {
int poll_count = poll(&_poll_fds[0], _poll_fds.size(), -1); int poll_count = poll(&_poll_fds[0], _poll_fds.size(), -1);
@ -89,57 +96,59 @@ void Server::run()
{ {
_clientManager->acceptClient(); _clientManager->acceptClient();
} }
else if (_poll_fds[i].fd == STDIN_FILENO)
{
handleServerCommands();
}
else else
{ {
_clientManager->handleClient(_poll_fds[i].fd); _clientManager->handleClient(_poll_fds[i].fd);
} }
} }
} }
handleServerCommands();
} }
} }
std::map<std::string, Channel *> &Server::getChannels()
{
return _channels;
}
const std::string &Server::getPassword() const
{
return _password;
}
void Server::handleServerCommands() void Server::handleServerCommands()
{ {
fd_set readfds; std::string command;
FD_ZERO(&readfds); std::getline(std::cin, command);
FD_SET(STDIN_FILENO, &readfds);
struct timeval tv = {0, 0}; // non-blocking
int activity = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv); if (command == "quit")
if (activity > 0 && FD_ISSET(STDIN_FILENO, &readfds))
{ {
std::string command; log("Server shutting down.", YELLOW);
std::getline(std::cin, command); exit(EXIT_SUCCESS);
}
if (command == "quit") else if (command == "channels")
{
log("Listing all channels:", BLUE);
for (std::map<std::string, Channel*>::iterator it = _channels.begin(); it != _channels.end(); ++it)
{ {
log("Server shutting down.", YELLOW); log(it->first, BLUE);
exit(EXIT_SUCCESS);
} }
else if (command == "channels") }
else if (command == "clients")
{
log("Listing all clients:", BLUE);
for (std::map<int, Client*>::iterator it = _clients.begin(); it != _clients.end(); ++it)
{ {
log("Listing all channels:", BLUE); log(it->second->getNickname(), BLUE);
for (std::map<std::string, Channel*>::iterator it = _channels.begin(); it != _channels.end(); ++it)
{
log(it->first, BLUE);
}
}
else if (command == "clients")
{
log("Listing all clients:", BLUE);
for (std::map<int, Client*>::iterator it = _clients.begin(); it != _clients.end(); ++it)
{
log(it->second->getNickname(), BLUE);
}
}
else
{
log("Unknown server command.", RED);
} }
} }
else
{
log("Unknown server command.", RED);
}
} }
void Server::log(const std::string &message, const std::string &color) void Server::log(const std::string &message, const std::string &color)
@ -147,7 +156,6 @@ void Server::log(const std::string &message, const std::string &color)
std::cout << color << message << "\033[0m" << std::endl; std::cout << color << message << "\033[0m" << std::endl;
} }
void Server::sendToClient(int client_fd, const std::string &message) void Server::sendToClient(int client_fd, const std::string &message)
{ {
int result = send(client_fd, message.c_str(), message.length(), 0); int result = send(client_fd, message.c_str(), message.length(), 0);
@ -165,11 +173,6 @@ void Server::sendToClient(int client_fd, const std::string &message)
} }
} }
const std::string &Server::getPassword() const
{
return _password;
}
void Server::broadcast(const std::string &message) void Server::broadcast(const std::string &message)
{ {
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)
@ -178,16 +181,6 @@ void Server::broadcast(const std::string &message)
} }
} }
std::map<std::string, Channel *> &Server::getChannels()
{
return _channels;
}
std::map<int, Client *> &Server::getClients()
{
return _clients;
}
Client* Server::getClientByName(const std::string &name) Client* Server::getClientByName(const std::string &name)
{ {
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)
@ -205,17 +198,11 @@ void Server::sendChannelListToClient(Client *client)
std::map<std::string, Channel *> &channels = getChannels(); std::map<std::string, Channel *> &channels = getChannels();
for (std::map<std::string, Channel *>::iterator it = channels.begin(); it != channels.end(); ++it) for (std::map<std::string, Channel *>::iterator it = channels.begin(); it != channels.end(); ++it)
{ {
std::stringstream channelMsg; sendToClient(client->getFd(), RPL_LIST(client->getFd(), it->first, it->second->getClients().size(), "Existing channel"));
channelMsg << ":server 322 " << client->getNickname() << " " << it->first << " :" << it->second->getClients().size() << "\r\n";
sendToClient(client->getFd(), channelMsg.str());
} }
std::stringstream endOfListMsg; sendToClient(client->getFd(), RPL_LISTEND(client->getFd()));
endOfListMsg << ":server 323 " << client->getNickname() << " :End of /LIST\r\n";
sendToClient(client->getFd(), endOfListMsg.str());
} }
/* Explications des Fonctions /* Explications des Fonctions
Server::Server(int port, const std::string &password) Server::Server(int port, const std::string &password)