Implement MUC self ping
This commit is contained in:
parent
ff9a9a0d66
commit
e6a90fc25c
|
@ -21,7 +21,8 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
public signal void conference_removed(Account account, Jid jid);
|
public signal void conference_removed(Account account, Jid jid);
|
||||||
|
|
||||||
private StreamInteractor stream_interactor;
|
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 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 ReceivedMessageListener received_message_listener;
|
||||||
private HashMap<Account, BookmarksProvider> bookmarks_provider = new HashMap<Account, BookmarksProvider>(Account.hash_func, Account.equals_func);
|
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);
|
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) {
|
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)) {
|
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);
|
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);
|
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);
|
mucs_joining[account].remove(jid);
|
||||||
|
@ -84,6 +97,8 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void part(Account account, Jid jid) {
|
public void part(Account account, Jid jid) {
|
||||||
|
mucs_todo[account].remove(jid);
|
||||||
|
|
||||||
XmppStream? stream = stream_interactor.get_stream(account);
|
XmppStream? stream = stream_interactor.get_stream(account);
|
||||||
if (stream == null) return;
|
if (stream == null) return;
|
||||||
unset_autojoin(account, stream, jid);
|
unset_autojoin(account, stream, jid);
|
||||||
|
@ -123,6 +138,11 @@ public class MucManager : StreamInteractionModule, Object {
|
||||||
|
|
||||||
conversation.nickname = new_nick;
|
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
|
// Update nick in bookmark
|
||||||
Set<Conference>? conferences = yield bookmarks_provider[conversation.account].get_conferences(stream);
|
Set<Conference>? conferences = yield bookmarks_provider[conversation.account].get_conferences(stream);
|
||||||
if (conferences == null) return;
|
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 {
|
private class ReceivedMessageListener : MessageListener {
|
||||||
|
|
||||||
public string[] after_actions_const = new string[]{ };
|
public string[] after_actions_const = new string[]{ };
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class StreamInteractor : Object {
|
||||||
|
|
||||||
public signal void account_added(Account account);
|
public signal void account_added(Account account);
|
||||||
public signal void account_removed(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 stream_negotiated(Account account, XmppStream stream);
|
||||||
public signal void attached_modules(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);
|
var flag = stream.get_flag(Xep.StreamManagement.Flag.IDENTITY);
|
||||||
if (flag == null || flag.resumed == false) {
|
if (flag == null || flag.resumed == false) {
|
||||||
stream_negotiated(account, stream);
|
stream_negotiated(account, stream);
|
||||||
|
} else if (flag != null && flag.resumed == true) {
|
||||||
|
stream_resumed(account, stream);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ SOURCES
|
||||||
"src/module/xep/0368_srv_records_tls.vala"
|
"src/module/xep/0368_srv_records_tls.vala"
|
||||||
"src/module/xep/0380_explicit_encryption.vala"
|
"src/module/xep/0380_explicit_encryption.vala"
|
||||||
"src/module/xep/0391_jingle_encrypted_transports.vala"
|
"src/module/xep/0391_jingle_encrypted_transports.vala"
|
||||||
|
"src/module/xep/0410_muc_self_ping.vala"
|
||||||
"src/module/xep/pixbuf_storage.vala"
|
"src/module/xep/pixbuf_storage.vala"
|
||||||
|
|
||||||
"src/util.vala"
|
"src/util.vala"
|
||||||
|
|
|
@ -6,10 +6,10 @@ namespace Xmpp.Xep.Ping {
|
||||||
public class Module : XmppStreamModule, Iq.Handler {
|
public class Module : XmppStreamModule, Iq.Handler {
|
||||||
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0199_ping");
|
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0199_ping");
|
||||||
|
|
||||||
public async void send_ping(XmppStream stream, Jid jid) {
|
public async Iq.Stanza send_ping(XmppStream stream, Jid jid) {
|
||||||
StanzaNode ping_node = new StanzaNode.build("ping", NS_URI).add_self_xmlns();
|
StanzaNode ping_node = new StanzaNode.build("ping", NS_URI).add_self_xmlns();
|
||||||
Iq.Stanza iq = new Iq.Stanza.get(ping_node) { to=jid };
|
Iq.Stanza iq = new Iq.Stanza.get(ping_node) { to=jid };
|
||||||
yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq);
|
return yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void attach(XmppStream stream) {
|
public override void attach(XmppStream stream) {
|
||||||
|
|
18
xmpp-vala/src/module/xep/0410_muc_self_ping.vala
Normal file
18
xmpp-vala/src/module/xep/0410_muc_self_ping.vala
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Xmpp.Xep.MucSelfPing {
|
||||||
|
|
||||||
|
public static async bool is_joined(XmppStream stream, Jid jid) {
|
||||||
|
Iq.Stanza iq_result = yield stream.get_module(Xmpp.Xep.Ping.Module.IDENTITY).send_ping(stream, jid);
|
||||||
|
|
||||||
|
if (!iq_result.is_error()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
var error_stanza = iq_result.get_error();
|
||||||
|
if (error_stanza.condition in new string[] {ErrorStanza.CONDITION_SERVICE_UNAVAILABLE, ErrorStanza.CONDITION_FEATURE_NOT_IMPLEMENTED}) {
|
||||||
|
// the client is joined, but the pinged client does not implement XMPP Ping
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue