Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
NAME := ircserv
BOT_NAME := ircbot
CXX := c++
CXXFLAGS:= -Wall -Wextra -Werror -std=c++20 -Iinc
CXXFLAGS:= -Wall -Wextra -Werror -std=c++20 -Iinc

SRC := \
Client.cpp \
main.cpp \
Server.cpp \
Channel.cpp \
User.cpp \
RecvParser.cpp \
Client.cpp \
Command.cpp \
CommandDispatcher.cpp \
Handler.cpp
Expand Down
18 changes: 12 additions & 6 deletions inc/Client.hpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#pragma once
#include <queue>
#include <functional>
#include <cstdint>
#include <stdexcept>
#include <sys/epoll.h>
#include <fcntl.h>
#include <memory>
#include "CommandDispatcher.hpp"
#include "User.hpp"
#include "RecvParser.hpp"

class User;

class CommandDispatcher;
/*
* @class Client
Expand All @@ -24,24 +27,27 @@ class Client {
std::function<void(int)> _IN = nullptr;
std::function<void(int)> _RDHUP = nullptr;
std::function<void(int)> _HUP = nullptr;
User* _self;
User _self;
bool _authenticated = false;
bool _registered = false;
CommandDispatcher* _test;
CommandDispatcher* _dispatch;
std::queue<std::unique_ptr<Message>> _msg_queue;
RecvParser _parser;

public:
explicit Client(int fd);
~Client();
Client(const Client&);
Client& operator=(const Client&);
const int _fd;
bool _initialized = false;
bool handler(uint32_t eventType) const;
void setHandler(uint32_t eventType, std::function<void(int)> handler);
std::function<void(int)>& getHandler(uint32_t eventType);
User* getUser(void);
User& getUser(void);
CommandDispatcher* getDispatch(void);
RecvParser& getParser(void);
void authenticate(void);
bool isAuthenticated(void) const;
bool& accessRegistered(void);
};

#include "CommandDispatcher.hpp"
3 changes: 2 additions & 1 deletion inc/RecvParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <memory>
#include "Message.hpp"

/**
/**
* @class RecvParser
* @brief A class for parsing data read by recv() into a message queue
*/
Expand All @@ -16,6 +16,7 @@ class RecvParser
public:
RecvParser(std::queue<std::unique_ptr<Message>> &msg_queue);

std::queue<std::unique_ptr<Message>> &getQueue(void);
void feed(const char *read_buf, size_t len);

private:
Expand Down
10 changes: 6 additions & 4 deletions inc/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vector>
#include <string>
#include <future>
#include <memory>
#include <cstdint>
#include <fcntl.h>
#include <unistd.h>
Expand All @@ -21,10 +22,12 @@

constexpr static const std::array<uint32_t, 3> eventTypes{EPOLLIN, EPOLLHUP, EPOLLRDHUP};

class Client;

class Server {
private:
std::map<std::string, class Channel> _channels;
std::unordered_map<int, class Client> _clients;
std::unordered_map<int, std::shared_ptr<Client>> _clients;
std::vector<epoll_event> _events;
std::time_t _startTime;
const int _fd;
Expand All @@ -34,7 +37,6 @@ class Server {
const int _max_events = 100;
std::string _password;
void _reloadHandler(Client &client) const;
void _addOwnSocket(int sockfd);
public:
Server(std::string port = "6667", std::string passwd = "");
virtual ~Server();
Expand Down Expand Up @@ -63,8 +65,8 @@ class Server {
*/
bool checkPassword(std::string password = "") const;
void poll(int tout = -1);
const std::unordered_map<int, class Client>& getClients() const;
Client& getClient(int fd);
const std::unordered_map<int, std::shared_ptr<Client>>& getClients() const;
Client* getClient(int fd);
int getServerFd() const;

};
3 changes: 2 additions & 1 deletion inc/User.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

#include "Channel.hpp"
#include <string>
#include <vector>

Expand Down Expand Up @@ -28,3 +27,5 @@ class User {
Channel* getChannel(string needle);
void exitChannel(string needle);
};

#include "Channel.hpp"
25 changes: 19 additions & 6 deletions inc/macro.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
#pragma once

#define HOST ":localhost "
#define NICK irc->getClient(fd).getUser()->getNick()
#define USER(X) irc->getClient(X).getUser()
#define PREFIX irc->getClient(fd).getUser()->createPrefix()
#define MSG ":" + USER(user)->getNick() + " " + type + " " + _name + " :" + msg + "\r\n"
#define NICK irc->getClient(fd)->getUser().getNick()
#define USER(X) irc->getClient(X)->getUser()
#define PREFIX irc->getClient(fd)->getUser().createPrefix()
#define MSG ":" + USER(user).getNick() + " " + type \
+ " " + _name + " :" + msg + "\r\n"
#define PARAM msg.params[0]
#define PARAM1 msg.params[1]
#define PARAM2 msg.params[2]
#define PRIVMSG ":" + NICK + " PRIVMSG " + PARAM + " :" + PARAM1
#define PONG "PONG localhost :" + PARAM
#define INVITE PREFIX + " INVITE " + PARAM + " :" + PARAM1
#define KICK PREFIX + " KICK " + PARAM + " " + PARAM1
#define CAP ":localhost CAP * LS :"
#define CAP410 "410 CAP :Unsupported subcommand"
#define CAP461 "461 CAP :Not enough parameters"
#define R315 "315 " + nick + " :End of /WHO list"
#define R318 "318 " + NICK + " :End of WHOIS list"
#define R324 ":localhost 324 " + NICK + " " + PARAM + " " + ch->modes()
#define R329 ":localhost 329 " + NICK + " " + PARAM + " " + ch->getTime()
#define R331 "331 " + NICK + " " + PARAM + " :No topic is set"
#define R332 "332 " + NICK + " " + PARAM + " :" + topic
#define R341 "341 :Invitation send"
#define R341 "341 " + NICK + " " + PARAM + " " + PARAM1 + " :Invitation send "
#define R352 "352 " + PARAM + " " + user.getUser() + " "\
+ user.getHost() + " localhost " + user.getNick() + " H"
#define R353 "353 " + NICK + " @ " + PARAM + " :" + names
#define R366 "366 " + NICK + " " + PARAM + " :End of NAMES list"
#define E401 "401 :No such nick"
Expand All @@ -26,11 +38,12 @@
#define E431 "431 :No nickname given"
#define E432 "432 " + oldNick + " " + newNick + " :Erroneous nickname"
#define E433 "433 * " + newNick + " :Nickname is already in use"
#define E441 "441 :They aren't on that channel"
#define E441 "441 " + NICK + " " + PARAM + " :They aren't on that channel"
#define E442 "442 :You're not on that channel"
#define E443 "443 :User already on channel"
#define E461 "461 :Missing parameters"
#define E462 "462 " + NICK + " : You may not reregister"
#define E464 "464 " + NICK + " :Incorrect password"
#define E471 "471 " + nick + " " + _name + " :Cannot join channel (+l)"
#define E472 "472 :Unknown mode"
#define E473 "473 " + nick + " " + _name + " :Cannot join channel (+i)"
Expand Down
24 changes: 12 additions & 12 deletions src/Channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ bool Channel::setTopic(int user, string topic) {
return false;
}
_topic = topic;
string response = ":" + USER(user)->getNick() + " TOPIC " + _name + " :" + topic;
string response = ":" + USER(user).getNick() + " TOPIC " + _name + " :" + topic;
message(-1, response);
return true;
}
Expand All @@ -82,7 +82,7 @@ bool Channel::checkUser(int user) {

const string Channel::addUser(int user, string passwd) {
string ret;
const string nick = USER(user)->getNick();
const string nick = USER(user).getNick();
if (not checkUser(user))
ret = E443;
else if (_mode.contains('l') && _users.size() + _oper.size() >= _limit)
Expand All @@ -101,21 +101,21 @@ const string Channel::addUser(int user, string passwd) {
ret = E475;
else if (isEmpty()) {
_oper.emplace(user);
USER(user)->join(this);
USER(user).join(this);
} else {
_users.emplace(user);
USER(user)->join(this);
USER(user).join(this);
}
return ret;
}

void Channel::removeUser(int fd, string msg, string cmd) {
if (_users.contains(fd)) {
USER(fd)->exitChannel(_name);
USER(fd).exitChannel(_name);
_users.erase(fd);
message(fd, msg, cmd);
} else if (_oper.contains(fd)) {
USER(fd)->exitChannel(_name);
USER(fd).exitChannel(_name);
_oper.erase(fd);
if (_oper.empty()) {
if (_users.empty()) {
Expand All @@ -141,7 +141,7 @@ bool Channel::joinWithPassword(int fd, string passwd) {
_oper.emplace(fd);
else
_users.emplace(fd);
USER(fd)->join(this);
USER(fd).join(this);
return true;
} else {
return false;
Expand All @@ -158,7 +158,7 @@ bool Channel::joinWithInvite(int fd, string passwd) {
_invite.erase(fd);
_users.emplace(fd);
}
USER(fd)->join(this);
USER(fd).join(this);
return true;
} else {
if (joinWithPassword(fd, passwd))
Expand All @@ -175,12 +175,12 @@ string Channel::userList(void) const {
string ret;

for (auto users : _users) {
ret += USER(users)->getNick();
ret += USER(users).getNick();
ret += " ";
}
for (auto users : _oper) {
ret += '@';
ret += USER(users)->getNick();
ret += USER(users).getNick();
ret += " ";
}
ret.erase(ret.end() - 1);
Expand All @@ -202,7 +202,7 @@ bool Channel::makeOperator(int fd, string uname) {
int newOp = 0;

for (auto user : _users) {
if (USER(user)->getNick() == uname) {
if (USER(user).getNick() == uname) {
newOp = user;
break ;
}
Expand All @@ -221,7 +221,7 @@ void Channel::invite(int fd) {
bool Channel::kick(int op, int user) {
if (_users.contains(user) && _oper.contains(op)) {
_users.erase(user);
USER(user)->exitChannel(_name);
USER(user).exitChannel(_name);
return true;
} else {
return false;
Expand Down
33 changes: 9 additions & 24 deletions src/Client.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
#include "Client.hpp"


Client::Client(int fd) : _self(new User()), _test(new CommandDispatcher()), _fd(fd) {}

Client::Client(const Client& other) :
_IN(other._IN),
_RDHUP(other._RDHUP),
_HUP(other._HUP),
_self(new User(*other._self)),
_test(other._test),
_fd(other._fd),
_initialized(other._initialized){}

Client& Client::operator=(const Client& other) {
if (this != &other) {
delete _self;
_self = new User(*other._self);
_test = other._test;
}
return *this;
}
Client::Client(int fd) : _self(User()), _dispatch(new CommandDispatcher()), _parser(RecvParser(_msg_queue)), _fd(fd) {}

Client::~Client() {
delete _self;
delete _dispatch;
}

User* Client::getUser(void) {
User& Client::getUser(void) {
return _self;
}

CommandDispatcher* Client::getDispatch(void) {
return _test;
return _dispatch;
}

RecvParser& Client::getParser(void) {
return _parser;
}

void Client::setHandler(uint32_t eventType, std::function<void(int)> handler) {
Expand Down Expand Up @@ -71,7 +56,7 @@ std::function<void(int)>& Client::getHandler(uint32_t eventType) {
case EPOLLHUP:
return _HUP;
default:
throw std::runtime_error("Client::getHandler: Error; invalid eventType");
throw std::runtime_error("Client::getHandler: Error: invalid eventType");
}
}

Expand Down
Loading