Merge remote-tracking branch 'bwmarrin/develop' into develop

This commit is contained in:
Chris Rhodes 2016-03-05 20:18:22 -08:00
commit e37b86d3e8
2 changed files with 194 additions and 26 deletions

View file

@ -104,11 +104,10 @@ func (s *Session) request(method, urlStr, contentType string, b []byte) (respons
fmt.Printf("API RESPONSE BODY :: [%s]\n", response) fmt.Printf("API RESPONSE BODY :: [%s]\n", response)
} }
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
switch resp.StatusCode { switch resp.StatusCode {
case 200: // OK case http.StatusOK:
case 204: // No Content case http.StatusNoContent:
// TODO check for 401 response, invalidate token if we get one. // TODO check for 401 response, invalidate token if we get one.
@ -328,6 +327,70 @@ func (s *Session) UserGuilds() (st []*Guild, err error) {
return return
} }
// UserChannelPermissions returns the permission of a user in a channel.
// userID : The ID of the user to calculate permissions for.
// channelID : The ID of the channel to calculate permission for.
func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions int, err error) {
channel, err := s.Channel(channelID)
if err != nil {
return
}
guild, err := s.Guild(channel.GuildID)
if err != nil {
return
}
if userID == guild.OwnerID {
apermissions = PermissionAll
return
}
member, err := s.GuildMember(guild.ID, userID)
if err != nil {
return
}
for _, role := range guild.Roles {
for _, roleID := range member.Roles {
if role.ID == roleID {
apermissions |= role.Permissions
break
}
}
}
if apermissions & PermissionManageRoles > 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 & PermissionManageRoles > 0 {
apermissions |= PermissionAllChannel
}
return
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Functions specific to Discord Guilds // Functions specific to Discord Guilds
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -371,14 +434,44 @@ func (s *Session) GuildCreate(name string) (st *Guild, err error) {
// GuildEdit edits a new Guild // GuildEdit edits a new Guild
// guildID : The ID of a Guild // guildID : The ID of a Guild
// name : A name for the Guild (2-100 characters) // g : A GuildParams struct with the values Name, Region and VerificationLevel defined.
func (s *Session) GuildEdit(guildID, name string) (st *Guild, err error) { func (s *Session) GuildEdit(guildID string, g GuildParams) (st *Guild, err error) {
// Bounds checking for VerificationLevel, interval: [0, 3]
if g.VerificationLevel != nil {
val := *g.VerificationLevel
if val < 0 || val > 3 {
err = errors.New("VerificationLevel out of bounds, should be between 0 and 3")
return
}
}
//Bounds checking for regions
if g.Region != "" {
isValid := false
regions, _ := s.VoiceRegions()
for _, r := range regions {
if g.Region == r.ID {
isValid = true
}
}
if !isValid {
var valid []string
for _, r := range regions {
valid = append(valid, r.ID)
}
err = errors.New(fmt.Sprintf("Region not a valid region (%q)", valid))
return
}
}
data := struct { data := struct {
Name string `json:"name"` Name string `json:"name,omitempty"`
}{name} Region string `json:"region,omitempty"`
VerificationLevel *VerificationLevel `json:"verification_level,omitempty"`
}{g.Name, g.Region, g.VerificationLevel}
body, err := s.Request("POST", GUILD(guildID), data) body, err := s.Request("PATCH", GUILD(guildID), data)
if err != nil { if err != nil {
return return
} }

View file

@ -145,6 +145,17 @@ type Emoji struct {
RequireColons bool `json:"require_colons"` RequireColons bool `json:"require_colons"`
} }
// Custom VerificationLevel typedef for int
type VerificationLevel int
// Constants for VerificationLevel levels from 0 to 3 inclusive
const (
VerificationLevelNone VerificationLevel = iota
VerificationLevelLow
VerificationLevelMedium
VerificationLevelHigh
)
// A Guild holds all data related to a specific Discord Guild. Guilds are also // A Guild holds all data related to a specific Discord Guild. Guilds are also
// sometimes referred to as Servers in the Discord client. // sometimes referred to as Servers in the Discord client.
type Guild struct { type Guild struct {
@ -158,6 +169,7 @@ type Guild struct {
JoinedAt string `json:"joined_at"` // make this a timestamp JoinedAt string `json:"joined_at"` // make this a timestamp
Splash string `json:"splash"` Splash string `json:"splash"`
AfkTimeout int `json:"afk_timeout"` AfkTimeout int `json:"afk_timeout"`
VerificationLevel VerificationLevel `json:"verification_level"`
EmbedEnabled bool `json:"embed_enabled"` EmbedEnabled bool `json:"embed_enabled"`
Large bool `json:"large"` // ?? Large bool `json:"large"` // ??
Roles []*Role `json:"roles"` Roles []*Role `json:"roles"`
@ -168,6 +180,13 @@ type Guild struct {
VoiceStates []*VoiceState `json:"voice_states"` VoiceStates []*VoiceState `json:"voice_states"`
} }
// A GuildParams stores all the data needed to update discord guild settings
type GuildParams struct {
Name string `json:"name"`
Region string `json:"region"`
VerificationLevel *VerificationLevel `json:"verification_level"`
}
// A Role stores information about Discord guild member roles. // A Role stores information about Discord guild member roles.
type Role struct { type Role struct {
ID string `json:"id"` ID string `json:"id"`
@ -346,3 +365,59 @@ type State struct {
Ready Ready
MaxMessageCount int MaxMessageCount int
} }
// Constants for the different bit offsets of text channel permissions
const (
PermissionReadMessages = 1 << (iota + 10)
PermissionSendMessages
PermissionSendTTSMessages
PermissionManageMessages
PermissionEmbedLinks
PermissionAttachFiles
PermissionReadMessageHistory
PermissionMentionEveryone
)
// Constants for the different bit offsets of voice permissions
const (
PermissionVoiceConnect = 1 << (iota + 20)
PermissionVoiceSpeak
PermissionVoiceMuteMembers
PermissionVoiceDeafenMembers
PermissionVoiceMoveMembers
PermissionVoiceUseVAD
)
// Constants for the different bit offsets of general permissions
const (
PermissionCreateInstantInvite = 1 << iota
PermissionKickMembers
PermissionBanMembers
PermissionManageRoles
PermissionManageChannels
PermissionManageServer
PermissionAllText = PermissionReadMessages |
PermissionSendMessages |
PermissionSendTTSMessages |
PermissionManageMessages |
PermissionEmbedLinks |
PermissionAttachFiles |
PermissionReadMessageHistory |
PermissionMentionEveryone
PermissionAllVoice = PermissionVoiceConnect |
PermissionVoiceSpeak |
PermissionVoiceMuteMembers |
PermissionVoiceDeafenMembers |
PermissionVoiceMoveMembers |
PermissionVoiceUseVAD
PermissionAllChannel = PermissionAllText |
PermissionAllVoice |
PermissionCreateInstantInvite |
PermissionManageRoles |
PermissionManageChannels
PermissionAll = PermissionAllChannel |
PermissionKickMembers |
PermissionBanMembers |
PermissionManageServer
)