bridge.hpp 4.85 KB
Newer Older
1
2
3
4
#ifndef BRIDGE_INCLUDED
# define BRIDGE_INCLUDED

#include <irc/irc_client.hpp>
5
#include <bridge/colors.hpp>
6
#include <irc/irc_user.hpp>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <irc/iid.hpp>

#include <unordered_map>
#include <string>
#include <memory>

class XmppComponent;
class Poller;

/**
 * One bridge is spawned for each XMPP user that uses the component.  The
 * bridge spawns IrcClients when needed (when the user wants to join a
 * channel on a new server) and does the translation between the two
 * protocols.
 */
class Bridge
{
public:
  explicit Bridge(const std::string& user_jid, XmppComponent* xmpp, Poller* poller);
  ~Bridge();
louiz’'s avatar
louiz’ committed
27
28
29
30
  /**
   * QUIT all connected IRC servers.
   */
  void shutdown();
louiz’'s avatar
louiz’ committed
31
32
33
34
  /**
   * Remove all inactive IrcClients
   */
  void clean();
35
  static Xmpp::body make_xmpp_body(const std::string& str);
36
37
38
39
40
41
  /***
   **
   ** From XMPP to IRC.
   **
   **/

louiz’'s avatar
louiz’ committed
42
43
44
45
46
  /**
   * Try to join an irc_channel, does nothing and return true if the channel
   * was already joined.
   */
  bool join_irc_channel(const Iid& iid, const std::string& username);
louiz’'s avatar
louiz’ committed
47
  void send_channel_message(const Iid& iid, const std::string& body);
louiz’'s avatar
louiz’ committed
48
  void send_private_message(const Iid& iid, const std::string& body);
louiz’'s avatar
louiz’ committed
49
  void leave_irc_channel(Iid&& iid, std::string&& status_message);
louiz’'s avatar
louiz’ committed
50
  void send_irc_nick_change(const Iid& iid, const std::string& new_nick);
51
  void send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason);
52
  void set_channel_topic(const Iid& iid, const std::string& subject);
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

  /***
   **
   ** From IRC to XMPP.
   **
   **/

  /**
   * Send a message corresponding to a server NOTICE, the from attribute
   * should be juste the server hostname@irc.component.
   */
  void send_xmpp_message(const std::string& from, const std::string& author, const std::string& msg);
  /**
   * Send the presence of a new user in the MUC.
   */
68
69
  void send_user_join(const std::string& hostname,
                      const std::string& chan_name,
70
                      const IrcUser* user,
71
                      const char user_mode,
72
                      const bool self);
73
74
75
76
  /**
   * Send the topic of the MUC to the user
   */
  void send_topic(const std::string& hostname, const std::string& chan_name, const std::string topic);
louiz’'s avatar
louiz’ committed
77
78
79
  /**
   * Send a MUC message from some participant
   */
louiz’'s avatar
louiz’ committed
80
  void send_message(const Iid& iid, const std::string& nick, const std::string& body, const bool muc);
louiz’'s avatar
louiz’ committed
81
82
83
  /**
   * Send an unavailable presence from this participant
   */
louiz’'s avatar
louiz’ committed
84
85
86
  void send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self);
  /**
   * Send presences to indicate that an user old_nick (ourself if self ==
87
88
89
   * true) changed his nick to new_nick.  The user_mode is needed because
   * the xmpp presence needs ton contain the role and affiliation of the
   * user.
louiz’'s avatar
louiz’ committed
90
   */
91
92
93
94
95
  void send_nick_change(Iid&& iid,
                        const std::string& old_nick,
                        const std::string& new_nick,
                        const char user_mode,
                        const bool self);
96
  void kick_muc_user(Iid&& iid, const std::string& target, const std::string& reason, const std::string& author);
97
  void send_nickname_conflict_error(const Iid& iid, const std::string& nickname);
98
99
100
101
  /**
   * Send a role/affiliation change, matching the change of mode for that user
   */
  void send_affiliation_role_change(const Iid& iid, const std::string& target, const char mode);
louiz’'s avatar
louiz’ committed
102
103
104
105
106

  /**
   * Misc
   */
  std::string get_own_nick(const Iid& iid);
louiz’'s avatar
louiz’ committed
107
  /**
108
   * Get the number of server to which this bridge is connected or connecting.
louiz’'s avatar
louiz’ committed
109
   */
110
  size_t active_clients() const;
louiz’'s avatar
louiz’ committed
111

112
113
114
115
116
117
118
private:
  /**
   * Returns the client for the given hostname, create one (and use the
   * username in this case) if none is found, and connect that newly-created
   * client immediately.
   */
  IrcClient* get_irc_client(const std::string& hostname, const std::string& username);
louiz’'s avatar
louiz’ committed
119
120
121
122
123
  /**
   * This version does not create the IrcClient if it does not exist, and
   * returns nullptr in that case
   */
  IrcClient* get_irc_client(const std::string& hostname);
124
125
126
127
  /**
   * The JID of the user associated with this bridge. Messages from/to this
   * JID are only managed by this bridge.
   */
128
  const std::string user_jid;
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
  /**
   * One IrcClient for each IRC server we need to be connected to.
   * The pointer is shared by the bridge and the poller.
   */
  std::unordered_map<std::string, std::shared_ptr<IrcClient>> irc_clients;
  /**
   * A raw pointer, because we do not own it, the XMPP component owns us,
   * but we still need to communicate with it, when sending messages from
   * IRC to XMPP.
   */
  XmppComponent* xmpp;
  /**
   * Poller, to give it the IrcClients that we spawn, to make it manage
   * their sockets.
   * We don't own it.
   */
  Poller* poller;

  Bridge(const Bridge&) = delete;
  Bridge(Bridge&& other) = delete;
  Bridge& operator=(const Bridge&) = delete;
  Bridge& operator=(Bridge&&) = delete;
};

#endif // BRIDGE_INCLUDED