From 1a439b7df816a141eb9bafc36b6653eba01ca476 Mon Sep 17 00:00:00 2001 From: damencho Date: Thu, 16 Jan 2025 12:03:58 -0600 Subject: [PATCH 1/2] squash: reformat. --- .../java/org/jitsi/jigasi/JvbConference.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jitsi/jigasi/JvbConference.java b/src/main/java/org/jitsi/jigasi/JvbConference.java index ff78c5e6..d15ea19a 100644 --- a/src/main/java/org/jitsi/jigasi/JvbConference.java +++ b/src/main/java/org/jitsi/jigasi/JvbConference.java @@ -976,23 +976,18 @@ public void joinConferenceRoom() + " 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); + ((ChatRoomJabberImpl)mucRoom).addPresencePacketExtensions(rpe); } - ((ChatRoomJabberImpl)mucRoom) - .addPresencePacketExtensions( - new ColibriStatsExtension.Stat( - ColibriStatsExtension.VERSION, - CurrentVersionImpl.VERSION.getApplicationName() - + " " + CurrentVersionImpl.VERSION)); + ((ChatRoomJabberImpl)mucRoom).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 @@ -1018,8 +1013,7 @@ public void joinConferenceRoom() } 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"); } From 5443c19511e40e03df8c3afa2914ff153375b777 Mon Sep 17 00:00:00 2001 From: damencho Date: Thu, 16 Jan 2025 13:12:57 -0600 Subject: [PATCH 2/2] feat: Leave room when a transcriber is detected on joining. --- .../java/org/jitsi/jigasi/JvbConference.java | 68 ++++++++++++++++--- src/main/java/org/jitsi/jigasi/util/Util.java | 21 ++++++ 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/jitsi/jigasi/JvbConference.java b/src/main/java/org/jitsi/jigasi/JvbConference.java index d15ea19a..3ed6d68a 100644 --- a/src/main/java/org/jitsi/jigasi/JvbConference.java +++ b/src/main/java/org/jitsi/jigasi/JvbConference.java @@ -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.*; @@ -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. */ @@ -964,16 +971,16 @@ 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); @@ -982,10 +989,10 @@ public void joinConferenceRoom() JitsiParticipantRegionPacketExtension rpe = new JitsiParticipantRegionPacketExtension(); rpe.setRegionId(region); - ((ChatRoomJabberImpl)mucRoom).addPresencePacketExtensions(rpe); + chatRoom.addPresencePacketExtensions(rpe); } - ((ChatRoomJabberImpl)mucRoom).addPresencePacketExtensions(new ColibriStatsExtension.Stat( + chatRoom.addPresencePacketExtensions(new ColibriStatsExtension.Stat( ColibriStatsExtension.VERSION, CurrentVersionImpl.VERSION.getApplicationName() + " " + CurrentVersionImpl.VERSION)); @@ -1006,10 +1013,18 @@ 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 { @@ -2797,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(); + } + } + } +} diff --git a/src/main/java/org/jitsi/jigasi/util/Util.java b/src/main/java/org/jitsi/jigasi/util/Util.java index ee7aa103..b2bbc696 100644 --- a/src/main/java/org/jitsi/jigasi/util/Util.java +++ b/src/main/java/org/jitsi/jigasi/util/Util.java @@ -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.*; @@ -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 true 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