discordrb 3.3.0 → 3.4.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +126 -0
- data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +0 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
- data/.github/pull_request_template.md +37 -0
- data/.rubocop.yml +34 -37
- data/.travis.yml +5 -6
- data/CHANGELOG.md +472 -347
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +61 -79
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/discordrb-webhooks.gemspec +6 -6
- data/discordrb.gemspec +17 -17
- data/lib/discordrb.rb +73 -0
- data/lib/discordrb/allowed_mentions.rb +36 -0
- data/lib/discordrb/api.rb +40 -15
- data/lib/discordrb/api/channel.rb +57 -39
- data/lib/discordrb/api/invite.rb +3 -3
- data/lib/discordrb/api/server.rb +55 -50
- data/lib/discordrb/api/user.rb +8 -8
- data/lib/discordrb/api/webhook.rb +6 -6
- data/lib/discordrb/await.rb +0 -1
- data/lib/discordrb/bot.rb +164 -72
- data/lib/discordrb/cache.rb +4 -2
- data/lib/discordrb/colour_rgb.rb +43 -0
- data/lib/discordrb/commands/command_bot.rb +22 -6
- data/lib/discordrb/commands/container.rb +20 -23
- data/lib/discordrb/commands/parser.rb +18 -18
- data/lib/discordrb/commands/rate_limiter.rb +3 -2
- data/lib/discordrb/container.rb +77 -17
- data/lib/discordrb/data.rb +25 -4180
- data/lib/discordrb/data/activity.rb +264 -0
- data/lib/discordrb/data/application.rb +50 -0
- data/lib/discordrb/data/attachment.rb +56 -0
- data/lib/discordrb/data/audit_logs.rb +345 -0
- data/lib/discordrb/data/channel.rb +849 -0
- data/lib/discordrb/data/embed.rb +251 -0
- data/lib/discordrb/data/emoji.rb +82 -0
- data/lib/discordrb/data/integration.rb +83 -0
- data/lib/discordrb/data/invite.rb +137 -0
- data/lib/discordrb/data/member.rb +297 -0
- data/lib/discordrb/data/message.rb +334 -0
- data/lib/discordrb/data/overwrite.rb +102 -0
- data/lib/discordrb/data/profile.rb +91 -0
- data/lib/discordrb/data/reaction.rb +33 -0
- data/lib/discordrb/data/recipient.rb +34 -0
- data/lib/discordrb/data/role.rb +191 -0
- data/lib/discordrb/data/server.rb +1002 -0
- data/lib/discordrb/data/user.rb +204 -0
- data/lib/discordrb/data/voice_region.rb +45 -0
- data/lib/discordrb/data/voice_state.rb +41 -0
- data/lib/discordrb/data/webhook.rb +145 -0
- data/lib/discordrb/errors.rb +2 -1
- data/lib/discordrb/events/bans.rb +7 -5
- data/lib/discordrb/events/channels.rb +2 -0
- data/lib/discordrb/events/guilds.rb +16 -9
- data/lib/discordrb/events/invites.rb +125 -0
- data/lib/discordrb/events/members.rb +6 -2
- data/lib/discordrb/events/message.rb +69 -27
- data/lib/discordrb/events/presence.rb +14 -4
- data/lib/discordrb/events/raw.rb +1 -3
- data/lib/discordrb/events/reactions.rb +49 -3
- data/lib/discordrb/events/typing.rb +6 -4
- data/lib/discordrb/events/voice_server_update.rb +47 -0
- data/lib/discordrb/events/voice_state_update.rb +15 -10
- data/lib/discordrb/events/webhooks.rb +9 -6
- data/lib/discordrb/gateway.rb +72 -57
- data/lib/discordrb/id_object.rb +39 -0
- data/lib/discordrb/light/integrations.rb +1 -1
- data/lib/discordrb/light/light_bot.rb +1 -1
- data/lib/discordrb/logger.rb +4 -4
- data/lib/discordrb/paginator.rb +57 -0
- data/lib/discordrb/permissions.rb +103 -8
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +3 -3
- data/lib/discordrb/voice/network.rb +84 -43
- data/lib/discordrb/voice/sodium.rb +96 -0
- data/lib/discordrb/voice/voice_bot.rb +34 -26
- metadata +93 -55
data/lib/discordrb/cache.rb
CHANGED
@@ -134,6 +134,7 @@ module Discordrb
|
|
134
134
|
def pm_channel(id)
|
135
135
|
id = id.resolve_id
|
136
136
|
return @pm_channels[id] if @pm_channels[id]
|
137
|
+
|
137
138
|
debug("Creating pm channel with user id #{id}")
|
138
139
|
response = API::User.create_pm(token, id)
|
139
140
|
channel = Channel.new(JSON.parse(response), self)
|
@@ -187,7 +188,7 @@ module Discordrb
|
|
187
188
|
#
|
188
189
|
# * An {Invite} object
|
189
190
|
# * The code for an invite
|
190
|
-
# * A fully qualified invite URL (e.g. `https://
|
191
|
+
# * A fully qualified invite URL (e.g. `https://discord.com/invite/0A37aN7fasF7n83q`)
|
191
192
|
# * A short invite URL with protocol (e.g. `https://discord.gg/0A37aN7fasF7n83q`)
|
192
193
|
# * A short invite URL without protocol (e.g. `discord.gg/0A37aN7fasF7n83q`)
|
193
194
|
# @return [String] Only the code for the invite.
|
@@ -219,7 +220,7 @@ module Discordrb
|
|
219
220
|
return [channel(id)]
|
220
221
|
end
|
221
222
|
|
222
|
-
@servers.
|
223
|
+
@servers.each_value do |server|
|
223
224
|
server.channels.each do |channel|
|
224
225
|
results << channel if channel.name == channel_name && (server_name || server.name) == server.name && (!type || (channel.type == type))
|
225
226
|
end
|
@@ -248,6 +249,7 @@ module Discordrb
|
|
248
249
|
def find_user(username, discrim = nil)
|
249
250
|
users = @users.values.find_all { |e| e.username == username }
|
250
251
|
return users.find { |u| u.discrim == discrim } if discrim
|
252
|
+
|
251
253
|
users
|
252
254
|
end
|
253
255
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Discordrb
|
4
|
+
# A colour (red, green and blue values). Used for role colours. If you prefer the American spelling, the alias
|
5
|
+
# {ColorRGB} is also available.
|
6
|
+
class ColourRGB
|
7
|
+
# @return [Integer] the red part of this colour (0-255).
|
8
|
+
attr_reader :red
|
9
|
+
|
10
|
+
# @return [Integer] the green part of this colour (0-255).
|
11
|
+
attr_reader :green
|
12
|
+
|
13
|
+
# @return [Integer] the blue part of this colour (0-255).
|
14
|
+
attr_reader :blue
|
15
|
+
|
16
|
+
# @return [Integer] the colour's RGB values combined into one integer.
|
17
|
+
attr_reader :combined
|
18
|
+
alias_method :to_i, :combined
|
19
|
+
|
20
|
+
# Make a new colour from the combined value.
|
21
|
+
# @param combined [String, Integer] The colour's RGB values combined into one integer or a hexadecimal string
|
22
|
+
# @example Initialize a with a base 10 integer
|
23
|
+
# ColourRGB.new(7506394) #=> ColourRGB
|
24
|
+
# ColourRGB.new(0x7289da) #=> ColourRGB
|
25
|
+
# @example Initialize a with a hexadecimal string
|
26
|
+
# ColourRGB.new('7289da') #=> ColourRGB
|
27
|
+
def initialize(combined)
|
28
|
+
@combined = combined.is_a?(String) ? combined.to_i(16) : combined
|
29
|
+
@red = (@combined >> 16) & 0xFF
|
30
|
+
@green = (@combined >> 8) & 0xFF
|
31
|
+
@blue = @combined & 0xFF
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String] the colour as a hexadecimal.
|
35
|
+
def hex
|
36
|
+
@combined.to_s(16)
|
37
|
+
end
|
38
|
+
alias_method :hexadecimal, :hex
|
39
|
+
end
|
40
|
+
|
41
|
+
# Alias for the class {ColourRGB}
|
42
|
+
ColorRGB = ColourRGB
|
43
|
+
end
|
@@ -24,7 +24,7 @@ module Discordrb::Commands
|
|
24
24
|
|
25
25
|
# Creates a new CommandBot and logs in to Discord.
|
26
26
|
# @param attributes [Hash] The attributes to initialize the CommandBot with.
|
27
|
-
# @see
|
27
|
+
# @see Discordrb::Bot#initialize Discordrb::Bot#initialize for other attributes that should be used to create the underlying regular bot.
|
28
28
|
# @option attributes [String, Array<String>, #call] :prefix The prefix that should trigger this bot's commands. It
|
29
29
|
# can be:
|
30
30
|
#
|
@@ -39,7 +39,7 @@ module Discordrb::Commands
|
|
39
39
|
# complicated dynamic prefixes (e. g. based on server), or even something else entirely (suffixes, or most
|
40
40
|
# adventurous, infixes).
|
41
41
|
# @option attributes [true, false] :advanced_functionality Whether to enable advanced functionality (very powerful
|
42
|
-
# way to nest commands into chains, see https://github.com/
|
42
|
+
# way to nest commands into chains, see https://github.com/shardlab/discordrb/wiki/Commands#command-chain-syntax
|
43
43
|
# for info. Default is false.
|
44
44
|
# @option attributes [Symbol, Array<Symbol>, false] :help_command The name of the command that displays info for
|
45
45
|
# other commands. Use an array if you want to have aliases. Default is "help". If none should be created, use
|
@@ -83,7 +83,9 @@ module Discordrb::Commands
|
|
83
83
|
num_shards: attributes[:num_shards],
|
84
84
|
redact_token: attributes.key?(:redact_token) ? attributes[:redact_token] : true,
|
85
85
|
ignore_bots: attributes[:ignore_bots],
|
86
|
-
compress_mode: attributes[:compress_mode]
|
86
|
+
compress_mode: attributes[:compress_mode],
|
87
|
+
intents: attributes[:intents]
|
88
|
+
)
|
87
89
|
|
88
90
|
@prefix = attributes[:prefix]
|
89
91
|
@attributes = {
|
@@ -140,6 +142,7 @@ module Discordrb::Commands
|
|
140
142
|
}
|
141
143
|
|
142
144
|
return unless @attributes[:help_command]
|
145
|
+
|
143
146
|
command(@attributes[:help_command], max_args: 1, description: 'Shows a list of all the commands available or displays help for a specific command.', usage: 'help [command name]') do |event, command_name|
|
144
147
|
if command_name
|
145
148
|
command = @commands[command_name.to_sym]
|
@@ -148,6 +151,7 @@ module Discordrb::Commands
|
|
148
151
|
command_name = command.name
|
149
152
|
end
|
150
153
|
return "The command `#{command_name}` does not exist!" unless command
|
154
|
+
|
151
155
|
desc = command.attributes[:description] || '*No description available*'
|
152
156
|
usage = command.attributes[:usage]
|
153
157
|
parameters = command.attributes[:parameters]
|
@@ -206,15 +210,18 @@ module Discordrb::Commands
|
|
206
210
|
def execute_command(name, event, arguments, chained = false, check_permissions = true)
|
207
211
|
debug("Executing command #{name} with arguments #{arguments}")
|
208
212
|
return unless @commands
|
213
|
+
|
209
214
|
command = @commands[name]
|
210
215
|
command = command.aliased_command if command.is_a?(CommandAlias)
|
211
216
|
return unless !check_permissions || channels?(event.channel, @attributes[:channels]) ||
|
212
217
|
(command && !command.attributes[:channels].nil?)
|
218
|
+
|
213
219
|
unless command
|
214
220
|
event.respond @attributes[:command_doesnt_exist_message].gsub('%command%', name.to_s) if @attributes[:command_doesnt_exist_message]
|
215
221
|
return
|
216
222
|
end
|
217
223
|
return unless !check_permissions || channels?(event.channel, command.attributes[:channels])
|
224
|
+
|
218
225
|
arguments = arg_check(arguments, command.attributes[:arg_types], event.server) if check_permissions
|
219
226
|
if (check_permissions &&
|
220
227
|
permission?(event.author, command.attributes[:permission_level], event.server) &&
|
@@ -238,11 +245,13 @@ module Discordrb::Commands
|
|
238
245
|
# For example, `['1', '10..14']` with types `[Integer, Range]` would turn into `[1, 10..14]`.
|
239
246
|
def arg_check(args, types = nil, server = nil)
|
240
247
|
return args unless types
|
248
|
+
|
241
249
|
args.each_with_index.map do |arg, i|
|
242
250
|
next arg if types[i].nil? || types[i] == String
|
251
|
+
|
243
252
|
if types[i] == Integer
|
244
253
|
begin
|
245
|
-
Integer(arg)
|
254
|
+
Integer(arg, 10)
|
246
255
|
rescue ArgumentError
|
247
256
|
nil
|
248
257
|
end
|
@@ -304,7 +313,7 @@ module Discordrb::Commands
|
|
304
313
|
elsif types[i].respond_to?(:from_argument)
|
305
314
|
begin
|
306
315
|
types[i].from_argument arg
|
307
|
-
rescue
|
316
|
+
rescue StandardError
|
308
317
|
nil
|
309
318
|
end
|
310
319
|
else
|
@@ -319,6 +328,7 @@ module Discordrb::Commands
|
|
319
328
|
# @return [String, nil] the command's result, if there is any.
|
320
329
|
def simple_execute(chain, event)
|
321
330
|
return nil if chain.empty?
|
331
|
+
|
322
332
|
args = chain.split(' ')
|
323
333
|
execute_command(args[0].to_sym, event, args[1..-1])
|
324
334
|
end
|
@@ -369,6 +379,7 @@ module Discordrb::Commands
|
|
369
379
|
# @param channel [String, Integer, Channel] The channel name, integer ID, or `Channel` object to be added
|
370
380
|
def add_channel(channel)
|
371
381
|
return if @attributes[:channels].find { |c| channel.resolve_id == c.resolve_id }
|
382
|
+
|
372
383
|
@attributes[:channels] << channel
|
373
384
|
end
|
374
385
|
|
@@ -426,6 +437,7 @@ module Discordrb::Commands
|
|
426
437
|
|
427
438
|
def standard_prefix_trigger(message, prefix)
|
428
439
|
return nil unless message.start_with? prefix
|
440
|
+
|
429
441
|
message[prefix.length..-1]
|
430
442
|
end
|
431
443
|
|
@@ -437,11 +449,13 @@ module Discordrb::Commands
|
|
437
449
|
|
438
450
|
def required_roles?(member, required)
|
439
451
|
return true if member.webhook? || member.is_a?(Discordrb::Recipient) || required.nil? || required.empty?
|
452
|
+
|
440
453
|
required.is_a?(Array) ? check_multiple_roles(member, required) : member.role?(role)
|
441
454
|
end
|
442
455
|
|
443
456
|
def allowed_roles?(member, required)
|
444
457
|
return true if member.webhook? || member.is_a?(Discordrb::Recipient) || required.nil? || required.empty?
|
458
|
+
|
445
459
|
required.is_a?(Array) ? check_multiple_roles(member, required, false) : member.role?(role)
|
446
460
|
end
|
447
461
|
|
@@ -459,9 +473,11 @@ module Discordrb::Commands
|
|
459
473
|
|
460
474
|
def channels?(channel, channels)
|
461
475
|
return true if channels.nil? || channels.empty?
|
476
|
+
|
462
477
|
channels.any? do |c|
|
463
478
|
# if c is string, make sure to remove the "#" from channel names in case it was specified
|
464
479
|
return true if c.is_a?(String) && c.delete('#') == channel.name
|
480
|
+
|
465
481
|
c.resolve_id == channel.resolve_id
|
466
482
|
end
|
467
483
|
end
|
@@ -480,7 +496,7 @@ module Discordrb::Commands
|
|
480
496
|
else
|
481
497
|
event.respond result unless result.nil? || result.empty?
|
482
498
|
end
|
483
|
-
rescue => e
|
499
|
+
rescue StandardError => e
|
484
500
|
log_exception(e)
|
485
501
|
ensure
|
486
502
|
@event_threads.delete(t)
|
@@ -9,22 +9,25 @@ module Discordrb::Commands
|
|
9
9
|
module CommandContainer
|
10
10
|
include RateLimiter
|
11
11
|
|
12
|
-
# @return [Hash<Symbol, Command>] hash of command names and commands this container has.
|
12
|
+
# @return [Hash<Symbol, Command, CommandAlias>] hash of command names and commands this container has.
|
13
13
|
attr_reader :commands
|
14
14
|
|
15
15
|
# Adds a new command to the container.
|
16
|
-
# @param name [Symbol
|
16
|
+
# @param name [Symbol] The name of the command to add.
|
17
17
|
# @param attributes [Hash] The attributes to initialize the command with.
|
18
|
+
# @option attributes [Array<Symbol>] :aliases A list of additional names for this command. This in effect
|
19
|
+
# creates {CommandAlias} objects in the container ({#commands}) that refer to the newly created command.
|
20
|
+
# Additionally, the default help command will identify these command names as an alias where applicable.
|
18
21
|
# @option attributes [Integer] :permission_level The minimum permission level that can use this command, inclusive.
|
19
22
|
# See {CommandBot#set_user_permission} and {CommandBot#set_role_permission}.
|
20
23
|
# @option attributes [String, false] :permission_message Message to display when a user does not have sufficient
|
21
24
|
# permissions to execute a command. %name% in the message will be replaced with the name of the command. Disable
|
22
25
|
# the message by setting this option to false.
|
23
26
|
# @option attributes [Array<Symbol>] :required_permissions Discord action permissions (e.g. `:kick_members`) that
|
24
|
-
# should be required to use this command. See {Discordrb::Permissions::
|
25
|
-
# @option attributes [Array<Role>, Array
|
27
|
+
# should be required to use this command. See {Discordrb::Permissions::FLAGS} for a list.
|
28
|
+
# @option attributes [Array<Role>, Array<String, Integer>] :required_roles Roles, or their IDs, that user must have to use this command
|
26
29
|
# (user must have all of them).
|
27
|
-
# @option attributes [Array<Role>, Array
|
30
|
+
# @option attributes [Array<Role>, Array<String, Integer>] :allowed_roles Roles, or their IDs, that user should have to use this command
|
28
31
|
# (user should have at least one of them).
|
29
32
|
# @option attributes [Array<String, Integer, Channel>] :channels The channels that this command can be used on. An
|
30
33
|
# empty array indicates it can be used on any channel. Supersedes the command bot attribute.
|
@@ -55,26 +58,22 @@ module Discordrb::Commands
|
|
55
58
|
# @note `LocalJumpError`s are rescued from internally, giving bots the opportunity to use `return` or `break` in
|
56
59
|
# their blocks without propagating an exception.
|
57
60
|
# @return [Command] The command that was added.
|
58
|
-
# @deprecated The command name argument will no longer support arrays in the next release.
|
59
|
-
# Use the `aliases` attribute instead.
|
60
61
|
def command(name, attributes = {}, &block)
|
61
62
|
@commands ||= {}
|
62
|
-
if name.is_a? Array
|
63
|
-
new_command = nil
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
# TODO: Remove in 4.0
|
65
|
+
if name.is_a?(Array)
|
66
|
+
name, *aliases = name
|
67
|
+
attributes[:aliases] = aliases if attributes[:aliases].nil?
|
68
|
+
Discordrb::LOGGER.warn("While registering command #{name.inspect}")
|
69
|
+
Discordrb::LOGGER.warn('Arrays for command aliases is removed. Please use `aliases` argument instead.')
|
70
|
+
end
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
new_command.attributes[:aliases].each do |aliased_name|
|
74
|
-
@commands[aliased_name] = CommandAlias.new(aliased_name, new_command)
|
75
|
-
end
|
76
|
-
@commands[name] = new_command
|
72
|
+
new_command = Command.new(name, attributes, &block)
|
73
|
+
new_command.attributes[:aliases].each do |aliased_name|
|
74
|
+
@commands[aliased_name] = CommandAlias.new(aliased_name, new_command)
|
77
75
|
end
|
76
|
+
@commands[name] = new_command
|
78
77
|
end
|
79
78
|
|
80
79
|
# Removes a specific command from this container.
|
@@ -100,9 +99,7 @@ module Discordrb::Commands
|
|
100
99
|
container_modules = container.singleton_class.included_modules
|
101
100
|
|
102
101
|
# If the container is an EventContainer and we can include it, then do that
|
103
|
-
if container_modules.include?(Discordrb::EventContainer) && respond_to?(:include_events)
|
104
|
-
include_events(container)
|
105
|
-
end
|
102
|
+
include_events(container) if container_modules.include?(Discordrb::EventContainer) && respond_to?(:include_events)
|
106
103
|
|
107
104
|
if container_modules.include? Discordrb::Commands::CommandContainer
|
108
105
|
include_commands(container)
|
@@ -81,45 +81,43 @@ module Discordrb::Commands
|
|
81
81
|
# @return [String] the result of the execution.
|
82
82
|
def call(event, arguments, chained = false, check_permissions = true)
|
83
83
|
if arguments.length < @attributes[:min_args]
|
84
|
-
|
85
|
-
|
84
|
+
response = "Too few arguments for command `#{name}`!"
|
85
|
+
response += "\nUsage: `#{@attributes[:usage]}`" if @attributes[:usage]
|
86
|
+
event.respond(response)
|
86
87
|
return
|
87
88
|
end
|
88
89
|
if @attributes[:max_args] >= 0 && arguments.length > @attributes[:max_args]
|
89
|
-
|
90
|
-
|
90
|
+
response = "Too many arguments for command `#{name}`!"
|
91
|
+
response += "\nUsage: `#{@attributes[:usage]}`" if @attributes[:usage]
|
92
|
+
event.respond(response)
|
91
93
|
return
|
92
94
|
end
|
93
|
-
unless @attributes[:chain_usable]
|
94
|
-
|
95
|
-
|
96
|
-
return
|
97
|
-
end
|
95
|
+
unless @attributes[:chain_usable] && !chained
|
96
|
+
event.respond "Command `#{name}` cannot be used in a command chain!"
|
97
|
+
return
|
98
98
|
end
|
99
99
|
|
100
100
|
if check_permissions
|
101
101
|
rate_limited = event.bot.rate_limited?(@attributes[:bucket], event.author)
|
102
102
|
if @attributes[:bucket] && rate_limited
|
103
|
-
if @attributes[:rate_limit_message]
|
104
|
-
event.respond @attributes[:rate_limit_message].gsub('%time%', rate_limited.round(2).to_s)
|
105
|
-
end
|
103
|
+
event.respond @attributes[:rate_limit_message].gsub('%time%', rate_limited.round(2).to_s) if @attributes[:rate_limit_message]
|
106
104
|
return
|
107
105
|
end
|
108
106
|
end
|
109
107
|
|
110
108
|
result = @block.call(event, *arguments)
|
111
109
|
event.drain_into(result)
|
112
|
-
rescue LocalJumpError =>
|
113
|
-
result =
|
110
|
+
rescue LocalJumpError => e # occurs when breaking
|
111
|
+
result = e.exit_value
|
114
112
|
event.drain_into(result)
|
115
|
-
rescue =>
|
113
|
+
rescue StandardError => e # Something went wrong inside our @block!
|
116
114
|
rescue_value = @attributes[:rescue] || event.bot.attributes[:rescue]
|
117
115
|
if rescue_value
|
118
|
-
event.respond(rescue_value.gsub('%exception%',
|
119
|
-
rescue_value.call(event,
|
116
|
+
event.respond(rescue_value.gsub('%exception%', e.message)) if rescue_value.is_a?(String)
|
117
|
+
rescue_value.call(event, e) if rescue_value.respond_to?(:call)
|
120
118
|
end
|
121
119
|
|
122
|
-
raise
|
120
|
+
raise e
|
123
121
|
end
|
124
122
|
end
|
125
123
|
|
@@ -209,8 +207,10 @@ module Discordrb::Commands
|
|
209
207
|
result += char if b_level <= 0
|
210
208
|
|
211
209
|
next unless char == @attributes[:sub_chain_end] && !quoted
|
210
|
+
|
212
211
|
b_level -= 1
|
213
212
|
next unless b_level.zero?
|
213
|
+
|
214
214
|
nested = @chain[b_start + 1..index - 1]
|
215
215
|
subchain = CommandChain.new(nested, @bot, true)
|
216
216
|
result += subchain.execute(event)
|
@@ -35,7 +35,7 @@ module Discordrb::Commands
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# Performs a rate limiting request
|
38
|
-
# @param thing [
|
38
|
+
# @param thing [String, Integer, Symbol] The particular thing that should be rate-limited (usually a user/channel, but you can also choose arbitrary integers or symbols)
|
39
39
|
# @param rate_limit_time [Time] The time to base the rate limiting on, only useful for testing.
|
40
40
|
# @param increment [Integer] How much to increment the rate-limit counter. Default is 1.
|
41
41
|
# @return [Integer, false] the waiting time until the next request, in seconds, or false if the request succeeded
|
@@ -83,6 +83,7 @@ module Discordrb::Commands
|
|
83
83
|
def resolve_key(thing)
|
84
84
|
return thing.resolve_id if thing.respond_to?(:resolve_id) && !thing.is_a?(String)
|
85
85
|
return thing if thing.is_a?(Integer) || thing.is_a?(Symbol)
|
86
|
+
|
86
87
|
raise ArgumentError, "Cannot use a #{thing.class} as a rate limiting key!"
|
87
88
|
end
|
88
89
|
end
|
@@ -104,7 +105,7 @@ module Discordrb::Commands
|
|
104
105
|
|
105
106
|
# Performs a rate limit request.
|
106
107
|
# @param key [Symbol] Which bucket to perform the request for.
|
107
|
-
# @param thing [
|
108
|
+
# @param thing [String, Integer, Symbol] What should be rate-limited.
|
108
109
|
# @param increment (see Bucket#rate_limited?)
|
109
110
|
# @see Bucket#rate_limited?
|
110
111
|
# @return [Integer, false] How much time to wait or false if the request succeeded.
|
data/lib/discordrb/container.rb
CHANGED
@@ -5,6 +5,7 @@ require 'discordrb/events/typing'
|
|
5
5
|
require 'discordrb/events/lifetime'
|
6
6
|
require 'discordrb/events/presence'
|
7
7
|
require 'discordrb/events/voice_state_update'
|
8
|
+
require 'discordrb/events/voice_server_update'
|
8
9
|
require 'discordrb/events/channels'
|
9
10
|
require 'discordrb/events/members'
|
10
11
|
require 'discordrb/events/roles'
|
@@ -89,7 +90,7 @@ module Discordrb
|
|
89
90
|
|
90
91
|
# This **event** is raised when a message is edited in a channel.
|
91
92
|
# @param attributes [Hash] The event's attributes.
|
92
|
-
# @option attributes [
|
93
|
+
# @option attributes [String, Integer] :id Matches the ID of the message that was edited.
|
93
94
|
# @option attributes [String, Integer, Channel] :in Matches the channel the message was edited in.
|
94
95
|
# @yield The block is executed when the event is raised.
|
95
96
|
# @yieldparam event [MessageEditEvent] The event that was raised.
|
@@ -100,7 +101,7 @@ module Discordrb
|
|
100
101
|
|
101
102
|
# This **event** is raised when a message is deleted in a channel.
|
102
103
|
# @param attributes [Hash] The event's attributes.
|
103
|
-
# @option attributes [
|
104
|
+
# @option attributes [String, Integer] :id Matches the ID of the message that was deleted.
|
104
105
|
# @option attributes [String, Integer, Channel] :in Matches the channel the message was deleted in.
|
105
106
|
# @yield The block is executed when the event is raised.
|
106
107
|
# @yieldparam event [MessageDeleteEvent] The event that was raised.
|
@@ -109,9 +110,26 @@ module Discordrb
|
|
109
110
|
register_event(MessageDeleteEvent, attributes, block)
|
110
111
|
end
|
111
112
|
|
113
|
+
# This **event** is raised whenever a message is updated. Message updates can be triggered from
|
114
|
+
# a user editing their own message, or from Discord automatically attaching embeds to the
|
115
|
+
# user's message for URLs contained in the message's content. If you only want to listen
|
116
|
+
# for users editing their own messages, use the {message_edit} handler instead.
|
117
|
+
# @param attributes [Hash] The event's attributes.
|
118
|
+
# @option attributes [String, Integer] :id Matches the ID of the message that was updated.
|
119
|
+
# @option attributes [String, Integer, Channel] :in Matches the channel the message was updated in.
|
120
|
+
# @yield The block is executed when the event is raised.
|
121
|
+
# @yieldparam event [MessageUpdateEvent] The event that was raised.
|
122
|
+
# @return [MessageUpdateEventHandler] the event handler that was registered.
|
123
|
+
def message_update(attributes = {}, &block)
|
124
|
+
register_event(MessageUpdateEvent, attributes, block)
|
125
|
+
end
|
126
|
+
|
112
127
|
# This **event** is raised when somebody reacts to a message.
|
113
128
|
# @param attributes [Hash] The event's attributes.
|
114
|
-
# @option attributes [
|
129
|
+
# @option attributes [String, Integer] :emoji Matches the ID of the emoji that was reacted with, or its name.
|
130
|
+
# @option attributes [String, Integer, User] :from Matches the user who added the reaction.
|
131
|
+
# @option attributes [String, Integer, Message] :message Matches the message to which the reaction was added.
|
132
|
+
# @option attributes [String, Integer, Channel] :in Matches the channel the reaction was added in.
|
115
133
|
# @yield The block is executed when the event is raised.
|
116
134
|
# @yieldparam event [ReactionAddEvent] The event that was raised.
|
117
135
|
# @return [ReactionAddEventHandler] The event handler that was registered.
|
@@ -121,8 +139,11 @@ module Discordrb
|
|
121
139
|
|
122
140
|
# This **event** is raised when somebody removes a reaction from a message.
|
123
141
|
# @param attributes [Hash] The event's attributes.
|
124
|
-
# @option attributes [
|
142
|
+
# @option attributes [String, Integer] :emoji Matches the ID of the emoji that was removed from the reactions, or
|
125
143
|
# its name.
|
144
|
+
# @option attributes [String, Integer, User] :from Matches the user who removed the reaction.
|
145
|
+
# @option attributes [String, Integer, Message] :message Matches the message to which the reaction was removed.
|
146
|
+
# @option attributes [String, Integer, Channel] :in Matches the channel the reaction was removed in.
|
126
147
|
# @yield The block is executed when the event is raised.
|
127
148
|
# @yieldparam event [ReactionRemoveEvent] The event that was raised.
|
128
149
|
# @return [ReactionRemoveEventHandler] The event handler that was registered.
|
@@ -132,6 +153,9 @@ module Discordrb
|
|
132
153
|
|
133
154
|
# This **event** is raised when somebody removes all reactions from a message.
|
134
155
|
# @param attributes [Hash] The event's attributes.
|
156
|
+
# @option attributes [Hash] The event's attributes.
|
157
|
+
# @option attributes [String, Integer, Message] :message Matches the message to which the reactions were removed.
|
158
|
+
# @option attributes [String, Integer, Channel] :in Matches the channel the reactions were removed in.
|
135
159
|
# @yield The block is executed when the event is raised.
|
136
160
|
# @yieldparam event [ReactionRemoveAllEvent] The event that was raised.
|
137
161
|
# @return [ReactionRemoveAllEventHandler] The event handler that was registered.
|
@@ -143,6 +167,8 @@ module Discordrb
|
|
143
167
|
# @param attributes [Hash] The event's attributes.
|
144
168
|
# @option attributes [String, Integer, User] :from Matches the user whose status changed.
|
145
169
|
# @option attributes [:offline, :idle, :online] :status Matches the status the user has now.
|
170
|
+
# @option attributes [Hash<Symbol, Symbol>] :client_status Matches the current online status (`:online`, `:idle` or `:dnd`) of the user
|
171
|
+
# on various device types (`:desktop`, `:mobile`, or `:web`). The value will be `nil` when the user is offline or invisible
|
146
172
|
# @yield The block is executed when the event is raised.
|
147
173
|
# @yieldparam event [PresenceEvent] The event that was raised.
|
148
174
|
# @return [PresenceEventHandler] the event handler that was registered.
|
@@ -216,8 +242,8 @@ module Discordrb
|
|
216
242
|
# This **event** is raised when a recipient is added to a group channel.
|
217
243
|
# @param attributes [Hash] The event's attributes.
|
218
244
|
# @option attributes [String] :name Matches the name of the group channel that the recipient is added to.
|
219
|
-
# @option attributes [
|
220
|
-
# @option attributes [
|
245
|
+
# @option attributes [String, Integer] :owner_id Matches the ID of the group channel's owner.
|
246
|
+
# @option attributes [String, Integer] :id Matches the ID of the recipient added to the group channel.
|
221
247
|
# @yield The block is executed when the event is raised.
|
222
248
|
# @yieldparam event [ChannelRecipientAddEvent] The event that was raised.
|
223
249
|
# @return [ChannelRecipientAddHandler] the event handler that was registered.
|
@@ -228,8 +254,8 @@ module Discordrb
|
|
228
254
|
# This **event** is raised when a recipient is removed from a group channel.
|
229
255
|
# @param attributes [Hash] The event's attributes.
|
230
256
|
# @option attributes [String] :name Matches the name of the group channel that the recipient is added to.
|
231
|
-
# @option attributes [
|
232
|
-
# @option attributes [
|
257
|
+
# @option attributes [String, Integer] :owner_id Matches the ID of the group channel's owner.
|
258
|
+
# @option attributes [String, Integer] :id Matches the ID of the recipient removed from the group channel.
|
233
259
|
# @yield The block is executed when the event is raised.
|
234
260
|
# @yieldparam event [ChannelRecipientRemoveEvent] The event that was raised.
|
235
261
|
# @return [ChannelRecipientRemoveHandler] the event handler that was registered.
|
@@ -254,6 +280,16 @@ module Discordrb
|
|
254
280
|
register_event(VoiceStateUpdateEvent, attributes, block)
|
255
281
|
end
|
256
282
|
|
283
|
+
# This **event** is raised when first connecting to a server's voice channel.
|
284
|
+
# @param attributes [Hash] The event's attributes.
|
285
|
+
# @option attributes [String, Integer, User] :from Matches the server that the update is for.
|
286
|
+
# @yield The block is executed when the event is raised.
|
287
|
+
# @yieldparam event [VoiceServerUpdateEvent] The event that was raised.
|
288
|
+
# @return [VoiceServerUpdateEventHandler] The event handler that was registered.
|
289
|
+
def voice_server_update(attributes = {}, &block)
|
290
|
+
register_event(VoiceServerUpdateEvent, attributes, block)
|
291
|
+
end
|
292
|
+
|
257
293
|
# This **event** is raised when a new user joins a server.
|
258
294
|
# @param attributes [Hash] The event's attributes.
|
259
295
|
# @option attributes [String] :username Matches the username of the joined user.
|
@@ -352,7 +388,7 @@ module Discordrb
|
|
352
388
|
# This **event** is raised when an emoji is created.
|
353
389
|
# @param attributes [Hash] The event's attributes.
|
354
390
|
# @option attributes [String, Integer, Server] :server Matches the server.
|
355
|
-
# @option attributes [String, Integer] :id Matches the
|
391
|
+
# @option attributes [String, Integer] :id Matches the ID of the emoji.
|
356
392
|
# @option attributes [String] :name Matches the name of the emoji.
|
357
393
|
# @yield The block is executed when the event is raised.
|
358
394
|
# @yieldparam event [ServerEmojiCreateEvent] The event that was raised.
|
@@ -364,7 +400,7 @@ module Discordrb
|
|
364
400
|
# This **event** is raised when an emoji is deleted.
|
365
401
|
# @param attributes [Hash] The event's attributes.
|
366
402
|
# @option attributes [String, Integer, Server] :server Matches the server.
|
367
|
-
# @option attributes [String, Integer] :id Matches the
|
403
|
+
# @option attributes [String, Integer] :id Matches the ID of the emoji.
|
368
404
|
# @option attributes [String] :name Matches the name of the emoji.
|
369
405
|
# @yield The block is executed when the event is raised.
|
370
406
|
# @yieldparam event [ServerEmojiDeleteEvent] The event that was raised.
|
@@ -376,7 +412,7 @@ module Discordrb
|
|
376
412
|
# This **event** is raised when an emoji is updated.
|
377
413
|
# @param attributes [Hash] The event's attributes.
|
378
414
|
# @option attributes [String, Integer, Server] :server Matches the server.
|
379
|
-
# @option attributes [String, Integer] :id Matches the
|
415
|
+
# @option attributes [String, Integer] :id Matches the ID of the emoji.
|
380
416
|
# @option attributes [String] :name Matches the name of the emoji.
|
381
417
|
# @option attributes [String] :old_name Matches the name of the emoji before the update.
|
382
418
|
# @yield The block is executed when the event is raised.
|
@@ -398,7 +434,7 @@ module Discordrb
|
|
398
434
|
|
399
435
|
# This **event** is raised when a role is deleted.
|
400
436
|
# @param attributes [Hash] The event's attributes.
|
401
|
-
# @option attributes [
|
437
|
+
# @option attributes [String, Integer] :id Matches the role ID.
|
402
438
|
# @yield The block is executed when the event is raised.
|
403
439
|
# @yieldparam event [ServerRoleDeleteEvent] The event that was raised.
|
404
440
|
# @return [ServerRoleDeleteEventHandler] the event handler that was registered.
|
@@ -418,9 +454,9 @@ module Discordrb
|
|
418
454
|
|
419
455
|
# This **event** is raised when a webhook is updated.
|
420
456
|
# @param attributes [Hash] The event's attributes.
|
421
|
-
# @option attributes [String, Integer, Server] :server Matches the server by name,
|
422
|
-
# @option attributes [String, Integer, Channel] :channel Matches the channel by name,
|
423
|
-
# @option attribute [String, Integer, Webhook] :webhook Matches the webhook by name,
|
457
|
+
# @option attributes [String, Integer, Server] :server Matches the server by name, ID or instance.
|
458
|
+
# @option attributes [String, Integer, Channel] :channel Matches the channel by name, ID or instance.
|
459
|
+
# @option attribute [String, Integer, Webhook] :webhook Matches the webhook by name, ID or instance.
|
424
460
|
# @yield The block is executed when the event is raised.
|
425
461
|
# @yieldparam event [WebhookUpdateEvent] The event that was raised.
|
426
462
|
# @return [WebhookUpdateEventHandler] the event handler that was registered.
|
@@ -462,6 +498,30 @@ module Discordrb
|
|
462
498
|
alias_method :direct_message, :pm
|
463
499
|
alias_method :dm, :pm
|
464
500
|
|
501
|
+
# This **event** is raised when an invite is created.
|
502
|
+
# @param attributes [Hash] The event's attributes.
|
503
|
+
# @option attributes [String, Integer, User] :inviter Matches the user that created the invite.
|
504
|
+
# @option attributes [String, Integer, Channel] :channel Matches the channel the invite was created for.
|
505
|
+
# @option attributes [String, Integer, Server] :server Matches the server the invite was created for.
|
506
|
+
# @option attributes [true, false] :temporary Matches whether the invite is temporary or not.
|
507
|
+
# @yield The block is executed when the event is raised.
|
508
|
+
# @yieldparam event [InviteCreateEvent] The event that was raised.
|
509
|
+
# @return [InviteCreateEventHandler] The event handler that was registered.
|
510
|
+
def invite_create(attributes = {}, &block)
|
511
|
+
register_event(InviteCreateEvent, attributes, block)
|
512
|
+
end
|
513
|
+
|
514
|
+
# This **event** is raised when an invite is deleted.
|
515
|
+
# @param attributes [Hash] The event's attributes.
|
516
|
+
# @option attributes [String, Integer, Channel] :channel Matches the channel the deleted invite was for.
|
517
|
+
# @option attributes [String, Integer, Server] :server Matches the server the deleted invite was for.
|
518
|
+
# @yield The block is executed when the event is raised
|
519
|
+
# @yieldparam event [InviteDeleteEvent] The event that was raised.
|
520
|
+
# @return [InviteDeleteEventHandler] The event handler that was registered.
|
521
|
+
def invite_delete(attributes = {}, &block)
|
522
|
+
register_event(InviteDeleteEvent, attributes, block)
|
523
|
+
end
|
524
|
+
|
465
525
|
# This **event** is raised for every dispatch received over the gateway, whether supported by discordrb or not.
|
466
526
|
# @param attributes [Hash] The event's attributes.
|
467
527
|
# @option attributes [String, Symbol, Regexp] :type Matches the event type of the dispatch.
|
@@ -494,7 +554,7 @@ module Discordrb
|
|
494
554
|
|
495
555
|
# Removes all events from this event handler.
|
496
556
|
def clear!
|
497
|
-
@event_handlers
|
557
|
+
@event_handlers&.clear
|
498
558
|
end
|
499
559
|
|
500
560
|
# Adds an event handler to this container. Usually, it's more expressive to just use one of the shorthand adder
|
@@ -525,7 +585,7 @@ module Discordrb
|
|
525
585
|
# @param event_class [Class] The event type
|
526
586
|
# @return [Class] the handler type
|
527
587
|
def self.handler_class(event_class)
|
528
|
-
class_from_string(event_class
|
588
|
+
class_from_string("#{event_class}Handler")
|
529
589
|
end
|
530
590
|
|
531
591
|
# Returns the event class for a handler class type
|