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

@ -1,161 +1,161 @@
package org.bigbluebutton.core.api
import org.bigbluebutton.common2.messages.breakoutrooms._
import org.bigbluebutton.core.apps._
import org.bigbluebutton.core.models._
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
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnding(meetingID: String) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
case class MeetingHasEnded(meetingID: String, userId: String) extends IOutMessage
case class MeetingDestroyed(meetingID: String) extends IOutMessage
case class DisconnectAllUsers(meetingID: String) extends IOutMessage
case class InactivityWarning(meetingID: String, duration: Long) extends IOutMessage
case class MeetingIsActive(meetingID: String) extends IOutMessage
case class DisconnectUser(meetingID: String, userId: String) extends IOutMessage
case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
case object IsAliveMessage extends IOutMessage
// Breakout Rooms
case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean) extends IOutMessage
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, redirectJoinURL: String, noRedirectJoinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomInfo) extends IOutMessage
case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUserVO]) extends IOutMessage
case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) extends IOutMessage
// Permissions
case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class NewPermissionsSetting(meetingID: String, setByUser: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class UserLocked(meetingID: String, userId: String, lock: Boolean) extends IOutMessage
case class GetPermissionsSettingReply(meetingID: String, userId: String) extends IOutMessage
// Users
case class UserRegistered(meetingID: String, recorded: Boolean, user: RegisteredUser) extends IOutMessage
case class UserLeft(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserEjectedFromMeeting(meetingID: String, recorded: Boolean, userId: String, ejectedBy: String) extends IOutMessage
case class PresenterAssigned(meetingID: String, recorded: Boolean, presenter: Presenter) extends IOutMessage
case class EjectAllVoiceUsers(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class EndAndKickAll(meetingID: String, recorded: Boolean) extends IOutMessage
case class GetUsersReply(meetingID: String, requesterID: String, users: Array[UserVO]) extends IOutMessage
case class ValidateAuthTokenTimedOut(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class ValidateAuthTokenReply(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class UserJoined(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserChangedEmojiStatus(meetingID: String, recorded: Boolean, emojiStatus: String, userID: String) extends IOutMessage
case class UserListeningOnly(meetingID: String, recorded: Boolean, userID: String, listenOnly: Boolean) extends IOutMessage
case class UserSharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserUnsharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserStatusChange(meetingID: String, recorded: Boolean, userID: String, status: String, value: Object) extends IOutMessage
case class UserRoleChange(meetingID: String, recorded: Boolean, userID: String, role: String) extends IOutMessage
case class GetUsersInVoiceConference(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class MuteVoiceUser(meetingID: String, recorded: Boolean, requesterID: String,
userId: String, voiceConfId: String, voiceUserId: String, mute: Boolean) extends IOutMessage
case class UserVoiceMuted(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserVoiceTalking(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class EjectVoiceUser(meetingID: String, recorded: Boolean, requesterID: String, userId: String, voiceConfId: String, voiceUserId: String) extends IOutMessage
case class TransferUserToMeeting(voiceConfId: String, targetVoiceConfId: String, userId: String) extends IOutMessage
case class UserJoinedVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserLeftVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class AllowUserToShareDesktopOut(meetingID: String, userID: String, allowed: Boolean) extends IOutMessage
// Voice
case class IsMeetingMutedReply(meetingID: String, recorded: Boolean, requesterID: String, meetingMuted: Boolean) extends IOutMessage
case class StartRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
case class StartRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class StopRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String, recordedStream: String) extends IOutMessage
case class StopRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
// Chat
case class GetChatHistoryReply(meetingID: String, recorded: Boolean, requesterID: String,
replyTo: String, history: Array[Map[String, String]]) extends IOutMessage
case class SendPublicMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage
case class SendPrivateMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage
case class ClearPublicChatHistoryReply(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
// Layout
case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String,
locked: Boolean, setByUserID: String) extends IOutMessage
case class BroadcastLayoutEvent(meetingID: String, recorded: Boolean, requesterID: String,
layoutID: String, locked: Boolean, setByUserID: String, applyTo: Array[UserVO]) extends IOutMessage
case class LockLayoutEvent(meetingID: String, recorded: Boolean, setById: String, locked: Boolean,
applyTo: Array[UserVO]) extends IOutMessage
// Presentation
case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage
case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String,
info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage
case class GetSlideInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, page: Page, replyTo: String) extends IOutMessage
case class GetPreuploadedPresentationsOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class PresentationConversionProgress(meetingID: String, messageKey: String, code: String,
presentationId: String, presentationName: String) extends IOutMessage
case class PresentationConversionError(meetingID: String, messageKey: String, code: String,
presentationId: String, numberOfPages: Int, maxNumberPages: Int, presentationName: String) extends IOutMessage
case class PresentationPageGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presentationName: String) extends IOutMessage
case class PresentationConversionDone(meetingID: String, recorded: Boolean, messageKey: String, code: String,
presentation: Presentation) extends IOutMessage
case class PresentationChanged(meetingID: String, presentation: Presentation) extends IOutMessage
case class GetPresentationStatusReply(meetingID: String, presentations: Seq[Presentation], current: Presentation, replyTo: String) extends IOutMessage
case class PresentationRemoved(meetingID: String, presentationId: String) extends IOutMessage
case class PageChanged(meetingID: String, page: Page) extends IOutMessage
// Polling
//case class PollCreatedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: PollVO) extends IOutMessage
//case class CreatePollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String, pollType: String) extends IOutMessage
case class PollStartedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollOutVO) extends IOutMessage
case class StartPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollStoppedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class StopPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String) extends IOutMessage
case class PollShowResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class ShowPollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollHideResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class HidePollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class UserRespondedToPollMessage(meetingID: String, recorded: Boolean, presenterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class RespondToPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requesterId: String, hasPoll: Boolean, poll: Option[PollVO]) extends IOutMessage
// No idea what part this is for
case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage
// DeskShare
case class DeskShareStartRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareStopRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareNotifyViewersRTMP(meetingID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareNotifyASingleViewer(meetingID: String, userID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareHangUp(meetingID: String, fsConferenceName: String) extends IOutMessage
// Guest
case class GetGuestPolicyReply(meetingID: String, recorded: Boolean, requesterID: String, policy: String) extends IOutMessage
case class GuestPolicyChanged(meetingID: String, recorded: Boolean, policy: String) extends IOutMessage
case class GuestAccessDenied(meetingID: String, recorded: Boolean, userId: String) extends IOutMessage
// Shared Notes
case class PatchDocumentReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String, patch: String, patchID: Int, undo: Boolean, redo: Boolean) extends IOutMessage
case class GetCurrentDocumentReply(meetingID: String, recorded: Boolean, requesterID: String, notes: Map[String, NoteReport]) extends IOutMessage
case class CreateAdditionalNotesReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String, noteName: String) extends IOutMessage
case class DestroyAdditionalNotesReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String) extends IOutMessage
case class SharedNotesSyncNoteReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String, note: NoteReport) extends IOutMessage
// Value Objects
case class MeetingVO(id: String, recorded: Boolean)
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
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnding(meetingID: String) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
case class MeetingHasEnded(meetingID: String, userId: String) extends IOutMessage
case class MeetingDestroyed(meetingID: String) extends IOutMessage
case class DisconnectAllUsers(meetingID: String) extends IOutMessage
case class InactivityWarning(meetingID: String, duration: Long) extends IOutMessage
case class MeetingIsActive(meetingID: String) extends IOutMessage
case class DisconnectUser(meetingID: String, userId: String) extends IOutMessage
case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
case object IsAliveMessage extends IOutMessage
// Breakout Rooms
case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomInfo], roomsReady: Boolean) extends IOutMessage
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, redirectJoinURL: String, noRedirectJoinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomInfo) extends IOutMessage
case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUserVO]) extends IOutMessage
case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) extends IOutMessage
// Permissions
case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class NewPermissionsSetting(meetingID: String, setByUser: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage
case class UserLocked(meetingID: String, userId: String, lock: Boolean) extends IOutMessage
case class GetPermissionsSettingReply(meetingID: String, userId: String) extends IOutMessage
// Users
case class UserRegistered(meetingID: String, recorded: Boolean, user: RegisteredUser) extends IOutMessage
case class UserLeft(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserEjectedFromMeeting(meetingID: String, recorded: Boolean, userId: String, ejectedBy: String) extends IOutMessage
case class PresenterAssigned(meetingID: String, recorded: Boolean, presenter: Presenter) extends IOutMessage
case class EjectAllVoiceUsers(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class EndAndKickAll(meetingID: String, recorded: Boolean) extends IOutMessage
case class GetUsersReply(meetingID: String, requesterID: String, users: Array[UserVO]) extends IOutMessage
case class ValidateAuthTokenTimedOut(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class ValidateAuthTokenReply(meetingID: String, requesterId: String, token: String, valid: Boolean, correlationId: String) extends IOutMessage
case class UserJoined(meetingID: String, recorded: Boolean, user: UserVO) extends IOutMessage
case class UserChangedEmojiStatus(meetingID: String, recorded: Boolean, emojiStatus: String, userID: String) extends IOutMessage
case class UserListeningOnly(meetingID: String, recorded: Boolean, userID: String, listenOnly: Boolean) extends IOutMessage
case class UserSharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserUnsharedWebcam(meetingID: String, recorded: Boolean, userID: String, stream: String) extends IOutMessage
case class UserStatusChange(meetingID: String, recorded: Boolean, userID: String, status: String, value: Object) extends IOutMessage
case class UserRoleChange(meetingID: String, recorded: Boolean, userID: String, role: String) extends IOutMessage
case class GetUsersInVoiceConference(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class MuteVoiceUser(meetingID: String, recorded: Boolean, requesterID: String,
userId: String, voiceConfId: String, voiceUserId: String, mute: Boolean) extends IOutMessage
case class UserVoiceMuted(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserVoiceTalking(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class EjectVoiceUser(meetingID: String, recorded: Boolean, requesterID: String, userId: String, voiceConfId: String, voiceUserId: String) extends IOutMessage
case class TransferUserToMeeting(voiceConfId: String, targetVoiceConfId: String, userId: String) extends IOutMessage
case class UserJoinedVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class UserLeftVoice(meetingID: String, recorded: Boolean, confNum: String, user: UserVO) extends IOutMessage
case class AllowUserToShareDesktopOut(meetingID: String, userID: String, allowed: Boolean) extends IOutMessage
// Voice
case class IsMeetingMutedReply(meetingID: String, recorded: Boolean, requesterID: String, meetingMuted: Boolean) extends IOutMessage
case class StartRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
case class StartRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String) extends IOutMessage
case class StopRecordingVoiceConf(meetingID: String, recorded: Boolean, voiceConfId: String, recordedStream: String) extends IOutMessage
case class StopRecording(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
// Chat
case class GetChatHistoryReply(meetingID: String, recorded: Boolean, requesterID: String,
replyTo: String, history: Array[Map[String, String]]) extends IOutMessage
case class SendPublicMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage
case class SendPrivateMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage
case class ClearPublicChatHistoryReply(meetingID: String, recorded: Boolean, requesterID: String) extends IOutMessage
// Layout
case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String,
locked: Boolean, setByUserID: String) extends IOutMessage
case class BroadcastLayoutEvent(meetingID: String, recorded: Boolean, requesterID: String,
layoutID: String, locked: Boolean, setByUserID: String, applyTo: Array[UserVO]) extends IOutMessage
case class LockLayoutEvent(meetingID: String, recorded: Boolean, setById: String, locked: Boolean,
applyTo: Array[UserVO]) extends IOutMessage
// Presentation
case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage
case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String,
info: CurrentPresentationInfo, replyTo: String) extends IOutMessage
case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage
case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage
case class GetSlideInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, page: Page, replyTo: String) extends IOutMessage
case class GetPreuploadedPresentationsOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage
case class PresentationConversionProgress(meetingID: String, messageKey: String, code: String,
presentationId: String, presentationName: String) extends IOutMessage
case class PresentationConversionError(meetingID: String, messageKey: String, code: String,
presentationId: String, numberOfPages: Int, maxNumberPages: Int, presentationName: String) extends IOutMessage
case class PresentationPageGenerated(meetingID: String, messageKey: String, code: String, presentationId: String,
numberOfPages: Int, pagesCompleted: Int, presentationName: String) extends IOutMessage
case class PresentationConversionDone(meetingID: String, recorded: Boolean, messageKey: String, code: String,
presentation: Presentation) extends IOutMessage
case class PresentationChanged(meetingID: String, presentation: Presentation) extends IOutMessage
case class GetPresentationStatusReply(meetingID: String, presentations: Seq[Presentation], current: Presentation, replyTo: String) extends IOutMessage
case class PresentationRemoved(meetingID: String, presentationId: String) extends IOutMessage
case class PageChanged(meetingID: String, page: Page) extends IOutMessage
// Polling
//case class PollCreatedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: PollVO) extends IOutMessage
//case class CreatePollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String, pollType: String) extends IOutMessage
case class PollStartedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollOutVO) extends IOutMessage
case class StartPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollStoppedMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class StopPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String) extends IOutMessage
case class PollShowResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class ShowPollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollHideResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class HidePollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class UserRespondedToPollMessage(meetingID: String, recorded: Boolean, presenterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class RespondToPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requesterId: String, hasPoll: Boolean, poll: Option[PollVO]) extends IOutMessage
// No idea what part this is for
case class GetAllMeetingsReply(meetings: Array[MeetingInfo]) extends IOutMessage
// DeskShare
case class DeskShareStartRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareStopRTMPBroadcast(conferenceName: String, streamPath: String) extends IOutMessage
case class DeskShareNotifyViewersRTMP(meetingID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareNotifyASingleViewer(meetingID: String, userID: String, streamPath: String, videoWidth: Int, videoHeight: Int, broadcasting: Boolean) extends IOutMessage
case class DeskShareHangUp(meetingID: String, fsConferenceName: String) extends IOutMessage
// Guest
case class GetGuestPolicyReply(meetingID: String, recorded: Boolean, requesterID: String, policy: String) extends IOutMessage
case class GuestPolicyChanged(meetingID: String, recorded: Boolean, policy: String) extends IOutMessage
case class GuestAccessDenied(meetingID: String, recorded: Boolean, userId: String) extends IOutMessage
// Shared Notes
case class PatchDocumentReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String, patch: String, patchID: Int, undo: Boolean, redo: Boolean) extends IOutMessage
case class GetCurrentDocumentReply(meetingID: String, recorded: Boolean, requesterID: String, notes: Map[String, NoteReport]) extends IOutMessage
case class CreateAdditionalNotesReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String, noteName: String) extends IOutMessage
case class DestroyAdditionalNotesReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String) extends IOutMessage
case class SharedNotesSyncNoteReply(meetingID: String, recorded: Boolean, requesterID: String, noteID: String, note: NoteReport) extends IOutMessage
// 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,68 +1,68 @@
package org.bigbluebutton.core.apps
import org.bigbluebutton.core.api._
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.models.{ Roles, UserVO, Users }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait LayoutApp {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) {
outGW.send(new GetCurrentLayoutReply(msg.meetingID, props.recordProp.record, msg.requesterID,
liveMeeting.layoutModel.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
liveMeeting.layoutModel.getLayoutSetter()))
}
def handleLockLayoutRequest(msg: LockLayoutRequest) {
liveMeeting.layoutModel.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)
broadcastSyncLayout(msg.meetingID, msg.setById)
}
}
private def broadcastSyncLayout(meetingId: String, setById: String) {
outGW.send(new BroadcastLayoutEvent(meetingId, props.recordProp.record, setById,
liveMeeting.layoutModel.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
liveMeeting.layoutModel.getLayoutSetter(), affectedUsers))
}
def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
liveMeeting.layoutModel.setCurrentLayout(msg.layout)
broadcastSyncLayout(msg.meetingID, msg.requesterID)
}
def handleLockLayout(lock: Boolean, setById: String) {
outGW.send(new LockLayoutEvent(props.meetingProp.intId, props.recordProp.record, setById, lock, affectedUsers))
broadcastSyncLayout(props.meetingProp.intId, setById)
}
def affectedUsers(): Array[UserVO] = {
if (liveMeeting.layoutModel.doesLayoutApplyToViewersOnly()) {
val au = ArrayBuffer[UserVO]()
Users.getUsers(liveMeeting.users) foreach { u =>
if (!u.presenter && u.role != Roles.MODERATOR_ROLE) {
au += u
}
}
au.toArray
} else {
Users.getUsers(liveMeeting.users).toArray
}
}
}
package org.bigbluebutton.core.apps
import org.bigbluebutton.common2.domain.UserVO
import scala.collection.mutable.ArrayBuffer
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
import org.bigbluebutton.core.models.{ Layouts, Roles, Users }
import org.bigbluebutton.core.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
trait LayoutApp {
this: MeetingActor =>
val outGW: OutMessageGateway
def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) {
outGW.send(new GetCurrentLayoutReply(msg.meetingID, props.recordProp.record, msg.requesterID,
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter()))
}
def handleLockLayoutRequest(msg: LockLayoutRequest) {
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 =>
Layouts.setCurrentLayout(l)
broadcastSyncLayout(msg.meetingID, msg.setById)
}
}
private def broadcastSyncLayout(meetingId: String, setById: String) {
outGW.send(new BroadcastLayoutEvent(meetingId, props.recordProp.record, setById,
Layouts.getCurrentLayout(),
MeetingStatus2x.getPermissions(liveMeeting.status).lockedLayout,
Layouts.getLayoutSetter(), affectedUsers))
}
def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
Layouts.setCurrentLayout(msg.layout)
broadcastSyncLayout(msg.meetingID, msg.requesterID)
}
def handleLockLayout(lock: Boolean, setById: String) {
outGW.send(new LockLayoutEvent(props.meetingProp.intId, props.recordProp.record, setById, lock, affectedUsers))
broadcastSyncLayout(props.meetingProp.intId, setById)
}
def affectedUsers(): Array[UserVO] = {
if (Layouts.doesLayoutApplyToViewersOnly()) {
val au = ArrayBuffer[UserVO]()
Users.getUsers(liveMeeting.users) foreach { u =>
if (!u.presenter && u.role != Roles.MODERATOR_ROLE) {
au += u
}
}
au.toArray
} 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)
pres
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,
widthRatio = widthRatio, heightRatio = heightRatio)
val nPages = pres.pages + (page.id -> page)
val newPres = pres.copy(pages = nPages)
savePresentation(newPres)
Some(page)
}
case None => None
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 + (nPage.id -> nPage)
val newPres = pres.copy(pages = nPages)
savePresentation(newPres)
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,69 +1,71 @@
package org.bigbluebutton.core.models
object RegisteredUsers {
def create(userId: String, extId: String, name: String, roles: String,
token: String, avatar: String, guest: Boolean, authenticated: Boolean,
waitingForAcceptance: Boolean, users: RegisteredUsers): RegisteredUser = {
val ru = new RegisteredUser(userId, extId, name, roles, token, avatar, guest, authenticated, waitingForAcceptance)
users.save(ru)
ru
}
def findWithToken(token: String, users: RegisteredUsers): Option[RegisteredUser] = {
users.toVector.find(u => u.authToken == token)
}
def findWithUserId(id: String, users: RegisteredUsers): Option[RegisteredUser] = {
users.toVector.find(ru => id == ru.id)
}
def getRegisteredUserWithToken(token: String, userId: String, regUsers: RegisteredUsers): Option[RegisteredUser] = {
def isSameUserId(ru: RegisteredUser, userId: String): Option[RegisteredUser] = {
if (userId.startsWith(ru.id)) {
Some(ru)
} else {
None
}
}
for {
ru <- RegisteredUsers.findWithToken(token, regUsers)
user <- isSameUserId(ru, userId)
} yield user
}
def updateRegUser(uvo: UserVO, users: RegisteredUsers) {
for {
ru <- RegisteredUsers.findWithUserId(uvo.id, users)
regUser = new RegisteredUser(uvo.id, uvo.externalId, uvo.name, uvo.role, ru.authToken,
uvo.avatarURL, uvo.guest, uvo.authed, uvo.waitingForAcceptance)
} yield users.save(regUser)
}
def remove(id: String, users: RegisteredUsers): Option[RegisteredUser] = {
users.delete(id)
}
}
class RegisteredUsers {
private var regUsers = new collection.immutable.HashMap[String, RegisteredUser]
private def toVector: Vector[RegisteredUser] = regUsers.values.toVector
private def save(user: RegisteredUser): Vector[RegisteredUser] = {
regUsers += user.authToken -> user
regUsers.values.toVector
}
private def delete(id: String): Option[RegisteredUser] = {
val ru = regUsers.get(id)
ru foreach { u => regUsers -= u.authToken }
ru
}
}
case class RegisteredUser(id: String, externId: String, name: String, role: String,
authToken: String, avatarURL: String, guest: Boolean,
authed: Boolean, waitingForAcceptance: Boolean)
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,
waitingForAcceptance: Boolean, users: RegisteredUsers): RegisteredUser = {
val ru = new RegisteredUser(userId, extId, name, roles, token, avatar, guest, authenticated, waitingForAcceptance)
users.save(ru)
ru
}
def findWithToken(token: String, users: RegisteredUsers): Option[RegisteredUser] = {
users.toVector.find(u => u.authToken == token)
}
def findWithUserId(id: String, users: RegisteredUsers): Option[RegisteredUser] = {
users.toVector.find(ru => id == ru.id)
}
def getRegisteredUserWithToken(token: String, userId: String, regUsers: RegisteredUsers): Option[RegisteredUser] = {
def isSameUserId(ru: RegisteredUser, userId: String): Option[RegisteredUser] = {
if (userId.startsWith(ru.id)) {
Some(ru)
} else {
None
}
}
for {
ru <- RegisteredUsers.findWithToken(token, regUsers)
user <- isSameUserId(ru, userId)
} yield user
}
def updateRegUser(uvo: UserVO, users: RegisteredUsers) {
for {
ru <- RegisteredUsers.findWithUserId(uvo.id, users)
regUser = new RegisteredUser(uvo.id, uvo.externalId, uvo.name, uvo.role, ru.authToken,
uvo.avatarURL, uvo.guest, uvo.authed, uvo.waitingForAcceptance)
} yield users.save(regUser)
}
def remove(id: String, users: RegisteredUsers): Option[RegisteredUser] = {
users.delete(id)
}
}
class RegisteredUsers {
private var regUsers = new collection.immutable.HashMap[String, RegisteredUser]
private def toVector: Vector[RegisteredUser] = regUsers.values.toVector
private def save(user: RegisteredUser): Vector[RegisteredUser] = {
regUsers += user.authToken -> user
regUsers.values.toVector
}
private def delete(id: String): Option[RegisteredUser] = {
val ru = regUsers.get(id)
ru foreach { u => regUsers -= u.authToken }
ru
}
}
case class RegisteredUser(id: String, externId: String, name: String, role: String,
authToken: String, avatarURL: String, guest: Boolean,
authed: Boolean, waitingForAcceptance: 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)
@ -95,4 +119,4 @@ class VoiceUsers {
case class VoiceUser2x(intId: String, voiceUserId: String)
case class VoiceUserVO2x(intId: String, voiceUserId: String, callerName: String,
callerNum: String, joined: Boolean, locked: Boolean, muted: Boolean,
talking: Boolean, callingWith: String, listenOnly: Boolean)
talking: Boolean, callingWith: String, listenOnly: Boolean)

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,9 +267,9 @@ 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 = {
log.debug("Route envelope name " + envelope.name)
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,36 +1,36 @@
package org.bigbluebutton.core.util
import org.bigbluebutton.core.models.{ UserState, UserVO, VoiceUser, VoiceUserState }
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,
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 = {
new UserVO(intId, extId, name, role, guest, authed, waitingForAcceptance = waitingForAcceptance,
emojiStatus = "none", presenter = false,
hasStream = false, locked = lockStatus,
webcamStreams = new ListSet[String](), phoneUser = false, vu,
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,
muted = vu.muted, talking = vu.talking, "none", listenOnly = vu.listenOnly)
}
def toUserVO(u: UserState, vu: VoiceUser, 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,
presenter = u.presenter, hasStream = webcams.length > 0, locked = u.locked, webcamStreams = webcams.toSet,
phoneUser = false, voiceUser = vu, listenOnly = vu.listenOnly, avatarURL = u.avatar,
joinedWeb = true)
}
}
package org.bigbluebutton.core.util
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): 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: VoiceUserVO): UserVO = {
new UserVO(intId, extId, name, role, guest, authed, waitingForAcceptance = waitingForAcceptance,
emojiStatus = "none", presenter = false,
hasStream = false, locked = lockStatus,
webcamStreams = new ListSet[String](), phoneUser = false, vu,
listenOnly = vu.listenOnly, avatarURL = vu.avatarURL, joinedWeb = true)
}
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: 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,
presenter = u.presenter, hasStream = webcams.length > 0, locked = u.locked, webcamStreams = webcams.toSet,
phoneUser = false, voiceUser = vu, listenOnly = vu.listenOnly, avatarURL = u.avatar,
joinedWeb = true)
}
}

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

@ -1,124 +1,57 @@
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.running.MeetingActor
import org.bigbluebutton.core2.MeetingStatus2x
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 &&
!MeetingStatus2x.isVoiceRecording(liveMeeting.status)) {
MeetingStatus2x.startRecordingVoice(liveMeeting.status)
log.info("Send START RECORDING voice conf. meetingId=" + props.meetingProp.intId + " voice conf=" + props.voiceProp.voiceConf)
outGW.send(new StartRecordingVoiceConf(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf))
}
}
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
+ " userId=" + msg.userId + " extUserId=" + msg.externUserId)
Users.findWithId(msg.userId, liveMeeting.users) match {
case Some(user) => {
// this is used to restore the mute state on reconnect
val previouslyMuted = user.voiceUser.muted
val nu = Users.restoreMuteState(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) || previouslyMuted) {
outGW.send(new MuteVoiceUser(props.meetingProp.intId, props.recordProp.record,
nu.id, nu.id, props.voiceProp.voiceConf,
nu.voiceUser.userId, true))
}
startRecordingVoiceConference()
}
case None => {
handleUserJoinedVoiceFromPhone(msg)
startRecordingVoiceConference()
}
}
}
}
package org.bigbluebutton.core2.message.handlers.users
import org.bigbluebutton.core.OutMessageGateway
import org.bigbluebutton.core.api._
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 startRecordingVoiceConference() {
if (Users.numUsersInVoiceConference(liveMeeting.users) == 1 &&
props.recordProp.record &&
!MeetingStatus2x.isVoiceRecording(liveMeeting.status)) {
MeetingStatus2x.startRecordingVoice(liveMeeting.status)
log.info("Send START RECORDING voice conf. meetingId=" + props.meetingProp.intId + " voice conf=" + props.voiceProp.voiceConf)
outGW.send(new StartRecordingVoiceConf(props.meetingProp.intId, props.recordProp.record, props.voiceProp.voiceConf))
}
}
def handleUserJoinedVoiceConfMessage(msg: UserJoinedVoiceConfMessage) = {
log.info("Received user joined voice. meetingId=" + props.meetingProp.intId + " callername=" + msg.callerIdName
+ " userId=" + msg.userId + " extUserId=" + msg.externUserId)
Users.findWithId(msg.userId, liveMeeting.users) match {
case Some(user) => {
// this is used to restore the mute state on reconnect
val previouslyMuted = user.voiceUser.muted
val nu = Users.restoreMuteState(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) || previouslyMuted) {
outGW.send(new MuteVoiceUser(props.meetingProp.intId, props.recordProp.record,
nu.id, nu.id, props.voiceProp.voiceConf,
nu.voiceUser.userId, true))
}
startRecordingVoiceConference()
}
case None => {
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) =>
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 = 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)
}
sendOldValidateToken(props.meetingProp.intId, msg.body.userId, msg.body.authToken)
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)
}
ValidateAuthTokenRespMsgSender.send(outGW, meetingId = props.meetingProp.intId,
userId = msg.body.userId, authToken = msg.body.authToken, valid = valid)
}
userJoinMeeting(msg.body.authToken)
sendAllUsersInMeeting(msg.body.userId)
sendAllVoiceUsersInMeeting(msg.body.userId)
sendAllWebcamStreams(msg.body.userId)
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)
@ -29,4 +29,4 @@ trait GetWhiteboardAnnotationsReqMsgHdlr {
val history = getWhiteboardAnnotations(msg.body.whiteboardId)
broadcastEvent(msg, history)
}
}
}

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,8 +63,22 @@ 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