diff --git a/channel.go b/channel.go index a06e0dd..8bdb848 100644 --- a/channel.go +++ b/channel.go @@ -12,11 +12,11 @@ import ( type Channel struct { Id int Name string - Temporary bool Position int - clients map[uint32]*Client + temporary bool + clients map[uint32]*Client parent *Channel children map[int]*Channel @@ -122,3 +122,13 @@ func (channel *Channel) AllSubChannels() (seen map[int]*Channel) { } return } + +// Checks whether the channel is temporary +func (channel *Channel) IsTemporary() bool { + return channel.temporary +} + +// Checks whether the channel is temporary +func (channel *Channel) IsEmpty() bool { + return len(channel.clients) == 0 +} \ No newline at end of file diff --git a/client.go b/client.go index fea86af..1877126 100644 --- a/client.go +++ b/client.go @@ -547,7 +547,7 @@ func (client *Client) sendChannelTree(channel *Channel) { } } - if channel.Temporary { + if channel.IsTemporary() { chanstate.Temporary = proto.Bool(true) } diff --git a/message.go b/message.go index 5840cd3..70d94bc 100644 --- a/message.go +++ b/message.go @@ -136,7 +136,7 @@ func (server *Server) handleChannelRemoveMessage(client *Client, msg *Message) { } // Update datastore - if !channel.Temporary { + if !channel.IsTemporary() { server.DeleteFrozenChannel(channel) } @@ -244,7 +244,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) { } // We can't add channels to a temporary channel - if parent.Temporary { + if parent.IsTemporary() { client.sendPermissionDeniedType(mumbleproto.PermissionDenied_TemporaryChannel) return } @@ -260,7 +260,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) { // Add the new channel channel = server.AddChannel(name) channel.DescriptionBlob = key - channel.Temporary = *chanstate.Temporary + channel.temporary = *chanstate.Temporary channel.Position = int(*chanstate.Position) parent.AddChild(channel) @@ -307,7 +307,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) { }) // If it's a temporary channel, move the creator in there. - if channel.Temporary { + if channel.IsTemporary() { userstate := &mumbleproto.UserState{} userstate.Session = proto.Uint32(client.Session) userstate.ChannelId = proto.Uint32(uint32(channel.Id)) @@ -362,7 +362,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) { } // A temporary channel must not have any subchannels, so deny it. - if parent.Temporary { + if parent.IsTemporary() { client.sendPermissionDeniedType(mumbleproto.PermissionDenied_TemporaryChannel) return } @@ -473,7 +473,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) { } // Update channel in datastore - if !channel.Temporary { + if !channel.IsTemporary() { server.UpdateFrozenChannel(channel, chanstate) } } @@ -592,7 +592,7 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) { } maxChannelUsers := server.cfg.IntValue("MaxChannelUsers") - if len(dstChan.clients) >= maxChannelUsers { + if maxChannelUsers != 0 && len(dstChan.clients) >= maxChannelUsers { client.sendPermissionDeniedFallback(mumbleproto.PermissionDenied_ChannelFull, 0x010201, "Channel is full") return diff --git a/server.go b/server.go index 0e02860..8ad4036 100644 --- a/server.go +++ b/server.go @@ -69,6 +69,7 @@ type Server struct { incoming chan *Message voicebroadcast chan *VoiceBroadcast cfgUpdate chan *KeyValuePair + tempRemove chan *Channel // Signals to the server that a client has been successfully // authenticated. @@ -388,6 +389,11 @@ func (server *Server) handlerLoop() { target.SendVoiceBroadcast(vb) } + // Remove a temporary channel + case tempChannel := <- server.tempRemove: + if tempChannel.IsEmpty() { + server.RemoveChannel(tempChannel) + } // Finish client authentication. Send post-authentication // server info. case client := <-server.clientAuthenticated: @@ -1001,6 +1007,9 @@ func (server *Server) userEnterChannel(client *Client, channel *Channel, usersta oldchan := client.Channel if oldchan != nil { oldchan.RemoveClient(client) + if oldchan.IsTemporary() && oldchan.IsEmpty() { + server.tempRemove <- oldchan + } } channel.AddClient(client) @@ -1008,8 +1017,6 @@ func (server *Server) userEnterChannel(client *Client, channel *Channel, usersta server.UpdateFrozenUserLastChannel(client) - // fixme(mkrautz): Remove channel if temporary - canspeak := server.HasPermission(client, channel, SpeakPermission) if canspeak == client.Suppress { client.Suppress = !canspeak @@ -1262,6 +1269,7 @@ func (server *Server) initPerLaunchData() { server.incoming = make(chan *Message) server.voicebroadcast = make(chan *VoiceBroadcast) server.cfgUpdate = make(chan *KeyValuePair) + server.tempRemove = make(chan *Channel, 1) server.clientAuthenticated = make(chan *Client) } @@ -1276,6 +1284,7 @@ func (server *Server) cleanPerLaunchData() { server.incoming = nil server.voicebroadcast = nil server.cfgUpdate = nil + server.tempRemove = nil server.clientAuthenticated = nil }