1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-25 05:22:06 +01:00

[muc] Do not filter for presence ID if #stable_id is not announced

On leave(), do not filter for presence ID if the MUC service does not
announce #stable_id.
This commit is contained in:
Florian Schmaus 2021-03-12 22:26:36 +01:00
parent 61cb73ee37
commit 9d1b88a877
3 changed files with 42 additions and 21 deletions

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2003-2007 Jive Software. 2020 Florian Schmaus * Copyright 2003-2007 Jive Software. 2020-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -149,6 +149,8 @@ public class MultiUserChat {
private EntityFullJid myRoomJid; private EntityFullJid myRoomJid;
private StanzaCollector messageCollector; private StanzaCollector messageCollector;
private DiscoverInfo mucServiceDiscoInfo;
/** /**
* Used to signal that the reflected self-presence was received <b>and</b> processed by us. * Used to signal that the reflected self-presence was received <b>and</b> processed by us.
*/ */
@ -342,7 +344,8 @@ public class MultiUserChat {
private Presence enter(MucEnterConfiguration conf) throws NotConnectedException, NoResponseException, private Presence enter(MucEnterConfiguration conf) throws NotConnectedException, NoResponseException,
XMPPErrorException, InterruptedException, NotAMucServiceException { XMPPErrorException, InterruptedException, NotAMucServiceException {
final DomainBareJid mucService = room.asDomainBareJid(); final DomainBareJid mucService = room.asDomainBareJid();
if (!multiUserChatManager.providesMucService(mucService)) { mucServiceDiscoInfo = multiUserChatManager.getMucServiceDiscoInfo(mucService);
if (mucServiceDiscoInfo == null) {
throw new NotAMucServiceException(this); throw new NotAMucServiceException(this);
} }
// We enter a room by sending a presence packet where the "to" // We enter a room by sending a presence packet where the "to"
@ -757,6 +760,10 @@ public class MultiUserChat {
throw new MucNotJoinedException(this); throw new MucNotJoinedException(this);
} }
// TODO: Consider adding a origin-id to the presence, once it is moved form smack-experimental into
// smack-extensions, in case the MUC service does not support stable IDs, and modify
// reflectedLeavePresenceFilters accordingly.
// We leave a room by sending a presence packet where the "to" // We leave a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname" // field is in the form "roomName@service/nickname"
Presence leavePresence = connection.getStanzaFactory().buildPresenceStanza() Presence leavePresence = connection.getStanzaFactory().buildPresenceStanza()
@ -764,14 +771,19 @@ public class MultiUserChat {
.to(myRoomJid) .to(myRoomJid)
.build(); .build();
StanzaFilter reflectedLeavePresenceFilter = new AndFilter( List<StanzaFilter> reflectedLeavePresenceFilters = new ArrayList<>(3);
StanzaTypeFilter.PRESENCE, reflectedLeavePresenceFilters.add(StanzaTypeFilter.PRESENCE);
new StanzaIdFilter(leavePresence), reflectedLeavePresenceFilters.add(new OrFilter(
new OrFilter( new AndFilter(FromMatchesFilter.createFull(myRoomJid), PresenceTypeFilter.UNAVAILABLE,
new AndFilter(FromMatchesFilter.createFull(myRoomJid), PresenceTypeFilter.UNAVAILABLE, MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF), MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF),
new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR) new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR)));
)
); boolean supportsStableId = mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE);
if (supportsStableId) {
reflectedLeavePresenceFilters.add(new StanzaIdFilter(leavePresence));
}
StanzaFilter reflectedLeavePresenceFilter = new AndFilter(reflectedLeavePresenceFilters);
// Reset occupant information first so that we are assume that we left the room even if sendStanza() would // Reset occupant information first so that we are assume that we left the room even if sendStanza() would
// throw. // throw.

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus * Copyright 2020-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,4 +20,6 @@ public class MultiUserChatConstants {
public static final String NAMESPACE = "http://jabber.org/protocol/muc"; public static final String NAMESPACE = "http://jabber.org/protocol/muc";
public static final String STABLE_ID_FEATURE = NAMESPACE + "#stable_id";
} }

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright © 2014-2020 Florian Schmaus * Copyright © 2014-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -137,7 +137,7 @@ public final class MultiUserChatManager extends Manager {
private static final StanzaFilter INVITATION_FILTER = new AndFilter(StanzaTypeFilter.MESSAGE, new StanzaExtensionFilter(new MUCUser()), private static final StanzaFilter INVITATION_FILTER = new AndFilter(StanzaTypeFilter.MESSAGE, new StanzaExtensionFilter(new MUCUser()),
new NotFilter(MessageTypeFilter.ERROR)); new NotFilter(MessageTypeFilter.ERROR));
private static final ExpirationCache<DomainBareJid, Void> KNOWN_MUC_SERVICES = new ExpirationCache<>( private static final ExpirationCache<DomainBareJid, DiscoverInfo> KNOWN_MUC_SERVICES = new ExpirationCache<>(
100, 1000 * 60 * 60 * 24); 100, 1000 * 60 * 60 * 24);
private final Set<InvitationListener> invitationsListeners = new CopyOnWriteArraySet<InvitationListener>(); private final Set<InvitationListener> invitationsListeners = new CopyOnWriteArraySet<InvitationListener>();
@ -396,16 +396,23 @@ public final class MultiUserChatManager extends Manager {
*/ */
public boolean providesMucService(DomainBareJid domainBareJid) throws NoResponseException, public boolean providesMucService(DomainBareJid domainBareJid) throws NoResponseException,
XMPPErrorException, NotConnectedException, InterruptedException { XMPPErrorException, NotConnectedException, InterruptedException {
boolean contains = KNOWN_MUC_SERVICES.containsKey(domainBareJid); return getMucServiceDiscoInfo(domainBareJid) != null;
if (!contains) { }
if (serviceDiscoveryManager.supportsFeature(domainBareJid,
MUCInitialPresence.NAMESPACE)) { DiscoverInfo getMucServiceDiscoInfo(DomainBareJid mucServiceAddress)
KNOWN_MUC_SERVICES.put(domainBareJid, null); throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return true; DiscoverInfo discoInfo = KNOWN_MUC_SERVICES.get(mucServiceAddress);
} if (discoInfo != null) {
return discoInfo;
} }
return contains; discoInfo = serviceDiscoveryManager.discoverInfo(mucServiceAddress);
if (!discoInfo.containsFeature(MUCInitialPresence.NAMESPACE)) {
return null;
}
KNOWN_MUC_SERVICES.put(mucServiceAddress, discoInfo);
return discoInfo;
} }
/** /**