forked from External/grumble
133 lines
3 KiB
Go
133 lines
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
|
|
}
|