More cleanup, moving things around..
This commit is contained in:
parent
cab4964d3a
commit
513facf391
2 changed files with 88 additions and 97 deletions
177
voice.go
177
voice.go
|
@ -40,9 +40,6 @@ type VoiceConnection struct {
|
||||||
OpusSend chan []byte // Chan for sending opus audio
|
OpusSend chan []byte // Chan for sending opus audio
|
||||||
OpusRecv chan *Packet // Chan for receiving opus audio
|
OpusRecv chan *Packet // Chan for receiving opus audio
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
wsConn *websocket.Conn
|
wsConn *websocket.Conn
|
||||||
udpConn *net.UDPConn
|
udpConn *net.UDPConn
|
||||||
session *Session
|
session *Session
|
||||||
|
@ -50,8 +47,6 @@ type VoiceConnection struct {
|
||||||
sessionID string
|
sessionID string
|
||||||
token string
|
token string
|
||||||
endpoint string
|
endpoint string
|
||||||
op4 voiceOP4
|
|
||||||
op2 voiceOP2
|
|
||||||
|
|
||||||
// Used to send a close signal to goroutines
|
// Used to send a close signal to goroutines
|
||||||
close chan struct{}
|
close chan struct{}
|
||||||
|
@ -61,81 +56,43 @@ type VoiceConnection struct {
|
||||||
|
|
||||||
// Used to pass the sessionid from onVoiceStateUpdate
|
// Used to pass the sessionid from onVoiceStateUpdate
|
||||||
sessionRecv chan string
|
sessionRecv chan string
|
||||||
|
|
||||||
|
op4 voiceOP4
|
||||||
|
op2 voiceOP2
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// Speaking sends a speaking notification to Discord over the voice websocket.
|
||||||
// Code related to the VoiceConnection websocket connection
|
// 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) {
|
||||||
|
|
||||||
// A voiceOP4 stores the data for the voice operation 4 websocket event
|
type voiceSpeakingData struct {
|
||||||
// which provides us with the NaCl SecretBox encryption key
|
Speaking bool `json:"speaking"`
|
||||||
type voiceOP4 struct {
|
Delay int `json:"delay"`
|
||||||
SecretKey [32]byte `json:"secret_key"`
|
|
||||||
Mode string `json:"mode"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A voiceOP2 stores the data for the voice operation 2 websocket event
|
type voiceSpeakingOp struct {
|
||||||
// which is sort of like the voice READY packet
|
Op int `json:"op"` // Always 5
|
||||||
type voiceOP2 struct {
|
Data voiceSpeakingData `json:"d"`
|
||||||
SSRC uint32 `json:"ssrc"`
|
|
||||||
Port int `json:"port"`
|
|
||||||
Modes []string `json:"modes"`
|
|
||||||
HeartbeatInterval time.Duration `json:"heartbeat_interval"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type voiceHandshakeData struct {
|
if v.wsConn == nil {
|
||||||
ServerID string `json:"server_id"`
|
return fmt.Errorf("No VoiceConnection websocket.")
|
||||||
UserID string `json:"user_id"`
|
|
||||||
SessionID string `json:"session_id"`
|
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type voiceHandshakeOp struct {
|
data := voiceSpeakingOp{5, voiceSpeakingData{b, 0}}
|
||||||
Op int `json:"op"` // Always 0
|
|
||||||
Data voiceHandshakeData `json:"d"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open opens a voice connection. This should be called
|
|
||||||
// after VoiceChannelJoin is used and the data VOICE websocket events
|
|
||||||
// are captured.
|
|
||||||
func (v *VoiceConnection) Open() (err error) {
|
|
||||||
|
|
||||||
v.Lock()
|
|
||||||
defer v.Unlock()
|
|
||||||
|
|
||||||
// Don't open a websocket if one is already open
|
|
||||||
if v.wsConn != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to VoiceConnection Websocket
|
|
||||||
vg := fmt.Sprintf("wss://%s", strings.TrimSuffix(v.endpoint, ":80"))
|
|
||||||
v.wsConn, _, err = websocket.DefaultDialer.Dial(vg, nil)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("VOICE error opening websocket:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := voiceHandshakeOp{0, voiceHandshakeData{v.GuildID, v.UserID, v.sessionID, v.token}}
|
|
||||||
|
|
||||||
err = v.wsConn.WriteJSON(data)
|
err = v.wsConn.WriteJSON(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("VOICE error sending init packet:", err)
|
fmt.Println("Speaking() write json error:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a listening for voice websocket events
|
|
||||||
// TODO add a check here to make sure Listen worked by monitoring
|
|
||||||
// a chan or bool?
|
|
||||||
v.close = make(chan struct{})
|
|
||||||
go v.wsListen(v.wsConn, v.close)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// WaitUntilConnected is a TEMP FUNCTION
|
// WaitUntilConnected waits for the Voice Connection to
|
||||||
// And this is going to be removed or changed entirely.
|
// become ready, if it does not become ready it retuns an err
|
||||||
// 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
|
||||||
|
@ -155,36 +112,6 @@ 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
|
// ChangeChannel sends Discord a request to change channels within a Guild
|
||||||
// !!! NOTE !!! This function may be removed in favour of just using ChannelVoiceJoin
|
// !!! NOTE !!! This function may be removed in favour of just using ChannelVoiceJoin
|
||||||
func (v *VoiceConnection) ChangeChannel(channelID string, mute, deaf bool) (err error) {
|
func (v *VoiceConnection) ChangeChannel(channelID string, mute, deaf bool) (err error) {
|
||||||
|
@ -249,6 +176,70 @@ func (v *VoiceConnection) Close() {
|
||||||
// Unexported Internal Functions Below.
|
// Unexported Internal Functions Below.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// A voiceOP4 stores the data for the voice operation 4 websocket event
|
||||||
|
// which provides us with the NaCl SecretBox encryption key
|
||||||
|
type voiceOP4 struct {
|
||||||
|
SecretKey [32]byte `json:"secret_key"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// A voiceOP2 stores the data for the voice operation 2 websocket event
|
||||||
|
// which is sort of like the voice READY packet
|
||||||
|
type voiceOP2 struct {
|
||||||
|
SSRC uint32 `json:"ssrc"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Modes []string `json:"modes"`
|
||||||
|
HeartbeatInterval time.Duration `json:"heartbeat_interval"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open opens a voice connection. This should be called
|
||||||
|
// after VoiceChannelJoin is used and the data VOICE websocket events
|
||||||
|
// are captured.
|
||||||
|
func (v *VoiceConnection) open() (err error) {
|
||||||
|
|
||||||
|
v.Lock()
|
||||||
|
defer v.Unlock()
|
||||||
|
|
||||||
|
// Don't open a websocket if one is already open
|
||||||
|
if v.wsConn != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to VoiceConnection Websocket
|
||||||
|
vg := fmt.Sprintf("wss://%s", strings.TrimSuffix(v.endpoint, ":80"))
|
||||||
|
v.wsConn, _, err = websocket.DefaultDialer.Dial(vg, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("VOICE error opening websocket:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type voiceHandshakeData struct {
|
||||||
|
ServerID string `json:"server_id"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
SessionID string `json:"session_id"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
type voiceHandshakeOp struct {
|
||||||
|
Op int `json:"op"` // Always 0
|
||||||
|
Data voiceHandshakeData `json:"d"`
|
||||||
|
}
|
||||||
|
data := voiceHandshakeOp{0, voiceHandshakeData{v.GuildID, v.UserID, v.sessionID, v.token}}
|
||||||
|
|
||||||
|
err = v.wsConn.WriteJSON(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("VOICE error sending init packet:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a listening for voice websocket events
|
||||||
|
// TODO add a check here to make sure Listen worked by monitoring
|
||||||
|
// a chan or bool?
|
||||||
|
v.close = make(chan struct{})
|
||||||
|
go v.wsListen(v.wsConn, v.close)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 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{}) {
|
||||||
|
|
6
wsapi.go
6
wsapi.go
|
@ -352,11 +352,11 @@ func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *Voi
|
||||||
// Create a new voice session
|
// Create a new voice session
|
||||||
// TODO review what all these things are for....
|
// TODO review what all these things are for....
|
||||||
voice = &VoiceConnection{
|
voice = &VoiceConnection{
|
||||||
|
GuildID: gID,
|
||||||
|
ChannelID: cID,
|
||||||
session: s,
|
session: s,
|
||||||
connected: make(chan bool),
|
connected: make(chan bool),
|
||||||
sessionRecv: make(chan string),
|
sessionRecv: make(chan string),
|
||||||
GuildID: gID,
|
|
||||||
ChannelID: cID,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store voice in VoiceConnections map for this GuildID
|
// Store voice in VoiceConnections map for this GuildID
|
||||||
|
@ -451,7 +451,7 @@ func (s *Session) onVoiceServerUpdate(se *Session, st *VoiceServerUpdate) {
|
||||||
|
|
||||||
// We now have enough information to open a voice websocket conenction
|
// We now have enough information to open a voice websocket conenction
|
||||||
// so, that's what the next call does.
|
// so, that's what the next call does.
|
||||||
err := voice.Open()
|
err := voice.open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("onVoiceServerUpdate Voice.Open error: ", err)
|
fmt.Println("onVoiceServerUpdate Voice.Open error: ", err)
|
||||||
// TODO better logging
|
// TODO better logging
|
||||||
|
|
Loading…
Reference in a new issue