diff --git a/commands/guild.go b/commands/guild.go index 52df4ea..9d2bea1 100644 --- a/commands/guild.go +++ b/commands/guild.go @@ -5,6 +5,7 @@ import ( "math" "regexp" "sort" + "strconv" "strings" "unicode/utf8" @@ -106,11 +107,24 @@ func GetSortedChannels(guildId string, withCategories bool, withPrivate bool) [] continue } - perms := discord.CalcOverwrites(*guild, channel, *selfMember) + perms := lib.CalcPermissionsFixed(*guild, channel, *selfMember) private := !perms.Has(discord.PermissionViewChannel) + fmt.Print(channel.Name, " ", perms, " ", private, "\n\r") if perms == 0 { - private = false + if channel.ParentID.IsValid() { + category, err := client.ChannelStore.Channel(channel.ParentID) + if err == nil { + perms := lib.CalcPermissionsFixed(*guild, *category, *selfMember) + private = !perms.Has(discord.PermissionViewChannel) + fmt.Print(category.Name, " ", perms, " ", private, "\n\r") + if perms == 0 { + private = false + } + } + } else { + private = false + } } if private && !withPrivate { continue @@ -192,11 +206,22 @@ func GetSortedChannels(guildId string, withCategories bool, withPrivate bool) [] continue } - perms := discord.CalcOverwrites(*guild, channel, *selfMember) + perms := lib.CalcPermissionsFixed(*guild, channel, *selfMember) private := !perms.Has(discord.PermissionViewChannel) if perms == 0 { - private = false + if channel.ParentID.IsValid() { + category, err := client.ChannelStore.Channel(channel.ParentID) + if err == nil { + perms := lib.CalcPermissionsFixed(*guild, *category, *selfMember) + private = !perms.Has(discord.PermissionViewChannel) + if perms == 0 { + private = false + } + } + } else { + private = false + } } if private && !withPrivate { continue @@ -250,11 +275,22 @@ func ListChannelsCommand() { channels := GetSortedChannels(currentGuild, true, false) for _, channel := range channels { - perms := discord.CalcOverwrites(*guild, channel, *selfMember) + perms := lib.CalcPermissionsFixed(*guild, channel, *selfMember) private := !perms.Has(discord.PermissionViewChannel) if perms == 0 { - private = false + if channel.ParentID.IsValid() { + category, err := client.ChannelStore.Channel(channel.ParentID) + if err == nil { + perms := lib.CalcPermissionsFixed(*guild, *category, *selfMember) + private = !perms.Has(discord.PermissionViewChannel) + if perms == 0 { + private = false + } + } + } else { + private = false + } } category := channel.Type == discord.GuildCategory @@ -279,12 +315,23 @@ func ListChannelsCommand() { fmt.Printf(" %*s created topic\n\r", longest, "channel-name") fmt.Print(strings.Repeat("-", 80) + "\n\r") for _, channel := range channels { - perms := discord.CalcOverwrites(*guild, channel, *selfMember) + perms := lib.CalcPermissionsFixed(*guild, channel, *selfMember) private := !perms.Has(discord.PermissionViewChannel) if perms == 0 { + if channel.ParentID.IsValid() { + category, err := client.ChannelStore.Channel(channel.ParentID) + if err == nil { + perms := lib.CalcPermissionsFixed(*guild, *category, *selfMember) + private = !perms.Has(discord.PermissionViewChannel) + if perms == 0 { + private = false + } + } + } else { private = false } + } category := channel.Type == discord.GuildCategory topic := REGEX_EMOTE.ReplaceAllString(channel.Topic, ":$1:") topic = strings.ReplaceAll(topic, "\n", " ") @@ -380,10 +427,22 @@ func ListUsersCommand() { continue } - perms := discord.CalcOverwrites(*guild, *channel, *member) + perms := lib.CalcPermissionsFixed(*guild, *channel, *member) + private := !perms.Has(discord.PermissionViewChannel) if perms == 0 { - private = false + if channel.ParentID.IsValid() { + category, err := client.ChannelStore.Channel(channel.ParentID) + if err == nil { + perms := lib.CalcPermissionsFixed(*guild, *category, *member) + private = !perms.Has(discord.PermissionViewChannel) + if perms == 0 { + private = false + } + } + } else { + private = false + } } if private { continue @@ -451,6 +510,25 @@ func ListUsersCommand() { for _, position := range positions { members := membersByPosition[position] if len(members) > 150 { + str := "[hiding " + strconv.Itoa(len(members)) + " members]" + length := utf8.RuneCountInString(str) + + index++ + + pad := 0 + if index % columns != 0 { + pad = longest - length + } + if pad < 0 { + pad = 0 + } + + fmt.Printf(str + strings.Repeat(" ", pad)) + + if index % columns == 0 { + fmt.Print("\n\r") + } + continue } for _, member := range members { diff --git a/commands/send.go b/commands/send.go index 44e2ec0..22034a1 100644 --- a/commands/send.go +++ b/commands/send.go @@ -54,10 +54,21 @@ func SendMode() { return } - perms := discord.CalcOverwrites(*guild, *channel, *selfMember) + perms := lib.CalcPermissionsFixed(*guild, *channel, *selfMember) cannotSend := !perms.Has(discord.PermissionSendMessages) if perms == 0 { - cannotSend = false + if channel.ParentID.IsValid() { + category, err := client.ChannelStore.Channel(channel.ParentID) + if err == nil { + perms := lib.CalcPermissionsFixed(*guild, *category, *selfMember) + cannotSend = perms.Has(discord.PermissionSendMessages) + if perms == 0 { + cannotSend = false + } + } + } else { + cannotSend = false + } } if cannotSend { diff --git a/lib/messages.go b/lib/messages.go index 31cb1f0..b93f576 100644 --- a/lib/messages.go +++ b/lib/messages.go @@ -227,7 +227,7 @@ func FormatMessage(options MessageOptions) []string { if options.Reply != nil { nameColor := "cyan+b" - if options.Bot { + if options.Reply.Author.Bot { nameColor = "yellow+b" } diff --git a/lib/util.go b/lib/util.go new file mode 100644 index 0000000..1a1968d --- /dev/null +++ b/lib/util.go @@ -0,0 +1,65 @@ +package lib + +import "github.com/diamondburned/arikawa/v3/discord" + +func CalcPermissionsFixed(guild discord.Guild, channel discord.Channel, member discord.Member) discord.Permissions { + if guild.OwnerID == member.User.ID { + return discord.PermissionAll + } + + var perm discord.Permissions + + for _, role := range guild.Roles { + if role.ID == discord.RoleID(guild.ID) { + perm |= role.Permissions + break + } + } + + for _, role := range guild.Roles { + for _, id := range member.RoleIDs { + if id == role.ID { + perm |= role.Permissions + } + } + } + + if perm.Has(discord.PermissionAdministrator) { + return discord.PermissionAll + } + + for _, overwrite := range channel.Overwrites { + if discord.GuildID(overwrite.ID) == guild.ID { + perm &= ^overwrite.Deny + perm |= overwrite.Allow + break + } + } + + var deny, allow discord.Permissions + + for _, overwrite := range channel.Overwrites { + for _, id := range member.RoleIDs { + if id == discord.RoleID(overwrite.ID) && overwrite.Type == discord.OverwriteRole { + deny |= overwrite.Deny + allow |= overwrite.Allow + } + } + } + + perm &= ^deny + perm |= allow + + for _, overwrite := range channel.Overwrites { + if discord.UserID(overwrite.ID) == member.User.ID && overwrite.Type == discord.OverwriteMember { + perm &= ^overwrite.Deny + perm |= overwrite.Allow + } + } + + if perm.Has(discord.PermissionAdministrator) { + return discord.PermissionAll + } + + return perm +} diff --git a/main.go b/main.go index 4714c98..2342b2f 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,9 @@ import ( "github.com/Cynosphere/comcord/state" "github.com/diamondburned/arikawa/v3/discord" "github.com/diamondburned/arikawa/v3/gateway" + "github.com/diamondburned/arikawa/v3/session" + arikawa_state "github.com/diamondburned/arikawa/v3/state" + "github.com/diamondburned/arikawa/v3/state/store/defaultstore" "github.com/diamondburned/arikawa/v3/utils/handler" "github.com/diamondburned/ningen/v3" "golang.org/x/term" @@ -121,7 +124,15 @@ func main() { presence.Activities = append(presence.Activities, activity) ident.Presence = &presence - client := ningen.NewWithIdentifier(gateway.NewIdentifier(ident)) + gwURL, err := gateway.URL(context.Background()) + if err != nil { + fmt.Print("% Failed to get gateway URL: ", err, "\n\r") + os.Exit(1) + } + gw := gateway.NewCustomWithIdentifier(gateway.AddGatewayParams(gwURL), gateway.NewIdentifier(ident), nil) + ses := session.NewWithGateway(gw, handler.New()) + st := arikawa_state.NewFromSession(ses, defaultstore.New()) + client := ningen.FromState(st) client.PreHandler = handler.New() client.AddIntents(gateway.IntentGuilds) @@ -138,8 +149,7 @@ func main() { err = client.Open(context.Background()) if err != nil { - fmt.Println("% Failed to connect to Discord:", err) - fmt.Print("\r") + fmt.Print("% Failed to connect to Discord: ", err, "\n\r") os.Exit(1) return }