aboutsummaryrefslogtreecommitdiff
path: root/libdino/src/service
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2020-08-14 16:42:56 +0200
committerfiaxh <git@lightrise.org>2020-08-31 16:48:20 +0200
commite6a90fc25c19b4cfceff7b1d89c58927753ee98d (patch)
treeccdf16576088c7734e4ca0ec554a285d3ff0bf7f /libdino/src/service
parentff9a9a0d667694cc9254db832655bddfbcabc909 (diff)
downloaddino-e6a90fc25c19b4cfceff7b1d89c58927753ee98d.tar.gz
dino-e6a90fc25c19b4cfceff7b1d89c58927753ee98d.zip
Implement MUC self ping
Diffstat (limited to 'libdino/src/service')
-rw-r--r--libdino/src/service/muc_manager.vala47
-rw-r--r--libdino/src/service/stream_interactor.vala3
2 files changed, 48 insertions, 2 deletions
diff --git a/libdino/src/service/muc_manager.vala b/libdino/src/service/muc_manager.vala
index 94536ba2..8eba524d 100644
--- a/libdino/src/service/muc_manager.vala
+++ b/libdino/src/service/muc_manager.vala
@@ -21,7 +21,8 @@ public class MucManager : StreamInteractionModule, Object {
public signal void conference_removed(Account account, Jid jid);
private StreamInteractor stream_interactor;
- private HashMap<Account, Gee.List<Jid>> mucs_joining = new HashMap<Account, ArrayList<Jid>>(Account.hash_func, Account.equals_func);
+ private HashMap<Account, HashSet<Jid>> mucs_todo = new HashMap<Account, HashSet<Jid>>(Account.hash_func, Account.equals_func);
+ private HashMap<Account, HashSet<Jid>> mucs_joining = new HashMap<Account, HashSet<Jid>>(Account.hash_func, Account.equals_func);
private HashMap<Jid, Xep.Muc.MucEnterError> enter_errors = new HashMap<Jid, Xep.Muc.MucEnterError>(Jid.hash_func, Jid.equals_func);
private ReceivedMessageListener received_message_listener;
private HashMap<Account, BookmarksProvider> bookmarks_provider = new HashMap<Account, BookmarksProvider>(Account.hash_func, Account.equals_func);
@@ -42,6 +43,13 @@ public class MucManager : StreamInteractionModule, Object {
part(conversation.account, conversation.counterpart);
}
});
+ stream_interactor.stream_resumed.connect((account, stream) => self_ping(account));
+ Timeout.add_seconds(60 * 3, () => {
+ foreach (Account account in stream_interactor.get_accounts()) {
+ self_ping(account);
+ }
+ return true;
+ });
}
public async Muc.JoinResult? join(Account account, Jid jid, string? nick, string? password) {
@@ -58,10 +66,15 @@ public class MucManager : StreamInteractionModule, Object {
}
if (!mucs_joining.has_key(account)) {
- mucs_joining[account] = new ArrayList<Jid>(Jid.equals_bare_func);
+ mucs_joining[account] = new HashSet<Jid>(Jid.hash_bare_func, Jid.equals_bare_func);
}
mucs_joining[account].add(jid);
+ if (!mucs_todo.has_key(account)) {
+ mucs_todo[account] = new HashSet<Jid>(Jid.hash_bare_func, Jid.equals_bare_func);
+ }
+ mucs_todo[account].add(jid.with_resource(nick_));
+
Muc.JoinResult? res = yield stream.get_module(Xep.Muc.Module.IDENTITY).enter(stream, jid.bare_jid, nick_, password, history_since);
mucs_joining[account].remove(jid);
@@ -84,6 +97,8 @@ public class MucManager : StreamInteractionModule, Object {
}
public void part(Account account, Jid jid) {
+ mucs_todo[account].remove(jid);
+
XmppStream? stream = stream_interactor.get_stream(account);
if (stream == null) return;
unset_autojoin(account, stream, jid);
@@ -123,6 +138,11 @@ public class MucManager : StreamInteractionModule, Object {
conversation.nickname = new_nick;
+ if (mucs_todo.has_key(conversation.account)) {
+ mucs_todo[conversation.account].remove(conversation.counterpart);
+ mucs_todo[conversation.account].add(conversation.counterpart.with_resource(new_nick));
+ }
+
// Update nick in bookmark
Set<Conference>? conferences = yield bookmarks_provider[conversation.account].get_conferences(stream);
if (conferences == null) return;
@@ -466,6 +486,29 @@ public class MucManager : StreamInteractionModule, Object {
});
}
+ private void self_ping(Account account) {
+ XmppStream? stream = stream_interactor.get_stream(account);
+ if (stream == null) return;
+
+ if (!mucs_todo.has_key(account)) return;
+
+ foreach (Jid jid in mucs_todo[account]) {
+
+ bool joined = false;
+
+ Xmpp.Xep.MucSelfPing.is_joined.begin(stream, jid, (_, res) => {
+ joined = Xmpp.Xep.MucSelfPing.is_joined.end(res);
+ });
+
+ Timeout.add_seconds(10, () => {
+ if (joined || !mucs_todo.has_key(account) || stream_interactor.get_stream(account) != stream) return false;
+
+ join.begin(account, jid.bare_jid, jid.resourcepart, null);
+ return false;
+ });
+ }
+ }
+
private class ReceivedMessageListener : MessageListener {
public string[] after_actions_const = new string[]{ };
diff --git a/libdino/src/service/stream_interactor.vala b/libdino/src/service/stream_interactor.vala
index db6d58d8..e60a43d6 100644
--- a/libdino/src/service/stream_interactor.vala
+++ b/libdino/src/service/stream_interactor.vala
@@ -9,6 +9,7 @@ public class StreamInteractor : Object {
public signal void account_added(Account account);
public signal void account_removed(Account account);
+ public signal void stream_resumed(Account account, XmppStream stream);
public signal void stream_negotiated(Account account, XmppStream stream);
public signal void attached_modules(Account account, XmppStream stream);
@@ -70,6 +71,8 @@ public class StreamInteractor : Object {
var flag = stream.get_flag(Xep.StreamManagement.Flag.IDENTITY);
if (flag == null || flag.resumed == false) {
stream_negotiated(account, stream);
+ } else if (flag != null && flag.resumed == true) {
+ stream_resumed(account, stream);
}
});
}