irccd  3.0.3
server.hpp
1 /*
2  * server.hpp -- an IRC server
3  *
4  * Copyright (c) 2013-2019 David Demelier <markand@malikania.fr>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef IRCCD_DAEMON_SERVER_HPP
20 #define IRCCD_DAEMON_SERVER_HPP
21 
27 #include <irccd/sysconfig.hpp>
28 
29 #include <cstdint>
30 #include <deque>
31 #include <functional>
32 #include <map>
33 #include <memory>
34 #include <set>
35 #include <string>
36 #include <variant>
37 #include <vector>
38 
39 #include <json.hpp>
40 
41 #include "irc.hpp"
42 
43 namespace irccd::daemon {
44 
45 class server;
46 
51 enum class channel_mode {
52  creator = 'O',
53  half_op = 'h',
54  op = 'o',
55  protection = 'a',
56  voiced = 'v'
57 };
58 
63 struct channel {
64  std::string name;
65  std::string password;
66 };
67 
72 struct whois_info {
73  std::string nick;
74  std::string user;
75  std::string hostname;
76  std::string realname;
77  std::vector<std::string> channels;
78 };
79 
84 struct connect_event {
85  std::shared_ptr<class server> server;
86 };
87 
93  std::shared_ptr<class server> server;
94 };
95 
100 struct invite_event {
101  std::shared_ptr<class server> server;
102  std::string origin;
103  std::string channel;
104  std::string nickname;
105 };
106 
111 struct join_event {
112  std::shared_ptr<class server> server;
113  std::string origin;
114  std::string channel;
115 };
116 
121 struct kick_event {
122  std::shared_ptr<class server> server;
123  std::string origin;
124  std::string channel;
125  std::string target;
126  std::string reason;
127 };
128 
134  std::shared_ptr<class server> server;
135  std::string origin;
136  std::string channel;
137  std::string message;
138 };
139 
144 struct me_event {
145  std::shared_ptr<class server> server;
146  std::string origin;
147  std::string channel;
148  std::string message;
149 };
150 
155 struct mode_event {
156  std::shared_ptr<class server> server;
157  std::string origin;
158  std::string channel;
159  std::string mode;
160  std::string limit;
161  std::string user;
162  std::string mask;
163 };
164 
169 struct names_event {
170  std::shared_ptr<class server> server;
171  std::string channel;
172  std::vector<std::string> names;
173 };
174 
179 struct nick_event {
180  std::shared_ptr<class server> server;
181  std::string origin;
182  std::string nickname;
183 };
184 
189 struct notice_event {
190  std::shared_ptr<class server> server;
191  std::string origin;
192  std::string channel;
193  std::string message;
194 };
195 
200 struct part_event {
201  std::shared_ptr<class server> server;
202  std::string origin;
203  std::string channel;
204  std::string reason;
205 };
206 
211 struct topic_event {
212  std::shared_ptr<class server> server;
213  std::string origin;
214  std::string channel;
215  std::string topic;
216 };
217 
222 struct whois_event {
223  std::shared_ptr<class server> server;
225 };
226 
231 using event = std::variant<
232  std::monostate,
235  invite_event,
236  join_event,
237  kick_event,
238  me_event,
240  mode_event,
241  names_event,
242  nick_event,
243  notice_event,
244  part_event,
245  topic_event,
247 >;
248 
256 class server : public std::enable_shared_from_this<server> {
257 public:
261  using connect_handler = std::function<void (std::error_code)>;
262 
266  using recv_handler = std::function<void (std::error_code, event)>;
267 
271  enum class options : std::uint8_t {
272  none = 0,
273  ipv4 = (1 << 0),
274  ipv6 = (1 << 1),
275  ssl = (1 << 2),
276  auto_rejoin = (1 << 3),
277  auto_reconnect = (1 << 4),
278  join_invite = (1 << 5)
279  };
280 
284  enum class state : std::uint8_t {
285  disconnected,
286  connecting,
287  identifying,
288  connected
289  };
290 
291 protected:
296 
297 private:
298  // Requested and joined channels.
299  std::vector<channel> rchannels_;
300  std::set<std::string> jchannels_;
301 
302  // Identifier.
303  std::string id_;
304 
305  // Connection information.
306  std::string hostname_;
307  std::string password_;
308  std::uint16_t port_{6667};
309  options options_;
310 
311  // Identity.
312  std::string nickname_{"irccd"};
313  std::string username_{"irccd"};
314  std::string realname_{"IRC Client Daemon"};
315  std::string ctcpversion_{"IRC Client Daemon"};
316 
317  // Settings.
318  std::string command_char_{"!"};
319  std::uint16_t recodelay_{30};
320  std::uint16_t timeout_{1000};
321 
322  // Server information.
323  std::map<channel_mode, char> modes_;
324 
325  // Misc.
326  boost::asio::io_service& service_;
327  boost::asio::deadline_timer timer_;
328  std::shared_ptr<irc::connection> conn_;
329  std::deque<std::string> queue_;
330  std::map<std::string, std::set<std::string>> names_map_;
331  std::map<std::string, whois_info> whois_map_;
332 
333  auto dispatch_connect(const irc::message&, const recv_handler&) -> bool;
334  auto dispatch_endofnames(const irc::message&, const recv_handler&) -> bool;
335  auto dispatch_endofwhois(const irc::message&, const recv_handler&) -> bool;
336  auto dispatch_invite(const irc::message&, const recv_handler&) -> bool;
337  auto dispatch_isupport(const irc::message&) -> bool;
338  auto dispatch_join(const irc::message&, const recv_handler&) -> bool;
339  auto dispatch_kick(const irc::message&, const recv_handler&) -> bool;
340  auto dispatch_mode(const irc::message&, const recv_handler&) -> bool;
341  auto dispatch_namreply(const irc::message&) -> bool;
342  auto dispatch_nick(const irc::message&, const recv_handler&) -> bool;
343  auto dispatch_notice(const irc::message&, const recv_handler&) -> bool;
344  auto dispatch_part(const irc::message&, const recv_handler&) -> bool;
345  auto dispatch_ping(const irc::message&) -> bool;
346  auto dispatch_privmsg(const irc::message&, const recv_handler&) -> bool;
347  auto dispatch_topic(const irc::message&, const recv_handler&) -> bool;
348  auto dispatch_whoischannels(const irc::message&) -> bool;
349  auto dispatch_whoisuser(const irc::message&) -> bool;
350  auto dispatch(const irc::message&, const recv_handler&) -> bool;
351 
352  // I/O and connection.
353  void flush();
354  void identify();
355  void handle_send(const std::error_code&);
356  void handle_recv(const std::error_code&, const irc::message&, const recv_handler&);
357  void handle_connect(const std::error_code&, const connect_handler&);
358 
359 public:
368  server(boost::asio::io_service& service, std::string id, std::string hostname = "localhost");
369 
373  virtual ~server();
374 
380  auto get_state() const noexcept -> state;
381 
387  auto get_id() const noexcept -> const std::string&;
388 
394  auto get_hostname() const noexcept -> const std::string&;
395 
401  auto get_password() const noexcept -> const std::string&;
402 
410  void set_password(std::string password) noexcept;
411 
417  auto get_port() const noexcept -> std::uint16_t;
418 
424  void set_port(std::uint16_t port) noexcept;
425 
431  auto get_options() const noexcept -> options;
432 
438  void set_options(options flags) noexcept;
439 
445  auto get_nickname() const noexcept -> const std::string&;
446 
455  void set_nickname(std::string nickname);
456 
462  auto get_username() const noexcept -> const std::string&;
463 
470  void set_username(std::string name) noexcept;
471 
477  auto get_realname() const noexcept -> const std::string&;
478 
485  void set_realname(std::string realname) noexcept;
486 
492  auto get_ctcp_version() const noexcept -> const std::string&;
493 
499  void set_ctcp_version(std::string ctcpversion);
500 
506  auto get_command_char() const noexcept -> const std::string&;
507 
514  void set_command_char(std::string command_char) noexcept;
515 
521  auto get_reconnect_delay() const noexcept -> std::uint16_t;
522 
528  void set_reconnect_delay(std::uint16_t reconnect_delay) noexcept;
529 
535  auto get_ping_timeout() const noexcept -> std::uint16_t;
536 
542  void set_ping_timeout(std::uint16_t ping_timeout) noexcept;
543 
549  auto get_channels() const noexcept -> const std::set<std::string>&;
550 
557  auto is_self(std::string_view nick) const noexcept -> bool;
558 
570  virtual void connect(connect_handler handler) noexcept;
571 
575  virtual void disconnect();
576 
583  virtual void wait(connect_handler handler);
584 
592  virtual void recv(recv_handler handler) noexcept;
593 
600  virtual void invite(std::string_view target, std::string_view channel);
601 
608  virtual void join(std::string_view channel, std::string_view password = "");
609 
618  virtual void kick(std::string_view target,
619  std::string_view channel,
620  std::string_view reason = "");
621 
629  virtual void me(std::string_view target, std::string_view message);
630 
637  virtual void message(std::string_view target, std::string_view message);
638 
648  virtual void mode(std::string_view channel,
649  std::string_view mode,
650  std::string_view limit = "",
651  std::string_view user = "",
652  std::string_view mask = "");
653 
659  virtual void names(std::string_view channel);
660 
667  virtual void notice(std::string_view target, std::string_view message);
668 
678  virtual void part(std::string_view channel, std::string_view reason = "");
679 
689  virtual void send(std::string_view raw);
690 
697  virtual void topic(std::string_view channel, std::string_view topic);
698 
704  virtual void whois(std::string_view target);
705 };
706 
718 inline auto operator^(server::options v1, server::options v2) noexcept -> server::options
719 {
720  return static_cast<server::options>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2));
721 }
722 
730 inline auto operator&(server::options v1, server::options v2) noexcept -> server::options
731 {
732  return static_cast<server::options>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2));
733 }
734 
742 inline auto operator|(server::options v1, server::options v2) noexcept -> server::options
743 {
744  return static_cast<server::options>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2));
745 }
746 
753 inline auto operator~(server::options v) noexcept -> server::options
754 {
755  return static_cast<server::options>(~static_cast<unsigned>(v));
756 }
757 
765 inline auto operator|=(server::options& v1, server::options v2) noexcept -> server::options&
766 {
767  return v1 = v1 | v2;
768 }
769 
777 inline auto operator&=(server::options& v1, server::options v2) noexcept -> server::options&
778 {
779  return v1 = v1 & v2;
780 }
781 
789 inline auto operator^=(server::options& v1, server::options v2) noexcept -> server::options&
790 {
791  return v1 = v1 ^ v2;
792 }
793 
802 class server_error : public std::system_error {
803 public:
807  enum error {
809  no_error = 0,
810 
812  not_found,
813 
815  invalid_identifier,
816 
818  not_connected,
819 
821  already_connected,
822 
824  already_exists,
825 
827  invalid_port,
828 
830  invalid_reconnect_delay,
831 
833  invalid_hostname,
834 
836  invalid_channel,
837 
839  invalid_mode,
840 
842  invalid_nickname,
843 
845  invalid_username,
846 
848  invalid_realname,
849 
851  invalid_password,
852 
854  invalid_ping_timeout,
855 
857  invalid_ctcp_version,
858 
860  invalid_command_char,
861 
863  invalid_message,
864 
866  ssl_disabled,
867 
869  invalid_family
870  };
871 
872 public:
878  server_error(error code) noexcept;
879 };
880 
886 auto server_category() -> const std::error_category&;
887 
894 auto make_error_code(server_error::error e) -> std::error_code;
895 
896 } // !irccd::daemon
897 
902 namespace std {
903 
904 template <>
905 struct is_error_code_enum<irccd::daemon::server_error::error> : public std::true_type {
906 };
907 
908 } // !std
909 
914 #endif // !IRCCD_DAEMON_SERVER_HPP
Server error.
Definition: server.hpp:802
error
Server related errors.
Definition: server.hpp:807
server_error(error code) noexcept
The class that connect to a IRC server.
Definition: server.hpp:256
auto get_state() const noexcept -> state
auto get_command_char() const noexcept -> const std::string &
virtual void message(std::string_view target, std::string_view message)
std::function< void(std::error_code, event)> recv_handler
Definition: server.hpp:266
virtual void invite(std::string_view target, std::string_view channel)
virtual void part(std::string_view channel, std::string_view reason="")
server(boost::asio::io_service &service, std::string id, std::string hostname="localhost")
auto is_self(std::string_view nick) const noexcept -> bool
virtual void wait(connect_handler handler)
virtual void kick(std::string_view target, std::string_view channel, std::string_view reason="")
options
Various options for server.
Definition: server.hpp:271
@ ipv4
Connect using IPv4.
@ auto_rejoin
Auto rejoin a kick.
@ auto_reconnect
Auto reconnect on disconnection.
@ join_invite
Join a channel on invitation.
@ ipv6
Connect using IPv6.
auto get_ping_timeout() const noexcept -> std::uint16_t
void set_nickname(std::string nickname)
void set_port(std::uint16_t port) noexcept
auto get_nickname() const noexcept -> const std::string &
state
Describe current server state.
Definition: server.hpp:284
@ disconnected
not connected at all,
@ connecting
network connection in progress,
@ identifying
sending nick, user and password commands,
void set_options(options flags) noexcept
auto get_port() const noexcept -> std::uint16_t
void set_reconnect_delay(std::uint16_t reconnect_delay) noexcept
virtual void notice(std::string_view target, std::string_view message)
auto get_ctcp_version() const noexcept -> const std::string &
std::function< void(std::error_code)> connect_handler
Definition: server.hpp:261
auto get_reconnect_delay() const noexcept -> std::uint16_t
auto get_channels() const noexcept -> const std::set< std::string > &
void set_ping_timeout(std::uint16_t ping_timeout) noexcept
virtual void topic(std::string_view channel, std::string_view topic)
state state_
Server state.
Definition: server.hpp:295
auto get_password() const noexcept -> const std::string &
auto get_username() const noexcept -> const std::string &
auto get_hostname() const noexcept -> const std::string &
virtual void disconnect()
virtual void me(std::string_view target, std::string_view message)
virtual void connect(connect_handler handler) noexcept
void set_username(std::string name) noexcept
void set_command_char(std::string command_char) noexcept
auto get_id() const noexcept -> const std::string &
virtual void mode(std::string_view channel, std::string_view mode, std::string_view limit="", std::string_view user="", std::string_view mask="")
void set_realname(std::string realname) noexcept
void set_ctcp_version(std::string ctcpversion)
virtual void send(std::string_view raw)
virtual void join(std::string_view channel, std::string_view password="")
auto get_options() const noexcept -> options
virtual void names(std::string_view channel)
virtual void whois(std::string_view target)
auto get_realname() const noexcept -> const std::string &
void set_password(std::string password) noexcept
virtual void recv(recv_handler handler) noexcept
std::variant< std::monostate, connect_event, disconnect_event, invite_event, join_event, kick_event, me_event, message_event, mode_event, names_event, nick_event, notice_event, part_event, topic_event, whois_event > event
Store all possible events.
Definition: server.hpp:247
channel_mode
Prefixes for nicknames.
Definition: server.hpp:51
@ op
Channel operator.
@ creator
Channel creator.
Main irccd namespace.
Definition: bot.hpp:41
auto server_category() -> const std::error_category &
auto make_error_code(bot_error::error e) noexcept -> std::error_code
Parent namespace.
Definition: acceptor.hpp:43
Definition: bot.hpp:253
A channel to join with an optional password.
Definition: server.hpp:63
std::string name
the channel to join
Definition: server.hpp:64
std::string password
the optional password
Definition: server.hpp:65
Connection success event.
Definition: server.hpp:84
std::shared_ptr< class server > server
The server.
Definition: server.hpp:85
Connection success event.
Definition: server.hpp:92
std::shared_ptr< class server > server
The server.
Definition: server.hpp:93
Invite event.
Definition: server.hpp:100
std::string nickname
The nickname (you).
Definition: server.hpp:104
std::string origin
The originator.
Definition: server.hpp:102
std::shared_ptr< class server > server
The server.
Definition: server.hpp:101
std::string channel
The channel.
Definition: server.hpp:103
Join event.
Definition: server.hpp:111
std::string channel
The channel.
Definition: server.hpp:114
std::string origin
The originator.
Definition: server.hpp:113
std::shared_ptr< class server > server
The server.
Definition: server.hpp:112
Kick event.
Definition: server.hpp:121
std::string reason
The reason (Optional).
Definition: server.hpp:126
std::string origin
The originator.
Definition: server.hpp:123
std::shared_ptr< class server > server
The server.
Definition: server.hpp:122
std::string channel
The channel.
Definition: server.hpp:124
std::string target
The target.
Definition: server.hpp:125
CTCP action event.
Definition: server.hpp:144
std::shared_ptr< class server > server
The server.
Definition: server.hpp:145
std::string origin
The originator.
Definition: server.hpp:146
std::string channel
The channel.
Definition: server.hpp:147
std::string message
The message.
Definition: server.hpp:148
Message event.
Definition: server.hpp:133
std::shared_ptr< class server > server
The server.
Definition: server.hpp:134
std::string message
The message.
Definition: server.hpp:137
std::string origin
The originator.
Definition: server.hpp:135
std::string channel
The channel.
Definition: server.hpp:136
Mode event.
Definition: server.hpp:155
std::string channel
The channel or target.
Definition: server.hpp:158
std::string limit
The optional limit.
Definition: server.hpp:160
std::shared_ptr< class server > server
The server.
Definition: server.hpp:156
std::string mode
The mode.
Definition: server.hpp:159
std::string mask
The optional ban mask.
Definition: server.hpp:162
std::string user
The optional user.
Definition: server.hpp:161
std::string origin
The originator.
Definition: server.hpp:157
Names listing event.
Definition: server.hpp:169
std::string channel
The channel.
Definition: server.hpp:171
std::vector< std::string > names
The names.
Definition: server.hpp:172
std::shared_ptr< class server > server
The server.
Definition: server.hpp:170
Nick change event.
Definition: server.hpp:179
std::string origin
The originator.
Definition: server.hpp:181
std::shared_ptr< class server > server
The server.
Definition: server.hpp:180
std::string nickname
The new nickname.
Definition: server.hpp:182
Notice event.
Definition: server.hpp:189
std::string channel
The channel or target.
Definition: server.hpp:192
std::string origin
The originator.
Definition: server.hpp:191
std::string message
The message.
Definition: server.hpp:193
std::shared_ptr< class server > server
The server.
Definition: server.hpp:190
Part event.
Definition: server.hpp:200
std::string reason
The reason.
Definition: server.hpp:204
std::string origin
The originator.
Definition: server.hpp:202
std::string channel
The channel.
Definition: server.hpp:203
std::shared_ptr< class server > server
The server.
Definition: server.hpp:201
Topic event.
Definition: server.hpp:211
std::string origin
The originator.
Definition: server.hpp:213
std::string topic
The topic message.
Definition: server.hpp:215
std::shared_ptr< class server > server
The server.
Definition: server.hpp:212
std::string channel
The channel.
Definition: server.hpp:214
Whois event.
Definition: server.hpp:222
std::shared_ptr< class server > server
The server.
Definition: server.hpp:223
whois_info whois
The whois information.
Definition: server.hpp:224
Describe a whois information.
Definition: server.hpp:72
std::string nick
user's nickname
Definition: server.hpp:73
std::string hostname
hostname
Definition: server.hpp:75
std::string user
user's user
Definition: server.hpp:74
std::string realname
realname
Definition: server.hpp:76
std::vector< std::string > channels
the channels where the user is
Definition: server.hpp:77