From 729384eade161e8eebf5e1b32d576143ddc71276 Mon Sep 17 00:00:00 2001
From: Simon Eisenmann <simon@longsleep.org>
Date: Sun, 16 Feb 2014 14:23:39 +0100
Subject: [PATCH] Global room id name as configuration option and disabled per
 default.

---
 server.conf.in                              |  1 +
 src/app/spreed-speakfreely-server/config.go | 17 +++++++++--------
 src/app/spreed-speakfreely-server/hub.go    | 15 +++++++++++----
 src/app/spreed-speakfreely-server/main.go   |  8 +++++++-
 4 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/server.conf.in b/server.conf.in
index 3da5d637..e3685467 100644
--- a/server.conf.in
+++ b/server.conf.in
@@ -13,6 +13,7 @@ listen = 127.0.0.1:8080
 #turnSecret = the-default-turn-shared-secret-do-not-keep
 sessionSecret = the-default-secret-do-not-keep
 #tokenFile = tokens.txt # If set, everyone needs to give one of the tokens to launch the web client. One token per line in the file.
+#globalRoom = global # Enables a global room. Users in that room are in all rooms.
 #extraHTML = <div>Rendered directly before closing body tag.</div>
 
 [log]
diff --git a/src/app/spreed-speakfreely-server/config.go b/src/app/spreed-speakfreely-server/config.go
index 159d33cf..85b6e3f0 100644
--- a/src/app/spreed-speakfreely-server/config.go
+++ b/src/app/spreed-speakfreely-server/config.go
@@ -25,15 +25,16 @@ import (
 )
 
 type Config struct {
-	ver      string   // Version (not exported to Javascript)
-	S        string   // Static URL prefix with version
-	StunURIs []string // STUN server URIs
-	TurnURIs []string // TURN server URIs
-	Tokens   bool     // True when we got a tokens file
-	Version  string   // Server version number
+	ver          string   // Version (not exported to Javascript)
+	S            string   // Static URL prefix with version
+	StunURIs     []string // STUN server URIs
+	TurnURIs     []string // TURN server URIs
+	Tokens       bool     // True when we got a tokens file
+	Version      string   // Server version number
+	globalRoomid string   // Id of the global room (not exported to Javascript)
 }
 
-func NewConfig(ver, runtimeVersion string, stunURIs, turnURIs []string, tokens bool) *Config {
+func NewConfig(ver, runtimeVersion string, stunURIs, turnURIs []string, tokens bool, globalRoomid string) *Config {
 	sv := fmt.Sprintf("static/ver=%s", ver)
-	return &Config{ver: ver, S: sv, StunURIs: stunURIs, TurnURIs: turnURIs, Tokens: tokens, Version: runtimeVersion}
+	return &Config{ver: ver, S: sv, StunURIs: stunURIs, TurnURIs: turnURIs, Tokens: tokens, Version: runtimeVersion, globalRoomid: globalRoomid}
 }
diff --git a/src/app/spreed-speakfreely-server/hub.go b/src/app/spreed-speakfreely-server/hub.go
index 2445058b..c72c2759 100644
--- a/src/app/spreed-speakfreely-server/hub.go
+++ b/src/app/spreed-speakfreely-server/hub.go
@@ -33,7 +33,6 @@ import (
 )
 
 const (
-	globalRoomId          = "global"
 	turnTTL               = 3600 // XXX(longsleep): Add to config file.
 	maxBroadcastPerSecond = 1000
 	maxUsersLength        = 5000
@@ -139,6 +138,12 @@ func (h *Hub) GetRoom(id string) *RoomWorker {
 
 }
 
+func (h *Hub) isGlobalRoomid(id string) bool {
+
+	return id != "" && (id == h.config.globalRoomid)
+
+}
+
 func (h *Hub) registerHandler(c *Connection) {
 
 	h.mutex.Lock()
@@ -193,8 +198,9 @@ func (h *Hub) broadcastHandler(m *MessageRequest) {
 	roomid := m.Id
 	users := make([]string, len(h.userTable))
 	i := 0
+	// TODO(longsleep): Keep a userTable per room to avoid looping all users every time.
 	for id, u := range h.userTable {
-		if id == m.From || (u.Roomid != roomid && roomid != globalRoomId) {
+		if id == m.From || (u.Roomid != roomid && !h.isGlobalRoomid(roomid)) {
 			// Skip self and users not in the correct room.
 			continue
 		}
@@ -224,7 +230,7 @@ func (h *Hub) broadcastHandler(m *MessageRequest) {
 			//fmt.Println("in h.broadcast id", id, m.From, userRoomid, roomid)
 			//fmt.Println("broadcasting to", id, ec.Idx, userRoomid, roomid)
 			h.mutex.RUnlock()
-			if userRoomid != roomid && roomid != globalRoomId {
+			if userRoomid != roomid && !h.isGlobalRoomid(roomid) {
 				// Skip other rooms.
 				continue
 			}
@@ -262,8 +268,9 @@ func (h *Hub) usersHandler(c *Connection) {
 	users := &DataUsers{Type: "Users", Index: 0, Batch: 0}
 	usersList := users.Users
 	roomid := c.User.Roomid
+	// TODO(longsleep): Keep per room userTable to avoid looping all users.
 	for id, u := range h.userTable {
-		if u.Roomid == roomid || u.Roomid == globalRoomId {
+		if u.Roomid == roomid || h.isGlobalRoomid(u.Roomid) {
 			user := &DataUser{Type: "Online", Id: id, Ua: u.Ua, Status: u.Status, Rev: u.UpdateRev}
 			usersList = append(usersList, user)
 			if len(usersList) >= maxUsersLength {
diff --git a/src/app/spreed-speakfreely-server/main.go b/src/app/spreed-speakfreely-server/main.go
index 62104cbc..54f095a9 100644
--- a/src/app/spreed-speakfreely-server/main.go
+++ b/src/app/spreed-speakfreely-server/main.go
@@ -199,6 +199,12 @@ func runner(runtime phoenix.Runtime) error {
 		extraHTMLString = ""
 	}
 
+	globalRoomid, err := runtime.GetString("app", "globalRoom")
+	if err != nil {
+		// Global room is disabled.
+		globalRoomid = ""
+	}
+
 	// Create token provider.
 	var tokenProvider TokenProvider
 	if tokenFile != "" {
@@ -207,7 +213,7 @@ func runner(runtime phoenix.Runtime) error {
 	}
 
 	// Create configuration data structure.
-	config = NewConfig(ver, runtimeVersion, stunURIs, turnURIs, tokenProvider != nil)
+	config = NewConfig(ver, runtimeVersion, stunURIs, turnURIs, tokenProvider != nil, globalRoomid)
 
 	// Load templates.
 	tt := template.New("")