Skip to content

Commit

Permalink
feat: Leave room when a transcriber is detected on joining. (#580)
Browse files Browse the repository at this point in the history
* squash: reformat.

* feat: Leave room when a transcriber is detected on joining.
  • Loading branch information
damencho authored Jan 24, 2025
1 parent c77d7ca commit 995a8b2
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 19 deletions.
82 changes: 63 additions & 19 deletions src/main/java/org/jitsi/jigasi/JvbConference.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.disco.*;
import org.jivesoftware.smackx.disco.packet.*;
import org.jivesoftware.smackx.muc.filter.*;
import org.jivesoftware.smackx.muc.packet.*;
import org.jivesoftware.smackx.nick.packet.*;
import org.jivesoftware.smackx.xdata.packet.*;
Expand Down Expand Up @@ -447,6 +448,12 @@ private ExtensionElement addSupportedFeatures(
*/
private final VisitorsMessagesListener visitorsMessagesListener = new VisitorsMessagesListener();

/**
* The Presence listener we use to monitor the initial participants when joining. We need this only when in
* transcriber mode. To make sure there is a single transcriber in the room.
*/
private final ChatRoomPresenceListener presenceListener = new ChatRoomPresenceListener();

/**
* The features for the current xmpp provider we will use later adding to the room presence we send.
*/
Expand Down Expand Up @@ -964,35 +971,30 @@ public void joinConferenceRoom()

if (mucRoom instanceof ChatRoomJabberImpl)
{
ChatRoomJabberImpl chatRoom = (ChatRoomJabberImpl)mucRoom;

String displayName = gatewaySession.getMucDisplayName();
if (displayName != null)
{
((ChatRoomJabberImpl)mucRoom).addPresencePacketExtensions(
new Nick(displayName));
chatRoom.addPresencePacketExtensions(new Nick(displayName));
}
else
{
logger.error(this.callContext
+ " No display name to use...");
logger.error(this.callContext + " No display name to use...");
}

String region = JigasiBundleActivator.getConfigurationService()
.getString(LOCAL_REGION_PNAME);
String region = JigasiBundleActivator.getConfigurationService().getString(LOCAL_REGION_PNAME);
if (StringUtils.isNotEmpty(region))
{
JitsiParticipantRegionPacketExtension rpe = new JitsiParticipantRegionPacketExtension();
rpe.setRegionId(region);

((ChatRoomJabberImpl)mucRoom)
.addPresencePacketExtensions(rpe);
chatRoom.addPresencePacketExtensions(rpe);
}

((ChatRoomJabberImpl)mucRoom)
.addPresencePacketExtensions(
new ColibriStatsExtension.Stat(
ColibriStatsExtension.VERSION,
CurrentVersionImpl.VERSION.getApplicationName()
+ " " + CurrentVersionImpl.VERSION));
chatRoom.addPresencePacketExtensions(new ColibriStatsExtension.Stat(
ColibriStatsExtension.VERSION,
CurrentVersionImpl.VERSION.getApplicationName() + " " + CurrentVersionImpl.VERSION));

// creates an extension to hold all headers, as when using
// addPresencePacketExtensions it requires unique extensions
Expand All @@ -1011,15 +1013,22 @@ public void joinConferenceRoom()
});
if (!initiator.getChildExtensions().isEmpty())
{
((ChatRoomJabberImpl)mucRoom).addPresencePacketExtensions(initiator);
chatRoom.addPresencePacketExtensions(initiator);
}

((ChatRoomJabberImpl)mucRoom).addPresencePacketExtensions(this.features);
chatRoom.addPresencePacketExtensions(this.features);

if (this.isTranscriber)
{
getConnection().addAsyncStanzaListener(
presenceListener,
new AndFilter(
FromMatchesFilter.create(chatRoom.getIdentifierAsJid()), StanzaTypeFilter.PRESENCE));
}
}
else
{
logger.error(this.callContext
+ " Cannot set presence extensions as chatRoom "
logger.error(this.callContext + " Cannot set presence extensions as chatRoom "
+ "is not an instance of ChatRoomJabberImpl");
}

Expand Down Expand Up @@ -2803,4 +2812,39 @@ public void processStanza(Stanza stanza)

processVisitorsJson(jsonMsg.getJson());
}
}}
}

/**
* Listens for presence packets.
*/
private class ChatRoomPresenceListener
implements StanzaListener
{
/**
* Processes an incoming presence packet.
* @param packet the incoming packet.
*/
@Override
public void processStanza(Stanza packet)
{
if (!(packet instanceof Presence) || packet.getError() != null)
{
logger.warn("Unable to handle packet: " + packet);
return;
}

Presence presence = (Presence) packet;
if (MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF.accept(presence))
{
getConnection().removeAsyncStanzaListener(this);
}
else if (Util.isTranscriberJigasi(presence))
{
getConnection().removeAsyncStanzaListener(this);

logger.warn(callContext + " Detected another transcriber in the room, will leave!");
stop();
}
}
}
}
21 changes: 21 additions & 0 deletions src/main/java/org/jitsi/jigasi/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.jitsi.xmpp.extensions.jitsimeet.*;
import org.jivesoftware.smack.bosh.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.muc.packet.*;
import org.json.simple.*;
import org.json.simple.parser.*;

Expand Down Expand Up @@ -314,6 +315,26 @@ private static boolean checkForFeature(ChatRoomMemberJabberImpl member, String f
return features.getFeatureExtensions().stream().anyMatch(f -> f.getVar().equals(feature));
}

/**
* Checks for the transcriber feature in presence.
* @param presence the presence to check,
* @return <tt>true</tt> when the presence is from a transcriber.
*/
public static boolean isTranscriberJigasi(Presence presence)
{
FeaturesExtension features = presence.getExtension(FeaturesExtension.class);
MUCUser mucUser = (MUCUser) presence.getExtensionElement("x", "http://jabber.org/protocol/muc#user");

if (features == null || mucUser == null || mucUser.getItem() == null
|| !getTrustedDomains().contains(mucUser.getItem().getJid().asDomainBareJid().toString()))
{
return false;
}

return features.getFeatureExtensions().stream()
.anyMatch(f -> f.getVar().equals(TRANSCRIBER_FEATURE_NAME));
}

/**
* Checks for the transcriber feature in presence.
* @param member the member to check
Expand Down

0 comments on commit 995a8b2

Please sign in to comment.