state.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. // Discordgo - Discord bindings for Go
  2. // Available at https://github.com/bwmarrin/discordgo
  3. // Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>. All rights reserved.
  4. // Use of this source code is governed by a BSD-style
  5. // license that can be found in the LICENSE file.
  6. // This file contains code related to state tracking. If enabled, state
  7. // tracking will capture the initial READY packet and many other websocket
  8. // events and maintain an in-memory state of of guilds, channels, users, and
  9. // so forth. This information can be accessed through the Session.State struct.
  10. package discordgo
  11. import (
  12. "errors"
  13. "sort"
  14. "sync"
  15. )
  16. // ErrNilState is returned when the state is nil.
  17. var ErrNilState = errors.New("state not instantiated, please use discordgo.New() or assign Session.State")
  18. // ErrStateNotFound is returned when the state cache
  19. // requested is not found
  20. var ErrStateNotFound = errors.New("state cache not found")
  21. // A State contains the current known state.
  22. // As discord sends this in a READY blob, it seems reasonable to simply
  23. // use that struct as the data store.
  24. type State struct {
  25. sync.RWMutex
  26. Ready
  27. // MaxMessageCount represents how many messages per channel the state will store.
  28. MaxMessageCount int
  29. TrackChannels bool
  30. TrackEmojis bool
  31. TrackMembers bool
  32. TrackRoles bool
  33. TrackVoice bool
  34. TrackPresences bool
  35. guildMap map[string]*Guild
  36. channelMap map[string]*Channel
  37. memberMap map[string]map[string]*Member
  38. }
  39. // NewState creates an empty state.
  40. func NewState() *State {
  41. return &State{
  42. Ready: Ready{
  43. PrivateChannels: []*Channel{},
  44. Guilds: []*Guild{},
  45. },
  46. TrackChannels: true,
  47. TrackEmojis: true,
  48. TrackMembers: true,
  49. TrackRoles: true,
  50. TrackVoice: true,
  51. TrackPresences: true,
  52. guildMap: make(map[string]*Guild),
  53. channelMap: make(map[string]*Channel),
  54. memberMap: make(map[string]map[string]*Member),
  55. }
  56. }
  57. func (s *State) createMemberMap(guild *Guild) {
  58. members := make(map[string]*Member)
  59. for _, m := range guild.Members {
  60. members[m.User.ID] = m
  61. }
  62. s.memberMap[guild.ID] = members
  63. }
  64. // GuildAdd adds a guild to the current world state, or
  65. // updates it if it already exists.
  66. func (s *State) GuildAdd(guild *Guild) error {
  67. if s == nil {
  68. return ErrNilState
  69. }
  70. s.Lock()
  71. defer s.Unlock()
  72. // Update the channels to point to the right guild, adding them to the channelMap as we go
  73. for _, c := range guild.Channels {
  74. s.channelMap[c.ID] = c
  75. }
  76. // If this guild contains a new member slice, we must regenerate the member map so the pointers stay valid
  77. if guild.Members != nil {
  78. s.createMemberMap(guild)
  79. } else if _, ok := s.memberMap[guild.ID]; !ok {
  80. // Even if we have no new member slice, we still initialize the member map for this guild if it doesn't exist
  81. s.memberMap[guild.ID] = make(map[string]*Member)
  82. }
  83. if g, ok := s.guildMap[guild.ID]; ok {
  84. // We are about to replace `g` in the state with `guild`, but first we need to
  85. // make sure we preserve any fields that the `guild` doesn't contain from `g`.
  86. if guild.Roles == nil {
  87. guild.Roles = g.Roles
  88. }
  89. if guild.Emojis == nil {
  90. guild.Emojis = g.Emojis
  91. }
  92. if guild.Members == nil {
  93. guild.Members = g.Members
  94. }
  95. if guild.Presences == nil {
  96. guild.Presences = g.Presences
  97. }
  98. if guild.Channels == nil {
  99. guild.Channels = g.Channels
  100. }
  101. if guild.VoiceStates == nil {
  102. guild.VoiceStates = g.VoiceStates
  103. }
  104. *g = *guild
  105. return nil
  106. }
  107. s.Guilds = append(s.Guilds, guild)
  108. s.guildMap[guild.ID] = guild
  109. return nil
  110. }
  111. // GuildRemove removes a guild from current world state.
  112. func (s *State) GuildRemove(guild *Guild) error {
  113. if s == nil {
  114. return ErrNilState
  115. }
  116. _, err := s.Guild(guild.ID)
  117. if err != nil {
  118. return err
  119. }
  120. s.Lock()
  121. defer s.Unlock()
  122. delete(s.guildMap, guild.ID)
  123. for i, g := range s.Guilds {
  124. if g.ID == guild.ID {
  125. s.Guilds = append(s.Guilds[:i], s.Guilds[i+1:]...)
  126. return nil
  127. }
  128. }
  129. return nil
  130. }
  131. // Guild gets a guild by ID.
  132. // Useful for querying if @me is in a guild:
  133. // _, err := discordgo.Session.State.Guild(guildID)
  134. // isInGuild := err == nil
  135. func (s *State) Guild(guildID string) (*Guild, error) {
  136. if s == nil {
  137. return nil, ErrNilState
  138. }
  139. s.RLock()
  140. defer s.RUnlock()
  141. if g, ok := s.guildMap[guildID]; ok {
  142. return g, nil
  143. }
  144. return nil, ErrStateNotFound
  145. }
  146. // PresenceAdd adds a presence to the current world state, or
  147. // updates it if it already exists.
  148. func (s *State) PresenceAdd(guildID string, presence *Presence) error {
  149. if s == nil {
  150. return ErrNilState
  151. }
  152. guild, err := s.Guild(guildID)
  153. if err != nil {
  154. return err
  155. }
  156. s.Lock()
  157. defer s.Unlock()
  158. for i, p := range guild.Presences {
  159. if p.User.ID == presence.User.ID {
  160. //guild.Presences[i] = presence
  161. //Update status
  162. guild.Presences[i].Game = presence.Game
  163. guild.Presences[i].Roles = presence.Roles
  164. if presence.Status != "" {
  165. guild.Presences[i].Status = presence.Status
  166. }
  167. if presence.Nick != "" {
  168. guild.Presences[i].Nick = presence.Nick
  169. }
  170. //Update the optionally sent user information
  171. //ID Is a mandatory field so you should not need to check if it is empty
  172. guild.Presences[i].User.ID = presence.User.ID
  173. if presence.User.Avatar != "" {
  174. guild.Presences[i].User.Avatar = presence.User.Avatar
  175. }
  176. if presence.User.Discriminator != "" {
  177. guild.Presences[i].User.Discriminator = presence.User.Discriminator
  178. }
  179. if presence.User.Email != "" {
  180. guild.Presences[i].User.Email = presence.User.Email
  181. }
  182. if presence.User.Token != "" {
  183. guild.Presences[i].User.Token = presence.User.Token
  184. }
  185. if presence.User.Username != "" {
  186. guild.Presences[i].User.Username = presence.User.Username
  187. }
  188. return nil
  189. }
  190. }
  191. guild.Presences = append(guild.Presences, presence)
  192. return nil
  193. }
  194. // PresenceRemove removes a presence from the current world state.
  195. func (s *State) PresenceRemove(guildID string, presence *Presence) error {
  196. if s == nil {
  197. return ErrNilState
  198. }
  199. guild, err := s.Guild(guildID)
  200. if err != nil {
  201. return err
  202. }
  203. s.Lock()
  204. defer s.Unlock()
  205. for i, p := range guild.Presences {
  206. if p.User.ID == presence.User.ID {
  207. guild.Presences = append(guild.Presences[:i], guild.Presences[i+1:]...)
  208. return nil
  209. }
  210. }
  211. return ErrStateNotFound
  212. }
  213. // Presence gets a presence by ID from a guild.
  214. func (s *State) Presence(guildID, userID string) (*Presence, error) {
  215. if s == nil {
  216. return nil, ErrNilState
  217. }
  218. guild, err := s.Guild(guildID)
  219. if err != nil {
  220. return nil, err
  221. }
  222. for _, p := range guild.Presences {
  223. if p.User.ID == userID {
  224. return p, nil
  225. }
  226. }
  227. return nil, ErrStateNotFound
  228. }
  229. // TODO: Consider moving Guild state update methods onto *Guild.
  230. // MemberAdd adds a member to the current world state, or
  231. // updates it if it already exists.
  232. func (s *State) MemberAdd(member *Member) error {
  233. if s == nil {
  234. return ErrNilState
  235. }
  236. guild, err := s.Guild(member.GuildID)
  237. if err != nil {
  238. return err
  239. }
  240. s.Lock()
  241. defer s.Unlock()
  242. members, ok := s.memberMap[member.GuildID]
  243. if !ok {
  244. return ErrStateNotFound
  245. }
  246. m, ok := members[member.User.ID]
  247. if !ok {
  248. members[member.User.ID] = member
  249. guild.Members = append(guild.Members, member)
  250. } else {
  251. *m = *member // Update the actual data, which will also update the member pointer in the slice
  252. }
  253. return nil
  254. }
  255. // MemberRemove removes a member from current world state.
  256. func (s *State) MemberRemove(member *Member) error {
  257. if s == nil {
  258. return ErrNilState
  259. }
  260. guild, err := s.Guild(member.GuildID)
  261. if err != nil {
  262. return err
  263. }
  264. s.Lock()
  265. defer s.Unlock()
  266. members, ok := s.memberMap[member.GuildID]
  267. if !ok {
  268. return ErrStateNotFound
  269. }
  270. _, ok = members[member.User.ID]
  271. if !ok {
  272. return ErrStateNotFound
  273. }
  274. delete(members, member.User.ID)
  275. for i, m := range guild.Members {
  276. if m.User.ID == member.User.ID {
  277. guild.Members = append(guild.Members[:i], guild.Members[i+1:]...)
  278. return nil
  279. }
  280. }
  281. return ErrStateNotFound
  282. }
  283. // Member gets a member by ID from a guild.
  284. func (s *State) Member(guildID, userID string) (*Member, error) {
  285. if s == nil {
  286. return nil, ErrNilState
  287. }
  288. s.RLock()
  289. defer s.RUnlock()
  290. members, ok := s.memberMap[guildID]
  291. if !ok {
  292. return nil, ErrStateNotFound
  293. }
  294. m, ok := members[userID]
  295. if ok {
  296. return m, nil
  297. }
  298. return nil, ErrStateNotFound
  299. }
  300. // RoleAdd adds a role to the current world state, or
  301. // updates it if it already exists.
  302. func (s *State) RoleAdd(guildID string, role *Role) error {
  303. if s == nil {
  304. return ErrNilState
  305. }
  306. guild, err := s.Guild(guildID)
  307. if err != nil {
  308. return err
  309. }
  310. s.Lock()
  311. defer s.Unlock()
  312. for i, r := range guild.Roles {
  313. if r.ID == role.ID {
  314. guild.Roles[i] = role
  315. return nil
  316. }
  317. }
  318. guild.Roles = append(guild.Roles, role)
  319. return nil
  320. }
  321. // RoleRemove removes a role from current world state by ID.
  322. func (s *State) RoleRemove(guildID, roleID string) error {
  323. if s == nil {
  324. return ErrNilState
  325. }
  326. guild, err := s.Guild(guildID)
  327. if err != nil {
  328. return err
  329. }
  330. s.Lock()
  331. defer s.Unlock()
  332. for i, r := range guild.Roles {
  333. if r.ID == roleID {
  334. guild.Roles = append(guild.Roles[:i], guild.Roles[i+1:]...)
  335. return nil
  336. }
  337. }
  338. return ErrStateNotFound
  339. }
  340. // Role gets a role by ID from a guild.
  341. func (s *State) Role(guildID, roleID string) (*Role, error) {
  342. if s == nil {
  343. return nil, ErrNilState
  344. }
  345. guild, err := s.Guild(guildID)
  346. if err != nil {
  347. return nil, err
  348. }
  349. s.RLock()
  350. defer s.RUnlock()
  351. for _, r := range guild.Roles {
  352. if r.ID == roleID {
  353. return r, nil
  354. }
  355. }
  356. return nil, ErrStateNotFound
  357. }
  358. // ChannelAdd adds a channel to the current world state, or
  359. // updates it if it already exists.
  360. // Channels may exist either as PrivateChannels or inside
  361. // a guild.
  362. func (s *State) ChannelAdd(channel *Channel) error {
  363. if s == nil {
  364. return ErrNilState
  365. }
  366. s.Lock()
  367. defer s.Unlock()
  368. // If the channel exists, replace it
  369. if c, ok := s.channelMap[channel.ID]; ok {
  370. if channel.Messages == nil {
  371. channel.Messages = c.Messages
  372. }
  373. if channel.PermissionOverwrites == nil {
  374. channel.PermissionOverwrites = c.PermissionOverwrites
  375. }
  376. *c = *channel
  377. return nil
  378. }
  379. if channel.Type == ChannelTypeDM || channel.Type == ChannelTypeGroupDM {
  380. s.PrivateChannels = append(s.PrivateChannels, channel)
  381. } else {
  382. guild, ok := s.guildMap[channel.GuildID]
  383. if !ok {
  384. return ErrStateNotFound
  385. }
  386. guild.Channels = append(guild.Channels, channel)
  387. }
  388. s.channelMap[channel.ID] = channel
  389. return nil
  390. }
  391. // ChannelRemove removes a channel from current world state.
  392. func (s *State) ChannelRemove(channel *Channel) error {
  393. if s == nil {
  394. return ErrNilState
  395. }
  396. _, err := s.Channel(channel.ID)
  397. if err != nil {
  398. return err
  399. }
  400. if channel.Type == ChannelTypeDM || channel.Type == ChannelTypeGroupDM {
  401. s.Lock()
  402. defer s.Unlock()
  403. for i, c := range s.PrivateChannels {
  404. if c.ID == channel.ID {
  405. s.PrivateChannels = append(s.PrivateChannels[:i], s.PrivateChannels[i+1:]...)
  406. break
  407. }
  408. }
  409. } else {
  410. guild, err := s.Guild(channel.GuildID)
  411. if err != nil {
  412. return err
  413. }
  414. s.Lock()
  415. defer s.Unlock()
  416. for i, c := range guild.Channels {
  417. if c.ID == channel.ID {
  418. guild.Channels = append(guild.Channels[:i], guild.Channels[i+1:]...)
  419. break
  420. }
  421. }
  422. }
  423. delete(s.channelMap, channel.ID)
  424. return nil
  425. }
  426. // GuildChannel gets a channel by ID from a guild.
  427. // This method is Deprecated, use Channel(channelID)
  428. func (s *State) GuildChannel(guildID, channelID string) (*Channel, error) {
  429. return s.Channel(channelID)
  430. }
  431. // PrivateChannel gets a private channel by ID.
  432. // This method is Deprecated, use Channel(channelID)
  433. func (s *State) PrivateChannel(channelID string) (*Channel, error) {
  434. return s.Channel(channelID)
  435. }
  436. // Channel gets a channel by ID, it will look in all guilds and private channels.
  437. func (s *State) Channel(channelID string) (*Channel, error) {
  438. if s == nil {
  439. return nil, ErrNilState
  440. }
  441. s.RLock()
  442. defer s.RUnlock()
  443. if c, ok := s.channelMap[channelID]; ok {
  444. return c, nil
  445. }
  446. return nil, ErrStateNotFound
  447. }
  448. // Emoji returns an emoji for a guild and emoji id.
  449. func (s *State) Emoji(guildID, emojiID string) (*Emoji, error) {
  450. if s == nil {
  451. return nil, ErrNilState
  452. }
  453. guild, err := s.Guild(guildID)
  454. if err != nil {
  455. return nil, err
  456. }
  457. s.RLock()
  458. defer s.RUnlock()
  459. for _, e := range guild.Emojis {
  460. if e.ID == emojiID {
  461. return e, nil
  462. }
  463. }
  464. return nil, ErrStateNotFound
  465. }
  466. // EmojiAdd adds an emoji to the current world state.
  467. func (s *State) EmojiAdd(guildID string, emoji *Emoji) error {
  468. if s == nil {
  469. return ErrNilState
  470. }
  471. guild, err := s.Guild(guildID)
  472. if err != nil {
  473. return err
  474. }
  475. s.Lock()
  476. defer s.Unlock()
  477. for i, e := range guild.Emojis {
  478. if e.ID == emoji.ID {
  479. guild.Emojis[i] = emoji
  480. return nil
  481. }
  482. }
  483. guild.Emojis = append(guild.Emojis, emoji)
  484. return nil
  485. }
  486. // EmojisAdd adds multiple emojis to the world state.
  487. func (s *State) EmojisAdd(guildID string, emojis []*Emoji) error {
  488. for _, e := range emojis {
  489. if err := s.EmojiAdd(guildID, e); err != nil {
  490. return err
  491. }
  492. }
  493. return nil
  494. }
  495. // MessageAdd adds a message to the current world state, or updates it if it exists.
  496. // If the channel cannot be found, the message is discarded.
  497. // Messages are kept in state up to s.MaxMessageCount per channel.
  498. func (s *State) MessageAdd(message *Message) error {
  499. if s == nil {
  500. return ErrNilState
  501. }
  502. c, err := s.Channel(message.ChannelID)
  503. if err != nil {
  504. return err
  505. }
  506. s.Lock()
  507. defer s.Unlock()
  508. // If the message exists, merge in the new message contents.
  509. for _, m := range c.Messages {
  510. if m.ID == message.ID {
  511. if message.Content != "" {
  512. m.Content = message.Content
  513. }
  514. if message.EditedTimestamp != "" {
  515. m.EditedTimestamp = message.EditedTimestamp
  516. }
  517. if message.Mentions != nil {
  518. m.Mentions = message.Mentions
  519. }
  520. if message.Embeds != nil {
  521. m.Embeds = message.Embeds
  522. }
  523. if message.Attachments != nil {
  524. m.Attachments = message.Attachments
  525. }
  526. if message.Timestamp != "" {
  527. m.Timestamp = message.Timestamp
  528. }
  529. if message.Author != nil {
  530. m.Author = message.Author
  531. }
  532. return nil
  533. }
  534. }
  535. c.Messages = append(c.Messages, message)
  536. if len(c.Messages) > s.MaxMessageCount {
  537. c.Messages = c.Messages[len(c.Messages)-s.MaxMessageCount:]
  538. }
  539. return nil
  540. }
  541. // MessageRemove removes a message from the world state.
  542. func (s *State) MessageRemove(message *Message) error {
  543. if s == nil {
  544. return ErrNilState
  545. }
  546. return s.messageRemoveByID(message.ChannelID, message.ID)
  547. }
  548. // messageRemoveByID removes a message by channelID and messageID from the world state.
  549. func (s *State) messageRemoveByID(channelID, messageID string) error {
  550. c, err := s.Channel(channelID)
  551. if err != nil {
  552. return err
  553. }
  554. s.Lock()
  555. defer s.Unlock()
  556. for i, m := range c.Messages {
  557. if m.ID == messageID {
  558. c.Messages = append(c.Messages[:i], c.Messages[i+1:]...)
  559. return nil
  560. }
  561. }
  562. return ErrStateNotFound
  563. }
  564. func (s *State) voiceStateUpdate(update *VoiceStateUpdate) error {
  565. guild, err := s.Guild(update.GuildID)
  566. if err != nil {
  567. return err
  568. }
  569. s.Lock()
  570. defer s.Unlock()
  571. // Handle Leaving Channel
  572. if update.ChannelID == "" {
  573. for i, state := range guild.VoiceStates {
  574. if state.UserID == update.UserID {
  575. guild.VoiceStates = append(guild.VoiceStates[:i], guild.VoiceStates[i+1:]...)
  576. return nil
  577. }
  578. }
  579. } else {
  580. for i, state := range guild.VoiceStates {
  581. if state.UserID == update.UserID {
  582. guild.VoiceStates[i] = update.VoiceState
  583. return nil
  584. }
  585. }
  586. guild.VoiceStates = append(guild.VoiceStates, update.VoiceState)
  587. }
  588. return nil
  589. }
  590. // Message gets a message by channel and message ID.
  591. func (s *State) Message(channelID, messageID string) (*Message, error) {
  592. if s == nil {
  593. return nil, ErrNilState
  594. }
  595. c, err := s.Channel(channelID)
  596. if err != nil {
  597. return nil, err
  598. }
  599. s.RLock()
  600. defer s.RUnlock()
  601. for _, m := range c.Messages {
  602. if m.ID == messageID {
  603. return m, nil
  604. }
  605. }
  606. return nil, ErrStateNotFound
  607. }
  608. // OnReady takes a Ready event and updates all internal state.
  609. func (s *State) onReady(se *Session, r *Ready) (err error) {
  610. if s == nil {
  611. return ErrNilState
  612. }
  613. s.Lock()
  614. defer s.Unlock()
  615. // We must track at least the current user for Voice, even
  616. // if state is disabled, store the bare essentials.
  617. if !se.StateEnabled {
  618. ready := Ready{
  619. Version: r.Version,
  620. SessionID: r.SessionID,
  621. User: r.User,
  622. }
  623. s.Ready = ready
  624. return nil
  625. }
  626. s.Ready = *r
  627. for _, g := range s.Guilds {
  628. s.guildMap[g.ID] = g
  629. s.createMemberMap(g)
  630. for _, c := range g.Channels {
  631. s.channelMap[c.ID] = c
  632. }
  633. }
  634. for _, c := range s.PrivateChannels {
  635. s.channelMap[c.ID] = c
  636. }
  637. return nil
  638. }
  639. // OnInterface handles all events related to states.
  640. func (s *State) OnInterface(se *Session, i interface{}) (err error) {
  641. if s == nil {
  642. return ErrNilState
  643. }
  644. r, ok := i.(*Ready)
  645. if ok {
  646. return s.onReady(se, r)
  647. }
  648. if !se.StateEnabled {
  649. return nil
  650. }
  651. switch t := i.(type) {
  652. case *GuildCreate:
  653. err = s.GuildAdd(t.Guild)
  654. case *GuildUpdate:
  655. err = s.GuildAdd(t.Guild)
  656. case *GuildDelete:
  657. err = s.GuildRemove(t.Guild)
  658. case *GuildMemberAdd:
  659. if s.TrackMembers {
  660. err = s.MemberAdd(t.Member)
  661. }
  662. case *GuildMemberUpdate:
  663. if s.TrackMembers {
  664. err = s.MemberAdd(t.Member)
  665. }
  666. case *GuildMemberRemove:
  667. if s.TrackMembers {
  668. err = s.MemberRemove(t.Member)
  669. }
  670. case *GuildMembersChunk:
  671. if s.TrackMembers {
  672. for i := range t.Members {
  673. t.Members[i].GuildID = t.GuildID
  674. err = s.MemberAdd(t.Members[i])
  675. }
  676. }
  677. case *GuildRoleCreate:
  678. if s.TrackRoles {
  679. err = s.RoleAdd(t.GuildID, t.Role)
  680. }
  681. case *GuildRoleUpdate:
  682. if s.TrackRoles {
  683. err = s.RoleAdd(t.GuildID, t.Role)
  684. }
  685. case *GuildRoleDelete:
  686. if s.TrackRoles {
  687. err = s.RoleRemove(t.GuildID, t.RoleID)
  688. }
  689. case *GuildEmojisUpdate:
  690. if s.TrackEmojis {
  691. err = s.EmojisAdd(t.GuildID, t.Emojis)
  692. }
  693. case *ChannelCreate:
  694. if s.TrackChannels {
  695. err = s.ChannelAdd(t.Channel)
  696. }
  697. case *ChannelUpdate:
  698. if s.TrackChannels {
  699. err = s.ChannelAdd(t.Channel)
  700. }
  701. case *ChannelDelete:
  702. if s.TrackChannels {
  703. err = s.ChannelRemove(t.Channel)
  704. }
  705. case *MessageCreate:
  706. if s.MaxMessageCount != 0 {
  707. err = s.MessageAdd(t.Message)
  708. }
  709. case *MessageUpdate:
  710. if s.MaxMessageCount != 0 {
  711. err = s.MessageAdd(t.Message)
  712. }
  713. case *MessageDelete:
  714. if s.MaxMessageCount != 0 {
  715. err = s.MessageRemove(t.Message)
  716. }
  717. case *MessageDeleteBulk:
  718. if s.MaxMessageCount != 0 {
  719. for _, mID := range t.Messages {
  720. s.messageRemoveByID(t.ChannelID, mID)
  721. }
  722. }
  723. case *VoiceStateUpdate:
  724. if s.TrackVoice {
  725. err = s.voiceStateUpdate(t)
  726. }
  727. case *PresenceUpdate:
  728. if s.TrackPresences {
  729. s.PresenceAdd(t.GuildID, &t.Presence)
  730. }
  731. if s.TrackMembers {
  732. if t.Status == StatusOffline {
  733. return
  734. }
  735. var m *Member
  736. m, err = s.Member(t.GuildID, t.User.ID)
  737. if err != nil {
  738. // Member not found; this is a user coming online
  739. m = &Member{
  740. GuildID: t.GuildID,
  741. Nick: t.Nick,
  742. User: t.User,
  743. Roles: t.Roles,
  744. }
  745. } else {
  746. if t.Nick != "" {
  747. m.Nick = t.Nick
  748. }
  749. if t.User.Username != "" {
  750. m.User.Username = t.User.Username
  751. }
  752. // PresenceUpdates always contain a list of roles, so there's no need to check for an empty list here
  753. m.Roles = t.Roles
  754. }
  755. err = s.MemberAdd(m)
  756. }
  757. }
  758. return
  759. }
  760. // UserChannelPermissions returns the permission of a user in a channel.
  761. // userID : The ID of the user to calculate permissions for.
  762. // channelID : The ID of the channel to calculate permission for.
  763. func (s *State) UserChannelPermissions(userID, channelID string) (apermissions int, err error) {
  764. if s == nil {
  765. return 0, ErrNilState
  766. }
  767. channel, err := s.Channel(channelID)
  768. if err != nil {
  769. return
  770. }
  771. guild, err := s.Guild(channel.GuildID)
  772. if err != nil {
  773. return
  774. }
  775. if userID == guild.OwnerID {
  776. apermissions = PermissionAll
  777. return
  778. }
  779. member, err := s.Member(guild.ID, userID)
  780. if err != nil {
  781. return
  782. }
  783. return memberPermissions(guild, channel, member), nil
  784. }
  785. // UserColor returns the color of a user in a channel.
  786. // While colors are defined at a Guild level, determining for a channel is more useful in message handlers.
  787. // 0 is returned in cases of error, which is the color of @everyone.
  788. // userID : The ID of the user to calculate the color for.
  789. // channelID : The ID of the channel to calculate the color for.
  790. func (s *State) UserColor(userID, channelID string) int {
  791. if s == nil {
  792. return 0
  793. }
  794. channel, err := s.Channel(channelID)
  795. if err != nil {
  796. return 0
  797. }
  798. guild, err := s.Guild(channel.GuildID)
  799. if err != nil {
  800. return 0
  801. }
  802. member, err := s.Member(guild.ID, userID)
  803. if err != nil {
  804. return 0
  805. }
  806. roles := Roles(guild.Roles)
  807. sort.Sort(roles)
  808. for _, role := range roles {
  809. for _, roleID := range member.Roles {
  810. if role.ID == roleID {
  811. if role.Color != 0 {
  812. return role.Color
  813. }
  814. }
  815. }
  816. }
  817. return 0
  818. }