diff --git a/eventhandlers.go b/eventhandlers.go index 6d78bac..b39806b 100644 --- a/eventhandlers.go +++ b/eventhandlers.go @@ -69,6 +69,8 @@ func (eh channelCreateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = channelCreateEventHandler(nil) + // channelDeleteEventHandler is an event handler for ChannelDelete events. type channelDeleteEventHandler func(*Session, *ChannelDelete) @@ -89,6 +91,8 @@ func (eh channelDeleteEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = channelDeleteEventHandler(nil) + // channelPinsUpdateEventHandler is an event handler for ChannelPinsUpdate events. type channelPinsUpdateEventHandler func(*Session, *ChannelPinsUpdate) @@ -109,6 +113,8 @@ func (eh channelPinsUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = channelPinsUpdateEventHandler(nil) + // channelUpdateEventHandler is an event handler for ChannelUpdate events. type channelUpdateEventHandler func(*Session, *ChannelUpdate) @@ -129,6 +135,8 @@ func (eh channelUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = channelUpdateEventHandler(nil) + // connectEventHandler is an event handler for Connect events. type connectEventHandler func(*Session, *Connect) @@ -137,11 +145,6 @@ func (eh connectEventHandler) Type() string { return connectEventType } -// New returns a new instance of Connect. -func (eh connectEventHandler) New() interface{} { - return &Connect{} -} - // Handle is the handler for Connect events. func (eh connectEventHandler) Handle(s *Session, i interface{}) { if t, ok := i.(*Connect); ok { @@ -149,6 +152,8 @@ func (eh connectEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = connectEventHandler(nil) + // disconnectEventHandler is an event handler for Disconnect events. type disconnectEventHandler func(*Session, *Disconnect) @@ -157,11 +162,6 @@ func (eh disconnectEventHandler) Type() string { return disconnectEventType } -// New returns a new instance of Disconnect. -func (eh disconnectEventHandler) New() interface{} { - return &Disconnect{} -} - // Handle is the handler for Disconnect events. func (eh disconnectEventHandler) Handle(s *Session, i interface{}) { if t, ok := i.(*Disconnect); ok { @@ -169,6 +169,8 @@ func (eh disconnectEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = disconnectEventHandler(nil) + // eventEventHandler is an event handler for Event events. type eventEventHandler func(*Session, *Event) @@ -177,11 +179,6 @@ func (eh eventEventHandler) Type() string { return eventEventType } -// New returns a new instance of Event. -func (eh eventEventHandler) New() interface{} { - return &Event{} -} - // Handle is the handler for Event events. func (eh eventEventHandler) Handle(s *Session, i interface{}) { if t, ok := i.(*Event); ok { @@ -189,6 +186,8 @@ func (eh eventEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = eventEventHandler(nil) + // guildBanAddEventHandler is an event handler for GuildBanAdd events. type guildBanAddEventHandler func(*Session, *GuildBanAdd) @@ -209,6 +208,8 @@ func (eh guildBanAddEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildBanAddEventHandler(nil) + // guildBanRemoveEventHandler is an event handler for GuildBanRemove events. type guildBanRemoveEventHandler func(*Session, *GuildBanRemove) @@ -229,6 +230,8 @@ func (eh guildBanRemoveEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildBanRemoveEventHandler(nil) + // guildCreateEventHandler is an event handler for GuildCreate events. type guildCreateEventHandler func(*Session, *GuildCreate) @@ -249,6 +252,8 @@ func (eh guildCreateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildCreateEventHandler(nil) + // guildDeleteEventHandler is an event handler for GuildDelete events. type guildDeleteEventHandler func(*Session, *GuildDelete) @@ -269,6 +274,8 @@ func (eh guildDeleteEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildDeleteEventHandler(nil) + // guildEmojisUpdateEventHandler is an event handler for GuildEmojisUpdate events. type guildEmojisUpdateEventHandler func(*Session, *GuildEmojisUpdate) @@ -289,6 +296,8 @@ func (eh guildEmojisUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildEmojisUpdateEventHandler(nil) + // guildIntegrationsUpdateEventHandler is an event handler for GuildIntegrationsUpdate events. type guildIntegrationsUpdateEventHandler func(*Session, *GuildIntegrationsUpdate) @@ -309,6 +318,8 @@ func (eh guildIntegrationsUpdateEventHandler) Handle(s *Session, i interface{}) } } +var _ EventHandler = guildIntegrationsUpdateEventHandler(nil) + // guildMemberAddEventHandler is an event handler for GuildMemberAdd events. type guildMemberAddEventHandler func(*Session, *GuildMemberAdd) @@ -329,6 +340,8 @@ func (eh guildMemberAddEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildMemberAddEventHandler(nil) + // guildMemberRemoveEventHandler is an event handler for GuildMemberRemove events. type guildMemberRemoveEventHandler func(*Session, *GuildMemberRemove) @@ -349,6 +362,8 @@ func (eh guildMemberRemoveEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildMemberRemoveEventHandler(nil) + // guildMemberUpdateEventHandler is an event handler for GuildMemberUpdate events. type guildMemberUpdateEventHandler func(*Session, *GuildMemberUpdate) @@ -369,6 +384,8 @@ func (eh guildMemberUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildMemberUpdateEventHandler(nil) + // guildMembersChunkEventHandler is an event handler for GuildMembersChunk events. type guildMembersChunkEventHandler func(*Session, *GuildMembersChunk) @@ -389,6 +406,8 @@ func (eh guildMembersChunkEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildMembersChunkEventHandler(nil) + // guildRoleCreateEventHandler is an event handler for GuildRoleCreate events. type guildRoleCreateEventHandler func(*Session, *GuildRoleCreate) @@ -409,6 +428,8 @@ func (eh guildRoleCreateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildRoleCreateEventHandler(nil) + // guildRoleDeleteEventHandler is an event handler for GuildRoleDelete events. type guildRoleDeleteEventHandler func(*Session, *GuildRoleDelete) @@ -429,6 +450,8 @@ func (eh guildRoleDeleteEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildRoleDeleteEventHandler(nil) + // guildRoleUpdateEventHandler is an event handler for GuildRoleUpdate events. type guildRoleUpdateEventHandler func(*Session, *GuildRoleUpdate) @@ -449,6 +472,8 @@ func (eh guildRoleUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildRoleUpdateEventHandler(nil) + // guildUpdateEventHandler is an event handler for GuildUpdate events. type guildUpdateEventHandler func(*Session, *GuildUpdate) @@ -469,6 +494,8 @@ func (eh guildUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = guildUpdateEventHandler(nil) + // messageAckEventHandler is an event handler for MessageAck events. type messageAckEventHandler func(*Session, *MessageAck) @@ -489,6 +516,8 @@ func (eh messageAckEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = messageAckEventHandler(nil) + // messageCreateEventHandler is an event handler for MessageCreate events. type messageCreateEventHandler func(*Session, *MessageCreate) @@ -509,6 +538,8 @@ func (eh messageCreateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = messageCreateEventHandler(nil) + // messageDeleteEventHandler is an event handler for MessageDelete events. type messageDeleteEventHandler func(*Session, *MessageDelete) @@ -529,6 +560,8 @@ func (eh messageDeleteEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = messageDeleteEventHandler(nil) + // messageReactionAddEventHandler is an event handler for MessageReactionAdd events. type messageReactionAddEventHandler func(*Session, *MessageReactionAdd) @@ -549,6 +582,8 @@ func (eh messageReactionAddEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = messageReactionAddEventHandler(nil) + // messageReactionRemoveEventHandler is an event handler for MessageReactionRemove events. type messageReactionRemoveEventHandler func(*Session, *MessageReactionRemove) @@ -569,6 +604,8 @@ func (eh messageReactionRemoveEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = messageReactionRemoveEventHandler(nil) + // messageUpdateEventHandler is an event handler for MessageUpdate events. type messageUpdateEventHandler func(*Session, *MessageUpdate) @@ -589,6 +626,8 @@ func (eh messageUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = messageUpdateEventHandler(nil) + // presenceUpdateEventHandler is an event handler for PresenceUpdate events. type presenceUpdateEventHandler func(*Session, *PresenceUpdate) @@ -609,6 +648,8 @@ func (eh presenceUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = presenceUpdateEventHandler(nil) + // presencesReplaceEventHandler is an event handler for PresencesReplace events. type presencesReplaceEventHandler func(*Session, *PresencesReplace) @@ -629,6 +670,8 @@ func (eh presencesReplaceEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = presencesReplaceEventHandler(nil) + // rateLimitEventHandler is an event handler for RateLimit events. type rateLimitEventHandler func(*Session, *RateLimit) @@ -637,11 +680,6 @@ func (eh rateLimitEventHandler) Type() string { return rateLimitEventType } -// New returns a new instance of RateLimit. -func (eh rateLimitEventHandler) New() interface{} { - return &RateLimit{} -} - // Handle is the handler for RateLimit events. func (eh rateLimitEventHandler) Handle(s *Session, i interface{}) { if t, ok := i.(*RateLimit); ok { @@ -649,6 +687,8 @@ func (eh rateLimitEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = rateLimitEventHandler(nil) + // readyEventHandler is an event handler for Ready events. type readyEventHandler func(*Session, *Ready) @@ -669,6 +709,8 @@ func (eh readyEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = readyEventHandler(nil) + // relationshipAddEventHandler is an event handler for RelationshipAdd events. type relationshipAddEventHandler func(*Session, *RelationshipAdd) @@ -689,6 +731,8 @@ func (eh relationshipAddEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = relationshipAddEventHandler(nil) + // relationshipRemoveEventHandler is an event handler for RelationshipRemove events. type relationshipRemoveEventHandler func(*Session, *RelationshipRemove) @@ -709,6 +753,8 @@ func (eh relationshipRemoveEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = relationshipRemoveEventHandler(nil) + // resumedEventHandler is an event handler for Resumed events. type resumedEventHandler func(*Session, *Resumed) @@ -729,6 +775,8 @@ func (eh resumedEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = resumedEventHandler(nil) + // typingStartEventHandler is an event handler for TypingStart events. type typingStartEventHandler func(*Session, *TypingStart) @@ -749,6 +797,8 @@ func (eh typingStartEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = typingStartEventHandler(nil) + // userGuildSettingsUpdateEventHandler is an event handler for UserGuildSettingsUpdate events. type userGuildSettingsUpdateEventHandler func(*Session, *UserGuildSettingsUpdate) @@ -769,6 +819,8 @@ func (eh userGuildSettingsUpdateEventHandler) Handle(s *Session, i interface{}) } } +var _ EventHandler = userGuildSettingsUpdateEventHandler(nil) + // userSettingsUpdateEventHandler is an event handler for UserSettingsUpdate events. type userSettingsUpdateEventHandler func(*Session, *UserSettingsUpdate) @@ -789,6 +841,8 @@ func (eh userSettingsUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = userSettingsUpdateEventHandler(nil) + // userUpdateEventHandler is an event handler for UserUpdate events. type userUpdateEventHandler func(*Session, *UserUpdate) @@ -809,6 +863,8 @@ func (eh userUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = userUpdateEventHandler(nil) + // voiceServerUpdateEventHandler is an event handler for VoiceServerUpdate events. type voiceServerUpdateEventHandler func(*Session, *VoiceServerUpdate) @@ -829,6 +885,8 @@ func (eh voiceServerUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = voiceServerUpdateEventHandler(nil) + // voiceStateUpdateEventHandler is an event handler for VoiceStateUpdate events. type voiceStateUpdateEventHandler func(*Session, *VoiceStateUpdate) @@ -849,6 +907,8 @@ func (eh voiceStateUpdateEventHandler) Handle(s *Session, i interface{}) { } } +var _ EventHandler = voiceStateUpdateEventHandler(nil) + func handlerForInterface(handler interface{}) EventHandler { switch v := handler.(type) { case func(*Session, interface{}): @@ -937,6 +997,7 @@ func handlerForInterface(handler interface{}) EventHandler { return nil } + func init() { registerInterfaceProvider(channelCreateEventHandler(nil)) registerInterfaceProvider(channelDeleteEventHandler(nil)) diff --git a/restapi.go b/restapi.go index e7f3357..57cdb0e 100644 --- a/restapi.go +++ b/restapi.go @@ -423,6 +423,13 @@ func (s *Session) UserGuildSettingsEdit(guildID string, settings *UserGuildSetti // NOTE: This function is now deprecated and will be removed in the future. // Please see the same function inside state.go func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions int, err error) { + // Try to just get permissions from state. + apermissions, err = s.State.UserChannelPermissions(userID, channelID) + if err == nil { + return + } + + // Otherwise try get as much data from state as possible, falling back to the network. channel, err := s.State.Channel(channelID) if err != nil || channel == nil { channel, err = s.Channel(channelID) @@ -452,6 +459,19 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } } + return memberPermissions(guild, channel, member), nil +} + +// Calculates the permissions for a member. +// https://support.discordapp.com/hc/en-us/articles/206141927-How-is-the-permission-hierarchy-structured- +func memberPermissions(guild *Guild, channel *Channel, member *Member) (apermissions int) { + userID := member.User.ID + + if userID == guild.OwnerID { + apermissions = PermissionAll + return + } + for _, role := range guild.Roles { if role.ID == guild.ID { apermissions |= role.Permissions @@ -468,21 +488,36 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } } - if apermissions&PermissionAdministrator > 0 { + if apermissions&PermissionAdministrator == PermissionAdministrator { apermissions |= PermissionAll } + // Apply @everyone overrides from the channel. + for _, overwrite := range channel.PermissionOverwrites { + if guild.ID == overwrite.ID { + apermissions &= ^overwrite.Deny + apermissions |= overwrite.Allow + break + } + } + + denies := 0 + allows := 0 + // Member overwrites can override role overrides, so do two passes for _, overwrite := range channel.PermissionOverwrites { for _, roleID := range member.Roles { if overwrite.Type == "role" && roleID == overwrite.ID { - apermissions &= ^overwrite.Deny - apermissions |= overwrite.Allow + denies |= overwrite.Deny + allows |= overwrite.Allow break } } } + apermissions &= ^denies + apermissions |= allows + for _, overwrite := range channel.PermissionOverwrites { if overwrite.Type == "member" && overwrite.ID == userID { apermissions &= ^overwrite.Deny @@ -491,11 +526,11 @@ func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions } } - if apermissions&PermissionAdministrator > 0 { + if apermissions&PermissionAdministrator == PermissionAdministrator { apermissions |= PermissionAllChannel } - return + return apermissions } // ------------------------------------------------------------------------------------------------ diff --git a/state.go b/state.go index 25dd3d1..c7bd4c3 100644 --- a/state.go +++ b/state.go @@ -14,6 +14,7 @@ package discordgo import ( "errors" + "sort" "sync" ) @@ -747,48 +748,46 @@ func (s *State) UserChannelPermissions(userID, channelID string) (apermissions i return } - for _, role := range guild.Roles { - if role.ID == guild.ID { - apermissions |= role.Permissions - break - } + return memberPermissions(guild, channel, member), nil +} + +// UserColor returns the color of a user in a channel. +// While colors are defined at a Guild level, determining for a channel is more useful in message handlers. +// 0 is returned in cases of error, which is the color of @everyone. +// userID : The ID of the user to calculate the color for. +// channelID : The ID of the channel to calculate the color for. +func (s *State) UserColor(userID, channelID string) int { + if s == nil { + return 0 } - for _, role := range guild.Roles { + channel, err := s.Channel(channelID) + if err != nil { + return 0 + } + + guild, err := s.Guild(channel.GuildID) + if err != nil { + return 0 + } + + member, err := s.Member(guild.ID, userID) + if err != nil { + return 0 + } + + roles := Roles(guild.Roles) + sort.Sort(roles) + + for _, role := range roles { for _, roleID := range member.Roles { if role.ID == roleID { - apermissions |= role.Permissions - break + if role.Color != 0 { + return role.Color + } } } } - if apermissions&PermissionAdministrator > 0 { - apermissions |= PermissionAll - } - - // Member overwrites can override role overrides, so do two passes - for _, overwrite := range channel.PermissionOverwrites { - for _, roleID := range member.Roles { - if overwrite.Type == "role" && roleID == overwrite.ID { - apermissions &= ^overwrite.Deny - apermissions |= overwrite.Allow - break - } - } - } - - for _, overwrite := range channel.PermissionOverwrites { - if overwrite.Type == "member" && overwrite.ID == userID { - apermissions &= ^overwrite.Deny - apermissions |= overwrite.Allow - break - } - } - - if apermissions&PermissionAdministrator > 0 { - apermissions |= PermissionAllChannel - } - - return + return 0 } diff --git a/structs.go b/structs.go index 340f234..463c446 100644 --- a/structs.go +++ b/structs.go @@ -246,6 +246,20 @@ type Role struct { Permissions int `json:"permissions"` } +type Roles []*Role + +func (r Roles) Len() int { + return len(r) +} + +func (r Roles) Less(i, j int) bool { + return r[i].Position > r[j].Position +} + +func (r Roles) Swap(i, j int) { + r[i], r[j] = r[j], r[i] +} + // A VoiceState stores the voice states of Guilds type VoiceState struct { UserID string `json:"user_id"` diff --git a/tools/cmd/eventhandlers/main.go b/tools/cmd/eventhandlers/main.go index f389408..8f00766 100644 --- a/tools/cmd/eventhandlers/main.go +++ b/tools/cmd/eventhandlers/main.go @@ -37,18 +37,19 @@ type {{privateName .}}EventHandler func(*Session, *{{.}}) func (eh {{privateName .}}EventHandler) Type() string { return {{privateName .}}EventType } - +{{if isDiscordEvent .}} // New returns a new instance of {{.}}. func (eh {{privateName .}}EventHandler) New() interface{} { return &{{.}}{} -} - +}{{end}} // Handle is the handler for {{.}} events. func (eh {{privateName .}}EventHandler) Handle(s *Session, i interface{}) { if t, ok := i.(*{{.}}); ok { eh(s, t) } } + +var _ EventHandler = {{privateName .}}EventHandler(nil) {{end}} func handlerForInterface(handler interface{}) EventHandler { switch v := handler.(type) { @@ -60,6 +61,7 @@ func handlerForInterface(handler interface{}) EventHandler { return nil } + func init() { {{range .}}{{if isDiscordEvent .}} registerInterfaceProvider({{privateName .}}EventHandler(nil)){{end}}{{end}} }