Skip to content

Commit

Permalink
Merge pull request #40 from jdomingu98/39-aplicar-patron-singleton-a-…
Browse files Browse the repository at this point in the history
…clase-server

feat: Applied singleton pattern to Server class
  • Loading branch information
jdomingu98 authored Mar 26, 2024
2 parents 99a06f1 + a392913 commit 8a65020
Show file tree
Hide file tree
Showing 25 changed files with 105 additions and 96 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ PARSER_PREFIXS = Command User Pass Nick Quit PrivateMessage Join
PARSER_FILES = $(addsuffix Parser, $(PARSER_PREFIXS))
PARSER_SRCS = $(addprefix $(PARSER_DIR), $(PARSER_FILES))

FILES = main Server User Channel utils Logger
FILES = main Server User Channel libsUtils Logger

SRCS_PATHS = $(addprefix $(SRC_DIR)/, $(FILES)) $(CMD_SRCS) $(PARSER_SRCS)
SRCS = $(addsuffix .cpp, $(SRCS_PATHS))
Expand Down
2 changes: 0 additions & 2 deletions includes/Channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

# include "User.hpp"

# include "ChannelException.hpp"

# include "libsUtils.hpp"

# define MAX_CHANNEL_NAME_LENGTH 20
Expand Down
14 changes: 11 additions & 3 deletions includes/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class Server {
std::vector<User> _users;
std::vector<Channel> _channels;

// Singleton Pattern
static Server *_server;
Server(const std::string port, const std::string password);

bool isValidPort(const std::string port);
void initServer();
void listenClients();
Expand All @@ -48,15 +52,19 @@ class Server {
std::vector<User>::iterator findUserByNickname(std::string nickname);

public:
Server(const std::string port, const std::string password);
~Server();
static void init(std::string port, std::string password);
static Server &getInstance();

std::vector<Channel>::iterator findChannel(std::string channelName);

void sendMessage(int clientFd, const std::string& message) const;
bool isValidPassword(const std::string& password);
//Getters
User &getUserByFd(int clientFd);
User &getUserByNickname(const std::string& nickname);

//Operations
void sendMessage(int clientFd, const std::string& message) const;
bool isValidPassword(const std::string& password);
bool isNicknameInUse(const std::string& nickname);
bool userHasCheckedPassword(int clientFd);
void removeUser(int clientFd);
Expand Down
4 changes: 2 additions & 2 deletions includes/User.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ class User {

// Operations
void checkPassword();
void makeRegistration(Server &server);
void makeRegistration();
bool canRegister();
void addChannel(Channel &channel);
void sendPrivateMessageToUser(const Server &server, const User &destination, const std::string& message);
void sendPrivateMessageToUser(const User &destination, const std::string& message);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/ICommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ICommand {
protected:
bool _needValidate;
public:
virtual void execute(Server &server, int clientFd) = 0;
virtual void execute(int clientFd) = 0;
ICommand(bool needValidate) : _needValidate(needValidate) {};
};

Expand Down
3 changes: 1 addition & 2 deletions includes/commands/JoinCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
# include "Server.hpp"

# include "libsUtils.hpp"
# include "utils.hpp"

/**
* An ICommand implementation that is responsible for the binding and creation of a channel.
Expand All @@ -22,7 +21,7 @@ class JoinCommand : public ICommand {
JoinCommand(std::map<std::string, std::string> _channels);
~JoinCommand();

void execute(Server &server, int fd);
void execute(int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/NickCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class NickCommand : public ICommand {
NickCommand(const std::string& nickname);
~NickCommand();

void execute(Server &server, int clientFd);
void execute(int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/PassCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PassCommand : public ICommand {
PassCommand(const std::string& password);
~PassCommand();

void execute(Server &server, int clientFd);
void execute(int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/PrivateMessageCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class PrivateMessageCommand : public ICommand {

public:
PrivateMessageCommand(std::vector<std::string> receivers, std::string message);
void execute(Server &server, int fd);
void execute(int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/QuitCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class QuitCommand : public ICommand {
QuitCommand(std::string msg);
~QuitCommand();

void execute(Server &server, int clientFd);
void execute(int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/UserCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserCommand : public ICommand {
public:
UserCommand();
UserCommand(const std::string& username, const std::string& hostname, const std::string& serverName, const std::string& realName);
void execute(Server &server, int clientFd);
void execute(int clientFd);
~UserCommand();
};

Expand Down
21 changes: 0 additions & 21 deletions includes/exceptions/ChannelException.hpp

This file was deleted.

17 changes: 8 additions & 9 deletions includes/libsUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
# include <cstdlib>
# include <iostream>
# include <sstream>
# include <string>
# include <algorithm>
# include <vector>
# include <unistd.h>

# include "utils.hpp"

# include "exceptions.hpp"

# include "Logger.hpp"
Expand All @@ -23,6 +22,9 @@
# define SUCCESS 0
# define EXIT 1

# define DEFAULT_PORT "6666"
# define DEFAULT_PASS "1234"

// ========================================= IRC SERVER ERROR MESSAGES =========================================
# define INVALID_ARGS "[ERROR] Invalid args.\nUsage: ./ircserv <port> <password>"

Expand All @@ -37,13 +39,10 @@
# define RECV_EXPT "[ERROR] Unable to receive message."
# define SEND_EXPT "[ERROR] Unable to send message."

# define INVALID_COMMAND "[ERROR] Invalid command sent to server socket." //???

# define AUTH_ERR "[ERROR] Unauthorized.\nPlease send connection password and set your nickname and username."
# define INVALID_PASSWORD "[ERROR] Password provided doesn't match server password."

# define USER_NOT_FOUND_ERR "[ERROR] User not found in list."

# define CHANNEL_ALREADY_ADDED_ERR "[ERROR] Channel already added."
# define USER_ALREADY_IN_CHANNEL_ERR "[ERROR] User already in channel."

std::string trim(const std::string& str);
std::vector<std::string> split(const std::string &s, char delim);

#endif
15 changes: 0 additions & 15 deletions includes/utils.hpp

This file was deleted.

30 changes: 27 additions & 3 deletions src/Server.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "Server.hpp"

Server *Server::_server = NULL;

/**
* This function aims to validate the port number.
* A valid port number is between 1 and 65535.
Expand Down Expand Up @@ -29,7 +31,6 @@ Server::Server(const std::string port, const std::string password) : _password(p
throw ServerException(PORT_OUT_OF_RANGE_ERR);
_port = std::atoi(port.c_str());
this->initServer();
this->listenClients();
}

/**
Expand All @@ -41,6 +42,29 @@ Server::~Server() {
this->closeConnections();
}

/**
* This function aims to initialize the server.
*
* @param port The port number to listen for incoming connections.
* @param password The password to authenticate the clients.
*
*/
void Server::init(std::string port, std::string password) {
Server::_server = new Server(port, password);
Server::_server->listenClients();
}

/**
* This function aims to get the instance of the server.
*
* @return The instance of the server.
*/
Server &Server::getInstance() {
if (Server::_server == NULL)
Server::_server = new Server(DEFAULT_PORT, DEFAULT_PASS);
return *Server::_server;
}

/**
* This function aims to close all the connections.
*/
Expand Down Expand Up @@ -170,7 +194,7 @@ void Server::handleExistingConnection(int clientFd) {
Logger::debug("Mensaje del cliente: " + std::string(buffer, readBytes));
try {
ICommand* command = CommandParser::parse(std::string(buffer, readBytes));
command->execute(*this, clientFd);
command->execute(clientFd);
} catch (IRCException& e) {
std::string clientNickname = getUserByFd(clientFd).getNickname();
sendMessage(clientFd,
Expand Down Expand Up @@ -275,7 +299,7 @@ void Server::removeUser(int fd) {
* @param clientFd The file descriptor of the user.
*/
void Server::attemptUserRegistration(int clientFd) {
this->getUserByFd(clientFd).makeRegistration(*this);
this->getUserByFd(clientFd).makeRegistration();
}

/**
Expand Down
10 changes: 4 additions & 6 deletions src/User.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,9 @@ bool User::canRegister() {
/**
* This function try to register the user and verify that it is the same password as on the server.
*
* @param server The server where the user is trying to register.
*/
void User::makeRegistration(Server &server) {
if (!server.isValidPassword(_password))
void User::makeRegistration() {
if (!Server::getInstance().isValidPassword(_password))
throw PasswordMismatchException();
this->_registered = true;
}
Expand All @@ -212,12 +211,11 @@ void User::addChannel(Channel &channel) {
/**
* This function aims to send a private message to a user.
*
* @param server The server where the user is connected.
* @param destination The user who will receive the message.
* @param message The message to send.
*/
void User::sendPrivateMessageToUser(const Server &server, const User &destination, const std::string& message) {
void User::sendPrivateMessageToUser(const User &destination, const std::string& message) {
Logger::debug("Sending private message to " + destination.getNickname() + " from " + this->getNickname() + ": " + message);
std::string response = ":" + this->_nickname + " PRIVMSG " + destination.getNickname() + " :" + message;
server.sendMessage(destination.getFd(), response);
Server::getInstance().sendMessage(destination.getFd(), response);
}
4 changes: 2 additions & 2 deletions src/commands/JoinCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ JoinCommand::~JoinCommand() {
/**
* Executes the command JOIN.
*
* @param server The server where the command will be executed
* @param clientFd The socket file descriptor of the client
*
*/
void JoinCommand::execute(Server &server, int clientFd) {
void JoinCommand::execute(int clientFd) {
Server& server = Server::getInstance();
User user = server.getUserByFd(clientFd);
std::vector<Channel> serverChannels = server.getChannels();

Expand Down
4 changes: 2 additions & 2 deletions src/commands/NickCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ NickCommand::~NickCommand() {}
/**
* Execute the command NICK.
*
* @param server The server where the command will be executed
* @param clientFd The socket file descriptor of the client
*
* @throws `NoNicknameGivenException` If the nickname is empty
Expand All @@ -29,7 +28,8 @@ NickCommand::~NickCommand() {}
* @throws `NicknameInUseException` If the nickname is already in use and the user is registered
*
*/
void NickCommand::execute(Server &server, int clientFd) {
void NickCommand::execute(int clientFd) {
Server& server = Server::getInstance();
if (this->_nickname.empty())
throw NoNicknameGivenException();

Expand Down
7 changes: 3 additions & 4 deletions src/commands/PassCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ PassCommand::~PassCommand() {}
/**
* Execute the command PASS.
*
* @param server The server where the command will be executed
* @param fd The socket file descriptor of the client
* @param clientFd The socket file descriptor of the client
*
* @throws `AlreadyRegisteredException` If the user is already registered
*
*/
void PassCommand::execute(Server &server, int clientFd) {
void PassCommand::execute(int clientFd) {
Server& server = Server::getInstance();
if (server.getUserByFd(clientFd).isRegistered())
throw AlreadyRegisteredException();
server.getUserByFd(clientFd).setPassword(_password);
Expand Down
Loading

0 comments on commit 8a65020

Please sign in to comment.