1
0
forked from lug/matterbridge

Update vendor (bwmarrin/discordgo)

This commit is contained in:
Wim
2017-07-16 14:38:45 +02:00
parent aec5e3d77b
commit 5db24aa901
24 changed files with 1072 additions and 659 deletions

View File

@@ -14,11 +14,16 @@ package discordgo
import (
"errors"
"sort"
"sync"
)
// ErrNilState is returned when the state is nil.
var ErrNilState = errors.New("State not instantiated, please use discordgo.New() or assign Session.State.")
var ErrNilState = errors.New("state not instantiated, please use discordgo.New() or assign Session.State")
// ErrStateNotFound is returned when the state cache
// requested is not found
var ErrStateNotFound = errors.New("state cache not found")
// A State contains the current known state.
// As discord sends this in a READY blob, it seems reasonable to simply
@@ -33,6 +38,7 @@ type State struct {
TrackMembers bool
TrackRoles bool
TrackVoice bool
TrackPresences bool
guildMap map[string]*Guild
channelMap map[string]*Channel
@@ -45,13 +51,14 @@ func NewState() *State {
PrivateChannels: []*Channel{},
Guilds: []*Guild{},
},
TrackChannels: true,
TrackEmojis: true,
TrackMembers: true,
TrackRoles: true,
TrackVoice: true,
guildMap: make(map[string]*Guild),
channelMap: make(map[string]*Channel),
TrackChannels: true,
TrackEmojis: true,
TrackMembers: true,
TrackRoles: true,
TrackVoice: true,
TrackPresences: true,
guildMap: make(map[string]*Guild),
channelMap: make(map[string]*Channel),
}
}
@@ -143,7 +150,108 @@ func (s *State) Guild(guildID string) (*Guild, error) {
return g, nil
}
return nil, errors.New("Guild not found.")
return nil, ErrStateNotFound
}
// PresenceAdd adds a presence to the current world state, or
// updates it if it already exists.
func (s *State) PresenceAdd(guildID string, presence *Presence) error {
if s == nil {
return ErrNilState
}
guild, err := s.Guild(guildID)
if err != nil {
return err
}
s.Lock()
defer s.Unlock()
for i, p := range guild.Presences {
if p.User.ID == presence.User.ID {
//guild.Presences[i] = presence
//Update status
guild.Presences[i].Game = presence.Game
guild.Presences[i].Roles = presence.Roles
if presence.Status != "" {
guild.Presences[i].Status = presence.Status
}
if presence.Nick != "" {
guild.Presences[i].Nick = presence.Nick
}
//Update the optionally sent user information
//ID Is a mandatory field so you should not need to check if it is empty
guild.Presences[i].User.ID = presence.User.ID
if presence.User.Avatar != "" {
guild.Presences[i].User.Avatar = presence.User.Avatar
}
if presence.User.Discriminator != "" {
guild.Presences[i].User.Discriminator = presence.User.Discriminator
}
if presence.User.Email != "" {
guild.Presences[i].User.Email = presence.User.Email
}
if presence.User.Token != "" {
guild.Presences[i].User.Token = presence.User.Token
}
if presence.User.Username != "" {
guild.Presences[i].User.Username = presence.User.Username
}
return nil
}
}
guild.Presences = append(guild.Presences, presence)
return nil
}
// PresenceRemove removes a presence from the current world state.
func (s *State) PresenceRemove(guildID string, presence *Presence) error {
if s == nil {
return ErrNilState
}
guild, err := s.Guild(guildID)
if err != nil {
return err
}
s.Lock()
defer s.Unlock()
for i, p := range guild.Presences {
if p.User.ID == presence.User.ID {
guild.Presences = append(guild.Presences[:i], guild.Presences[i+1:]...)
return nil
}
}
return ErrStateNotFound
}
// Presence gets a presence by ID from a guild.
func (s *State) Presence(guildID, userID string) (*Presence, error) {
if s == nil {
return nil, ErrNilState
}
guild, err := s.Guild(guildID)
if err != nil {
return nil, err
}
for _, p := range guild.Presences {
if p.User.ID == userID {
return p, nil
}
}
return nil, ErrStateNotFound
}
// TODO: Consider moving Guild state update methods onto *Guild.
@@ -195,7 +303,7 @@ func (s *State) MemberRemove(member *Member) error {
}
}
return errors.New("Member not found.")
return ErrStateNotFound
}
// Member gets a member by ID from a guild.
@@ -218,7 +326,7 @@ func (s *State) Member(guildID, userID string) (*Member, error) {
}
}
return nil, errors.New("Member not found.")
return nil, ErrStateNotFound
}
// RoleAdd adds a role to the current world state, or
@@ -268,7 +376,7 @@ func (s *State) RoleRemove(guildID, roleID string) error {
}
}
return errors.New("Role not found.")
return ErrStateNotFound
}
// Role gets a role by ID from a guild.
@@ -291,10 +399,10 @@ func (s *State) Role(guildID, roleID string) (*Role, error) {
}
}
return nil, errors.New("Role not found.")
return nil, ErrStateNotFound
}
// ChannelAdd adds a guild to the current world state, or
// ChannelAdd adds a channel to the current world state, or
// updates it if it already exists.
// Channels may exist either as PrivateChannels or inside
// a guild.
@@ -324,7 +432,7 @@ func (s *State) ChannelAdd(channel *Channel) error {
} else {
guild, ok := s.guildMap[channel.GuildID]
if !ok {
return errors.New("Guild for channel not found.")
return ErrStateNotFound
}
guild.Channels = append(guild.Channels, channel)
@@ -403,7 +511,7 @@ func (s *State) Channel(channelID string) (*Channel, error) {
return c, nil
}
return nil, errors.New("Channel not found.")
return nil, ErrStateNotFound
}
// Emoji returns an emoji for a guild and emoji id.
@@ -426,7 +534,7 @@ func (s *State) Emoji(guildID, emojiID string) (*Emoji, error) {
}
}
return nil, errors.New("Emoji not found.")
return nil, ErrStateNotFound
}
// EmojiAdd adds an emoji to the current world state.
@@ -523,7 +631,12 @@ func (s *State) MessageRemove(message *Message) error {
return ErrNilState
}
c, err := s.Channel(message.ChannelID)
return s.messageRemoveByID(message.ChannelID, message.ID)
}
// messageRemoveByID removes a message by channelID and messageID from the world state.
func (s *State) messageRemoveByID(channelID, messageID string) error {
c, err := s.Channel(channelID)
if err != nil {
return err
}
@@ -532,13 +645,13 @@ func (s *State) MessageRemove(message *Message) error {
defer s.Unlock()
for i, m := range c.Messages {
if m.ID == message.ID {
if m.ID == messageID {
c.Messages = append(c.Messages[:i], c.Messages[i+1:]...)
return nil
}
}
return errors.New("Message not found.")
return ErrStateNotFound
}
func (s *State) voiceStateUpdate(update *VoiceStateUpdate) error {
@@ -592,7 +705,7 @@ func (s *State) Message(channelID, messageID string) (*Message, error) {
}
}
return nil, errors.New("Message not found.")
return nil, ErrStateNotFound
}
// OnReady takes a Ready event and updates all internal state.
@@ -608,10 +721,9 @@ func (s *State) onReady(se *Session, r *Ready) (err error) {
// if state is disabled, store the bare essentials.
if !se.StateEnabled {
ready := Ready{
Version: r.Version,
SessionID: r.SessionID,
HeartbeatInterval: r.HeartbeatInterval,
User: r.User,
Version: r.Version,
SessionID: r.SessionID,
User: r.User,
}
s.Ready = ready
@@ -710,10 +822,55 @@ func (s *State) onInterface(se *Session, i interface{}) (err error) {
if s.MaxMessageCount != 0 {
err = s.MessageRemove(t.Message)
}
case *MessageDeleteBulk:
if s.MaxMessageCount != 0 {
for _, mID := range t.Messages {
s.messageRemoveByID(t.ChannelID, mID)
}
}
case *VoiceStateUpdate:
if s.TrackVoice {
err = s.voiceStateUpdate(t)
}
case *PresenceUpdate:
if s.TrackPresences {
s.PresenceAdd(t.GuildID, &t.Presence)
}
if s.TrackMembers {
if t.Status == StatusOffline {
return
}
var m *Member
m, err = s.Member(t.GuildID, t.User.ID)
if err != nil {
// Member not found; this is a user coming online
m = &Member{
GuildID: t.GuildID,
Nick: t.Nick,
User: t.User,
Roles: t.Roles,
}
} else {
if t.Nick != "" {
m.Nick = t.Nick
}
if t.User.Username != "" {
m.User.Username = t.User.Username
}
// PresenceUpdates always contain a list of roles, so there's no need to check for an empty list here
m.Roles = t.Roles
}
err = s.MemberAdd(m)
}
}
return
@@ -747,48 +904,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
}