diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bridge/bridge.cpp | 16 | ||||
-rw-r--r-- | src/bridge/bridge.hpp | 2 | ||||
-rw-r--r-- | src/irc/irc_client.cpp | 15 | ||||
-rw-r--r-- | src/irc/irc_client.hpp | 5 | ||||
-rw-r--r-- | src/xmpp/biboumi_component.cpp | 13 |
5 files changed, 49 insertions, 2 deletions
diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 23fc71d..8323c77 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -543,6 +543,22 @@ void Bridge::on_gateway_ping(const std::string& irc_hostname, const std::string& "", true); } +void Bridge::send_irc_invitation(const Iid& iid, const std::string to) +{ + IrcClient* irc = this->get_irc_client(iid.get_server()); + Jid to_jid(to); + std::string target_nick; + // Many ways to address a nick: + // A jid (ANY jid…) with a resource + if (!to_jid.resource.empty()) + target_nick = to_jid.resource; + else if (!to_jid.local.empty()) // A jid with a iid with a local part + target_nick = Iid(to_jid.local, {}).get_local(); + else + target_nick = to; // Not a jid, just the nick + irc->send_invitation(iid.get_local(), target_nick); +} + void Bridge::send_irc_version_request(const std::string& irc_hostname, const std::string& target, const std::string& iq_id, const std::string& to_jid, const std::string& from_jid) diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index d7b2a5c..a1ff3ad 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -105,6 +105,8 @@ public: void on_gateway_ping(const std::string& irc_hostname, const std::string& iq_id, const std::string& to_jid, const std::string& from_jid); + void send_irc_invitation(const Iid& iid, const std::string to); + /*** ** ** From IRC to XMPP. diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index d00b6ee..6d4df4a 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -64,6 +64,8 @@ static const std::unordered_map<std::string, {"432", {&IrcClient::on_erroneous_nickname, {2, 0}}}, {"433", {&IrcClient::on_nickname_conflict, {2, 0}}}, {"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}}, + {"443", {&IrcClient::on_useronchannel, {3, 0}}}, + {"ERR_USERONCHANNEL", {&IrcClient::on_useronchannel, {3, 0}}}, {"001", {&IrcClient::on_welcome_message, {1, 0}}}, {"PART", {&IrcClient::on_part, {1, 0}}}, {"ERROR", {&IrcClient::on_error, {1, 0}}}, @@ -95,7 +97,6 @@ static const std::unordered_map<std::string, {"436", {&IrcClient::on_generic_error, {2, 0}}}, {"441", {&IrcClient::on_generic_error, {2, 0}}}, {"442", {&IrcClient::on_generic_error, {2, 0}}}, - {"443", {&IrcClient::on_generic_error, {2, 0}}}, {"444", {&IrcClient::on_generic_error, {2, 0}}}, {"446", {&IrcClient::on_generic_error, {2, 0}}}, {"451", {&IrcClient::on_generic_error, {2, 0}}}, @@ -429,6 +430,11 @@ void IrcClient::send_list_command() this->send_message(IrcMessage("LIST", {})); } +void IrcClient::send_invitation(const std::string& chan_name, const std::string& nick) +{ + this->send_message(IrcMessage("INVITE", {nick, chan_name})); +} + void IrcClient::send_topic_command(const std::string& chan_name, const std::string& topic) { this->send_message(IrcMessage("TOPIC", {chan_name, topic})); @@ -803,7 +809,6 @@ void IrcClient::on_nickname_change_too_fast(const IrcMessage& message) "", txt); } } - void IrcClient::on_generic_error(const IrcMessage& message) { const std::string error_msg = message.arguments.size() >= 3 ? @@ -811,6 +816,12 @@ void IrcClient::on_generic_error(const IrcMessage& message) this->send_gateway_message(message.arguments[1] + ": " + error_msg, message.prefix); } +void IrcClient::on_useronchannel(const IrcMessage& message) +{ + this->send_gateway_message(message.arguments[1] + " " + message.arguments[3] + " " + + message.arguments[2]); +} + void IrcClient::on_welcome_message(const IrcMessage& message) { this->current_nick = message.arguments[0]; diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index fa35e65..6fa40ce 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -129,6 +129,7 @@ public: * Send the LIST irc command */ void send_list_command(); + void send_invitation(const std::string& chan_name, const std::string& nick); void send_topic_command(const std::string& chan_name, const std::string& topic); /** * Send the QUIT irc command @@ -235,6 +236,10 @@ public: */ void on_nickname_change_too_fast(const IrcMessage& message); /** + * An error when we try to invite a user already in the channel + */ + void on_useronchannel(const IrcMessage& message); + /** * Handles most errors from the server by just forwarding the message to the user. */ void on_generic_error(const IrcMessage& message); diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index a0222f5..e7549df 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -254,6 +254,19 @@ void BiboumiComponent::handle_message(const Stanza& stanza) } } } + else if (type == "normal" && iid.type == Iid::Type::Channel) + { + if (const XmlNode* x = stanza.get_child("x", MUC_USER_NS)) + if (const XmlNode* invite = x->get_child("invite", MUC_USER_NS)) + { + const auto invite_to = invite->get_tag("to"); + if (!invite_to.empty()) + { + bridge->send_irc_invitation(iid, invite_to); + } + } + + } else if (iid.type == Iid::Type::User) this->send_invalid_user_error(to.local, from); } catch (const IRCNotConnected& ex) |