1
0
Fork 0
forked from External/grumble
grumble/channel.go

134 lines
No EOL
3 KiB
Go

// Copyright (c) 2010 The Grumble Authors
// The use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE-file.
package main
import (
"encoding/hex"
)
// A Mumble channel
type Channel struct {
Id int
Name string
Position int
temporary bool
clients map[uint32]*Client
parent *Channel
children map[int]*Channel
// ACL
ACL []*ChannelACL
InheritACL bool
// Groups
Groups map[string]*Group
// Links
Links map[int]*Channel
// Blobs
DescriptionBlob string
}
func NewChannel(id int, name string) (channel *Channel) {
channel = new(Channel)
channel.Id = id
channel.Name = name
channel.clients = make(map[uint32]*Client)
channel.children = make(map[int]*Channel)
channel.ACL = []*ChannelACL{}
channel.Groups = make(map[string]*Group)
channel.Links = make(map[int]*Channel)
return
}
// Add a child channel to a channel
func (channel *Channel) AddChild(child *Channel) {
child.parent = channel
channel.children[child.Id] = child
}
// Remove a child channel from a parent
func (channel *Channel) RemoveChild(child *Channel) {
child.parent = nil
delete(channel.children, child.Id)
}
// Add client
func (channel *Channel) AddClient(client *Client) {
channel.clients[client.Session] = client
client.Channel = channel
}
// Remove client
func (channel *Channel) RemoveClient(client *Client) {
delete(channel.clients, client.Session)
client.Channel = nil
}
// Does the channel have a description?
func (channel *Channel) HasDescription() bool {
return len(channel.DescriptionBlob) > 0
}
// Get the channel's blob hash as a byte slice for sending via a protobuf message.
// Returns nil if there is no blob.
func (channel *Channel) DescriptionBlobHashBytes() (buf []byte) {
buf, err := hex.DecodeString(channel.DescriptionBlob)
if err != nil {
return nil
}
return buf
}
// Returns a slice of all channels in this channel's
// link chain.
func (channel *Channel) AllLinks() (seen map[int]*Channel) {
seen = make(map[int]*Channel)
walk := []*Channel{channel}
for len(walk) > 0 {
current := walk[len(walk)-1]
walk = walk[0 : len(walk)-1]
for _, linked := range current.Links {
if _, alreadySeen := seen[linked.Id]; !alreadySeen {
seen[linked.Id] = linked
walk = append(walk, linked)
}
}
}
return
}
// Returns a slice of all of this channel's subchannels.
func (channel *Channel) AllSubChannels() (seen map[int]*Channel) {
seen = make(map[int]*Channel)
walk := []*Channel{}
if len(channel.children) > 0 {
walk = append(walk, channel)
for len(walk) > 0 {
current := walk[len(walk)-1]
walk = walk[0 : len(walk)-1]
for _, child := range current.children {
if _, alreadySeen := seen[child.Id]; !alreadySeen {
seen[child.Id] = child
walk = append(walk, child)
}
}
}
}
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
}