discorb 0.13.4 → 0.15.1

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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/build_version.yml +1 -1
  4. data/.github/workflows/codeql-analysis.yml +70 -0
  5. data/.github/workflows/lint-push.yml +20 -0
  6. data/.github/workflows/lint.yml +16 -0
  7. data/.rubocop.yml +74 -0
  8. data/Changelog.md +30 -0
  9. data/Gemfile +7 -3
  10. data/Rakefile +28 -22
  11. data/discorb.gemspec +1 -0
  12. data/docs/events.md +50 -0
  13. data/docs/faq.md +8 -8
  14. data/examples/commands/bookmarker.rb +2 -1
  15. data/examples/commands/hello.rb +1 -0
  16. data/examples/commands/inspect.rb +3 -2
  17. data/examples/components/authorization_button.rb +2 -1
  18. data/examples/components/select_menu.rb +2 -1
  19. data/examples/extension/main.rb +1 -0
  20. data/examples/extension/message_expander.rb +1 -0
  21. data/examples/simple/eval.rb +3 -2
  22. data/examples/simple/ping_pong.rb +1 -0
  23. data/examples/simple/rolepanel.rb +1 -0
  24. data/examples/simple/wait_for_message.rb +4 -3
  25. data/exe/discorb +8 -7
  26. data/lib/discorb/allowed_mentions.rb +71 -0
  27. data/lib/discorb/app_command/command.rb +336 -0
  28. data/lib/discorb/app_command/handler.rb +168 -0
  29. data/lib/discorb/app_command.rb +2 -426
  30. data/lib/discorb/application.rb +16 -7
  31. data/lib/discorb/asset.rb +11 -0
  32. data/lib/discorb/{file.rb → attachment.rb} +55 -33
  33. data/lib/discorb/audit_logs.rb +45 -7
  34. data/lib/discorb/channel.rb +65 -15
  35. data/lib/discorb/client.rb +34 -27
  36. data/lib/discorb/common.rb +19 -27
  37. data/lib/discorb/components/button.rb +105 -0
  38. data/lib/discorb/components/select_menu.rb +143 -0
  39. data/lib/discorb/components/text_input.rb +96 -0
  40. data/lib/discorb/components.rb +11 -276
  41. data/lib/discorb/dictionary.rb +5 -0
  42. data/lib/discorb/embed.rb +73 -40
  43. data/lib/discorb/emoji.rb +48 -5
  44. data/lib/discorb/error.rb +9 -5
  45. data/lib/discorb/event.rb +36 -24
  46. data/lib/discorb/exe/about.rb +1 -0
  47. data/lib/discorb/exe/irb.rb +4 -3
  48. data/lib/discorb/exe/new.rb +6 -7
  49. data/lib/discorb/exe/run.rb +2 -1
  50. data/lib/discorb/exe/setup.rb +8 -5
  51. data/lib/discorb/exe/show.rb +1 -0
  52. data/lib/discorb/extend.rb +19 -14
  53. data/lib/discorb/extension.rb +5 -1
  54. data/lib/discorb/gateway.rb +112 -51
  55. data/lib/discorb/gateway_requests.rb +4 -7
  56. data/lib/discorb/guild.rb +73 -41
  57. data/lib/discorb/guild_template.rb +26 -5
  58. data/lib/discorb/http.rb +38 -18
  59. data/lib/discorb/integration.rb +24 -9
  60. data/lib/discorb/intents.rb +16 -11
  61. data/lib/discorb/interaction/autocomplete.rb +6 -5
  62. data/lib/discorb/interaction/command.rb +66 -12
  63. data/lib/discorb/interaction/components.rb +19 -3
  64. data/lib/discorb/interaction/modal.rb +33 -0
  65. data/lib/discorb/interaction/response.rb +45 -4
  66. data/lib/discorb/interaction/root.rb +16 -0
  67. data/lib/discorb/interaction.rb +2 -1
  68. data/lib/discorb/invite.rb +11 -7
  69. data/lib/discorb/log.rb +5 -5
  70. data/lib/discorb/member.rb +22 -3
  71. data/lib/discorb/message.rb +39 -234
  72. data/lib/discorb/message_meta.rb +186 -0
  73. data/lib/discorb/modules.rb +39 -15
  74. data/lib/discorb/permission.rb +16 -7
  75. data/lib/discorb/presence.rb +45 -9
  76. data/lib/discorb/rate_limit.rb +7 -4
  77. data/lib/discorb/reaction.rb +6 -0
  78. data/lib/discorb/role.rb +12 -0
  79. data/lib/discorb/sticker.rb +22 -14
  80. data/lib/discorb/user.rb +12 -1
  81. data/lib/discorb/utils/colored_puts.rb +1 -0
  82. data/lib/discorb/voice_state.rb +23 -2
  83. data/lib/discorb/webhook.rb +54 -3
  84. data/lib/discorb.rb +5 -2
  85. data/sig/discorb.rbs +838 -702
  86. data/template-replace/scripts/arrow.rb +1 -0
  87. data/template-replace/scripts/favicon.rb +1 -0
  88. data/template-replace/scripts/index.rb +2 -1
  89. data/template-replace/scripts/locale_ja.rb +5 -4
  90. data/template-replace/scripts/sidebar.rb +1 -0
  91. data/template-replace/scripts/version.rb +7 -10
  92. data/template-replace/scripts/yard_replace.rb +5 -4
  93. metadata +17 -3
@@ -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
- @events = {
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
- @converts = {
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 = self.class.events[data[:action_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,15 +239,21 @@ 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
- @data = data.map { |d| [d[:key].to_sym, d] }.to_h
248
+ @data = data.to_h { |d| [d[:key].to_sym, d] }
230
249
  @data.each do |k, v|
231
250
  define_singleton_method(k) { Change.new(v) }
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
@@ -287,8 +312,8 @@ module Discorb
287
312
  else
288
313
  ->(v) { v }
289
314
  end
290
- @old_value = method.(data[:old_value])
291
- @new_value = method.(data[:new_value])
315
+ @old_value = method.call(data[:old_value])
316
+ @new_value = method.call(data[:new_value])
292
317
  end
293
318
 
294
319
  #
@@ -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
@@ -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,12 +47,22 @@ 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]
@@ -59,7 +72,10 @@ module Discorb
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)
@@ -211,9 +232,9 @@ module Discorb
211
232
  @guild_id = data[:guild_id]
212
233
  @position = data[:position]
213
234
  @permission_overwrites = if data[:permission_overwrites]
214
- data[:permission_overwrites].map do |ow|
235
+ data[:permission_overwrites].to_h do |ow|
215
236
  [(ow[:type] == 1 ? guild.roles : guild.members)[ow[:id]], PermissionOverwrite.new(ow[:allow], ow[:deny])]
216
- end.to_h
237
+ end
217
238
  else
218
239
  {}
219
240
  end
@@ -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
- # @private
250
- def initialize(client, data, no_cache: false)
251
- super
252
- @threads = Dictionary.new
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(...)
@@ -759,7 +784,7 @@ module Discorb
759
784
  end
760
785
 
761
786
  def audiences
762
- voice_states.filter { |state| state.suppress? }.map(&:member)
787
+ voice_states.filter(&:suppress?).map(&:member)
763
788
  end
764
789
 
765
790
  private
@@ -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
 
@@ -990,14 +1020,23 @@ module Discorb
990
1020
  end
991
1021
  end
992
1022
 
1023
+ #
1024
+ # Represents a thread in news channel(aka announcement channel).
1025
+ #
993
1026
  class News < ThreadChannel
994
1027
  @channel_type = 10
995
1028
  end
996
1029
 
1030
+ #
1031
+ # Represents a public thread in text channel.
1032
+ #
997
1033
  class Public < ThreadChannel
998
1034
  @channel_type = 11
999
1035
  end
1000
1036
 
1037
+ #
1038
+ # Represents a private thread in text channel.
1039
+ #
1001
1040
  class Private < ThreadChannel
1002
1041
  @channel_type = 12
1003
1042
  end
@@ -1007,7 +1046,7 @@ module Discorb
1007
1046
  end
1008
1047
 
1009
1048
  #
1010
- # Repre
1049
+ # Represents a member in a thread.
1011
1050
  #
1012
1051
  class Member < DiscordModel
1013
1052
  attr_reader :joined_at
@@ -1059,6 +1098,9 @@ module Discorb
1059
1098
  end
1060
1099
  end
1061
1100
 
1101
+ #
1102
+ # Represents a category in a guild.
1103
+ #
1062
1104
  class CategoryChannel < GuildChannel
1063
1105
  @channel_type = 4
1064
1106
 
@@ -1099,10 +1141,18 @@ module Discorb
1099
1141
  end
1100
1142
  end
1101
1143
 
1144
+ #
1145
+ # Represents a DM channel.
1146
+ #
1102
1147
  class DMChannel < Channel
1103
1148
  include Messageable
1104
1149
 
1150
+ #
1151
+ # Returns the channel id to request.
1105
1152
  # @private
1153
+ #
1154
+ # @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
1155
+ #
1106
1156
  def channel_id
1107
1157
  Async do
1108
1158
  @id
@@ -54,7 +54,10 @@ module Discorb
54
54
  attr_reader :session_id
55
55
  # @return [Hash{String => Discorb::Extension}] The loaded extensions.
56
56
  attr_reader :extensions
57
+ #
57
58
  # @private
59
+ # @return [Hash{Discorb::Snowflake => Discorb::ApplicationCommand::Command}] The commands on the top level.
60
+ #
58
61
  attr_reader :bottom_commands
59
62
 
60
63
  #
@@ -186,10 +189,8 @@ module Discorb
186
189
  @log.debug "Dispatching event #{event_name}"
187
190
  events.each do |block|
188
191
  Async do
189
- Async(annotation: "Discorb event: #{event_name}") do |task|
190
- if block.is_a?(Discorb::EventHandler)
191
- @events[event_name].delete(block) if block.metadata[:once]
192
- end
192
+ Async(annotation: "Discorb event: #{event_name}") do |_task|
193
+ @events[event_name].delete(block) if block.is_a?(Discorb::EventHandler) && block.metadata[:once]
193
194
  block.call(*args)
194
195
  @log.debug "Dispatched proc with ID #{block.id.inspect}"
195
196
  rescue StandardError, ScriptError => e
@@ -261,7 +262,7 @@ module Discorb
261
262
  #
262
263
  # @return [Async::Task<Discorb::Invite>] The invite.
263
264
  #
264
- def fetch_invite(code, with_count: false, with_expiration: false)
265
+ def fetch_invite(code, with_count: true, with_expiration: true)
265
266
  Async do
266
267
  _resp, data = @http.request(Route.new("/invites/#{code}?with_count=#{with_count}&with_expiration=#{with_expiration}", "//invites/:code", :get)).wait
267
268
  Invite.new(self, data, false)
@@ -295,8 +296,8 @@ module Discorb
295
296
  #
296
297
  def fetch_nitro_sticker_packs
297
298
  Async do
298
- _resp, data = @http.request(Route.new("/stickers-packs", "//stickers-packs", :get)).wait
299
- data.map { |pack| Sticker::Pack.new(self, pack) }
299
+ _resp, data = @http.request(Route.new("/sticker-packs", "//sticker-packs", :get)).wait
300
+ data[:sticker_packs].map { |pack| Sticker::Pack.new(self, pack) }
300
301
  end
301
302
  end
302
303
 
@@ -305,18 +306,15 @@ module Discorb
305
306
  #
306
307
  # @param [Discorb::Activity] activity The activity to update.
307
308
  # @param [:online, :idle, :dnd, :invisible] status The status to update.
308
- # @param [String] afk Whether to set the client as AFK.
309
309
  #
310
- def update_presence(activity = nil, status: nil, afk: false)
310
+ def update_presence(activity = nil, status: nil)
311
311
  payload = {
312
312
  activities: [],
313
313
  status: status,
314
- afk: nil,
315
314
  since: nil,
315
+ afk: nil,
316
316
  }
317
- if !activity.nil?
318
- payload[:activities] = [activity.to_hash]
319
- end
317
+ payload[:activities] = [activity.to_hash] unless activity.nil?
320
318
  payload[:status] = status unless status.nil?
321
319
  if @connection
322
320
  Async do
@@ -374,10 +372,11 @@ module Discorb
374
372
  # @param [Object] ... The arguments to pass to the `ext#initialize`.
375
373
  #
376
374
  def load_extension(ext, ...)
377
- if ext.is_a?(Class)
375
+ case ext
376
+ when Class
378
377
  raise ArgumentError, "#{ext} is not a extension" unless ext < Discorb::Extension
379
378
  ins = ext.new(self, ...)
380
- elsif ext.is_a?(Discorb::Extension)
379
+ when Discorb::Extension
381
380
  ins = ext
382
381
  else
383
382
  raise ArgumentError, "#{ext} is not a extension"
@@ -398,12 +397,20 @@ module Discorb
398
397
  ins.class.commands.each do |cmd|
399
398
  cmd.define_singleton_method(:extension) { ins.class.name }
400
399
  cmd.replace_block(ins)
400
+ cmd.block.define_singleton_method(:self_replaced) { true }
401
401
  @commands << cmd
402
402
  end
403
403
 
404
404
  cls = ins.class
405
405
  cls.loaded(self, ...) if cls.respond_to? :loaded
406
- @bottom_commands += ins.class.bottom_commands
406
+ ins.class.bottom_commands.each do |cmd|
407
+ unless cmd.respond_to? :self_replaced
408
+ cmd.define_singleton_method(:extension) { ins.class.name }
409
+ cmd.replace_block(ins)
410
+ cmd.block.define_singleton_method(:self_replaced) { true }
411
+ end
412
+ @bottom_commands << cmd
413
+ end
407
414
  @extensions[ins.class.name] = ins
408
415
  ins
409
416
  end
@@ -463,7 +470,7 @@ module Discorb
463
470
  ::File.open(options[:log_file], "a")
464
471
  end
465
472
  @log.level = options[:log_level].to_sym
466
- @log.colorize_log = options[:log_color] == nil ? @log.out.isatty : options[:log_color]
473
+ @log.colorize_log = options[:log_color].nil? ? @log.out.isatty : options[:log_color]
467
474
  end
468
475
  end
469
476
  end
@@ -473,29 +480,29 @@ module Discorb
473
480
  if guilds = ENV["DISCORB_SETUP_GUILDS"]
474
481
  guild_ids = guilds.split(",")
475
482
  end
476
- if guild_ids == ["global"]
477
- guild_ids = false
478
- end
483
+ guild_ids = false if guild_ids == ["global"]
479
484
  setup_commands(token, guild_ids: guild_ids).wait
480
- @events[:setup]&.each do |event|
481
- event.call
485
+ if ENV["DISCORB_SETUP_SCRIPT"] == "true"
486
+ @events[:setup]&.each do |event|
487
+ event.call
488
+ end
489
+ self.on_setup if respond_to? :on_setup
482
490
  end
483
- self.on_setup if respond_to? :on_setup
484
491
  end
485
492
 
486
493
  def start_client(token)
487
- Async do |task|
488
- Signal.trap(:SIGINT) {
494
+ Async do |_task|
495
+ Signal.trap(:SIGINT) do
489
496
  @log.info "SIGINT received, closing..."
490
497
  Signal.trap(:SIGINT, "DEFAULT")
491
498
  close!
492
- }
499
+ end
493
500
  @token = token.to_s
494
501
  @close_condition = Async::Condition.new
495
502
  @main_task = Async do
496
503
  @status = :running
497
504
  connect_gateway(false).wait
498
- rescue
505
+ rescue StandardError
499
506
  @status = :stopped
500
507
  @close_condition.signal
501
508
  raise
@@ -2,11 +2,13 @@
2
2
 
3
3
  module Discorb
4
4
  # @return [String] The API base URL.
5
- API_BASE_URL = "https://discord.com/api/v9"
5
+ API_BASE_URL = "https://discord.com/api/v10"
6
6
  # @return [String] The version of discorb.
7
- VERSION = "0.13.4"
7
+ VERSION = "0.15.1"
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
- USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}"
11
+ USER_AGENT = "DiscordBot (https://discorb-lib.github.io #{VERSION}) Ruby/#{RUBY_VERSION}".freeze
10
12
 
11
13
  #
12
14
  # @abstract
@@ -25,11 +27,11 @@ module Discorb
25
27
  end
26
28
  end
27
29
 
28
- # @private
29
30
  def inspect
30
- super
31
+ "#<#{self.class}: #{@id}>"
31
32
  end
32
33
 
34
+ # @private
33
35
  def hash
34
36
  @id.hash
35
37
  end
@@ -40,7 +42,12 @@ module Discorb
40
42
  #
41
43
  # @see https://discord.com/developers/docs/reference#snowflakes Official Discord API docs
42
44
  class Snowflake < String
45
+ #
46
+ # Initialize new snowflake.
43
47
  # @private
48
+ #
49
+ # @param [#to_s] value The value of the snowflake.
50
+ #
44
51
  def initialize(value)
45
52
  @value = value.to_i
46
53
  super(@value.to_s)
@@ -95,7 +102,7 @@ module Discorb
95
102
  end
96
103
 
97
104
  def timestamp
98
- Time.at(((@value >> 22) + 1_420_070_400_000) / 1000)
105
+ Time.at(((@value >> 22) + 1_420_070_400_000) / 1000.0)
99
106
  end
100
107
 
101
108
  def worker_id
@@ -111,7 +118,7 @@ module Discorb
111
118
  end
112
119
 
113
120
  def inspect
114
- "#<#{self.class} #{to_s}>"
121
+ "#<#{self.class} #{self}>"
115
122
  end
116
123
 
117
124
  alias id to_s
@@ -130,6 +137,10 @@ module Discorb
130
137
  @method = method
131
138
  end
132
139
 
140
+ def inspect
141
+ "#<#{self.class} #{self.identifier}>"
142
+ end
143
+
133
144
  def hash
134
145
  @url.hash
135
146
  end
@@ -146,26 +157,7 @@ module Discorb
146
157
  end
147
158
  end
148
159
 
149
- # @return [Object] Object that represents nil.
160
+ # @return [Object] Object that represents unspecified value.
150
161
  # This is used as a default value for optional parameters.
151
162
  Unset = Object.new
152
- class << Unset
153
- def method_missing(*)
154
- self
155
- end
156
-
157
- def or(other)
158
- other
159
- end
160
- end
161
-
162
- module DefineOr
163
- refine Object do
164
- def or(other)
165
- self
166
- end
167
- end
168
- end
169
-
170
- using DefineOr
171
163
  end