diff --git a/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoom.kt b/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoom.kt index 76af1b6066..9e786a6111 100644 --- a/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoom.kt +++ b/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoom.kt @@ -55,6 +55,13 @@ interface ChatRoom { /** Whether a lobby is enabled for the room. Read from the MUC config form. */ val lobbyEnabled: Boolean + /** Whether the visitors feature is enabled for the room. Read from the MUC config form. */ + val visitorsEnabled: Boolean? + + /** The number of participants in the room after which new endpoints should be redirected to visitors. + * Read from the MUC config form. */ + val participantsSoftLimit: Int? + val debugState: OrderedJsonObject /** Returns the number of members that currently have their audio sources unmuted. */ diff --git a/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoomImpl.kt b/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoomImpl.kt index 71668a6356..855cafd31f 100644 --- a/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoomImpl.kt +++ b/jicofo-common/src/main/kotlin/org/jitsi/jicofo/xmpp/muc/ChatRoomImpl.kt @@ -140,6 +140,22 @@ class ChatRoomImpl( } } + override var visitorsEnabled: Boolean? = null + private set(value) { + if (value != field) { + logger.info("Visitors is now: $value") + field = value + } + } + + override var participantsSoftLimit: Int? = null + private set(value) { + if (value != field) { + logger.info("ParticipantsSoftLimit is now $value.") + field = value + } + } + private val avModerationByMediaType = ConcurrentHashMap() /** The emitter used to fire events. */ @@ -262,6 +278,10 @@ class ChatRoomImpl( private fun parseConfigForm(configForm: Form) { lobbyEnabled = configForm.getField(MucConfigFormManager.MUC_ROOMCONFIG_MEMBERSONLY)?.firstValue?.toBoolean() ?: false + visitorsEnabled = + configForm.getField(MucConfigFields.VISITORS_ENABLED)?.firstValue?.toBoolean() + participantsSoftLimit = + configForm.getField(MucConfigFields.PARTICIPANTS_SOFT_LIMIT)?.firstValue?.toInt() } override fun leave() { @@ -544,6 +564,8 @@ class ChatRoomImpl( const val MAIN_ROOM = "muc#roominfo_breakout_main_room" const val MEETING_ID = "muc#roominfo_meetingId" const val WHOIS = "muc#roomconfig_whois" + const val PARTICIPANTS_SOFT_LIMIT = "muc#roominfo_participantsSoftLimit" + const val VISITORS_ENABLED = "muc#roominfo_visitorsEnabled" } internal inner class MemberListener : ParticipantStatusListener { diff --git a/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java b/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java index e0fbc9cc76..e3c224dfea 100644 --- a/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java +++ b/jicofo/src/main/java/org/jitsi/jicofo/conference/JitsiMeetConferenceImpl.java @@ -1677,7 +1677,7 @@ public String redirectVisitor(boolean visitorRequested) // We don't support both visitors and a lobby. Once a lobby is enabled we don't use visitors anymore. ChatRoom chatRoom = this.chatRoom; - if (chatRoom != null && chatRoom.getLobbyEnabled()) + if (chatRoom != null && (chatRoom.getLobbyEnabled() || Boolean.FALSE.equals(chatRoom.getVisitorsEnabled()))) { return null; } @@ -1688,13 +1688,19 @@ public String redirectVisitor(boolean visitorRequested) } long participantCount = getUserParticipantCount(); - boolean visitorsAlreadyUsed = false; + boolean visitorsAlreadyUsed; synchronized (visitorChatRooms) { visitorsAlreadyUsed = !visitorChatRooms.isEmpty(); } - if (visitorsAlreadyUsed || visitorRequested || participantCount >= VisitorsConfig.config.getMaxParticipants()) + int participantsSoftLimit = VisitorsConfig.config.getMaxParticipants(); + if (chatRoom != null && chatRoom.getParticipantsSoftLimit() != null && chatRoom.getParticipantsSoftLimit() > 0) + { + participantsSoftLimit = chatRoom.getParticipantsSoftLimit(); + } + + if (visitorsAlreadyUsed || visitorRequested || participantCount >= participantsSoftLimit) { return selectVisitorNode(); }