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:
55
vendor/layeh.com/gumble/gumbleutil/acl.go
generated
vendored
Normal file
55
vendor/layeh.com/gumble/gumbleutil/acl.go
generated
vendored
Normal 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
27
vendor/layeh.com/gumble/gumbleutil/bitrate.go
generated
vendored
Normal 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
18
vendor/layeh.com/gumble/gumbleutil/channel.go
generated
vendored
Normal 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
2
vendor/layeh.com/gumble/gumbleutil/doc.go
generated
vendored
Normal 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
100
vendor/layeh.com/gumble/gumbleutil/listener.go
generated
vendored
Normal 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
80
vendor/layeh.com/gumble/gumbleutil/listenerfunc.go
generated
vendored
Normal 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
79
vendor/layeh.com/gumble/gumbleutil/main.go
generated
vendored
Normal 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
45
vendor/layeh.com/gumble/gumbleutil/textmessage.go
generated
vendored
Normal 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()
|
||||
}
|
Reference in New Issue
Block a user