Merge remote-tracking branch 'upstream/bbb-2x-mconf' into move-caption-messages-2x

This commit is contained in:
Chad Pilkey 2017-06-26 18:09:56 -04:00
commit 4c66393dbd
281 changed files with 5546 additions and 3258 deletions

3
akka-bbb-apps/run.sh Executable file
View File

@ -0,0 +1,3 @@
sbt clean
sbt run

View File

@ -13,11 +13,10 @@ import org.bigbluebutton.core.api._
import org.bigbluebutton.SystemConfiguration
import java.util.concurrent.TimeUnit
import org.bigbluebutton.common2.messages.MessageBody.MeetingCreatedEvtBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.RegisterUserReqMsg
import org.bigbluebutton.core.running.RunningMeeting
import org.bigbluebutton.core2.RunningMeetings
import org.bigbluebutton.core2.message.handlers.CreateMeetingReqMsgHdlr
object BigBlueButtonActor extends SystemConfiguration {
def props(system: ActorSystem,
@ -78,12 +77,12 @@ class BigBlueButtonActor(val system: ActorSystem,
msg.core match {
case m: CreateMeetingReqMsg => handleCreateMeetingReqMsg(m)
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case _ => println("***** Cannot handle " + msg.envelope.name)
case _ => log.warning("Cannot handle " + msg.envelope.name)
}
}
def handleRegisterUserReqMsg(msg: RegisterUserReqMsg): Unit = {
log.debug("****** RECEIVED RegisterUserReqMsg msg {}", msg)
log.debug("RECEIVED RegisterUserReqMsg msg {}", msg)
for {
m <- RunningMeetings.findWithId(meetings, msg.header.meetingId)
} yield {
@ -327,4 +326,3 @@ class BigBlueButtonActor(val system: ActorSystem,
}
}

View File

@ -13,7 +13,9 @@ import org.bigbluebutton.common.messages.PubSubPingMessage
import org.bigbluebutton.messages._
import akka.event.Logging
import org.bigbluebutton.SystemConfiguration
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.models.Roles
import scala.collection.JavaConverters
class BigBlueButtonInGW(
@ -334,8 +336,8 @@ class BigBlueButtonInGW(
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationSlideGenerated(meetingId, messageKey, code, presentationId, numberOfPages, pagesCompleted, presName)))
}
def generatePresentationPages(presId: String, numPages: Int, presBaseUrl: String): scala.collection.immutable.HashMap[String, Page] = {
var pages = new scala.collection.immutable.HashMap[String, Page]
def generatePresentationPages(presId: String, numPages: Int, presBaseUrl: String): scala.collection.immutable.Map[String, PageVO] = {
var pages = new scala.collection.mutable.HashMap[String, PageVO]
for (i <- 1 to numPages) {
val id = presId + "/" + i
val num = i;
@ -346,19 +348,19 @@ class BigBlueButtonInGW(
val txtUri = presBaseUrl + "/textfiles/" + i
val svgUri = presBaseUrl + "/svg/" + i
val p = new Page(id = id, num = num, thumbUri = thumbnail, swfUri = swfUri,
val p = new PageVO(id = id, num = num, thumbUri = thumbnail, swfUri = swfUri,
txtUri = txtUri, svgUri = svgUri,
current = current)
pages += (p.id -> p)
pages += p.id -> p
}
pages
pages.toMap
}
def sendConversionCompleted(messageKey: String, meetingId: String, code: String, presentationId: String, numPages: Int, presName: String, presBaseUrl: String, downloadable: Boolean) {
val pages = generatePresentationPages(presentationId, numPages, presBaseUrl)
val presentation = new Presentation(id = presentationId, name = presName, pages = pages, downloadable = downloadable)
val presentation = new Presentation(id = presentationId, name = presName, current = true, pages = pages, downloadable = downloadable)
eventBus.publish(BigBlueButtonEvent(meetingId, new PresentationConversionCompleted(meetingId, messageKey, code, presentation)))
}

View File

@ -306,23 +306,6 @@ class MessageSenderActor(val service: MessageSender)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
}
private def pageToMap(page: Page): java.util.Map[String, Any] = {
val res = new scala.collection.mutable.HashMap[String, Any]
res += "id" -> page.id
res += "num" -> page.num
res += "thumb_uri" -> page.thumbUri
res += "swf_uri" -> page.swfUri
res += "txt_uri" -> page.txtUri
res += "svg_uri" -> page.svgUri
res += "current" -> page.current
res += "x_offset" -> page.xOffset
res += "y_offset" -> page.yOffset
res += "width_ratio" -> page.widthRatio
res += "height_ratio" -> page.heightRatio
JavaConverters.mapAsJavaMap(res)
}
private def handleClearPresentationOutMsg(msg: ClearPresentationOutMsg) {
val json = PesentationMessageToJsonConverter.clearPresentationOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
@ -334,36 +317,7 @@ class MessageSenderActor(val service: MessageSender)
}
private def handleGetPresentationInfoOutMsg(msg: GetPresentationInfoOutMsg) {
// Create a map for our current presenter
val presenter = new java.util.HashMap[String, Object]()
presenter.put(Constants.USER_ID, msg.info.presenter.userId)
presenter.put(Constants.NAME, msg.info.presenter.name)
presenter.put(Constants.ASSIGNED_BY, msg.info.presenter.assignedBy)
// Create an array for our presentations
val presentations = new java.util.ArrayList[java.util.Map[String, Object]]
msg.info.presentations.foreach { pres =>
val presentation = new java.util.HashMap[String, Object]()
presentation.put(Constants.ID, pres.id)
presentation.put(Constants.NAME, pres.name)
presentation.put(Constants.CURRENT, pres.current: java.lang.Boolean)
// Get the pages for a presentation
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
pres.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// store the pages in the presentation
presentation.put(Constants.PAGES, pages)
// add this presentation into our presentations list
presentations.add(presentation);
}
val reply = new GetPresentationInfoReplyMessage(msg.meetingID, msg.requesterID, presenter, presentations)
val json = PesentationMessageToJsonConverter.getPresentationInfoOutMsgToJson(msg)
service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json)
}
private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) {

View File

@ -124,7 +124,6 @@ case class RespondToGuest(meetingID: String, userId: String, response: Boolean,
//////////////////////////////////////////////////////////////////////////////////////
case class GetCurrentLayoutRequest(meetingID: String, requesterID: String) extends InMessage
case class SetLayoutRequest(meetingID: String, requesterID: String, layoutID: String) extends InMessage
case class LockLayoutRequest(meetingID: String, setById: String, lock: Boolean, viewersOnly: Boolean,
layout: Option[String]) extends InMessage
case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout: String) extends InMessage

View File

@ -3,6 +3,7 @@ package org.bigbluebutton.core.api
import org.bigbluebutton.common2.messages.breakoutrooms._
import org.bigbluebutton.core.apps._
import org.bigbluebutton.core.models._
import org.bigbluebutton.common2.domain.UserVO
case class VoiceRecordingStarted(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
@ -158,4 +159,3 @@ case class SharedNotesSyncNoteReply(meetingID: String, recorded: Boolean, reques
// Value Objects
case class MeetingVO(id: String, recorded: Boolean)

View File

@ -1,6 +1,6 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.common2.domain.TranscriptVO
import org.bigbluebutton.common2.messages.caption.TranscriptVO
import scala.collection.immutable.HashMap
class CaptionModel {

View File

@ -1,10 +1,11 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._
import org.bigbluebutton.common2.domain.UserVO
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ Roles, UserVO, Users }
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.models.{ Layouts, Roles, Users }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
@ -15,32 +16,32 @@ trait LayoutApp {
def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) {
outGW.send(new GetCurrentLayoutReply(msg.meetingID, props.recordProp.record, msg.requesterID,
liveMeeting.layoutModel.getCurrentLayout(),
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
liveMeeting.layoutModel.getLayoutSetter()))
Layouts.getLayoutSetter()))
}
def handleLockLayoutRequest(msg: LockLayoutRequest) {
liveMeeting.layoutModel.applyToViewersOnly(msg.viewersOnly)
Layouts.applyToViewersOnly(msg.viewersOnly)
liveMeeting.lockLayout(msg.lock)
outGW.send(new LockLayoutEvent(msg.meetingID, props.recordProp.record, msg.setById, msg.lock, affectedUsers))
msg.layout foreach { l =>
liveMeeting.layoutModel.setCurrentLayout(l)
Layouts.setCurrentLayout(l)
broadcastSyncLayout(msg.meetingID, msg.setById)
}
}
private def broadcastSyncLayout(meetingId: String, setById: String) {
outGW.send(new BroadcastLayoutEvent(meetingId, props.recordProp.record, setById,
liveMeeting.layoutModel.getCurrentLayout(),
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
liveMeeting.layoutModel.getLayoutSetter(), affectedUsers))
Layouts.getLayoutSetter(), affectedUsers))
}
def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
liveMeeting.layoutModel.setCurrentLayout(msg.layout)
Layouts.setCurrentLayout(msg.layout)
broadcastSyncLayout(msg.meetingID, msg.requesterID)
}
@ -51,7 +52,7 @@ trait LayoutApp {
}
def affectedUsers(): Array[UserVO] = {
if (liveMeeting.layoutModel.doesLayoutApplyToViewersOnly()) {
if (Layouts.doesLayoutApplyToViewersOnly()) {
val au = ArrayBuffer[UserVO]()
Users.getUsers(liveMeeting.users) foreach { u =>
if (!u.presenter && u.role != Roles.MODERATOR_ROLE) {
@ -62,7 +63,6 @@ trait LayoutApp {
} else {
Users.getUsers(liveMeeting.users).toArray
}
}
}

View File

@ -1,6 +1,6 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.models.UserVO
import org.bigbluebutton.common2.domain.UserVO
trait PermisssionCheck {

View File

@ -12,13 +12,13 @@ trait PresentationApp {
val outGW: OutMessageGateway
def handlePreuploadedPresentations(msg: PreuploadedPresentations) {
val pres = msg.presentations
msg.presentations.foreach(presentation => {
liveMeeting.presModel.addPresentation(presentation)
sharePresentation(presentation.id, true)
})
// val pres = msg.presentations
//
// msg.presentations.foreach(presentation => {
// liveMeeting.presModel.addPresentation(presentation)
//
// sharePresentation(presentation.id, true)
// })
}
def handleInitializeMeeting(msg: InitializeMeeting) {
@ -26,81 +26,81 @@ trait PresentationApp {
}
def handleClearPresentation(msg: ClearPresentation) {
outGW.send(new ClearPresentationOutMsg(props.meetingProp.intId, props.recordProp.record))
// outGW.send(new ClearPresentationOutMsg(props.meetingProp.intId, props.recordProp.record))
}
def handlePresentationConversionUpdate(msg: PresentationConversionUpdate) {
outGW.send(new PresentationConversionProgress(props.meetingProp.intId, msg.messageKey,
msg.code, msg.presentationId, msg.presName))
// outGW.send(new PresentationConversionProgress(props.meetingProp.intId, msg.messageKey,
// msg.code, msg.presentationId, msg.presName))
}
def handlePresentationPageCountError(msg: PresentationPageCountError) {
outGW.send(new PresentationConversionError(props.meetingProp.intId, msg.messageKey,
msg.code, msg.presentationId,
msg.numberOfPages,
msg.maxNumberPages, msg.presName))
// outGW.send(new PresentationConversionError(props.meetingProp.intId, msg.messageKey,
// msg.code, msg.presentationId,
// msg.numberOfPages,
// msg.maxNumberPages, msg.presName))
}
def handlePresentationSlideGenerated(msg: PresentationSlideGenerated) {
outGW.send(new PresentationPageGenerated(props.meetingProp.intId, msg.messageKey,
msg.code, msg.presentationId,
msg.numberOfPages,
msg.pagesCompleted, msg.presName))
// outGW.send(new PresentationPageGenerated(props.meetingProp.intId, msg.messageKey,
// msg.code, msg.presentationId,
// msg.numberOfPages,
// msg.pagesCompleted, msg.presName))
}
def handlePresentationConversionCompleted(msg: PresentationConversionCompleted) {
liveMeeting.presModel.addPresentation(msg.presentation)
outGW.send(new PresentationConversionDone(props.meetingProp.intId, props.recordProp.record, msg.messageKey,
msg.code, msg.presentation))
sharePresentation(msg.presentation.id, true)
//
// outGW.send(new PresentationConversionDone(props.meetingProp.intId, props.recordProp.record, msg.messageKey,
// msg.code, msg.presentation))
//
// sharePresentation(msg.presentation.id, true)
}
def handleRemovePresentation(msg: RemovePresentation) {
val curPres = liveMeeting.presModel.getCurrentPresentation
val removedPresentation = liveMeeting.presModel.remove(msg.presentationID)
curPres foreach (cp => {
if (cp.id == msg.presentationID) {
sharePresentation(msg.presentationID, false);
}
})
outGW.send(new RemovePresentationOutMsg(msg.meetingID, props.recordProp.record, msg.presentationID))
// val curPres = liveMeeting.presModel.getCurrentPresentation
//
// val removedPresentation = liveMeeting.presModel.remove(msg.presentationID)
//
// curPres foreach (cp => {
// if (cp.id == msg.presentationID) {
// sharePresentation(msg.presentationID, false);
// }
// })
//
// outGW.send(new RemovePresentationOutMsg(msg.meetingID, props.recordProp.record, msg.presentationID))
}
def handleGetPresentationInfo(msg: GetPresentationInfo) {
val curPresenter = MeetingStatus2x.getCurrentPresenterInfo(liveMeeting.status)
val presenter = new CurrentPresenter(curPresenter.presenterID, curPresenter.presenterName, curPresenter.assignedBy)
val presentations = liveMeeting.presModel.getPresentations
val presentationInfo = new CurrentPresentationInfo(presenter, presentations)
outGW.send(new GetPresentationInfoOutMsg(props.meetingProp.intId, props.recordProp.record, msg.requesterID, presentationInfo, msg.replyTo))
// val curPresenter = MeetingStatus2x.getCurrentPresenterInfo(liveMeeting.status)
// val presenter = new CurrentPresenter(curPresenter.presenterID, curPresenter.presenterName, curPresenter.assignedBy)
// val presentations = liveMeeting.presModel.getPresentations
// val presentationInfo = new CurrentPresentationInfo(presenter, presentations)
// outGW.send(new GetPresentationInfoOutMsg(props.meetingProp.intId, props.recordProp.record, msg.requesterID, presentationInfo, msg.replyTo))
}
def handleResizeAndMoveSlide(msg: ResizeAndMoveSlide) {
// Force coordinate that are out-of-bounds inside valid values
val xOffset = if (msg.xOffset <= 0) msg.xOffset else 0
val yOffset = if (msg.yOffset <= 0) msg.yOffset else 0
val width = if (msg.widthRatio <= 100) msg.widthRatio else 100
val height = if (msg.heightRatio <= 100) msg.heightRatio else 100
val page = liveMeeting.presModel.resizePage(xOffset, yOffset, width, height);
page foreach (p => outGW.send(new ResizeAndMoveSlideOutMsg(props.meetingProp.intId, props.recordProp.record, p)))
// // Force coordinate that are out-of-bounds inside valid values
// val xOffset = if (msg.xOffset <= 0) msg.xOffset else 0
// val yOffset = if (msg.yOffset <= 0) msg.yOffset else 0
// val width = if (msg.widthRatio <= 100) msg.widthRatio else 100
// val height = if (msg.heightRatio <= 100) msg.heightRatio else 100
//
// val page = liveMeeting.presModel.resizePage(xOffset, yOffset, width, height);
// page foreach (p => outGW.send(new ResizeAndMoveSlideOutMsg(props.meetingProp.intId, props.recordProp.record, p)))
}
def handleGotoSlide(msg: GotoSlide) {
liveMeeting.presModel.changePage(msg.page) foreach { page =>
log.debug("Switching page for meeting=[{}] page=[{}]", msg.meetingID, page.num);
outGW.send(new GotoSlideOutMsg(props.meetingProp.intId, props.recordProp.record, page))
}
Users.getCurrentPresenter(liveMeeting.users) foreach { pres =>
handleStopPollRequest(StopPollRequest(props.meetingProp.intId, pres.id))
}
// liveMeeting.presModel.changePage(msg.page) foreach { page =>
// log.debug("Switching page for meeting=[{}] page=[{}]", msg.meetingID, page.num);
// outGW.send(new GotoSlideOutMsg(props.meetingProp.intId, props.recordProp.record, page))
// }
//
// Users.getCurrentPresenter(liveMeeting.users) foreach { pres =>
// handleStopPollRequest(StopPollRequest(props.meetingProp.intId, pres.id))
// }
}
@ -109,6 +109,7 @@ trait PresentationApp {
}
def sharePresentation(presentationID: String, share: Boolean) {
/*
val pres = liveMeeting.presModel.sharePresentation(presentationID)
pres foreach { p =>
@ -118,15 +119,15 @@ trait PresentationApp {
outGW.send(new GotoSlideOutMsg(props.meetingProp.intId, props.recordProp.record, page))
}
}
*/
}
def handleGetSlideInfo(msg: GetSlideInfo) {
liveMeeting.presModel.getCurrentPresentation foreach { pres =>
liveMeeting.presModel.getCurrentPage(pres) foreach { page =>
outGW.send(new GetSlideInfoOutMsg(props.meetingProp.intId, props.recordProp.record, msg.requesterID, page, msg.replyTo))
}
}
// liveMeeting.presModel.getCurrentPresentation foreach { pres =>
// liveMeeting.presModel.getCurrentPage(pres) foreach { page =>
// outGW.send(new GetSlideInfoOutMsg(props.meetingProp.intId, props.recordProp.record, msg.requesterID, page, msg.replyTo))
// }
// }
}

View File

@ -1,9 +1,12 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.common2.domain.PageVO
case class CurrentPresenter(userId: String, name: String, assignedBy: String)
case class CurrentPresentationInfo(presenter: CurrentPresenter, presentations: Seq[Presentation])
case class Presentation(id: String, name: String, current: Boolean = false,
pages: scala.collection.immutable.HashMap[String, Page], downloadable: Boolean)
pages: scala.collection.immutable.Map[String, PageVO], downloadable: Boolean)
case class Page(id: String, num: Int, thumbUri: String = "", swfUri: String,
txtUri: String, svgUri: String, current: Boolean = false, xOffset: Double = 0, yOffset: Double = 0,
@ -16,32 +19,35 @@ class PresentationModel {
savePresentation(pres)
}
def getPresentations(): Seq[Presentation] = {
presentations.values.toSeq
def getPresentations(): Vector[Presentation] = {
presentations.values.toVector
}
def getCurrentPresentation(): Option[Presentation] = {
presentations.values find (p => p.current)
}
def getCurrentPage(pres: Presentation): Option[Page] = {
def getCurrentPage(pres: Presentation): Option[PageVO] = {
pres.pages.values find (p => p.current)
}
def getCurrentPage(): Option[Page] = {
def getCurrentPage(): Option[PageVO] = {
for {
curPres <- getCurrentPresentation()
curPage <- getCurrentPage(curPres)
} yield curPage
}
def remove(presId: String): Option[Presentation] = {
val pres = presentations.get(presId)
pres foreach (p => presentations -= p.id)
def removePresentation(presId: String): Option[Presentation] = {
for {
pres <- presentations.get(presId)
} yield {
presentations -= presId
pres
}
}
def sharePresentation(presId: String): Option[Presentation] = {
def setCurrentPresentation(presId: String): Option[Presentation] = {
getCurrentPresentation foreach (curPres => {
if (curPres.id != presId) {
val newPres = curPres.copy(current = false)
@ -63,54 +69,41 @@ class PresentationModel {
presentations += pres.id -> pres
}
private def resizeCurrentPage(pres: Presentation,
xOffset: Double, yOffset: Double,
widthRatio: Double,
heightRatio: Double): Option[Page] = {
getCurrentPage(pres) match {
case Some(cp) => {
val page = cp.copy(xOffset = xOffset, yOffset = yOffset,
def resizePage(presentationId: String, pageId: String,
xOffset: Double, yOffset: Double, widthRatio: Double,
heightRatio: Double): Option[PageVO] = {
for {
pres <- presentations.get(presentationId)
page <- pres.pages.get(pageId)
} yield {
val nPage = page.copy(xOffset = xOffset, yOffset = yOffset,
widthRatio = widthRatio, heightRatio = heightRatio)
val nPages = pres.pages + (page.id -> page)
val nPages = pres.pages + (nPage.id -> nPage)
val newPres = pres.copy(pages = nPages)
savePresentation(newPres)
Some(page)
}
case None => None
nPage
}
}
def resizePage(xOffset: Double, yOffset: Double,
widthRatio: Double, heightRatio: Double): Option[Page] = {
for {
curPres <- getCurrentPresentation
page <- resizeCurrentPage(curPres, xOffset, yOffset, widthRatio, heightRatio)
} yield page
}
private def deactivateCurrentPage(pres: Presentation) {
getCurrentPage(pres) foreach { cp =>
private def deactivateCurrentPage(pres: Presentation, pageIdToIgnore: String): Presentation = {
var updatedPres = pres
pres.pages.values.find(p => p.current && p.id != pageIdToIgnore).foreach { cp =>
val page = cp.copy(current = false)
val nPages = pres.pages + (page.id -> page)
val newPres = pres.copy(pages = nPages)
savePresentation(newPres)
// println("Making page[" + page.id + "] not current[" + page.current + "]")
// println("After deact page. presentation id=[" + newPres.id + "] current=[" + newPres.current + "]")
// newPres.pages.values foreach {page =>
// println("page id=[" + page.id + "] current=[" + page.current + "]")
// }
updatedPres = newPres
}
updatedPres
}
private def makePageCurrent(pres: Presentation, page: String): Option[Page] = {
pres.pages.values find (p => p.id == page) match {
private def makePageCurrent(pres: Presentation, pageId: String): Option[Presentation] = {
pres.pages.get(pageId) match {
case Some(newCurPage) => {
val page = newCurPage.copy(current = true)
val newPages = pres.pages + (page.id -> page)
val newPres = pres.copy(pages = newPages)
savePresentation(newPres)
Some(newPres)
// println("Making page[" + page.id + "] current[" + page.current + "]")
Some(page)
}
case None => {
// println("Could not find page[" + page + "] in presentation [" + pres.id + "]")
@ -119,13 +112,18 @@ class PresentationModel {
}
}
def changePage(pageId: String): Option[Page] = {
getCurrentPresentation foreach { pres => deactivateCurrentPage(pres) }
def changeCurrentPage(presentationId: String, pageId: String): Boolean = {
var foundPage: Boolean = false;
for {
pres <- getCurrentPresentation
page <- makePageCurrent(pres, pageId)
} yield page
pres <- presentations.get(presentationId)
newPres <- makePageCurrent(pres, pageId)
} yield {
foundPage = true
savePresentation(deactivateCurrentPage(newPres, pageId))
}
foundPage
}
}

View File

@ -1,48 +1,58 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.common2.domain.UserVO
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.{ PresenterAssignedEvtMsg, PresenterAssignedEvtMsgBody }
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.GuestPolicy
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core2.message.handlers.users.{ UserEmojiStatusHdlr, UserLeavingHdlr }
trait UsersApp {
trait UsersApp extends UserLeavingHdlr with UserEmojiStatusHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleValidateAuthToken(msg: ValidateAuthToken) {
log.info("Got ValidateAuthToken message. meetingId=" + msg.meetingID + " userId=" + msg.userId)
RegisteredUsers.getRegisteredUserWithToken(msg.token, msg.userId, liveMeeting.registeredUsers) match {
case Some(u) =>
def automaticallyAssignPresenter(): Unit = {
log.debug("auto assigning presenter")
//send the reply
outGW.send(new ValidateAuthTokenReply(props.meetingProp.intId, msg.userId, msg.token, true, msg.correlationId))
Users2x.findModerator(liveMeeting.users2x) match {
case Some(moderator) =>
for {
newPresenter <- Users2x.makePresenter(liveMeeting.users2x, moderator.intId)
} yield {
log.debug("sending assigned presenter for intId={} name={}", newPresenter.intId, newPresenter.name)
sendPresenterAssigned(newPresenter.intId, newPresenter.name, newPresenter.name)
}
case None => log.debug("No moderator found.")
}
log.info("ValidateToken success. meetingId=" + props.meetingProp.intId + " userId=" + msg.userId)
//join the user
handleUserJoin(new UserJoining(props.meetingProp.intId, msg.userId, msg.token))
case None =>
log.info("ValidateToken failed. meetingId=" + props.meetingProp.intId + " userId=" + msg.userId)
outGW.send(new ValidateAuthTokenReply(props.meetingProp.intId, msg.userId, msg.token, false, msg.correlationId))
for {
moderator <- Users2x.findModerator(liveMeeting.users2x)
newPresenter <- Users2x.makePresenter(liveMeeting.users2x, moderator.intId)
} yield {
log.debug("sending assigned presenter for intId={} name={}", newPresenter.intId, newPresenter.name)
sendPresenterAssigned(newPresenter.intId, newPresenter.name, newPresenter.name)
}
}
def handleRegisterUser(msg: RegisterUser) {
if (MeetingStatus2x.hasMeetingEnded(liveMeeting.status)) {
// Check first if the meeting has ended and the user refreshed the client to re-connect.
log.info("Register user failed. Mmeeting has ended. meetingId=" + props.meetingProp.intId + " userId=" + msg.userID)
sendMeetingHasEnded(msg.userID)
} else {
val regUser = RegisteredUsers.create(msg.userID, msg.extUserID, msg.name, msg.role, msg.authToken,
msg.avatarURL, msg.guest, msg.authed, msg.guest, liveMeeting.registeredUsers)
def sendPresenterAssigned(intId: String, name: String, assignedBy: String): Unit = {
def build(meetingId: String, intId: String, name: String, assignedBy: String): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, intId)
val envelope = BbbCoreEnvelope(PresenterAssignedEvtMsg.NAME, routing)
log.info("Register user success. meetingId=" + props.meetingProp.intId + " userId=" + msg.userID + " user=" + regUser)
outGW.send(new UserRegistered(props.meetingProp.intId, props.recordProp.record, regUser))
val body = PresenterAssignedEvtMsgBody(intId, name, assignedBy)
val header = BbbClientMsgHeader(PresenterAssignedEvtMsg.NAME, meetingId, intId)
val event = PresenterAssignedEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
def event = build(props.meetingProp.intId, intId, name, assignedBy)
outGW.send(event)
}
def usersWhoAreNotPresenter(): Array[UserVO] = {
@ -117,26 +127,6 @@ trait UsersApp {
}
def handleUserMutedInVoiceConfMessage(msg: UserMutedInVoiceConfMessage) {
for {
user <- Users.getUserWithVoiceUserId(msg.voiceUserId, liveMeeting.users)
nu = Users.setUserMuted(user, liveMeeting.users, msg.muted)
} yield {
log.info("User muted in voice conf. meetingId=" + props.meetingProp.intId + " userId=" + nu.id + " user=" + nu)
outGW.send(new UserVoiceMuted(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf, nu))
}
}
def handleUserTalkingInVoiceConfMessage(msg: UserTalkingInVoiceConfMessage) {
for {
user <- Users.getUserWithVoiceUserId(msg.voiceUserId, liveMeeting.users)
nv = Users.setUserTalking(user, liveMeeting.users, msg.talking)
} yield {
outGW.send(new UserVoiceTalking(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf, nv))
}
}
def handleAssignPresenter(msg: AssignPresenter): Unit = {
assignNewPresenter(msg.newPresenterID, msg.newPresenterName, msg.assignedBy)
}

View File

@ -9,10 +9,10 @@ import org.bigbluebutton.core2.message.handlers.whiteboard.UndoWhiteboardPubMsgH
import org.bigbluebutton.core2.message.handlers.whiteboard.ModifyWhiteboardAccessPubMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.GetWhiteboardAccessReqMsgHdlr
import org.bigbluebutton.core2.message.handlers.whiteboard.SendWhiteboardAnnotationPubMsgHdlr
import org.bigbluebutton.common2.domain.AnnotationProps
import org.bigbluebutton.common2.domain.AnnotationVO
import org.bigbluebutton.core2.message.handlers.whiteboard.GetWhiteboardAnnotationsReqMsgHdlr
case class Whiteboard(id: String, annotationCount: Int, annotationsMap: scala.collection.immutable.Map[String, scala.collection.immutable.List[AnnotationProps]])
case class Whiteboard(id: String, annotationCount: Int, annotationsMap: scala.collection.immutable.Map[String, scala.collection.immutable.List[AnnotationVO]])
trait WhiteboardApp
extends SendCursorPositionPubMsgHdlr
@ -26,9 +26,9 @@ trait WhiteboardApp
val outGW: OutMessageGateway
def sendWhiteboardAnnotation(annotation: AnnotationProps): AnnotationProps = {
def sendWhiteboardAnnotation(annotation: AnnotationVO): AnnotationVO = {
// println("Received whiteboard annotation. status=[" + status + "], annotationType=[" + annotationType + "]")
var rtnAnnotation: AnnotationProps = annotation
var rtnAnnotation: AnnotationVO = annotation
if (WhiteboardKeyUtil.DRAW_START_STATUS == annotation.status) {
rtnAnnotation = liveMeeting.wbModel.addAnnotation(annotation.wbId, annotation.userId, annotation)
@ -51,7 +51,7 @@ trait WhiteboardApp
rtnAnnotation
}
def getWhiteboardAnnotations(whiteboardId: String): Array[AnnotationProps] = {
def getWhiteboardAnnotations(whiteboardId: String): Array[AnnotationVO] = {
//println("WB: Received page history [" + msg.whiteboardId + "]")
liveMeeting.wbModel.getHistory(whiteboardId)
}
@ -60,7 +60,7 @@ trait WhiteboardApp
liveMeeting.wbModel.clearWhiteboard(whiteboardId, requesterId)
}
def undoWhiteboard(whiteboardId: String, requesterId: String): Option[AnnotationProps] = {
def undoWhiteboard(whiteboardId: String, requesterId: String): Option[AnnotationVO] = {
liveMeeting.wbModel.undoWhiteboard(whiteboardId, requesterId)
}

View File

@ -5,7 +5,7 @@ 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.domain.AnnotationProps
import org.bigbluebutton.common2.domain.AnnotationVO
class WhiteboardModel {
private var _whiteboards = new HashMap[String, Whiteboard]()
@ -25,14 +25,14 @@ class WhiteboardModel {
}
private def createWhiteboard(wbId: String): Whiteboard = {
new Whiteboard(wbId, 0, new HashMap[String, List[AnnotationProps]]())
new Whiteboard(wbId, 0, new HashMap[String, List[AnnotationVO]]())
}
private def getAnnotationsByUserId(wb: Whiteboard, id: String): List[AnnotationProps] = {
wb.annotationsMap.get(id).getOrElse(List[AnnotationProps]())
private def getAnnotationsByUserId(wb: Whiteboard, id: String): List[AnnotationVO] = {
wb.annotationsMap.get(id).getOrElse(List[AnnotationVO]())
}
def addAnnotation(wbId: String, userId: String, annotation: AnnotationProps): AnnotationProps = {
def addAnnotation(wbId: String, userId: String, annotation: AnnotationVO): AnnotationVO = {
val wb = getWhiteboard(wbId)
val usersAnnotations = getAnnotationsByUserId(wb, userId)
val rtnAnnotation = cleansePointsInAnnotation(annotation).copy(position = wb.annotationCount)
@ -45,7 +45,7 @@ class WhiteboardModel {
rtnAnnotation
}
def updateAnnotation(wbId: String, userId: String, annotation: AnnotationProps): AnnotationProps = {
def updateAnnotation(wbId: String, userId: String, annotation: AnnotationVO): AnnotationVO = {
val wb = getWhiteboard(wbId)
val usersAnnotations = getAnnotationsByUserId(wb, userId)
@ -63,7 +63,7 @@ class WhiteboardModel {
}
}
def updateAnnotationPencil(wbId: String, userId: String, annotation: AnnotationProps): AnnotationProps = {
def updateAnnotationPencil(wbId: String, userId: String, annotation: AnnotationVO): AnnotationVO = {
val wb = getWhiteboard(wbId)
val usersAnnotations = getAnnotationsByUserId(wb, userId)
@ -97,8 +97,8 @@ class WhiteboardModel {
}
}
def endAnnotationPencil(wbId: String, userId: String, annotation: AnnotationProps): AnnotationProps = {
var rtnAnnotation: AnnotationProps = annotation
def endAnnotationPencil(wbId: String, userId: String, annotation: AnnotationVO): AnnotationVO = {
var rtnAnnotation: AnnotationVO = annotation
val wb = getWhiteboard(wbId)
val usersAnnotations = getAnnotationsByUserId(wb, userId)
@ -146,7 +146,7 @@ class WhiteboardModel {
rtnAnnotation
}
def getHistory(wbId: String): Array[AnnotationProps] = {
def getHistory(wbId: String): Array[AnnotationVO] = {
val wb = getWhiteboard(wbId)
wb.annotationsMap.values.flatten.toArray.sortBy(_.position);
}
@ -165,7 +165,7 @@ class WhiteboardModel {
}
} else {
if (wb.annotationsMap.nonEmpty) {
val newWb = wb.copy(annotationsMap = new HashMap[String, List[AnnotationProps]]())
val newWb = wb.copy(annotationsMap = new HashMap[String, List[AnnotationVO]]())
saveWhiteboard(newWb)
cleared = Some(true)
}
@ -174,8 +174,8 @@ class WhiteboardModel {
cleared
}
def undoWhiteboard(wbId: String, userId: String): Option[AnnotationProps] = {
var last: Option[AnnotationProps] = None
def undoWhiteboard(wbId: String, userId: String): Option[AnnotationVO] = {
var last: Option[AnnotationVO] = None
val wb = getWhiteboard(wbId)
if (_multiUser) {
@ -202,7 +202,7 @@ class WhiteboardModel {
last
}
private def removeHeadAnnotation(wb: Whiteboard, key: String, list: List[AnnotationProps]): Whiteboard = {
private def removeHeadAnnotation(wb: Whiteboard, key: String, list: List[AnnotationVO]): Whiteboard = {
val newAnnotationsMap = if (list.tail == Nil) wb.annotationsMap - key else wb.annotationsMap + (key -> list.tail)
wb.copy(annotationsMap = newAnnotationsMap)
}
@ -215,7 +215,7 @@ class WhiteboardModel {
_multiUser
}
def cleansePointsInAnnotation(ann: AnnotationProps): AnnotationProps = {
def cleansePointsInAnnotation(ann: AnnotationVO): AnnotationVO = {
var updatedAnnotationInfo = ann.annotationInfo
ann.annotationInfo.get("points").foreach(points =>
updatedAnnotationInfo = (ann.annotationInfo + ("points" -> convertListNumbersToFloat(points.asInstanceOf[List[_]])))

View File

@ -2,7 +2,7 @@ package org.bigbluebutton.core.apps.caption
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.common2.domain.TranscriptVO
import org.bigbluebutton.common2.messages.caption.TranscriptVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ EditCaptionHistoryEvtMsgBody }
import org.bigbluebutton.common2.messages.caption.{ EditCaptionHistoryPubMsg, EditCaptionHistoryEvtMsg, EditCaptionHistoryEvtMsgBody }
import org.bigbluebutton.common2.messages._
trait EditCaptionHistoryPubMsgHdlr {

View File

@ -1,8 +1,8 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.domain.TranscriptVO
import org.bigbluebutton.common2.messages.MessageBody.{ SendCaptionHistoryRespMsgBody }
import org.bigbluebutton.common2.messages.caption.TranscriptVO
import org.bigbluebutton.common2.messages.caption.{ SendCaptionHistoryReqMsg, SendCaptionHistoryRespMsg, SendCaptionHistoryRespMsgBody }
import org.bigbluebutton.common2.messages._
trait SendCaptionHistoryReqMsgHdlr {

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core.apps.caption
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ UpdateCaptionOwnerEvtMsgBody }
import org.bigbluebutton.common2.messages.caption.{ UpdateCaptionOwnerPubMsg, UpdateCaptionOwnerEvtMsg, UpdateCaptionOwnerEvtMsgBody }
import org.bigbluebutton.common2.messages._
trait UpdateCaptionOwnerPubMsgHdlr {

View File

@ -0,0 +1,34 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.GetPresentationInfoRespMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.core.apps.Presentation
trait GetPresentationInfoReqMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handleGetPresentationInfoReqMsg(msg: GetPresentationInfoReqMsg): Unit = {
log.debug("Received GetPresentationInfoReqMsg")
def broadcastEvent(msg: GetPresentationInfoReqMsg, presentations: Vector[Presentation]): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(GetPresentationInfoRespMsg.NAME, routing)
val header = BbbClientMsgHeader(GetPresentationInfoRespMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val presVOs = presentations.map { p =>
PresentationVO(p.id, p.name, p.current, p.pages.values.toVector, p.downloadable)
}
val body = GetPresentationInfoRespMsgBody(presVOs)
val event = GetPresentationInfoRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
broadcastEvent(msg, getPresentationInfo())
}
}

View File

@ -0,0 +1,25 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.NewPresentationEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.domain.PresentationVO
trait NewPresentationMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def broadcastNewPresentationEvent(userId: String, presentation: PresentationVO): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, userId)
val envelope = BbbCoreEnvelope(NewPresentationEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(NewPresentationEvtMsg.NAME, liveMeeting.props.meetingProp.intId, userId)
val body = NewPresentationEvtMsgBody(presentation)
val event = NewPresentationEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
}

View File

@ -2,12 +2,72 @@ package org.bigbluebutton.core.apps.presentation
import akka.actor.ActorContext
import akka.event.Logging
import org.bigbluebutton.common2.domain.PresentationVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.apps.Presentation
class PresentationApp2x(val liveMeeting: LiveMeeting,
val outGW: OutMessageGateway)(implicit val context: ActorContext)
extends EjectUserFromMeetingHdlr {
extends EjectUserFromMeetingHdlr
with NewPresentationMsgHdlr
with SetCurrentPresentationPubMsgHdlr
with GetPresentationInfoReqMsgHdlr
with SetCurrentPagePubMsgHdlr
with ResizeAndMovePagePubMsgHdlr
with RemovePresentationPubMsgHdlr
with PreuploadedPresentationsPubMsgHdlr
with PresentationConversionUpdatePubMsgHdlr
with PresentationPageCountErrorPubMsgHdlr
with PresentationPageGeneratedPubMsgHdlr
with PresentationConversionCompletedPubMsgHdlr {
val log = Logging(context.system, getClass)
def processPreuploadedPresentations(presentations: Vector[Presentation]) {
presentations.foreach(presentation => {
liveMeeting.presModel.addPresentation(presentation)
})
}
def presentationConversionCompleted(presentation: Presentation) {
liveMeeting.presModel.addPresentation(presentation)
}
def setCurrentPresentation(presentationId: String): Option[Presentation] = {
liveMeeting.presModel.setCurrentPresentation(presentationId)
}
def getPresentationInfo(): Vector[Presentation] = {
liveMeeting.presModel.getPresentations
}
def setCurrentPage(presentationId: String, pageId: String): Boolean = {
liveMeeting.presModel.changeCurrentPage(presentationId, pageId)
/* Need to figure out if this is still needed and if it is how to do it now
Users.getCurrentPresenter(liveMeeting.users) foreach { pres =>
handleStopPollRequest(StopPollRequest(props.meetingProp.intId, pres.id))
}
*/
}
def resizeAndMovePage(presentationId: String, pageId: String,
xOffset: Double, yOffset: Double, widthRatio: Double,
heightRatio: Double): Option[PageVO] = {
// Force coordinate that are out-of-bounds inside valid values
// 0.25D is 400% zoom
// 100D-checkedWidth is the maximum the page can be moved over
val checkedWidth = Math.min(Math.max(widthRatio, 25D), 100D) //if (widthRatio <= 100D) widthRatio else 100D
val checkedHeight = Math.min(Math.max(heightRatio, 25D), 100D)
val checkedXOffset = Math.min(Math.max(xOffset, 0D), 100D - checkedWidth)
val checkedYOffset = Math.min(Math.max(yOffset, 0D), 100D - checkedHeight)
liveMeeting.presModel.resizePage(presentationId, pageId, checkedXOffset, checkedYOffset, checkedWidth, checkedHeight);
}
def removePresentation(presentationId: String): Option[Presentation] = {
liveMeeting.presModel.removePresentation(presentationId)
}
}

View File

@ -0,0 +1,45 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.PresentationConversionCompletedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.core.apps.Presentation
trait PresentationConversionCompletedPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handlePresentationConversionCompletedPubMsg(msg: PresentationConversionCompletedPubMsg): Unit = {
log.debug("PresentationConversionCompletedPubMsg ")
def broadcastEvent(msg: PresentationConversionCompletedPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(PresentationConversionCompletedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(PresentationConversionCompletedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = PresentationConversionCompletedEvtMsgBody(msg.body.messageKey, msg.body.code, msg.body.presentation)
val event = PresentationConversionCompletedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
val pages = new collection.mutable.HashMap[String, PageVO]
msg.body.presentation.pages.foreach { p =>
val page = PageVO(p.id, p.num, p.thumbUri, p.swfUri, p.txtUri, p.svgUri, p.current, p.xOffset, p.yOffset,
p.widthRatio, p.heightRatio)
pages += page.id -> page
}
val pres = new Presentation(msg.body.presentation.id, msg.body.presentation.name, msg.body.presentation.current,
pages.toMap, msg.body.presentation.downloadable)
log.debug("PresentationConversionCompletedPubMsg name={}", pres.name)
presentationConversionCompleted(pres)
broadcastEvent(msg)
}
}

View File

@ -0,0 +1,29 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.PresentationConversionUpdateEvtMsgBody
import org.bigbluebutton.common2.messages._
trait PresentationConversionUpdatePubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handlePresentationConversionUpdatePubMsg(msg: PresentationConversionUpdatePubMsg): Unit = {
def broadcastEvent(msg: PresentationConversionUpdatePubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(PresentationConversionUpdateEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(PresentationConversionUpdateEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = PresentationConversionUpdateEvtMsgBody(msg.body.messageKey, msg.body.code, msg.body.presentationId, msg.body.presName)
val event = PresentationConversionUpdateEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
broadcastEvent(msg)
}
}

View File

@ -0,0 +1,29 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.PresentationPageCountErrorEvtMsgBody
import org.bigbluebutton.common2.messages._
trait PresentationPageCountErrorPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handlePresentationPageCountErrorPubMsg(msg: PresentationPageCountErrorPubMsg): Unit = {
def broadcastEvent(msg: PresentationPageCountErrorPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(PresentationPageCountErrorEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(PresentationPageCountErrorEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = PresentationPageCountErrorEvtMsgBody(msg.body.messageKey, msg.body.code, msg.body.presentationId, msg.body.numberOfPages, msg.body.maxNumberPages, msg.body.presName)
val event = PresentationPageCountErrorEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
broadcastEvent(msg)
}
}

View File

@ -0,0 +1,29 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.PresentationPageGeneratedEvtMsgBody
import org.bigbluebutton.common2.messages._
trait PresentationPageGeneratedPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handlePresentationPageGeneratedPubMsg(msg: PresentationPageGeneratedPubMsg): Unit = {
def broadcastEvent(msg: PresentationPageGeneratedPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(PresentationPageGeneratedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(PresentationPageGeneratedEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = PresentationPageGeneratedEvtMsgBody(msg.body.messageKey, msg.body.code, msg.body.presentationId, msg.body.numberOfPages, msg.body.pagesCompleted, msg.body.presName)
val event = PresentationPageGeneratedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
broadcastEvent(msg)
}
}

View File

@ -0,0 +1,37 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.common2.domain.PageVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.core.apps.Presentation
trait PreuploadedPresentationsPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handlePreuploadedPresentationsPubMsg(msg: PreuploadedPresentationsPubMsg): Unit = {
val presos = new collection.mutable.HashMap[String, Presentation]
msg.body.presentations.foreach { pres =>
val pages = new collection.mutable.HashMap[String, PageVO]()
pres.pages.foreach { p =>
val page = new PageVO(p.id, p.num, p.thumbUri, p.swfUri, p.txtUri, p.svgUri, p.current, p.xOffset, p.yOffset,
p.widthRatio, p.heightRatio)
pages += page.id -> page
}
val pr = new Presentation(pres.id, pres.name, pres.current,
pages.toMap, pres.downloadable)
presos += pres.id -> pr
}
processPreuploadedPresentations(presos.values.toVector)
msg.body.presentations foreach (presentation => {
broadcastNewPresentationEvent(msg.header.userId, presentation)
})
}
}

View File

@ -0,0 +1,33 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.RemovePresentationEvtMsgBody
import org.bigbluebutton.common2.messages._
trait RemovePresentationPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handleRemovePresentationPubMsg(msg: RemovePresentationPubMsg): Unit = {
def broadcastEvent(msg: RemovePresentationPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(RemovePresentationEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(RemovePresentationEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = RemovePresentationEvtMsgBody(msg.body.presentationId)
val event = RemovePresentationEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
for {
presentation <- removePresentation(msg.body.presentationId)
} yield {
broadcastEvent(msg)
}
}
}

View File

@ -0,0 +1,34 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.ResizeAndMovePageEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.domain.PageVO
trait ResizeAndMovePagePubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handleResizeAndMovePagePubMsg(msg: ResizeAndMovePagePubMsg): Unit = {
def broadcastEvent(msg: ResizeAndMovePagePubMsg, page: PageVO): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(ResizeAndMovePageEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(ResizeAndMovePageEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = ResizeAndMovePageEvtMsgBody(msg.body.presentationId, page.id, page.xOffset, page.yOffset, page.widthRatio, page.heightRatio)
val event = ResizeAndMovePageEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
for {
page <- resizeAndMovePage(msg.body.presentationId, msg.body.pageId, msg.body.xOffset, msg.body.yOffset, msg.body.widthRatio, msg.body.heightRatio)
} yield {
broadcastEvent(msg, page)
}
}
}

View File

@ -0,0 +1,31 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.SetCurrentPageEvtMsgBody
import org.bigbluebutton.common2.messages._
trait SetCurrentPagePubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handleSetCurrentPagePubMsg(msg: SetCurrentPagePubMsg): Unit = {
def broadcastEvent(msg: SetCurrentPagePubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(SetCurrentPageEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(SetCurrentPageEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = SetCurrentPageEvtMsgBody(msg.body.presentationId, msg.body.pageId)
val event = SetCurrentPageEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
if (setCurrentPage(msg.body.presentationId, msg.body.pageId)) {
broadcastEvent(msg)
}
}
}

View File

@ -0,0 +1,33 @@
package org.bigbluebutton.core.apps.presentation
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.SetCurrentPresentationEvtMsgBody
import org.bigbluebutton.common2.messages._
trait SetCurrentPresentationPubMsgHdlr {
this: PresentationApp2x =>
val outGW: OutMessageGateway
def handleSetCurrentPresentationPubMsg(msg: SetCurrentPresentationPubMsg): Unit = {
def broadcastEvent(msg: SetCurrentPresentationPubMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, liveMeeting.props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(SetCurrentPresentationEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(SetCurrentPresentationEvtMsg.NAME, liveMeeting.props.meetingProp.intId, msg.header.userId)
val body = SetCurrentPresentationEvtMsgBody(msg.body.presentationId)
val event = SetCurrentPresentationEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
//record(event)
}
for {
presentation <- setCurrentPresentation(msg.body.presentationId)
} yield {
broadcastEvent(msg)
}
}
}

View File

@ -0,0 +1,40 @@
package org.bigbluebutton.core.models
object GuestsWaiting {
def findWithIntId(guests: GuestsWaiting, intId: String): Option[GuestWaiting] = {
guests.toVector find (u => u.intId == intId)
}
def findAll(guests: GuestsWaiting): Vector[GuestWaiting] = guests.toVector
def add(guests: GuestsWaiting, user: GuestWaiting): Option[GuestWaiting] = {
guests.save(user)
Some(user)
}
def remove(guests: GuestsWaiting, intId: String): Option[GuestWaiting] = {
guests.remove(intId)
}
}
class GuestsWaiting {
private var guests: collection.immutable.HashMap[String, GuestWaiting] = new collection.immutable.HashMap[String, GuestWaiting]
private def toVector: Vector[GuestWaiting] = guests.values.toVector
private def save(user: GuestWaiting): GuestWaiting = {
guests += user.intId -> user
user
}
private def remove(id: String): Option[GuestWaiting] = {
for {
user <- guests.get(id)
} yield {
guests -= id
user
}
}
}
case class GuestWaiting(intId: String, name: String, role: String)

View File

@ -0,0 +1,31 @@
package org.bigbluebutton.core.models
object Layouts {
private var setByUser: String = "system";
private var currentLayout = "";
// this is not being set by the client, and we need to apply the layouts to all users, not just viewers, so will keep the default value of this as false
private var affectViewersOnly = false
def setCurrentLayout(layout: String) {
currentLayout = layout
}
def getCurrentLayout(): String = {
currentLayout
}
def applyToViewersOnly(viewersOnly: Boolean) {
affectViewersOnly = viewersOnly
}
def doesLayoutApplyToViewersOnly(): Boolean = {
affectViewersOnly
}
def getLayoutSetter(): String = {
setByUser
}
}
class Layouts {
}

View File

@ -1,5 +1,7 @@
package org.bigbluebutton.core.models
import org.bigbluebutton.common2.domain.UserVO
object RegisteredUsers {
def create(userId: String, extId: String, name: String, roles: String,
token: String, avatar: String, guest: Boolean, authenticated: Boolean,

View File

@ -1,11 +1,16 @@
package org.bigbluebutton.core.models
import scala.collection.immutable.ListSet
import org.bigbluebutton.core.util.RandomStringGenerator
import com.softwaremill.quicklens.ModifyPimp
import com.softwaremill.quicklens.modify
import org.bigbluebutton.common2.domain.{ UserVO, VoiceUserVO }
object CallingWith {
val WEBRTC = "webrtc"
val FLASH = "flash"
val PHONE = "phone"
}
object Roles {
val MODERATOR_ROLE = "MODERATOR"
@ -17,7 +22,7 @@ object Roles {
object Users {
def newUser(userId: String, lockStatus: Boolean, ru: RegisteredUser, waitingForAcceptance: Boolean,
vu: VoiceUser, users: Users): Option[UserVO] = {
vu: VoiceUserVO, users: Users): Option[UserVO] = {
val uvo = new UserVO(userId, ru.externId, ru.name,
ru.role, ru.guest, ru.authed, waitingForAcceptance = waitingForAcceptance, emojiStatus = "none", presenter = false,
hasStream = false, locked = lockStatus,
@ -189,7 +194,7 @@ object Users {
}
def resetVoiceUser(user: UserVO, users: Users): UserVO = {
val vu = new VoiceUser(user.id, user.id, user.name, user.name,
val vu = new VoiceUserVO(user.id, user.id, user.name, user.name,
joined = false, locked = false, muted = false, talking = false, user.avatarURL, listenOnly = false)
val nu = user.modify(_.voiceUser).setTo(vu)
@ -202,7 +207,7 @@ object Users {
def switchUserToPhoneUser(user: UserVO, users: Users, voiceUserId: String, userId: String,
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean,
avatarURL: String, listenOnly: Boolean): UserVO = {
val vu = new VoiceUser(voiceUserId, userId, callerIdName,
val vu = new VoiceUserVO(voiceUserId, userId, callerIdName,
callerIdNum, joined = true, locked = false,
muted, talking, avatarURL, listenOnly)
val nu = user.modify(_.voiceUser).setTo(vu)
@ -214,7 +219,7 @@ object Users {
def restoreMuteState(user: UserVO, users: Users, voiceUserId: String, userId: String,
callerIdName: String, callerIdNum: String, muted: Boolean, talking: Boolean,
avatarURL: String, listenOnly: Boolean): UserVO = {
val vu = new VoiceUser(voiceUserId, userId, callerIdName,
val vu = new VoiceUserVO(voiceUserId, userId, callerIdName,
callerIdNum, joined = true, locked = false,
muted, talking, avatarURL, listenOnly)
val nu = user.modify(_.voiceUser).setTo(vu)
@ -223,7 +228,7 @@ object Users {
nu
}
def makeUserPhoneUser(vu: VoiceUser, users: Users, webUserId: String, externUserId: String,
def makeUserPhoneUser(vu: VoiceUserVO, users: Users, webUserId: String, externUserId: String,
callerIdName: String, lockStatus: Boolean, listenOnly: Boolean, avatarURL: String): UserVO = {
val uvo = new UserVO(webUserId, externUserId, callerIdName,
Roles.VIEWER_ROLE, guest = false, authed = false, waitingForAcceptance = false, emojiStatus = "none", presenter = false,
@ -256,6 +261,7 @@ class Users {
case class UserIdAndName(id: String, name: String)
/*
case class UserVO(id: String, externalId: String, name: String, role: String,
guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emojiStatus: String,
presenter: Boolean, hasStream: Boolean, locked: Boolean, webcamStreams: Set[String],
@ -265,3 +271,4 @@ case class UserVO(id: String, externalId: String, name: String, role: String,
case class VoiceUser(userId: String, webUserId: String, callerName: String,
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
talking: Boolean, avatarURL: String, listenOnly: Boolean)
*/

View File

@ -45,14 +45,35 @@ object Users2x {
for {
u <- findWithIntId(users, intId)
} yield {
val newUser = u.modify(_.presenter).setTo(true).modify(_.role).setTo(Roles.PRESENTER_ROLE)
val newUser = u.modify(_.presenter).setTo(true)
users.save(newUser)
newUser
}
}
def setEmojiStatus(users: Users2x, intId: String, emoji: String): Option[UserState] = {
for {
u <- findWithIntId(users, intId)
} yield {
val newUser = u.modify(_.emoji).setTo(emoji)
users.save(newUser)
newUser
}
}
def hasPresenter(users: Users2x): Boolean = {
findPresenter(users) match {
case Some(p) => true
case None => false
}
}
def findPresenter(users: Users2x): Option[UserState] = {
users.toVector.find(u => u.presenter)
}
def findModerator(users: Users2x): Option[UserState] = {
val mods = users.toVector.filter(u => u.role == Roles.MODERATOR_ROLE)
if (mods.length > 1) Some(mods.head) else None
users.toVector.find(u => u.role == Roles.MODERATOR_ROLE)
}
}

View File

@ -4,7 +4,7 @@ import com.softwaremill.quicklens._
object VoiceUsers {
def findWithVoiceUserId(users: VoiceUsers, voiceUserId: String): Option[VoiceUserState] = {
users.toVector find (u => u.intId == voiceUserId)
users.toVector find (u => u.voiceUserId == voiceUserId)
}
def findWIthIntId(users: VoiceUsers, intId: String): Option[VoiceUserState] = {
@ -25,6 +25,30 @@ object VoiceUsers {
users.toVector.find(u => u.intId == intId)
}
def userMuted(users: VoiceUsers, voiceUserId: String, muted: Boolean): Option[VoiceUserState] = {
for {
u <- findWithVoiceUserId(users, voiceUserId)
} yield {
val vu = u.modify(_.muted).setTo(muted)
.modify(_.talking).setTo(false)
.modify(_.listenOnly).setTo(false)
users.save(vu)
vu
}
}
def userTalking(users: VoiceUsers, voiceUserId: String, talkng: Boolean): Option[VoiceUserState] = {
for {
u <- findWithVoiceUserId(users, voiceUserId)
} yield {
val vu = u.modify(_.muted).setTo(false)
.modify(_.talking).setTo(talkng)
.modify(_.listenOnly).setTo(false)
users.save(vu)
vu
}
}
def joinedVoiceListenOnly(users: VoiceUsers, userId: String): Option[VoiceUserState] = {
for {
u <- findWIthIntId(users, userId)

View File

@ -4,10 +4,10 @@ import org.bigbluebutton.core.api._
import org.bigbluebutton.core.messaging.Util
import org.bigbluebutton.core.apps.Page
import scala.collection.JavaConverters
object PesentationMessageToJsonConverter {
/*
private def pageToMap(page: Page): java.util.Map[String, Any] = {
val res = new scala.collection.mutable.HashMap[String, Any]
val res = new scala.collection.mutable.Map[String, Any]
res += "id" -> page.id
res += "num" -> page.num
res += "thumb_uri" -> page.thumbUri
@ -20,9 +20,9 @@ object PesentationMessageToJsonConverter {
res += "width_ratio" -> page.widthRatio
res += "height_ratio" -> page.heightRatio
JavaConverters.mapAsJavaMap(res)
JavaConverters.mapAsScalaMap(res)
}
*/
def clearPresentationOutMsgToJson(msg: ClearPresentationOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
@ -67,9 +67,9 @@ object PesentationMessageToJsonConverter {
// Get the pages for a presentation
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
pres.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// pres.pages.values foreach { p =>
// pages.add(p)
// }
// store the pages in the presentation
presentation.put(Constants.PAGES, pages)
@ -87,7 +87,7 @@ object PesentationMessageToJsonConverter {
def resizeAndMoveSlideOutMsgToJson(msg: ResizeAndMoveSlideOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.PAGE, pageToMap(msg.page))
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_RESIZED, None)
Util.buildJson(header, payload)
@ -96,7 +96,7 @@ object PesentationMessageToJsonConverter {
def gotoSlideOutMsgToJson(msg: GotoSlideOutMsg): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.PAGE, pageToMap(msg.page))
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_CHANGED, None)
Util.buildJson(header, payload)
@ -114,9 +114,9 @@ object PesentationMessageToJsonConverter {
// Get the pages for a presentation
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
msg.presentation.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// msg.presentation.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
// store the pages in the presentation
presentation.put(Constants.PAGES, pages)
@ -131,7 +131,7 @@ object PesentationMessageToJsonConverter {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
payload.put(Constants.PAGE, pageToMap(msg.page))
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.GET_SLIDE_INFO_REPLY, None)
Util.buildJson(header, payload)
@ -198,9 +198,9 @@ object PesentationMessageToJsonConverter {
presentation.put(Constants.DOWNLOADABLE, msg.presentation.downloadable: java.lang.Boolean)
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
msg.presentation.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// msg.presentation.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
presentation.put(Constants.PAGES, pages)
@ -220,9 +220,9 @@ object PesentationMessageToJsonConverter {
presentation.put(Constants.DOWNLOADABLE, msg.presentation.downloadable: java.lang.Boolean)
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
msg.presentation.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// msg.presentation.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
presentation.put(Constants.PAGES, pages)
payload.put(Constants.PRESENTATION, presentation);
@ -243,9 +243,9 @@ object PesentationMessageToJsonConverter {
val pages = new java.util.ArrayList[java.util.Map[String, Any]]()
msg.current.pages.values foreach { p =>
pages.add(pageToMap(p))
}
// msg.current.pages.values foreach { p =>
// pages.add(pageToMap(p))
// }
presentation.put(Constants.PAGES, pages)
@ -267,7 +267,7 @@ object PesentationMessageToJsonConverter {
def pageChangedToJson(msg: PageChanged): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.PAGE, pageToMap(msg.page))
// payload.put(Constants.PAGE, pageToMap(msg.page))
val header = Util.buildHeader(MessageNames.PRESENTATION_PAGE_CHANGED, None)
Util.buildJson(header, payload)

View File

@ -5,9 +5,15 @@ import org.bigbluebutton.SystemConfiguration
import com.fasterxml.jackson.databind.JsonNode
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.breakoutrooms._
import org.bigbluebutton.common2.messages.caption._
import org.bigbluebutton.common2.messages.polls._
import org.bigbluebutton.common2.messages.users._
import org.bigbluebutton.common2.messages.layout._
import org.bigbluebutton.common2.messages.voiceconf._
import org.bigbluebutton.common2.messages.whiteboard._
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core2.ReceivedMessageRouter
import scala.reflect.runtime.universe._
object ReceivedJsonMsgHandlerActor {
@ -45,7 +51,9 @@ class ReceivedJsonMsgHandlerActor(
}
def handle(envelope: BbbCoreEnvelope, jsonNode: JsonNode): Unit = {
if (SendCursorPositionPubMsg.NAME != envelope.name)
log.debug("Route envelope name " + envelope.name)
envelope.name match {
case CreateMeetingReqMsg.NAME =>
// for {
@ -213,6 +221,30 @@ class ReceivedJsonMsgHandlerActor(
} yield {
send(m.header.meetingId, envelope, m)
}
case GetCurrentLayoutMsg.NAME =>
for {
m <- deserialize[GetCurrentLayoutMsg](jsonNode)
} yield {
send(m.header.meetingId, envelope, m)
}
case LockLayoutMsg.NAME =>
for {
m <- deserialize[LockLayoutMsg](jsonNode)
} yield {
send(m.header.meetingId, envelope, m)
}
case BroadcastLayoutMsg.NAME =>
for {
m <- deserialize[BroadcastLayoutMsg](jsonNode)
} yield {
send(m.header.meetingId, envelope, m)
}
case UserLeaveReqMsg.NAME =>
for {
m <- deserialize[UserLeaveReqMsg](jsonNode)
} yield {
send(m.header.meetingId, envelope, m)
}
case SendCursorPositionPubMsg.NAME =>
routeGenericMsg[SendCursorPositionPubMsg](envelope, jsonNode)
case ModifyWhiteboardAccessPubMsg.NAME =>
@ -227,6 +259,26 @@ class ReceivedJsonMsgHandlerActor(
routeGenericMsg[SendWhiteboardAnnotationPubMsg](envelope, jsonNode)
case GetWhiteboardAnnotationsReqMsg.NAME =>
routeGenericMsg[GetWhiteboardAnnotationsReqMsg](envelope, jsonNode)
case SetCurrentPresentationPubMsg.NAME =>
routeGenericMsg[SetCurrentPresentationPubMsg](envelope, jsonNode)
case GetPresentationInfoReqMsg.NAME =>
routeGenericMsg[GetPresentationInfoReqMsg](envelope, jsonNode)
case SetCurrentPagePubMsg.NAME =>
routeGenericMsg[SetCurrentPagePubMsg](envelope, jsonNode)
case ResizeAndMovePagePubMsg.NAME =>
routeGenericMsg[ResizeAndMovePagePubMsg](envelope, jsonNode)
case RemovePresentationPubMsg.NAME =>
routeGenericMsg[RemovePresentationPubMsg](envelope, jsonNode)
case PreuploadedPresentationsPubMsg.NAME =>
routeGenericMsg[PreuploadedPresentationsPubMsg](envelope, jsonNode)
case PresentationConversionUpdatePubMsg.NAME =>
routeGenericMsg[PresentationConversionUpdatePubMsg](envelope, jsonNode)
case PresentationPageCountErrorPubMsg.NAME =>
routeGenericMsg[PresentationPageCountErrorPubMsg](envelope, jsonNode)
case PresentationPageGeneratedPubMsg.NAME =>
routeGenericMsg[PresentationPageGeneratedPubMsg](envelope, jsonNode)
case PresentationConversionCompletedPubMsg.NAME =>
routeGenericMsg[PresentationConversionCompletedPubMsg](envelope, jsonNode)
case EditCaptionHistoryPubMsg.NAME =>
routeGenericMsg[EditCaptionHistoryPubMsg](envelope, jsonNode)
case UpdateCaptionOwnerPubMsg.NAME =>

View File

@ -1,9 +1,11 @@
package org.bigbluebutton.core.pubsub.senders
import scala.collection.JavaConverters._
import org.bigbluebutton.common2.domain.UserVO
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.messaging.Util
import org.bigbluebutton.core.models.{ RegisteredUser, UserVO }
import scala.collection.JavaConverters._
import org.bigbluebutton.core.models.RegisteredUser
object UsersMessageToJsonConverter {
private def userToMap(user: UserVO): java.util.Map[String, Any] = {

View File

@ -12,6 +12,7 @@ class LiveMeeting(val props: DefaultProps,
val status: MeetingStatus2x,
val chatModel: ChatModel,
val layoutModel: LayoutModel,
val layouts: Layouts,
val users: Users,
val registeredUsers: RegisteredUsers,
val polls: Polls, // 2x
@ -23,7 +24,8 @@ class LiveMeeting(val props: DefaultProps,
val notesModel: SharedNotesModel,
val webcams: Webcams,
val voiceUsers: VoiceUsers,
val users2x: Users2x)
val users2x: Users2x,
val guestsWaiting: GuestsWaiting)
extends ChatModelTrait {
def hasMeetingEnded(): Boolean = {

View File

@ -1,30 +1,38 @@
package org.bigbluebutton.core.running
import java.io.{ PrintWriter, StringWriter }
import akka.actor._
import akka.actor.ActorLogging
import akka.actor.SupervisorStrategy.Resume
import org.bigbluebutton.common2.domain.DefaultProps
import org.bigbluebutton.common2.messages.MessageBody.ValidateAuthTokenRespMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.breakoutrooms._
import org.bigbluebutton.common2.messages.voiceconf.UserJoinedVoiceConfEvtMsg
import org.bigbluebutton.common2.messages.caption._
import org.bigbluebutton.common2.messages.polls._
import org.bigbluebutton.common2.messages.users._
import org.bigbluebutton.common2.messages.voiceconf.{ UserJoinedVoiceConfEvtMsg, UserLeftVoiceConfEvtMsg, UserMutedInVoiceConfEvtMsg, UserTalkingInVoiceConfEvtMsg }
import org.bigbluebutton.common2.messages.whiteboard._
import org.bigbluebutton.common2.messages.layout._
import org.bigbluebutton.core._
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.apps._
import org.bigbluebutton.core.apps.caption.CaptionApp2x
import org.bigbluebutton.core.apps.deskshare.DeskshareApp2x
import org.bigbluebutton.core.apps.presentation.PresentationApp2x
import org.bigbluebutton.core.apps.presentation.poll.PollApp2x
import org.bigbluebutton.core.apps.users.UsersApp2x
import org.bigbluebutton.core.bus._
import org.bigbluebutton.core.models.{ RegisteredUsers, Users, Polls }
import org.bigbluebutton.core.models.{ RegisteredUsers, Users }
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core2.message.handlers._
import org.bigbluebutton.core2.message.handlers.users._
import scala.concurrent.duration._
import org.bigbluebutton.core.models.BreakoutRooms
import org.bigbluebutton.core2.message.handlers.breakoutrooms._
import org.bigbluebutton.core.apps.caption.CaptionApp2x
import org.bigbluebutton.core2.testdata.FakeTestData
import org.bigbluebutton.core2.message.handlers.layout._
object MeetingActor {
def props(props: DefaultProps,
@ -42,13 +50,8 @@ class MeetingActor(val props: DefaultProps,
with BreakoutRoomApp
with SharedNotesApp with PermisssionCheck
with UserBroadcastCamStartMsgHdlr
with StartCustomPollReqMsgHdlr
with StopPollReqMsgHdlr
with ShowPollResultReqMsgHdlr
with HidePollResultReqMsgHdlr
with GetCurrentPollReqMsgHdlr
with RespondToPollReqMsgHdlr
with UserJoinedVoiceConfEvtMsgHdlr
with UserLeftVoiceConfEvtMsgHdlr
with UserJoinMeetingReqMsgHdlr
with StartPollReqMsgHdlr
with UserBroadcastCamStopMsgHdlr
@ -59,20 +62,12 @@ class MeetingActor(val props: DefaultProps,
with IsMeetingMutedRequestHdlr
with MuteUserRequestHdlr
with EjectUserFromVoiceRequestHdlr
with GetLockSettingsHdlr
with SetLockSettingsHdlr
with LockUserRequestHdlr
with InitLockSettingsHdlr
with InitAudioSettingsHdlr
with UserEmojiStatusHdlr
with EjectUserFromMeetingHdlr
with UserShareWebcamHdlr
with UserUnshareWebcamHdlr
with ChangeUserStatusHdlr
with GetUsersHdlr
with UserJoiningHdlr
with UserLeavingHdlr
with ChangeUserRoleHdlr
with StartCustomPollReqMsgHdlr
with StopPollReqMsgHdlr
with RespondToPollReqMsgHdlr
with GetCurrentPollReqMsgHdlr
with HidePollResultReqMsgHdlr
with ShowPollResultReqMsgHdlr
with UserJoinedVoiceConfMessageHdlr
with ValidateAuthTokenReqMsgHdlr
with BreakoutRoomsListMsgHdlr
@ -83,7 +78,12 @@ class MeetingActor(val props: DefaultProps,
with BreakoutRoomEndedMsgHdlr
with BreakoutRoomUsersUpdateMsgHdlr
with SendBreakoutUsersUpdateMsgHdlr
with TransferUserToMeetingRequestHdlr {
with TransferUserToMeetingRequestHdlr
with UserMutedInVoiceConfEvtMsgHdlr
with UserTalkingInVoiceConfEvtMsgHdlr
with GetCurrentLayoutMsgHdlr
with LockLayoutMsgHdlr
with BroadcastLayoutMsgHdlr {
override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case e: Exception => {
@ -113,6 +113,11 @@ class MeetingActor(val props: DefaultProps,
val deskshareApp2x = new DeskshareApp2x(liveMeeting, outGW = outGW)
val captionApp2x = new CaptionApp2x(liveMeeting, outGW = outGW)
/*******************************************************************/
//object FakeTestData extends FakeTestData
//FakeTestData.createFakeUsers(liveMeeting)
/*******************************************************************/
def receive = {
//=============================
// 2x messages
@ -125,34 +130,20 @@ class MeetingActor(val props: DefaultProps,
// old messages
case msg: ActivityResponse => handleActivityResponse(msg)
case msg: MonitorNumberOfUsers => handleMonitorNumberOfUsers(msg)
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
//case msg: RegisterUser => handleRegisterUser(msg)
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
case msg: UserLeftVoiceConfMessage => handleUserLeftVoiceConfMessage(msg)
case msg: UserMutedInVoiceConfMessage => handleUserMutedInVoiceConfMessage(msg)
case msg: UserTalkingInVoiceConfMessage => handleUserTalkingInVoiceConfMessage(msg)
case msg: VoiceConfRecordingStartedMessage => handleVoiceConfRecordingStartedMessage(msg)
case msg: UserJoining => handleUserJoin(msg)
case msg: UserLeaving => handleUserLeft(msg)
case msg: AssignPresenter => handleAssignPresenter(msg)
case msg: AllowUserToShareDesktop => handleAllowUserToShareDesktop(msg)
case msg: GetUsers => handleGetUsers(msg)
case msg: ChangeUserStatus => handleChangeUserStatus(msg)
case msg: EjectUserFromMeeting => handle(msg)
case msg: UserEmojiStatus => handleUserEmojiStatus(msg)
case msg: UserShareWebcam => handleUserShareWebcam(msg)
case msg: UserUnshareWebcam => handleUserunshareWebcam(msg)
case msg: MuteMeetingRequest => handleMuteMeetingRequest(msg)
case msg: MuteAllExceptPresenterRequest => handleMuteAllExceptPresenterRequest(msg)
case msg: IsMeetingMutedRequest => handleIsMeetingMutedRequest(msg)
case msg: MuteUserRequest => handleMuteUserRequest(msg)
case msg: EjectUserFromVoiceRequest => handleEjectUserRequest(msg)
case msg: TransferUserToMeetingRequest => handleTransferUserToMeeting(msg)
case msg: SetLockSettings => handleSetLockSettings(msg)
case msg: GetLockSettings => handleGetLockSettings(msg)
case msg: LockUserRequest => handleLockUserRequest(msg)
case msg: InitLockSettings => handleInitLockSettings(msg)
case msg: InitAudioSettings => handleInitAudioSettings(msg)
case msg: GetChatHistoryRequest => handleGetChatHistoryRequest(msg)
case msg: SendPublicMessageRequest => handleSendPublicMessageRequest(msg)
case msg: SendPrivateMessageRequest => handleSendPrivateMessageRequest(msg)
@ -175,15 +166,7 @@ class MeetingActor(val props: DefaultProps,
case msg: PreuploadedPresentations => handlePreuploadedPresentations(msg)
case msg: SetRecordingStatus => handleSetRecordingStatus(msg)
case msg: GetRecordingStatus => handleGetRecordingStatus(msg)
case msg: StartCustomPollRequest => handleStartCustomPollRequest(msg)
case msg: StartPollRequest => handleStartPollRequest(msg)
case msg: StopPollRequest => handleStopPollRequest(msg)
case msg: ShowPollResultRequest => handleShowPollResultRequest(msg)
case msg: HidePollResultRequest => handleHidePollResultRequest(msg)
case msg: RespondToPollRequest => handleRespondToPollRequest(msg)
case msg: GetPollRequest => handleGetPollRequest(msg)
case msg: GetCurrentPollRequest => handleGetCurrentPollRequest(msg)
case msg: ChangeUserRole => handle(msg)
case msg: LogoutEndMeeting => handleLogoutEndMeeting(msg)
case msg: ClearPublicChatHistoryRequest => handleClearPublicChatHistoryRequest(msg)
@ -228,6 +211,7 @@ class MeetingActor(val props: DefaultProps,
case m: ValidateAuthTokenReqMsg => handleValidateAuthTokenReqMsg(m)
case m: RegisterUserReqMsg => handleRegisterUserReqMsg(m)
case m: UserJoinMeetingReqMsg => handle(m)
case m: UserLeaveReqMsg => handle(m)
case m: UserBroadcastCamStartMsg => handleUserBroadcastCamStartMsg(m)
case m: UserBroadcastCamStopMsg => handleUserBroadcastCamStopMsg(m)
case m: UserJoinedVoiceConfEvtMsg => handleUserJoinedVoiceConfEvtMsg(m)
@ -248,16 +232,32 @@ class MeetingActor(val props: DefaultProps,
case m: BreakoutRoomsListMsg => handleBreakoutRoomsListMsg(m)
case m: CreateBreakoutRoomsMsg => handleCreateBreakoutRoomsMsg(m)
case m: EndAllBreakoutRoomsMsg => handleEndAllBreakoutRoomsMsg(m)
case m: RequestBreakoutJoinURLMsg => handleRequestBreakoutJoinURLMsg(m);
case m: BreakoutRoomCreatedMsg => handleBreakoutRoomCreatedMsg(m);
case m: RequestBreakoutJoinURLMsg => handleRequestBreakoutJoinURLMsg(m)
case m: BreakoutRoomCreatedMsg => handleBreakoutRoomCreatedMsg(m)
case m: BreakoutRoomEndedMsg => handleBreakoutRoomEndedMsg(m)
case m: BreakoutRoomUsersUpdateMsg => handleBreakoutRoomUsersUpdateMsg(m)
case m: SendBreakoutUsersUpdateMsg => handleSendBreakoutUsersUpdateMsg(m)
case m: TransferUserToMeetingRequestMsg => handleTransferUserToMeetingRequestMsg(m)
case m: UserLeftVoiceConfEvtMsg => handle(m)
case m: UserMutedInVoiceConfEvtMsg => handle(m)
case m: UserTalkingInVoiceConfEvtMsg => handle(m)
case m: GetCurrentLayoutMsg => handleGetCurrentLayoutMsg(m)
case m: LockLayoutMsg => handleLockLayoutMsg(m)
case m: BroadcastLayoutMsg => handleBroadcastLayoutMsg(m)
case m: SetCurrentPresentationPubMsg => presentationApp2x.handleSetCurrentPresentationPubMsg(m)
case m: GetPresentationInfoReqMsg => presentationApp2x.handleGetPresentationInfoReqMsg(m)
case m: SetCurrentPagePubMsg => presentationApp2x.handleSetCurrentPagePubMsg(m)
case m: ResizeAndMovePagePubMsg => presentationApp2x.handleResizeAndMovePagePubMsg(m)
case m: RemovePresentationPubMsg => presentationApp2x.handleRemovePresentationPubMsg(m)
case m: PreuploadedPresentationsPubMsg => presentationApp2x.handlePreuploadedPresentationsPubMsg(m)
case m: PresentationConversionUpdatePubMsg => presentationApp2x.handlePresentationConversionUpdatePubMsg(m)
case m: PresentationPageCountErrorPubMsg => presentationApp2x.handlePresentationPageCountErrorPubMsg(m)
case m: PresentationPageGeneratedPubMsg => presentationApp2x.handlePresentationPageGeneratedPubMsg(m)
case m: PresentationConversionCompletedPubMsg => presentationApp2x.handlePresentationConversionCompletedPubMsg(m)
case m: EditCaptionHistoryPubMsg => captionApp2x.handleEditCaptionHistoryPubMsg(m)
case m: UpdateCaptionOwnerPubMsg => captionApp2x.handleUpdateCaptionOwnerPubMsg(m)
case m: SendCaptionHistoryReqMsg => captionApp2x.handleSendCaptionHistoryReqMsg(m)
case _ => println("***** Cannot handle " + msg.envelope.name)
case _ => log.warning("***** Cannot handle " + msg.envelope.name)
}
}

View File

@ -19,6 +19,7 @@ class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
val chatModel = new ChatModel()
val layoutModel = new LayoutModel()
val layouts = new Layouts()
val pollModel = new PollModel()
val wbModel = new WhiteboardModel()
val presModel = new PresentationModel()
@ -33,14 +34,15 @@ class RunningMeeting(val props: DefaultProps, val outGW: OutMessageGateway,
val users2x = new Users2x
val usersState = new UsersState
val polls2x = new Polls
val guestsWaiting = new GuestsWaiting
// meetingModel.setGuestPolicy(props.usersProp.guestPolicy)
// We extract the meeting handlers into this class so it is
// easy to test.
val liveMeeting = new LiveMeeting(props, meetingStatux2x, chatModel, layoutModel,
val liveMeeting = new LiveMeeting(props, meetingStatux2x, chatModel, layoutModel, layouts,
users, registeredUsers, polls2x, pollModel, wbModel, presModel, breakoutRooms, captionModel,
notesModel, webcams, voiceUsers, users2x)
notesModel, webcams, voiceUsers, users2x, guestsWaiting)
val actorRef = context.actorOf(MeetingActor.props(props, eventBus, outGW, liveMeeting), props.meetingProp.intId)

View File

@ -1,18 +1,18 @@
package org.bigbluebutton.core.util
import org.bigbluebutton.core.models.{ UserState, UserVO, VoiceUser, VoiceUserState }
import org.bigbluebutton.common2.domain.{ UserVO, VoiceUserVO }
import org.bigbluebutton.core.models.{ VoiceUserState, UserState }
import scala.collection.immutable.ListSet
object Model1x2xConverter {
def defaultVoiceUser(intId: String, voiceUserId: String, callerIdName: String, callerIdNum: String, avatar: String): VoiceUser = {
new VoiceUser(voiceUserId, intId, callerIdName, callerIdNum, joined = false, locked = false,
def defaultVoiceUser(intId: String, voiceUserId: String, callerIdName: String, callerIdNum: String, avatar: String): VoiceUserVO = {
new VoiceUserVO(voiceUserId, intId, callerIdName, callerIdNum, joined = false, locked = false,
muted = false, talking = false, avatar, listenOnly = false)
}
def defaultUserVO(intId: String, extId: String, name: String, role: String, guest: Boolean, authed: Boolean,
waitingForAcceptance: Boolean, lockStatus: Boolean, vu: VoiceUser): UserVO = {
waitingForAcceptance: Boolean, lockStatus: Boolean, vu: VoiceUserVO): UserVO = {
new UserVO(intId, extId, name, role, guest, authed, waitingForAcceptance = waitingForAcceptance,
emojiStatus = "none", presenter = false,
hasStream = false, locked = lockStatus,
@ -20,12 +20,12 @@ object Model1x2xConverter {
listenOnly = vu.listenOnly, avatarURL = vu.avatarURL, joinedWeb = true)
}
def toVoiceUser(vu: VoiceUserState): VoiceUser = {
new VoiceUser(vu.voiceUserId, vu.intId, vu.callerName, vu.callerNum, joined = false, locked = false,
def toVoiceUser(vu: VoiceUserState): VoiceUserVO = {
new VoiceUserVO(vu.voiceUserId, vu.intId, vu.callerName, vu.callerNum, joined = false, locked = false,
muted = vu.muted, talking = vu.talking, "none", listenOnly = vu.listenOnly)
}
def toUserVO(u: UserState, vu: VoiceUser, webcams: Vector[String]): UserVO = {
def toUserVO(u: UserState, vu: VoiceUserVO, webcams: Vector[String]): UserVO = {
new UserVO(id = u.intId, externalId = u.extId, name = u.name, role = u.role,
guest = u.guest, authed = u.authed, waitingForAcceptance = u.waitingForAcceptance, emojiStatus = u.emoji,

View File

@ -1,11 +1,11 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.messages.MessageBody.GetCurrentPollRespMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.common2.domain.PollVO
import org.bigbluebutton.common2.messages.polls.{ GetCurrentPollReqMsg, GetCurrentPollRespMsg, GetCurrentPollRespMsgBody }
trait GetCurrentPollReqMsgHdlr {
this: MeetingActor =>

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.messages.MessageBody.{ PollHideResultEvtMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.polls.{ HidePollResultReqMsg, PollHideResultEvtMsg, PollHideResultEvtMsgBody }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor

View File

@ -1,6 +1,5 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.messages.MessageBody.UserBroadcastCamStartedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.voiceconf.{ MuteUserInVoiceConfMsg, MuteUserInVoiceConfMsgBody }
import org.bigbluebutton.core.OutMessageGateway

View File

@ -1,8 +1,8 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.domain.SimplePollResultOutVO
import org.bigbluebutton.common2.messages.MessageBody.UserRespondedToPollEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.polls.{ RespondToPollReqMsg, UserRespondedToPollEvtMsg, UserRespondedToPollEvtMsgBody }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor

View File

@ -14,10 +14,12 @@ trait SetLockSettingsHdlr {
def handleSetLockSettings(msg: SetLockSettings) {
if (!liveMeeting.permissionsEqual(msg.settings)) {
liveMeeting.newPermissions(msg.settings)
/*
outGW.send(new NewPermissionsSetting(props.meetingProp.intId, msg.setByUser,
MeetingStatus2x.getPermissions(liveMeeting.status),
Users.getUsers(liveMeeting.users).toArray))
*/
handleLockLayout(msg.settings.lockedLayout, msg.setByUser)
}
}

View File

@ -1,11 +1,11 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.messages.MessageBody.PollShowResultEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.common2.domain.SimplePollResultOutVO
import org.bigbluebutton.common2.messages.polls.{ PollShowResultEvtMsg, PollShowResultEvtMsgBody, ShowPollResultReqMsg }
trait ShowPollResultReqMsgHdlr {
this: MeetingActor =>

View File

@ -1,8 +1,8 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.domain.SimplePollOutVO
import org.bigbluebutton.common2.messages.MessageBody.PollStartedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.polls.{ PollStartedEvtMsg, PollStartedEvtMsgBody, StartCustomPollReqMsg }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor

View File

@ -1,8 +1,8 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.messages.MessageBody.PollStartedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.domain.SimplePollOutVO
import org.bigbluebutton.common2.messages.polls.{ PollStartedEvtMsg, PollStartedEvtMsgBody, StartPollReqMsg }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core2.message.handlers
import org.bigbluebutton.common2.messages.MessageBody.PollStoppedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.polls.{ PollStoppedEvtMsg, PollStoppedEvtMsgBody, StopPollReqMsg }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Polls
import org.bigbluebutton.core.running.MeetingActor

View File

@ -0,0 +1,33 @@
package org.bigbluebutton.core2.message.handlers.layout
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.Routing
import org.bigbluebutton.common2.messages.layout._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Layouts
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait BroadcastLayoutMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleBroadcastLayoutMsg(msg: BroadcastLayoutMsg): Unit = {
Layouts.setCurrentLayout(msg.body.layout)
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(BroadcastLayoutEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(BroadcastLayoutEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = BroadcastLayoutEvtMsgBody(msg.body.meetingId, props.recordProp.record, msg.body.requesterId,
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter(), affectedUsers)
val event = BroadcastLayoutEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
}

View File

@ -0,0 +1,40 @@
package org.bigbluebutton.core2.message.handlers.layout
import org.bigbluebutton.common2.messages.Routing
import org.bigbluebutton.common2.messages.MessageTypes
import org.bigbluebutton.common2.messages.layout._
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.common2.messages.BbbCommonEnvCoreMsg
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.common2.messages.layout.GetCurrentLayoutMsg
import org.bigbluebutton.common2.messages.BbbClientMsgHeader
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Layouts
import org.bigbluebutton.common2.messages.BbbCoreEnvelope
trait GetCurrentLayoutMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleGetCurrentLayoutMsg(msg: GetCurrentLayoutMsg): Unit = {
def broadcastEvent(msg: GetCurrentLayoutMsg): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(GetCurrentLayoutEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(GetCurrentLayoutEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = GetCurrentLayoutEvtMsgBody(msg.body.meetingId, props.recordProp.record, msg.body.requesterId,
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter())
val event = GetCurrentLayoutEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
broadcastEvent(msg)
}
}

View File

@ -0,0 +1,59 @@
package org.bigbluebutton.core2.message.handlers.layout
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.Routing
import org.bigbluebutton.common2.messages.layout._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Layouts
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait LockLayoutMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleLockLayoutMsg(msg: LockLayoutMsg): Unit = {
def broadcastEvent(msg: LockLayoutMsg): Unit = {
Layouts.applyToViewersOnly(msg.body.viewersOnly)
liveMeeting.lockLayout(msg.body.lock)
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(LockLayoutEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(LockLayoutEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = LockLayoutEvtMsgBody(msg.body.meetingId, props.recordProp.record, msg.body.setById, msg.body.lock, affectedUsers)
val event = LockLayoutEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
msg.body.layout foreach { l =>
Layouts.setCurrentLayout(l)
broadcastSyncLayout(msg.body.meetingId, msg.body.setById)
}
outGW.send(msgEvent)
}
def broadcastSyncLayout(meetingId: String, setById: String) {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(BroadcastLayoutEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(BroadcastLayoutEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)
val body = BroadcastLayoutEvtMsgBody(meetingId, props.recordProp.record, setById,
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter(), affectedUsers)
val event = BroadcastLayoutEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
broadcastEvent(msg)
}
}

View File

@ -12,7 +12,7 @@ trait EjectUserFromMeetingHdlr {
val outGW: OutMessageGateway
def handle(msg: EjectUserFromMeeting) {
/*
for {
user <- Users2x.findWithIntId(liveMeeting.users2x, msg.userId)
} yield {
@ -21,6 +21,7 @@ trait EjectUserFromMeetingHdlr {
pollApp2x.handle(msg, user)
deskshareApp2x.handle(msg, user)
}
*/
}
}

View File

@ -13,8 +13,8 @@ trait GetLockSettingsHdlr {
def handleGetLockSettings(msg: GetLockSettings) {
outGW.send(new NewPermissionsSetting(props.meetingProp.intId, msg.userId,
MeetingStatus2x.getPermissions(liveMeeting.status),
Users.getUsers(liveMeeting.users).toArray))
// outGW.send(new NewPermissionsSetting(props.meetingProp.intId, msg.userId,
// MeetingStatus2x.getPermissions(liveMeeting.status),
// Users.getUsers(liveMeeting.users).toArray))
}
}

View File

@ -16,16 +16,4 @@ trait GetUsersHdlr {
sendAllUsersInMeeting(msg.requesterID)
}
def sendAllUsersInMeeting(requesterId: String): Unit = {
val users = Users2x.findAll(liveMeeting.users2x)
val webUsers = users.map { u =>
WebUser(intId = u.intId, extId = u.extId, name = u.name, role = u.role,
guest = u.guest, authed = u.authed, waitingForAcceptance = u.waitingForAcceptance, emoji = u.emoji,
locked = u.locked, presenter = u.presenter, avatar = u.avatar)
}
val event = GetUsersMeetingRespMsgBuilder.build(liveMeeting.props.meetingProp.intId, requesterId, webUsers)
Sender.send(outGW, event)
}
}

View File

@ -15,8 +15,6 @@ trait InitLockSettingsHdlr {
if (!MeetingStatus2x.permisionsInitialized(liveMeeting.status)) {
MeetingStatus2x.initializePermissions(liveMeeting.status)
liveMeeting.newPermissions(msg.settings)
outGW.send(new PermissionsSettingInitialized(msg.meetingID, msg.settings,
Users.getUsers(liveMeeting.users).toArray))
}
}
}

View File

@ -2,7 +2,7 @@ package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ MuteUserRequest, MuteVoiceUser }
import org.bigbluebutton.core.models.Users
import org.bigbluebutton.core.models.{ Users, Users2x, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
trait MuteUserRequestHdlr {
@ -13,11 +13,11 @@ trait MuteUserRequestHdlr {
def handleMuteUserRequest(msg: MuteUserRequest) {
log.info("Received mute user request. meetingId=" + props.meetingProp.intId + " userId=" + msg.userID + " mute=" + msg.mute)
for {
u <- Users.findWithId(msg.userID, liveMeeting.users)
u <- VoiceUsers.findWithIntId(liveMeeting.voiceUsers, msg.userID)
} yield {
log.info("Send mute user request. meetingId=" + props.meetingProp.intId + " userId=" + u.id + " user=" + u)
log.info("Send mute user request. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
outGW.send(new MuteVoiceUser(props.meetingProp.intId, props.recordProp.record,
msg.requesterID, u.id, props.voiceProp.voiceConf, u.voiceUser.userId, msg.mute))
msg.requesterID, u.intId, props.voiceProp.voiceConf, u.voiceUserId, msg.mute))
}
}
}

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.messages.MessageBody.UserBroadcastCamStartedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.{ UserBroadcastCamStartMsg, UserBroadcastCamStartedEvtMsg, UserBroadcastCamStartedEvtMsgBody }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ MediaStream, WebcamStream, Webcams }
import org.bigbluebutton.core.running.MeetingActor

View File

@ -1,7 +1,7 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.messages.MessageBody.UserBroadcastCamStoppedEvtMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.{ UserBroadcastCamStopMsg, UserBroadcastCamStoppedEvtMsg, UserBroadcastCamStoppedEvtMsgBody }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.Webcams
import org.bigbluebutton.core.running.MeetingActor

View File

@ -16,18 +16,6 @@ trait UserConnectedToGlobalAudioHdlr {
def handleUserConnectedToGlobalAudio(msg: UserConnectedToGlobalAudio) {
log.info("Handling UserConnectedToGlobalAudio: meetingId=" + props.meetingProp.intId + " userId=" + msg.userid)
val user = Users.findWithId(msg.userid, liveMeeting.users)
user foreach { u =>
if (MeetingStatus2x.addGlobalAudioConnection(liveMeeting.status, msg.userid)) {
for {
uvo <- Users.joinedVoiceListenOnly(msg.userid, liveMeeting.users)
} yield {
log.info("UserConnectedToGlobalAudio: meetingId=" + props.meetingProp.intId + " userId=" + uvo.id + " user=" + uvo)
outGW.send(new UserListeningOnly(props.meetingProp.intId, props.recordProp.record, uvo.id, uvo.listenOnly))
}
}
}
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId,
vu.intId)

View File

@ -4,9 +4,8 @@ import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.voiceconf.{ UserLeftVoiceConfToClientEvtMsg, UserLeftVoiceConfToClientEvtMsgBody }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ UserDisconnectedFromGlobalAudio, UserLeft, UserListeningOnly }
import org.bigbluebutton.core.models.{ Users, VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait UserDisconnectedFromGlobalAudioHdlr {
this: MeetingActor =>
@ -16,27 +15,6 @@ trait UserDisconnectedFromGlobalAudioHdlr {
def handleUserDisconnectedFromGlobalAudio(msg: UserDisconnectedFromGlobalAudio) {
log.info("Handling UserDisconnectedToGlobalAudio: meetingId=" + props.meetingProp.intId + " userId=" + msg.userid)
val user = Users.findWithId(msg.userid, liveMeeting.users)
user foreach { u =>
if (MeetingStatus2x.removeGlobalAudioConnection(liveMeeting.status, msg.userid)) {
if (!u.joinedWeb) {
for {
uvo <- Users.userLeft(u.id, liveMeeting.users)
} yield {
log.info("Not web user. Send user left message. meetingId=" + props.meetingProp.intId + " userId=" + u.id + " user=" + u)
outGW.send(new UserLeft(props.meetingProp.intId, props.recordProp.record, uvo))
}
} else {
for {
uvo <- Users.leftVoiceListenOnly(u.id, liveMeeting.users)
} yield {
log.info("UserDisconnectedToGlobalAudio: meetingId=" + props.meetingProp.intId + " userId=" + uvo.id + " user=" + uvo)
outGW.send(new UserListeningOnly(props.meetingProp.intId, props.recordProp.record, uvo.id, uvo.listenOnly))
}
}
}
}
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId,
vu.intId)

View File

@ -1,8 +1,10 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.messages.users.{ UserEmojiChangedEvtMsg, UserEmojiChangedEvtMsgBody, ValidateAuthTokenRespMsg, ValidateAuthTokenRespMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ UserChangedEmojiStatus, UserEmojiStatus }
import org.bigbluebutton.core.models.Users
import org.bigbluebutton.core.models.{ Users, Users2x }
import org.bigbluebutton.core.running.MeetingActor
trait UserEmojiStatusHdlr {
@ -12,10 +14,19 @@ trait UserEmojiStatusHdlr {
def handleUserEmojiStatus(msg: UserEmojiStatus) {
for {
uvo <- Users.setEmojiStatus(msg.userId, liveMeeting.users, msg.emojiStatus)
uvo <- Users2x.setEmojiStatus(liveMeeting.users2x, msg.userId, msg.emojiStatus)
} yield {
outGW.send(new UserChangedEmojiStatus(props.meetingProp.intId, props.recordProp.record, msg.emojiStatus, uvo.id))
sendUserEmojiChangedEvtMsg(outGW, liveMeeting.props.meetingProp.intId, msg.userId, msg.emojiStatus)
}
}
def sendUserEmojiChangedEvtMsg(outGW: OutMessageGateway, meetingId: String, userId: String, emoji: String): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
val envelope = BbbCoreEnvelope(UserEmojiChangedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserEmojiChangedEvtMsg.NAME, meetingId, userId)
val body = UserEmojiChangedEvtMsgBody(userId, emoji)
val event = UserEmojiChangedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
}

View File

@ -1,6 +1,6 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.UserJoinMeetingReqMsg
import org.bigbluebutton.core.{ MessageRecorder, OutMessageGateway }
import org.bigbluebutton.core.models.{ RegisteredUsers, UserState, Users2x }
import org.bigbluebutton.core.running.MeetingActor
@ -13,9 +13,13 @@ trait UserJoinMeetingReqMsgHdlr {
def handle(msg: UserJoinMeetingReqMsg): Unit = {
userJoinMeeting(msg.body.authToken)
startRecordingIfAutoStart()
}
def userJoinMeeting(authToken: String): Unit = {
log.debug("User joining with token {}", authToken)
for {
regUser <- RegisteredUsers.findWithToken(authToken, liveMeeting.registeredUsers)
} yield {
@ -37,6 +41,7 @@ trait UserJoinMeetingReqMsgHdlr {
Sender.send(outGW, event)
MessageRecorder.record(outGW, liveMeeting.props.recordProp.record, event.core)
}
}
}

View File

@ -2,61 +2,17 @@ package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.models.{ Roles, Users, VoiceUser }
import org.bigbluebutton.core.models.{ Roles, Users }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.common2.domain.VoiceUserVO
trait UserJoinedVoiceConfMessageHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleUserJoinedVoiceFromPhone(msg: UserJoinedVoiceConfMessage) = {
log.info("User joining from phone. meetingId=" + props.meetingProp.intId + " userId=" + msg.userId
+ " extUserId=" + msg.externUserId)
Users.getUserWithVoiceUserId(msg.voiceUserId, liveMeeting.users) match {
case Some(user) => {
log.info("Voice user=" + msg.voiceUserId + " is already in conf="
+ props.voiceProp.voiceConf + ". Must be duplicate message. meetigId=" + props.meetingProp.intId)
}
case None => {
val webUserId = if (msg.userId != msg.callerIdName) {
msg.userId
} else {
// No current web user. This means that the user called in through
// the phone. We need to generate a new user as we are not able
// to match with a web user.
Users.generateWebUserId(liveMeeting.users)
}
/**
* If user is not joined listenOnly then user is joined calling through phone or webrtc.
*/
val vu = new VoiceUser(msg.voiceUserId, webUserId, msg.callerIdName, msg.callerIdNum,
joined = !msg.listenOnly, locked = false, muted = msg.muted, talking = msg.talking, msg.avatarURL, listenOnly = msg.listenOnly)
/**
* If user is not joined listenOnly then user is joined calling through phone or webrtc.
* So we call him "phoneUser".
*/
val uvo = Users.makeUserPhoneUser(vu, liveMeeting.users, webUserId, msg.externUserId, msg.callerIdName,
lockStatus = getInitialLockStatus(Roles.VIEWER_ROLE),
listenOnly = msg.listenOnly, avatarURL = msg.avatarURL)
log.info("User joined from phone. meetingId=" + props.meetingProp.intId + " userId=" + uvo.id + " user=" + uvo)
outGW.send(new UserJoined(props.meetingProp.intId, props.recordProp.record, uvo))
outGW.send(new UserJoinedVoice(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf, uvo))
if (MeetingStatus2x.isMeetingMuted(liveMeeting.status)) {
outGW.send(new MuteVoiceUser(props.meetingProp.intId, props.recordProp.record, uvo.id, uvo.id,
props.voiceProp.voiceConf, vu.userId, MeetingStatus2x.isMeetingMuted(liveMeeting.status)))
}
}
}
}
/*
def startRecordingVoiceConference() {
if (Users.numUsersInVoiceConference(liveMeeting.users) == 1 &&
props.recordProp.record &&
@ -67,30 +23,7 @@ trait UserJoinedVoiceConfMessageHdlr {
}
}
def switchUserToPhoneUser(msg: UserJoinedVoiceConfMessage) = {
log.info("User has been disconnected but still in voice conf. Switching to phone user. meetingId="
+ props.meetingProp.intId + " callername=" + msg.callerIdName
+ " userId=" + msg.userId + " extUserId=" + msg.externUserId)
Users.findWithId(msg.userId, liveMeeting.users) match {
case Some(user) => {
val nu = Users.switchUserToPhoneUser(user, liveMeeting.users, msg.voiceUserId, msg.userId, msg.callerIdName,
msg.callerIdNum, msg.muted, msg.talking, msg.avatarURL, msg.listenOnly)
log.info("User joined voice. meetingId=" + props.meetingProp.intId + " userId=" + user.id + " user=" + nu)
outGW.send(new UserJoinedVoice(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf, nu))
if (MeetingStatus2x.isMeetingMuted(liveMeeting.status)) {
outGW.send(new MuteVoiceUser(props.meetingProp.intId, props.recordProp.record,
nu.id, nu.id, props.voiceProp.voiceConf,
nu.voiceUser.userId, MeetingStatus2x.isMeetingMuted(liveMeeting.status)))
}
}
case None => {
handleUserJoinedVoiceFromPhone(msg)
}
}
}
def handleUserJoinedVoiceConfMessage(msg: UserJoinedVoiceConfMessage) = {
log.info("Received user joined voice. meetingId=" + props.meetingProp.intId + " callername=" + msg.callerIdName
@ -116,9 +49,9 @@ trait UserJoinedVoiceConfMessageHdlr {
startRecordingVoiceConference()
}
case None => {
handleUserJoinedVoiceFromPhone(msg)
startRecordingVoiceConference()
}
}
}
*/
}

View File

@ -1,5 +1,6 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.domain.VoiceUserVO
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.models._
@ -13,67 +14,7 @@ trait UserJoiningHdlr {
def handleUserJoin(msg: UserJoining): Unit = {
log.debug("Received user joined meeting. metingId=" + props.meetingProp.intId + " userId=" + msg.userID)
def initVoiceUser(userId: String, ru: RegisteredUser): VoiceUser = {
val wUser = Users.findWithId(userId, liveMeeting.users)
wUser match {
case Some(u) => {
log.debug("Found user. metingId=" + props.meetingProp.intId + " userId=" + msg.userID + " user=" + u)
if (u.voiceUser.joined) {
/*
* User is in voice conference. Must mean that the user reconnected with audio
* still in the voice conference.
*/
u.voiceUser.copy()
} else {
/**
* User is not joined in voice conference. Initialize user and copy status
* as user maybe joined listenOnly.
*/
new VoiceUser(u.voiceUser.userId, msg.userID, ru.name, ru.name,
joined = false, locked = false, muted = false,
talking = false, u.avatarURL, listenOnly = u.listenOnly)
}
}
case None => {
log.debug("User not found. metingId=" + props.meetingProp.intId + " userId=" + msg.userID)
/**
* New user. Initialize voice status.
*/
new VoiceUser(msg.userID, msg.userID, ru.name, ru.name,
joined = false, locked = false,
muted = false, talking = false, ru.avatarURL, listenOnly = false)
}
}
}
val regUser = RegisteredUsers.getRegisteredUserWithToken(msg.authToken, msg.userID, liveMeeting.registeredUsers)
regUser foreach { ru =>
log.debug("Found registered user. metingId=" + props.meetingProp.intId + " userId=" + msg.userID + " ru=" + ru)
val wUser = Users.findWithId(msg.userID, liveMeeting.users)
val vu = initVoiceUser(msg.userID, ru)
wUser.foreach { w =>
if (!w.joinedWeb) {
log.debug("User is in voice only. Mark as user left. metingId=" + props.meetingProp.intId + " userId=" + msg.userID)
/**
* If user is not joined through the web (perhaps reconnecting).
* Send a user left event to clear up user list of all clients.
*/
Users.userLeft(w.id, liveMeeting.users)
outGW.send(new UserLeft(msg.meetingID, props.recordProp.record, w))
}
}
/**
* Initialize the newly joined user copying voice status in case this
* join is due to a reconnect.
*/
val waitingForAcceptance = ru.guest &&
MeetingStatus2x.getGuestPolicy(liveMeeting.status) == GuestPolicy.ASK_MODERATOR && ru.waitingForAcceptance
val lockStatus = getInitialLockStatus(ru.role)
for {
uvo <- Users.newUser(msg.userID, lockStatus, ru, waitingForAcceptance, vu, liveMeeting.users)
@ -102,6 +43,7 @@ trait UserJoiningHdlr {
startRecordingIfAutoStart()
}
}
}
*/
}
}

View File

@ -1,8 +1,9 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.UserLeaveReqMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ UserJoinedVoiceConfMessage, UserLeaving, UserLeft }
import org.bigbluebutton.core.models.Users
import org.bigbluebutton.core.models.Users2x
import org.bigbluebutton.core.running.MeetingActor
trait UserLeavingHdlr {
@ -10,30 +11,26 @@ trait UserLeavingHdlr {
val outGW: OutMessageGateway
def handleUserLeft(msg: UserLeaving): Unit = {
def handle(msg: UserLeaveReqMsg): Unit = {
for {
u <- Users.userLeft(msg.userID, liveMeeting.users)
u <- Users2x.remove(liveMeeting.users2x, msg.body.userId)
} yield {
log.info("User left meeting. meetingId=" + props.meetingProp.intId + " userId=" + u.id + " user=" + u)
outGW.send(new UserLeft(msg.meetingID, props.recordProp.record, u))
log.info("User left meeting. meetingId=" + props.meetingProp.intId + " userId=" + u.intId + " user=" + u)
makeSurePresenterIsAssigned(u)
val vu = u.voiceUser
if (vu.joined || u.listenOnly) {
/**
* The user that left is still in the voice conference. Maybe this user just got disconnected
* and is reconnecting. Make the user as joined only in the voice conference. If we get a
* user left voice conference message, then we will remove the user from the users list.
*/
switchUserToPhoneUser(new UserJoinedVoiceConfMessage(props.voiceProp.voiceConf,
vu.userId, u.id, u.externalId, vu.callerName,
vu.callerNum, vu.muted, vu.talking, vu.avatarURL, u.listenOnly));
}
captionApp2x.handleUserLeavingMsg(u.id)
captionApp2x.handleUserLeavingMsg(msg.body.userId)
liveMeeting.startCheckingIfWeNeedToEndVoiceConf()
stopAutoStartedRecording()
sendUserLeftMeetingEvtMsg(outGW, props.meetingProp.intId, msg.body.userId)
}
}
def sendUserLeftMeetingEvtMsg(outGW: OutMessageGateway, meetingId: String, userId: String): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, meetingId, userId)
val envelope = BbbCoreEnvelope(UserLeftMeetingEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserLeftMeetingEvtMsg.NAME, meetingId, userId)
val body = UserLeftMeetingEvtMsgBody(userId)
val event = UserLeftMeetingEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
}
}

View File

@ -1,8 +1,39 @@
package org.bigbluebutton.core2.message.handlers.users
/**
* Created by ritz on 2017-06-09.
*/
trait UserLeftVoiceConfEvtMsgHdlr {
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.voiceconf.{ UserLeftVoiceConfEvtMsg, UserLeftVoiceConfToClientEvtMsg, UserLeftVoiceConfToClientEvtMsgBody }
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
trait UserLeftVoiceConfEvtMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handle(msg: UserLeftVoiceConfEvtMsg): Unit = {
log.debug("Received UserLeftVoiceConfEvtMsg from FS {} ", msg.body.voiceUserId)
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId,
vu.intId)
val envelope = BbbCoreEnvelope(UserLeftVoiceConfToClientEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserLeftVoiceConfToClientEvtMsg.NAME, props.meetingProp.intId, vu.intId)
val body = UserLeftVoiceConfToClientEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId)
val event = UserLeftVoiceConfToClientEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
for {
user <- VoiceUsers.findWithVoiceUserId(liveMeeting.voiceUsers, msg.body.voiceUserId)
} yield {
VoiceUsers.removeWithIntId(liveMeeting.voiceUsers, user.intId)
broadcastEvent(user)
}
}
}

View File

@ -1,8 +1,37 @@
package org.bigbluebutton.core2.message.handlers.users
/**
* Created by ritz on 2017-06-09.
*/
trait UserMutedInVoiceConfEvtMsgHdlr {
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.voiceconf._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
trait UserMutedInVoiceConfEvtMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handle(msg: UserMutedInVoiceConfEvtMsg): Unit = {
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId,
vu.intId)
val envelope = BbbCoreEnvelope(UserMutedEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserMutedEvtMsg.NAME, props.meetingProp.intId, vu.intId)
val body = UserMutedEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId, vu.muted)
val event = UserMutedEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
for {
mutedUser <- VoiceUsers.userMuted(liveMeeting.voiceUsers, msg.body.voiceUserId, msg.body.muted)
} yield {
broadcastEvent(mutedUser)
}
}
}

View File

@ -1,8 +1,37 @@
package org.bigbluebutton.core2.message.handlers.users
/**
* Created by ritz on 2017-06-09.
*/
trait UserTalkingInVoiceConfEvtMsgHdlr {
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.voiceconf._
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ VoiceUserState, VoiceUsers }
import org.bigbluebutton.core.running.MeetingActor
trait UserTalkingInVoiceConfEvtMsgHdlr {
this: MeetingActor =>
val outGW: OutMessageGateway
def handle(msg: UserTalkingInVoiceConfEvtMsg): Unit = {
def broadcastEvent(vu: VoiceUserState): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId,
vu.intId)
val envelope = BbbCoreEnvelope(UserTalkingEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(UserTalkingEvtMsg.NAME, props.meetingProp.intId, vu.intId)
val body = UserTalkingEvtMsgBody(intId = vu.intId, voiceUserId = vu.intId, vu.talking)
val event = UserTalkingEvtMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)
record(event)
}
for {
mutedUser <- VoiceUsers.userTalking(liveMeeting.voiceUsers, msg.body.voiceUserId, msg.body.talking)
} yield {
broadcastEvent(mutedUser)
}
}
}

View File

@ -1,12 +1,13 @@
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.ValidateAuthTokenReqMsg
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ RegisteredUsers, VoiceUsers, Webcams }
import org.bigbluebutton.core.api.ValidateAuthToken
import org.bigbluebutton.core.models.RegisteredUsers
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.api.{ GuestPolicy, ValidateAuthToken }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.message.senders.{ GetVoiceUsersMeetingRespMsgBuilder, GetWebcamStreamsMeetingRespMsgBuilder, Sender, ValidateAuthTokenRespMsgSender }
import org.bigbluebutton.core2.MeetingStatus2x
import org.bigbluebutton.core2.message.senders._
trait ValidateAuthTokenReqMsgHdlr {
this: MeetingActor =>
@ -14,25 +15,66 @@ trait ValidateAuthTokenReqMsgHdlr {
val outGW: OutMessageGateway
def handleValidateAuthTokenReqMsg(msg: ValidateAuthTokenReqMsg): Unit = {
log.debug("****** RECEIVED ValidateAuthTokenReqMsg msg {}", msg)
log.debug("RECEIVED ValidateAuthTokenReqMsg msg {}", msg)
val valid = RegisteredUsers.getRegisteredUserWithToken(msg.body.authToken, msg.body.userId, liveMeeting.registeredUsers) match {
case Some(u) => true
case None => false
}
RegisteredUsers.getRegisteredUserWithToken(msg.body.authToken, msg.body.userId, liveMeeting.registeredUsers) match {
case Some(u) =>
sendOldValidateToken(props.meetingProp.intId, msg.body.userId, msg.body.authToken)
if (u.guest && u.waitingForAcceptance && MeetingStatus2x.getGuestPolicy(liveMeeting.status) == GuestPolicy.ASK_MODERATOR) {
ValidateAuthTokenRespMsgSender.send(outGW, meetingId = props.meetingProp.intId,
userId = msg.body.userId, authToken = msg.body.authToken, valid = true, waitForApproval = true)
val guest = GuestWaiting(u.id, u.name, u.role)
addGuestToWaitingForApproval(guest)
notifyModeratorsOfGuestWaiting(Vector(guest))
} else {
ValidateAuthTokenRespMsgSender.send(outGW, meetingId = props.meetingProp.intId,
userId = msg.body.userId, authToken = msg.body.authToken, valid = valid)
userId = msg.body.userId, authToken = msg.body.authToken, valid = true, waitForApproval = false)
log.debug("validate token token={}, valid=true, waitForApproval=false", msg.body.authToken)
// Temp only so we can implement user handling in client. (ralam june 21, 2017)
userJoinMeeting(msg.body.authToken)
sendAllUsersInMeeting(msg.body.userId)
sendAllVoiceUsersInMeeting(msg.body.userId)
sendAllWebcamStreams(msg.body.userId)
if (!Users2x.hasPresenter(liveMeeting.users2x)) {
automaticallyAssignPresenter()
} else {
log.debug("Not sending presenter.")
}
}
case None =>
ValidateAuthTokenRespMsgSender.send(outGW, meetingId = props.meetingProp.intId,
userId = msg.body.userId, authToken = msg.body.authToken, valid = false, waitForApproval = false)
}
}
def notifyModeratorsOfGuestWaiting(guests: Vector[GuestWaiting]): Unit = {
def build(meetingId: String, userId: String, guests: Vector[GuestWaiting]): BbbCommonEnvCoreMsg = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
val envelope = BbbCoreEnvelope(GuestsWaitingApprovalEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(GuestsWaitingApprovalEvtMsg.NAME, meetingId, userId)
val guestsWaiting = guests.map(g => GuestWaitingVO(g.intId, g.name, g.role))
val body = GuestsWaitingApprovalEvtMsgBody(guestsWaiting)
val event = GuestsWaitingApprovalEvtMsg(header, body)
BbbCommonEnvCoreMsg(envelope, event)
}
val mods = Users2x.findAll(liveMeeting.users2x).filter(p => p.role == Roles.MODERATOR_ROLE)
mods foreach { m =>
val event = build(liveMeeting.props.meetingProp.intId, m.intId, guests)
Sender.send(outGW, event)
}
}
def addGuestToWaitingForApproval(guest: GuestWaiting): Unit = {
GuestsWaiting.add(liveMeeting.guestsWaiting, guest)
}
def sendAllVoiceUsersInMeeting(requesterId: String): Unit = {
@ -59,8 +101,15 @@ trait ValidateAuthTokenReqMsgHdlr {
Sender.send(outGW, event)
}
def sendOldValidateToken(meetingId: String, userId: String, authToken: String): Unit = {
handleValidateAuthToken(ValidateAuthToken(meetingID = meetingId, userId = userId, token = authToken,
correlationId = authToken, sessionId = authToken))
def sendAllUsersInMeeting(requesterId: String): Unit = {
val users = Users2x.findAll(liveMeeting.users2x)
val webUsers = users.map { u =>
WebUser(intId = u.intId, extId = u.extId, name = u.name, role = u.role,
guest = u.guest, authed = u.authed, waitingForAcceptance = u.waitingForAcceptance, emoji = u.emoji,
locked = u.locked, presenter = u.presenter, avatar = u.avatar)
}
val event = GetUsersMeetingRespMsgBuilder.build(liveMeeting.props.meetingProp.intId, requesterId, webUsers)
Sender.send(outGW, event)
}
}

View File

@ -2,8 +2,8 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ ClearWhiteboardEvtMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.whiteboard.{ ClearWhiteboardEvtMsg, ClearWhiteboardEvtMsgBody, ClearWhiteboardPubMsg }
trait ClearWhiteboardPubMsgHdlr {
this: MeetingActor =>

View File

@ -2,8 +2,8 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ GetWhiteboardAccessRespMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.whiteboard.{ GetWhiteboardAccessReqMsg, GetWhiteboardAccessRespMsg, GetWhiteboardAccessRespMsgBody }
trait GetWhiteboardAccessReqMsgHdlr {
this: MeetingActor =>

View File

@ -2,9 +2,9 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ GetWhiteboardAnnotationsRespMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.domain.AnnotationProps
import org.bigbluebutton.common2.messages.whiteboard.{ GetWhiteboardAnnotationsReqMsg, GetWhiteboardAnnotationsRespMsg, GetWhiteboardAnnotationsRespMsgBody }
import org.bigbluebutton.common2.domain.AnnotationVO
trait GetWhiteboardAnnotationsReqMsgHdlr {
this: MeetingActor =>
@ -13,7 +13,7 @@ trait GetWhiteboardAnnotationsReqMsgHdlr {
def handleGetWhiteboardAnnotationsReqMsg(msg: GetWhiteboardAnnotationsReqMsg): Unit = {
def broadcastEvent(msg: GetWhiteboardAnnotationsReqMsg, history: Array[AnnotationProps]): Unit = {
def broadcastEvent(msg: GetWhiteboardAnnotationsReqMsg, history: Array[AnnotationVO]): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(GetWhiteboardAnnotationsRespMsg.NAME, routing)
val header = BbbClientMsgHeader(GetWhiteboardAnnotationsRespMsg.NAME, props.meetingProp.intId, msg.header.userId)

View File

@ -2,8 +2,8 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ ModifyWhiteboardAccessEvtMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.whiteboard.{ ModifyWhiteboardAccessEvtMsg, ModifyWhiteboardAccessEvtMsgBody, ModifyWhiteboardAccessPubMsg }
trait ModifyWhiteboardAccessPubMsgHdlr {
this: MeetingActor =>

View File

@ -2,8 +2,8 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ SendCursorPositionEvtMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.whiteboard.{ SendCursorPositionEvtMsg, SendCursorPositionEvtMsgBody, SendCursorPositionPubMsg }
trait SendCursorPositionPubMsgHdlr {
this: MeetingActor =>

View File

@ -2,9 +2,9 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ SendWhiteboardAnnotationEvtMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.domain.AnnotationProps
import org.bigbluebutton.common2.messages.whiteboard.{ SendWhiteboardAnnotationEvtMsg, SendWhiteboardAnnotationEvtMsgBody, SendWhiteboardAnnotationPubMsg }
import org.bigbluebutton.common2.domain.AnnotationVO
trait SendWhiteboardAnnotationPubMsgHdlr {
this: MeetingActor =>
@ -13,7 +13,7 @@ trait SendWhiteboardAnnotationPubMsgHdlr {
def handleSendWhiteboardAnnotationPubMsg(msg: SendWhiteboardAnnotationPubMsg): Unit = {
def broadcastEvent(msg: SendWhiteboardAnnotationPubMsg, annotation: AnnotationProps): Unit = {
def broadcastEvent(msg: SendWhiteboardAnnotationPubMsg, annotation: AnnotationVO): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.BROADCAST_TO_MEETING, props.meetingProp.intId, msg.header.userId)
val envelope = BbbCoreEnvelope(SendWhiteboardAnnotationEvtMsg.NAME, routing)
val header = BbbClientMsgHeader(SendWhiteboardAnnotationEvtMsg.NAME, props.meetingProp.intId, msg.header.userId)

View File

@ -2,8 +2,8 @@ package org.bigbluebutton.core2.message.handlers.whiteboard
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.common2.messages.MessageBody.{ UndoWhiteboardEvtMsgBody }
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.whiteboard.{ UndoWhiteboardEvtMsg, UndoWhiteboardEvtMsgBody, UndoWhiteboardPubMsg }
trait UndoWhiteboardPubMsgHdlr {
this: MeetingActor =>

View File

@ -2,8 +2,8 @@ package org.bigbluebutton.core2.message.senders
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api.{ DisconnectUser, EjectVoiceUser, UserEjectedFromMeeting, UserLeft }
import org.bigbluebutton.core.models.UserVO
import org.bigbluebutton.core.running.LiveMeeting
import org.bigbluebutton.common2.domain.UserVO
trait MsgSenders1x {
val outGW: OutMessageGateway

View File

@ -1,16 +1,17 @@
package org.bigbluebutton.core2.message.senders
import org.bigbluebutton.common2.messages.MessageBody.ValidateAuthTokenRespMsgBody
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.messages.users.{ ValidateAuthTokenRespMsg, ValidateAuthTokenRespMsgBody }
import org.bigbluebutton.core.OutMessageGateway
object ValidateAuthTokenRespMsgSender {
def send(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String, valid: Boolean): Unit = {
def send(outGW: OutMessageGateway, meetingId: String, userId: String, authToken: String,
valid: Boolean, waitForApproval: Boolean): Unit = {
val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
val envelope = BbbCoreEnvelope(ValidateAuthTokenRespMsg.NAME, routing)
val header = BbbClientMsgHeader(ValidateAuthTokenRespMsg.NAME, meetingId, userId)
val body = ValidateAuthTokenRespMsgBody(userId, authToken, valid)
val body = ValidateAuthTokenRespMsgBody(userId, authToken, valid, waitForApproval)
val event = ValidateAuthTokenRespMsg(header, body)
val msgEvent = BbbCommonEnvCoreMsg(envelope, event)
outGW.send(msgEvent)

View File

@ -0,0 +1,58 @@
package org.bigbluebutton.core2.testdata
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.running.LiveMeeting
/**
* Create fake test data so we can populate meeting.
*/
trait FakeTestData {
def createFakeUsers(liveMeeting: LiveMeeting): Unit = {
createUserVoiceAndCam(liveMeeting, Roles.MODERATOR_ROLE, false, false, CallingWith.WEBRTC, muted = false,
talking = true, listenOnly = false)
createUserVoiceAndCam(liveMeeting, Roles.MODERATOR_ROLE, guest = true, authed = true, CallingWith.WEBRTC, muted = false,
talking = false, listenOnly = false)
createUserVoiceAndCam(liveMeeting, Roles.VIEWER_ROLE, guest = true, authed = true, CallingWith.WEBRTC, muted = false,
talking = false, listenOnly = false)
createUserVoiceAndCam(liveMeeting, Roles.VIEWER_ROLE, guest = true, authed = true, CallingWith.FLASH, muted = false,
talking = false, listenOnly = false)
val vu1 = FakeUserGenerator.createFakeVoiceOnlyUser(CallingWith.PHONE, muted = false, talking = false, listenOnly = false)
VoiceUsers.add(liveMeeting.voiceUsers, vu1)
val vu2 = FakeUserGenerator.createFakeVoiceOnlyUser(CallingWith.PHONE, muted = false, talking = false, listenOnly = false)
VoiceUsers.add(liveMeeting.voiceUsers, vu2)
val vu3 = FakeUserGenerator.createFakeVoiceOnlyUser(CallingWith.PHONE, muted = false, talking = false, listenOnly = false)
VoiceUsers.add(liveMeeting.voiceUsers, vu3)
val vu4 = FakeUserGenerator.createFakeVoiceOnlyUser(CallingWith.PHONE, muted = false, talking = false, listenOnly = false)
VoiceUsers.add(liveMeeting.voiceUsers, vu4)
val vu5 = FakeUserGenerator.createFakeVoiceOnlyUser(CallingWith.PHONE, muted = false, talking = false, listenOnly = false)
VoiceUsers.add(liveMeeting.voiceUsers, vu5)
}
def createUserVoiceAndCam(liveMeeting: LiveMeeting, role: String, guest: Boolean, authed: Boolean, callingWith: String,
muted: Boolean, talking: Boolean, listenOnly: Boolean): Unit = {
val ruser1 = FakeUserGenerator.createFakeRegisteredUser(liveMeeting.registeredUsers, Roles.MODERATOR_ROLE, true, false)
val vuser1 = FakeUserGenerator.createFakeVoiceUser(ruser1, "webrtc", muted = false, talking = true, listenOnly = false)
VoiceUsers.add(liveMeeting.voiceUsers, vuser1)
val rusers = Users2x.findAll(liveMeeting.users2x)
val others = rusers.filterNot(u => u.intId == ruser1.id)
val viewers = others.map { o => o.intId }
val wstream1 = FakeUserGenerator.createFakeWebcamStreamFor(ruser1.id, viewers.toSet)
Webcams.addWebcamBroadcastStream(liveMeeting.webcams, wstream1)
createFakeUser(liveMeeting, ruser1)
}
def createFakeUser(liveMeeting: LiveMeeting, regUser: RegisteredUser): Unit = {
val u = UserState(intId = regUser.id, extId = regUser.externId, name = regUser.name, role = regUser.role,
guest = regUser.guest, authed = regUser.authed, waitingForAcceptance = regUser.waitingForAcceptance,
emoji = "none", locked = false, presenter = false, avatar = regUser.avatarURL)
Users2x.add(liveMeeting.users2x, u)
}
}

View File

@ -0,0 +1,86 @@
package org.bigbluebutton.core2.testdata
import org.bigbluebutton.core.models._
import org.bigbluebutton.core.util.RandomStringGenerator
import scala.util.Random
/**
* Create fake names.
*/
object FakeUserGenerator {
private val random = new Random
// From Fake Name Generator (http://homepage.net/name_generator/)
private val firstNames = Seq("Abigail", "Alexandra", "Alison", "Amanda", "Amelia", "Amy", "Andrea", "Angela", "Anna", "Anne",
"Audrey", "Ava", "Bella", "Bernadette", "Carol", "Caroline", "Carolyn", "Chloe", "Claire", "Deirdre", "Diana",
"Diane", "Donna", "Dorothy", "Elizabeth", "Ella", "Emily", "Emma", "Faith", "Felicity", "Fiona", "Gabrielle",
"Grace", "Hannah", "Heather", "Irene", "Jan", "Jane", "Jasmine", "Jennifer", "Jessica", "Joan", "Joanne", "Julia",
"Karen", "Katherine", "Kimberly", "Kylie", "Lauren", "Leah", "Lillian", "Lily", "Lisa", "Madeleine", "Maria",
"Mary", "Megan", "Melanie", "Michelle", "Molly", "Natalie", "Nicola", "Olivia", "Penelope", "Pippa", "Rachel",
"Rebecca", "Rose", "Ruth", "Sally", "Samantha", "Sarah", "Sonia", "Sophie", "Stephanie", "Sue", "Theresa",
"Tracey", "Una", "Vanessa", "Victoria", "Virginia", "Wanda", "Wendy", "Yvonne", "Zoe", "Adam", "Adrian",
"Alan", "Alexander", "Andrew", "Anthony", "Austin", "Benjamin", "Blake", "Boris", "Brandon", "Brian",
"Cameron", "Carl", "Charles", "Christian", "Christopher", "Colin", "Connor", "Dan", "David", "Dominic",
"Dylan", "Edward", "Eric", "Evan", "Frank", "Gavin", "Gordon", "Harry", "Ian", "Isaac", "Jack", "Jacob",
"Jake", "James", "Jason", "Joe", "John", "Jonathan", "Joseph", "Joshua", "Julian", "Justin", "Keith", "Kevin",
"Leonard", "Liam", "Lucas", "Luke", "Matt", "Max", "Michael", "Nathan", "Neil", "Nicholas", "Oliver", "Owen",
"Paul", "Peter", "Phil", "Piers", "Richard", "Robert", "Ryan", "Sam", "Sean", "Sebastian", "Simon", "Stephen",
"Steven", "Stewart", "Thomas", "Tim", "Trevor", "Victor", "Warren", "William"
)
private val lastNames = Seq("Abraham", "Allan", "Alsop", "Anderson", "Arnold", "Avery", "Bailey", "Baker", "Ball", "Bell",
"Berry", "Black", "Blake", "Bond", "Bower", "Brown", "Buckland", "Burgess", "Butler", "Cameron", "Campbell",
"Carr", "Chapman", "Churchill", "Clark", "Clarkson", "Coleman", "Cornish", "Davidson", "Davies", "Dickens",
"Dowd", "Duncan", "Dyer", "Edmunds", "Ellison", "Ferguson", "Fisher", "Forsyth", "Fraser", "Gibson", "Gill",
"Glover", "Graham", "Grant", "Gray", "Greene", "Hamilton", "Hardacre", "Harris", "Hart", "Hemmings", "Henderson",
"Hill", "Hodges", "Howard", "Hudson", "Hughes", "Hunter", "Ince", "Jackson", "James", "Johnston", "Jones",
"Kelly", "Kerr", "King", "Knox", "Lambert", "Langdon", "Lawrence", "Lee", "Lewis", "Lyman", "MacDonald",
"Mackay", "Mackenzie", "MacLeod", "Manning", "Marshall", "Martin", "Mathis", "May", "McDonald", "McLean",
"McGrath", "Metcalfe", "Miller", "Mills", "Mitchell", "Morgan", "Morrison", "Murray", "Nash", "Newman",
"Nolan", "North", "Ogden", "Oliver", "Paige", "Parr", "Parsons", "Paterson", "Payne", "Peake", "Peters",
"Piper", "Poole", "Powell", "Pullman", "Quinn", "Rampling", "Randall", "Rees", "Reid", "Roberts", "Robertson",
"Ross", "Russell", "Rutherford", "Sanderson", "Scott", "Sharp", "Short", "Simpson", "Skinner", "Slater", "Smith",
"Springer", "Stewart", "Sutherland", "Taylor", "Terry", "Thomson", "Tucker", "Turner", "Underwood", "Vance",
"Vaughan", "Walker", "Wallace", "Walsh", "Watson", "Welch", "White", "Wilkins", "Wilson", "Wright", "Young"
)
private def getRandomElement(list: Seq[String], random: Random): String = list(random.nextInt(list.length))
def createFakeRegisteredUser(users: RegisteredUsers, role: String, guest: Boolean, authed: Boolean): RegisteredUser = {
val name = getRandomElement(firstNames, random) + " " + getRandomElement(lastNames, random)
val id = "w_" + RandomStringGenerator.randomAlphanumericString(16)
val extId = RandomStringGenerator.randomAlphanumericString(16)
val authToken = RandomStringGenerator.randomAlphanumericString(16)
val avatarURL = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" +
RandomStringGenerator.randomAlphanumericString(10) + ".png"
RegisteredUsers.create(userId = id, extId, name, role,
authToken, avatarURL, guest, authed, waitingForAcceptance = true, users)
}
def createFakeVoiceUser(user: RegisteredUser, callingWith: String, muted: Boolean, talking: Boolean,
listenOnly: Boolean): VoiceUserState = {
val voiceUserId = RandomStringGenerator.randomAlphanumericString(8)
VoiceUserState(intId = user.id, voiceUserId = voiceUserId, callingWith, callerName = user.name,
callerNum = user.name, muted, talking, listenOnly)
}
def createFakeVoiceOnlyUser(callingWith: String, muted: Boolean, talking: Boolean,
listenOnly: Boolean): VoiceUserState = {
val voiceUserId = RandomStringGenerator.randomAlphanumericString(8)
val intId = "v_" + RandomStringGenerator.randomAlphanumericString(16)
val name = getRandomElement(firstNames, random) + " " + getRandomElement(lastNames, random)
VoiceUserState(intId, voiceUserId = voiceUserId, callingWith, callerName = name,
callerNum = name, muted, talking, listenOnly)
}
def createFakeWebcamStreamFor(userId: String, viewers: Set[String]): WebcamStream = {
val streamId = RandomStringGenerator.randomAlphanumericString(10)
val url = "https://www." + RandomStringGenerator.randomAlphanumericString(32) + ".com/" + streamId
val attributes = collection.immutable.HashMap("height" -> "600", "width" -> "800", "codec" -> "h264")
val media = MediaStream(streamId, url: String, userId: String, attributes, viewers)
WebcamStream(streamId, stream = media)
}
}

3
akka-bbb-fsesl/run.sh Executable file
View File

@ -0,0 +1,3 @@
sbt clean
sbt run

View File

@ -31,8 +31,6 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
val json = JsonUtil.toJson(msgEvent)
sender.publish(fromVoiceConfRedisChannel, json)
val oldmsg = new VoiceConfRecordingStartedMessage(voiceConfId, recordStream, recording, timestamp)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, oldmsg.toJson())
}
def userJoinedVoiceConf(voiceConfId: String, voiceUserId: String, userId: String, callerIdName: String,
@ -51,8 +49,6 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
val json = JsonUtil.toJson(msgEvent)
sender.publish(fromVoiceConfRedisChannel, json)
val oldmsg = new UserJoinedVoiceConfMessage(voiceConfId, voiceUserId, userId, callerIdName, callerIdNum, muted, talking, avatarURL)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, oldmsg.toJson())
}
def userLeftVoiceConf(voiceConfId: String, voiceUserId: String) {
@ -68,8 +64,6 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
val json = JsonUtil.toJson(msgEvent)
sender.publish(fromVoiceConfRedisChannel, json)
val oldmsg = new UserLeftVoiceConfMessage(voiceConfId, voiceUserId)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, oldmsg.toJson())
}
def userLockedInVoiceConf(voiceConfId: String, voiceUserId: String, locked: java.lang.Boolean) {
@ -89,8 +83,6 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
val json = JsonUtil.toJson(msgEvent)
sender.publish(fromVoiceConfRedisChannel, json)
val oldmsg = new UserMutedInVoiceConfMessage(voiceConfId, voiceUserId, muted)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, oldmsg.toJson())
}
def userTalkingInVoiceConf(voiceConfId: String, voiceUserId: String, talking: java.lang.Boolean) {
@ -106,8 +98,6 @@ class VoiceConferenceService(sender: RedisPublisher) extends IVoiceConferenceSer
val json = JsonUtil.toJson(msgEvent)
sender.publish(fromVoiceConfRedisChannel, json)
val oldmsg = new UserTalkingInVoiceConfMessage(voiceConfId, voiceUserId, talking)
sender.publish(FROM_VOICE_CONF_SYSTEM_CHAN, oldmsg.toJson())
}
def deskShareStarted(voiceConfId: String, callerIdNum: String, callerIdName: String) {

View File

@ -9,12 +9,12 @@ case class DisconnectAllConnections(scope: String) extends SystemMessage
class MsgToClientGW(val connInvokerService: IConnectionInvokerService) {
def broadcastToMeeting(msg: BroadcastToMeetingMsg): Unit = {
println("**** MsgToClientGW broadcastToMeeting " + msg.json)
//println("**** MsgToClientGW broadcastToMeeting " + msg.json)
connInvokerService.sendMessage(msg)
}
def directToClient(msg: DirectToClientMsg): Unit = {
println("**** MsgToClientGW directToClient " + msg.json)
//println("**** MsgToClientGW directToClient " + msg.json)
connInvokerService.sendMessage(msg)
}

View File

@ -4,7 +4,7 @@ import scala.util.Try
import com.typesafe.config.ConfigFactory
trait SystemConfiguration {
val config = ConfigFactory.load("bbb-app")
val config = ConfigFactory.load()
lazy val redisHost = Try(config.getString("redis.host")).getOrElse("127.0.0.1")
lazy val redisPort = Try(config.getInt("redis.port")).getOrElse(6379)

View File

@ -28,6 +28,10 @@ object Connections {
def remove(conns: Connections, connId: String): Option[Connection] = {
conns.remove(connId)
}
def noMoreConnections(conns: Connections): Boolean = {
conns.toVector.length == 0
}
}
class Connections {

View File

@ -78,7 +78,7 @@ class MeetingManagerActor(msgToAkkaAppsEventBus: MsgToAkkaAppsEventBus,
private def forwardToMeeting(msg: BbbCommonEnvJsNodeMsg): Unit = {
msg.envelope.routing.get("meetingId") match {
case Some(meetingId2) => println("**** MeetingManagerActor forwardToMeeting. Found " + meetingId2)
case Some(meetingId2) => log.debug("**** MeetingManagerActor forwardToMeeting. Found " + meetingId2)
MeetingManager.findWithMeetingId(meetingMgr, meetingId2) match {
case Some(meetingId2) => log.debug("**** MeetingManagerActor forwardToMeeting. Found " + meetingId2.meetingId)
case None => log.debug("**** MeetingManagerActor forwardToMeeting. Could not find meetingId")

View File

@ -1,11 +1,12 @@
package org.bigbluebutton.client.meeting
import akka.actor.{Actor, ActorLogging, Props}
import org.bigbluebutton.client.SystemConfiguration
import org.bigbluebutton.client.{ConnInfo, SystemConfiguration}
import org.bigbluebutton.client.bus._
import org.bigbluebutton.common2.messages._
import org.bigbluebutton.common2.util.JsonUtil
import com.fasterxml.jackson.databind.JsonNode
import org.bigbluebutton.common2.messages.users.{UserLeaveReqMsg, UserLeaveReqMsgBody}
import scala.util.{Failure, Success}
@ -62,7 +63,21 @@ class UserActor(val userId: String,
log.debug("**** UserActor remove connection " + m.connId)
Connections.remove(conns, m.connId)
}
if (Connections.noMoreConnections(conns)) {
val json = buildUserLeavingMessage(msg.connInfo)
val msgFromClient = MsgFromClientMsg(msg.connInfo, json)
handleMsgFromClientMsg(msgFromClient)
}
}
private def buildUserLeavingMessage(connInfo: ConnInfo): String = {
val header = BbbClientMsgHeader(UserLeaveReqMsg.NAME, meetingId, userId)
val body = UserLeaveReqMsgBody(userId, connInfo.sessionId)
val event = UserLeaveReqMsg(header, body)
JsonUtil.toJson(event)
}
def handleMsgFromClientMsg(msg: MsgFromClientMsg):Unit = {
log.debug("Received MsgFromClientMsg " + msg)
@ -141,5 +156,3 @@ class UserActor(val userId: String,
}
}
}

View File

@ -27,7 +27,6 @@ case class DefaultProps(meetingProp: MeetingProp, breakoutProps: BreakoutProps,
recordProp: RecordProp, welcomeProp: WelcomeProp, voiceProp: VoiceProp,
usersProp: UsersProp, metadataProp: MetadataProp, screenshareProps: ScreenshareProps)
case class StartEndTimeStatus(startTime: Long, endTime: Long)
case class RecordingStatus(isRecording: Boolean)
case class GuestPolicyStatus(currentGuestPolicy: String)
@ -45,3 +44,13 @@ case class Responder(userId: String, name: String)
case class AnswerVO(id: Int, key: String, text: Option[String], responders: Option[Array[Responder]])
case class QuestionVO(id: Int, questionType: String, multiResponse: Boolean, questionText: Option[String], answers: Option[Array[AnswerVO]])
case class PollVO(id: String, questions: Array[QuestionVO], title: Option[String], started: Boolean, stopped: Boolean, showResult: Boolean)
case class UserVO(id: String, externalId: String, name: String, role: String,
guest: Boolean, authed: Boolean, waitingForAcceptance: Boolean, emojiStatus: String,
presenter: Boolean, hasStream: Boolean, locked: Boolean, webcamStreams: Set[String],
phoneUser: Boolean, voiceUser: VoiceUserVO, listenOnly: Boolean, avatarURL: String,
joinedWeb: Boolean)
case class VoiceUserVO(userId: String, webUserId: String, callerName: String,
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
talking: Boolean, avatarURL: String, listenOnly: Boolean)

View File

@ -0,0 +1,8 @@
package org.bigbluebutton.common2.domain
case class PresentationVO(id: String, name: String, current: Boolean = false,
pages: Vector[PageVO], downloadable: Boolean)
case class PageVO(id: String, num: Int, thumbUri: String = "", swfUri: String,
txtUri: String, svgUri: String, current: Boolean = false, xOffset: Double = 0,
yOffset: Double = 0, widthRatio: Double = 100D, heightRatio: Double = 100D)

View File

@ -1,3 +1,3 @@
package org.bigbluebutton.common2.domain
case class AnnotationProps(id: String, status: String, annotationType: String, annotationInfo: scala.collection.immutable.Map[String, Object], wbId: String, userId: String, position: Int)
case class AnnotationVO(id: String, status: String, annotationType: String, annotationInfo: scala.collection.immutable.Map[String, Object], wbId: String, userId: String, position: Int)

View File

@ -0,0 +1,9 @@
package org.bigbluebutton.common2.messages
import org.bigbluebutton.common2.domain.DefaultProps
object CreateMeetingReqMsg { val NAME = "CreateMeetingReqMsg" }
case class CreateMeetingReqMsg(header: BbbCoreBaseHeader,
body: CreateMeetingReqMsgBody) extends BbbCoreMsg
case class CreateMeetingReqMsgBody(props: DefaultProps)

View File

@ -3,16 +3,16 @@ package org.bigbluebutton.common2.messages
object GetGuestsWaitingApprovalRespMsg {
val NAME = "GetGuestsWaitingApprovalRespMsg"
def apply(meetingId: String, userId: String, users: Vector[WebUser]): GetGuestsWaitingApprovalRespMsg = {
def apply(meetingId: String, userId: String, guests: Vector[GuestWaitingVO]): GetGuestsWaitingApprovalRespMsg = {
val header = BbbClientMsgHeader(GetGuestsWaitingApprovalRespMsg.NAME, meetingId, userId)
val body = GetGuestsWaitingApprovalRespMsgBody(users)
val body = GetGuestsWaitingApprovalRespMsgBody(guests)
GetGuestsWaitingApprovalRespMsg(header, body)
}
}
case class GetGuestsWaitingApprovalRespMsg(header: BbbClientMsgHeader, body: GetGuestsWaitingApprovalRespMsgBody) extends BbbCoreMsg
case class GetGuestsWaitingApprovalRespMsgBody(users: Vector[WebUser])
case class GetGuestsWaitingApprovalRespMsg(header: BbbClientMsgHeader,
body: GetGuestsWaitingApprovalRespMsgBody) extends BbbCoreMsg
case class GetGuestsWaitingApprovalRespMsgBody(guests: Vector[GuestWaitingVO])
case class Guest(intId: String, name: String, role: String)
case class GuestWaitingVO(intId: String, name: String, role: String)

View File

@ -0,0 +1,17 @@
package org.bigbluebutton.common2.messages
object GuestsWaitingApprovalEvtMsg {
val NAME = "GuestsWaitingApprovalEvtMsg"
def apply(meetingId: String, userId: String, guests: Vector[GuestWaitingVO]): GuestsWaitingApprovalEvtMsg = {
val header = BbbClientMsgHeader(GetGuestsWaitingApprovalRespMsg.NAME, meetingId, userId)
val body = GuestsWaitingApprovalEvtMsgBody(guests)
GuestsWaitingApprovalEvtMsg(header, body)
}
}
case class GuestsWaitingApprovalEvtMsg(header: BbbClientMsgHeader,
body: GuestsWaitingApprovalEvtMsgBody) extends BbbCoreMsg
case class GuestsWaitingApprovalEvtMsgBody(guests: Vector[GuestWaitingVO])

View File

@ -0,0 +1,17 @@
package org.bigbluebutton.common2.messages
object GuestsWaitingApprovedEvtMsg {
val NAME = "GuestsWaitingApprovedEvtMsg"
def apply(meetingId: String, userId: String, guests: Vector[GuestWaitingVO]): GuestsWaitingApprovedEvtMsg = {
val header = BbbClientMsgHeader(GetGuestsWaitingApprovalRespMsg.NAME, meetingId, userId)
val body = GuestsWaitingApprovedEvtMsgBody(guests)
GuestsWaitingApprovedEvtMsg(header, body)
}
}
case class GuestsWaitingApprovedEvtMsg(header: BbbClientMsgHeader,
body: GuestsWaitingApprovedEvtMsgBody) extends BbbCoreMsg
case class GuestsWaitingApprovedEvtMsgBody(guests: Vector[GuestWaitingVO])

View File

@ -0,0 +1,17 @@
package org.bigbluebutton.common2.messages
object GuestsWaitingApprovedMsg {
val NAME = "GuestsWaitingApprovedMsg"
def apply(meetingId: String, userId: String, guests: Vector[String]): GuestsWaitingApprovedMsg = {
val header = BbbClientMsgHeader(GetGuestsWaitingApprovalRespMsg.NAME, meetingId, userId)
val body = GuestsWaitingApprovedMsgBody(guests)
GuestsWaitingApprovedMsg(header, body)
}
}
case class GuestsWaitingApprovedMsg(header: BbbClientMsgHeader,
body: GuestsWaitingApprovedMsgBody) extends BbbCoreMsg
case class GuestsWaitingApprovedMsgBody(guests: Vector[String])

View File

@ -0,0 +1,10 @@
package org.bigbluebutton.common2.messages
import org.bigbluebutton.common2.domain.DefaultProps
object MeetingCreatedEvtMsg { val NAME = "MeetingCreatedEvtMsg"}
case class MeetingCreatedEvtMsg(header: BbbCoreBaseHeader,
body: MeetingCreatedEvtBody) extends BbbCoreMsg
case class MeetingCreatedEvtBody(props: DefaultProps)

Some files were not shown because too many files have changed in this diff Show More