From d9681ea1d1c7028325799e63e4040da575055187 Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 3 Nov 2023 22:34:08 +0000 Subject: [PATCH] state: Use store roles for calculating overrides (#411) This commit is breaking. It fixes `CalcOverwrites` which previously relied on incorrect assumptions. --- discord/permission.go | 8 +++--- state/state.go | 59 +++++++++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/discord/permission.go b/discord/permission.go index 700240f..6228ec8 100644 --- a/discord/permission.go +++ b/discord/permission.go @@ -170,21 +170,23 @@ func (p Permissions) Add(perm Permissions) Permissions { return p | perm } -func CalcOverwrites(guild Guild, channel Channel, member Member) Permissions { +func CalcOverrides( + guild Guild, channel Channel, member Member, roles []Role) Permissions { + if guild.OwnerID == member.User.ID { return PermissionAll } var perm Permissions - for _, role := range guild.Roles { + for _, role := range roles { if role.ID == RoleID(guild.ID) { perm |= role.Permissions break } } - for _, role := range guild.Roles { + for _, role := range roles { for _, id := range member.RoleIDs { if id == role.ID { perm |= role.Permissions diff --git a/state/state.go b/state/state.go index 0b9567a..597abe7 100644 --- a/state/state.go +++ b/state/state.go @@ -299,15 +299,18 @@ func (s *State) Permissions( var wg sync.WaitGroup var ( - g *discord.Guild - m *discord.Member + g *discord.Guild + m *discord.Member + rs []discord.Role gerr = store.ErrNotFound merr = store.ErrNotFound + rerr = store.ErrNotFound ) if s.HasIntents(gateway.IntentGuilds) { g, gerr = s.Cabinet.Guild(ch.GuildID) + rs, rerr = s.Cabinet.Roles(ch.GuildID) } if s.HasIntents(gateway.IntentGuildMembers) { @@ -329,6 +332,28 @@ func (s *State) Permissions( m, merr = s.fetchMember(ch.GuildID, userID) } + if gerr != nil { + wg.Add(1) + go func() { + g, gerr = s.fetchGuild(ch.GuildID) + wg.Done() + }() + } + if merr != nil { + wg.Add(1) + go func() { + m, merr = s.fetchMember(ch.GuildID, userID) + wg.Done() + }() + } + if rerr != nil { + wg.Add(1) + go func() { + rs, rerr = s.fetchRoles(ch.GuildID) + wg.Done() + }() + } + wg.Wait() if gerr != nil { @@ -338,7 +363,7 @@ func (s *State) Permissions( return 0, fmt.Errorf("failed to get member: %w", merr) } - return discord.CalcOverwrites(*g, *ch, *m), nil + return discord.CalcOverrides(*g, *ch, *m, rs), nil } //// @@ -765,23 +790,14 @@ func (s *State) Role(guildID discord.GuildID, roleID discord.RoleID) (target *di } func (s *State) Roles(guildID discord.GuildID) ([]discord.Role, error) { - rs, err := s.Cabinet.Roles(guildID) - if err == nil { - return rs, nil - } - - rs, err = s.Session.Roles(guildID) - if err != nil { - return nil, err - } - if s.HasIntents(gateway.IntentGuilds) { - for i := range rs { - s.RoleSet(guildID, &rs[i], false) + rs, err := s.Cabinet.Roles(guildID) + if err == nil { + return rs, nil } } - return rs, nil + return s.fetchRoles(guildID) } func (s *State) fetchGuild(id discord.GuildID) (g *discord.Guild, err error) { @@ -793,6 +809,17 @@ func (s *State) fetchGuild(id discord.GuildID) (g *discord.Guild, err error) { return } +func (s *State) fetchRoles(gID discord.GuildID) (rs []discord.Role, err error) { + rs, err = s.Session.Roles(gID) + if err == nil && s.HasIntents(gateway.IntentGuilds) { + for i := range rs { + s.RoleSet(gID, &rs[i], false) + } + } + + return +} + func (s *State) fetchMember(gID discord.GuildID, uID discord.UserID) (m *discord.Member, err error) { m, err = s.Session.Member(gID, uID) if err == nil && s.HasIntents(gateway.IntentGuildMembers) {