Add connect timeout, fix ChannelVoiceJoin "leaking" connections
This commit is contained in:
parent
b48e8c992e
commit
5dc0b9f2a1
3 changed files with 40 additions and 16 deletions
|
@ -54,7 +54,7 @@ type Session struct {
|
||||||
// Whether the UDP Connection is ready
|
// Whether the UDP Connection is ready
|
||||||
UDPReady bool
|
UDPReady bool
|
||||||
|
|
||||||
// Stores a mapping of channel id's to VoiceConnections
|
// Stores a mapping of guild id's to VoiceConnections
|
||||||
VoiceConnections map[string]*VoiceConnection
|
VoiceConnections map[string]*VoiceConnection
|
||||||
|
|
||||||
// Managed state object, updated internally with events when
|
// Managed state object, updated internally with events when
|
||||||
|
|
28
voice.go
28
voice.go
|
@ -12,6 +12,7 @@ package discordgo
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -97,7 +98,6 @@ type voiceHandshakeOp struct {
|
||||||
// after VoiceConnectionChannelJoin is used and the data VOICE websocket events
|
// after VoiceConnectionChannelJoin is used and the data VOICE websocket events
|
||||||
// are captured.
|
// are captured.
|
||||||
func (v *VoiceConnection) Open() (err error) {
|
func (v *VoiceConnection) Open() (err error) {
|
||||||
|
|
||||||
v.Lock()
|
v.Lock()
|
||||||
defer v.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
|
@ -131,8 +131,19 @@ func (v *VoiceConnection) Open() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *VoiceConnection) WaitUntilConnected() {
|
func (v *VoiceConnection) WaitUntilConnected() error {
|
||||||
<-v.connected
|
if v.Ready {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := <-v.connected
|
||||||
|
|
||||||
|
if (!value && !v.Ready) || !ok {
|
||||||
|
delete(v.session.VoiceConnections, v.GuildID)
|
||||||
|
return errors.New("Timed out connecting to voice")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// wsListen listens on the voice websocket for messages and passes them
|
// wsListen listens on the voice websocket for messages and passes them
|
||||||
|
@ -603,9 +614,11 @@ func (v *VoiceConnection) Close() {
|
||||||
v.Lock()
|
v.Lock()
|
||||||
defer v.Unlock()
|
defer v.Unlock()
|
||||||
|
|
||||||
if v.Ready {
|
// Send a OP4 with a nil channel to disconnect
|
||||||
|
if v.sessionID != "" {
|
||||||
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, nil, true, true}}
|
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, nil, true, true}}
|
||||||
v.session.wsConn.WriteJSON(data)
|
v.session.wsConn.WriteJSON(data)
|
||||||
|
v.sessionID = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Ready = false
|
v.Ready = false
|
||||||
|
@ -632,15 +645,10 @@ func (v *VoiceConnection) Close() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change channels
|
// Request to change channels
|
||||||
func (v *VoiceConnection) ChangeChannel(channelID string) (err error) {
|
func (v *VoiceConnection) ChangeChannel(channelID string) (err error) {
|
||||||
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, &channelID, true, true}}
|
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, &channelID, true, true}}
|
||||||
|
|
||||||
err = v.session.wsConn.WriteJSON(data)
|
err = v.session.wsConn.WriteJSON(data)
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
v.ChannelID = channelID
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
18
wsapi.go
18
wsapi.go
|
@ -336,7 +336,13 @@ type voiceChannelJoinOp struct {
|
||||||
// cID : Channel ID of the channel to join.
|
// cID : Channel ID of the channel to join.
|
||||||
// mute : If true, you will be set to muted upon joining.
|
// mute : If true, you will be set to muted upon joining.
|
||||||
// deaf : If true, you will be set to deafened upon joining.
|
// deaf : If true, you will be set to deafened upon joining.
|
||||||
func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *VoiceConnection, err error) {
|
// timeout : If greater than zero, the timeout in milliseconds after which connecting will fail
|
||||||
|
func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool, timeout int) (voice *VoiceConnection, err error) {
|
||||||
|
// If a voice connection for the guild exists, return that
|
||||||
|
if _, exists := s.VoiceConnections[gID]; exists {
|
||||||
|
return s.VoiceConnections[gID], err
|
||||||
|
}
|
||||||
|
|
||||||
// Send the request to Discord that we want to join the voice channel
|
// Send the request to Discord that we want to join the voice channel
|
||||||
data := voiceChannelJoinOp{4, voiceChannelJoinData{&gID, &cID, mute, deaf}}
|
data := voiceChannelJoinOp{4, voiceChannelJoinData{&gID, &cID, mute, deaf}}
|
||||||
err = s.wsConn.WriteJSON(data)
|
err = s.wsConn.WriteJSON(data)
|
||||||
|
@ -359,6 +365,16 @@ func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *Voi
|
||||||
voice.GuildID = gID
|
voice.GuildID = gID
|
||||||
voice.ChannelID = cID
|
voice.ChannelID = cID
|
||||||
|
|
||||||
|
// Queue the timeout in case we fail to connect
|
||||||
|
if timeout > 0 {
|
||||||
|
go func() {
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(timeout))
|
||||||
|
if !voice.Ready {
|
||||||
|
voice.connected <- false
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
return voice, err
|
return voice, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue