This commit is contained in:
Kbz-8
2024-01-24 16:35:52 +01:00
parent 0fb93fa399
commit 9ab9e38d86
7 changed files with 97 additions and 63 deletions

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 10:34:25 by maldavid #+# #+# */ /* Created: 2024/01/21 10:34:25 by maldavid #+# #+# */
/* Updated: 2024/01/24 00:42:16 by vvaas ### ########.fr */ /* Updated: 2024/01/24 15:34:26 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -37,8 +37,7 @@ 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; }
void addClient(unstd::SharedPtr<Client> client); void addClient(unstd::SharedPtr<Client> client, bool op = false);
void addClient(unstd::SharedPtr<Client> client, bool op);
bool removeClient(unstd::SharedPtr<Client> 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(); }
@@ -46,7 +45,7 @@ namespace irc
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; void handleMessage(const std::string& msg, unstd::SharedPtr<Client> client, bool notice = false) const;
inline bool isInviteOnly() const { return _invite_only; } inline bool isInviteOnly() const { return _invite_only; }

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/24 00:11:46 by vvaas ### ########.fr */ /* Updated: 2024/01/24 15:00:39 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -27,8 +27,6 @@ namespace irc
inline int getFD() const { return _fd; } inline int getFD() const { return _fd; }
inline int getID() const { return _id; } inline int getID() const { return _id; }
inline int getLogged() const { return _logged; }
inline int getDisconnect() const { return _to_disconnect; }
inline sockaddr_in getSockAddr() const { return _s_data; } inline sockaddr_in getSockAddr() const { return _s_data; }
inline const std::string& getMsgInFlight() const { return _msg_in_flight; } inline const std::string& getMsgInFlight() const { return _msg_in_flight; }
@@ -37,8 +35,12 @@ namespace irc
inline void setNewNickName(const std::string& name) { _nickname = name; } inline void setNewNickName(const std::string& name) { _nickname = name; }
inline void setNewUserName(const std::string& name) { _username = name; } inline void setNewUserName(const std::string& name) { _username = name; }
inline void setNewRealName(const std::string& name) { _realname = name; } inline void setNewRealName(const std::string& name) { _realname = name; }
inline void setLogged(void) { _logged = true; }
inline void setDisconnect(void) { _to_disconnect = true; } inline void login() { _logged = true; }
inline void requireDisconnect() { _disconnect_required = true; }
inline bool isLogged() const { return _logged; }
inline bool disconnectRequired() const { return _disconnect_required; }
inline const std::string& getNickName() const { return _nickname; } inline const std::string& getNickName() const { return _nickname; }
inline const std::string& getUserName() const { return _username; } inline const std::string& getUserName() const { return _username; }
@@ -48,6 +50,7 @@ namespace irc
inline void setFd(int new_fd) { _fd = new_fd; } inline void setFd(int new_fd) { _fd = new_fd; }
void sendPlainText(const std::string& str);
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); void sendMsg(const std::string& sender, const std::string& cmd, const std::string& trailing);
@@ -62,7 +65,7 @@ namespace irc
int _fd; int _fd;
int _id; int _id;
bool _logged; bool _logged;
bool _to_disconnect; bool _disconnect_required;
}; };
} }

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/23 23:29:00 by vvaas ### ########.fr */ /* Updated: 2024/01/24 15:14:05 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -57,7 +57,6 @@ namespace irc
void handlePrivMsg(unstd::SharedPtr<class Client> client, const class Message& msg); void handlePrivMsg(unstd::SharedPtr<class Client> client, const class Message& msg);
void handleNotice(unstd::SharedPtr<class Client> client, const class Message& msg); void handleNotice(unstd::SharedPtr<class Client> client, const class Message& msg);
void handleKick(unstd::SharedPtr<class Client> client, const class Message& msg); void handleKick(unstd::SharedPtr<class Client> client, const class Message& msg);
void handleMotD(unstd::SharedPtr<class Client> client, const class Message& msg);
void handleTopic(unstd::SharedPtr<class Client> client, const class Message& msg); void handleTopic(unstd::SharedPtr<class Client> client, const class Message& msg);
void handlePing(unstd::SharedPtr<class Client> client, const class Message& msg); void handlePing(unstd::SharedPtr<class Client> client, const class Message& msg);
void handleMode(unstd::SharedPtr<class Client> client, const class Message& msg); void handleMode(unstd::SharedPtr<class Client> client, const class Message& msg);

View File

@@ -6,7 +6,7 @@
/* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */ /* By: vvaas <vvaas@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/21 10:36:21 by maldavid #+# #+# */ /* Created: 2024/01/21 10:36:21 by maldavid #+# #+# */
/* Updated: 2024/01/24 12:52:25 by maldavid ### ########.fr */ /* Updated: 2024/01/24 15:34:53 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -16,28 +16,20 @@
namespace irc namespace irc
{ {
typedef std::set<unstd::SharedPtr<Client> >::iterator client_it;
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->sendCode(ERR_USERONCHANNEL, "You are already in the 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);
}
void Channel::addClient(unstd::SharedPtr<Client> client, bool op) void Channel::addClient(unstd::SharedPtr<Client> client, bool op)
{ {
if (!_clients.insert(client).second) if(!_clients.insert(client).second)
{ {
client->sendCode(ERR_USERONCHANNEL, "You are already in the channel"); client->sendCode(ERR_USERONCHANNEL, "You are already in the channel");
return ; return;
} }
if (op) if(op)
_operators.insert(client); _operators.insert(client);
for(std::set<unstd::SharedPtr<Client> >::iterator it = _clients.begin(); it != _clients.end(); ++it) for(client_it it = _clients.begin(); it != _clients.end(); ++it)
const_cast<unstd::SharedPtr<irc::Client>&>(*it)->sendMsg(client->getNickName(), "JOIN", _name); const_cast<unstd::SharedPtr<irc::Client>&>(*it)->sendMsg(client->getNickName(), "JOIN", _name);
} }
@@ -46,14 +38,14 @@ namespace irc
return _clients.erase(client); return _clients.erase(client);
} }
void Channel::handleMessage(const std::string& msg, unstd::SharedPtr<Client> client) const void Channel::handleMessage(const std::string& msg, unstd::SharedPtr<Client> client, bool notice) const
{ {
const std::string sender = client ? client->getNickName() : ""; const std::string sender = client ? client->getNickName() : "";
for(std::set<unstd::SharedPtr<Client> >::iterator it = _clients.begin(); it != _clients.end(); ++it) for(client_it it = _clients.begin(); it != _clients.end(); ++it)
{ {
if(client == *it) if(client == *it)
continue; continue;
const_cast<unstd::SharedPtr<irc::Client>&>(*it)->sendMsg(sender, "PRIVMSG " + _name, msg); const_cast<unstd::SharedPtr<irc::Client>&>(*it)->sendMsg(sender, (notice ? "NOTICE " : "PRIVMSG ") + _name, msg);
} }
} }

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/24 00:07:56 by vvaas ### ########.fr */ /* Updated: 2024/01/24 15:01:44 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -23,15 +23,21 @@ namespace irc
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;
logs::report(log_message, "C<-%s", command.c_str()); //logs::report(log_message, "C<-%s", command.c_str());
if(send(_fd, command.c_str(), command.size(), 0) != static_cast<ssize_t>(command.length())) 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()); logs::report(log_error, "server failed to send a code to '%s' (:sadge:)", _username.c_str());
} }
void Client::sendPlainText(const std::string& str)
{
if(send(_fd, str.c_str(), str.length(), 0) != static_cast<ssize_t>(str.length()))
logs::report(log_error, "server failed to send a message to '%s' (:sadge:)", _username.c_str());
}
void Client::sendMsg(const std::string& sender, const std::string& cmd, const std::string& trailing) void Client::sendMsg(const std::string& sender, const std::string& cmd, const std::string& trailing)
{ {
const std::string out = ':' + sender + ' ' + cmd + " :" + trailing + "\r\n"; const std::string out = ':' + sender + ' ' + cmd + " :" + trailing + "\r\n";
logs::report(log_message,"<- S %s", out.c_str()); //logs::report(log_message,"<- S %s", out.c_str());
if(send(_fd, out.c_str(), out.length(), 0) != static_cast<ssize_t>(out.length())) 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()); logs::report(log_error, "server failed to send a message from '%s' to '%s' (:sadge:)", sender.c_str(), _username.c_str());
} }

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/24 00:16:34 by vvaas ### ########.fr */ /* Updated: 2024/01/24 15:14:19 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -75,7 +75,7 @@ namespace irc
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
} }
if(recv((*it)->getFD(), buffer, INPUT_SIZE, 0) == 0 || (*it)->getDisconnect()) // recv return 0 if an user disconnect if(recv((*it)->getFD(), buffer, INPUT_SIZE, 0) == 0 || (*it)->disconnectRequired()) // recv return 0 if an user disconnect
{ {
logs::report(log_message, "User %d disconnected", (*it)->getID()); logs::report(log_message, "User %d disconnected", (*it)->getID());
close((*it)->getFD()); close((*it)->getFD());
@@ -133,7 +133,7 @@ namespace irc
handleUser(client, msg); handleUser(client, msg);
else if (msg.getCmd() == "PASS") else if (msg.getCmd() == "PASS")
handlePass(client, msg); handlePass(client, msg);
else if (!client->getLogged()) else if(!client->isLogged())
return true; return true;
else if(msg.getCmd() == "QUIT") else if(msg.getCmd() == "QUIT")
handleQuit(client, msg); handleQuit(client, msg);
@@ -147,8 +147,6 @@ namespace irc
handleNotice(client, msg); handleNotice(client, msg);
else if(msg.getCmd() == "KICK") else if(msg.getCmd() == "KICK")
handleKick(client, msg); handleKick(client, msg);
else if(msg.getCmd() == "MOTD")
handleMotD(client, msg);
else if(msg.getCmd() == "TOPIC") else if(msg.getCmd() == "TOPIC")
handleTopic(client, msg); handleTopic(client, msg);
else if(msg.getCmd() == "PING") else if(msg.getCmd() == "PING")

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/24 12:52:32 by maldavid ### ########.fr */ /* Updated: 2024/01/24 15:35:06 by maldavid ### ########.fr */
/* */ /* */
/******************************************************************************/ /******************************************************************************/
@@ -24,6 +24,12 @@
namespace irc namespace irc
{ {
typedef std::vector<unstd::SharedPtr<Client> >::iterator client_it;
typedef std::vector<unstd::SharedPtr<Client> >::const_iterator client_const_it;
typedef std::vector<Channel>::iterator channel_it;
typedef std::vector<Channel>::const_iterator channel_const_it;
void Server::handleNick(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleNick(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
if(msg.getTokens().size() != 2 && msg.getTokens().size() != 3) if(msg.getTokens().size() != 2 && msg.getTokens().size() != 3)
@@ -32,7 +38,7 @@ namespace irc
return; return;
} }
const std::string& nickname = msg.getTokens()[1]; const std::string& nickname = msg.getTokens()[1];
for(std::vector<unstd::SharedPtr<Client> >::iterator it = _client.begin(); it != _client.end(); ++it) for(client_it it = _client.begin(); it != _client.end(); ++it)
{ {
if((*it)->getNickName() == nickname) if((*it)->getNickName() == nickname)
{ {
@@ -62,26 +68,27 @@ namespace irc
client->setNewRealName(msg.getTokens()[4]); client->setNewRealName(msg.getTokens()[4]);
std::cout << "new realname, " << client->getRealName() << std::endl; std::cout << "new realname, " << client->getRealName() << std::endl;
} }
void Server::handlePass(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handlePass(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
if(client->isLogged())
if (client->getLogged()) return;
return ; if(msg.getTokens()[1] == _password)
if (msg.getTokens()[1] == _password)
{ {
client->setLogged(); client->login();
client->sendCode(RPL_WELCOME, "Welcome :)\n"); client->sendCode(RPL_WELCOME, "Welcome :)\n");
} }
else else
{ {
client->sendCode(ERR_PASSWDMISMATCH); client->sendCode(ERR_PASSWDMISMATCH);
client->setDisconnect(); client->requireDisconnect();
} }
} }
void Server::handleQuit(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleQuit(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
(void)msg; (void)msg;
for(std::vector<Channel>::iterator it = _channels.begin(); it != _channels.end(); ++it) for(channel_it it = _channels.begin(); it != _channels.end(); ++it)
it->removeClient(client); it->removeClient(client);
client->printUserHeader(); client->printUserHeader();
std::cout << "quit" << std::endl; std::cout << "quit" << std::endl;
@@ -109,7 +116,7 @@ namespace irc
} }
} }
std::vector<Channel>::iterator chit; channel_it chit;
for(chit = _channels.begin(); chit != _channels.end(); ++chit) for(chit = _channels.begin(); chit != _channels.end(); ++chit)
{ {
if(msg.getTokens()[1] == chit->getName()) if(msg.getTokens()[1] == chit->getName())
@@ -144,7 +151,7 @@ namespace irc
return; return;
} }
std::vector<Channel>::iterator it; channel_it it;
for(it = _channels.begin(); it != _channels.end(); ++it) for(it = _channels.begin(); it != _channels.end(); ++it)
{ {
if(msg.getTokens()[1] == it->getName()) if(msg.getTokens()[1] == it->getName())
@@ -169,16 +176,20 @@ namespace irc
logs::report(log_error, "PRIVMSG, invalid command '%s'", msg.getRawMsg().c_str()); logs::report(log_error, "PRIVMSG, invalid command '%s'", msg.getRawMsg().c_str());
return; return;
} }
std::vector<Channel>::iterator it; channel_it it;
for(it = _channels.begin(); it != _channels.end(); ++it) for(it = _channels.begin(); it != _channels.end(); ++it)
{ {
if(msg.getTokens()[1] == it->getName()) if(msg.getTokens()[1] == it->getName())
{ {
std::string complete_msg; std::string complete_msg;
for(std::vector<std::string>::const_iterator tit = msg.getTokens().begin(); tit != msg.getTokens().end(); ++it) if(msg.getTokens().size() > 2)
{ {
complete_msg.append(*tit); for(std::vector<std::string>::const_iterator tit = msg.getTokens().begin() + 2; tit < msg.getTokens().end(); ++tit)
complete_msg.append(" "); {
complete_msg.append(*tit);
complete_msg.append(" ");
}
complete_msg.erase(complete_msg.begin());
} }
it->handleMessage(complete_msg, client); it->handleMessage(complete_msg, client);
break; break;
@@ -188,8 +199,30 @@ namespace irc
void Server::handleNotice(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleNotice(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
(void)client; if(msg.getTokens().size() < 2)
(void)msg; {
logs::report(log_error, "NOTICE, invalid command '%s'", msg.getRawMsg().c_str());
return;
}
channel_it it;
for(it = _channels.begin(); it != _channels.end(); ++it)
{
if(msg.getTokens()[1] == it->getName())
{
std::string complete_msg;
if(msg.getTokens().size() > 2)
{
for(std::vector<std::string>::const_iterator tit = msg.getTokens().begin() + 2; tit < msg.getTokens().end(); ++tit)
{
complete_msg.append(*tit);
complete_msg.append(" ");
}
complete_msg.erase(complete_msg.begin());
}
it->handleMessage(complete_msg, client, true);
break;
}
}
} }
void Server::handleKick(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleKick(unstd::SharedPtr<class Client> client, const Message& msg)
@@ -198,12 +231,6 @@ namespace irc
(void)msg; (void)msg;
} }
void Server::handleMotD(unstd::SharedPtr<class Client> client, const Message& msg)
{
(void)client;
(void)msg;
}
void Server::handleTopic(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleTopic(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
(void)client; (void)client;
@@ -221,8 +248,18 @@ namespace irc
void Server::handlePing(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handlePing(unstd::SharedPtr<class Client> client, const Message& msg)
{ {
(void)client; if(msg.getTokens().size() == 1)
(void)msg; {
logs::report(log_error, "PING, invalid command '%s'", msg.getRawMsg().c_str());
return;
}
std::string out = "PONG";
for(std::vector<std::string>::const_iterator it = msg.getTokens().begin() + 1; it < msg.getTokens().end(); ++it)
out += ' ' + *it;
out += "\r\n";
client->sendPlainText(out);
client->printUserHeader();
std::cout << "pong" << std::endl;
} }
void Server::handleMode(unstd::SharedPtr<class Client> client, const Message& msg) void Server::handleMode(unstd::SharedPtr<class Client> client, const Message& msg)