This repository has been archived by the owner on Jul 11, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 70
Guild.VoiceStates not kept up to date #438
Labels
Comments
What I've done in the interim: // NewVoiceStateTracker returns a new voice tracker.
func NewVoiceStateTracker() *voiceStateTracker {
return &voiceStateTracker{
db: make(map[disgord.Snowflake]map[disgord.Snowflake]*disgord.VoiceState),
}
}
type voiceStateTracker struct {
mu sync.RWMutex
db map[disgord.Snowflake]map[disgord.Snowflake]*disgord.VoiceState
}
// Register should be used before the connection is established. Registers
// the necessary handlers for tracking voice state changes.
func (t *voiceStateTracker) Register(gw disgord.GatewayQueryBuilder) {
gw.GuildCreate(func(s disgord.Session, h *disgord.GuildCreate) {
t.process(h.Guild.ID, h.Guild.VoiceStates...)
})
gw.VoiceStateUpdate(func(s disgord.Session, h *disgord.VoiceStateUpdate) {
t.process(h.GuildID, h.VoiceState)
})
gw.GuildDelete(func(s disgord.Session, h *disgord.GuildDelete) {
if h.UserWasRemoved() {
t.removeGuild(h.UnavailableGuild.ID)
}
})
}
func (t *voiceStateTracker) process(guildID disgord.Snowflake, states ...*disgord.VoiceState) {
if states == nil {
return
}
t.mu.Lock()
defer t.mu.Unlock()
for _, state := range states {
if _, ok := t.db[guildID]; !ok {
t.db[guildID] = make(map[disgord.Snowflake]*disgord.VoiceState)
}
// https://discord.com/developers/docs/topics/gateway#update-voice-state
// channel_id: id of the voice channel client wants to join (null if disconnecting)
if state.ChannelID.IsZero() {
delete(t.db[guildID], state.UserID)
continue
}
t.db[guildID][state.UserID] = state
}
}
func (t *voiceStateTracker) removeGuild(guildID disgord.Snowflake) {
if guildID.IsZero() {
return
}
t.mu.Lock()
defer t.mu.Unlock()
delete(t.db, guildID)
}
// States returns the full list of known voice states for a given guild.
func (t *voiceStateTracker) States(guildID disgord.Snowflake) (states []*disgord.VoiceState) {
if guildID.IsZero() {
return states
}
t.mu.RLock()
defer t.mu.RUnlock()
if _, ok := t.db[guildID]; !ok {
return states
}
states = make([]*disgord.VoiceState, 0, len(t.db[guildID]))
for _, state := range t.db[guildID] {
states = append(states, state)
}
return states
}
// UserCount returns a map where the keys are channels that have active voice states,
// and the value is the number of users in that voice channel, for a given guild.
func (t *voiceStateTracker) UserCount(guildID disgord.Snowflake) map[disgord.Snowflake]int {
voiceCount := map[disgord.Snowflake]int{}
for _, state := range t.States(guildID) {
voiceCount[state.ChannelID]++
}
return voiceCount
}
voiceCount[state.ChannelID]++
}
return voiceCount
} Example usage: gw := client.Gateway().WithContext(context.TODO())
voiceStates := NewVoiceStateTracker()
voiceStates.Register(gw) // registers handlers used for tracking voice states
[...]
voicestates.States(yourGuildID) // returns voice states like Guild.VoiceStates normally would |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Describe the bug
Guild.VoiceStates
isn't kept up to date as newVoiceStateUpdate
events are received. It looks as though the initial value is kept from theGuildCreate
event, and never updated.Expected behavior
It's possible this is the intended behavior (for
disgord
to not track state updates). If this is the case, it would be nice to have the struct field documented to make this obvious. If it's intended, could support be added to keep it up to date?Configuration
Additional context
Code used to replicate the issue:
Important output:
The text was updated successfully, but these errors were encountered: