summaryrefslogtreecommitdiff
path: root/src/bridge
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2018-08-26 17:39:16 +0200
committerlouiz’ <louiz@louiz.org>2018-09-29 20:04:42 +0200
commite560352fcf95ba70891d1a847973160c923fb702 (patch)
tree714c34103ba77be51e03ba912e8b503a5ce2205f /src/bridge
parentbf97478b89b24bbf3a6a92c9137041cf2e987f02 (diff)
downloadbiboumi-e560352fcf95ba70891d1a847973160c923fb702.tar.gz
biboumi-e560352fcf95ba70891d1a847973160c923fb702.tar.bz2
biboumi-e560352fcf95ba70891d1a847973160c923fb702.tar.xz
biboumi-e560352fcf95ba70891d1a847973160c923fb702.zip
Force connect to a server when a presence is received on a server JID
Diffstat (limited to 'src/bridge')
-rw-r--r--src/bridge/bridge.cpp55
-rw-r--r--src/bridge/bridge.hpp3
2 files changed, 57 insertions, 1 deletions
diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp
index cc2ef66..24959d1 100644
--- a/src/bridge/bridge.cpp
+++ b/src/bridge/bridge.cpp
@@ -569,6 +569,57 @@ void Bridge::send_irc_channel_list_request(const Iid& iid, const std::string& iq
}
}
+void Bridge::force_connect_to_server(const std::string& hostname, const std::string& resource)
+{
+ auto soptions = Database::get_irc_server_options(this->get_bare_jid(), hostname);
+ const auto& nickname = soptions.col<Database::Nick>();
+ IrcClient* irc = nullptr;
+ if (nickname.empty())
+ {
+ irc = this->find_irc_client(hostname);
+ if (!irc)
+ return;
+ }
+ else
+ {
+ irc = this->make_irc_client(hostname, nickname);
+ this->add_resource_to_server(hostname, resource);
+ irc->start();
+ }
+ auto result = this->force_connected_resources.insert(std::make_pair(irc, std::set<Resource>{resource}));
+ const bool& inserted = result.second;
+ if (!inserted)
+ {
+ auto& it = result.first;
+ std::set<Resource>& resources = it->second;
+ resources.insert(resource);
+ }
+}
+
+void Bridge::unforce_connect_to_server(const std::string& hostname, const std::string& resource)
+{
+ IrcClient* irc = this->find_irc_client(hostname);
+ if (!irc)
+ return;
+ auto server_it = this->force_connected_resources.find(irc);
+ if (server_it == this->force_connected_resources.end())
+ return;
+ std::set<Resource>& forced_resources = server_it->second;
+ auto resource_it = forced_resources.find(resource);
+ if (resource_it == forced_resources.end())
+ return;
+ forced_resources.erase(resource_it);
+ if (forced_resources.empty())
+ {
+ this->force_connected_resources.erase(server_it);
+ irc->send_quit_command("");
+ }
+ else
+ {
+ this->remove_resource_from_server(hostname, resource);
+ }
+}
+
bool Bridge::send_matching_channel_list(const ChannelList& channel_list, const ResultSetInfo& rs_info,
const std::string& id, const std::string& to_jid, const std::string& from)
{
@@ -902,7 +953,9 @@ void Bridge::send_muc_leave(const Iid& iid, const IrcUser& user,
}
}
IrcClient* irc = this->find_irc_client(iid.get_server());
- if (self && irc && irc->number_of_joined_channels() == 0)
+ auto forced_resources = this->force_connected_resources.find(irc);
+ const bool force_connected = forced_resources != this->force_connected_resources.end() && !forced_resources->second.empty();
+ if (self && irc && irc->number_of_joined_channels() == 0 && !force_connected)
irc->send_quit_command("");
}
diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp
index 5c547ff..a1934bb 100644
--- a/src/bridge/bridge.hpp
+++ b/src/bridge/bridge.hpp
@@ -97,6 +97,8 @@ public:
const std::string& from_jid);
void send_irc_channel_list_request(const Iid& iid, const std::string& iq_id, const std::string& to_jid,
ResultSetInfo rs_info);
+ void force_connect_to_server(const std::string& hostname, const std::string& resource);
+ void unforce_connect_to_server(const std::string& hostname, const std::string& resource);
/**
* Check if the channel list contains what is needed to answer the RSM request,
* if it does, send the iq result. If the list is complete but does not contain
@@ -310,6 +312,7 @@ private:
public:
std::map<ChannelKey, std::set<Resource>> resources_in_chan;
std::map<IrcHostname, std::set<Resource>> resources_in_server;
+ std::map<const IrcClient*, std::set<Resource>> force_connected_resources;
private:
/**
* Manage which resource is in which channel