summaryrefslogtreecommitdiffstats
path: root/vendor/layeh.com/gumble/gumbleutil
diff options
context:
space:
mode:
authorSebastian P <5564491+s3lph@users.noreply.github.com>2020-10-01 22:50:56 +0200
committerGitHub <noreply@github.com>2020-10-01 22:50:56 +0200
commit214a6a13861b9fd495797386f36507373728e577 (patch)
treea2eb9541924b432ecf7a0807f42281296fa144a4 /vendor/layeh.com/gumble/gumbleutil
parente7781dc79c0c556f60eb64a93a95a5da494dcf2d (diff)
downloadmatterbridge-msglm-214a6a13861b9fd495797386f36507373728e577.tar.gz
matterbridge-msglm-214a6a13861b9fd495797386f36507373728e577.tar.bz2
matterbridge-msglm-214a6a13861b9fd495797386f36507373728e577.zip
Add Mumble support (#1245)
Diffstat (limited to 'vendor/layeh.com/gumble/gumbleutil')
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/acl.go55
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/bitrate.go27
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/channel.go18
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/doc.go2
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/listener.go100
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/listenerfunc.go80
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/main.go79
-rw-r--r--vendor/layeh.com/gumble/gumbleutil/textmessage.go45
8 files changed, 406 insertions, 0 deletions
diff --git a/vendor/layeh.com/gumble/gumbleutil/acl.go b/vendor/layeh.com/gumble/gumbleutil/acl.go
new file mode 100644
index 00000000..67cd86d5
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/acl.go
@@ -0,0 +1,55 @@
+package gumbleutil
+
+import (
+ "layeh.com/gumble/gumble"
+)
+
+// UserGroups fetches the group names the given user belongs to in the given
+// channel. The slice of group names sent via the returned channel. On error,
+// the returned channel is closed without without sending a slice.
+func UserGroups(client *gumble.Client, user *gumble.User, channel *gumble.Channel) <-chan []string {
+ ch := make(chan []string)
+
+ if !user.IsRegistered() {
+ close(ch)
+ return ch
+ }
+
+ var detacher gumble.Detacher
+ listener := Listener{
+ Disconnect: func(e *gumble.DisconnectEvent) {
+ detacher.Detach()
+ close(ch)
+ },
+ ChannelChange: func(e *gumble.ChannelChangeEvent) {
+ if e.Channel == channel && e.Type.Has(gumble.ChannelChangeRemoved) {
+ detacher.Detach()
+ close(ch)
+ }
+ },
+ PermissionDenied: func(e *gumble.PermissionDeniedEvent) {
+ if e.Channel == channel && e.Type == gumble.PermissionDeniedPermission && (e.Permission&gumble.PermissionWrite) != 0 {
+ detacher.Detach()
+ close(ch)
+ }
+ },
+ ACL: func(e *gumble.ACLEvent) {
+ if e.ACL.Channel != channel {
+ return
+ }
+ var names []string
+ for _, g := range e.ACL.Groups {
+ if (g.UsersAdd[user.UserID] != nil || g.UsersInherited[user.UserID] != nil) && g.UsersRemove[user.UserID] == nil {
+ names = append(names, g.Name)
+ }
+ }
+ detacher.Detach()
+ ch <- names
+ close(ch)
+ },
+ }
+ detacher = client.Config.Attach(&listener)
+ channel.RequestACL()
+
+ return ch
+}
diff --git a/vendor/layeh.com/gumble/gumbleutil/bitrate.go b/vendor/layeh.com/gumble/gumbleutil/bitrate.go
new file mode 100644
index 00000000..6b93caa9
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/bitrate.go
@@ -0,0 +1,27 @@
+package gumbleutil
+
+import (
+ "time"
+
+ "layeh.com/gumble/gumble"
+)
+
+var autoBitrate = &Listener{
+ Connect: func(e *gumble.ConnectEvent) {
+ if e.MaximumBitrate != nil {
+ const safety = 5
+ interval := e.Client.Config.AudioInterval
+ dataBytes := (*e.MaximumBitrate / (8 * (int(time.Second/interval) + safety))) - 32 - 10
+
+ e.Client.Config.AudioDataBytes = dataBytes
+ }
+ },
+}
+
+// AutoBitrate is a gumble.EventListener that automatically sets the client's
+// AudioDataBytes to suitable value, based on the server's bitrate.
+var AutoBitrate gumble.EventListener
+
+func init() {
+ AutoBitrate = autoBitrate
+}
diff --git a/vendor/layeh.com/gumble/gumbleutil/channel.go b/vendor/layeh.com/gumble/gumbleutil/channel.go
new file mode 100644
index 00000000..ecf8bbef
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/channel.go
@@ -0,0 +1,18 @@
+package gumbleutil
+
+import (
+ "layeh.com/gumble/gumble"
+)
+
+// ChannelPath returns a slice of channel names, starting from the root channel
+// to the given channel.
+func ChannelPath(channel *gumble.Channel) []string {
+ var pieces []string
+ for ; channel != nil; channel = channel.Parent {
+ pieces = append(pieces, channel.Name)
+ }
+ for i := 0; i < (len(pieces) / 2); i++ {
+ pieces[len(pieces)-1-i], pieces[i] = pieces[i], pieces[len(pieces)-1-i]
+ }
+ return pieces
+}
diff --git a/vendor/layeh.com/gumble/gumbleutil/doc.go b/vendor/layeh.com/gumble/gumbleutil/doc.go
new file mode 100644
index 00000000..864a3b89
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/doc.go
@@ -0,0 +1,2 @@
+// Package gumbleutil provides extras that can make working with gumble easier.
+package gumbleutil
diff --git a/vendor/layeh.com/gumble/gumbleutil/listener.go b/vendor/layeh.com/gumble/gumbleutil/listener.go
new file mode 100644
index 00000000..5bc3167d
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/listener.go
@@ -0,0 +1,100 @@
+package gumbleutil
+
+import (
+ "layeh.com/gumble/gumble"
+)
+
+// Listener is a struct that implements the gumble.EventListener interface. The
+// corresponding event function in the struct is called if it is non-nil.
+type Listener struct {
+ Connect func(e *gumble.ConnectEvent)
+ Disconnect func(e *gumble.DisconnectEvent)
+ TextMessage func(e *gumble.TextMessageEvent)
+ UserChange func(e *gumble.UserChangeEvent)
+ ChannelChange func(e *gumble.ChannelChangeEvent)
+ PermissionDenied func(e *gumble.PermissionDeniedEvent)
+ UserList func(e *gumble.UserListEvent)
+ ACL func(e *gumble.ACLEvent)
+ BanList func(e *gumble.BanListEvent)
+ ContextActionChange func(e *gumble.ContextActionChangeEvent)
+ ServerConfig func(e *gumble.ServerConfigEvent)
+}
+
+var _ gumble.EventListener = (*Listener)(nil)
+
+// OnConnect implements gumble.EventListener.OnConnect.
+func (l Listener) OnConnect(e *gumble.ConnectEvent) {
+ if l.Connect != nil {
+ l.Connect(e)
+ }
+}
+
+// OnDisconnect implements gumble.EventListener.OnDisconnect.
+func (l Listener) OnDisconnect(e *gumble.DisconnectEvent) {
+ if l.Disconnect != nil {
+ l.Disconnect(e)
+ }
+}
+
+// OnTextMessage implements gumble.EventListener.OnTextMessage.
+func (l Listener) OnTextMessage(e *gumble.TextMessageEvent) {
+ if l.TextMessage != nil {
+ l.TextMessage(e)
+ }
+}
+
+// OnUserChange implements gumble.EventListener.OnUserChange.
+func (l Listener) OnUserChange(e *gumble.UserChangeEvent) {
+ if l.UserChange != nil {
+ l.UserChange(e)
+ }
+}
+
+// OnChannelChange implements gumble.EventListener.OnChannelChange.
+func (l Listener) OnChannelChange(e *gumble.ChannelChangeEvent) {
+ if l.ChannelChange != nil {
+ l.ChannelChange(e)
+ }
+}
+
+// OnPermissionDenied implements gumble.EventListener.OnPermissionDenied.
+func (l Listener) OnPermissionDenied(e *gumble.PermissionDeniedEvent) {
+ if l.PermissionDenied != nil {
+ l.PermissionDenied(e)
+ }
+}
+
+// OnUserList implements gumble.EventListener.OnUserList.
+func (l Listener) OnUserList(e *gumble.UserListEvent) {
+ if l.UserList != nil {
+ l.UserList(e)
+ }
+}
+
+// OnACL implements gumble.EventListener.OnACL.
+func (l Listener) OnACL(e *gumble.ACLEvent) {
+ if l.ACL != nil {
+ l.ACL(e)
+ }
+}
+
+// OnBanList implements gumble.EventListener.OnBanList.
+func (l Listener) OnBanList(e *gumble.BanListEvent) {
+ if l.BanList != nil {
+ l.BanList(e)
+ }
+}
+
+// OnContextActionChange implements gumble.EventListener.OnContextActionChange.
+func (l Listener) OnContextActionChange(e *gumble.ContextActionChangeEvent) {
+ if l.ContextActionChange != nil {
+ l.ContextActionChange(e)
+ }
+}
+
+// OnServerConfig implements gumble.EventListener.OnServerConfig.
+func (l Listener) OnServerConfig(e *gumble.ServerConfigEvent) {
+ if l.ServerConfig != nil {
+ l.ServerConfig(e)
+ }
+}
diff --git a/vendor/layeh.com/gumble/gumbleutil/listenerfunc.go b/vendor/layeh.com/gumble/gumbleutil/listenerfunc.go
new file mode 100644
index 00000000..14af0d10
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/listenerfunc.go
@@ -0,0 +1,80 @@
+package gumbleutil
+
+import (
+ "layeh.com/gumble/gumble"
+)
+
+// ListenerFunc is a single listener function that implements the
+// gumble.EventListener interface. This is useful if you would like to use a
+// type-switch for handling the different event types.
+//
+// Example:
+// handler := func(e interface{}) {
+// switch e.(type) {
+// case *gumble.ConnectEvent:
+// println("Connected")
+// case *gumble.DisconnectEvent:
+// println("Disconnected")
+// // ...
+// }
+// }
+//
+// client.Attach(gumbleutil.ListenerFunc(handler))
+type ListenerFunc func(e interface{})
+
+var _ gumble.EventListener = ListenerFunc(nil)
+
+// OnConnect implements gumble.EventListener.OnConnect.
+func (lf ListenerFunc) OnConnect(e *gumble.ConnectEvent) {
+ lf(e)
+}
+
+// OnDisconnect implements gumble.EventListener.OnDisconnect.
+func (lf ListenerFunc) OnDisconnect(e *gumble.DisconnectEvent) {
+ lf(e)
+}
+
+// OnTextMessage implements gumble.EventListener.OnTextMessage.
+func (lf ListenerFunc) OnTextMessage(e *gumble.TextMessageEvent) {
+ lf(e)
+}
+
+// OnUserChange implements gumble.EventListener.OnUserChange.
+func (lf ListenerFunc) OnUserChange(e *gumble.UserChangeEvent) {
+ lf(e)
+}
+
+// OnChannelChange implements gumble.EventListener.OnChannelChange.
+func (lf ListenerFunc) OnChannelChange(e *gumble.ChannelChangeEvent) {
+ lf(e)
+}
+
+// OnPermissionDenied implements gumble.EventListener.OnPermissionDenied.
+func (lf ListenerFunc) OnPermissionDenied(e *gumble.PermissionDeniedEvent) {
+ lf(e)
+}
+
+// OnUserList implements gumble.EventListener.OnUserList.
+func (lf ListenerFunc) OnUserList(e *gumble.UserListEvent) {
+ lf(e)
+}
+
+// OnACL implements gumble.EventListener.OnACL.
+func (lf ListenerFunc) OnACL(e *gumble.ACLEvent) {
+ lf(e)
+}
+
+// OnBanList implements gumble.EventListener.OnBanList.
+func (lf ListenerFunc) OnBanList(e *gumble.BanListEvent) {
+ lf(e)
+}
+
+// OnContextActionChange implements gumble.EventListener.OnContextActionChange.
+func (lf ListenerFunc) OnContextActionChange(e *gumble.ContextActionChangeEvent) {
+ lf(e)
+}
+
+// OnServerConfig implements gumble.EventListener.OnServerConfig.
+func (lf ListenerFunc) OnServerConfig(e *gumble.ServerConfigEvent) {
+ lf(e)
+}
diff --git a/vendor/layeh.com/gumble/gumbleutil/main.go b/vendor/layeh.com/gumble/gumbleutil/main.go
new file mode 100644
index 00000000..36419ea6
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/main.go
@@ -0,0 +1,79 @@
+package gumbleutil
+
+import (
+ "crypto/tls"
+ "flag"
+ "fmt"
+ "net"
+ "os"
+ "strconv"
+
+ "layeh.com/gumble/gumble"
+)
+
+// Main aids in the creation of a basic command line gumble bot. It accepts the
+// following flag arguments:
+// --server
+// --username
+// --password
+// --insecure
+// --certificate
+// --key
+func Main(listeners ...gumble.EventListener) {
+ server := flag.String("server", "localhost:64738", "Mumble server address")
+ username := flag.String("username", "gumble-bot", "client username")
+ password := flag.String("password", "", "client password")
+ insecure := flag.Bool("insecure", false, "skip server certificate verification")
+ certificateFile := flag.String("certificate", "", "user certificate file (PEM)")
+ keyFile := flag.String("key", "", "user certificate key file (PEM)")
+
+ if !flag.Parsed() {
+ flag.Parse()
+ }
+
+ host, port, err := net.SplitHostPort(*server)
+ if err != nil {
+ host = *server
+ port = strconv.Itoa(gumble.DefaultPort)
+ }
+
+ keepAlive := make(chan bool)
+
+ config := gumble.NewConfig()
+ config.Username = *username
+ config.Password = *password
+ address := net.JoinHostPort(host, port)
+
+ var tlsConfig tls.Config
+
+ if *insecure {
+ tlsConfig.InsecureSkipVerify = true
+ }
+ if *certificateFile != "" {
+ if *keyFile == "" {
+ keyFile = certificateFile
+ }
+ if certificate, err := tls.LoadX509KeyPair(*certificateFile, *keyFile); err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err)
+ os.Exit(1)
+ } else {
+ tlsConfig.Certificates = append(tlsConfig.Certificates, certificate)
+ }
+ }
+ config.Attach(AutoBitrate)
+ for _, listener := range listeners {
+ config.Attach(listener)
+ }
+ config.Attach(Listener{
+ Disconnect: func(e *gumble.DisconnectEvent) {
+ keepAlive <- true
+ },
+ })
+ _, err = gumble.DialWithDialer(new(net.Dialer), address, config, &tlsConfig)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err)
+ os.Exit(1)
+ }
+
+ <-keepAlive
+}
diff --git a/vendor/layeh.com/gumble/gumbleutil/textmessage.go b/vendor/layeh.com/gumble/gumbleutil/textmessage.go
new file mode 100644
index 00000000..1ccb62b4
--- /dev/null
+++ b/vendor/layeh.com/gumble/gumbleutil/textmessage.go
@@ -0,0 +1,45 @@
+package gumbleutil
+
+import (
+ "bytes"
+ "encoding/xml"
+ "strings"
+
+ "layeh.com/gumble/gumble"
+)
+
+// PlainText returns the Message string without HTML tags or entities.
+func PlainText(tm *gumble.TextMessage) string {
+ d := xml.NewDecoder(strings.NewReader(tm.Message))
+ d.Strict = false
+ d.AutoClose = xml.HTMLAutoClose
+ d.Entity = xml.HTMLEntity
+
+ var b bytes.Buffer
+ newline := false
+ for {
+ t, _ := d.Token()
+ if t == nil {
+ break
+ }
+ switch node := t.(type) {
+ case xml.CharData:
+ if len(node) > 0 {
+ b.Write(node)
+ newline = false
+ }
+ case xml.StartElement:
+ switch node.Name.Local {
+ case "address", "article", "aside", "audio", "blockquote", "canvas", "dd", "div", "dl", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "noscript", "ol", "output", "p", "pre", "section", "table", "tfoot", "ul", "video":
+ if !newline {
+ b.WriteByte('\n')
+ newline = true
+ }
+ case "br":
+ b.WriteByte('\n')
+ newline = true
+ }
+ }
+ }
+ return b.String()
+}