1 /** 2 Implementations of Discord events. 3 */ 4 5 module dscord.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 dscord.types, 15 dscord.gateway, 16 dscord.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 User user; 170 } 171 172 /** 173 Sent when a guild ban is removed. 174 */ 175 class GuildBanRemove { 176 mixin Event; 177 178 User user; 179 } 180 181 /** 182 Sent when a guilds emojis are updated. 183 */ 184 class GuildEmojisUpdate { 185 mixin Event; 186 } 187 188 /** 189 Sent when a guilds integrations are updated. 190 */ 191 class GuildIntegrationsUpdate { 192 mixin Event; 193 } 194 195 /** 196 Sent in response to RequestGuildMembers. 197 */ 198 199 class GuildMembersChunk { 200 mixin Event; 201 202 Snowflake guildID; 203 GuildMember[] members; 204 205 /+ 206 void load(JSONDecoder obj) { 207 obj.keySwitch!("guild_id", "members")( 208 { this.guildID = readSnowflake(obj); }, 209 { loadMany!GuildMember(this.client, obj, (m) { this.members ~= m; }); }, 210 ); 211 212 auto guild = this.client.state.guilds.get(this.guildID); 213 foreach (member; this.members) { 214 member.guild = guild; 215 } 216 } 217 +/ 218 } 219 220 /** 221 Sent when a member is added to a guild. 222 */ 223 class GuildMemberAdd { 224 mixin Event; 225 226 @JSONFlat 227 GuildMember member; 228 } 229 230 /** 231 Sent when a member is removed from a guild. 232 */ 233 class GuildMemberRemove { 234 mixin Event; 235 236 Snowflake guildID; 237 User user; 238 } 239 240 /** 241 Sent when a guild member is updated. 242 */ 243 class GuildMemberUpdate { 244 mixin Event; 245 246 @JSONFlat 247 GuildMember member; 248 } 249 250 /** 251 Sent when a guild role is created. 252 */ 253 class GuildRoleCreate { 254 mixin Event; 255 256 Snowflake guildID; 257 Role role; 258 } 259 260 /** 261 Sent when a guild role is updated. 262 */ 263 class GuildRoleUpdate { 264 mixin Event; 265 266 Snowflake guildID; 267 Role role; 268 } 269 270 /** 271 Sent when a guild role is deleted. 272 */ 273 class GuildRoleDelete { 274 mixin Event; 275 276 Snowflake guildID; 277 Role role; 278 } 279 280 /** 281 Sent when a message is created. 282 */ 283 class MessageCreate { 284 mixin Event; 285 286 @JSONFlat 287 Message message; 288 289 // Reference to the command event 290 @JSONIgnore 291 CommandEvent commandEvent; 292 } 293 294 /** 295 Sent when a message is updated. 296 */ 297 class MessageUpdate { 298 mixin Event; 299 300 @JSONFlat 301 Message message; 302 } 303 304 /** 305 Sent when a message is deleted. 306 */ 307 class MessageDelete { 308 mixin Event; 309 310 Snowflake id; 311 Snowflake channelID; 312 } 313 314 /** 315 Sent when a users presence is updated. 316 */ 317 class PresenceUpdate { 318 mixin Event; 319 320 @JSONFlat 321 Presence presence; 322 } 323 324 /** 325 Sent when a user starts typing. 326 */ 327 class TypingStart { 328 mixin Event; 329 330 Snowflake channelID; 331 Snowflake userID; 332 ulong timestamp; 333 } 334 335 /** 336 Sent when this users settings are updated. 337 */ 338 class UserSettingsUpdate { 339 mixin Event; 340 } 341 342 /** 343 Sent when this user is updated. 344 */ 345 class UserUpdate { 346 mixin Event; 347 } 348 349 /** 350 Sent when a voice state is updated. 351 */ 352 class VoiceStateUpdate { 353 mixin Event; 354 355 @JSONFlat 356 VoiceState state; 357 } 358 359 /** 360 Sent when a voice server is updated. 361 */ 362 class VoiceServerUpdate { 363 mixin Event; 364 365 string token; 366 string endpoint; 367 Snowflake guildID; 368 } 369 370 /** 371 Sent when a channels pins are updated. 372 */ 373 class ChannelPinsUpdate { 374 mixin Event; 375 376 Snowflake channelID; 377 string lastPinTimestamp; 378 } 379 380 /** 381 Sent when a bulk set of messages gets deleted from a channel. 382 */ 383 class MessageDeleteBulk { 384 mixin Event; 385 386 Snowflake channelID; 387 Snowflake[] ids; 388 }