state.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package discordgo
  2. import "errors"
  3. var nilError error = errors.New("State not instantiated, please use discordgo.New() or assign session.State.")
  4. // NewState creates an empty state.
  5. func NewState() *State {
  6. return &State{
  7. Ready: Ready{
  8. PrivateChannels: []Channel{},
  9. Guilds: []Guild{},
  10. },
  11. }
  12. }
  13. // OnReady takes a Ready event and updates all internal state.
  14. func (s *State) OnReady(r *Ready) error {
  15. if s == nil {
  16. return nilError
  17. }
  18. s.Ready = *r
  19. return nil
  20. }
  21. // GuildAdd adds a guild to the current world state, or
  22. // updates it if it already exists.
  23. func (s *State) GuildAdd(guild *Guild) error {
  24. if s == nil {
  25. return nilError
  26. }
  27. for _, g := range s.Guilds {
  28. if g.ID == guild.ID {
  29. // This could be a little faster ;)
  30. for _, m := range guild.Members {
  31. s.MemberAdd(&m)
  32. }
  33. for _, c := range guild.Channels {
  34. s.ChannelAdd(&c)
  35. }
  36. return nil
  37. }
  38. }
  39. s.Guilds = append(s.Guilds, *guild)
  40. return nil
  41. }
  42. // GuildRemove removes a guild from current world state.
  43. func (s *State) GuildRemove(guild *Guild) error {
  44. if s == nil {
  45. return nilError
  46. }
  47. for i, g := range s.Guilds {
  48. if g.ID == guild.ID {
  49. s.Guilds = append(s.Guilds[:i], s.Guilds[i+1:]...)
  50. return nil
  51. }
  52. }
  53. return errors.New("Guild not found.")
  54. }
  55. // Guild gets a guild by ID.
  56. // Useful for querying if @me is in a guild:
  57. // _, err := discordgo.Session.State.Guild(guildID)
  58. // isInGuild := err == nil
  59. func (s *State) Guild(guildID string) (*Guild, error) {
  60. if s == nil {
  61. return nil, nilError
  62. }
  63. for _, g := range s.Guilds {
  64. if g.ID == guildID {
  65. return &g, nil
  66. }
  67. }
  68. return nil, errors.New("Guild not found.")
  69. }
  70. // TODO: Consider moving Guild state update methods onto *Guild.
  71. // MemberAdd adds a member to the current world state, or
  72. // updates it if it already exists.
  73. func (s *State) MemberAdd(member *Member) error {
  74. if s == nil {
  75. return nilError
  76. }
  77. guild, err := s.Guild(member.GuildID)
  78. if err != nil {
  79. return err
  80. }
  81. for i, m := range guild.Members {
  82. if m.User.ID == member.User.ID {
  83. guild.Members[i] = *member
  84. return nil
  85. }
  86. }
  87. guild.Members = append(guild.Members, *member)
  88. return nil
  89. }
  90. // MemberRemove removes a member from current world state.
  91. func (s *State) MemberRemove(member *Member) error {
  92. if s == nil {
  93. return nilError
  94. }
  95. guild, err := s.Guild(member.GuildID)
  96. if err != nil {
  97. return err
  98. }
  99. for i, m := range guild.Members {
  100. if m.User.ID == member.User.ID {
  101. guild.Members = append(guild.Members[:i], guild.Members[i+1:]...)
  102. return nil
  103. }
  104. }
  105. return errors.New("Member not found.")
  106. }
  107. // Member gets a member by ID from a guild.
  108. func (s *State) Member(guildID string, userID string) (*Member, error) {
  109. if s == nil {
  110. return nil, nilError
  111. }
  112. guild, err := s.Guild(guildID)
  113. if err != nil {
  114. return nil, err
  115. }
  116. for _, m := range guild.Members {
  117. if m.User.ID == userID {
  118. return &m, nil
  119. }
  120. }
  121. return nil, errors.New("Member not found.")
  122. }
  123. // ChannelAdd adds a guild to the current world state, or
  124. // updates it if it already exists.
  125. // Channels may exist either as PrivateChannels or inside
  126. // a guild.
  127. func (s *State) ChannelAdd(channel *Channel) error {
  128. if s == nil {
  129. return nilError
  130. }
  131. if channel.IsPrivate {
  132. for i, c := range s.PrivateChannels {
  133. if c.ID == channel.ID {
  134. s.PrivateChannels[i] = *channel
  135. return nil
  136. }
  137. }
  138. s.PrivateChannels = append(s.PrivateChannels, *channel)
  139. } else {
  140. guild, err := s.Guild(channel.GuildID)
  141. if err != nil {
  142. return err
  143. }
  144. for i, c := range guild.Channels {
  145. if c.ID == channel.ID {
  146. guild.Channels[i] = *channel
  147. return nil
  148. }
  149. }
  150. guild.Channels = append(guild.Channels, *channel)
  151. }
  152. return nil
  153. }
  154. // ChannelRemove removes a channel from current world state.
  155. func (s *State) ChannelRemove(channel *Channel) error {
  156. if s == nil {
  157. return nilError
  158. }
  159. if channel.IsPrivate {
  160. for i, c := range s.PrivateChannels {
  161. if c.ID == channel.ID {
  162. s.PrivateChannels = append(s.PrivateChannels[:i], s.PrivateChannels[i+1:]...)
  163. return nil
  164. }
  165. }
  166. } else {
  167. guild, err := s.Guild(channel.GuildID)
  168. if err != nil {
  169. return err
  170. }
  171. for i, c := range guild.Channels {
  172. if c.ID == channel.ID {
  173. guild.Channels = append(guild.Channels[:i], guild.Channels[i+1:]...)
  174. return nil
  175. }
  176. }
  177. }
  178. return errors.New("Channel not found.")
  179. }
  180. // GuildChannel gets a channel by ID from a guild.
  181. func (s *State) GuildChannel(guildID string, channelID string) (*Channel, error) {
  182. if s == nil {
  183. return nil, nilError
  184. }
  185. guild, err := s.Guild(guildID)
  186. if err != nil {
  187. return nil, err
  188. }
  189. for _, c := range guild.Channels {
  190. if c.ID == channelID {
  191. return &c, nil
  192. }
  193. }
  194. return nil, errors.New("Channel not found.")
  195. }
  196. // PrivateChannel gets a private channel by ID.
  197. func (s *State) PrivateChannel(channelID string) (*Channel, error) {
  198. if s == nil {
  199. return nil, nilError
  200. }
  201. for _, c := range s.PrivateChannels {
  202. if c.ID == channelID {
  203. return &c, nil
  204. }
  205. }
  206. return nil, errors.New("Channel not found.")
  207. }
  208. // Channel gets a channel by ID, it will look in all guilds an private channels.
  209. func (s *State) Channel(channelID string) (*Channel, error) {
  210. if s == nil {
  211. return nil, nilError
  212. }
  213. c, err := s.PrivateChannel(channelID)
  214. if err == nil {
  215. return c, nil
  216. }
  217. for _, g := range s.Guilds {
  218. c, err := s.GuildChannel(g.ID, channelID)
  219. if err == nil {
  220. return c, nil
  221. }
  222. }
  223. return nil, errors.New("Channel not found.")
  224. }