|
|
|
@ -22,15 +22,17 @@
@@ -22,15 +22,17 @@
|
|
|
|
|
package main |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"fmt" |
|
|
|
|
"log" |
|
|
|
|
"sync" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type RoomStatusManager interface { |
|
|
|
|
RoomUsers(*Session) []*DataSession |
|
|
|
|
JoinRoom(roomID string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) |
|
|
|
|
JoinRoom(roomID, roomName, roomType string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) |
|
|
|
|
LeaveRoom(roomID, sessionID string) |
|
|
|
|
UpdateRoom(*Session, *DataRoom) (*DataRoom, error) |
|
|
|
|
MakeRoomID(roomName, roomType string) string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type Broadcaster interface { |
|
|
|
@ -52,15 +54,24 @@ type roomManager struct {
@@ -52,15 +54,24 @@ type roomManager struct {
|
|
|
|
|
*Config |
|
|
|
|
OutgoingEncoder |
|
|
|
|
roomTable map[string]RoomWorker |
|
|
|
|
globalRoomID string |
|
|
|
|
defaultRoomID string |
|
|
|
|
roomTypeDefault string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func NewRoomManager(config *Config, encoder OutgoingEncoder) RoomManager { |
|
|
|
|
return &roomManager{ |
|
|
|
|
rm := &roomManager{ |
|
|
|
|
sync.RWMutex{}, |
|
|
|
|
config, |
|
|
|
|
encoder, |
|
|
|
|
make(map[string]RoomWorker), |
|
|
|
|
"", |
|
|
|
|
"", |
|
|
|
|
"Room", |
|
|
|
|
} |
|
|
|
|
rm.globalRoomID = rm.MakeRoomID(config.globalRoomID, "") |
|
|
|
|
rm.defaultRoomID = rm.MakeRoomID("", "") |
|
|
|
|
return rm |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rooms *roomManager) RoomUsers(session *Session) []*DataSession { |
|
|
|
@ -71,12 +82,12 @@ func (rooms *roomManager) RoomUsers(session *Session) []*DataSession {
@@ -71,12 +82,12 @@ func (rooms *roomManager) RoomUsers(session *Session) []*DataSession {
|
|
|
|
|
return []*DataSession{} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rooms *roomManager) JoinRoom(roomID string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) { |
|
|
|
|
if roomID == "" && !rooms.DefaultRoomEnabled { |
|
|
|
|
func (rooms *roomManager) JoinRoom(roomID, roomName, roomType string, credentials *DataRoomCredentials, session *Session, sessionAuthenticated bool, sender Sender) (*DataRoom, error) { |
|
|
|
|
if roomID == rooms.defaultRoomID && !rooms.DefaultRoomEnabled { |
|
|
|
|
return nil, NewDataError("default_room_disabled", "The default room is not enabled") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
roomWorker, err := rooms.GetOrCreate(roomID, credentials, sessionAuthenticated) |
|
|
|
|
roomWorker, err := rooms.GetOrCreate(roomID, roomName, roomType, credentials, sessionAuthenticated) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, err |
|
|
|
|
} |
|
|
|
@ -91,14 +102,18 @@ func (rooms *roomManager) LeaveRoom(roomID, sessionID string) {
@@ -91,14 +102,18 @@ func (rooms *roomManager) LeaveRoom(roomID, sessionID string) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rooms *roomManager) UpdateRoom(session *Session, room *DataRoom) (*DataRoom, error) { |
|
|
|
|
if !session.Hello || session.Roomid != room.Name { |
|
|
|
|
var roomID string |
|
|
|
|
if room != nil { |
|
|
|
|
roomID = rooms.MakeRoomID(room.Name, room.Type) |
|
|
|
|
} |
|
|
|
|
if !session.Hello || session.Roomid != roomID { |
|
|
|
|
return nil, NewDataError("not_in_room", "Cannot update other rooms") |
|
|
|
|
} |
|
|
|
|
// XXX(lcooper): We'll process and send documents without this field
|
|
|
|
|
// correctly, however clients cannot not handle it currently.
|
|
|
|
|
room.Type = "Room" |
|
|
|
|
if roomWorker, ok := rooms.Get(session.Roomid); ok { |
|
|
|
|
return room, roomWorker.Update(room) |
|
|
|
|
} else { |
|
|
|
|
// Set default room type if not found.
|
|
|
|
|
room.Type = rooms.roomTypeDefault |
|
|
|
|
} |
|
|
|
|
// TODO(lcooper): We should almost certainly return an error in this case.
|
|
|
|
|
return room, nil |
|
|
|
@ -145,7 +160,7 @@ func (rooms *roomManager) Get(roomID string) (room RoomWorker, ok bool) {
@@ -145,7 +160,7 @@ func (rooms *roomManager) Get(roomID string) (room RoomWorker, ok bool) {
|
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rooms *roomManager) GetOrCreate(roomID string, credentials *DataRoomCredentials, sessionAuthenticated bool) (RoomWorker, error) { |
|
|
|
|
func (rooms *roomManager) GetOrCreate(roomID, roomName, roomType string, credentials *DataRoomCredentials, sessionAuthenticated bool) (RoomWorker, error) { |
|
|
|
|
if rooms.AuthorizeRoomJoin && rooms.UsersEnabled && !sessionAuthenticated { |
|
|
|
|
return nil, NewDataError("room_join_requires_account", "Room join requires a user account") |
|
|
|
|
} |
|
|
|
@ -167,7 +182,7 @@ func (rooms *roomManager) GetOrCreate(roomID string, credentials *DataRoomCreden
@@ -167,7 +182,7 @@ func (rooms *roomManager) GetOrCreate(roomID string, credentials *DataRoomCreden
|
|
|
|
|
return nil, NewDataError("room_join_requires_account", "Room creation requires a user account") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
room := NewRoomWorker(rooms, roomID, credentials) |
|
|
|
|
room := NewRoomWorker(rooms, roomID, roomName, roomType, credentials) |
|
|
|
|
rooms.roomTable[roomID] = room |
|
|
|
|
rooms.Unlock() |
|
|
|
|
go func() { |
|
|
|
@ -196,3 +211,10 @@ func (rooms *roomManager) GlobalUsers() []*roomUser {
@@ -196,3 +211,10 @@ func (rooms *roomManager) GlobalUsers() []*roomUser {
|
|
|
|
|
rooms.RUnlock() |
|
|
|
|
return make([]*roomUser, 0) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (rooms *roomManager) MakeRoomID(roomName, roomType string) string { |
|
|
|
|
if roomType == "" { |
|
|
|
|
roomType = rooms.roomTypeDefault |
|
|
|
|
} |
|
|
|
|
return fmt.Sprintf("%s:%s", roomType, roomName) |
|
|
|
|
} |
|
|
|
|