IRC SERVER
The goal of this project is to make you write your own IRC server.
Server.hpp
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* Server.hpp :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: aborboll <[email protected]> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2022/03/09 17:13:29 by aborboll #+# #+# */
9 /* Updated: 2023/03/23 18:29:43 by aborboll ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #ifndef SERVER_H
14 #define SERVER_H
15 
16 // Main libraries
17 #include <fcntl.h>
18 #include <poll.h>
19 
20 // Our includes
21 #include "./Channel.hpp"
22 #include "./Client.hpp"
23 #include "./Color.hpp"
24 #include "./config.hpp"
25 
26 // Commands
27 class Command;
28 
29 // Validation
30 bool validate_args(int argc, char **argv);
31 
32 class Server
33 {
34  private:
35  typedef std::map<size_t, Client *>::iterator clientMap_iterator;
36  typedef std::map<std::string, Channel *>::iterator channelMap_iterator;
37  typedef std::vector<pollfd>::iterator pollVector_iterator;
38 
39  // Connection params
40  std::string const host;
41  std::string const servername;
42  std::string const version;
43  std::string const port;
44  std::string const password;
45 
46  public:
47  // Clients
48  std::map<size_t, Client *> _clients;
49 
50  // Commands
51  std::map<std::string, Command *> _commands;
52 
53  // Channels
54  std::map<std::string, Channel *> _channels;
55 
56  // Socket status
57  enum Status
58  {
62  } _status;
63 
64  // Socket specific vars
65  std::vector<pollfd> _pfds;
66  int _fd;
67 
68  public:
69  Server(std::string host, std::string port, std::string password);
70  ~Server();
71  void close_server();
72  void run();
73 
74  // Helpers
75  bool is_running(void)
76  {
77  return (_status == ONLINE);
78  }
79  bool hasPassword(void)
80  {
81  return (password != "");
82  }
83  std::string const getPassword(void)
84  {
85  return (password);
86  }
87 
88  std::string const getServerName(void)
89  {
90  return (servername);
91  }
92 
93  std::vector<Client *> getRelatedClients(Client *client)
94  {
95  std::vector<Channel *> channels = this->getChannels();
96  std::vector<Client *> related_clients;
97 
98  for (size_t i = 0; i < channels.size(); i++)
99  {
100  if (channels[i]->joined(client))
101  {
102  std::vector<Client *> channel_clients = channels[i]->getClients();
103  for (size_t u = 0; u < channel_clients.size(); u++)
104  {
105  if (channel_clients[u] != client &&
106  !std::count(related_clients.begin(), related_clients.end(), channel_clients[u]))
107  related_clients.push_back(channel_clients[u]);
108  }
109  }
110  }
111  return (related_clients);
112  }
113 
114  std::map<std::string, Channel *> getRelatedChannels(Client *client)
115  {
116  std::map<std::string, Channel *> related_channels;
117 
118  std::map<std::string, Channel *>::iterator it = _channels.begin();
119  for (; it != _channels.end(); it++)
120  {
121  if (it->second->joined(client))
122  {
123  related_channels.insert(std::pair<std::string, Channel *>(it->first, it->second));
124  }
125  }
126  return (related_channels);
127  }
128 
129  private:
130  void createServerListener(void);
131  void createServerPoll(void);
132  void removeClientFromServer(size_t clientId);
133  int readClient(size_t &i);
134  void setupCommands(void);
135 
136  public:
137  // --------------
138  // Clients stuff
139  // --------------
140  Client *getClient(std::string const &name)
141  {
142  std::map<size_t, Client *>::iterator it = _clients.begin();
143  for (; it != _clients.end(); it++)
144  {
145  if (it->second->_nick == name)
146  {
147  return (it->second);
148  }
149  }
150  return (NULL);
151  }
152 
153  void deleteClient(int fd)
154  {
155  for (clientMap_iterator it = _clients.begin(); it != _clients.end();)
156  {
157  if (it->second->_fd == fd)
158  {
159  for (channelMap_iterator itc = _channels.begin();
160  itc != _channels.end();)
161  {
162  itc->second->removeClientFromChannel(it->second);
163  if (itc->second->getClients().size() == 0)
164  {
165  delete itc->second;
166  _channels.erase(itc++);
167  }
168  else
169  itc++;
170  }
171  delete it->second;
172  _clients.erase(it++);
173  for (pollVector_iterator it2 = _pfds.begin(); it2 != _pfds.end();)
174  {
175  if (it2->fd == fd)
176  {
177  _pfds.erase(it2++);
178  break;
179  }
180  else
181  it2++;
182  }
183  }
184  else
185  it++;
186  }
187  }
188 
189  size_t getClientIndex(std::string &name)
190  {
191  for (size_t i = 0; i < _clients.size(); i++)
192  {
193  if (_clients[i]->_nick == name)
194  return (i);
195  }
196  return (-1);
197  }
198 
199  // --------------
200  // Channel stuff
201  // --------------
202  Channel *getChannel(std::string &name)
203  {
204  if (name.at(0) == '#')
205  name = name.substr(1);
206  if (_channels.find(name) != _channels.end())
207  return _channels[name];
208  else
209  return NULL;
210  }
211 
212  std::vector<Channel *> getChannels(void)
213  {
214  std::vector<Channel *> channels;
215  std::map<std::string, Channel *>::iterator it;
216  for (it = _channels.begin(); it != _channels.end(); it++)
217  channels.push_back(it->second);
218  return channels;
219  }
220 
221  Channel *createChannel(std::string &name, std::string &password)
222  {
223  if (name.at(0) == '#')
224  name = name.substr(1);
225  _channels[name] = new Channel(name, password);
226  return _channels[name];
227  }
228 
229  // --------------
230  // Commands stuff
231  // --------------
232  Command *getCommand(std::string &name)
233  {
234  if (_commands.find(name) != _commands.end())
235  return _commands[name];
236  return (NULL);
237  }
238 };
239 
240 #endif
Server::close_server
void close_server()
Server::CLOSED
@ CLOSED
Definition: Server.hpp:61
Channel
Definition: Channel.hpp:26
Server::ONLINE
@ ONLINE
Definition: Server.hpp:60
Server::getClientIndex
size_t getClientIndex(std::string &name)
Definition: Server.hpp:189
Server::_commands
std::map< std::string, Command * > _commands
Definition: Server.hpp:51
Server::_pfds
std::vector< pollfd > _pfds
Definition: Server.hpp:65
config.hpp
Server::Status
Status
Definition: Server.hpp:57
Server::~Server
~Server()
Definition: server.cpp:191
validate_args
bool validate_args(int argc, char **argv)
Definition: validation.cpp:15
Server::OFFLINE
@ OFFLINE
Definition: Server.hpp:59
Command
Definition: Command.hpp:7
Server::getRelatedClients
std::vector< Client * > getRelatedClients(Client *client)
Definition: Server.hpp:93
Server::_channels
std::map< std::string, Channel * > _channels
Definition: Server.hpp:54
Server::createChannel
Channel * createChannel(std::string &name, std::string &password)
Definition: Server.hpp:221
Server::is_running
bool is_running(void)
Definition: Server.hpp:75
Server::_clients
std::map< size_t, Client * > _clients
Definition: Server.hpp:48
Server::getChannels
std::vector< Channel * > getChannels(void)
Definition: Server.hpp:212
Server::hasPassword
bool hasPassword(void)
Definition: Server.hpp:79
Server::getCommand
Command * getCommand(std::string &name)
Definition: Server.hpp:232
Server::_fd
int _fd
Definition: Server.hpp:66
Channel.hpp
Server::deleteClient
void deleteClient(int fd)
Definition: Server.hpp:153
Server::getPassword
const std::string getPassword(void)
Definition: Server.hpp:83
Server::Server
Server(std::string host, std::string port, std::string password)
Here we init the server instance.
Definition: server.cpp:162
Server::_status
enum Server::Status _status
Server::run
void run()
Server::getClient
Client * getClient(std::string const &name)
Definition: Server.hpp:140
Server::getChannel
Channel * getChannel(std::string &name)
Definition: Server.hpp:202
Color.hpp
Client
Definition: Client.hpp:22
Server::getServerName
const std::string getServerName(void)
Definition: Server.hpp:88
Server::getRelatedChannels
std::map< std::string, Channel * > getRelatedChannels(Client *client)
Definition: Server.hpp:114
Server
Definition: Server.hpp:32
Client.hpp