/*
* GT-Mconf: Multiconference system for interoperable web and mobile
* http://www.inf.ufrgs.br/prav/gtmconf
* PRAV Labs - UFRGS
*
* This file is part of Mconf-Mobile.
*
* Mconf-Mobile is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Mconf-Mobile is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Mconf-Mobile. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mconf.bbb.listeners;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.netty.channel.Channel;
import org.mconf.bbb.MainRtmpConnection;
import org.mconf.bbb.Module;
import org.mconf.bbb.BigBlueButtonClient.OnListenerJoinedListener;
import org.mconf.bbb.BigBlueButtonClient.OnListenerLeftListener;
import org.mconf.bbb.BigBlueButtonClient.OnListenerStatusChangeListener;
import org.red5.server.api.IAttributeStore;
import org.red5.server.api.so.IClientSharedObject;
import org.red5.server.api.so.ISharedObjectBase;
import org.red5.server.api.so.ISharedObjectListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.flazr.rtmp.message.Command;
import com.flazr.rtmp.message.CommandAmf0;
public class ListenersModule extends Module implements ISharedObjectListener {
private static final Logger log = LoggerFactory.getLogger(ListenersModule.class);
private final IClientSharedObject voiceSO;
private Map<Integer, Listener> listeners = new HashMap<Integer, Listener>();
private boolean roomMuted;
public ListenersModule(MainRtmpConnection handler, Channel channel) {
super(handler, channel);
voiceSO = handler.getSharedObject("meetMeUsersSO", false);
voiceSO.addSharedObjectListener(this);
voiceSO.connect(channel);
}
@Override
public void onSharedObjectClear(ISharedObjectBase so) {
log.debug("onSharedObjectClear");
doGetCurrentUsers();
doGetRoomMuteState();
}
public void doGetCurrentUsers() {
Command cmd = new CommandAmf0("voice.getMeetMeUsers", null);
handler.writeCommandExpectingResult(channel, cmd);
}
/*
<< [STRING _result]
<< [NUMBER 5.0]
<< [NULL null]
<< [NUMBER 1.0]
<< [BOOLEAN false]
<< [BOOLEAN false]
<< [STRING Felipe]
<< [NUMBER 5.0]
<< [BOOLEAN false]
<< [MAP {talking=false, muted=false, name=Felipe, participant=5.0, locked=false}]
<< [MAP {5={talking=false, muted=false, name=Felipe, participant=5.0, locked=false}}]
<< [MAP {count=1.0, participants={5={talking=false, muted=false, name=Felipe, participant=5.0, locked=false}}}]
<< [1 COMMAND_AMF0 c3 #0 t0 (0) s144] name: _result, transactionId: 5, object: null, args: [{count=1.0, participants={5={talking=false, muted=false, name=Felipe, participant=5.0, locked=false}}}]
server command: _result
result for method call: voice.getMeetMeUsers
<< [STRING _result]
<< [NUMBER 5.0]
<< [NULL null]
<< [NUMBER 0.0]
<< [MAP {count=0.0}]
<< [1 COMMAND_AMF0 c3 #0 t0 (0) s44] name: _result, transactionId: 5, object: null, args: [{count=0.0}]
server command: _result
result for method call: voice.getMeetMeUsers
*/
@SuppressWarnings("unchecked")
public boolean onGetCurrentUsers(String resultFor, Command command) {
if (resultFor.equals("voice.getMeetMeUsers")) {
listeners.clear();
// the userId is different from the UsersModule
Map<String, Object> currentUsers = (Map<String, Object>) command.getArg(0);
int count = ((Double) currentUsers.get("count")).intValue();
if (count > 0) {
Map<String, Object> participants = (Map<String, Object>) currentUsers.get("participants");
for (Map.Entry<String, Object> entry : participants.entrySet()) {
@SuppressWarnings("unused")
int userId = Integer.parseInt(entry.getKey());
Listener listener = new Listener((Map<String, Object>) entry.getValue());
onListenerJoined(listener);
}
}
return true;
}
return false;
}
public void doGetRoomMuteState() {
Command cmd = new CommandAmf0("voice.isRoomMuted", null);
handler.writeCommandExpectingResult(channel, cmd);
}
public boolean onGetRoomMuteState(String resultFor, Command command) {
if (resultFor.equals("voice.isRoomMuted")) {
setRoomMuted((Boolean) command.getArg(0));
return true;
}
return false;
}
public void doLockMuteUser(int userId, boolean lock) {
Command cmd = new CommandAmf0("voice.lockMuteUser", null, Double.valueOf(userId), Boolean.valueOf(lock));
handler.writeCommandExpectingResult(channel, cmd);
}
public void doMuteUnmuteUser(int userId, boolean mute) {
Command cmd = new CommandAmf0("voice.muteUnmuteUser", null, Double.valueOf(userId), Boolean.valueOf(mute));
handler.writeCommandExpectingResult(channel, cmd);
}
public void doMuteAllUsers(boolean mute) {
Command cmd = new CommandAmf0("voice.muteAllUsers", null, Boolean.valueOf(mute));
handler.writeCommandExpectingResult(channel, cmd);
doGetRoomMuteState();
}
public void doEjectUser(int userId) {
Command cmd = new CommandAmf0("voice.kickUSer", null, Double.valueOf(userId));
handler.writeCommandExpectingResult(channel, cmd);
}
@Override
public void onSharedObjectConnect(ISharedObjectBase so) {
log.debug("onSharedObjectConnect");
}
@Override
public void onSharedObjectDelete(ISharedObjectBase so, String key) {
log.debug("onSharedObjectDelete");
}
@Override
public void onSharedObjectDisconnect(ISharedObjectBase so) {
log.debug("onSharedObjectDisconnect");
}
@Override
public void onSharedObjectSend(ISharedObjectBase so, String method,
List<?> params) {
if (method.equals("userJoin")) {
// meetMeUsersSO { SOEvent(SERVER_SEND_MESSAGE, userJoin, [5.0, Felipe, Felipe, false, false, false]) }
Listener listener = new Listener(params);
if (!listeners.containsKey(listener.getUserId())) {
onListenerJoined(listener);
} else {
log.warn("The listener {} is already in the list", listener.getUserId());
}
} else if (method.equals("userTalk")) {
// meetMeUsersSO { SOEvent(SERVER_SEND_MESSAGE, userTalk, [5.0, true]) }
int userId = ((Double) params.get(0)).intValue();
IListener listener = listeners.get(userId);
if (listener != null) {
listener.setTalking((Boolean) params.get(1));
for (OnListenerStatusChangeListener l : handler.getContext().getListenerStatusChangeListeners())
l.onChangeIsTalking(listener);
} else {
log.warn("Can't find the listener {} on userTalk", userId);
}
} else if (method.equals("userLockedMute")) {
// meetMeUsersSO { SOEvent(SERVER_SEND_MESSAGE, userLockedMute, [4.0, true]) }
int userId = ((Double) params.get(0)).intValue();
IListener listener = listeners.get(userId);
if (listener != null) {
listener.setLocked((Boolean) params.get(1));
} else {
log.warn("Can't find the listener {} on userLockedMute", userId);
}
} else if (method.equals("userMute")) {
// meetMeUsersSO { SOEvent(SERVER_SEND_MESSAGE, userMute, [4.0, true]) }
int userId = ((Double) params.get(0)).intValue();
IListener listener = listeners.get(userId);
if (listener != null) {
listener.setMuted((Boolean) params.get(1));
for (OnListenerStatusChangeListener l : handler.getContext().getListenerStatusChangeListeners())
l.onChangeIsMuted(listener);
} else {
log.warn("Can't find the listener {} on userMute", userId);
}
} else if (method.equals("userLeft")) {
// meetMeUsersSO { SOEvent(SERVER_SEND_MESSAGE, userLeft, [2.0]) }
int userId = ((Double) params.get(0)).intValue();
IListener listener = listeners.get(userId);
if (listener != null) {
for (OnListenerLeftListener l : handler.getContext().getListenerLeftListeners())
l.onListenerLeft(listener);
listeners.remove(userId);
} else {
log.warn("Can't find the listener {} on userLeft", userId);
}
} else if (method.equals("muteStateCallback")) {
// meetMeUsersSO { SOEvent(SERVER_SEND_MESSAGE, muteStateCallback, [false]) }
setRoomMuted((Boolean) params.get(0));
}
log.debug("onSharedObjectSend");
}
@Override
public void onSharedObjectUpdate(ISharedObjectBase so, String key,
Object value) {
log.debug("onSharedObjectUpdate1");
}
@Override
public void onSharedObjectUpdate(ISharedObjectBase so,
IAttributeStore values) {
log.debug("onSharedObjectUpdate2");
}
@Override
public void onSharedObjectUpdate(ISharedObjectBase so,
Map<String, Object> values) {
log.debug("onSharedObjectUpdate3");
}
@Override
public boolean onCommand(String resultFor, Command command) {
if (onGetCurrentUsers(resultFor, command)
|| onGetRoomMuteState(resultFor, command)) {
return true;
} else
return false;
}
public void setRoomMuted(boolean roomMuted) {
this.roomMuted = roomMuted;
}
public boolean isRoomMuted() {
return roomMuted;
}
public Map<Integer, Listener> getListeners() {
return listeners;
}
public void onListenerJoined(Listener p) {
log.debug("New listener: " + p.toString());
listeners.put(p.getUserId(), p);
for (OnListenerJoinedListener l : handler.getContext().getListenerJoinedListeners())
l.onListenerJoined(p);
}
}