1 /** 2 Implementations of Discord events. 3 */ 4 5 module dcord.gateway.events; 6 7 import std.algorithm, 8 std..string, 9 std.stdio, 10 std.datetime, 11 std.array, 12 std.conv; 13 14 import dcord.types, 15 dcord.gateway, 16 dcord.bot.command; 17 18 /** 19 A wrapper type for delegates that can be attached to an event, and run after 20 all listeners are executed. This can be used to ensure an event has fully passed 21 through all listeners, or to avoid having function/stack pointers within plugin 22 code (which allows for dynamically reloading the plugin). 23 */ 24 alias EventDeferredFunc = void delegate(); 25 26 /** 27 Base template for events from discord. Handles basic initilization, and some 28 deferred-function code. 29 */ 30 mixin template Event() { 31 @JSONIgnore 32 Client client; 33 34 @JSONIgnore 35 VibeJSON raw; 36 37 /** 38 Array of functions to be ran when this event has completed its pass through 39 the any listeners, and is ready to be destroyed. 40 */ 41 @JSONIgnore 42 EventDeferredFunc[] deferred; 43 44 this(Client c, VibeJSON obj) { 45 version (TIMING) { 46 auto sw = StopWatch(AutoStart.yes); 47 c.log.tracef("Starting create event for %s", this.toString); 48 } 49 50 this.raw = obj; 51 this.client = c; 52 this.deserializeFromJSON(obj); 53 54 version (TIMING) { 55 this.client.log.tracef("Create event for %s took %sms", this.toString, 56 sw.peek().to!("msecs", real)); 57 } 58 } 59 60 /** 61 Used to defer a functions execution until after this event has passed through 62 all listeners, and is ready to be destroyed. 63 */ 64 void defer(EventDeferredFunc f) { 65 this.deferred ~= f; 66 } 67 68 /** 69 Calls all deferred functions. 70 */ 71 void resolveDeferreds() { 72 foreach (ref f; this.deferred) { 73 f(); 74 } 75 } 76 } 77 78 /** 79 Sent when we initially connect, contains base state and connection information. 80 */ 81 class Ready { 82 mixin Event; 83 84 ushort ver; 85 string sessionID; 86 87 @JSONSource("user") 88 User me; 89 90 Guild[] guilds; 91 Channel[] dms; 92 } 93 94 /** 95 Sent when we've completed a reconnect/resume sequence. 96 */ 97 class Resumed { 98 mixin Event; 99 } 100 101 /** 102 Sent when a channel is created. 103 */ 104 class ChannelCreate { 105 mixin Event; 106 107 @JSONFlat 108 Channel channel; 109 } 110 111 /** 112 Sent when a channel is updated. 113 */ 114 class ChannelUpdate { 115 mixin Event; 116 117 @JSONFlat 118 Channel channel; 119 } 120 121 /** 122 Sent when a channel is deleted. 123 */ 124 class ChannelDelete { 125 mixin Event; 126 127 @JSONFlat 128 Channel channel; 129 } 130 131 /** 132 Sent when a guild is created (often on startup). 133 */ 134 class GuildCreate { 135 mixin Event; 136 137 @JSONFlat 138 Guild guild; 139 140 bool unavailable; 141 } 142 143 /** 144 Sent when a guild is updated 145 */ 146 class GuildUpdate { 147 mixin Event; 148 149 @JSONFlat 150 Guild guild; 151 } 152 153 /** 154 Sent when a guild is deleted (or becomes unavailable) 155 */ 156 class GuildDelete { 157 mixin Event; 158 159 Snowflake guildID; 160 bool unavailable; 161 } 162 163 /** 164 Sent when a guild ban is added. 165 */ 166 class GuildBanAdd { 167 mixin Event; 168 169 Snowflake guildID; 170 User user; 171 } 172 173 /** 174 Sent when a guild ban is removed. 175 */ 176 class GuildBanRemove { 177 mixin Event; 178 179 Snowflake guildID; 180 User user; 181 } 182 183 /** 184 Sent when a guilds emojis are updated. 185 */ 186 class GuildEmojisUpdate { 187 mixin Event; 188 } 189 190 /** 191 Sent when a guilds integrations are updated. 192 */ 193 class GuildIntegrationsUpdate { 194 mixin Event; 195 } 196 197 /** 198 Sent in response to RequestGuildMembers. 199 */ 200 201 class GuildMembersChunk { 202 mixin Event; 203 204 Snowflake guildID; 205 GuildMember[] members; 206 207 /+ 208 void load(JSONDecoder obj) { 209 obj.keySwitch!("guild_id", "members")( 210 { this.guildID = readSnowflake(obj); }, 211 { loadMany!GuildMember(this.client, obj, (m) { this.members ~= m; }); }, 212 ); 213 214 auto guild = this.client.state.guilds.get(this.guildID); 215 foreach (member; this.members) { 216 member.guild = guild; 217 } 218 } 219 +/ 220 } 221 222 /** 223 Sent when a member is added to a guild. 224 */ 225 class GuildMemberAdd { 226 mixin Event; 227 228 @JSONFlat 229 GuildMember member; 230 } 231 232 /** 233 Sent when a member is removed from a guild. 234 */ 235 class GuildMemberRemove { 236 mixin Event; 237 238 Snowflake guildID; 239 User user; 240 } 241 242 /** 243 Sent when a guild member is updated. 244 */ 245 class GuildMemberUpdate { 246 mixin Event; 247 248 @JSONFlat 249 GuildMember member; 250 } 251 252 /** 253 Sent when a guild role is created. 254 */ 255 class GuildRoleCreate { 256 mixin Event; 257 258 Snowflake guildID; 259 Role role; 260 } 261 262 /** 263 Sent when a guild role is updated. 264 */ 265 class GuildRoleUpdate { 266 mixin Event; 267 268 Snowflake guildID; 269 Role role; 270 } 271 272 /** 273 Sent when a guild role is deleted. 274 */ 275 class GuildRoleDelete { 276 mixin Event; 277 278 Snowflake guildID; 279 Role role; 280 } 281 282 /** 283 Sent when a message is created. 284 */ 285 class MessageCreate { 286 mixin Event; 287 288 @JSONFlat 289 Message message; 290 291 // Reference to the command event 292 @JSONIgnore 293 CommandEvent commandEvent; 294 } 295 296 /** 297 Sent when a message is updated. 298 */ 299 class MessageUpdate { 300 mixin Event; 301 302 @JSONFlat 303 Message message; 304 } 305 306 /** 307 Sent when a message is deleted. 308 */ 309 class MessageDelete { 310 mixin Event; 311 312 Snowflake id; 313 Snowflake channelID; 314 } 315 316 /** 317 Sent when a user's presence is updated. 318 */ 319 class PresenceUpdate { 320 mixin Event; 321 322 @JSONFlat 323 Presence presence; 324 } 325 326 /** 327 Sent when a user starts typing. 328 */ 329 class TypingStart { 330 mixin Event; 331 332 Snowflake channelID; 333 Snowflake userID; 334 ulong timestamp; 335 } 336 337 /** 338 Sent when this users settings are updated. 339 */ 340 class UserSettingsUpdate { 341 mixin Event; 342 } 343 344 /** 345 Sent when this user is updated. 346 */ 347 class UserUpdate { 348 mixin Event; 349 } 350 351 /** 352 Sent when a voice state is updated. 353 */ 354 class VoiceStateUpdate { 355 mixin Event; 356 357 @JSONFlat 358 VoiceState state; 359 } 360 361 /** 362 Sent when a voice server is updated. 363 */ 364 class VoiceServerUpdate { 365 mixin Event; 366 367 string token; 368 string endpoint; 369 Snowflake guildID; 370 } 371 372 /** 373 Sent when a channels pins are updated. 374 */ 375 class ChannelPinsUpdate { 376 mixin Event; 377 378 Snowflake channelID; 379 string lastPinTimestamp; 380 } 381 382 /** 383 Sent when a bulk set of messages gets deleted from a channel. 384 */ 385 class MessageDeleteBulk { 386 mixin Event; 387 388 Snowflake channelID; 389 Snowflake[] ids; 390 } 391 392 /** 393 Sent when a reaction is added. 394 */ 395 class MessageReactionAdd { 396 mixin Event; 397 398 Snowflake messageID; 399 }