diff --git a/includes/channel.hpp b/includes/channel.hpp index 2644283..1db2769 100644 --- a/includes/channel.hpp +++ b/includes/channel.hpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 10:34:25 by maldavid #+# #+# */ -/* Updated: 2024/01/22 20:05:52 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 10:49:35 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -28,13 +28,16 @@ namespace irc inline const std::string& getName() const { return _name; } inline const std::string& getPassword() const { return _password; } - inline void addClient(unstd::SharedPtr client) { _clients.insert(client); } - inline bool removeClient(unstd::SharedPtr client) { return _clients.erase(client); } + void addClient(unstd::SharedPtr client); + bool removeClient(unstd::SharedPtr client); + inline std::size_t getNumberOfClients() const { return _clients.size(); } inline void addOperator(unstd::SharedPtr op) { _operators.insert(op); } inline bool removeOperator(unstd::SharedPtr op) { return _operators.erase(op); } + void handleMessage(const std::string& msg, unstd::SharedPtr client) const; + inline bool isInviteOnly() const { return _invite_only; } void setTopic(unstd::SharedPtr client, const std::string& new_topic); diff --git a/includes/client.hpp b/includes/client.hpp index e58d124..e739fd0 100644 --- a/includes/client.hpp +++ b/includes/client.hpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 10:33:17 by maldavid #+# #+# */ -/* Updated: 2024/01/22 20:41:53 by vvaas ### ########.fr */ +/* Updated: 2024/01/23 10:30:27 by maldavid ### ########.fr */ /* */ /******************************************************************************/ @@ -44,7 +44,9 @@ namespace irc inline void setFd(int new_fd) { _fd = new_fd; } - void sendCode(const std::string& code, const std::string &msg); + void sendCode(const std::string& code, const std::string& msg); + void sendMsg(const std::string& sender, const std::string& cmd, const std::string& trailing); + ~Client(); private: diff --git a/includes/config.hpp b/includes/config.hpp index 8a6c192..056b8d3 100644 --- a/includes/config.hpp +++ b/includes/config.hpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/22 09:45:10 by maldavid #+# #+# */ -/* Updated: 2024/01/22 09:46:42 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 10:22:15 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,5 +15,7 @@ #define INPUT_SIZE 1024 #define LOGS_BUFFER_SIZE 4096 +#define MAX_USERS 20 +#define NULL_SOCKET -1 #endif diff --git a/includes/irc.hpp b/includes/irc.hpp index 4a607e0..f843576 100644 --- a/includes/irc.hpp +++ b/includes/irc.hpp @@ -6,19 +6,16 @@ /* By: vavaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/29 13:24:01 by vavaas #+# #+# */ -/* Updated: 2024/01/22 09:46:18 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 10:14:40 by maldavid ### ########.fr */ /* */ /******************************************************************************/ #ifndef __IRC__ #define __IRC__ -#include -#include #include #include #include -#include #include #include diff --git a/includes/server.hpp b/includes/server.hpp index 3e2afb2..c30f035 100644 --- a/includes/server.hpp +++ b/includes/server.hpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 09:12:28 by maldavid #+# #+# */ -/* Updated: 2024/01/22 17:30:47 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 10:21:04 by maldavid ### ########.fr */ /* */ /******************************************************************************/ @@ -17,9 +17,7 @@ #include #include #include -#include - -#define MAX_USERS 20 +#include namespace irc { @@ -28,7 +26,14 @@ namespace irc public: Server(int port, const std::string& password); - inline void closeMainSocket() { close(_main_socket); _main_socket = 0; _active = false; } + inline void closeMainSocket() + { + if(_main_socket > NULL_SOCKET) + close(_main_socket); + _main_socket = NULL_SOCKET; + _active = false; + } + void wait(); ~Server(); diff --git a/srcs/ansi.cpp b/srcs/ansi.cpp index 0c58595..6857c8d 100644 --- a/srcs/ansi.cpp +++ b/srcs/ansi.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/20 19:08:31 by maldavid #+# #+# */ -/* Updated: 2024/01/20 19:18:41 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 09:38:17 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/srcs/channel.cpp b/srcs/channel.cpp index 2b59f9c..c4bda60 100644 --- a/srcs/channel.cpp +++ b/srcs/channel.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 10:36:21 by maldavid #+# #+# */ -/* Updated: 2024/01/22 20:06:36 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 11:01:06 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,9 +14,32 @@ namespace irc { - Channel::Channel(const std::string& name) : _name(name) - { + Channel::Channel(const std::string& name) : _name(name) {} + void Channel::addClient(unstd::SharedPtr client) + { + if(!_clients.insert(client).second) // client already in coco channel + return; + for(std::set >::iterator it = _clients.begin(); it != _clients.end(); ++it) + { + const_cast&>(*it)->sendMsg(client->getNickName(), "JOIN", _name); + } + } + + bool Channel::removeClient(unstd::SharedPtr client) + { + return _clients.erase(client); + } + + void Channel::handleMessage(const std::string& msg, unstd::SharedPtr client) const + { + const std::string sender = client ? client->getNickName() : ""; + for(std::set >::iterator it = _clients.begin(); it != _clients.end(); ++it) + { + if(client == *it) + continue; + const_cast&>(*it)->sendMsg(sender, "PRIVMSG " + _name, msg); + } } void Channel::setTopic(unstd::SharedPtr client, const std::string& new_topic) diff --git a/srcs/client.cpp b/srcs/client.cpp index 3313dbf..e26be1d 100644 --- a/srcs/client.cpp +++ b/srcs/client.cpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 10:35:52 by maldavid #+# #+# */ -/* Updated: 2024/01/22 20:52:52 by vvaas ### ########.fr */ +/* Updated: 2024/01/23 12:38:15 by maldavid ### ########.fr */ /* */ /******************************************************************************/ @@ -20,17 +20,25 @@ namespace irc { Client::Client(int fd, sockaddr_in sock, int id) : _s_data(sock), _fd(fd), _id(id) {} - void Client::sendCode(const std::string& code, const std::string &msg) + void Client::sendCode(const std::string& code, const std::string& msg) { const std::string command = code + " :" + msg; - send(_fd, command.c_str(), command.size(), 0); + if(send(_fd, command.c_str(), command.size(), 0) != static_cast(command.length())) + logs::report(log_error, "server failed to send a code to '%s' (:sadge:)", _username.c_str()); + } + + void Client::sendMsg(const std::string& sender, const std::string& cmd, const std::string& trailing) + { + const std::string out = ':' + sender + ' ' + cmd + " :" + trailing + "\r\n"; + if(send(_fd, out.c_str(), out.length(), 0) != static_cast(out.length())) + logs::report(log_error, "server failed to send a message from '%s' to '%s' (:sadge:)", sender.c_str(), _username.c_str()); } void Client::printUserHeader() const { std::cout << AnsiColor::green << "[User " << _id; if(!_realname.empty()) - std::cout << " " << _realname; + std::cout << " {realname " << _realname << '}'; if(!_username.empty()) std::cout << " {username " << _username << "}"; if(!_nickname.empty()) diff --git a/srcs/main.cpp b/srcs/main.cpp index cdb5a0b..f9278f2 100644 --- a/srcs/main.cpp +++ b/srcs/main.cpp @@ -6,17 +6,17 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/20 09:27:04 by maldavid #+# #+# */ -/* Updated: 2024/01/22 21:04:13 by vvaas ### ########.fr */ +/* Updated: 2024/01/23 10:23:01 by maldavid ### ########.fr */ /* */ /******************************************************************************/ #include #include -#include #include #include #include #include +#include static unstd::SharedPtr server_ref; @@ -51,5 +51,6 @@ int main(int ac, char** av) signal(SIGQUIT, signalsHandler); serv->wait(); serv->closeMainSocket(); + irc::logs::report(irc::log_message, "Server has been closed"); return 0; } diff --git a/srcs/server.cpp b/srcs/server.cpp index c232962..5de2d5d 100644 --- a/srcs/server.cpp +++ b/srcs/server.cpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 09:31:17 by maldavid #+# #+# */ -/* Updated: 2024/01/22 17:44:27 by maldavid ### ########.fr */ +/* Updated: 2024/01/23 10:48:00 by maldavid ### ########.fr */ /* */ /******************************************************************************/ @@ -15,13 +15,10 @@ #include #include #include -#include -#include #include #include #include #include -#include namespace irc { @@ -73,6 +70,7 @@ namespace irc while(recv((*it)->getFD(), buffer, INPUT_SIZE, 0) > 0) // read() but for socket fd { (*it)->newMsgInFlight(buffer); + //std::cout << buffer << std::endl; while(handleMessage(*it)); std::memset(buffer, 0, sizeof(buffer)); // clear the buffer to avoid trash remaining } @@ -101,13 +99,13 @@ namespace irc FD_SET((*it)->getFD(), &_fd_set); tmp = select(MAX_USERS, &_fd_set, NULL, NULL, NULL); // SELECT blocks till a connection or message is received, and let only those in _fd_set - if(tmp < 0 && _main_socket != 0) + if(tmp < 0 && _main_socket != NULL_SOCKET) logs::report(log_fatal_error, "select fd error"); if(FD_ISSET(_main_socket, &_fd_set)) // if it's a new connection { sockaddr_in cli_sock; - fd = accept(_main_socket, (sockaddr *)&cli_sock, &len); // adds the new connection + fd = accept(_main_socket, reinterpret_cast(&cli_sock), &len); // adds the new connection if(fd < 0) logs::report(log_fatal_error, "accept() error"); if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) @@ -159,7 +157,6 @@ namespace irc Server::~Server() { - if(_main_socket > 0) - close(_main_socket); + closeMainSocket(); } } diff --git a/srcs/server_functions.cpp b/srcs/server_functions.cpp index 4e0832d..f6cd18a 100644 --- a/srcs/server_functions.cpp +++ b/srcs/server_functions.cpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/22 17:31:06 by maldavid #+# #+# */ -/* Updated: 2024/01/22 21:09:56 by vvaas ### ########.fr */ +/* Updated: 2024/01/23 12:33:34 by maldavid ### ########.fr */ /* */ /******************************************************************************/ @@ -15,13 +15,10 @@ #include #include #include -#include -#include #include #include #include #include -#include #include #include @@ -34,14 +31,16 @@ namespace irc logs::report(log_error, "NICK, invalid command '%s'", msg.getRawMsg().c_str()); return; } + const std::string& nickname = msg.getTokens()[1]; for(std::vector >::iterator it = _client.begin(); it != _client.end(); ++it) { - if((*it)->getNickName() == msg.getTokens()[1]) + if((*it)->getNickName() == nickname) { client->sendCode(ERR_NICKCOLLISION, "Nickname is used"); - return ; + return; } } + client->printUserHeader(); client->setNewNickName(msg.getTokens()[1]); std::cout << "new nickname, " << client->getNickName() << std::endl; @@ -58,9 +57,9 @@ namespace irc client->setNewUserName(msg.getTokens()[1]); std::cout << "new username, " << client->getUserName() << std::endl; - //client->printUserHeader(); - //client->setNewRealName(msg.getTokens()[1]); - //std::cout << "new realname, " << client->getRealName() << std::endl; + client->printUserHeader(); + client->setNewRealName(msg.getTokens()[4]); + std::cout << "new realname, " << client->getRealName() << std::endl; } void Server::handleQuit(unstd::SharedPtr client, const Message& msg) @@ -149,8 +148,20 @@ namespace irc void Server::handlePrivMsg(unstd::SharedPtr client, const Message& msg) { - (void)client; - (void)msg; + if(msg.getTokens().size() < 2) + { + logs::report(log_error, "PRIVMSG, invalid command '%s'", msg.getRawMsg().c_str()); + return; + } + std::vector::iterator it; + for(it = _channels.begin(); it != _channels.end(); ++it) + { + if(msg.getTokens()[1] == it->getName()) + { + it->handleMessage(msg.getTokens()[2], client); + break; + } + } } void Server::handleNotice(unstd::SharedPtr client, const Message& msg)