discordrb 3.1.1 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of discordrb might be problematic. Click here for more details.

@@ -6,6 +6,7 @@ require 'discordrb/commands/parser'
6
6
  require 'discordrb/commands/events'
7
7
  require 'discordrb/commands/container'
8
8
  require 'discordrb/commands/rate_limiter'
9
+ require 'time'
9
10
 
10
11
  # Specialized bot to run commands
11
12
 
@@ -66,11 +67,11 @@ module Discordrb::Commands
66
67
  # :advanced_functionality). Default is '"'.
67
68
  # @option attributes [String] :quote_end Character that should end a quoted string (see
68
69
  # :advanced_functionality). Default is '"'.
70
+ # @option attributes [true, false] :ignore_bots Whether the bot should ignore bot accounts or not. Default is false.
69
71
  def initialize(attributes = {})
70
72
  super(
71
73
  log_mode: attributes[:log_mode],
72
74
  token: attributes[:token],
73
- application_id: attributes[:application_id],
74
75
  client_id: attributes[:client_id],
75
76
  type: attributes[:type],
76
77
  name: attributes[:name],
@@ -79,7 +80,8 @@ module Discordrb::Commands
79
80
  parse_self: attributes[:parse_self],
80
81
  shard_id: attributes[:shard_id],
81
82
  num_shards: attributes[:num_shards],
82
- redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true)
83
+ redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true,
84
+ ignore_bots: attributes[:ignore_bots])
83
85
 
84
86
  @prefix = attributes[:prefix]
85
87
  @attributes = {
@@ -149,7 +151,9 @@ module Discordrb::Commands
149
151
  end
150
152
  result
151
153
  else
152
- available_commands = @commands.values.reject { |c| !c.attributes[:help_available] }
154
+ available_commands = @commands.values.reject do |c|
155
+ !c.attributes[:help_available] || !required_roles?(event.user, c.attributes[:required_roles]) || !required_permissions?(event.user, c.attributes[:required_permissions], event.channel)
156
+ end
153
157
  case available_commands.length
154
158
  when 0..5
155
159
  available_commands.reduce "**List of commands:**\n" do |memo, c|
@@ -160,8 +164,8 @@ module Discordrb::Commands
160
164
  memo + "`#{c.name}`, "
161
165
  end)[0..-3]
162
166
  else
163
- event.user.pm(available_commands.reduce("**List of commands:**\n") { |a, e| a + "`#{e.name}`, " })[0..-3]
164
- 'Sending list in PM!'
167
+ event.user.pm(available_commands.reduce("**List of commands:**\n") { |m, e| m + "`#{e.name}`, " }[0..-3])
168
+ event.channel.pm? ? '' : 'Sending list in PM!'
165
169
  end
166
170
  end
167
171
  end
@@ -187,6 +191,7 @@ module Discordrb::Commands
187
191
  return
188
192
  end
189
193
  return unless !check_permissions || channels?(event.channel, command.attributes[:channels])
194
+ arguments = arg_check(arguments, command.attributes[:arg_types], event.server) if check_permissions
190
195
  if (check_permissions &&
191
196
  permission?(event.author, command.attributes[:permission_level], event.server) &&
192
197
  required_permissions?(event.author, command.attributes[:required_permissions], event.channel) &&
@@ -204,6 +209,85 @@ module Discordrb::Commands
204
209
  raise
205
210
  end
206
211
 
212
+ # Transforms an array of string arguments based on types array.
213
+ # For example, `['1', '10..14']` with types `[Integer, Range]` would turn into `[1, 10..14]`.
214
+ def arg_check(args, types = nil, server = nil)
215
+ return args unless types
216
+ args.each_with_index.map do |arg, i|
217
+ next arg if types[i].nil? || types[i] == String
218
+ if types[i] == Integer
219
+ begin
220
+ Integer(arg)
221
+ rescue ArgumentError
222
+ nil
223
+ end
224
+ elsif types[i] == Float
225
+ begin
226
+ Float(arg)
227
+ rescue ArgumentError
228
+ nil
229
+ end
230
+ elsif types[i] == Time
231
+ begin
232
+ Time.parse arg
233
+ rescue ArgumentError
234
+ nil
235
+ end
236
+ elsif types[i] == TrueClass || types[i] == FalseClass
237
+ if arg.casecmp('true').zero? || arg.downcase.start_with?('y')
238
+ true
239
+ elsif arg.casecmp('false').zero? || arg.downcase.start_with?('n')
240
+ false
241
+ end
242
+ elsif types[i] == Symbol
243
+ arg.to_sym
244
+ elsif types[i] == Encoding
245
+ begin
246
+ Encoding.find arg
247
+ rescue ArgumentError
248
+ nil
249
+ end
250
+ elsif types[i] == Regexp
251
+ begin
252
+ Regexp.new arg
253
+ rescue ArgumentError
254
+ nil
255
+ end
256
+ elsif types[i] == Rational
257
+ begin
258
+ Rational(arg)
259
+ rescue ArgumentError
260
+ nil
261
+ end
262
+ elsif types[i] == Range
263
+ begin
264
+ if arg.include? '...'
265
+ Range.new(*arg.split('...').map(&:to_i), true)
266
+ elsif arg.include? '..'
267
+ Range.new(*arg.split('..').map(&:to_i))
268
+ end
269
+ rescue ArgumentError
270
+ nil
271
+ end
272
+ elsif types[i] == NilClass
273
+ nil
274
+ elsif [Discordrb::User, Discordrb::Role, Discordrb::Emoji].include? types[i]
275
+ result = parse_mention arg, server
276
+ result if result.instance_of? types[i]
277
+ elsif types[i] == Discordrb::Invite
278
+ resolve_invite_code arg
279
+ elsif types[i].respond_to?(:from_argument)
280
+ begin
281
+ types[i].from_argument arg
282
+ rescue
283
+ nil
284
+ end
285
+ else
286
+ raise ArgumentError, "#{type} doesn't implement from_argument"
287
+ end
288
+ end
289
+ end
290
+
207
291
  # Executes a command in a simple manner, without command chains or permissions.
208
292
  # @param chain [String] The command with its arguments separated by spaces.
209
293
  # @param event [CommandEvent] The event to pass to the command.
@@ -285,7 +369,7 @@ module Discordrb::Commands
285
369
  if @prefix.is_a? String
286
370
  standard_prefix_trigger(message.content, @prefix)
287
371
  elsif @prefix.is_a? Array
288
- @prefix.map { |e| standard_prefix_trigger(message.content, e) }.reduce { |a, e| a || e }
372
+ @prefix.map { |e| standard_prefix_trigger(message.content, e) }.reduce { |m, e| m || e }
289
373
  elsif @prefix.respond_to? :call
290
374
  @prefix.call(message)
291
375
  end
@@ -298,12 +382,12 @@ module Discordrb::Commands
298
382
 
299
383
  def required_permissions?(member, required, channel = nil)
300
384
  required.reduce(true) do |a, action|
301
- a && !member.webhook? && member.permission?(action, channel)
385
+ a && !member.webhook? && !member.is_a?(Discordrb::Recipient) && member.permission?(action, channel)
302
386
  end
303
387
  end
304
388
 
305
389
  def required_roles?(member, required)
306
- return (required.nil? || required.empty?) if member.webhook?
390
+ return (required.nil? || required.empty?) if member.webhook? || member.is_a?(Discordrb::Recipient)
307
391
  if required.is_a? Array
308
392
  required.all? do |role|
309
393
  member.role?(role)
@@ -319,7 +403,7 @@ module Discordrb::Commands
319
403
  if c.is_a? String
320
404
  # Make sure to remove the "#" from channel names in case it was specified
321
405
  c.delete('#') == channel.name
322
- elsif c.is_a? Fixnum
406
+ elsif c.is_a? Integer
323
407
  c == channel.id
324
408
  else
325
409
  c == channel
@@ -33,6 +33,9 @@ module Discordrb::Commands
33
33
  # command if the user asks for it.
34
34
  # @option attributes [String] :usage A short description of how this command should be used. Will be displayed in
35
35
  # the help command or if the user uses it wrong.
36
+ # @option attributes [Array<Class>] :arg_types An array of argument classes which will be used for type-checking.
37
+ # Hard-coded for some native classes, but can be used with any class that implements static
38
+ # method `from_argument`.
36
39
  # @option attributes [Integer] :min_args The minimum number of arguments this command should have. If a user
37
40
  # attempts to call the command with fewer arguments, the usage information will be displayed, if it exists.
38
41
  # @option attributes [Integer] :max_args The maximum number of arguments the command should have.
@@ -40,6 +40,9 @@ module Discordrb::Commands
40
40
  # Usage description (for help command and error messages)
41
41
  usage: attributes[:usage] || nil,
42
42
 
43
+ # Array of arguments (for type-checking)
44
+ arg_types: attributes[:arg_types] || nil,
45
+
43
46
  # Parameter list (for help command and error messages)
44
47
  parameters: attributes[:parameters] || nil,
45
48
 
@@ -123,39 +126,52 @@ module Discordrb::Commands
123
126
  b_level = 0
124
127
  result = ''
125
128
  quoted = false
126
- hacky_delim, hacky_space, hacky_prev = [0xe001, 0xe002, 0xe003].pack('U*').chars
129
+ escaped = false
130
+ hacky_delim, hacky_space, hacky_prev, hacky_newline = [0xe001, 0xe002, 0xe003, 0xe004].pack('U*').chars
127
131
 
128
132
  @chain.each_char.each_with_index do |char, index|
129
- # Quote begin
130
- if char == @attributes[:quote_start] && !quoted
131
- quoted = true
132
- next
133
- end
134
-
135
- # Quote end
136
- if char == @attributes[:quote_end] && quoted
137
- quoted = false
138
- next
139
- end
140
-
141
- if char == @attributes[:chain_delimiter] && quoted
142
- result += hacky_delim
133
+ # Escape character
134
+ if char == '\\' && !escaped
135
+ escaped = true
143
136
  next
144
- end
145
-
146
- if char == @attributes[:previous] && quoted
147
- result += hacky_prev
137
+ elsif escaped && b_level <= 0
138
+ result += char
139
+ escaped = false
148
140
  next
149
141
  end
150
142
 
151
- if char == ' ' && quoted
152
- result += hacky_space
153
- next
154
- end
143
+ if quoted
144
+ # Quote end
145
+ if char == @attributes[:quote_end]
146
+ quoted = false
147
+ next
148
+ end
155
149
 
156
- if char == @attributes[:sub_chain_start] && !quoted
157
- b_start = index if b_level.zero?
158
- b_level += 1
150
+ if b_level <= 0
151
+ case char
152
+ when @attributes[:chain_delimiter]
153
+ result += hacky_delim
154
+ next
155
+ when @attributes[:previous]
156
+ result += hacky_prev
157
+ next
158
+ when ' '
159
+ result += hacky_space
160
+ next
161
+ when "\n"
162
+ result += hacky_newline
163
+ next
164
+ end
165
+ end
166
+ else
167
+ case char
168
+ when @attributes[:quote_start] # Quote begin
169
+ quoted = true
170
+ next
171
+ when @attributes[:sub_chain_start]
172
+ b_start = index if b_level.zero?
173
+ b_level += 1
174
+ end
159
175
  end
160
176
 
161
177
  result += char if b_level <= 0
@@ -179,7 +195,7 @@ module Discordrb::Commands
179
195
  chain_to_split = @chain
180
196
 
181
197
  # Don't break if a command is called the same thing as the chain delimiter
182
- chain_to_split.slice!(1..-1) if chain_to_split.start_with?(@attributes[:chain_delimiter])
198
+ chain_to_split = chain_to_split.slice(1..-1) if chain_to_split.start_with?(@attributes[:chain_delimiter])
183
199
 
184
200
  first = true
185
201
  split_chain = chain_to_split.split(@attributes[:chain_delimiter])
@@ -205,9 +221,9 @@ module Discordrb::Commands
205
221
 
206
222
  arguments = arguments.split ' '
207
223
 
208
- # Replace the hacky spaces with actual spaces
224
+ # Replace the hacky spaces/newlines with actual ones
209
225
  arguments.map! do |elem|
210
- elem.gsub hacky_space, ' '
226
+ elem.gsub(hacky_space, ' ').gsub(hacky_newline, "\n")
211
227
  end
212
228
 
213
229
  # Finally execute the command
@@ -57,15 +57,13 @@ module Discordrb::Commands
57
57
  rate_limit_time ||= Time.now
58
58
 
59
59
  if @limit && (limit_hash[:count] + 1) > @limit
60
- if @time_span && rate_limit_time < (limit_hash[:set_time] + @time_span)
61
- # Second case: Count is over the limit and the time has not run out yet
62
- return (limit_hash[:set_time] + @time_span) - rate_limit_time
63
- else
64
- # Third case: Count is over the limit but the time has run out
65
- # Don't return anything here because there may still be delay-based limiting
66
- limit_hash[:set_time] = rate_limit_time
67
- limit_hash[:count] = 0
68
- end
60
+ # Second case: Count is over the limit and the time has not run out yet
61
+ return (limit_hash[:set_time] + @time_span) - rate_limit_time if @time_span && rate_limit_time < (limit_hash[:set_time] + @time_span)
62
+
63
+ # Third case: Count is over the limit but the time has run out
64
+ # Don't return anything here because there may still be delay-based limiting
65
+ limit_hash[:set_time] = rate_limit_time
66
+ limit_hash[:count] = 0
69
67
  end
70
68
 
71
69
  if @delay && rate_limit_time < (limit_hash[:last_time] + @delay)
@@ -11,6 +11,7 @@ require 'discordrb/events/roles'
11
11
  require 'discordrb/events/guilds'
12
12
  require 'discordrb/events/await'
13
13
  require 'discordrb/events/bans'
14
+ require 'discordrb/events/reactions'
14
15
 
15
16
  require 'discordrb/await'
16
17
 
@@ -31,7 +32,7 @@ module Discordrb
31
32
  # @option attributes [Boolean] :private Matches whether or not the channel is private.
32
33
  # @yield The block is executed when the event is raised.
33
34
  # @yieldparam event [MessageEvent] The event that was raised.
34
- # @return [MessageEventHandler] The event handler that was registered.
35
+ # @return [MessageEventHandler] the event handler that was registered.
35
36
  def message(attributes = {}, &block)
36
37
  register_event(MessageEvent, attributes, block)
37
38
  end
@@ -41,7 +42,7 @@ module Discordrb
41
42
  # @param attributes [Hash] Event attributes, none in this particular case
42
43
  # @yield The block is executed when the event is raised.
43
44
  # @yieldparam event [ReadyEvent] The event that was raised.
44
- # @return [ReadyEventHandler] The event handler that was registered.
45
+ # @return [ReadyEventHandler] the event handler that was registered.
45
46
  def ready(attributes = {}, &block)
46
47
  register_event(ReadyEvent, attributes, block)
47
48
  end
@@ -51,7 +52,7 @@ module Discordrb
51
52
  # @param attributes [Hash] Event attributes, none in this particular case
52
53
  # @yield The block is executed when the event is raised.
53
54
  # @yieldparam event [DisconnectEvent] The event that was raised.
54
- # @return [DisconnectEventHandler] The event handler that was registered.
55
+ # @return [DisconnectEventHandler] the event handler that was registered.
55
56
  def disconnected(attributes = {}, &block)
56
57
  register_event(DisconnectEvent, attributes, block)
57
58
  end
@@ -66,7 +67,7 @@ module Discordrb
66
67
  # @param attributes [Hash] Event attributes, none in this particular case
67
68
  # @yield The block is executed when the event is raised.
68
69
  # @yieldparam event [HeartbeatEvent] The event that was raised.
69
- # @return [HeartbeatEventHandler] The event handler that was registered.
70
+ # @return [HeartbeatEventHandler] the event handler that was registered.
70
71
  def heartbeat(attributes = {}, &block)
71
72
  register_event(HeartbeatEvent, attributes, block)
72
73
  end
@@ -81,7 +82,7 @@ module Discordrb
81
82
  # @option attributes [Time] :before Matches a time before the time the typing started.
82
83
  # @yield The block is executed when the event is raised.
83
84
  # @yieldparam event [TypingEvent] The event that was raised.
84
- # @return [TypingEventHandler] The event handler that was registered.
85
+ # @return [TypingEventHandler] the event handler that was registered.
85
86
  def typing(attributes = {}, &block)
86
87
  register_event(TypingEvent, attributes, block)
87
88
  end
@@ -92,7 +93,7 @@ module Discordrb
92
93
  # @option attributes [String, Integer, Channel] :in Matches the channel the message was edited in.
93
94
  # @yield The block is executed when the event is raised.
94
95
  # @yieldparam event [MessageEditEvent] The event that was raised.
95
- # @return [MessageEditEventHandler] The event handler that was registered.
96
+ # @return [MessageEditEventHandler] the event handler that was registered.
96
97
  def message_edit(attributes = {}, &block)
97
98
  register_event(MessageEditEvent, attributes, block)
98
99
  end
@@ -103,18 +104,48 @@ module Discordrb
103
104
  # @option attributes [String, Integer, Channel] :in Matches the channel the message was deleted in.
104
105
  # @yield The block is executed when the event is raised.
105
106
  # @yieldparam event [MessageDeleteEvent] The event that was raised.
106
- # @return [MessageDeleteEventHandler] The event handler that was registered.
107
+ # @return [MessageDeleteEventHandler] the event handler that was registered.
107
108
  def message_delete(attributes = {}, &block)
108
109
  register_event(MessageDeleteEvent, attributes, block)
109
110
  end
110
111
 
112
+ # This **event** is raised when somebody reacts to a message.
113
+ # @param attributes [Hash] The event's attributes.
114
+ # @option attributes [Integer, String] :emoji Matches the ID of the emoji that was reacted with, or its name.
115
+ # @yield The block is executed when the event is raised.
116
+ # @yieldparam event [ReactionAddEvent] The event that was raised.
117
+ # @return [ReactionAddEventHandler] The event handler that was registered.
118
+ def reaction_add(attributes = {}, &block)
119
+ register_event(ReactionAddEvent, attributes, block)
120
+ end
121
+
122
+ # This **event** is raised when somebody removes a reaction from a message.
123
+ # @param attributes [Hash] The event's attributes.
124
+ # @option attributes [Integer, String] :emoji Matches the ID of the emoji that was removed from the reactions, or
125
+ # its name.
126
+ # @yield The block is executed when the event is raised.
127
+ # @yieldparam event [ReactionRemoveEvent] The event that was raised.
128
+ # @return [ReactionRemoveEventHandler] The event handler that was registered.
129
+ def reaction_remove(attributes = {}, &block)
130
+ register_event(ReactionRemoveEvent, attributes, block)
131
+ end
132
+
133
+ # This **event** is raised when somebody removes all reactions from a message.
134
+ # @param attributes [Hash] The event's attributes.
135
+ # @yield The block is executed when the event is raised.
136
+ # @yieldparam event [ReactionRemoveAllEvent] The event that was raised.
137
+ # @return [ReactionRemoveAllEventHandler] The event handler that was registered.
138
+ def reaction_remove_all(attributes = {}, &block)
139
+ register_event(ReactionRemoveAllEvent, attributes, block)
140
+ end
141
+
111
142
  # This **event** is raised when a user's status (online/offline/idle) changes.
112
143
  # @param attributes [Hash] The event's attributes.
113
144
  # @option attributes [String, Integer, User] :from Matches the user whose status changed.
114
145
  # @option attributes [:offline, :idle, :online] :status Matches the status the user has now.
115
146
  # @yield The block is executed when the event is raised.
116
147
  # @yieldparam event [PresenceEvent] The event that was raised.
117
- # @return [PresenceEventHandler] The event handler that was registered.
148
+ # @return [PresenceEventHandler] the event handler that was registered.
118
149
  def presence(attributes = {}, &block)
119
150
  register_event(PresenceEvent, attributes, block)
120
151
  end
@@ -126,7 +157,7 @@ module Discordrb
126
157
  # @option attributes [Integer] :type Matches the type of game object (0 game, 1 Twitch stream)
127
158
  # @yield The block is executed when the event is raised.
128
159
  # @yieldparam event [PlayingEvent] The event that was raised.
129
- # @return [PlayingEventHandler] The event handler that was registered.
160
+ # @return [PlayingEventHandler] the event handler that was registered.
130
161
  def playing(attributes = {}, &block)
131
162
  register_event(PlayingEvent, attributes, block)
132
163
  end
@@ -144,7 +175,7 @@ module Discordrb
144
175
  # @option attributes [Boolean] :private Matches whether or not the channel is private.
145
176
  # @yield The block is executed when the event is raised.
146
177
  # @yieldparam event [MentionEvent] The event that was raised.
147
- # @return [MentionEventHandler] The event handler that was registered.
178
+ # @return [MentionEventHandler] the event handler that was registered.
148
179
  def mention(attributes = {}, &block)
149
180
  register_event(MentionEvent, attributes, block)
150
181
  end
@@ -155,7 +186,7 @@ module Discordrb
155
186
  # @option attributes [String] :name Matches the name of the created channel.
156
187
  # @yield The block is executed when the event is raised.
157
188
  # @yieldparam event [ChannelCreateEvent] The event that was raised.
158
- # @return [ChannelCreateEventHandler] The event handler that was registered.
189
+ # @return [ChannelCreateEventHandler] the event handler that was registered.
159
190
  def channel_create(attributes = {}, &block)
160
191
  register_event(ChannelCreateEvent, attributes, block)
161
192
  end
@@ -166,7 +197,7 @@ module Discordrb
166
197
  # @option attributes [String] :name Matches the new name of the channel.
167
198
  # @yield The block is executed when the event is raised.
168
199
  # @yieldparam event [ChannelUpdateEvent] The event that was raised.
169
- # @return [ChannelUpdateEventHandler] The event handler that was registered.
200
+ # @return [ChannelUpdateEventHandler] the event handler that was registered.
170
201
  def channel_update(attributes = {}, &block)
171
202
  register_event(ChannelUpdateEvent, attributes, block)
172
203
  end
@@ -177,7 +208,7 @@ module Discordrb
177
208
  # @option attributes [String] :name Matches the name of the deleted channel.
178
209
  # @yield The block is executed when the event is raised.
179
210
  # @yieldparam event [ChannelDeleteEvent] The event that was raised.
180
- # @return [ChannelDeleteEventHandler] The event handler that was registered.
211
+ # @return [ChannelDeleteEventHandler] the event handler that was registered.
181
212
  def channel_delete(attributes = {}, &block)
182
213
  register_event(ChannelDeleteEvent, attributes, block)
183
214
  end
@@ -189,7 +220,7 @@ module Discordrb
189
220
  # @option attributes [#resolve_id] :id Matches the id of the recipient added to the group channel.
190
221
  # @yield The block is executed when the event is raised.
191
222
  # @yieldparam event [ChannelRecipientAddEvent] The event that was raised.
192
- # @return [ChannelRecipientAddHandler] The event handler that was registered.
223
+ # @return [ChannelRecipientAddHandler] the event handler that was registered.
193
224
  def channel_recipient_add(attributes = {}, &block)
194
225
  register_event(ChannelRecipientAddEvent, attributes, block)
195
226
  end
@@ -201,7 +232,7 @@ module Discordrb
201
232
  # @option attributes [#resolve_id] :id Matches the id of the recipient removed from the group channel.
202
233
  # @yield The block is executed when the event is raised.
203
234
  # @yieldparam event [ChannelRecipientRemoveEvent] The event that was raised.
204
- # @return [ChannelRecipientRemoveHandler] The event handler that was registered.
235
+ # @return [ChannelRecipientRemoveHandler] the event handler that was registered.
205
236
  def channel_recipient_remove(attributes = {}, &block)
206
237
  register_event(ChannelRecipientRemoveEvent, attributes, block)
207
238
  end
@@ -210,13 +241,14 @@ module Discordrb
210
241
  # @param attributes [Hash] The event's attributes.
211
242
  # @option attributes [String, Integer, User] :from Matches the user that sent the message.
212
243
  # @option attributes [String, Integer, Channel] :channel Matches the voice channel the user has joined.
244
+ # @option attributes [String, Integer, Channel] :old_channel Matches the voice channel the user was in previously.
213
245
  # @option attributes [true, false] :mute Matches whether or not the user is muted server-wide.
214
246
  # @option attributes [true, false] :deaf Matches whether or not the user is deafened server-wide.
215
247
  # @option attributes [true, false] :self_mute Matches whether or not the user is muted by the bot.
216
248
  # @option attributes [true, false] :self_deaf Matches whether or not the user is deafened by the bot.
217
249
  # @yield The block is executed when the event is raised.
218
250
  # @yieldparam event [VoiceStateUpdateEvent] The event that was raised.
219
- # @return [VoiceStateUpdateEventHandler] The event handler that was registered.
251
+ # @return [VoiceStateUpdateEventHandler] the event handler that was registered.
220
252
  def voice_state_update(attributes = {}, &block)
221
253
  register_event(VoiceStateUpdateEvent, attributes, block)
222
254
  end
@@ -226,7 +258,7 @@ module Discordrb
226
258
  # @option attributes [String] :username Matches the username of the joined user.
227
259
  # @yield The block is executed when the event is raised.
228
260
  # @yieldparam event [ServerMemberAddEvent] The event that was raised.
229
- # @return [ServerMemberAddEventHandler] The event handler that was registered.
261
+ # @return [ServerMemberAddEventHandler] the event handler that was registered.
230
262
  def member_join(attributes = {}, &block)
231
263
  register_event(ServerMemberAddEvent, attributes, block)
232
264
  end
@@ -236,7 +268,7 @@ module Discordrb
236
268
  # @option attributes [String] :username Matches the username of the updated user.
237
269
  # @yield The block is executed when the event is raised.
238
270
  # @yieldparam event [ServerMemberUpdateEvent] The event that was raised.
239
- # @return [ServerMemberUpdateEventHandler] The event handler that was registered.
271
+ # @return [ServerMemberUpdateEventHandler] the event handler that was registered.
240
272
  def member_update(attributes = {}, &block)
241
273
  register_event(ServerMemberUpdateEvent, attributes, block)
242
274
  end
@@ -246,7 +278,7 @@ module Discordrb
246
278
  # @option attributes [String] :username Matches the username of the member.
247
279
  # @yield The block is executed when the event is raised.
248
280
  # @yieldparam event [ServerMemberDeleteEvent] The event that was raised.
249
- # @return [ServerMemberDeleteEventHandler] The event handler that was registered.
281
+ # @return [ServerMemberDeleteEventHandler] the event handler that was registered.
250
282
  def member_leave(attributes = {}, &block)
251
283
  register_event(ServerMemberDeleteEvent, attributes, block)
252
284
  end
@@ -257,7 +289,7 @@ module Discordrb
257
289
  # @option attributes [String, Integer, Server] :server Matches the server from which the user was banned.
258
290
  # @yield The block is executed when the event is raised.
259
291
  # @yieldparam event [UserBanEvent] The event that was raised.
260
- # @return [UserBanEventHandler] The event handler that was registered.
292
+ # @return [UserBanEventHandler] the event handler that was registered.
261
293
  def user_ban(attributes = {}, &block)
262
294
  register_event(UserBanEvent, attributes, block)
263
295
  end
@@ -268,7 +300,7 @@ module Discordrb
268
300
  # @option attributes [String, Integer, Server] :server Matches the server from which the user was unbanned.
269
301
  # @yield The block is executed when the event is raised.
270
302
  # @yieldparam event [UserUnbanEvent] The event that was raised.
271
- # @return [UserUnbanEventHandler] The event handler that was registered.
303
+ # @return [UserUnbanEventHandler] the event handler that was registered.
272
304
  def user_unban(attributes = {}, &block)
273
305
  register_event(UserUnbanEvent, attributes, block)
274
306
  end
@@ -280,7 +312,7 @@ module Discordrb
280
312
  # @option attributes [String, Integer, Server] :server Matches the server that was created.
281
313
  # @yield The block is executed when the event is raised.
282
314
  # @yieldparam event [ServerCreateEvent] The event that was raised.
283
- # @return [ServerCreateEventHandler] The event handler that was registered.
315
+ # @return [ServerCreateEventHandler] the event handler that was registered.
284
316
  def server_create(attributes = {}, &block)
285
317
  register_event(ServerCreateEvent, attributes, block)
286
318
  end
@@ -290,7 +322,7 @@ module Discordrb
290
322
  # @option attributes [String, Integer, Server] :server Matches the server that was updated.
291
323
  # @yield The block is executed when the event is raised.
292
324
  # @yieldparam event [ServerUpdateEvent] The event that was raised.
293
- # @return [ServerUpdateEventHandler] The event handler that was registered.
325
+ # @return [ServerUpdateEventHandler] the event handler that was registered.
294
326
  def server_update(attributes = {}, &block)
295
327
  register_event(ServerUpdateEvent, attributes, block)
296
328
  end
@@ -301,11 +333,58 @@ module Discordrb
301
333
  # @option attributes [String, Integer, Server] :server Matches the server that was deleted.
302
334
  # @yield The block is executed when the event is raised.
303
335
  # @yieldparam event [ServerDeleteEvent] The event that was raised.
304
- # @return [ServerDeleteEventHandler] The event handler that was registered.
336
+ # @return [ServerDeleteEventHandler] the event handler that was registered.
305
337
  def server_delete(attributes = {}, &block)
306
338
  register_event(ServerDeleteEvent, attributes, block)
307
339
  end
308
340
 
341
+ # This **event** is raised when an emoji or collection of emojis is created/deleted/updated.
342
+ # @param attributes [Hash] The event's attributes.
343
+ # @option attributes [String, Integer, Server] :server Matches the server.
344
+ # @yield The block is executed when the event is raised.
345
+ # @yieldparam event [ServerEmojiChangeEvent] The event that was raised.
346
+ # @return [ServerEmojiChangeEventHandler] the event handler that was registered.
347
+ def server_emoji(attributes = {}, &block)
348
+ register_event(ServerEmojiChangeEvent, attributes, block)
349
+ end
350
+
351
+ # This **event** is raised when an emoji is created.
352
+ # @param attributes [Hash] The event's attributes.
353
+ # @option attributes [String, Integer, Server] :server Matches the server.
354
+ # @option attributes [String, Integer] :id Matches the id of the emoji.
355
+ # @option attributes [String] :name Matches the name of the emoji.
356
+ # @yield The block is executed when the event is raised.
357
+ # @yieldparam event [ServerEmojiCreateEvent] The event that was raised.
358
+ # @return [ServerEmojiCreateEventHandler] the event handler that was registered.
359
+ def server_emoji_create(attributes = {}, &block)
360
+ register_event(ServerEmojiCreateEvent, attributes, block)
361
+ end
362
+
363
+ # This **event** is raised when an emoji is deleted.
364
+ # @param attributes [Hash] The event's attributes.
365
+ # @option attributes [String, Integer, Server] :server Matches the server.
366
+ # @option attributes [String, Integer] :id Matches the id of the emoji.
367
+ # @option attributes [String] :name Matches the name of the emoji.
368
+ # @yield The block is executed when the event is raised.
369
+ # @yieldparam event [ServerEmojiDeleteEvent] The event that was raised.
370
+ # @return [ServerEmojiDeleteEventHandler] the event handler that was registered.
371
+ def server_emoji_delete(attributes = {}, &block)
372
+ register_event(ServerEmojiDeleteEvent, attributes, block)
373
+ end
374
+
375
+ # This **event** is raised when an emoji is updated.
376
+ # @param attributes [Hash] The event's attributes.
377
+ # @option attributes [String, Integer, Server] :server Matches the server.
378
+ # @option attributes [String, Integer] :id Matches the id of the emoji.
379
+ # @option attributes [String] :name Matches the name of the emoji.
380
+ # @option attributes [String] :old_name Matches the name of the emoji before the update.
381
+ # @yield The block is executed when the event is raised.
382
+ # @yieldparam event [ServerEmojiUpdateEvent] The event that was raised.
383
+ # @return [ServerEmojiUpdateEventHandler] the event handler that was registered.
384
+ def server_emoji_update(attributes = {}, &block)
385
+ register_event(ServerEmojiUpdateEvent, attributes, block)
386
+ end
387
+
309
388
  # This **event** is raised when an {Await} is triggered. It provides an easy way to execute code
310
389
  # on an await without having to rely on the await's block.
311
390
  # @param attributes [Hash] The event's attributes.
@@ -313,7 +392,7 @@ module Discordrb
313
392
  # @option attributes [Class] :type Exactly matches the event's type.
314
393
  # @yield The block is executed when the event is raised.
315
394
  # @yieldparam event [AwaitEvent] The event that was raised.
316
- # @return [AwaitEventHandler] The event handler that was registered.
395
+ # @return [AwaitEventHandler] the event handler that was registered.
317
396
  def await(attributes = {}, &block)
318
397
  register_event(AwaitEvent, attributes, block)
319
398
  end
@@ -331,7 +410,7 @@ module Discordrb
331
410
  # @option attributes [Boolean] :private Matches whether or not the channel is private.
332
411
  # @yield The block is executed when the event is raised.
333
412
  # @yieldparam event [PrivateMessageEvent] The event that was raised.
334
- # @return [PrivateMessageEventHandler] The event handler that was registered.
413
+ # @return [PrivateMessageEventHandler] the event handler that was registered.
335
414
  def pm(attributes = {}, &block)
336
415
  register_event(PrivateMessageEvent, attributes, block)
337
416
  end
@@ -340,6 +419,27 @@ module Discordrb
340
419
  alias_method :direct_message, :pm
341
420
  alias_method :dm, :pm
342
421
 
422
+ # This **event** is raised for every dispatch received over the gateway, whether supported by discordrb or not.
423
+ # @param attributes [Hash] The event's attributes.
424
+ # @option attributes [String, Symbol, Regexp] :type Matches the event type of the dispatch.
425
+ # @yield The block is executed when the event is raised.
426
+ # @yieldparam event [RawEvent] The event that was raised.
427
+ # @return [RawEventHandler] The event handler that was registered.
428
+ def raw(attributes = {}, &block)
429
+ register_event(RawEvent, attributes, block)
430
+ end
431
+
432
+ # This **event** is raised for a dispatch received over the gateway that is not currently handled otherwise by
433
+ # discordrb.
434
+ # @param attributes [Hash] The event's attributes.
435
+ # @option attributes [String, Symbol, Regexp] :type Matches the event type of the dispatch.
436
+ # @yield The block is executed when the event is raised.
437
+ # @yieldparam event [UnknownEvent] The event that was raised.
438
+ # @return [UnknownEventHandler] The event handler that was registered.
439
+ def unknown(attributes = {}, &block)
440
+ register_event(UnknownEvent, attributes, block)
441
+ end
442
+
343
443
  # Removes an event handler from this container. If you're looking for a way to do temporary events, I recommend
344
444
  # {Await}s instead of this.
345
445
  # @param handler [Discordrb::Events::EventHandler] The handler to remove.