Little cleanup, moved funcs around.

This commit is contained in:
Bruce Marriner 2016-03-17 14:30:58 -05:00
parent 397d04b1ff
commit 0c3d957330

218
voice.go
View file

@ -29,16 +29,18 @@ import (
// A VoiceConnectionConnection struct holds all the data and functions related to a Discord Voice Connection. // A VoiceConnectionConnection struct holds all the data and functions related to a Discord Voice Connection.
type VoiceConnection struct { type VoiceConnection struct {
sync.Mutex // future use sync.Mutex
Ready bool // If true, voice is ready to send/receive audio Debug bool // If true, print extra logging
Debug bool // If true, print extra logging Ready bool // If true, voice is ready to send/receive audio
Receive bool // If false, don't try to receive packets GuildID string
OP2 *voiceOP2 // exported for dgvoice, may change. ChannelID string
OpusSend chan []byte // Chan for sending opus audio UserID string
OpusRecv chan *Packet // Chan for receiving opus audio
GuildID string OpusSend chan []byte // Chan for sending opus audio
ChannelID string OpusRecv chan *Packet // Chan for receiving opus audio
UserID string
Receive bool // If false, don't try to receive packets
OP2 *voiceOP2 // exported for dgvoice, may change.
// FrameRate int // This can be used to set the FrameRate of Opus data // FrameRate int // This can be used to set the FrameRate of Opus data
// FrameSize int // This can be used to set the FrameSize of Opus data // FrameSize int // This can be used to set the FrameSize of Opus data
@ -94,9 +96,10 @@ type voiceHandshakeOp struct {
} }
// Open opens a voice connection. This should be called // Open opens a voice connection. This should be called
// after VoiceConnectionChannelJoin is used and the data VOICE websocket events // after VoiceChannelJoin 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,19 +134,20 @@ func (v *VoiceConnection) Open() (err error) {
} }
// WaitUntilConnected is a TEMP FUNCTION // WaitUntilConnected is a TEMP FUNCTION
// And this is going to be removed to changed entirely. // And this is going to be removed or changed entirely.
// I know it looks hacky, but I needed to get it working quickly. // I know it looks hacky, but I needed to get it working quickly.
func (v *VoiceConnection) WaitUntilConnected() error { func (v *VoiceConnection) WaitUntilConnected() error {
i := 0 i := 0
for { for {
if v.Ready {
return nil
}
if i > 10 { if i > 10 {
return fmt.Errorf("Timeout waiting for voice.") return fmt.Errorf("Timeout waiting for voice.")
} }
if v.Ready {
return nil
}
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
i++ i++
} }
@ -151,6 +155,100 @@ func (v *VoiceConnection) WaitUntilConnected() error {
return nil return nil
} }
type voiceSpeakingData struct {
Speaking bool `json:"speaking"`
Delay int `json:"delay"`
}
type voiceSpeakingOp struct {
Op int `json:"op"` // Always 5
Data voiceSpeakingData `json:"d"`
}
// Speaking sends a speaking notification to Discord over the voice websocket.
// This must be sent as true prior to sending audio and should be set to false
// once finished sending audio.
// b : Send true if speaking, false if not.
func (v *VoiceConnection) Speaking(b bool) (err error) {
if v.wsConn == nil {
return fmt.Errorf("No VoiceConnection websocket.")
}
data := voiceSpeakingOp{5, voiceSpeakingData{b, 0}}
err = v.wsConn.WriteJSON(data)
if err != nil {
fmt.Println("Speaking() write json error:", err)
return
}
return
}
// ChangeChannel sends Discord a request to change channels within a Guild
// !!! NOTE !!! This function may be removed in favour of just using ChannelVoiceJoin
func (v *VoiceConnection) ChangeChannel(channelID string, mute, deaf bool) (err error) {
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, &channelID, mute, deaf}}
err = v.session.wsConn.WriteJSON(data)
return
}
// Disconnect disconnects from this voice channel and closes the websocket
// and udp connections to Discord.
// !!! NOTE !!! this function may be removed in favour of ChannelVoiceLeave
func (v *VoiceConnection) Disconnect() (err error) {
// Send a OP4 with a nil channel to disconnect
if v.sessionID != "" {
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, nil, true, true}}
err = v.session.wsConn.WriteJSON(data)
v.sessionID = ""
}
// Close websocket and udp connections
v.Close()
delete(v.session.VoiceConnections, v.GuildID)
return
}
// Close closes the voice ws and udp connections
func (v *VoiceConnection) Close() {
v.Lock()
defer v.Unlock()
v.Ready = false
if v.close != nil {
close(v.close)
v.close = nil
}
if v.UDPConn != nil {
err := v.UDPConn.Close()
if err != nil {
fmt.Println("error closing udp connection: ", err)
}
v.UDPConn = nil
}
if v.wsConn != nil {
err := v.wsConn.Close()
if err != nil {
fmt.Println("error closing websocket connection: ", err)
}
v.wsConn = nil
}
}
// ------------------------------------------------------------------------------------------------
// Unexported Internal Functions Below.
// ------------------------------------------------------------------------------------------------
// wsListen listens on the voice websocket for messages and passes them // wsListen listens on the voice websocket for messages and passes them
// to the voice event handler. This is automatically called by the Open func // to the voice event handler. This is automatically called by the Open func
func (v *VoiceConnection) wsListen(wsConn *websocket.Conn, close <-chan struct{}) { func (v *VoiceConnection) wsListen(wsConn *websocket.Conn, close <-chan struct{}) {
@ -298,36 +396,6 @@ func (v *VoiceConnection) wsHeartbeat(wsConn *websocket.Conn, close <-chan struc
} }
} }
type voiceSpeakingData struct {
Speaking bool `json:"speaking"`
Delay int `json:"delay"`
}
type voiceSpeakingOp struct {
Op int `json:"op"` // Always 5
Data voiceSpeakingData `json:"d"`
}
// Speaking sends a speaking notification to Discord over the voice websocket.
// This must be sent as true prior to sending audio and should be set to false
// once finished sending audio.
// b : Send true if speaking, false if not.
func (v *VoiceConnection) Speaking(b bool) (err error) {
if v.wsConn == nil {
return fmt.Errorf("No VoiceConnection websocket.")
}
data := voiceSpeakingOp{5, voiceSpeakingData{b, 0}}
err = v.wsConn.WriteJSON(data)
if err != nil {
fmt.Println("Speaking() write json error:", err)
return
}
return
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Code related to the VoiceConnection UDP connection // Code related to the VoiceConnection UDP connection
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -613,63 +681,3 @@ func (v *VoiceConnection) opusReceiver(UDPConn *net.UDPConn, close <-chan struct
} }
} }
} }
// Close closes the voice ws and udp connections
func (v *VoiceConnection) Close() {
v.Lock()
defer v.Unlock()
v.Ready = false
if v.close != nil {
close(v.close)
v.close = nil
}
if v.UDPConn != nil {
err := v.UDPConn.Close()
if err != nil {
fmt.Println("error closing udp connection: ", err)
}
v.UDPConn = nil
}
if v.wsConn != nil {
err := v.wsConn.Close()
if err != nil {
fmt.Println("error closing websocket connection: ", err)
}
v.wsConn = nil
}
}
// ChangeChannel sends Discord a request to change channels within a Guild
// !!! NOTE !!! This function may be removed in favour of just using ChannelVoiceJoin
func (v *VoiceConnection) ChangeChannel(channelID string, mute, deaf bool) (err error) {
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, &channelID, mute, deaf}}
err = v.session.wsConn.WriteJSON(data)
return
}
// Disconnect disconnects from this voice channel and closes the websocket
// and udp connections to Discord.
// !!! NOTE !!! this function may be removed in favour of ChannelVoiceLeave
func (v *VoiceConnection) Disconnect() (err error) {
// Send a OP4 with a nil channel to disconnect
if v.sessionID != "" {
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, nil, true, true}}
err = v.session.wsConn.WriteJSON(data)
v.sessionID = ""
}
// Close websocket and udp connections
v.Close()
delete(v.session.VoiceConnections, v.GuildID)
return
}