Little cleanup, moved funcs around.
This commit is contained in:
parent
397d04b1ff
commit
0c3d957330
1 changed files with 113 additions and 105 deletions
218
voice.go
218
voice.go
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue