/Sources/Sword/Gateway/EventHandler.swift

https://github.com/Azoy/Sword · Swift · 423 lines · 319 code · 62 blank · 42 comment · 75 complexity · 72df3ad73e1ffc3bb260fd4b10eb0d12 MD5 · raw file

  1. //
  2. // EventHandler.swift
  3. // Sword
  4. //
  5. // Created by Alejandro Alonso
  6. // Copyright © 2017 Alejandro Alonso. All rights reserved.
  7. //
  8. import Foundation
  9. /// EventHandler
  10. extension Shard {
  11. /**
  12. Handles all dispatch events
  13. - parameter data: Data sent with dispatch
  14. - parameter eventName: Event name sent with dispatch
  15. */
  16. func handleEvent(
  17. _ data: [String: Any],
  18. _ eventName: String
  19. ) {
  20. guard let event = Event(rawValue: eventName) else {
  21. self.sword.log("Received unknown event: \(eventName)")
  22. return
  23. }
  24. switch event {
  25. /// CHANNEL_CREATE
  26. case .channelCreate:
  27. switch data["type"] as! Int {
  28. case 0:
  29. let channel = GuildText(self.sword, data)
  30. self.sword.emit(.channelCreate, with: channel)
  31. case 1:
  32. let dm = DM(self.sword, data)
  33. self.sword.emit(.channelCreate, with: dm)
  34. case 2:
  35. let channel = GuildVoice(self.sword, data)
  36. self.sword.emit(.channelCreate, with: channel)
  37. case 3:
  38. let group = GroupDM(self.sword, data)
  39. self.sword.emit(.channelCreate, with: group)
  40. case 4:
  41. let category = GuildCategory(self.sword, data)
  42. self.sword.emit(.channelCreate, with: category)
  43. default: return
  44. }
  45. /// CHANNEL_DELETE
  46. case .channelDelete:
  47. switch data["type"] as! Int {
  48. case 0, 2, 4:
  49. let guildId = Snowflake(data["guild_id"])!
  50. guard let guild = self.sword.guilds[guildId] else {
  51. return
  52. }
  53. let channelId = Snowflake(data["id"])!
  54. guard let channel = guild.channels.removeValue(forKey: channelId) else {
  55. return
  56. }
  57. self.sword.emit(.channelDelete, with: channel)
  58. case 1:
  59. let recipient = (data["recipients"] as! [[String: Any]])[0]
  60. let userId = Snowflake(recipient["id"])!
  61. guard let dm = self.sword.dms.removeValue(forKey: userId) else {
  62. return
  63. }
  64. self.sword.emit(.channelDelete, with: dm)
  65. case 3:
  66. let channelId = Snowflake(data["id"])!
  67. guard let group = self.sword.groups.removeValue(forKey: channelId) else {
  68. return
  69. }
  70. self.sword.emit(.channelDelete, with: group)
  71. default: return
  72. }
  73. /// CHANNEL_PINS_UPDATE
  74. case .channelPinsUpdate:
  75. let channelId = Snowflake(data["channel_id"])!
  76. let timestamp = data["last_pin_timestamp"] as? String
  77. guard let channel = self.sword.getChannel(for: channelId) else {
  78. return
  79. }
  80. self.sword.emit(.channelPinsUpdate, with: (channel, timestamp?.date)
  81. )
  82. /// CHANNEL_UPDATE
  83. case .channelUpdate:
  84. switch data["type"] as! Int {
  85. case 0, 2, 4:
  86. let guildId = Snowflake(data["guild_id"])!
  87. let channelId = Snowflake(data["id"])!
  88. guard let channel = self.sword.guilds[guildId]!.channels[channelId] as? Updatable else {
  89. return
  90. }
  91. channel.update(data)
  92. self.sword.emit(.channelUpdate, with: channel)
  93. case 3:
  94. let group = GroupDM(self.sword, data)
  95. self.sword.groups[group.id] = group
  96. self.sword.emit(.channelUpdate, with: group)
  97. default: return
  98. }
  99. /// GUILD_BAN_ADD & GUILD_BAN_REMOVE
  100. case .guildBanAdd, .guildBanRemove:
  101. let guildId = Snowflake(data["guild_id"])!
  102. guard let guild = self.sword.guilds[guildId] else {
  103. return
  104. }
  105. let user = User(self.sword, data["user"] as! [String: Any])
  106. self.sword.emit(event, with: (guild, user))
  107. /// GUILD_CREATE
  108. case .guildCreate:
  109. let guild = Guild(self.sword, data, self.id)
  110. self.sword.guilds[guild.id] = guild
  111. if self.sword.unavailableGuilds[guild.id] != nil {
  112. self.sword.unavailableGuilds.removeValue(forKey: guild.id)
  113. self.sword.emit(.guildAvailable, with: guild)
  114. }else {
  115. self.sword.emit(.guildCreate, with: guild)
  116. }
  117. if self.sword.options.willCacheAllMembers
  118. && guild.members.count != guild.memberCount {
  119. self.requestOfflineMembers(for: guild.id)
  120. }
  121. /// GUILD_DELETE
  122. case .guildDelete:
  123. let guildId = Snowflake(data["id"])!
  124. guard let guild = self.sword.guilds.removeValue(forKey: guildId) else {
  125. return
  126. }
  127. if data["unavailable"] != nil {
  128. let unavailableGuild = UnavailableGuild(data, self.id)
  129. self.sword.unavailableGuilds[guild.id] = unavailableGuild
  130. self.sword.emit(.guildUnavailable, with: unavailableGuild)
  131. }else {
  132. self.sword.emit(.guildDelete, with: guild)
  133. }
  134. /// GUILD_EMOJIS_UPDATE
  135. case .guildEmojisUpdate:
  136. let emojis = (data["emojis"] as! [[String: Any]]).map(Emoji.init)
  137. let guildId = Snowflake(data["guild_id"])!
  138. guard let guild = self.sword.guilds[guildId] else {
  139. return
  140. }
  141. guild.emojis = emojis
  142. self.sword.emit(.guildEmojisUpdate, with: (guild, emojis))
  143. /// GUILD_INTEGRATIONS_UPDATE
  144. case .guildIntegrationsUpdate:
  145. let guildId = Snowflake(data["guild_id"])!
  146. guard let guild = self.sword.guilds[guildId] else {
  147. return
  148. }
  149. self.sword.emit(.guildIntegrationsUpdate, with: guild)
  150. /// GUILD_MEMBER_ADD
  151. case .guildMemberAdd:
  152. let guildId = Snowflake(data["guild_id"])!
  153. guard let guild = self.sword.guilds[guildId] else {
  154. return
  155. }
  156. let member = Member(self.sword, guild, data)
  157. guild.members[member.user.id] = member
  158. self.sword.emit(.guildMemberAdd, with: (guild, member))
  159. /// GUILD_MEMBER_REMOVE
  160. case .guildMemberRemove:
  161. let guildId = Snowflake(data["guild_id"])!
  162. guard let guild = self.sword.guilds[guildId] else {
  163. return
  164. }
  165. let user = User(self.sword, data["user"] as! [String: Any])
  166. guild.members.removeValue(forKey: user.id)
  167. self.sword.emit(.guildMemberRemove, with: (guild, user))
  168. /// GUILD_MEMBERS_CHUNK
  169. case .guildMembersChunk:
  170. let guildId = Snowflake(data["guild_id"])!
  171. guard let guild = self.sword.guilds[guildId] else {
  172. return
  173. }
  174. let members = data["members"] as! [[String: Any]]
  175. for member in members {
  176. let member = Member(self.sword, guild, member)
  177. guild.members[member.user.id] = member
  178. }
  179. /// GUILD_MEMBER_UPDATE
  180. case .guildMemberUpdate:
  181. let guildId = Snowflake(data["guild_id"])!
  182. guard let guild = self.sword.guilds[guildId] else {
  183. return
  184. }
  185. let member = Member(self.sword, guild, data)
  186. guild.members[member.user.id] = member
  187. self.sword.emit(.guildMemberUpdate, with: member)
  188. /// GUILD_ROLE_CREATE
  189. case .guildRoleCreate:
  190. let guildId = Snowflake(data["guild_id"])!
  191. guard let guild = self.sword.guilds[guildId] else {
  192. return
  193. }
  194. let role = Role(data["role"] as! [String: Any])
  195. guild.roles[role.id] = role
  196. self.sword.emit(.guildRoleCreate, with: (guild, role))
  197. /// GUILD_ROLE_DELETE
  198. case .guildRoleDelete:
  199. let guildId = Snowflake(data["guild_id"])!
  200. guard let guild = self.sword.guilds[guildId] else {
  201. return
  202. }
  203. let roleId = Snowflake(data["role_id"])!
  204. guard let role = guild.roles[roleId] else {
  205. return
  206. }
  207. guild.roles.removeValue(forKey: role.id)
  208. self.sword.emit(.guildRoleDelete, with: (guild, role))
  209. /// GUILD_ROLE_UPDATE
  210. case .guildRoleUpdate:
  211. let guildId = Snowflake(data["guild_id"])!
  212. guard let guild = self.sword.guilds[guildId] else {
  213. return
  214. }
  215. let role = Role(data["role"] as! [String: Any])
  216. guild.roles[role.id] = role
  217. self.sword.emit(.guildRoleUpdate, with: (guild, role))
  218. /// GUILD_UPDATE
  219. case .guildUpdate:
  220. let guildId = Snowflake(data["id"])!
  221. guard let guild = self.sword.guilds[guildId] else {
  222. return
  223. }
  224. guild.update(data)
  225. self.sword.emit(.guildUpdate, with: guild)
  226. /// MESSAGE_CREATE
  227. case .messageCreate:
  228. let msg = Message(self.sword, data)
  229. if let channel = msg.channel as? GuildText {
  230. channel.lastMessageId = msg.id
  231. }
  232. self.sword.emit(.messageCreate, with: msg)
  233. /// MESSAGE_DELETE
  234. case .messageDelete:
  235. let channelId = Snowflake(data["channel_id"])!
  236. guard let channel = self.sword.getChannel(for: channelId) else {
  237. return
  238. }
  239. let messageId = Snowflake(data["id"])!
  240. self.sword.emit(.messageDelete, with: (messageId, channel))
  241. /// MESSAGE_BULK_DELETE
  242. case .messageDeleteBulk:
  243. let channelId = Snowflake(data["channel_id"])!
  244. guard let channel = self.sword.getChannel(for: channelId) else {
  245. return
  246. }
  247. let messageIds = (data["ids"] as! [String]).map({ Snowflake($0)! })
  248. self.sword.emit(.messageDeleteBulk, with: (messageIds, channel))
  249. /// MESSAGE_REACTION_REMOVE_ALL
  250. case .messageReactionRemoveAll:
  251. let channelId = Snowflake(data["channel_id"])!
  252. guard let channel = self.sword.getChannel(for: channelId) else {
  253. return
  254. }
  255. let messageId = Snowflake(data["message_id"])!
  256. self.sword.emit(.messageReactionRemoveAll, with: (messageId, channel))
  257. /// MESSAGE_UPDATE
  258. case .messageUpdate:
  259. self.sword.emit(.messageUpdate, with: data)
  260. /// PRESENCE_UPDATE
  261. case .presenceUpdate:
  262. let userId = Snowflake((data["user"] as! [String: Any])["id"])!
  263. let presence = Presence(data)
  264. let guildID = Snowflake(data["guild_id"])!
  265. guard self.sword.options.willCacheAllMembers else {
  266. guard presence.status == .offline else { return }
  267. self.sword.guilds[guildID]?.members.removeValue(forKey: userId)
  268. return
  269. }
  270. self.sword.guilds[guildID]?.members[userId]?.presence = presence
  271. self.sword.emit(.presenceUpdate, with: (userId, presence))
  272. /// READY
  273. case .ready:
  274. self.sword.readyTimestamp = Date()
  275. self.sessionId = data["session_id"] as? String
  276. let guilds = data["guilds"] as! [[String: Any]]
  277. for guild in guilds {
  278. let guildID = Snowflake(guild["id"])!
  279. self.sword.unavailableGuilds[guildID] = UnavailableGuild(guild, self.id)
  280. }
  281. self.sword.shardsReady += 1
  282. self.sword.emit(.shardReady, with: self.id)
  283. if self.sword.shardsReady == self.sword.shardCount {
  284. self.sword.user = User(self.sword, data["user"] as! [String: Any])
  285. self.sword.emit(.ready, with: self.sword.user!)
  286. }
  287. /// MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE
  288. case .reactionAdd, .reactionRemove:
  289. let channelId = Snowflake(data["channel_id"])!
  290. guard let channel = self.sword.getChannel(for: channelId) else {
  291. return
  292. }
  293. let userID = Snowflake(data["user_id"])!
  294. let messageID = Snowflake(data["message_id"])!
  295. let emoji = Emoji(data["emoji"] as! [String: Any])
  296. self.sword.emit(event, with: (channel, userID, messageID, emoji))
  297. /// TYPING_START
  298. case .typingStart:
  299. #if !os(Linux)
  300. let timestamp = Date(timeIntervalSince1970: data["timestamp"] as! Double)
  301. #else
  302. let timestamp = Date(
  303. timeIntervalSince1970: Double(data["timestamp"] as! Int)
  304. )
  305. #endif
  306. let channelId = Snowflake(data["channel_id"])!
  307. guard let channel = self.sword.getChannel(for: channelId) else {
  308. return
  309. }
  310. let userId = Snowflake(data["user_id"])!
  311. self.sword.emit(.typingStart, with: (channel, userId, timestamp))
  312. /// USER_UPDATE
  313. case .userUpdate:
  314. self.sword.emit(.userUpdate, with: User(self.sword, data))
  315. /// VOICE_STATE_UPDATE
  316. case .voiceStateUpdate:
  317. let guildId = Snowflake(data["guild_id"])!
  318. guard let guild = self.sword.guilds[guildId] else {
  319. return
  320. }
  321. let channelId = Snowflake(data["channel_id"])
  322. let userId = Snowflake(data["user_id"])!
  323. if channelId != nil {
  324. let voiceState = VoiceState(data)
  325. guild.voiceStates[userId] = voiceState
  326. guild.members[userId]?.voiceState = voiceState
  327. self.sword.emit(.voiceChannelJoin, with: (userId, voiceState))
  328. }else {
  329. guild.voiceStates.removeValue(forKey: userId)
  330. guild.members[userId]?.voiceState = nil
  331. self.sword.emit(.voiceChannelLeave, with: userId)
  332. }
  333. self.sword.emit(.voiceStateUpdate, with: userId)
  334. case .voiceServerUpdate:
  335. return
  336. case .audioData:
  337. return
  338. case .connectionClose:
  339. return
  340. case .disconnect:
  341. return
  342. case .guildAvailable:
  343. return
  344. case .guildUnavailable:
  345. return
  346. case .payload:
  347. return
  348. case .resume:
  349. return
  350. case .resumed:
  351. return
  352. case .shardReady:
  353. return
  354. case .voiceChannelJoin:
  355. return
  356. case .voiceChannelLeave:
  357. return
  358. }
  359. }
  360. }