This commit is contained in:
Kbz-8
2024-01-23 13:16:52 +01:00
parent 2cda614d92
commit 8042d3db6f
11 changed files with 93 additions and 44 deletions

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 10:34:25 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& getName() const { return _name; }
inline const std::string& getPassword() const { return _password; } inline const std::string& getPassword() const { return _password; }
inline void addClient(unstd::SharedPtr<Client> client) { _clients.insert(client); } void addClient(unstd::SharedPtr<Client> client);
inline bool removeClient(unstd::SharedPtr<Client> client) { return _clients.erase(client); } bool removeClient(unstd::SharedPtr<Client> client);
inline std::size_t getNumberOfClients() const { return _clients.size(); } inline std::size_t getNumberOfClients() const { return _clients.size(); }
inline void addOperator(unstd::SharedPtr<Client> op) { _operators.insert(op); } inline void addOperator(unstd::SharedPtr<Client> op) { _operators.insert(op); }
inline bool removeOperator(unstd::SharedPtr<Client> op) { return _operators.erase(op); } inline bool removeOperator(unstd::SharedPtr<Client> op) { return _operators.erase(op); }
void handleMessage(const std::string& msg, unstd::SharedPtr<Client> client) const;
inline bool isInviteOnly() const { return _invite_only; } inline bool isInviteOnly() const { return _invite_only; }
void setTopic(unstd::SharedPtr<Client> client, const std::string& new_topic); void setTopic(unstd::SharedPtr<Client> client, const std::string& new_topic);

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 10:33:17 by maldavid #+# #+# */ /* 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; } 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(); ~Client();
private: private:

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/22 09:45:10 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 INPUT_SIZE 1024
#define LOGS_BUFFER_SIZE 4096 #define LOGS_BUFFER_SIZE 4096
#define MAX_USERS 20
#define NULL_SOCKET -1
#endif #endif

View File

@@ -6,19 +6,16 @@
/* By: vavaas <vavaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vavaas <vavaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/29 13:24:01 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__ #ifndef __IRC__
#define __IRC__ #define __IRC__
#include <iostream>
#include <string>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h> #include <unistd.h>
#include <cstdlib>
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> #include <arpa/inet.h>

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 09:12:28 by maldavid #+# #+# */ /* 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 <vector> #include <vector>
#include <irc.hpp> #include <irc.hpp>
#include <unstd/shared_ptr.hpp> #include <unstd/shared_ptr.hpp>
#include <csignal> #include <config.hpp>
#define MAX_USERS 20
namespace irc namespace irc
{ {
@@ -28,7 +26,14 @@ namespace irc
public: public:
Server(int port, const std::string& password); 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(); void wait();
~Server(); ~Server();

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/20 19:08:31 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 */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 10:36:21 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 namespace irc
{ {
Channel::Channel(const std::string& name) : _name(name) Channel::Channel(const std::string& name) : _name(name) {}
{
void Channel::addClient(unstd::SharedPtr<Client> client)
{
if(!_clients.insert(client).second) // client already in coco channel
return;
for(std::set<unstd::SharedPtr<Client> >::iterator it = _clients.begin(); it != _clients.end(); ++it)
{
const_cast<unstd::SharedPtr<irc::Client>&>(*it)->sendMsg(client->getNickName(), "JOIN", _name);
}
}
bool Channel::removeClient(unstd::SharedPtr<Client> client)
{
return _clients.erase(client);
}
void Channel::handleMessage(const std::string& msg, unstd::SharedPtr<Client> client) const
{
const std::string sender = client ? client->getNickName() : "";
for(std::set<unstd::SharedPtr<Client> >::iterator it = _clients.begin(); it != _clients.end(); ++it)
{
if(client == *it)
continue;
const_cast<unstd::SharedPtr<irc::Client>&>(*it)->sendMsg(sender, "PRIVMSG " + _name, msg);
}
} }
void Channel::setTopic(unstd::SharedPtr<Client> client, const std::string& new_topic) void Channel::setTopic(unstd::SharedPtr<Client> client, const std::string& new_topic)

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 10:35:52 by maldavid #+# #+# */ /* 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) {} 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; 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<ssize_t>(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<ssize_t>(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 void Client::printUserHeader() const
{ {
std::cout << AnsiColor::green << "[User " << _id; std::cout << AnsiColor::green << "[User " << _id;
if(!_realname.empty()) if(!_realname.empty())
std::cout << " " << _realname; std::cout << " {realname " << _realname << '}';
if(!_username.empty()) if(!_username.empty())
std::cout << " {username " << _username << "}"; std::cout << " {username " << _username << "}";
if(!_nickname.empty()) if(!_nickname.empty())

View File

@@ -6,17 +6,17 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/20 09:27:04 by maldavid #+# #+# */ /* 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 <logs.hpp> #include <logs.hpp>
#include <cstdlib> #include <cstdlib>
#include <cctype>
#include <cstring> #include <cstring>
#include <cerrno> #include <cerrno>
#include <server.hpp> #include <server.hpp>
#include <signal.h> #include <signal.h>
#include <iostream>
static unstd::SharedPtr<irc::Server> server_ref; static unstd::SharedPtr<irc::Server> server_ref;
@@ -51,5 +51,6 @@ int main(int ac, char** av)
signal(SIGQUIT, signalsHandler); signal(SIGQUIT, signalsHandler);
serv->wait(); serv->wait();
serv->closeMainSocket(); serv->closeMainSocket();
irc::logs::report(irc::log_message, "Server has been closed");
return 0; return 0;
} }

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 09:31:17 by maldavid #+# #+# */ /* 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 <channel.hpp> #include <channel.hpp>
#include <logs.hpp> #include <logs.hpp>
#include <cstring> #include <cstring>
#include <errno.h>
#include <stack>
#include <fcntl.h> #include <fcntl.h>
#include <ansi.hpp> #include <ansi.hpp>
#include <config.hpp> #include <config.hpp>
#include <message.hpp> #include <message.hpp>
#include <algorithm>
namespace irc namespace irc
{ {
@@ -73,6 +70,7 @@ namespace irc
while(recv((*it)->getFD(), buffer, INPUT_SIZE, 0) > 0) // read() but for socket fd while(recv((*it)->getFD(), buffer, INPUT_SIZE, 0) > 0) // read() but for socket fd
{ {
(*it)->newMsgInFlight(buffer); (*it)->newMsgInFlight(buffer);
//std::cout << buffer << std::endl;
while(handleMessage(*it)); while(handleMessage(*it));
std::memset(buffer, 0, sizeof(buffer)); // clear the buffer to avoid trash remaining 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); 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 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"); logs::report(log_fatal_error, "select fd error");
if(FD_ISSET(_main_socket, &_fd_set)) // if it's a new connection if(FD_ISSET(_main_socket, &_fd_set)) // if it's a new connection
{ {
sockaddr_in cli_sock; sockaddr_in cli_sock;
fd = accept(_main_socket, (sockaddr *)&cli_sock, &len); // adds the new connection fd = accept(_main_socket, reinterpret_cast<sockaddr*>(&cli_sock), &len); // adds the new connection
if(fd < 0) if(fd < 0)
logs::report(log_fatal_error, "accept() error"); logs::report(log_fatal_error, "accept() error");
if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0) if(fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
@@ -159,7 +157,6 @@ namespace irc
Server::~Server() Server::~Server()
{ {
if(_main_socket > 0) closeMainSocket();
close(_main_socket);
} }
} }

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/22 17:31:06 by maldavid #+# #+# */ /* 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 <channel.hpp> #include <channel.hpp>
#include <logs.hpp> #include <logs.hpp>
#include <cstring> #include <cstring>
#include <errno.h>
#include <stack>
#include <fcntl.h> #include <fcntl.h>
#include <ansi.hpp> #include <ansi.hpp>
#include <config.hpp> #include <config.hpp>
#include <message.hpp> #include <message.hpp>
#include <algorithm>
#include <errorscode.hpp> #include <errorscode.hpp>
#include <irc.hpp> #include <irc.hpp>
@@ -34,14 +31,16 @@ namespace irc
logs::report(log_error, "NICK, invalid command '%s'", msg.getRawMsg().c_str()); logs::report(log_error, "NICK, invalid command '%s'", msg.getRawMsg().c_str());
return; return;
} }
const std::string& nickname = msg.getTokens()[1];
for(std::vector<unstd::SharedPtr<Client> >::iterator it = _client.begin(); it != _client.end(); ++it) for(std::vector<unstd::SharedPtr<Client> >::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"); client->sendCode(ERR_NICKCOLLISION, "Nickname is used");
return ; return;
} }
} }
client->printUserHeader(); client->printUserHeader();
client->setNewNickName(msg.getTokens()[1]); client->setNewNickName(msg.getTokens()[1]);
std::cout << "new nickname, " << client->getNickName() << std::endl; std::cout << "new nickname, " << client->getNickName() << std::endl;
@@ -58,9 +57,9 @@ namespace irc
client->setNewUserName(msg.getTokens()[1]); client->setNewUserName(msg.getTokens()[1]);
std::cout << "new username, " << client->getUserName() << std::endl; std::cout << "new username, " << client->getUserName() << std::endl;
//client->printUserHeader(); client->printUserHeader();
//client->setNewRealName(msg.getTokens()[1]); client->setNewRealName(msg.getTokens()[4]);
//std::cout << "new realname, " << client->getRealName() << std::endl; std::cout << "new realname, " << client->getRealName() << std::endl;
} }
void Server::handleQuit(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleQuit(unstd::SharedPtr<class Client> client, const Message& msg)
@@ -149,8 +148,20 @@ namespace irc
void Server::handlePrivMsg(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handlePrivMsg(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
(void)client; if(msg.getTokens().size() < 2)
(void)msg; {
logs::report(log_error, "PRIVMSG, invalid command '%s'", msg.getRawMsg().c_str());
return;
}
std::vector<Channel>::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<class Client> client, const Message& msg) void Server::handleNotice(unstd::SharedPtr<class Client> client, const Message& msg)