Kaynağa Gözat

Track voice state changes, expose stuff, add channel changing

andrei 8 yıl önce
ebeveyn
işleme
b48e8c992e
4 değiştirilmiş dosya ile 67 ekleme ve 19 silme
  1. 41 0
      state.go
  2. 1 0
      structs.go
  3. 18 5
      voice.go
  4. 7 14
      wsapi.go

+ 41 - 0
state.go

@@ -453,6 +453,45 @@ func (s *State) MessageRemove(message *Message) error {
 	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.
 func (s *State) Message(channelID, messageID string) (*Message, error) {
 	if s == nil {
@@ -514,6 +553,8 @@ func (s *State) onInterface(se *Session, i interface{}) (err error) {
 		err = s.MessageAdd(t.Message)
 	case *MessageDelete:
 		err = s.MessageRemove(t.Message)
+	case *VoiceStateUpdate:
+		err = s.VoiceStateUpdate(t)
 	}
 
 	return

+ 1 - 0
structs.go

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

+ 18 - 5
voice.go

@@ -36,6 +36,9 @@ type VoiceConnection struct {
 	OP2        *voiceOP2    // exported for dgvoice, may change.
 	OpusSend   chan []byte  // Chan for sending 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
 	//	FrameSize  int         // This can be used to set the FrameSize of Opus data
 
@@ -46,9 +49,6 @@ type VoiceConnection struct {
 	sessionID string
 	token     string
 	endpoint  string
-	guildID   string
-	channelID string
-	userID    string
 	op4       voiceOP4
 
 	// Used to send a close signal to goroutines
@@ -114,7 +114,7 @@ func (v *VoiceConnection) Open() (err error) {
 		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)
 	if err != nil {
@@ -604,7 +604,7 @@ func (v *VoiceConnection) Close() {
 	defer v.Unlock()
 
 	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)
 	}
 
@@ -631,3 +631,16 @@ func (v *VoiceConnection) Close() {
 		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
+}

+ 7 - 14
wsapi.go

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