4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-06-27 18:09:26 +00:00

Add Mumble support (#1245)

This commit is contained in:
Sebastian P
2020-10-01 22:50:56 +02:00
committed by GitHub
parent e7781dc79c
commit 214a6a1386
61 changed files with 9409 additions and 0 deletions

55
vendor/layeh.com/gumble/gumbleutil/acl.go generated vendored Normal file
View File

@ -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
}

27
vendor/layeh.com/gumble/gumbleutil/bitrate.go generated vendored Normal file
View File

@ -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
}

18
vendor/layeh.com/gumble/gumbleutil/channel.go generated vendored Normal file
View File

@ -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
}

2
vendor/layeh.com/gumble/gumbleutil/doc.go generated vendored Normal file
View File

@ -0,0 +1,2 @@
// Package gumbleutil provides extras that can make working with gumble easier.
package gumbleutil

100
vendor/layeh.com/gumble/gumbleutil/listener.go generated vendored Normal file
View File

@ -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)
}
}

80
vendor/layeh.com/gumble/gumbleutil/listenerfunc.go generated vendored Normal file
View File

@ -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)
}

79
vendor/layeh.com/gumble/gumbleutil/main.go generated vendored Normal file
View File

@ -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
}

45
vendor/layeh.com/gumble/gumbleutil/textmessage.go generated vendored Normal file
View File

@ -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()
}