diff --git a/bridge.go b/bridge.go index cd57238..48a84b8 100644 --- a/bridge.go +++ b/bridge.go @@ -12,6 +12,7 @@ import ( "github.com/bwmarrin/discordgo" "layeh.com/gumble/gumble" + "layeh.com/gumble/gumbleutil" ) type BridgeState struct { @@ -19,6 +20,7 @@ type BridgeState struct { Connected bool Client *gumble.Client DiscordUsers map[string]bool + MumbleUsers map[string]bool MumbleUserCount int DiscordUserCount int AutoChan chan bool @@ -44,7 +46,10 @@ func startBridge(discord *discordgo.Session, discordGID string, discordCID strin if mumbleInsecure { tlsConfig.InsecureSkipVerify = true } - + config.Attach(gumbleutil.Listener{ + Connect: mumbleConnect, + UserChange: mumbleUserChange, + }) mumble, err := gumble.DialWithDialer(new(net.Dialer), mumbleAddr, config, &tlsConfig) if err != nil { @@ -53,13 +58,6 @@ func startBridge(discord *discordgo.Session, discordGID string, discordCID strin } defer mumble.Disconnect() Bridge.Client = mumble - if BridgeConf.MumbleChannel != "" { - //join specified channel - startingChannel := mumble.Channels.Find(BridgeConf.MumbleChannel) - if startingChannel != nil { - mumble.Self.Move(startingChannel) - } - } // Shared Channels // Shared channels pass PCM information in 10ms chunks [480]int16 var toMumble = mumble.AudioOutgoing() @@ -71,6 +69,7 @@ func startBridge(discord *discordgo.Session, discordGID string, discordCID strin // Mumble go m.fromMumbleMixer(toDiscord, die) det := config.AudioListeners.Attach(m) + //Discord go discordReceivePCM(dgv, die) go fromDiscordMixer(toMumble, die) @@ -115,7 +114,9 @@ func startBridge(discord *discordgo.Session, discordGID string, discordCID strin if err != nil { log.Println("error looking up username") Bridge.DiscordUsers[u.Username] = true - Bridge.Client.Self.Channel.Send(fmt.Sprintf("%v has joined Discord channel\n", u.Username), false) + Bridge.Client.Do(func() { + Bridge.Client.Self.Channel.Send(fmt.Sprintf("%v has joined Discord channel\n", u.Username), false) + }) } } } @@ -161,7 +162,11 @@ func discordStatusUpdate(dg *discordgo.Session, host, port string) { if curr == 0 { status = "" } else { - status = fmt.Sprintf("%v users in Mumble\n", curr) + if len(Bridge.MumbleUsers) > 0 { + status = fmt.Sprintf("%v/%v users in Mumble\n", len(Bridge.MumbleUsers), curr) + } else { + status = fmt.Sprintf("%v users in Mumble\n", curr) + } } dg.UpdateListeningStatus(status) } diff --git a/handlers.go b/handlers.go index c8451a3..256108f 100644 --- a/handlers.go +++ b/handlers.go @@ -7,6 +7,7 @@ import ( "time" "github.com/bwmarrin/discordgo" + "layeh.com/gumble/gumble" ) func ready(s *discordgo.Session, event *discordgo.Ready) { @@ -153,7 +154,9 @@ func voiceUpdate(s *discordgo.Session, event *discordgo.VoiceStateUpdate) { } log.Println("user joined watched discord channel") if Bridge.Connected { - Bridge.Client.Self.Channel.Send(fmt.Sprintf("%v has joined Discord channel\n", u.Username), false) + Bridge.Client.Do(func() { + Bridge.Client.Self.Channel.Send(fmt.Sprintf("%v has joined Discord channel\n", u.Username), false) + }) } Bridge.DiscordUsers[u.Username] = true log.Println(Bridge.DiscordUsers) @@ -183,7 +186,9 @@ func voiceUpdate(s *discordgo.Session, event *discordgo.VoiceStateUpdate) { delete(Bridge.DiscordUsers, u.Username) log.Println("user left watched discord channel") if Bridge.Connected { - Bridge.Client.Self.Channel.Send(fmt.Sprintf("%v has left Discord channel\n", u.Username), false) + Bridge.Client.Do(func() { + Bridge.Client.Self.Channel.Send(fmt.Sprintf("%v has left Discord channel\n", u.Username), false) + }) } Bridge.DiscordUserCount = count } @@ -192,3 +197,27 @@ func voiceUpdate(s *discordgo.Session, event *discordgo.VoiceStateUpdate) { } return } + +func mumbleConnect(e *gumble.ConnectEvent) { + if BridgeConf.MumbleChannel != "" { + //join specified channel + startingChannel := e.Client.Channels.Find(BridgeConf.MumbleChannel) + if startingChannel != nil { + e.Client.Self.Move(startingChannel) + } + } +} + +func mumbleUserChange(e *gumble.UserChangeEvent) { + if e.Type.Has(gumble.UserChangeConnected) || e.Type.Has(gumble.UserChangeChannel) || e.Type.Has(gumble.UserChangeDisconnected) { + Bridge.MumbleUsers = make(map[string]bool) + for _, user := range Bridge.Client.Self.Channel.Users { + //note, this might be too slow for really really big channels? + //event listeners block while processing + //also probably bad to rebuild the set every user change. + if user.Name != Bridge.Client.Self.Name { + Bridge.MumbleUsers[user.Name] = true + } + } + } +} diff --git a/main.go b/main.go index 03b32f9..10dad71 100644 --- a/main.go +++ b/main.go @@ -91,6 +91,7 @@ func main() { config.Password = *mumblePassword config.AudioInterval = time.Millisecond * 10 + // Bridge setup BridgeConf = &BridgeConfig{ Config: config, MumbleAddr: *mumbleAddr + ":" + strconv.Itoa(*mumblePort),