discorb 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/build_version.yml +1 -1
- data/.github/workflows/lint-push.yml +4 -2
- data/.rubocop.yml +6 -2
- data/Changelog.md +27 -0
- data/Rakefile +6 -0
- data/docs/events.md +71 -5
- data/docs/faq.md +8 -8
- data/examples/simple/rolepanel.rb +1 -1
- data/examples/simple/shard.rb +17 -0
- data/lib/discorb/allowed_mentions.rb +7 -0
- data/lib/discorb/app_command/command.rb +64 -2
- data/lib/discorb/app_command/handler.rb +1 -1
- data/lib/discorb/application.rb +16 -7
- data/lib/discorb/asset.rb +9 -0
- data/lib/discorb/{file.rb → attachment.rb} +55 -33
- data/lib/discorb/audit_logs.rb +42 -4
- data/lib/discorb/channel.rb +47 -12
- data/lib/discorb/client.rb +135 -51
- data/lib/discorb/common.rb +18 -4
- data/lib/discorb/components/button.rb +5 -6
- data/lib/discorb/components/select_menu.rb +2 -16
- data/lib/discorb/dictionary.rb +2 -0
- data/lib/discorb/embed.rb +71 -38
- data/lib/discorb/emoji.rb +29 -2
- data/lib/discorb/emoji_table.rb +1 -1
- data/lib/discorb/error.rb +7 -1
- data/lib/discorb/event.rb +27 -17
- data/lib/discorb/exe/new.rb +5 -5
- data/lib/discorb/exe/run.rb +1 -15
- data/lib/discorb/gateway.rb +262 -161
- data/lib/discorb/gateway_requests.rb +4 -7
- data/lib/discorb/guild.rb +67 -33
- data/lib/discorb/guild_template.rb +24 -3
- data/lib/discorb/http.rb +25 -3
- data/lib/discorb/integration.rb +23 -8
- data/lib/discorb/intents.rb +15 -10
- data/lib/discorb/interaction/autocomplete.rb +4 -4
- data/lib/discorb/interaction/command.rb +34 -5
- data/lib/discorb/interaction/components.rb +15 -2
- data/lib/discorb/interaction/response.rb +12 -0
- data/lib/discorb/interaction/root.rb +16 -1
- data/lib/discorb/invite.rb +11 -7
- data/lib/discorb/member.rb +21 -0
- data/lib/discorb/message.rb +59 -3
- data/lib/discorb/message_meta.rb +36 -55
- data/lib/discorb/modules.rb +38 -14
- data/lib/discorb/permission.rb +14 -5
- data/lib/discorb/presence.rb +41 -8
- data/lib/discorb/rate_limit.rb +7 -2
- data/lib/discorb/reaction.rb +6 -0
- data/lib/discorb/role.rb +12 -0
- data/lib/discorb/shard.rb +74 -0
- data/lib/discorb/sticker.rb +22 -14
- data/lib/discorb/user.rb +11 -0
- data/lib/discorb/voice_state.rb +20 -2
- data/lib/discorb/webhook.rb +53 -2
- data/lib/discorb.rb +5 -3
- data/sig/discorb.rbs +7234 -6714
- metadata +5 -4
- data/lib/discorb/log.rb +0 -81
data/lib/discorb/audit_logs.rb
CHANGED
@@ -14,7 +14,10 @@ module Discorb
|
|
14
14
|
# @return [Array<Discorb::AuditLog::Entry>] The entries in this audit log.
|
15
15
|
attr_reader :entries
|
16
16
|
|
17
|
+
#
|
18
|
+
# Initializes a new instance of the AuditLog class.
|
17
19
|
# @private
|
20
|
+
#
|
18
21
|
def initialize(client, data, guild)
|
19
22
|
@client = client
|
20
23
|
@guild = guild
|
@@ -24,6 +27,10 @@ module Discorb
|
|
24
27
|
@entries = data[:audit_log_entries].map { |entry| AuditLog::Entry.new(@client, entry, guild.id) }
|
25
28
|
end
|
26
29
|
|
30
|
+
def inspect
|
31
|
+
"<#{self.class} #{@entries.length} entries>"
|
32
|
+
end
|
33
|
+
|
27
34
|
#
|
28
35
|
# Gets an entry from entries.
|
29
36
|
#
|
@@ -108,8 +115,11 @@ module Discorb
|
|
108
115
|
# @!attribute [r] user
|
109
116
|
# @return [Discorb::User] The user who performed the action.
|
110
117
|
|
118
|
+
#
|
119
|
+
# @return [{Integer => Symbol}] The map of events to their respective changes.
|
111
120
|
# @private
|
112
|
-
|
121
|
+
#
|
122
|
+
EVENTS = {
|
113
123
|
1 => :guild_update,
|
114
124
|
10 => :channel_create,
|
115
125
|
11 => :channel_update,
|
@@ -159,24 +169,30 @@ module Discorb
|
|
159
169
|
112 => :thread_delete,
|
160
170
|
}.freeze
|
161
171
|
|
172
|
+
#
|
173
|
+
# The converter for the change.
|
162
174
|
# @private
|
163
|
-
|
175
|
+
#
|
176
|
+
CONVERTERS = {
|
164
177
|
channel: ->(client, id, _guild_id) { client.channels[id] },
|
165
178
|
thread: ->(client, id, _guild_id) { client.channels[id] },
|
166
179
|
role: ->(client, id, guild_id) { client.guilds[guild_id]&.roles&.[](id) },
|
167
180
|
member: ->(client, id, guild_id) { client.guilds[guild_id]&.members&.[](id) },
|
168
181
|
guild: ->(client, id, _guild_id) { client.guilds[id] },
|
169
182
|
message: ->(client, id, _guild_id) { client.messages[id] },
|
170
|
-
}
|
183
|
+
}.freeze
|
171
184
|
|
185
|
+
#
|
186
|
+
# Initializes a new AuditLog entry.
|
172
187
|
# @private
|
188
|
+
#
|
173
189
|
def initialize(client, data, guild_id)
|
174
190
|
@client = client
|
175
191
|
@guild_id = Snowflake.new(guild_id)
|
176
192
|
@id = Snowflake.new(data[:id])
|
177
193
|
@user_id = Snowflake.new(data[:user_id])
|
178
194
|
@target_id = Snowflake.new(data[:target_id])
|
179
|
-
@type =
|
195
|
+
@type = EVENTS[data[:action_type]]
|
180
196
|
@target = self.class.converts[@type.to_s.split("_")[0].to_sym]&.call(client, @target_id, @gui)
|
181
197
|
@target ||= Snowflake.new(data[:target_id])
|
182
198
|
@changes = data[:changes] && Changes.new(data[:changes])
|
@@ -223,8 +239,11 @@ module Discorb
|
|
223
239
|
attr_reader :data
|
224
240
|
|
225
241
|
#
|
242
|
+
# Initializes a new changes object.
|
226
243
|
# @private
|
227
244
|
#
|
245
|
+
# @param [Hash] data The data to initialize with.
|
246
|
+
#
|
228
247
|
def initialize(data)
|
229
248
|
@data = data.to_h { |d| [d[:key].to_sym, d] }
|
230
249
|
@data.each do |k, v|
|
@@ -232,6 +251,9 @@ module Discorb
|
|
232
251
|
end
|
233
252
|
end
|
234
253
|
|
254
|
+
#
|
255
|
+
# Formats the changes into a string.
|
256
|
+
#
|
235
257
|
def inspect
|
236
258
|
"#<#{self.class} #{@data.length} changes>"
|
237
259
|
end
|
@@ -270,7 +292,10 @@ module Discorb
|
|
270
292
|
# @return [Object] The new value of the change.
|
271
293
|
attr_reader :new_value
|
272
294
|
|
295
|
+
#
|
296
|
+
# Initializes a new change object.
|
273
297
|
# @private
|
298
|
+
#
|
274
299
|
def initialize(data)
|
275
300
|
@key = data[:key].to_sym
|
276
301
|
method = case @key.to_s
|
@@ -298,10 +323,20 @@ module Discorb
|
|
298
323
|
@new_value.__send__(method, ...)
|
299
324
|
end
|
300
325
|
|
326
|
+
#
|
327
|
+
# Format the change into a string.
|
328
|
+
#
|
329
|
+
# @return [String] The string representation of the change.
|
330
|
+
#
|
301
331
|
def inspect
|
302
332
|
"#<#{self.class} #{@key.inspect} #{@old_value.inspect} -> #{@new_value.inspect}>"
|
303
333
|
end
|
304
334
|
|
335
|
+
#
|
336
|
+
# Whether the change responds to the given method.
|
337
|
+
#
|
338
|
+
# @return [Boolean] Whether the change responds to the given method.
|
339
|
+
#
|
305
340
|
def respond_to_missing?(method, include_private = false)
|
306
341
|
@new_value.respond_to?(method, include_private)
|
307
342
|
end
|
@@ -321,7 +356,10 @@ module Discorb
|
|
321
356
|
# @return [Discorb::Integration::Account] The account of the integration.
|
322
357
|
attr_reader :account
|
323
358
|
|
359
|
+
#
|
360
|
+
# Initializes a new integration object.
|
324
361
|
# @private
|
362
|
+
#
|
325
363
|
def initialize(data)
|
326
364
|
@id = Snowflake.new(data[:id])
|
327
365
|
@type = data[:type].to_sym
|
data/lib/discorb/channel.rb
CHANGED
@@ -19,7 +19,10 @@ module Discorb
|
|
19
19
|
@channel_type = nil
|
20
20
|
@subclasses = []
|
21
21
|
|
22
|
+
#
|
23
|
+
# Initializes a new instance of the Channel class.
|
22
24
|
# @private
|
25
|
+
#
|
23
26
|
def initialize(client, data, no_cache: false)
|
24
27
|
@client = client
|
25
28
|
@data = {}
|
@@ -44,22 +47,35 @@ module Discorb
|
|
44
47
|
"#<#{self.class} \"##{@name}\" id=#{@id}>"
|
45
48
|
end
|
46
49
|
|
50
|
+
#
|
51
|
+
# Returns the descendants of the Channel class.
|
47
52
|
# @private
|
53
|
+
#
|
48
54
|
def self.descendants
|
49
55
|
ObjectSpace.each_object(Class).select { |klass| klass < self }
|
50
56
|
end
|
51
57
|
|
58
|
+
#
|
59
|
+
# Creates a new instance of the Channel class or instance of its descendants.
|
52
60
|
# @private
|
61
|
+
#
|
62
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
63
|
+
# @param [Hash] data The data of the object.
|
64
|
+
# @param [Boolean] no_cache Whether to disable cache the object.
|
65
|
+
#
|
53
66
|
def self.make_channel(client, data, no_cache: false)
|
54
67
|
descendants.each do |klass|
|
55
68
|
return klass.new(client, data, no_cache: no_cache) if !klass.channel_type.nil? && klass.channel_type == data[:type]
|
56
69
|
end
|
57
|
-
client.
|
70
|
+
client.logger.warn("Unknown channel type #{data[:type]}, initialized GuildChannel")
|
58
71
|
GuildChannel.new(client, data)
|
59
72
|
end
|
60
73
|
|
61
74
|
class << self
|
75
|
+
#
|
62
76
|
# @private
|
77
|
+
# @return [Integer] The type of the channel.
|
78
|
+
#
|
63
79
|
attr_reader :channel_type
|
64
80
|
end
|
65
81
|
|
@@ -67,7 +83,12 @@ module Discorb
|
|
67
83
|
self.class.channel_type
|
68
84
|
end
|
69
85
|
|
86
|
+
#
|
87
|
+
# Returns the channel id to request.
|
70
88
|
# @private
|
89
|
+
#
|
90
|
+
# @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
|
91
|
+
#
|
71
92
|
def channel_id
|
72
93
|
Async do
|
73
94
|
@id
|
@@ -114,7 +135,7 @@ module Discorb
|
|
114
135
|
#
|
115
136
|
# @param [Discorb::GuildChannel] other The channel to compare.
|
116
137
|
#
|
117
|
-
# @return [-1, 1] -1 if the channel is at lower than the other, 1 if the channel is at highter than the other.
|
138
|
+
# @return [-1, 0, 1] -1 if the channel is at lower than the other, 1 if the channel is at highter than the other.
|
118
139
|
#
|
119
140
|
def <=>(other)
|
120
141
|
return 0 unless other.respond_to?(:position)
|
@@ -239,17 +260,15 @@ module Discorb
|
|
239
260
|
# @return [Time] The time when the last pinned message was pinned.
|
240
261
|
attr_reader :last_pin_timestamp
|
241
262
|
alias last_pinned_at last_pin_timestamp
|
242
|
-
# @return [Array<Discorb::ThreadChannel>] The threads in the channel.
|
243
|
-
attr_reader :threads
|
244
263
|
|
245
264
|
include Messageable
|
246
265
|
|
247
266
|
@channel_type = 0
|
248
267
|
|
249
|
-
#
|
250
|
-
|
251
|
-
|
252
|
-
|
268
|
+
# @!attribute [r] threads
|
269
|
+
# @return [Array<Discorb::ThreadChannel>] The threads in the channel.
|
270
|
+
def threads
|
271
|
+
guild.threads.select { |thread| thread.parent == self }
|
253
272
|
end
|
254
273
|
|
255
274
|
#
|
@@ -421,7 +440,7 @@ module Discorb
|
|
421
440
|
def fetch_invites
|
422
441
|
Async do
|
423
442
|
_resp, data = @client.http.request(Route.new("/channels/#{@id}/invites", "//channels/:channel_id/invites", :get)).wait
|
424
|
-
data.map { |invite| Invite.new(@client, invite) }
|
443
|
+
data.map { |invite| Invite.new(@client, invite, false) }
|
425
444
|
end
|
426
445
|
end
|
427
446
|
|
@@ -446,7 +465,7 @@ module Discorb
|
|
446
465
|
temporary: temporary,
|
447
466
|
unique: unique,
|
448
467
|
}, audit_log_reason: reason).wait
|
449
|
-
Invite.new(@client, data)
|
468
|
+
Invite.new(@client, data, false)
|
450
469
|
end
|
451
470
|
end
|
452
471
|
|
@@ -666,7 +685,10 @@ module Discorb
|
|
666
685
|
attr_reader :bitrate
|
667
686
|
# @return [Integer] The user limit of the voice channel.
|
668
687
|
attr_reader :user_limit
|
688
|
+
#
|
669
689
|
# @private
|
690
|
+
# @return [Discorb::Dictionary{Discorb::Snowflake => StageInstance}] The stage instances associated with the stage channel.
|
691
|
+
#
|
670
692
|
attr_reader :stage_instances
|
671
693
|
|
672
694
|
include Connectable
|
@@ -675,7 +697,10 @@ module Discorb
|
|
675
697
|
# @return [Discorb::StageInstance] The stage instance of the channel.
|
676
698
|
|
677
699
|
@channel_type = 13
|
700
|
+
#
|
701
|
+
# Initialize a new stage channel.
|
678
702
|
# @private
|
703
|
+
#
|
679
704
|
def initialize(...)
|
680
705
|
@stage_instances = Dictionary.new
|
681
706
|
super(...)
|
@@ -825,12 +850,17 @@ module Discorb
|
|
825
850
|
include Messageable
|
826
851
|
@channel_type = nil
|
827
852
|
|
853
|
+
#
|
854
|
+
# Initialize a new thread channel.
|
828
855
|
# @private
|
856
|
+
#
|
857
|
+
# @param [Discorb::Client] client The client.
|
858
|
+
# @param [Hash] data The data of the thread channel.
|
859
|
+
# @param [Boolean] no_cache Whether to disable the cache.
|
860
|
+
#
|
829
861
|
def initialize(client, data, no_cache: false)
|
830
862
|
@members = Dictionary.new
|
831
863
|
super
|
832
|
-
@client.channels[@parent_id].threads[@id] = self
|
833
|
-
|
834
864
|
@client.channels[@id] = self unless no_cache
|
835
865
|
end
|
836
866
|
|
@@ -1117,7 +1147,12 @@ module Discorb
|
|
1117
1147
|
class DMChannel < Channel
|
1118
1148
|
include Messageable
|
1119
1149
|
|
1150
|
+
#
|
1151
|
+
# Returns the channel id to request.
|
1120
1152
|
# @private
|
1153
|
+
#
|
1154
|
+
# @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
|
1155
|
+
#
|
1121
1156
|
def channel_id
|
1122
1157
|
Async do
|
1123
1158
|
@id
|
data/lib/discorb/client.rb
CHANGED
@@ -40,8 +40,6 @@ module Discorb
|
|
40
40
|
attr_reader :emojis
|
41
41
|
# @return [Discorb::Dictionary{Discorb::Snowflake => Discorb::Message}] A dictionary of messages.
|
42
42
|
attr_reader :messages
|
43
|
-
# @return [Discorb::Logger] The logger.
|
44
|
-
attr_reader :log
|
45
43
|
# @return [Array<Discorb::ApplicationCommand::Command>] The commands that the client is using.
|
46
44
|
attr_reader :commands
|
47
45
|
# @return [Float] The ping of the client.
|
@@ -50,12 +48,28 @@ module Discorb
|
|
50
48
|
attr_reader :ping
|
51
49
|
# @return [:initialized, :running, :closed] The status of the client.
|
52
50
|
attr_reader :status
|
53
|
-
# @return [Integer] The session ID of connection.
|
54
|
-
attr_reader :session_id
|
55
51
|
# @return [Hash{String => Discorb::Extension}] The loaded extensions.
|
56
52
|
attr_reader :extensions
|
53
|
+
# @return [Hash{Integer => Discorb::Shard}] The shards of the client.
|
54
|
+
attr_reader :shards
|
57
55
|
# @private
|
56
|
+
# @return [Hash{Discorb::Snowflake => Discorb::ApplicationCommand::Command}] The commands on the top level.
|
58
57
|
attr_reader :bottom_commands
|
58
|
+
# @private
|
59
|
+
# @return [{String => Thread::Mutex}] A hash of mutexes.
|
60
|
+
attr_reader :mutex
|
61
|
+
|
62
|
+
# @!attribute [r] session_id
|
63
|
+
# @return [String] The session ID of the client or current shard.
|
64
|
+
# @return [nil] If not connected to the gateway.
|
65
|
+
# @!attribute [r] shard
|
66
|
+
# @return [Discorb::Shard] The current shard. This is implemented with Thread variables.
|
67
|
+
# @return [nil] If client has no shard.
|
68
|
+
# @!attribute [r] shard_id
|
69
|
+
# @return [Discorb::Shard] The current shard ID. This is implemented with Thread variables.
|
70
|
+
# @return [nil] If client has no shard.
|
71
|
+
# @!attribute [r] logger
|
72
|
+
# @return [Logger] The logger.
|
59
73
|
|
60
74
|
#
|
61
75
|
# Initializes a new client.
|
@@ -63,8 +77,7 @@ module Discorb
|
|
63
77
|
# @param [Discorb::AllowedMentions] allowed_mentions The allowed mentions that the client is using.
|
64
78
|
# @param [Discorb::Intents] intents The intents that the client is currently using.
|
65
79
|
# @param [Integer] message_caches The number of messages to cache.
|
66
|
-
# @param [
|
67
|
-
# @param [Boolean] colorize_log Whether to colorize the log.
|
80
|
+
# @param [Logger] logger The IO object to use for logging.
|
68
81
|
# @param [:debug, :info, :warn, :error, :critical] log_level The log level.
|
69
82
|
# @param [Boolean] wait_until_ready Whether to delay event dispatch until ready.
|
70
83
|
# @param [Boolean] fetch_member Whether to fetch member on ready. This may slow down the client. Default to `false`.
|
@@ -72,7 +85,7 @@ module Discorb
|
|
72
85
|
#
|
73
86
|
def initialize(
|
74
87
|
allowed_mentions: nil, intents: nil, message_caches: 1000,
|
75
|
-
|
88
|
+
logger: nil,
|
76
89
|
wait_until_ready: true, fetch_member: false,
|
77
90
|
title: nil
|
78
91
|
)
|
@@ -80,7 +93,7 @@ module Discorb
|
|
80
93
|
@intents = (intents or Intents.default)
|
81
94
|
@events = {}
|
82
95
|
@api_version = nil
|
83
|
-
@
|
96
|
+
@logger = logger || Logger.new($stdout, progname: "discorb")
|
84
97
|
@user = nil
|
85
98
|
@users = Discorb::Dictionary.new
|
86
99
|
@channels = Discorb::Dictionary.new
|
@@ -100,6 +113,8 @@ module Discorb
|
|
100
113
|
@fetch_member = fetch_member
|
101
114
|
@title = title
|
102
115
|
@extensions = {}
|
116
|
+
@mutex = {}
|
117
|
+
@shards = {}
|
103
118
|
set_default_events
|
104
119
|
end
|
105
120
|
|
@@ -180,16 +195,16 @@ module Discorb
|
|
180
195
|
events << event_method
|
181
196
|
end
|
182
197
|
if events.nil?
|
183
|
-
|
198
|
+
logger.debug "Event #{event_name} doesn't have any proc, skipping"
|
184
199
|
next
|
185
200
|
end
|
186
|
-
|
201
|
+
logger.debug "Dispatching event #{event_name}"
|
187
202
|
events.each do |block|
|
188
203
|
Async do
|
189
204
|
Async(annotation: "Discorb event: #{event_name}") do |_task|
|
190
205
|
@events[event_name].delete(block) if block.is_a?(Discorb::EventHandler) && block.metadata[:once]
|
191
206
|
block.call(*args)
|
192
|
-
|
207
|
+
logger.debug "Dispatched proc with ID #{block.id.inspect}"
|
193
208
|
rescue StandardError, ScriptError => e
|
194
209
|
dispatch(:error, event_name, args, e)
|
195
210
|
end
|
@@ -309,10 +324,11 @@ module Discorb
|
|
309
324
|
activities: [],
|
310
325
|
status: status,
|
311
326
|
since: nil,
|
327
|
+
afk: nil,
|
312
328
|
}
|
313
329
|
payload[:activities] = [activity.to_hash] unless activity.nil?
|
314
330
|
payload[:status] = status unless status.nil?
|
315
|
-
if
|
331
|
+
if connection
|
316
332
|
Async do
|
317
333
|
send_gateway(3, **payload)
|
318
334
|
end
|
@@ -423,15 +439,15 @@ module Discorb
|
|
423
439
|
#
|
424
440
|
# @note If the token is nil, you should use `discorb run` with the `-e` or `--env` option.
|
425
441
|
#
|
426
|
-
def run(token = nil)
|
442
|
+
def run(token = nil, shards: nil, shard_count: nil)
|
427
443
|
token ||= ENV["DISCORB_CLI_TOKEN"]
|
428
444
|
raise ArgumentError, "Token is not specified, and -e/--env is not specified" if token.nil?
|
429
445
|
case ENV["DISCORB_CLI_FLAG"]
|
430
446
|
when nil
|
431
|
-
start_client(token)
|
447
|
+
start_client(token, shards: shards, shard_count: shard_count)
|
432
448
|
when "run"
|
433
449
|
before_run(token)
|
434
|
-
start_client(token)
|
450
|
+
start_client(token, shards: shards, shard_count: shard_count)
|
435
451
|
when "setup"
|
436
452
|
run_setup(token)
|
437
453
|
end
|
@@ -441,10 +457,33 @@ module Discorb
|
|
441
457
|
# Stops the client.
|
442
458
|
#
|
443
459
|
def close!
|
444
|
-
@
|
460
|
+
if @shards.any?
|
461
|
+
@shards.each(&:close!)
|
462
|
+
else
|
463
|
+
@connection.send_close
|
464
|
+
end
|
445
465
|
@tasks.each(&:stop)
|
446
466
|
@status = :closed
|
447
|
-
|
467
|
+
end
|
468
|
+
|
469
|
+
def session_id
|
470
|
+
if shard
|
471
|
+
shard.session_id
|
472
|
+
else
|
473
|
+
@session_id
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
def logger
|
478
|
+
shard&.logger || @logger
|
479
|
+
end
|
480
|
+
|
481
|
+
def shard
|
482
|
+
Thread.current.thread_variable_get("shard")
|
483
|
+
end
|
484
|
+
|
485
|
+
def shard_id
|
486
|
+
Thread.current.thread_variable_get("shard_id")
|
448
487
|
end
|
449
488
|
|
450
489
|
private
|
@@ -453,22 +492,6 @@ module Discorb
|
|
453
492
|
require "json"
|
454
493
|
options = JSON.parse(ENV["DISCORB_CLI_OPTIONS"], symbolize_names: true)
|
455
494
|
setup_commands(token) if options[:setup]
|
456
|
-
if options[:log_level]
|
457
|
-
if options[:log_level] == "none"
|
458
|
-
@log.out = nil
|
459
|
-
else
|
460
|
-
@log.out = case options[:log_file]
|
461
|
-
when nil, "stderr"
|
462
|
-
$stderr
|
463
|
-
when "stdout"
|
464
|
-
$stdout
|
465
|
-
else
|
466
|
-
::File.open(options[:log_file], "a")
|
467
|
-
end
|
468
|
-
@log.level = options[:log_level].to_sym
|
469
|
-
@log.colorize_log = options[:log_color].nil? ? @log.out.isatty : options[:log_color]
|
470
|
-
end
|
471
|
-
end
|
472
495
|
end
|
473
496
|
|
474
497
|
def run_setup(token)
|
@@ -486,32 +509,93 @@ module Discorb
|
|
486
509
|
end
|
487
510
|
end
|
488
511
|
|
489
|
-
def
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
512
|
+
def set_status(status, shard)
|
513
|
+
if shard.nil?
|
514
|
+
@status = status
|
515
|
+
else
|
516
|
+
@shards[shard].status = status
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
def connection
|
521
|
+
if shard_id
|
522
|
+
@shards[shard_id].connection
|
523
|
+
else
|
524
|
+
@connection
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|
528
|
+
def connection=(value)
|
529
|
+
if shard_id
|
530
|
+
@shards[shard_id].connection = value
|
531
|
+
else
|
532
|
+
@connection = value
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
def session_id=(value)
|
537
|
+
if shard_id
|
538
|
+
@shards[shard_id].session_id = value
|
539
|
+
else
|
540
|
+
@session_id = value
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
def start_client(token, shards: nil, shard_count: nil)
|
545
|
+
@token = token.to_s
|
546
|
+
@shard_count = shard_count
|
547
|
+
Signal.trap(:SIGINT) do
|
548
|
+
logger.info "SIGINT received, closing..."
|
549
|
+
Signal.trap(:SIGINT, "DEFAULT")
|
550
|
+
close!
|
551
|
+
end
|
552
|
+
if shards.nil?
|
553
|
+
main_loop(nil)
|
554
|
+
else
|
555
|
+
@shards = shards.map.with_index do |shard, i|
|
556
|
+
Shard.new(self, shard, shard_count, i)
|
495
557
|
end
|
496
|
-
@
|
497
|
-
|
498
|
-
@main_task = Async do
|
499
|
-
@status = :running
|
500
|
-
connect_gateway(false).wait
|
501
|
-
rescue StandardError
|
502
|
-
@status = :stopped
|
503
|
-
@close_condition.signal
|
504
|
-
raise
|
558
|
+
@shards[..-1].each_with_index do |shard, i|
|
559
|
+
shard.next_shard = @shards[i + 1]
|
505
560
|
end
|
506
|
-
@
|
507
|
-
|
561
|
+
@shards.each { |s| s.thread.join }
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
def main_loop(shard)
|
566
|
+
close_condition = Async::Condition.new
|
567
|
+
self.main_task = Async do
|
568
|
+
set_status(:running, shard)
|
569
|
+
connect_gateway(false).wait
|
570
|
+
rescue StandardError
|
571
|
+
set_status(:running, shard)
|
572
|
+
close_condition.signal
|
573
|
+
raise
|
574
|
+
end
|
575
|
+
close_condition.wait
|
576
|
+
main_task.stop
|
577
|
+
end
|
578
|
+
|
579
|
+
def main_task
|
580
|
+
if shard_id
|
581
|
+
shard.main_task
|
582
|
+
else
|
583
|
+
@main_task
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
def main_task=(value)
|
588
|
+
if shard_id
|
589
|
+
shard.main_task = value
|
590
|
+
else
|
591
|
+
@main_task = value
|
508
592
|
end
|
509
593
|
end
|
510
594
|
|
511
595
|
def set_default_events
|
512
596
|
on :error, override: true do |event_name, _args, e|
|
513
597
|
message = "An error occurred while dispatching #{event_name}:\n#{e.full_message}"
|
514
|
-
|
598
|
+
logger.error message, fallback: $stderr
|
515
599
|
end
|
516
600
|
|
517
601
|
once :standby do
|
data/lib/discorb/common.rb
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
module Discorb
|
4
4
|
# @return [String] The API base URL.
|
5
|
-
API_BASE_URL = "https://discord.com/api/
|
5
|
+
API_BASE_URL = "https://discord.com/api/v10"
|
6
6
|
# @return [String] The version of discorb.
|
7
|
-
VERSION = "0.
|
7
|
+
VERSION = "0.16.0"
|
8
|
+
# @return [Array<Integer>] The version array of discorb.
|
9
|
+
VERSION_ARRAY = VERSION.split(".").map(&:to_i).freeze
|
8
10
|
# @return [String] The user agent for the bot.
|
9
11
|
USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}".freeze
|
10
12
|
|
@@ -25,8 +27,11 @@ module Discorb
|
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
|
30
|
+
def inspect
|
31
|
+
"#<#{self.class}: #{@id}>"
|
32
|
+
end
|
29
33
|
|
34
|
+
# @private
|
30
35
|
def hash
|
31
36
|
@id.hash
|
32
37
|
end
|
@@ -37,7 +42,12 @@ module Discorb
|
|
37
42
|
#
|
38
43
|
# @see https://discord.com/developers/docs/reference#snowflakes Official Discord API docs
|
39
44
|
class Snowflake < String
|
45
|
+
#
|
46
|
+
# Initialize new snowflake.
|
40
47
|
# @private
|
48
|
+
#
|
49
|
+
# @param [#to_s] value The value of the snowflake.
|
50
|
+
#
|
41
51
|
def initialize(value)
|
42
52
|
@value = value.to_i
|
43
53
|
super(@value.to_s)
|
@@ -92,7 +102,7 @@ module Discorb
|
|
92
102
|
end
|
93
103
|
|
94
104
|
def timestamp
|
95
|
-
Time.at(((@value >> 22) + 1_420_070_400_000) / 1000)
|
105
|
+
Time.at(((@value >> 22) + 1_420_070_400_000) / 1000.0)
|
96
106
|
end
|
97
107
|
|
98
108
|
def worker_id
|
@@ -127,6 +137,10 @@ module Discorb
|
|
127
137
|
@method = method
|
128
138
|
end
|
129
139
|
|
140
|
+
def inspect
|
141
|
+
"#<#{self.class} #{self.identifier}>"
|
142
|
+
end
|
143
|
+
|
130
144
|
def hash
|
131
145
|
@url.hash
|
132
146
|
end
|
@@ -21,7 +21,9 @@ module Discorb
|
|
21
21
|
attr_accessor :disabled
|
22
22
|
alias disabled? disabled
|
23
23
|
|
24
|
-
@
|
24
|
+
# @private
|
25
|
+
# @return [{Symbol => Integer}] The mapping of button styles.
|
26
|
+
STYLES = {
|
25
27
|
primary: 1,
|
26
28
|
secondary: 2,
|
27
29
|
success: 3,
|
@@ -59,7 +61,7 @@ module Discorb
|
|
59
61
|
{
|
60
62
|
type: 2,
|
61
63
|
label: @label,
|
62
|
-
style:
|
64
|
+
style: STYLES[@style],
|
63
65
|
url: @url,
|
64
66
|
emoji: @emoji&.to_hash,
|
65
67
|
disabled: @disabled,
|
@@ -68,7 +70,7 @@ module Discorb
|
|
68
70
|
{
|
69
71
|
type: 2,
|
70
72
|
label: @label,
|
71
|
-
style:
|
73
|
+
style: STYLES[@style],
|
72
74
|
custom_id: @custom_id,
|
73
75
|
emoji: @emoji&.to_hash,
|
74
76
|
disabled: @disabled,
|
@@ -81,9 +83,6 @@ module Discorb
|
|
81
83
|
end
|
82
84
|
|
83
85
|
class << self
|
84
|
-
# @private
|
85
|
-
attr_reader :styles
|
86
|
-
|
87
86
|
#
|
88
87
|
# Creates a new button from a hash.
|
89
88
|
#
|