blob: 7d3886327f916db0203ca1309d340cdf186e64ee (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// 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"
"mumble.info/grumble/pkg/acl"
)
// 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 acl.Context
// 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.Groups = make(map[string]acl.Group)
channel.Links = make(map[int]*Channel)
return
}
// AddChild adds a child channel to a channel
func (channel *Channel) AddChild(child *Channel) {
child.parent = channel
child.ACL.Parent = &channel.ACL
channel.children[child.Id] = child
}
// RemoveChild removes a child channel from a parent
func (channel *Channel) RemoveChild(child *Channel) {
child.parent = nil
child.ACL.Parent = nil
delete(channel.children, child.Id)
}
// AddClient adds client
func (channel *Channel) AddClient(client *Client) {
channel.clients[client.Session()] = client
client.Channel = channel
}
// RemoveClient removes client
func (channel *Channel) RemoveClient(client *Client) {
delete(channel.clients, client.Session())
client.Channel = nil
}
// HasDescription Does the channel have a description?
func (channel *Channel) HasDescription() bool {
return len(channel.DescriptionBlob) > 0
}
// DescriptionBlobHashBytes gets 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
}
// AllLinks 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
}
// AllSubChannels 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
}
// IsTemporary checks whether the channel is temporary
func (channel *Channel) IsTemporary() bool {
return channel.temporary
}
// IsEmpty checks whether the channel is temporary
func (channel *Channel) IsEmpty() bool {
return len(channel.clients) == 0
}
|