# HG changeset patch # User Goffi # Date 1563307170 -7200 # Node ID c8c68a3b0a7971f9fb979ae8e6526e4130fbeb9f # Parent 4208974880807c817dec4a53c5426965d6bac321 plugins XEP-0045, XEP-0198: rejoin MUC rooms while a hot reconnection is done: when resuming is not possible with stream management, a hot reconnection is done (reconnecting without restarting every plugin). This was causing trouble for joined MUC rooms, which were not accessible anymore (because they were not re-joined). This patch fixes it by clearing rooms first (to avoid considering the room joined and broadcasting the initial presence to them), then re-joining them. fix 322 diff -r 420897488080 -r c8c68a3b0a79 sat/plugins/plugin_xep_0045.py --- a/sat/plugins/plugin_xep_0045.py Mon Jul 15 22:36:28 2019 +0200 +++ b/sat/plugins/plugin_xep_0045.py Tue Jul 16 21:59:30 2019 +0200 @@ -496,6 +496,19 @@ errbackArgs=(client, room_jid, nick, password)) return d + def popRooms(self, client): + """Remove rooms and return data needed to re-join them + + This methods is to be called before a hot reconnection + @return (list[(jid.JID, unicode)]): arguments needed to re-join the rooms + This list can be used directly (unpacked) with self.join + """ + args_list = [] + for room in client._muc_client.joined_rooms.values(): + client._muc_client._removeRoom(room.roomJID) + args_list.append((client, room.roomJID, room.nick)) + return args_list + def _nick(self, room_jid_s, nick, profile_key=C.PROF_KEY_NONE): client = self.host.getClient(profile_key) return self.nick(client, jid.JID(room_jid_s), nick) @@ -785,7 +798,8 @@ whois_msg.append(_("Show: %s") % user.show) def presenceTrigger(self, presence_elt, client): - # XXX: shouldn't it be done by the server ?!! + # FIXME: should we add a privacy parameters in settings to activate before + # broadcasting the presence to all MUC rooms ? muc_client = client._muc_client for room_jid, room in muc_client.joined_rooms.iteritems(): elt = xml_tools.elementCopy(presence_elt) diff -r 420897488080 -r c8c68a3b0a79 sat/plugins/plugin_xep_0198.py --- a/sat/plugins/plugin_xep_0198.py Mon Jul 15 22:36:28 2019 +0200 +++ b/sat/plugins/plugin_xep_0198.py Tue Jul 16 21:59:30 2019 +0200 @@ -35,14 +35,15 @@ log = getLogger(__name__) PLUGIN_INFO = { - C.PI_NAME: "Stream Management", - C.PI_IMPORT_NAME: "XEP-0198", - C.PI_TYPE: "XEP", + C.PI_NAME: u"Stream Management", + C.PI_IMPORT_NAME: u"XEP-0198", + C.PI_TYPE: u"XEP", C.PI_MODES: C.PLUG_MODE_BOTH, - C.PI_PROTOCOLS: ["XEP-0198"], + C.PI_PROTOCOLS: [u"XEP-0198"], C.PI_DEPENDENCIES: [], - C.PI_MAIN: "XEP_0198", - C.PI_HANDLER: "yes", + C.PI_RECOMMENDATIONS: [u"XEP-0045"], + C.PI_MAIN: u"XEP_0198", + C.PI_HANDLER: u"yes", C.PI_DESCRIPTION: _(u"""Implementation of Stream Management"""), } @@ -394,6 +395,10 @@ client.conn_deferred = defer.Deferred() else: log.error(u"conn_deferred should be called at this point") + plg_0045 = self.host.plugins.get(u'XEP-0045') + if plg_0045 is not None: + # we have to remove joined rooms + muc_join_args = plg_0045.popRooms(client) # we need to recreate roster client.handlers.remove(client.roster) client.roster = client.roster.__class__(self.host) @@ -412,6 +417,10 @@ d.addCallback(lambda __: client.roster.got_roster) # initial presence must be sent manually d.addCallback(lambda __: client.presence.available()) + if plg_0045 is not None: + muc_d_list = defer.DeferredList( + [plg_0045.join(*args) for args in muc_join_args]) + d.addCallback(lambda __: muc_d_list) def onReceive(self, element, client): if not client.is_component: @@ -437,7 +446,7 @@ session.ack_requested = False if self._ack_timeout: if session.req_timer is None: - log.error("reg_timer should be set") + log.error("req_timer should be set") else: session.req_timer.cancel() session.req_timer = None