Skip to content

Commit

Permalink
Merge branch 'develop' into fixjitterbuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
ffdixon authored Dec 30, 2022
2 parents 9a45636 + 56388c1 commit 4c359d8
Show file tree
Hide file tree
Showing 488 changed files with 16,095 additions and 17,731 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/automated-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
build-install-and-test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- run: ./build/get_external_dependencies.sh
- run: ./build/setup.sh bbb-apps-akka
- run: ./build/setup.sh bbb-config
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/check-merge-conflict.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ on:
- opened
- synchronize

permissions:
contents: read

jobs:
main:
permissions:
pull-requests: write # for eps1lon/actions-label-merge-conflict to label PRs
runs-on: ubuntu-latest
steps:
- name: Check for dirty pull requests
Expand Down
4 changes: 2 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ stages:

# define which docker image to use for builds
default:
image: gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:v2022-07-12
image: gitlab.senfcall.de:5050/senfcall-public/docker-bbb-build:v2022-12-08-meteor-290

# This stage uses git to find out since when each package has been unmodified.
# it then checks an API endpoint on the package server to find out for which of
Expand Down Expand Up @@ -99,7 +99,7 @@ bbb-html5-build:
script:
- build/setup-inside-docker.sh bbb-html5

bbb-learning-dashboard:
bbb-learning-dashboard-build:
extends: .build_job
script:
- build/setup-inside-docker.sh bbb-learning-dashboard
Expand Down
4 changes: 2 additions & 2 deletions akka-bbb-apps/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ val compileSettings = Seq(
"-Xlint",
"-Ywarn-dead-code",
"-language:_",
"-target:jvm-1.11",
"-target:11",
"-encoding", "UTF-8"
),
javacOptions ++= List(
Expand Down Expand Up @@ -48,7 +48,7 @@ lazy val bbbAppsAkka = (project in file(".")).settings(name := "bbb-apps-akka",
// Config file is in ./.scalariform.conf
scalariformAutoformat := true

scalaVersion := "2.13.4"
scalaVersion := "2.13.9"
//-----------
// Packaging
//
Expand Down
4 changes: 2 additions & 2 deletions akka-bbb-apps/project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Dependencies {

object Versions {
// Scala
val scala = "2.13.4"
val scala = "2.13.9"
val junit = "4.12"
val junitInterface = "0.11"
val scalactic = "3.0.8"
Expand All @@ -26,7 +26,7 @@ object Dependencies {
val codec = "1.15"

// BigBlueButton
val bbbCommons = "0.0.21-SNAPSHOT"
val bbbCommons = "0.0.22-SNAPSHOT"

// Test
val scalaTest = "3.2.11"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class BigBlueButtonActor(

case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case m: EjectDuplicateUserReqMsg => handleEjectDuplicateUserReqMsg(m)
case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
case m: GetRunningMeetingsReqMsg => handleGetRunningMeetingsReqMsg(m)
case m: CheckAlivePingSysMsg => handleCheckAlivePingSysMsg(m)
Expand Down Expand Up @@ -105,16 +104,6 @@ class BigBlueButtonActor(
}
}

def handleEjectDuplicateUserReqMsg(msg: EjectDuplicateUserReqMsg): Unit = {
log.debug("RECEIVED EjectDuplicateUserReqMsg msg {}", msg)
for {
m <- RunningMeetings.findWithId(meetings, msg.header.meetingId)
} yield {
log.debug("FORWARDING EjectDuplicateUserReqMsg")
m.actorRef forward (msg)
}
}

def handleCreateMeetingReqMsg(msg: CreateMeetingReqMsg): Unit = {
log.debug("RECEIVED CreateMeetingReqMsg msg {}", msg)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ case class SendMessageToBreakoutRoomInternalMsg(parentId: String, breakoutId: St
*/
case class EjectUserFromBreakoutInternalMsg(parentId: String, breakoutId: String, extUserId: String, ejectedBy: String, reason: String, reasonCode: String, ban: Boolean) extends InMessage

/**
* Sent by parent meeting to breakout room to import annotated slides.
* @param userId
* @param parentMeetingId
* @param allPages
*/
case class CapturePresentationReqInternalMsg(userId: String, parentMeetingId: String, allPages: Boolean = true) extends InMessage

/**
* Sent by parent meeting to breakout room to import shared notes.
* @param parentMeetingId
* @param meetingName
*/
case class CaptureSharedNotesReqInternalMsg(parentMeetingId: String, meetingName: String) extends InMessage

// DeskShare
case class DeskShareStartedRequest(conferenceName: String, callerId: String, callerIdName: String) extends InMessage
case class DeskShareStoppedRequest(conferenceName: String, callerId: String, callerIdName: String) extends InMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ object BreakoutModel {
isDefaultName: Boolean,
freeJoin: Boolean,
voiceConf: String,
assignedUsers: Vector[String]
assignedUsers: Vector[String],
captureNotes: Boolean,
captureSlides: Boolean,
): BreakoutRoom2x = {
new BreakoutRoom2x(id, externalId, name, parentId, sequence, shortName, isDefaultName, freeJoin, voiceConf, assignedUsers, Vector(), Vector(), None, false)
new BreakoutRoom2x(id, externalId, name, parentId, sequence, shortName, isDefaultName, freeJoin, voiceConf, assignedUsers, Vector(), Vector(), None, false, captureNotes, captureSlides)
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package org.bigbluebutton.core.apps

import org.bigbluebutton.core.util.jhotdraw.BezierWrapper
import scala.collection.immutable.List
import scala.collection.immutable.HashMap
import scala.collection.JavaConverters._
import org.bigbluebutton.common2.msgs.AnnotationVO
import org.bigbluebutton.core.apps.whiteboard.Whiteboard
import org.bigbluebutton.SystemConfiguration
Expand All @@ -24,86 +21,83 @@ class WhiteboardModel extends SystemConfiguration {
}

private def createWhiteboard(wbId: String): Whiteboard = {
new Whiteboard(
Whiteboard(
wbId,
Array.empty[String],
Array.empty[String],
System.currentTimeMillis(),
new HashMap[String, Map[String, AnnotationVO]]()
new HashMap[String, AnnotationVO]
)
}

private def getAnnotationsByUserId(wb: Whiteboard, id: String): Map[String, AnnotationVO] = {
wb.annotationsMap.get(id).getOrElse(Map[String, AnnotationVO]())
}
private def deepMerge(test: Map[String, _], that: Map[String, _]): Map[String, _] =
(for (k <- test.keys ++ that.keys) yield {
val newValue =
(test.get(k), that.get(k)) match {
case (Some(v), None) => v
case (None, Some(v)) => v
case (Some(v1), Some(v2)) =>
if (v1.isInstanceOf[Map[String, _]] && v2.isInstanceOf[Map[String, _]])
deepMerge(v1.asInstanceOf[Map[String, _]], v2.asInstanceOf[Map[String, _]])
else v2
case (_, _) => ???
}
k -> newValue
}).toMap

def addAnnotations(wbId: String, userId: String, annotations: Array[AnnotationVO]): Array[AnnotationVO] = {
def addAnnotations(wbId: String, userId: String, annotations: Array[AnnotationVO], isPresenter: Boolean, isModerator: Boolean): Array[AnnotationVO] = {
var annotationsAdded = Array[AnnotationVO]()
val wb = getWhiteboard(wbId)
val usersAnnotations = getAnnotationsByUserId(wb, userId)
var newUserAnnotations = usersAnnotations
var newAnnotationsMap = wb.annotationsMap
for (annotation <- annotations) {
newUserAnnotations = newUserAnnotations + (annotation.id -> annotation)
println("Adding annotation to page [" + wb.id + "]. After numAnnotations=[" + newUserAnnotations.size + "].")
val oldAnnotation = wb.annotationsMap.get(annotation.id)
if (!oldAnnotation.isEmpty) {
val hasPermission = isPresenter || isModerator || oldAnnotation.get.userId == userId
if (hasPermission) {
val newAnnotation = oldAnnotation.get.copy(annotationInfo = deepMerge(oldAnnotation.get.annotationInfo, annotation.annotationInfo))
newAnnotationsMap += (annotation.id -> newAnnotation)
annotationsAdded :+= annotation
println(s"Updated annotation onpage [${wb.id}]. After numAnnotations=[${newAnnotationsMap.size}].")
} else {
println(s"User $userId doesn't have permission to edit annotation ${annotation.id}, ignoring...")
}
} else if (annotation.annotationInfo.contains("type")) {
newAnnotationsMap += (annotation.id -> annotation)
annotationsAdded :+= annotation
println(s"Adding annotation to page [${wb.id}]. After numAnnotations=[${newAnnotationsMap.size}].")
} else {
println(s"New annotation [${annotation.id}] with no type, ignoring (probably received a remove message before and now the shape is incomplete, ignoring...")
}
}
val newAnnotationsMap = wb.annotationsMap + (userId -> newUserAnnotations)
val newWb = wb.copy(annotationsMap = newAnnotationsMap)
saveWhiteboard(newWb)
annotations
annotationsAdded
}

def getHistory(wbId: String): Array[AnnotationVO] = {
//wb.annotationsMap.values.flatten.toArray.sortBy(_.position);
val wb = getWhiteboard(wbId)
var annotations = Array[AnnotationVO]()
// TODO: revisit this, probably there is a one-liner simple solution
wb.annotationsMap.values.foreach(
user => user.values.foreach(
annotation => annotations = annotations :+ annotation
)
)
annotations
wb.annotationsMap.values.toArray
}

def clearWhiteboard(wbId: String, userId: String): Option[Boolean] = {
var cleared: Option[Boolean] = None

if (hasWhiteboard(wbId)) {
val wb = getWhiteboard(wbId)

if (wb.multiUser.contains(userId)) {
if (wb.annotationsMap.contains(userId)) {
val newWb = wb.copy(annotationsMap = wb.annotationsMap - userId)
saveWhiteboard(newWb)
cleared = Some(false)
}
} else {
if (wb.annotationsMap.nonEmpty) {
val newWb = wb.copy(annotationsMap = new HashMap[String, Map[String, AnnotationVO]]())
saveWhiteboard(newWb)
cleared = Some(true)
}
}
}
cleared
}

def deleteAnnotations(wbId: String, userId: String, annotationsIds: Array[String]): Array[String] = {
def deleteAnnotations(wbId: String, userId: String, annotationsIds: Array[String], isPresenter: Boolean, isModerator: Boolean): Array[String] = {
var annotationsIdsRemoved = Array[String]()
val wb = getWhiteboard(wbId)
var newAnnotationsMap = wb.annotationsMap

val usersAnnotations = getAnnotationsByUserId(wb, userId)
var newUserAnnotations = usersAnnotations
for (annotationId <- annotationsIds) {
val annotation = usersAnnotations.get(annotationId)

//not empty and annotation exists
if (!usersAnnotations.isEmpty && !annotation.isEmpty) {
newUserAnnotations = newUserAnnotations - annotationId
println("Removing annotation on page [" + wb.id + "]. After numAnnotations=[" + newUserAnnotations.size + "].")
annotationsIdsRemoved = annotationsIdsRemoved :+ annotationId
val annotation = wb.annotationsMap.get(annotationId)

if (!annotation.isEmpty) {
val hasPermission = isPresenter || isModerator || annotation.get.userId == userId
if (hasPermission) {
newAnnotationsMap -= annotationId
println("Removing annotation on page [" + wb.id + "]. After numAnnotations=[" + newAnnotationsMap.size + "].")
annotationsIdsRemoved :+= annotationId
} else {
println("User doesn't have permission to remove this annotation, ignoring...")
}
}
}
val newAnnotationsMap = wb.annotationsMap + (userId -> newUserAnnotations)
val newWb = wb.copy(annotationsMap = newAnnotationsMap)
saveWhiteboard(newWb)
annotationsIdsRemoved
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ trait BreakoutRoomCreatedMsgHdlr {
(redirectToHtml5JoinURL, redirectJoinURL) <- BreakoutHdlrHelpers.getRedirectUrls(liveMeeting, user, r.externalId, r.sequence.toString())
} yield (user -> redirectToHtml5JoinURL)

new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin, html5JoinUrls.toMap)
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin, html5JoinUrls.toMap, r.captureNotes, r.captureSlides)
}

log.info("Sending breakout rooms list to {} with containing {} room(s)", liveMeeting.props.meetingProp.intId, breakoutRooms.length)
Expand All @@ -79,7 +79,7 @@ trait BreakoutRoomCreatedMsgHdlr {
BbbCommonEnvCoreMsg(envelope, event)
}

val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence, room.shortName, room.isDefaultName, room.freeJoin, Map())
val breakoutInfo = BreakoutRoomInfo(room.name, room.externalId, room.id, room.sequence, room.shortName, room.isDefaultName, room.freeJoin, Map(), room.captureNotes, room.captureSlides)
val event = build(liveMeeting.props.meetingProp.intId, breakoutInfo)
outGW.send(event)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ trait BreakoutRoomsListMsgHdlr {
breakoutModel <- state.breakout
} yield {
val rooms = breakoutModel.rooms.values.toVector map { r =>
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin, Map())
new BreakoutRoomInfo(r.name, r.externalId, r.id, r.sequence, r.shortName, r.isDefaultName, r.freeJoin, Map(), r.captureNotes, r.captureSlides)
}
val ready = breakoutModel.hasAllStarted()
broadcastEvent(rooms, ready)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait {
val (internalId, externalId) = BreakoutRoomsUtil.createMeetingIds(liveMeeting.props.meetingProp.intId, i)
val voiceConf = BreakoutRoomsUtil.createVoiceConfId(liveMeeting.props.voiceProp.voiceConf, i)

val breakout = BreakoutModel.create(parentId, internalId, externalId, room.name, room.sequence, room.shortName, room.isDefaultName, room.freeJoin, voiceConf, room.users)
val breakout = BreakoutModel.create(parentId, internalId, externalId, room.name, room.sequence, room.shortName, room.isDefaultName, room.freeJoin, voiceConf, room.users, msg.body.captureNotes, msg.body.captureSlides)
rooms = rooms + (breakout.id -> breakout)
}

Expand All @@ -70,7 +70,9 @@ trait CreateBreakoutRoomsCmdMsgHdlr extends RightsManagementTrait {
liveMeeting.props.password.moderatorPass,
liveMeeting.props.password.viewerPass,
presId, presSlide, msg.body.record,
liveMeeting.props.breakoutProps.privateChatEnabled
liveMeeting.props.breakoutProps.privateChatEnabled,
breakout.captureNotes,
breakout.captureSlides,
)

val event = buildCreateBreakoutRoomSysCmdMsg(liveMeeting.props.meetingProp.intId, roomDetail)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ trait EndAllBreakoutRoomsMsgHdlr extends RightsManagementTrait {
val outGW: OutMsgRouter

def handleEndAllBreakoutRoomsMsg(msg: EndAllBreakoutRoomsMsg, state: MeetingState2x): MeetingState2x = {
val meetingId = liveMeeting.props.meetingProp.intId
if (permissionFailed(PermissionCheck.MOD_LEVEL, PermissionCheck.VIEWER_LEVEL, liveMeeting.users2x, msg.header.userId)) {
val meetingId = liveMeeting.props.meetingProp.intId
val reason = "No permission to end breakout rooms for meeting."
PermissionCheck.ejectUserForFailedPermission(meetingId, msg.header.userId, reason, outGW, liveMeeting)
state
Expand All @@ -24,11 +24,11 @@ trait EndAllBreakoutRoomsMsgHdlr extends RightsManagementTrait {
model <- state.breakout
} yield {
model.rooms.values.foreach { room =>
eventBus.publish(BigBlueButtonEvent(room.id, EndBreakoutRoomInternalMsg(props.breakoutProps.parentId, room.id, MeetingEndReason.BREAKOUT_ENDED_BY_MOD)))
eventBus.publish(BigBlueButtonEvent(room.id, EndBreakoutRoomInternalMsg(meetingId, room.id, MeetingEndReason.BREAKOUT_ENDED_BY_MOD)))
}

val notifyEvent = MsgBuilder.buildNotifyAllInMeetingEvtMsg(
liveMeeting.props.meetingProp.intId,
meetingId,
"info",
"rooms",
"app.toast.breakoutRoomEnded",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.bigbluebutton.core.apps.breakout

import org.bigbluebutton.core.api.EndBreakoutRoomInternalMsg
import org.bigbluebutton.core.bus.{ InternalEventBus }
import org.bigbluebutton.core.api.{ CaptureSharedNotesReqInternalMsg, CapturePresentationReqInternalMsg, EndBreakoutRoomInternalMsg }
import org.bigbluebutton.core.bus.{ BigBlueButtonEvent, InternalEventBus }
import org.bigbluebutton.core.running.{ BaseMeetingActor, HandlerHelpers, LiveMeeting, OutMsgRouter }

trait EndBreakoutRoomInternalMsgHdlr extends HandlerHelpers {
Expand All @@ -12,6 +12,18 @@ trait EndBreakoutRoomInternalMsgHdlr extends HandlerHelpers {
val eventBus: InternalEventBus

def handleEndBreakoutRoomInternalMsg(msg: EndBreakoutRoomInternalMsg): Unit = {

if (liveMeeting.props.breakoutProps.captureSlides) {
val captureSlidesEvent = BigBlueButtonEvent(msg.breakoutId, CapturePresentationReqInternalMsg("system", msg.parentId))
eventBus.publish(captureSlidesEvent)
}

if (liveMeeting.props.breakoutProps.captureNotes) {
val meetingName: String = liveMeeting.props.meetingProp.name
val captureNotesEvent = BigBlueButtonEvent(msg.breakoutId, CaptureSharedNotesReqInternalMsg(msg.parentId, meetingName))
eventBus.publish(captureNotesEvent)
}

log.info("Breakout room {} ended by parent meeting {}.", msg.breakoutId, msg.parentId)
sendEndMeetingDueToExpiry(msg.reason, eventBus, outGW, liveMeeting, "system")
}
Expand Down
Loading

0 comments on commit 4c359d8

Please sign in to comment.