state.go 23 KB

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