Welcome to mirror list, hosted at ThFree Co, Russian Federation.

channel.go « grumble « cmd - github.com/mumble-voip/grumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 672c4391dc33a3829fc347231f7d70436eef0ac4 (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
132
// 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
}