discorb 0.13.4 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
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