@@ -1,5 +1,6 @@
|
|||||||
#include <bridge/bridge.hpp>
|
#include <bridge/bridge.hpp>
|
||||||
#include <bridge/colors.hpp>
|
#include <bridge/colors.hpp>
|
||||||
|
#include <bridge/list_element.hpp>
|
||||||
#include <xmpp/xmpp_component.hpp>
|
#include <xmpp/xmpp_component.hpp>
|
||||||
#include <xmpp/xmpp_stanza.hpp>
|
#include <xmpp/xmpp_stanza.hpp>
|
||||||
#include <irc/irc_message.hpp>
|
#include <irc/irc_message.hpp>
|
||||||
@@ -285,6 +286,43 @@ void Bridge::send_irc_nick_change(const Iid& iid, const std::string& new_nick)
|
|||||||
irc->send_nick_command(new_nick);
|
irc->send_nick_command(new_nick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bridge::send_irc_channel_list_request(const Iid& iid, const std::string& iq_id,
|
||||||
|
const std::string& to_jid)
|
||||||
|
{
|
||||||
|
IrcClient* irc = this->get_irc_client(iid.get_server());
|
||||||
|
|
||||||
|
if (!irc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
irc->send_list_command();
|
||||||
|
irc_responder_callback_t cb = [this, iid, iq_id, to_jid](const std::string& irc_hostname,
|
||||||
|
const IrcMessage& message) -> bool
|
||||||
|
{
|
||||||
|
static std::vector<ListElement> list;
|
||||||
|
|
||||||
|
if (irc_hostname != iid.get_server())
|
||||||
|
return false;
|
||||||
|
if (message.command == "263" || message.command == "RPL_TRYAGAIN")
|
||||||
|
{ // TODO send an error iq
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (message.command == "322" || message.command == "RPL_LIST")
|
||||||
|
{ // Add element to list
|
||||||
|
if (message.arguments.size() == 4)
|
||||||
|
list.emplace_back(message.arguments[1], message.arguments[2],
|
||||||
|
message.arguments[3]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (message.command == "323" || message.command == "RPL_LISTEND")
|
||||||
|
{ // Send the iq response with the content of the list
|
||||||
|
this->xmpp->send_iq_room_list_result(iq_id, to_jid, std::to_string(iid), list);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
this->add_waiting_irc(std::move(cb));
|
||||||
|
}
|
||||||
|
|
||||||
void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason,
|
void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason,
|
||||||
const std::string& iq_id, const std::string& to_jid)
|
const std::string& iq_id, const std::string& to_jid)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ public:
|
|||||||
void send_irc_version_request(const std::string& irc_hostname, const std::string& target,
|
void 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& iq_id, const std::string& to_jid,
|
||||||
const std::string& from_jid);
|
const std::string& from_jid);
|
||||||
|
void send_irc_channel_list_request(const Iid& iid, const std::string& iq_id,
|
||||||
|
const std::string& to_jid);
|
||||||
void forward_affiliation_role_change(const Iid& iid, const std::string& nick,
|
void forward_affiliation_role_change(const Iid& iid, const std::string& nick,
|
||||||
const std::string& affiliation, const std::string& role);
|
const std::string& affiliation, const std::string& role);
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef LIST_ELEMENT_HPP_INCLUDED
|
||||||
|
#define LIST_ELEMENT_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct ListElement
|
||||||
|
{
|
||||||
|
ListElement(const std::string& channel, const std::string& nb_users,
|
||||||
|
const std::string& topic):
|
||||||
|
channel(channel),
|
||||||
|
nb_users(nb_users),
|
||||||
|
topic(topic){}
|
||||||
|
|
||||||
|
std::string channel;
|
||||||
|
std::string nb_users;
|
||||||
|
std::string topic;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LIST_ELEMENT_HPP_INCLUDED */
|
||||||
@@ -196,6 +196,11 @@ void IrcClient::send_kick_command(const std::string& chan_name, const std::strin
|
|||||||
this->send_message(IrcMessage("KICK", {chan_name, target, reason}));
|
this->send_message(IrcMessage("KICK", {chan_name, target, reason}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IrcClient::send_list_command()
|
||||||
|
{
|
||||||
|
this->send_message(IrcMessage("LIST", {}));
|
||||||
|
}
|
||||||
|
|
||||||
void IrcClient::send_topic_command(const std::string& chan_name, const std::string& topic)
|
void IrcClient::send_topic_command(const std::string& chan_name, const std::string& topic)
|
||||||
{
|
{
|
||||||
this->send_message(IrcMessage("TOPIC", {chan_name, topic}));
|
this->send_message(IrcMessage("TOPIC", {chan_name, topic}));
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ public:
|
|||||||
* Send the KICK irc command
|
* Send the KICK irc command
|
||||||
*/
|
*/
|
||||||
void send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason);
|
void send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason);
|
||||||
|
/**
|
||||||
|
* Send the LIST irc command
|
||||||
|
*/
|
||||||
|
void send_list_command();
|
||||||
void send_topic_command(const std::string& chan_name, const std::string& topic);
|
void send_topic_command(const std::string& chan_name, const std::string& topic);
|
||||||
/**
|
/**
|
||||||
* Send the QUIT irc command
|
* Send the QUIT irc command
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <logger/logger.hpp>
|
#include <logger/logger.hpp>
|
||||||
|
|
||||||
#include <xmpp/xmpp_component.hpp>
|
#include <xmpp/xmpp_component.hpp>
|
||||||
|
#include <bridge/list_element.hpp>
|
||||||
#include <config/config.hpp>
|
#include <config/config.hpp>
|
||||||
#include <xmpp/jid.hpp>
|
#include <xmpp/jid.hpp>
|
||||||
#include <utils/sha1.hpp>
|
#include <utils/sha1.hpp>
|
||||||
@@ -556,12 +557,18 @@ void XmppComponent::handle_iq(const Stanza& stanza)
|
|||||||
}
|
}
|
||||||
else if ((query = stanza.get_child("query", DISCO_ITEMS_NS)))
|
else if ((query = stanza.get_child("query", DISCO_ITEMS_NS)))
|
||||||
{
|
{
|
||||||
|
Iid iid(to.local);
|
||||||
const std::string node = query->get_tag("node");
|
const std::string node = query->get_tag("node");
|
||||||
if (node == ADHOC_NS)
|
if (node == ADHOC_NS)
|
||||||
{
|
{
|
||||||
this->send_adhoc_commands_list(id, from);
|
this->send_adhoc_commands_list(id, from);
|
||||||
stanza_error.disable();
|
stanza_error.disable();
|
||||||
}
|
}
|
||||||
|
else if (node.empty() && !iid.is_user && !iid.is_channel)
|
||||||
|
{ // Disco on an IRC server: get the list of channels
|
||||||
|
bridge->send_irc_channel_list_request(iid, id, from);
|
||||||
|
stanza_error.disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ((query = stanza.get_child("ping", PING_NS)))
|
else if ((query = stanza.get_child("ping", PING_NS)))
|
||||||
{
|
{
|
||||||
@@ -1152,6 +1159,31 @@ void XmppComponent::send_iq_result(const std::string& id, const std::string& to_
|
|||||||
this->send_stanza(iq);
|
this->send_stanza(iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XmppComponent::send_iq_room_list_result(const std::string& id,
|
||||||
|
const std::string to_jid,
|
||||||
|
const std::string& from,
|
||||||
|
const std::vector<ListElement>& rooms_list)
|
||||||
|
{
|
||||||
|
Stanza iq("iq");
|
||||||
|
iq["from"] = from + "@" + this->served_hostname;
|
||||||
|
iq["to"] = to_jid;
|
||||||
|
iq["id"] = id;
|
||||||
|
iq["type"] = "result";
|
||||||
|
XmlNode query("query");
|
||||||
|
query["xmlns"] = DISCO_ITEMS_NS;
|
||||||
|
for (const auto& room: rooms_list)
|
||||||
|
{
|
||||||
|
XmlNode item("item");
|
||||||
|
item["jid"] = room.channel + "%" + from + "@" + this->served_hostname;
|
||||||
|
item.close();
|
||||||
|
query.add_child(std::move(item));
|
||||||
|
}
|
||||||
|
query.close();
|
||||||
|
iq.add_child(std::move(query));
|
||||||
|
iq.close();
|
||||||
|
this->send_stanza(iq);
|
||||||
|
}
|
||||||
|
|
||||||
std::string XmppComponent::next_id()
|
std::string XmppComponent::next_id()
|
||||||
{
|
{
|
||||||
char uuid_str[37];
|
char uuid_str[37];
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#define ADHOC_NS "http://jabber.org/protocol/commands"
|
#define ADHOC_NS "http://jabber.org/protocol/commands"
|
||||||
#define PING_NS "urn:xmpp:ping"
|
#define PING_NS "urn:xmpp:ping"
|
||||||
|
|
||||||
|
class ListElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback called when the waited iq result is received (it is matched
|
* A callback called when the waited iq result is received (it is matched
|
||||||
* against the iq id)
|
* against the iq id)
|
||||||
@@ -228,6 +230,12 @@ public:
|
|||||||
* Send an empty iq of type result
|
* Send an empty iq of type result
|
||||||
*/
|
*/
|
||||||
void send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from);
|
void send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from);
|
||||||
|
/**
|
||||||
|
* Send the channels list in one big stanza
|
||||||
|
*/
|
||||||
|
void send_iq_room_list_result(const std::string& id, const std::string to_jid,
|
||||||
|
const std::string& from,
|
||||||
|
const std::vector<ListElement>& rooms_list);
|
||||||
/**
|
/**
|
||||||
* Handle the various stanza types
|
* Handle the various stanza types
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user