Skip to content

Commit

Permalink
Merge pull request #49 from ArthanIRC/who-command-part2
Browse files Browse the repository at this point in the history
feat: finish WHO command
  • Loading branch information
Thibrac authored Sep 6, 2024
2 parents 7c0f3b0 + 2b90f14 commit 95e2727
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 33 deletions.
3 changes: 2 additions & 1 deletion include/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ class Client {
Client(int fd);
~Client();

std::string const& getName() const;
std::string const& getNickname() const;
std::string const& getUserName() const;
std::string const& getRealName() const;
std::string const getSource() const;
std::string getModes();
std::string const& getAwayMsg() const;
Expand Down
5 changes: 3 additions & 2 deletions include/Replies.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Replies : public Message {
static std::string RPL_WHOISSERVER();
static std::string RPL_WHOISOPERATOR();
static std::string RPL_WHOWASUSER();
static std::string RPL_ENDOFWHO();
static std::string RPL_ENDOFWHO(Client* client, std::string& mask);
static std::string RPL_WHOISIDLE();
static std::string RPL_ENDOFWHOIS();
static std::string RPL_WHOISCHANNELS();
Expand All @@ -74,7 +74,8 @@ class Replies : public Message {
static std::string RPL_EXCEPTLIST();
static std::string RPL_ENDOFEXCEPTLIST();
static std::string RPL_VERSION();
static std::string RPL_WHOREPLY();
static std::string RPL_WHOREPLY(Client* client, Client* target,
Channel* channel);
static std::string RPL_NAMREPLY(Client* client, Channel* channel);
static std::string RPL_LINKS();
static std::string RPL_ENDOFLINKS();
Expand Down
4 changes: 4 additions & 0 deletions src/Channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ void Channel::removeOperator(Client* client) {
}

void Channel::removeClient(Client* client) {
removeClientFromList(_inviteList, client);
removeClientFromList(_operatorsList, client);
removeClientFromList(_banList, client);
removeClientFromList(_voicedList, client);
removeClientFromList(_clients, client);
}

Expand Down
16 changes: 13 additions & 3 deletions src/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,22 @@ Client::Client(int fd)
_capEndedEarly(false), _invisible(false), _away(false),
_awayNotify(false) {}

Client::~Client() {}

string const& Client::getName() const { return this->_realname; }
Client::~Client() {
map<string, Channel*> channels = getChannels();
if (channels.empty())
return;

for (map<string, Channel*>::iterator it = channels.begin();
it != channels.end(); it++)
it->second->removeClient(this);
}

string const& Client::getNickname() const { return this->_nickname; }

string const& Client::getUserName() const { return this->_username; }

string const& Client::getRealName() const { return this->_realname; }

string const Client::getSource() const {
string source = _nickname + "!" + _username + "@localhost";
return source;
Expand Down
40 changes: 19 additions & 21 deletions src/Commands/WhoCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
#include "Channel.hpp"
#include "Replies.hpp"
#include "Server.hpp"
#include <cstddef>
#include <map>
#include <vector>

using std::map;
using std::string;
Expand All @@ -15,6 +12,7 @@ WhoCommand::WhoCommand(string source, vector<string> params, Client* client) {
client->sendMessage(Replies::ERR_NOTREGISTERED());
throw ClientException();
}

this->_source = source;
this->_params = params;
this->_client = client;
Expand All @@ -25,8 +23,10 @@ WhoCommand::~WhoCommand() {}
void WhoCommand::run() {
if (_params.size() < 1)
return;

Channel* chan;
Client* target;

try {
chan = Server::getInstance().findChannel(_params[0]);
} catch (const Server::ChannelNotFoundException&) {
Expand All @@ -43,30 +43,28 @@ void WhoCommand::run() {
return;

if (target != NULL) {
map<string, Channel*> chansClient = _client->getChannels();
map<string, Channel*> chansTarget = target->getChannels();
map<string, Channel*>::iterator it = chansClient.begin();
map<string, Channel*>::iterator itt;
while (it != chansClient.end()) {
itt = chansTarget.begin();
while (itt != chansTarget.end()) {
if ((*it) == (*itt) || !target->isInvisible()) {
_client->sendMessage(Replies::RPL_WHOREPLY());
_client->sendMessage(Replies::RPL_ENDOFWHO());
return;
}
itt++;
map<string, Channel*> channels = _client->getChannels();
for (map<string, Channel*>::iterator it = channels.begin();
it != channels.end(); it++) {
if (it->second->isInChannel(target)) {
_client->sendMessage(
Replies::RPL_WHOREPLY(_client, target, it->second));
_client->sendMessage(
Replies::RPL_ENDOFWHO(_client, _params[0]));
return;
}
it++;
}
if (!target->isInvisible()) {
_client->sendMessage(Replies::RPL_WHOREPLY(_client, target, NULL));
_client->sendMessage(Replies::RPL_ENDOFWHO(_client, _params[0]));
}
} else {
vector<Client*> clients = chan->getClients();
for (vector<Client*>::iterator it = clients.begin();
it != clients.end(); it++) {
if (!chan->isInChannel(_client) && (*it)->isInvisible())
continue;
_client->sendMessage(Replies::RPL_WHOREPLY());
if (chan->isInChannel(_client))
_client->sendMessage(Replies::RPL_WHOREPLY(_client, *it, chan));
}
_client->sendMessage(Replies::RPL_ENDOFWHO());
_client->sendMessage(Replies::RPL_ENDOFWHO(_client, _params[0]));
}
}
35 changes: 29 additions & 6 deletions src/Replies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,9 @@ string Replies::RPL_WHOWASUSER() {
return Message::create(reply);
}

string Replies::RPL_ENDOFWHO() {
string Replies::RPL_ENDOFWHO(Client* client, string& mask) {
string reply;
reply = "315 " + client->getNickname() + " " + mask + " :End of WHO list";
return Message::create(reply);
}

Expand Down Expand Up @@ -372,24 +373,46 @@ string Replies::RPL_VERSION() {
return Message::create(reply);
}

string Replies::RPL_WHOREPLY() {
string Replies::RPL_WHOREPLY(Client* client, Client* target, Channel* channel) {
string reply;
string flags = " ";
string chanName = "*";

if (target->isAway())
flags += "G";
else
flags += "H";
if (target->isServerOperator())
flags += "*";
if (channel) {
flags += channel->getPrefix(target);
chanName = channel->getName();
}

reply = "352 " + client->getNickname() + " " + chanName + " " +
target->getUserName() + " localhost " +
Server::getInstance().getSource() + " " + target->getNickname() +
flags + " :0 " + target->getRealName();
return Message::create(reply);
}

string Replies::RPL_NAMREPLY(Client* client, Channel* channel) {
string reply;
reply = "353 " + client->getNickname() + " = " + channel->getName() + " :" +
channel->getPrefix(client) + client->getNickname();
reply = "353 " + client->getNickname() + " = " + channel->getName() + " :";
vector<Client*> clients = channel->getClients();

if (clients.empty())
return "";
vector<Client*>::const_iterator it = clients.begin();
string prefix;
string spacer;

while (++it != clients.end()) {
for (; it != clients.end(); it++) {
if ((*it)->isInvisible() && !channel->isInChannel(client))
continue;
prefix = channel->getPrefix(*it);
reply += " " + prefix + (*it)->getNickname();
reply += spacer + prefix + (*it)->getNickname();
spacer = " ";
}
return Message::create(reply);
}
Expand Down

0 comments on commit 95e2727

Please sign in to comment.