mirror of
https://github.com/stryan/mumble-discord-bridge.git
synced 2024-12-28 17:15:40 -05:00
send messages between mumble and discord when users connect/disconnect
This commit is contained in:
parent
5f9ad7b7dd
commit
cbd6d19066
102
discord.go
102
discord.go
@ -18,10 +18,19 @@ type fromDiscord struct {
|
||||
streaming bool
|
||||
}
|
||||
|
||||
type discordUser struct {
|
||||
username string
|
||||
seen bool
|
||||
dm *discordgo.Channel
|
||||
}
|
||||
|
||||
var discordMutex sync.Mutex
|
||||
var discordMixerMutex sync.Mutex
|
||||
var fromDiscordMap = make(map[uint32]fromDiscord)
|
||||
|
||||
var discordUsersMutex sync.Mutex
|
||||
var discordUsers = make(map[string]discordUser) // id is the key
|
||||
|
||||
// OnError gets called by dgvoice when an error is encountered.
|
||||
// By default logs to STDERR
|
||||
var OnError = func(str string, err error) {
|
||||
@ -227,3 +236,96 @@ func fromDiscordMixer(toMumble chan<- gumble.AudioBuffer) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function acts a filter from the interall discordgo state the local state
|
||||
// This function
|
||||
func discordMemberWatcher(d *discordgo.Session, m *gumble.Client) {
|
||||
ticker := time.NewTicker(250 * time.Millisecond)
|
||||
|
||||
g, err := d.State.Guild(*discordGID)
|
||||
if err != nil {
|
||||
log.Println("error finding guild")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Watch Discordgo internal state for member changes in the channel
|
||||
for {
|
||||
<-ticker.C
|
||||
|
||||
discordUsersMutex.Lock()
|
||||
|
||||
// start := time.Now()
|
||||
|
||||
// Set all members to false
|
||||
for u := range discordUsers {
|
||||
du := discordUsers[u]
|
||||
du.seen = false
|
||||
discordUsers[u] = du
|
||||
}
|
||||
|
||||
// Sync the channel voice states to the local discordUsersMap
|
||||
for _, vs := range g.VoiceStates {
|
||||
if vs.ChannelID == *discordCID {
|
||||
if d.State.User.ID == vs.UserID {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := discordUsers[vs.UserID]; !ok {
|
||||
|
||||
u, err := d.User(vs.UserID)
|
||||
if err != nil {
|
||||
log.Println("error looking up username")
|
||||
continue
|
||||
}
|
||||
|
||||
println("User joined Discord " + u.Username)
|
||||
dm, err := d.UserChannelCreate(u.ID)
|
||||
if err != nil {
|
||||
log.Panicln("Error creating private channel for", u.Username)
|
||||
}
|
||||
discordUsers[vs.UserID] = discordUser{
|
||||
username: u.Username,
|
||||
seen: true,
|
||||
dm: dm,
|
||||
}
|
||||
m.Do(func() {
|
||||
m.Self.Channel.Send(fmt.Sprintf("%v has joined Discord\n", u.Username), false)
|
||||
})
|
||||
} else {
|
||||
du := discordUsers[vs.UserID]
|
||||
du.seen = true
|
||||
discordUsers[vs.UserID] = du
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Remove users that are no longer connected
|
||||
for id := range discordUsers {
|
||||
if discordUsers[id].seen == false {
|
||||
println("User left Discord channel " + discordUsers[id].username)
|
||||
m.Do(func() {
|
||||
m.Self.Channel.Send(fmt.Sprintf("%v has left Discord channel\n", discordUsers[id].username), false)
|
||||
})
|
||||
delete(discordUsers, id)
|
||||
}
|
||||
}
|
||||
|
||||
discordUsersMutex.Unlock()
|
||||
|
||||
// elapsed := time.Since(start)
|
||||
// log.Printf("Discord user sync took %s", elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
func discordSendMessageAll(d *discordgo.Session, msg string) {
|
||||
discordUsersMutex.Lock()
|
||||
for id := range discordUsers {
|
||||
du := discordUsers[id]
|
||||
if du.dm != nil {
|
||||
log.Println("Sensing msg to ")
|
||||
d.ChannelMessageSend(du.dm.ID, msg)
|
||||
}
|
||||
}
|
||||
discordUsersMutex.Unlock()
|
||||
}
|
||||
|
24
main.go
24
main.go
@ -25,6 +25,11 @@ var (
|
||||
date string
|
||||
)
|
||||
|
||||
var (
|
||||
discordGID *string
|
||||
discordCID *string
|
||||
)
|
||||
|
||||
func lookupEnvOrString(key string, defaultVal string) string {
|
||||
if val, ok := os.LookupEnv(key); ok {
|
||||
return val
|
||||
@ -71,13 +76,13 @@ func main() {
|
||||
|
||||
mumbleAddr := flag.String("mumble-address", lookupEnvOrString("MUMBLE_ADDRESS", ""), "MUMBLE_ADDRESS, mumble server address, example example.com")
|
||||
mumblePort := flag.Int("mumble-port", lookupEnvOrInt("MUMBLE_PORT", 64738), "MUMBLE_PORT mumble port")
|
||||
mumbleUsername := flag.String("mumble-username", lookupEnvOrString("MUMBLE_USERNAME", "discord-bridge"), "MUMBLE_USERNAME, mumble username")
|
||||
mumbleUsername := flag.String("mumble-username", lookupEnvOrString("MUMBLE_USERNAME", "discord"), "MUMBLE_USERNAME, mumble username")
|
||||
mumblePassword := flag.String("mumble-password", lookupEnvOrString("MUMBLE_PASSWORD", ""), "MUMBLE_PASSWORD, mumble password, optional")
|
||||
mumbleInsecure := flag.Bool("mumble-insecure", lookupEnvOrBool("MUMBLE_INSECURE", false), "mumble insecure, env alt MUMBLE_INSECURE")
|
||||
|
||||
discordToken := flag.String("discord-token", lookupEnvOrString("DISCORD_TOKEN", ""), "DISCORD_TOKEN, discord bot token")
|
||||
discordGID := flag.String("discord-gid", lookupEnvOrString("DISCORD_GID", ""), "DISCORD_GID, discord gid")
|
||||
discordCID := flag.String("discord-cid", lookupEnvOrString("DISCORD_CID", ""), "DISCORD_CID, discord cid")
|
||||
discordGID = flag.String("discord-gid", lookupEnvOrString("DISCORD_GID", ""), "DISCORD_GID, discord gid")
|
||||
discordCID = flag.String("discord-cid", lookupEnvOrString("DISCORD_CID", ""), "DISCORD_CID, discord cid")
|
||||
|
||||
flag.Parse()
|
||||
log.Printf("app.config %v\n", getConfig(flag.CommandLine))
|
||||
@ -116,7 +121,11 @@ func main() {
|
||||
}
|
||||
|
||||
// Open Websocket
|
||||
discord.ShouldReconnectOnError = true
|
||||
discord.LogLevel = 1
|
||||
discord.StateEnabled = true
|
||||
discord.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsAllWithoutPrivileged)
|
||||
|
||||
err = discord.Open()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
@ -134,8 +143,6 @@ func main() {
|
||||
defer dgv.Speaking(false)
|
||||
defer dgv.Close()
|
||||
|
||||
discord.ShouldReconnectOnError = true
|
||||
|
||||
// MUMBLE Setup
|
||||
|
||||
config := gumble.NewConfig()
|
||||
@ -144,7 +151,9 @@ func main() {
|
||||
config.AudioInterval = time.Millisecond * 10
|
||||
|
||||
m := MumbleDuplex{}
|
||||
ml := MumbleEventListener{}
|
||||
ml := MumbleEventListener{
|
||||
d: discord,
|
||||
}
|
||||
|
||||
var tlsConfig tls.Config
|
||||
if *mumbleInsecure {
|
||||
@ -167,6 +176,8 @@ func main() {
|
||||
|
||||
log.Println("Mumble Connected")
|
||||
|
||||
// Initial User States
|
||||
|
||||
// Start Passing Between
|
||||
// Mumble
|
||||
go m.fromMumbleMixer(toDiscord)
|
||||
@ -176,6 +187,7 @@ func main() {
|
||||
go discordReceivePCM(dgv, die)
|
||||
go fromDiscordMixer(toMumble)
|
||||
go discordSendPCM(dgv, toDiscord, die)
|
||||
go discordMemberWatcher(discord, mumble)
|
||||
|
||||
// Wait for Exit Signal
|
||||
c := make(chan os.Signal)
|
||||
|
@ -2,13 +2,17 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"layeh.com/gumble/gumble"
|
||||
_ "layeh.com/gumble/opus"
|
||||
)
|
||||
|
||||
// MumbleEventListener - Bridge Event Handler
|
||||
type MumbleEventListener struct{}
|
||||
type MumbleEventListener struct {
|
||||
d *discordgo.Session
|
||||
}
|
||||
|
||||
// OnConnect - event handler
|
||||
func (ml MumbleEventListener) OnConnect(e *gumble.ConnectEvent) {
|
||||
@ -28,6 +32,33 @@ func (ml MumbleEventListener) OnTextMessage(e *gumble.TextMessageEvent) {
|
||||
// OnUserChange - event handler
|
||||
func (ml MumbleEventListener) OnUserChange(e *gumble.UserChangeEvent) {
|
||||
fmt.Println("OnUserChange", e.User.Name, e)
|
||||
if e.Type.Has(gumble.UserChangeConnected) {
|
||||
e.User.Send("Mumble-Discord-Bridge v" + version)
|
||||
|
||||
// Tell the user who is connected to discord
|
||||
if len(discordUsers) == 0 {
|
||||
e.User.Send("No users connected to Discord")
|
||||
} else {
|
||||
s := "Users connected to Discord: "
|
||||
|
||||
arr := []string{}
|
||||
discordUsersMutex.Lock()
|
||||
for u := range discordUsers {
|
||||
arr = append(arr, u)
|
||||
}
|
||||
|
||||
s = s + strings.Join(arr[:], ",")
|
||||
|
||||
discordUsersMutex.Unlock()
|
||||
e.User.Send(s)
|
||||
}
|
||||
|
||||
// Send discord a notice
|
||||
discordSendMessageAll(ml.d, e.User.Name+" has joined mumble")
|
||||
}
|
||||
if e.Type.Has(gumble.UserChangeDisconnected) {
|
||||
discordSendMessageAll(ml.d, e.User.Name+" has left mumble")
|
||||
}
|
||||
}
|
||||
|
||||
// OnChannelChange - event handler
|
||||
|
Loading…
Reference in New Issue
Block a user