Use a db roster to manage biboumi’s presence with the contacts
This commit is contained in:
@@ -83,6 +83,15 @@ void BiboumiComponent::shutdown()
|
||||
{
|
||||
for (auto& pair: this->bridges)
|
||||
pair.second->shutdown("Gateway shutdown");
|
||||
#ifdef USE_DATABASE
|
||||
const auto full_roster = Database::get_full_roster();
|
||||
for (const Database::RosterItem& roster_item: full_roster)
|
||||
{
|
||||
this->send_presence_to_contact(roster_item.col<Database::LocalJid>(),
|
||||
roster_item.col<Database::RemoteJid>(),
|
||||
"unavailable");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BiboumiComponent::clean()
|
||||
@@ -160,10 +169,28 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
|
||||
{
|
||||
if (type == "subscribe")
|
||||
{ // Auto-accept any subscription request for an IRC server
|
||||
this->accept_subscription(to_str, from.bare());
|
||||
this->ask_subscription(to_str, from.bare());
|
||||
this->send_presence_to_contact(to_str, from.bare(), "subscribed", id);
|
||||
if (iid.type == Iid::Type::None)
|
||||
this->send_presence_to_contact(to_str, from.bare(), "");
|
||||
this->send_presence_to_contact(to_str, from.bare(), "subscribe");
|
||||
#ifdef USE_DATABASE
|
||||
if (!Database::has_roster_item(to_str, from.bare()))
|
||||
Database::add_roster_item(to_str, from.bare());
|
||||
#endif
|
||||
}
|
||||
else if (type == "unsubscribe")
|
||||
{
|
||||
#ifdef USE_DATABASE
|
||||
const bool res = Database::has_roster_item(to_str, from.bare());
|
||||
if (res)
|
||||
Database::delete_roster_item(to_str, from.bare());
|
||||
#endif
|
||||
}
|
||||
else if (type.empty())
|
||||
{ // We just receive a presence from someone (as the result of a probe,
|
||||
// or a directed presence, or a normal presence change)
|
||||
this->send_presence_to_contact(to_str, from.bare(), "");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -979,3 +1006,31 @@ void BiboumiComponent::ask_subscription(const std::string& from, const std::stri
|
||||
presence["type"] = "subscribe";
|
||||
this->send_stanza(presence);
|
||||
}
|
||||
|
||||
void BiboumiComponent::send_presence_to_contact(const std::string& from, const std::string& to,
|
||||
const std::string& type, const std::string& id)
|
||||
{
|
||||
Stanza presence("presence");
|
||||
presence["from"] = from;
|
||||
presence["to"] = to;
|
||||
if (!type.empty())
|
||||
presence["type"] = type;
|
||||
if (!id.empty())
|
||||
presence["id"] = id;
|
||||
this->send_stanza(presence);
|
||||
}
|
||||
|
||||
void BiboumiComponent::after_handshake()
|
||||
{
|
||||
XmppComponent::after_handshake();
|
||||
|
||||
#ifdef USE_DATABASE
|
||||
const auto contacts = Database::get_contact_list(this->get_served_hostname());
|
||||
|
||||
for (const Database::RosterItem& roster_item: contacts)
|
||||
{
|
||||
const auto remote_jid = roster_item.col<Database::RemoteJid>();
|
||||
this->send_presence_to_contact(this->get_served_hostname(), remote_jid, "probe");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ public:
|
||||
BiboumiComponent& operator=(const BiboumiComponent&) = delete;
|
||||
BiboumiComponent& operator=(BiboumiComponent&&) = delete;
|
||||
|
||||
void after_handshake() override final;
|
||||
|
||||
/**
|
||||
* Returns the bridge for the given user. If it does not exist, return
|
||||
* nullptr.
|
||||
@@ -87,6 +89,7 @@ public:
|
||||
void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick);
|
||||
void accept_subscription(const std::string& from, const std::string& to);
|
||||
void ask_subscription(const std::string& from, const std::string& to);
|
||||
void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id="");
|
||||
/**
|
||||
* Handle the various stanza types
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user