Skip to content

Commit

Permalink
Merge pull request #43 from ArthanIRC/channel-rework
Browse files Browse the repository at this point in the history
refactor: switch Channel lists from map to vector
  • Loading branch information
Thibrac authored Sep 5, 2024
2 parents 993d5aa + 6cc7705 commit 70f922b
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 397 deletions.
68 changes: 19 additions & 49 deletions include/Channel.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#pragma once

#include <ctime>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>

#include "Client.hpp"
#include "Exception.hpp"
Expand All @@ -21,47 +20,18 @@ class Channel {
size_t _maxClients;
time_t _creationTime;
time_t _topicSetTime;
std::map<std::string, Client*> _clients;
std::map<std::string, Client*> _inviteList;
std::map<std::string, Client*> _banList;
std::map<std::string, Client*> _operatorsList;
std::map<std::string, Client*> _voicedList;
std::vector<Client*> _clients;
std::vector<Client*> _inviteList;
std::vector<Client*> _banList;
std::vector<Client*> _operatorsList;
std::vector<Client*> _voicedList;
void checkNameSyntax(std::string& name);

template <typename MapType>
void addClientToMap(MapType& map, Client* client) {
std::string nickname = client->getNickname();
if (map.find(nickname) != map.end()) {
return;
}
map[nickname] = client;
}

template <typename MapType>
void removeClientFromMap(MapType& map, Client* client,
const std::string& errorMsg) {
std::string nickname = client->getNickname();
typename MapType::iterator it = map.find(nickname);
if (it != map.end()) {
map.erase(it);
} else {
throw std::runtime_error(errorMsg);
}
}

template <typename MapType>
bool verifClientOnMap(const MapType& map, const Client* client) const {
std::string nickname = client->getNickname();
typename MapType::const_iterator it = map.find(nickname);
return it != map.end();
}

template <typename MapType>
bool verifClientOnMap(const MapType& map,
const std::string nickname) const {
typename MapType::const_iterator it = map.find(nickname);
return it != map.end();
}
void addClientToList(std::vector<Client*>& vec, Client* client);
void removeClientFromList(std::vector<Client*>& vec, Client* client);
bool isOnList(const std::vector<Client*>& vec, const Client* client) const;
bool isOnList(const std::vector<Client*>& vec,
const std::string nickname) const;

public:
Channel(Client* client, std::string name);
Expand All @@ -80,11 +50,11 @@ class Channel {
bool isProtectedTopic() const;
void setProtectedTopic(bool lock);

std::map<std::string, Client*>& getClients();
std::map<std::string, Client*>& getInvitelist();
std::map<std::string, Client*>& getBanList();
std::map<std::string, Client*>& getOperatorsList();
std::map<std::string, Client*>& getVoicedList();
std::vector<Client*>& getClients();
std::vector<Client*>& getInvitelist();
std::vector<Client*>& getBanList();
std::vector<Client*>& getOperatorsList();
std::vector<Client*>& getVoicedList();

bool isInviteOnly() const;
void setInviteOnly(bool inviteMode);
Expand All @@ -101,13 +71,13 @@ class Channel {
void addClient(Client* client);
void addOperator(Client* client);
void addVoiced(Client* client);
void eraseVoiced(Client* client);
void removeVoiced(Client* client);
void banClient(Client* client);
void inviteClient(Client* client);

void eraseOperator(Client* client);
void removeOperator(Client* client);
void unbanClient(Client* client);
void eraseClient(Client* client);
void removeClient(Client* client);

bool isInChannel(Client* client) const;
bool isInvited(Client* client) const;
Expand Down
1 change: 0 additions & 1 deletion include/Commands/TopicCommand.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include "Command.hpp"
#include <map>

class TopicCommand : public Command {
private:
Expand Down
101 changes: 63 additions & 38 deletions src/Channel.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
#include <algorithm>

#include "Channel.hpp"

using std::map;
using std::string;
using std::vector;

Channel::Channel(Client* newClient, string name)
: _name(name), _key(""), _protectedTopic(false), _inviteOnly(false),
_noExternal(true), _maxClients(0) {
checkNameSyntax(name);
this->_clients[newClient->getNickname()] = newClient;
this->_operatorsList[newClient->getNickname()] = newClient;
this->_clients.push_back(newClient);
this->_operatorsList.push_back(newClient);
this->_creationTime = time(NULL);
}

Channel::Channel(Client* newClient, string name, string key)
: _name(name), _key(key), _protectedTopic(false), _inviteOnly(false),
_noExternal(true), _maxClients(0) {
checkNameSyntax(name);
this->_clients[newClient->getNickname()] = newClient;
this->_operatorsList[newClient->getNickname()] = newClient;
this->_clients.push_back(newClient);
this->_operatorsList.push_back(newClient);
this->_creationTime = time(NULL);
}

Expand All @@ -34,6 +36,34 @@ void Channel::checkNameSyntax(string& name) {
throw WrongSyntaxChannelName();
}

void Channel::addClientToList(vector<Client*>& vec, Client* client) {
if (std::find(vec.begin(), vec.end(), client) != vec.end())
return;
vec.push_back(client);
}

void Channel::removeClientFromList(vector<Client*>& vec, Client* client) {
vector<Client*>::iterator it = std::find(vec.begin(), vec.end(), client);
if (it != vec.end())
vec.erase(it);
}

bool Channel::isOnList(const vector<Client*>& vec, const Client* client) const {
vector<Client*>::const_iterator it =
std::find(vec.begin(), vec.end(), client);
return it != vec.end();
}

bool Channel::isOnList(const vector<Client*>& vec,
const string nickname) const {
for (vector<Client*>::const_iterator it = vec.begin(); it != vec.end();
it++) {
if ((*it)->getNickname() == nickname)
return true;
}
return false;
}

string const& Channel::getName() const { return this->_name; }

string Channel::getKey() const { return this->_key; }
Expand All @@ -56,17 +86,15 @@ bool Channel::isProtectedTopic() const { return this->_protectedTopic; }

void Channel::setProtectedTopic(bool lock) { this->_protectedTopic = lock; }

map<string, Client*>& Channel::getClients() { return this->_clients; }
vector<Client*>& Channel::getClients() { return this->_clients; }

map<string, Client*>& Channel::getInvitelist() { return this->_inviteList; }
vector<Client*>& Channel::getInvitelist() { return this->_inviteList; }

map<string, Client*>& Channel::getBanList() { return this->_banList; }
vector<Client*>& Channel::getBanList() { return this->_banList; }

map<string, Client*>& Channel::getOperatorsList() {
return this->_operatorsList;
}
vector<Client*>& Channel::getOperatorsList() { return this->_operatorsList; }

map<string, Client*>& Channel::getVoicedList() { return this->_voicedList; }
vector<Client*>& Channel::getVoicedList() { return this->_voicedList; }

bool Channel::isInviteOnly() const { return this->_inviteOnly; }

Expand All @@ -89,76 +117,73 @@ void Channel::setMaxClients(size_t nbMaxClients) {
void Channel::addClient(Client* client) {
if (this->_inviteOnly == true && !isInvited(client))
throw UserNotInvited();
string nickname = client->getNickname();
if (_clients.find(nickname) != _clients.end()) {
throw UserAlreadyExists();
}
_clients[nickname] = client;
addClientToList(_clients, client);
}

void Channel::addOperator(Client* client) {
addClientToMap(_operatorsList, client);
addClientToList(_operatorsList, client);
}

void Channel::addVoiced(Client* client) { addClientToMap(_voicedList, client); }
void Channel::addVoiced(Client* client) {
addClientToList(_operatorsList, client);
}

void Channel::eraseVoiced(Client* client) {
removeClientFromMap(_voicedList, client, "");
void Channel::removeVoiced(Client* client) {
removeClientFromList(_voicedList, client);
}

void Channel::banClient(Client* client) { addClientToMap(_banList, client); }
void Channel::banClient(Client* client) { addClientToList(_banList, client); }

void Channel::inviteClient(Client* client) {
addClientToMap(_inviteList, client);
addClientToList(_inviteList, client);
}

void Channel::eraseOperator(Client* client) {
removeClientFromMap(_operatorsList, client, "the user was not an operator");
void Channel::removeOperator(Client* client) {
removeClientFromList(_operatorsList, client);
}

void Channel::eraseClient(Client* client) {
removeClientFromMap(_clients, client, "the user does not exist");
void Channel::removeClient(Client* client) {
removeClientFromList(_clients, client);
}

void Channel::unbanClient(Client* client) {
removeClientFromMap(_banList, client, "the user was not blacklisted");
removeClientFromList(_banList, client);
}

bool Channel::isInChannel(Client* client) const {
return verifClientOnMap(_clients, client);
return isOnList(_clients, client);
}

bool Channel::isInvited(Client* client) const {
return verifClientOnMap(_inviteList, client);
return isOnList(_inviteList, client);
}

bool Channel::isBanned(Client* client) const {
return verifClientOnMap(_banList, client);
return isOnList(_banList, client);
}

bool Channel::isOperator(Client* client) const {
return verifClientOnMap(_operatorsList, client) ||
client->isServerOperator();
return isOnList(_operatorsList, client) || client->isServerOperator();
}

bool Channel::isVoiced(Client* client) const {
return isOperator(client) || verifClientOnMap(_voicedList, client);
return isOperator(client) || isOnList(_voicedList, client);
}

bool Channel::isInChannel(string nickname) const {
return verifClientOnMap(_clients, nickname);
return isOnList(_clients, nickname);
}

bool Channel::isInvited(string nickname) const {
return verifClientOnMap(_inviteList, nickname);
return isOnList(_inviteList, nickname);
}

bool Channel::isBanned(string nickname) const {
return verifClientOnMap(_banList, nickname);
return isOnList(_banList, nickname);
}

bool Channel::isOperator(string nickname) const {
return verifClientOnMap(_operatorsList, nickname);
return isOnList(_operatorsList, nickname);
}

string Channel::getModes() const {
Expand Down
4 changes: 2 additions & 2 deletions src/Commands/KickCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ void KickCommand::run() {
_client->sendMessage(Replies::ERR_NOSUCHNICK(_client, _targetNickname));
return;
}
_channel->eraseClient(target);
_channel->removeClient(target);
if (_channel->isOperator(target))
_channel->eraseOperator(target);
_channel->removeOperator(target);
target->sendMessage(reply);
Server::getInstance().sendMessage(_channel, reply, NULL);
}
12 changes: 5 additions & 7 deletions src/Commands/ModeCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "Replies.hpp"
#include "Server.hpp"

using std::map;
using std::string;
using std::vector;

Expand Down Expand Up @@ -76,11 +75,10 @@ void ModeCommand::invisibleMode(bool oper, size_t& p) {
void ModeCommand::banMode(bool oper, size_t& p) {
string param = retrieveParam(_params, p);
if (param.empty()) {
map<string, Client*> banlist = _channel->getBanList();
for (map<string, Client*>::iterator it = banlist.begin();
vector<Client*> banlist = _channel->getBanList();
for (vector<Client*>::iterator it = banlist.begin();
it != banlist.end(); it++)
_client->sendMessage(
Replies::RPL_BANLIST(_client, it->second, _channel));
_client->sendMessage(Replies::RPL_BANLIST(_client, *it, _channel));
_client->sendMessage(Replies::RPL_ENDOFBANLIST(_client, _channel));
return;
}
Expand Down Expand Up @@ -178,7 +176,7 @@ void ModeCommand::operatorMode(bool oper, size_t& p) {
if (oper)
_channel->addOperator(target);
else
_channel->eraseOperator(target);
_channel->removeOperator(target);
addResult(oper, "o", param);
}

Expand All @@ -201,7 +199,7 @@ void ModeCommand::voiceMode(bool oper, size_t& p) {
if (oper)
_channel->addVoiced(target);
else
_channel->eraseVoiced(target);
_channel->removeVoiced(target);
addResult(oper, "v", param);
}

Expand Down
7 changes: 4 additions & 3 deletions src/Commands/PartCommand.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <string>

#include "PartCommand.hpp"
#include "Replies.hpp"
#include <string>

PartCommand::PartCommand(std::string source, std::vector<std::string> params,
Client* client) {
Expand Down Expand Up @@ -49,8 +50,8 @@ void PartCommand::run() {
for (size_t i = 0; i < _channels.size(); ++i) {
if (_channels[i]->isInChannel(_client)) {
if (_channels[i]->isOperator(_client))
_channels[i]->eraseOperator(_client);
_channels[i]->eraseClient(_client);
_channels[i]->removeOperator(_client);
_channels[i]->removeClient(_client);
std::string reply = createReply(_channels[i]);
Server::getInstance().sendMessage(_channels[i], reply, _client);
_client->sendMessage(reply);
Expand Down
Loading

0 comments on commit 70f922b

Please sign in to comment.