state.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  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. return nil
  541. }
  542. }
  543. c.Messages = append(c.Messages, message)
  544. if len(c.Messages) > s.MaxMessageCount {
  545. c.Messages = c.Messages[len(c.Messages)-s.MaxMessageCount:]
  546. }
  547. return nil
  548. }
  549. // MessageRemove removes a message from the world state.
  550. func (s *State) MessageRemove(message *Message) error {
  551. if s == nil {
  552. return ErrNilState
  553. }
  554. return s.messageRemoveByID(message.ChannelID, message.ID)
  555. }
  556. // messageRemoveByID removes a message by channelID and messageID from the world state.
  557. func (s *State) messageRemoveByID(channelID, messageID string) error {
  558. c, err := s.Channel(channelID)
  559. if err != nil {
  560. return err
  561. }
  562. s.Lock()
  563. defer s.Unlock()
  564. for i, m := range c.Messages {
  565. if m.ID == messageID {
  566. c.Messages = append(c.Messages[:i], c.Messages[i+1:]...)
  567. return nil
  568. }
  569. }
  570. return ErrStateNotFound
  571. }
  572. func (s *State) voiceStateUpdate(update *VoiceStateUpdate) error {
  573. guild, err := s.Guild(update.GuildID)
  574. if err != nil {
  575. return err
  576. }
  577. s.Lock()
  578. defer s.Unlock()
  579. // Handle Leaving Channel
  580. if update.ChannelID == "" {
  581. for i, state := range guild.VoiceStates {
  582. if state.UserID == update.UserID {
  583. guild.VoiceStates = append(guild.VoiceStates[:i], guild.VoiceStates[i+1:]...)
  584. return nil
  585. }
  586. }
  587. } else {
  588. for i, state := range guild.VoiceStates {
  589. if state.UserID == update.UserID {
  590. guild.VoiceStates[i] = update.VoiceState
  591. return nil
  592. }
  593. }
  594. guild.VoiceStates = append(guild.VoiceStates, update.VoiceState)
  595. }
  596. return nil
  597. }
  598. // VoiceState gets a VoiceState by guild and user ID.
  599. func (s *State) VoiceState(guildID, userID string) (*VoiceState, error) {
  600. if s == nil {
  601. return nil, ErrNilState
  602. }
  603. guild, err := s.Guild(guildID)
  604. if err != nil {
  605. return nil, err
  606. }
  607. for _, state := range guild.VoiceStates {
  608. if state.UserID == userID {
  609. return state, nil
  610. }
  611. }
  612. return nil, ErrStateNotFound
  613. }
  614. // Message gets a message by channel and message ID.
  615. func (s *State) Message(channelID, messageID string) (*Message, error) {
  616. if s == nil {
  617. return nil, ErrNilState
  618. }
  619. c, err := s.Channel(channelID)
  620. if err != nil {
  621. return nil, err
  622. }
  623. s.RLock()
  624. defer s.RUnlock()
  625. for _, m := range c.Messages {
  626. if m.ID == messageID {
  627. return m, nil
  628. }
  629. }
  630. return nil, ErrStateNotFound
  631. }
  632. // OnReady takes a Ready event and updates all internal state.
  633. func (s *State) onReady(se *Session, r *Ready) (err error) {
  634. if s == nil {
  635. return ErrNilState
  636. }
  637. s.Lock()
  638. defer s.Unlock()
  639. // We must track at least the current user for Voice, even
  640. // if state is disabled, store the bare essentials.
  641. if !se.StateEnabled {
  642. ready := Ready{
  643. Version: r.Version,
  644. SessionID: r.SessionID,
  645. User: r.User,
  646. }
  647. s.Ready = ready
  648. return nil
  649. }
  650. s.Ready = *r
  651. for _, g := range s.Guilds {
  652. s.guildMap[g.ID] = g
  653. s.createMemberMap(g)
  654. for _, c := range g.Channels {
  655. s.channelMap[c.ID] = c
  656. }
  657. }
  658. for _, c := range s.PrivateChannels {
  659. s.channelMap[c.ID] = c
  660. }
  661. return nil
  662. }
  663. // OnInterface handles all events related to states.
  664. func (s *State) OnInterface(se *Session, i interface{}) (err error) {
  665. if s == nil {
  666. return ErrNilState
  667. }
  668. r, ok := i.(*Ready)
  669. if ok {
  670. return s.onReady(se, r)
  671. }
  672. if !se.StateEnabled {
  673. return nil
  674. }
  675. switch t := i.(type) {
  676. case *GuildCreate:
  677. err = s.GuildAdd(t.Guild)
  678. case *GuildUpdate:
  679. err = s.GuildAdd(t.Guild)
  680. case *GuildDelete:
  681. err = s.GuildRemove(t.Guild)
  682. case *GuildMemberAdd:
  683. // Updates the MemberCount of the guild.
  684. guild, err := s.Guild(t.Member.GuildID)
  685. if err != nil {
  686. return err
  687. }
  688. guild.MemberCount++
  689. // Caches member if tracking is enabled.
  690. if s.TrackMembers {
  691. err = s.MemberAdd(t.Member)
  692. }
  693. case *GuildMemberUpdate:
  694. if s.TrackMembers {
  695. err = s.MemberAdd(t.Member)
  696. }
  697. case *GuildMemberRemove:
  698. // Updates the MemberCount of the guild.
  699. guild, err := s.Guild(t.Member.GuildID)
  700. if err != nil {
  701. return err
  702. }
  703. guild.MemberCount--
  704. // Removes member from the cache if tracking is enabled.
  705. if s.TrackMembers {
  706. err = s.MemberRemove(t.Member)
  707. }
  708. case *GuildMembersChunk:
  709. if s.TrackMembers {
  710. for i := range t.Members {
  711. t.Members[i].GuildID = t.GuildID
  712. err = s.MemberAdd(t.Members[i])
  713. }
  714. }
  715. if s.TrackPresences {
  716. for _, p := range t.Presences {
  717. err = s.PresenceAdd(t.GuildID, p)
  718. }
  719. }
  720. case *GuildRoleCreate:
  721. if s.TrackRoles {
  722. err = s.RoleAdd(t.GuildID, t.Role)
  723. }
  724. case *GuildRoleUpdate:
  725. if s.TrackRoles {
  726. err = s.RoleAdd(t.GuildID, t.Role)
  727. }
  728. case *GuildRoleDelete:
  729. if s.TrackRoles {
  730. err = s.RoleRemove(t.GuildID, t.RoleID)
  731. }
  732. case *GuildEmojisUpdate:
  733. if s.TrackEmojis {
  734. err = s.EmojisAdd(t.GuildID, t.Emojis)
  735. }
  736. case *ChannelCreate:
  737. if s.TrackChannels {
  738. err = s.ChannelAdd(t.Channel)
  739. }
  740. case *ChannelUpdate:
  741. if s.TrackChannels {
  742. err = s.ChannelAdd(t.Channel)
  743. }
  744. case *ChannelDelete:
  745. if s.TrackChannels {
  746. err = s.ChannelRemove(t.Channel)
  747. }
  748. case *MessageCreate:
  749. if s.MaxMessageCount != 0 {
  750. err = s.MessageAdd(t.Message)
  751. }
  752. case *MessageUpdate:
  753. if s.MaxMessageCount != 0 {
  754. var old *Message
  755. old, err = s.Message(t.ChannelID, t.ID)
  756. if err == nil {
  757. oldCopy := *old
  758. t.BeforeUpdate = &oldCopy
  759. }
  760. err = s.MessageAdd(t.Message)
  761. }
  762. case *MessageDelete:
  763. if s.MaxMessageCount != 0 {
  764. var old *Message
  765. old, err = s.Message(t.ChannelID, t.ID)
  766. if err == nil {
  767. oldCopy := *old
  768. t.BeforeDelete = &oldCopy
  769. }
  770. err = s.MessageRemove(t.Message)
  771. }
  772. case *MessageDeleteBulk:
  773. if s.MaxMessageCount != 0 {
  774. for _, mID := range t.Messages {
  775. s.messageRemoveByID(t.ChannelID, mID)
  776. }
  777. }
  778. case *VoiceStateUpdate:
  779. if s.TrackVoice {
  780. var old *VoiceState
  781. old, err = s.VoiceState(t.GuildID, t.UserID)
  782. if err == nil {
  783. oldCopy := *old
  784. t.BeforeUpdate = &oldCopy
  785. }
  786. err = s.voiceStateUpdate(t)
  787. }
  788. case *PresenceUpdate:
  789. if s.TrackPresences {
  790. s.PresenceAdd(t.GuildID, &t.Presence)
  791. }
  792. if s.TrackMembers {
  793. if t.Status == StatusOffline {
  794. return
  795. }
  796. var m *Member
  797. m, err = s.Member(t.GuildID, t.User.ID)
  798. if err != nil {
  799. // Member not found; this is a user coming online
  800. m = &Member{
  801. GuildID: t.GuildID,
  802. User: t.User,
  803. }
  804. } else {
  805. if t.User.Username != "" {
  806. m.User.Username = t.User.Username
  807. }
  808. }
  809. err = s.MemberAdd(m)
  810. }
  811. }
  812. return
  813. }
  814. // UserChannelPermissions returns the permission of a user in a channel.
  815. // userID : The ID of the user to calculate permissions for.
  816. // channelID : The ID of the channel to calculate permission for.
  817. func (s *State) UserChannelPermissions(userID, channelID string) (apermissions int64, err error) {
  818. if s == nil {
  819. return 0, ErrNilState
  820. }
  821. channel, err := s.Channel(channelID)
  822. if err != nil {
  823. return
  824. }
  825. guild, err := s.Guild(channel.GuildID)
  826. if err != nil {
  827. return
  828. }
  829. member, err := s.Member(guild.ID, userID)
  830. if err != nil {
  831. return
  832. }
  833. return memberPermissions(guild, channel, userID, member.Roles), nil
  834. }
  835. // MessagePermissions returns the permissions of the author of the message
  836. // in the channel in which it was sent.
  837. func (s *State) MessagePermissions(message *Message) (apermissions int64, err error) {
  838. if s == nil {
  839. return 0, ErrNilState
  840. }
  841. if message.Author == nil || message.Member == nil {
  842. return 0, ErrMessageIncompletePermissions
  843. }
  844. channel, err := s.Channel(message.ChannelID)
  845. if err != nil {
  846. return
  847. }
  848. guild, err := s.Guild(channel.GuildID)
  849. if err != nil {
  850. return
  851. }
  852. return memberPermissions(guild, channel, message.Author.ID, message.Member.Roles), nil
  853. }
  854. // UserColor returns the color of a user in a channel.
  855. // While colors are defined at a Guild level, determining for a channel is more useful in message handlers.
  856. // 0 is returned in cases of error, which is the color of @everyone.
  857. // userID : The ID of the user to calculate the color for.
  858. // channelID : The ID of the channel to calculate the color for.
  859. func (s *State) UserColor(userID, channelID string) int {
  860. if s == nil {
  861. return 0
  862. }
  863. channel, err := s.Channel(channelID)
  864. if err != nil {
  865. return 0
  866. }
  867. guild, err := s.Guild(channel.GuildID)
  868. if err != nil {
  869. return 0
  870. }
  871. member, err := s.Member(guild.ID, userID)
  872. if err != nil {
  873. return 0
  874. }
  875. return firstRoleColorColor(guild, member.Roles)
  876. }
  877. // MessageColor returns the color of the author's name as displayed
  878. // in the client associated with this message.
  879. func (s *State) MessageColor(message *Message) int {
  880. if s == nil {
  881. return 0
  882. }
  883. if message.Member == nil || message.Member.Roles == nil {
  884. return 0
  885. }
  886. channel, err := s.Channel(message.ChannelID)
  887. if err != nil {
  888. return 0
  889. }
  890. guild, err := s.Guild(channel.GuildID)
  891. if err != nil {
  892. return 0
  893. }
  894. return firstRoleColorColor(guild, message.Member.Roles)
  895. }
  896. func firstRoleColorColor(guild *Guild, memberRoles []string) int {
  897. roles := Roles(guild.Roles)
  898. sort.Sort(roles)
  899. for _, role := range roles {
  900. for _, roleID := range memberRoles {
  901. if role.ID == roleID {
  902. if role.Color != 0 {
  903. return role.Color
  904. }
  905. }
  906. }
  907. }
  908. for _, role := range roles {
  909. if role.ID == guild.ID {
  910. return role.Color
  911. }
  912. }
  913. return 0
  914. }