瀏覽代碼

Merge branch 'develop' of https://github.com/bwmarrin/discordgo into develop

Bruce Marriner 8 年之前
父節點
當前提交
68a784327f
共有 5 個文件被更改,包括 172 次插入61 次删除
  1. 81 20
      eventhandlers.go
  2. 40 5
      restapi.go
  3. 32 33
      state.go
  4. 14 0
      structs.go
  5. 5 3
      tools/cmd/eventhandlers/main.go

+ 81 - 20
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))

+ 40 - 5
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
 }
 
 // ------------------------------------------------------------------------------------------------

+ 32 - 33
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
+}
 
-	for _, role := range guild.Roles {
-		for _, roleID := range member.Roles {
-			if role.ID == roleID {
-				apermissions |= role.Permissions
-				break
-			}
-		}
+// 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
 	}
 
-	if apermissions&PermissionAdministrator > 0 {
-		apermissions |= PermissionAll
+	channel, err := s.Channel(channelID)
+	if err != nil {
+		return 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
-				break
-			}
-		}
+	guild, err := s.Guild(channel.GuildID)
+	if err != nil {
+		return 0
 	}
 
-	for _, overwrite := range channel.PermissionOverwrites {
-		if overwrite.Type == "member" && overwrite.ID == userID {
-			apermissions &= ^overwrite.Deny
-			apermissions |= overwrite.Allow
-			break
-		}
+	member, err := s.Member(guild.ID, userID)
+	if err != nil {
+		return 0
 	}
 
-	if apermissions&PermissionAdministrator > 0 {
-		apermissions |= PermissionAllChannel
+	roles := Roles(guild.Roles)
+	sort.Sort(roles)
+
+	for _, role := range roles {
+		for _, roleID := range member.Roles {
+			if role.ID == roleID {
+				if role.Color != 0 {
+					return role.Color
+				}
+			}
+		}
 	}
 
-	return
+	return 0
 }

+ 14 - 0
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"`

+ 5 - 3
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}}
 }