Track voice state changes, expose stuff, add channel changing

This commit is contained in:
andrei 2016-03-05 03:53:42 -08:00
parent 1fc0e2053b
commit b48e8c992e
4 changed files with 67 additions and 19 deletions

View file

@ -453,6 +453,45 @@ func (s *State) MessageRemove(message *Message) error {
return errors.New("Message not found.") return errors.New("Message not found.")
} }
func (s *State) VoiceStateUpdate(update *VoiceStateUpdate) error {
var exists bool
var guild *Guild
for _, guild = range s.Guilds {
if guild.ID == update.GuildID {
exists = true
break
}
}
if !exists {
return nil
}
// Handle Leaving Channel
if update.ChannelID == "" {
for i, state := range guild.VoiceStates {
if state.UserID == update.UserID {
guild.VoiceStates = append(guild.VoiceStates[:i], guild.VoiceStates[i+1:]...)
}
}
} else {
exists := false
for _, state := range guild.VoiceStates {
if state.UserID == update.UserID {
state.ChannelID = update.ChannelID
exists = true
}
}
if !exists {
guild.VoiceStates = append(guild.VoiceStates, update.VoiceState)
}
}
return nil
}
// Message gets a message by channel and message ID. // Message gets a message by channel and message ID.
func (s *State) Message(channelID, messageID string) (*Message, error) { func (s *State) Message(channelID, messageID string) (*Message, error) {
if s == nil { if s == nil {
@ -514,6 +553,8 @@ func (s *State) onInterface(se *Session, i interface{}) (err error) {
err = s.MessageAdd(t.Message) err = s.MessageAdd(t.Message)
case *MessageDelete: case *MessageDelete:
err = s.MessageRemove(t.Message) err = s.MessageRemove(t.Message)
case *VoiceStateUpdate:
err = s.VoiceStateUpdate(t)
} }
return return

View file

@ -203,6 +203,7 @@ type VoiceState struct {
UserID string `json:"user_id"` UserID string `json:"user_id"`
SessionID string `json:"session_id"` SessionID string `json:"session_id"`
ChannelID string `json:"channel_id"` ChannelID string `json:"channel_id"`
GuildID string `json:"guild_id"`
Suppress bool `json:"suppress"` Suppress bool `json:"suppress"`
SelfMute bool `json:"self_mute"` SelfMute bool `json:"self_mute"`
SelfDeaf bool `json:"self_deaf"` SelfDeaf bool `json:"self_deaf"`

View file

@ -36,6 +36,9 @@ type VoiceConnection struct {
OP2 *voiceOP2 // exported for dgvoice, may change. OP2 *voiceOP2 // exported for dgvoice, may change.
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
GuildID string
ChannelID string
UserID string
// 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
@ -46,9 +49,6 @@ type VoiceConnection struct {
sessionID string sessionID string
token string token string
endpoint string endpoint string
guildID string
channelID string
userID string
op4 voiceOP4 op4 voiceOP4
// Used to send a close signal to goroutines // Used to send a close signal to goroutines
@ -114,7 +114,7 @@ func (v *VoiceConnection) Open() (err error) {
return return
} }
data := voiceHandshakeOp{0, voiceHandshakeData{v.guildID, v.userID, v.sessionID, v.token}} 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 {
@ -604,7 +604,7 @@ func (v *VoiceConnection) Close() {
defer v.Unlock() defer v.Unlock()
if v.Ready { if v.Ready {
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)
} }
@ -631,3 +631,16 @@ func (v *VoiceConnection) Close() {
v.wsConn = nil v.wsConn = nil
} }
} }
// Change channels
func (v *VoiceConnection) ChangeChannel(channelID string) (err error) {
data := voiceChannelJoinOp{4, voiceChannelJoinData{&v.GuildID, &channelID, true, true}}
err = v.session.wsConn.WriteJSON(data)
if err == nil {
v.ChannelID = channelID
}
return err
}

View file

@ -356,8 +356,8 @@ func (s *Session) ChannelVoiceJoin(gID, cID string, mute, deaf bool) (voice *Voi
s.VoiceConnections[gID] = voice s.VoiceConnections[gID] = voice
// Store gID and cID for later use // Store gID and cID for later use
voice.guildID = gID voice.GuildID = gID
voice.channelID = cID voice.ChannelID = cID
return voice, err return voice, err
} }
@ -371,13 +371,8 @@ func (s *Session) onVoiceStateUpdate(se *Session, st *VoiceStateUpdate) {
return return
} }
channel, err := s.Channel(st.ChannelID) // Check if we have a voice connection to update
if err != nil { voice, exists := s.VoiceConnections[st.GuildID]
fmt.Println(err)
return
}
voice, exists := s.VoiceConnections[channel.GuildID]
if !exists { if !exists {
return return
} }
@ -391,15 +386,13 @@ func (s *Session) onVoiceStateUpdate(se *Session, st *VoiceStateUpdate) {
return return
} }
// This event comes for all users, if it's not for the session // We only care about events that are about us
// user just ignore it.
// TODO Move this IF to the event() func
if st.UserID != self.ID { if st.UserID != self.ID {
return return
} }
// Store the SessionID for later use. // Store the SessionID for later use.
voice.userID = self.ID // TODO: Review voice.UserID = self.ID // TODO: Review
voice.sessionRecv <- st.SessionID voice.sessionRecv <- st.SessionID
} }
@ -421,7 +414,7 @@ func (s *Session) onVoiceServerUpdate(se *Session, st *VoiceServerUpdate) {
// Store values for later use // Store values for later use
voice.token = st.Token voice.token = st.Token
voice.endpoint = st.Endpoint voice.endpoint = st.Endpoint
voice.guildID = st.GuildID voice.GuildID = st.GuildID
// If currently connected to voice ws/udp, then disconnect. // If currently connected to voice ws/udp, then disconnect.
// Has no effect if not connected. // Has no effect if not connected.