state.go 23 KB

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