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.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.github/workflows/build_version.yml +1 -1
- data/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/lint-push.yml +20 -0
- data/.github/workflows/lint.yml +16 -0
- data/.rubocop.yml +74 -0
- data/Changelog.md +30 -0
- data/Gemfile +7 -3
- data/Rakefile +28 -22
- data/discorb.gemspec +1 -0
- data/docs/events.md +50 -0
- data/docs/faq.md +8 -8
- data/examples/commands/bookmarker.rb +2 -1
- data/examples/commands/hello.rb +1 -0
- data/examples/commands/inspect.rb +3 -2
- data/examples/components/authorization_button.rb +2 -1
- data/examples/components/select_menu.rb +2 -1
- data/examples/extension/main.rb +1 -0
- data/examples/extension/message_expander.rb +1 -0
- data/examples/simple/eval.rb +3 -2
- data/examples/simple/ping_pong.rb +1 -0
- data/examples/simple/rolepanel.rb +1 -0
- data/examples/simple/wait_for_message.rb +4 -3
- data/exe/discorb +8 -7
- data/lib/discorb/allowed_mentions.rb +71 -0
- data/lib/discorb/app_command/command.rb +336 -0
- data/lib/discorb/app_command/handler.rb +168 -0
- data/lib/discorb/app_command.rb +2 -426
- data/lib/discorb/application.rb +16 -7
- data/lib/discorb/asset.rb +11 -0
- data/lib/discorb/{file.rb → attachment.rb} +55 -33
- data/lib/discorb/audit_logs.rb +45 -7
- data/lib/discorb/channel.rb +65 -15
- data/lib/discorb/client.rb +34 -27
- data/lib/discorb/common.rb +19 -27
- data/lib/discorb/components/button.rb +105 -0
- data/lib/discorb/components/select_menu.rb +143 -0
- data/lib/discorb/components/text_input.rb +96 -0
- data/lib/discorb/components.rb +11 -276
- data/lib/discorb/dictionary.rb +5 -0
- data/lib/discorb/embed.rb +73 -40
- data/lib/discorb/emoji.rb +48 -5
- data/lib/discorb/error.rb +9 -5
- data/lib/discorb/event.rb +36 -24
- data/lib/discorb/exe/about.rb +1 -0
- data/lib/discorb/exe/irb.rb +4 -3
- data/lib/discorb/exe/new.rb +6 -7
- data/lib/discorb/exe/run.rb +2 -1
- data/lib/discorb/exe/setup.rb +8 -5
- data/lib/discorb/exe/show.rb +1 -0
- data/lib/discorb/extend.rb +19 -14
- data/lib/discorb/extension.rb +5 -1
- data/lib/discorb/gateway.rb +112 -51
- data/lib/discorb/gateway_requests.rb +4 -7
- data/lib/discorb/guild.rb +73 -41
- data/lib/discorb/guild_template.rb +26 -5
- data/lib/discorb/http.rb +38 -18
- data/lib/discorb/integration.rb +24 -9
- data/lib/discorb/intents.rb +16 -11
- data/lib/discorb/interaction/autocomplete.rb +6 -5
- data/lib/discorb/interaction/command.rb +66 -12
- data/lib/discorb/interaction/components.rb +19 -3
- data/lib/discorb/interaction/modal.rb +33 -0
- data/lib/discorb/interaction/response.rb +45 -4
- data/lib/discorb/interaction/root.rb +16 -0
- data/lib/discorb/interaction.rb +2 -1
- data/lib/discorb/invite.rb +11 -7
- data/lib/discorb/log.rb +5 -5
- data/lib/discorb/member.rb +22 -3
- data/lib/discorb/message.rb +39 -234
- data/lib/discorb/message_meta.rb +186 -0
- data/lib/discorb/modules.rb +39 -15
- data/lib/discorb/permission.rb +16 -7
- data/lib/discorb/presence.rb +45 -9
- data/lib/discorb/rate_limit.rb +7 -4
- data/lib/discorb/reaction.rb +6 -0
- data/lib/discorb/role.rb +12 -0
- data/lib/discorb/sticker.rb +22 -14
- data/lib/discorb/user.rb +12 -1
- data/lib/discorb/utils/colored_puts.rb +1 -0
- data/lib/discorb/voice_state.rb +23 -2
- data/lib/discorb/webhook.rb +54 -3
- data/lib/discorb.rb +5 -2
- data/sig/discorb.rbs +838 -702
- data/template-replace/scripts/arrow.rb +1 -0
- data/template-replace/scripts/favicon.rb +1 -0
- data/template-replace/scripts/index.rb +2 -1
- data/template-replace/scripts/locale_ja.rb +5 -4
- data/template-replace/scripts/sidebar.rb +1 -0
- data/template-replace/scripts/version.rb +7 -10
- data/template-replace/scripts/yard_replace.rb +5 -4
- metadata +17 -3
data/lib/discorb/gateway.rb
CHANGED
@@ -14,12 +14,22 @@ module Discorb
|
|
14
14
|
module Gateway
|
15
15
|
#
|
16
16
|
# Represents an event.
|
17
|
+
# @abstract
|
17
18
|
#
|
18
19
|
class GatewayEvent
|
20
|
+
#
|
21
|
+
# Initializes a new instance of the GatewayEvent class.
|
19
22
|
# @private
|
23
|
+
#
|
24
|
+
# @param [Hash] data The data of the event.
|
25
|
+
#
|
20
26
|
def initialize(data)
|
21
27
|
@data = data
|
22
28
|
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
"#<#{self.class}>"
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
#
|
@@ -61,7 +71,13 @@ module Discorb
|
|
61
71
|
alias reactor fired_by
|
62
72
|
alias from fired_by
|
63
73
|
|
74
|
+
#
|
75
|
+
# Initializes a new instance of the ReactionEvent class.
|
64
76
|
# @private
|
77
|
+
#
|
78
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
79
|
+
# @param [Hash] data The data of the event.
|
80
|
+
#
|
65
81
|
def initialize(client, data)
|
66
82
|
@client = client
|
67
83
|
@data = data
|
@@ -121,8 +137,15 @@ module Discorb
|
|
121
137
|
# @macro client_cache
|
122
138
|
# @return [Discorb::User] The user associated with the integration.
|
123
139
|
|
140
|
+
#
|
141
|
+
# Initialize a new instance of the IntegrationDeleteEvent class.
|
124
142
|
# @private
|
125
|
-
|
143
|
+
#
|
144
|
+
#
|
145
|
+
# @param [Hash] data The data of the event.
|
146
|
+
#
|
147
|
+
#
|
148
|
+
def initialize(_client, data)
|
126
149
|
@id = Snowflake.new(data[:id])
|
127
150
|
@guild_id = data[:guild_id]
|
128
151
|
@user_id = data[:application_id]
|
@@ -157,7 +180,13 @@ module Discorb
|
|
157
180
|
# @return [Discorb::Message] The message the reaction was sent in.
|
158
181
|
attr_reader :message
|
159
182
|
|
183
|
+
#
|
184
|
+
# Initialize a new instance of the ReactionRemoveAllEvent class.
|
160
185
|
# @private
|
186
|
+
#
|
187
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
188
|
+
# @param [Hash] data The data of the event.
|
189
|
+
#
|
161
190
|
def initialize(client, data)
|
162
191
|
@client = client
|
163
192
|
@data = data
|
@@ -207,7 +236,13 @@ module Discorb
|
|
207
236
|
# @return [Discorb::UnicodeEmoji, Discorb::PartialEmoji] The emoji that was reacted with.
|
208
237
|
attr_reader :emoji
|
209
238
|
|
239
|
+
#
|
240
|
+
# Initialize a new instance of the ReactionRemoveEmojiEvent class.
|
210
241
|
# @private
|
242
|
+
#
|
243
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
244
|
+
# @param [Hash] data The data of the event.
|
245
|
+
#
|
211
246
|
def initialize(client, data)
|
212
247
|
@client = client
|
213
248
|
@data = data
|
@@ -246,7 +281,13 @@ module Discorb
|
|
246
281
|
attr_reader :guild
|
247
282
|
# @return [Discorb::ScheduledEvent] The scheduled event.
|
248
283
|
attr_reader :scheduled_event
|
284
|
+
#
|
285
|
+
# Initialize a new instance of the ScheduledEventUserEvent class.
|
249
286
|
# @private
|
287
|
+
#
|
288
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
289
|
+
# @param [Hash] data The data of the event.
|
290
|
+
#
|
250
291
|
def initialize(client, data)
|
251
292
|
@client = client
|
252
293
|
@scheduled_event_id = Snowflake.new(data[:scheduled_event_id])
|
@@ -261,7 +302,6 @@ module Discorb
|
|
261
302
|
#
|
262
303
|
# Represents a `MESSAGE_UPDATE` event.
|
263
304
|
#
|
264
|
-
|
265
305
|
class MessageUpdateEvent < GatewayEvent
|
266
306
|
# @return [Discorb::Message] The message before update.
|
267
307
|
attr_reader :before
|
@@ -306,8 +346,8 @@ module Discorb
|
|
306
346
|
@timestamp = Time.iso8601(data[:edited_timestamp])
|
307
347
|
@mention_everyone = data[:mention_everyone]
|
308
348
|
@mention_roles = data[:mention_roles].map { |r| guild.roles[r] } if data.key?(:mention_roles)
|
309
|
-
@attachments = data[:attachments].map { |a| Attachment.
|
310
|
-
@embeds = data[:embeds] ? data[:embeds].map { |e| Embed.
|
349
|
+
@attachments = data[:attachments].map { |a| Attachment.from_hash(a) } if data.key?(:attachments)
|
350
|
+
@embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : [] if data.key?(:embeds)
|
311
351
|
end
|
312
352
|
|
313
353
|
def channel
|
@@ -343,7 +383,13 @@ module Discorb
|
|
343
383
|
# @macro client_cache
|
344
384
|
# @return [Discorb::Guild] The guild the message was sent in.
|
345
385
|
|
386
|
+
#
|
387
|
+
# Initialize a new instance of the UnknownDeleteBulkMessage class.
|
346
388
|
# @private
|
389
|
+
#
|
390
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
391
|
+
# @param [Hash] data The data of the event.
|
392
|
+
#
|
347
393
|
def initialize(client, id, data)
|
348
394
|
@client = client
|
349
395
|
@id = id
|
@@ -375,7 +421,13 @@ module Discorb
|
|
375
421
|
# @macro client_cache
|
376
422
|
# @return [Discorb::Guild] The guild the message was sent in.
|
377
423
|
|
424
|
+
#
|
425
|
+
# Initialize a new instance of the InviteDeleteEvent class.
|
378
426
|
# @private
|
427
|
+
#
|
428
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
429
|
+
# @param [Hash] data The data of the event.
|
430
|
+
#
|
379
431
|
def initialize(client, data)
|
380
432
|
@client = client
|
381
433
|
@data = data
|
@@ -393,18 +445,6 @@ module Discorb
|
|
393
445
|
end
|
394
446
|
end
|
395
447
|
|
396
|
-
class GuildIntegrationsUpdateEvent < GatewayEvent
|
397
|
-
def initialize(client, data)
|
398
|
-
@client = client
|
399
|
-
@data = data
|
400
|
-
@guild_id = Snowflake.new(data[:guild_id])
|
401
|
-
end
|
402
|
-
|
403
|
-
def guild
|
404
|
-
@client.guilds[@guild_id]
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
448
|
#
|
409
449
|
# Represents a `TYPING_START` event.
|
410
450
|
#
|
@@ -428,7 +468,13 @@ module Discorb
|
|
428
468
|
# @macro client_cache
|
429
469
|
# @return [Discorb::Member, Discorb::User] The member or user that started typing.
|
430
470
|
|
471
|
+
#
|
472
|
+
# Initialize a new instance of the TypingStartEvent class.
|
431
473
|
# @private
|
474
|
+
#
|
475
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
476
|
+
# @param [Hash] data The data of the event.
|
477
|
+
#
|
432
478
|
def initialize(client, data)
|
433
479
|
@client = client
|
434
480
|
@data = data
|
@@ -505,7 +551,13 @@ module Discorb
|
|
505
551
|
# @macro client_cache
|
506
552
|
# @return [Discorb::Guild] The guild where the webhook was updated.
|
507
553
|
|
554
|
+
#
|
555
|
+
# Initialize a new instance of the WebhooksUpdateEvent class.
|
508
556
|
# @private
|
557
|
+
#
|
558
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
559
|
+
# @param [Hash] data The data of the event.
|
560
|
+
#
|
509
561
|
def initialize(client, data)
|
510
562
|
@client = client
|
511
563
|
@data = data
|
@@ -528,26 +580,28 @@ module Discorb
|
|
528
580
|
module Handler
|
529
581
|
private
|
530
582
|
|
531
|
-
def connect_gateway(reconnect
|
583
|
+
def connect_gateway(reconnect)
|
532
584
|
if reconnect
|
533
585
|
@log.info "Reconnecting to gateway..."
|
534
586
|
else
|
535
587
|
@log.info "Connecting to gateway..."
|
536
588
|
end
|
537
589
|
Async do
|
538
|
-
if @connection
|
590
|
+
if @connection && !@connection.closed?
|
539
591
|
Async do
|
540
|
-
|
541
|
-
@connection.force_close
|
542
|
-
else
|
543
|
-
@connection.close
|
544
|
-
end
|
592
|
+
@connection.close
|
545
593
|
end
|
546
594
|
end
|
547
595
|
@http = HTTP.new(self)
|
548
596
|
_, gateway_response = @http.request(Route.new("/gateway", "//gateway", :get)).wait
|
549
597
|
gateway_url = gateway_response[:url]
|
550
|
-
|
598
|
+
gateway_version = if @intents.to_h[:message_content].nil?
|
599
|
+
warn "message_content intent not set, using gateway version 9. You should specify `message_content` intent for preventing unexpected changes in the future."
|
600
|
+
9
|
601
|
+
else
|
602
|
+
10
|
603
|
+
end
|
604
|
+
endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=#{gateway_version}&encoding=json&compress=zlib-stream",
|
551
605
|
alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
|
552
606
|
begin
|
553
607
|
@connection = Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
|
@@ -578,7 +632,8 @@ module Discorb
|
|
578
632
|
Errno::ECONNRESET,
|
579
633
|
IOError => e
|
580
634
|
@log.error "Gateway connection closed accidentally: #{e.class}: #{e.message}"
|
581
|
-
|
635
|
+
@connection.force_close
|
636
|
+
connect_gateway(true)
|
582
637
|
else # should never happen
|
583
638
|
connect_gateway(true)
|
584
639
|
end
|
@@ -593,13 +648,13 @@ module Discorb
|
|
593
648
|
when 4014
|
594
649
|
raise ClientError.new("Disallowed intents were specified"), cause: nil
|
595
650
|
when 4002, 4003, 4005, 4007
|
596
|
-
raise ClientError.new(<<~
|
597
|
-
|
598
|
-
|
651
|
+
raise ClientError.new(<<~ERROR), cause: e
|
652
|
+
Disconnected from gateway, probably due to library issues.
|
653
|
+
#{e.message}
|
599
654
|
|
600
|
-
|
601
|
-
|
602
|
-
|
655
|
+
Please report this to the library issue tracker.
|
656
|
+
https://github.com/discorb-lib/discorb/issues
|
657
|
+
ERROR
|
603
658
|
when 1001
|
604
659
|
@log.info "Gateway closed with code 1001, reconnecting."
|
605
660
|
connect_gateway(true)
|
@@ -608,8 +663,9 @@ module Discorb
|
|
608
663
|
@log.debug "#{e.message}"
|
609
664
|
connect_gateway(false)
|
610
665
|
end
|
611
|
-
rescue => e
|
666
|
+
rescue StandardError => e
|
612
667
|
@log.error "Discord WebSocket error: #{e.full_message}"
|
668
|
+
@connection.force_close
|
613
669
|
connect_gateway(false)
|
614
670
|
end
|
615
671
|
end
|
@@ -622,7 +678,7 @@ module Discorb
|
|
622
678
|
end
|
623
679
|
|
624
680
|
def handle_gateway(payload, reconnect)
|
625
|
-
Async do |
|
681
|
+
Async do |_task|
|
626
682
|
data = payload[:d]
|
627
683
|
@last_s = payload[:s] if payload[:s]
|
628
684
|
@log.debug "Received message with opcode #{payload[:op]} from gateway:"
|
@@ -648,7 +704,7 @@ module Discorb
|
|
648
704
|
send_gateway(2, **payload)
|
649
705
|
end
|
650
706
|
when 7
|
651
|
-
@log.info "Received opcode 7,
|
707
|
+
@log.info "Received opcode 7, stopping tasks"
|
652
708
|
@tasks.map(&:stop)
|
653
709
|
when 9
|
654
710
|
@log.warn "Received opcode 9, closed connection"
|
@@ -673,7 +729,7 @@ module Discorb
|
|
673
729
|
end
|
674
730
|
|
675
731
|
def handle_heartbeat
|
676
|
-
Async do |
|
732
|
+
Async do |_task|
|
677
733
|
interval = @heartbeat_interval
|
678
734
|
sleep((interval / 1000.0 - 1) * rand)
|
679
735
|
loop do
|
@@ -700,9 +756,7 @@ module Discorb
|
|
700
756
|
@session_id = data[:session_id]
|
701
757
|
@user = ClientUser.new(self, data[:user])
|
702
758
|
@uncached_guilds = data[:guilds].map { |g| g[:id] }
|
703
|
-
if @uncached_guilds == []
|
704
|
-
ready
|
705
|
-
end
|
759
|
+
ready if (@uncached_guilds == []) || !@intents.guilds
|
706
760
|
dispatch(:ready)
|
707
761
|
@tasks << handle_heartbeat
|
708
762
|
when "GUILD_CREATE"
|
@@ -714,7 +768,7 @@ module Discorb
|
|
714
768
|
ready
|
715
769
|
end
|
716
770
|
elsif @guilds.has?(data[:id])
|
717
|
-
@guilds[data[:id]].send(:_set_data, data)
|
771
|
+
@guilds[data[:id]].send(:_set_data, data, true)
|
718
772
|
dispatch(:guild_available, guild)
|
719
773
|
else
|
720
774
|
guild = Guild.new(self, data, true)
|
@@ -737,7 +791,7 @@ module Discorb
|
|
737
791
|
return @log.warn "Unknown guild id #{data[:id]}, ignoring" unless (guild = @guilds.delete(data[:id]))
|
738
792
|
|
739
793
|
dispatch(:guild_delete, guild)
|
740
|
-
if
|
794
|
+
if data[:unavailable]
|
741
795
|
dispatch(:guild_destroy, guild)
|
742
796
|
else
|
743
797
|
dispatch(:guild_leave, guild)
|
@@ -811,7 +865,7 @@ module Discorb
|
|
811
865
|
|
812
866
|
if (member = thread.members[data[:id]])
|
813
867
|
old = ThreadChannel::Member.new(self, member.instance_variable_get(:@data))
|
814
|
-
member._set_data
|
868
|
+
member.send(:_set_data, data)
|
815
869
|
else
|
816
870
|
old = nil
|
817
871
|
member = ThreadChannel::Member.new(self, data)
|
@@ -898,14 +952,13 @@ module Discorb
|
|
898
952
|
guild.emojis.delete(emoji)
|
899
953
|
end
|
900
954
|
when "GUILD_INTEGRATIONS_UPDATE"
|
901
|
-
|
902
|
-
# Currently not implemented
|
955
|
+
dispatch(:guild_integrations_update, @guilds[data[:guild_id]])
|
903
956
|
when "INTEGRATION_CREATE"
|
904
957
|
dispatch(:integration_create, Integration.new(self, data, data[:guild_id]))
|
905
958
|
when "INTEGRATION_UPDATE"
|
906
959
|
return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
907
960
|
|
908
|
-
|
961
|
+
integration = Integration.new(self, data, data[:guild_id])
|
909
962
|
dispatch(:integration_update, integration)
|
910
963
|
when "INTEGRATION_DELETE"
|
911
964
|
return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
@@ -1091,12 +1144,12 @@ module Discorb
|
|
1091
1144
|
(target_reaction = target_message.reactions.find { |r| data[:emoji][:id].nil? ? r.name == data[:emoji][:name] : r.id == data[:emoji][:id] })
|
1092
1145
|
target_message.reactions.delete(target_reaction)
|
1093
1146
|
end
|
1094
|
-
dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(data))
|
1147
|
+
dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(self, data))
|
1095
1148
|
when "TYPING_START"
|
1096
1149
|
dispatch(:typing_start, TypingStartEvent.new(self, data))
|
1097
1150
|
when "INTERACTION_CREATE"
|
1098
1151
|
interaction = Interaction.make_interaction(self, data)
|
1099
|
-
dispatch(:
|
1152
|
+
dispatch(:interaction_create, interaction)
|
1100
1153
|
|
1101
1154
|
dispatch(interaction.class.event_name, interaction)
|
1102
1155
|
when "RESUMED"
|
@@ -1114,15 +1167,15 @@ module Discorb
|
|
1114
1167
|
old = event.dup
|
1115
1168
|
event.send(:_set_data, data)
|
1116
1169
|
dispatch(:scheduled_event_update, old, event)
|
1117
|
-
if old.status
|
1170
|
+
if old.status == event.status
|
1171
|
+
dispatch(:scheduled_event_edit, old, event)
|
1172
|
+
else
|
1118
1173
|
case event.status
|
1119
1174
|
when :active
|
1120
1175
|
dispatch(:scheduled_event_start, event)
|
1121
1176
|
when :completed
|
1122
1177
|
dispatch(:scheduled_event_end, event)
|
1123
1178
|
end
|
1124
|
-
else
|
1125
|
-
dispatch(:scheduled_event_edit, old, event)
|
1126
1179
|
end
|
1127
1180
|
when "GUILD_SCHEDULED_EVENT_DELETE"
|
1128
1181
|
@log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
|
@@ -1175,6 +1228,10 @@ module Discorb
|
|
1175
1228
|
@closed = false
|
1176
1229
|
end
|
1177
1230
|
|
1231
|
+
def inspect
|
1232
|
+
"<#{self.class.name} #{io.fileno}>"
|
1233
|
+
end
|
1234
|
+
|
1178
1235
|
def closed?
|
1179
1236
|
@closed
|
1180
1237
|
end
|
@@ -1182,15 +1239,19 @@ module Discorb
|
|
1182
1239
|
def close
|
1183
1240
|
super
|
1184
1241
|
@closed = true
|
1185
|
-
rescue
|
1242
|
+
rescue StandardError
|
1186
1243
|
force_close
|
1187
1244
|
end
|
1188
1245
|
|
1189
1246
|
def force_close
|
1190
|
-
|
1247
|
+
io.close
|
1191
1248
|
@closed = true
|
1192
1249
|
end
|
1193
1250
|
|
1251
|
+
def io
|
1252
|
+
@framer.instance_variable_get(:@stream).instance_variable_get(:@io).instance_variable_get(:@io).instance_variable_get(:@io)
|
1253
|
+
end
|
1254
|
+
|
1194
1255
|
def parse(buffer)
|
1195
1256
|
# noop
|
1196
1257
|
buffer.to_s
|
@@ -5,7 +5,9 @@ module Discorb
|
|
5
5
|
# Represents an activity for Gateway Command.
|
6
6
|
#
|
7
7
|
class Activity
|
8
|
-
@
|
8
|
+
# @private
|
9
|
+
# @return [{Symbol => Integer}] The mapping of activity types.
|
10
|
+
TYPES = {
|
9
11
|
playing: 0,
|
10
12
|
streaming: 1,
|
11
13
|
listening: 2,
|
@@ -22,7 +24,7 @@ module Discorb
|
|
22
24
|
#
|
23
25
|
def initialize(name, type = :playing, url = nil)
|
24
26
|
@name = name
|
25
|
-
@type =
|
27
|
+
@type = TYPES[type] or raise ArgumentError, "Invalid activity type: #{type}"
|
26
28
|
@url = url
|
27
29
|
end
|
28
30
|
|
@@ -42,10 +44,5 @@ module Discorb
|
|
42
44
|
def inspect
|
43
45
|
"#<#{self.class} @type=#{@type}>"
|
44
46
|
end
|
45
|
-
|
46
|
-
class << self
|
47
|
-
# @private
|
48
|
-
attr_reader :types
|
49
|
-
end
|
50
47
|
end
|
51
48
|
end
|
data/lib/discorb/guild.rb
CHANGED
@@ -115,27 +115,36 @@ module Discorb
|
|
115
115
|
# @!attribute [r] me
|
116
116
|
# @return [Discorb::Member] The client's member in the guild.
|
117
117
|
|
118
|
-
@
|
119
|
-
@
|
120
|
-
|
121
|
-
@
|
122
|
-
@
|
118
|
+
# @private
|
119
|
+
# @return [Array<Symbol>] The mapping of mfa_level.
|
120
|
+
MFA_LEVELS = %i[none elevated].freeze
|
121
|
+
# @private
|
122
|
+
# @return [Array<Symbol>] The mapping of nsfw_level.
|
123
|
+
NSFW_LEVELS = %i[default explicit safe age_restricted].freeze
|
124
|
+
# @private
|
125
|
+
# @return [Array<Symbol>] The mapping of verification_level.
|
126
|
+
VERIFICATION_LEVELS = %i[none low medium high very_high].freeze
|
127
|
+
# @private
|
128
|
+
# @return [Array<Symbol>] The mapping of default_message_notifications.
|
129
|
+
DEFAULT_MESSAGE_NOTIFICATIONS = %i[all_messages only_mentions].freeze
|
130
|
+
# @private
|
131
|
+
# @return [Array<Symbol>] The mapping of explicit_content_filter.
|
132
|
+
EXPLICIT_CONTENT_FILTER = %i[disabled_in_text members_without_roles all_members].freeze
|
123
133
|
|
134
|
+
#
|
135
|
+
# Creates a new guild object.
|
124
136
|
# @private
|
137
|
+
#
|
138
|
+
# @param [Discorb::Client] client The client that owns this guild.
|
139
|
+
# @param [Hash] data The data of the guild.
|
140
|
+
# @param [Boolean] is_create_event Whether the guild is created by a `GUILD_CREATE` event.
|
141
|
+
#
|
125
142
|
def initialize(client, data, is_create_event)
|
126
143
|
@client = client
|
127
144
|
@data = {}
|
128
145
|
_set_data(data, is_create_event)
|
129
146
|
end
|
130
147
|
|
131
|
-
# @private
|
132
|
-
def update!
|
133
|
-
Async do
|
134
|
-
_, data = @client.get("/guilds/#{@id}").wait
|
135
|
-
_set_data(data, false)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
148
|
def afk_channel
|
140
149
|
@client.channels[@afk_channel_id]
|
141
150
|
end
|
@@ -242,9 +251,9 @@ module Discorb
|
|
242
251
|
description: description,
|
243
252
|
scheduled_start_time: start_time.iso8601,
|
244
253
|
scheduled_end_time: end_time&.iso8601,
|
245
|
-
privacy_level: Discorb::ScheduledEvent.
|
254
|
+
privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
|
246
255
|
channel_id: channel&.id,
|
247
|
-
entity_type: Discorb::ScheduledEvent.
|
256
|
+
entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:stage_instance),
|
248
257
|
}
|
249
258
|
when :voice
|
250
259
|
raise ArgumentError, "channel must be provided for voice events" unless channel
|
@@ -253,9 +262,9 @@ module Discorb
|
|
253
262
|
description: description,
|
254
263
|
scheduled_start_time: start_time.iso8601,
|
255
264
|
scheduled_end_time: end_time&.iso8601,
|
256
|
-
privacy_level: Discorb::ScheduledEvent.
|
265
|
+
privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
|
257
266
|
channel_id: channel&.id,
|
258
|
-
entity_type: Discorb::ScheduledEvent.
|
267
|
+
entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:voice),
|
259
268
|
}
|
260
269
|
when :external
|
261
270
|
raise ArgumentError, "location must be provided for external events" unless location
|
@@ -265,8 +274,8 @@ module Discorb
|
|
265
274
|
description: description,
|
266
275
|
scheduled_start_time: start_time.iso8601,
|
267
276
|
scheduled_end_time: end_time.iso8601,
|
268
|
-
privacy_level: Discorb::ScheduledEvent.
|
269
|
-
entity_type: Discorb::ScheduledEvent.
|
277
|
+
privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
|
278
|
+
entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:external),
|
270
279
|
entity_metadata: {
|
271
280
|
location: location,
|
272
281
|
},
|
@@ -614,7 +623,7 @@ module Discorb
|
|
614
623
|
#
|
615
624
|
def fetch_members(limit: 0, after: nil)
|
616
625
|
Async do
|
617
|
-
unless limit
|
626
|
+
unless limit.zero?
|
618
627
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/members?#{URI.encode_www_form({ after: after, limit: limit })}", "//guilds/:guild_id/members", :get)).wait
|
619
628
|
next data[:members].map { |m| Member.new(@client, @id, m[:user], m) }
|
620
629
|
end
|
@@ -625,9 +634,7 @@ module Discorb
|
|
625
634
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/members?#{URI.encode_www_form(params)}", "//guilds/:guild_id/members", :get)).wait
|
626
635
|
ret += data.map { |m| Member.new(@client, @id, m[:user], m) }
|
627
636
|
after = data.last[:user][:id]
|
628
|
-
if data.length != 1000
|
629
|
-
break
|
630
|
-
end
|
637
|
+
break if data.length != 1000
|
631
638
|
end
|
632
639
|
ret
|
633
640
|
end
|
@@ -860,7 +867,7 @@ module Discorb
|
|
860
867
|
def fetch_voice_regions
|
861
868
|
Async do
|
862
869
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/voice", "//guilds/:guild_id/voice", :get)).wait
|
863
|
-
data.map { |d| VoiceRegion.new(
|
870
|
+
data.map { |d| VoiceRegion.new(d) }
|
864
871
|
end
|
865
872
|
end
|
866
873
|
|
@@ -873,7 +880,7 @@ module Discorb
|
|
873
880
|
def fetch_invites
|
874
881
|
Async do
|
875
882
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/invites", "//guilds/:guild_id/invites", :get)).wait
|
876
|
-
data.map { |d| Invite.new(@client, d) }
|
883
|
+
data.map { |d| Invite.new(@client, d, false) }
|
877
884
|
end
|
878
885
|
end
|
879
886
|
|
@@ -886,7 +893,7 @@ module Discorb
|
|
886
893
|
def fetch_integrations
|
887
894
|
Async do
|
888
895
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/integrations", "//guilds/:guild_id/integrations", :get)).wait
|
889
|
-
data.map { |d| Integration.new(@client, d) }
|
896
|
+
data.map { |d| Integration.new(@client, d, @id) }
|
890
897
|
end
|
891
898
|
end
|
892
899
|
|
@@ -1014,7 +1021,14 @@ module Discorb
|
|
1014
1021
|
# @!attribute [r] url
|
1015
1022
|
# @return [String] The vanity URL.
|
1016
1023
|
|
1024
|
+
#
|
1025
|
+
# Initialize a new instance of the {VanityInvite} class.
|
1017
1026
|
# @private
|
1027
|
+
#
|
1028
|
+
# @param [Discorb::Client] client The client.
|
1029
|
+
# @param [Discorb::Guild] guild The guild.
|
1030
|
+
# @param [Hash] data The data of the invite.
|
1031
|
+
#
|
1018
1032
|
def initialize(client, guild, data)
|
1019
1033
|
@client = client
|
1020
1034
|
@guild = guild
|
@@ -1049,7 +1063,14 @@ module Discorb
|
|
1049
1063
|
# @!attribute [r] json_url
|
1050
1064
|
# @return [String] The JSON URL.
|
1051
1065
|
|
1066
|
+
#
|
1067
|
+
# Initialize a new instance of the {Widget} class.
|
1052
1068
|
# @private
|
1069
|
+
#
|
1070
|
+
# @param [Discorb::Client] client The client.
|
1071
|
+
# @param [Discorb::Snowflake] guild_id The guild ID.
|
1072
|
+
# @param [Hash] data The data from Discord.
|
1073
|
+
#
|
1053
1074
|
def initialize(client, guild_id, data)
|
1054
1075
|
@client = client
|
1055
1076
|
@enabled = data[:enabled]
|
@@ -1113,7 +1134,14 @@ module Discorb
|
|
1113
1134
|
# @return [String] The reason for the ban.
|
1114
1135
|
attr_reader :reason
|
1115
1136
|
|
1137
|
+
#
|
1138
|
+
# Initialize a new instance of the {Ban} class.
|
1116
1139
|
# @private
|
1140
|
+
#
|
1141
|
+
# @param [Discorb::Client] client The client.
|
1142
|
+
# @param [Discorb::Guild] guild The guild.
|
1143
|
+
# @param [Hash] data The data from Discord.
|
1144
|
+
#
|
1117
1145
|
def initialize(client, guild, data)
|
1118
1146
|
@client = client
|
1119
1147
|
@guild = guild
|
@@ -1123,9 +1151,6 @@ module Discorb
|
|
1123
1151
|
end
|
1124
1152
|
|
1125
1153
|
class << self
|
1126
|
-
# @private
|
1127
|
-
attr_reader :nsfw_levels, :mfa_levels, :verification_levels, :default_message_notifications, :explicit_content_filter
|
1128
|
-
|
1129
1154
|
#
|
1130
1155
|
# Returns a banner url from the guild's ID.
|
1131
1156
|
#
|
@@ -1152,9 +1177,9 @@ module Discorb
|
|
1152
1177
|
@unavailable = false
|
1153
1178
|
@name = data[:name]
|
1154
1179
|
@members = Discorb::Dictionary.new
|
1155
|
-
data[:members]
|
1180
|
+
data[:members]&.each do |m|
|
1156
1181
|
Member.new(@client, @id, m[:user], m)
|
1157
|
-
end
|
1182
|
+
end
|
1158
1183
|
@splash = data[:splash] && Asset.new(self, data[:splash], path: "splashes/#{@id}")
|
1159
1184
|
@discovery_splash = data[:discovery_splash] && Asset.new(self, data[:discovery_splash], path: "discovery-splashes/#{@id}")
|
1160
1185
|
@owner_id = data[:owner_id]
|
@@ -1172,10 +1197,10 @@ module Discorb
|
|
1172
1197
|
@emojis[e[:id]] = CustomEmoji.new(@client, self, e)
|
1173
1198
|
end
|
1174
1199
|
@features = data[:features].map { |f| f.downcase.to_sym }
|
1175
|
-
@mfa_level =
|
1176
|
-
@verification_level =
|
1177
|
-
@default_message_notifications =
|
1178
|
-
@explicit_content_filter =
|
1200
|
+
@mfa_level = MFA_LEVELS[data[:mfa_level]]
|
1201
|
+
@verification_level = VERIFICATION_LEVELS[data[:verification_level]]
|
1202
|
+
@default_message_notifications = DEFAULT_MESSAGE_NOTIFICATIONS[data[:default_message_notifications]]
|
1203
|
+
@explicit_content_filter = EXPLICIT_CONTENT_FILTER[data[:explicit_content_filter]]
|
1179
1204
|
@system_channel_id = data[:system_channel_id]
|
1180
1205
|
@system_channel_flag = SystemChannelFlag.new(0b111 - data[:system_channel_flags])
|
1181
1206
|
@rules_channel_id = data[:rules_channel_id]
|
@@ -1190,7 +1215,7 @@ module Discorb
|
|
1190
1215
|
@approximate_member_count = data[:approximate_member_count]
|
1191
1216
|
@approximate_presence_count = data[:approximate_presence_count]
|
1192
1217
|
@welcome_screen = data[:welcome_screen].nil? ? nil : WelcomeScreen.new(@client, self, data[:welcome_screen])
|
1193
|
-
@nsfw_level =
|
1218
|
+
@nsfw_level = NSFW_LEVELS[data[:nsfw_level]]
|
1194
1219
|
return unless is_create_event
|
1195
1220
|
|
1196
1221
|
@stickers = data[:stickers].nil? ? [] : data[:stickers].map { |s| Sticker::GuildSticker.new(self, s) }
|
@@ -1200,13 +1225,13 @@ module Discorb
|
|
1200
1225
|
tmp_channels = data[:channels].filter { |c| !c.key?(:thread_metadata) }.map do |c|
|
1201
1226
|
Channel.make_channel(@client, c.merge({ guild_id: @id }))
|
1202
1227
|
end
|
1203
|
-
@channels = Dictionary.new(tmp_channels.
|
1204
|
-
@voice_states = Dictionary.new(data[:voice_states].
|
1228
|
+
@channels = Dictionary.new(tmp_channels.to_h { |c| [c.id, c] }, sort: ->(c) { c[1].position })
|
1229
|
+
@voice_states = Dictionary.new(data[:voice_states].to_h { |v| [Snowflake.new(v[:user_id]), VoiceState.new(@client, v.merge({ guild_id: @id }))] })
|
1205
1230
|
@threads = data[:threads] ? data[:threads].map { |t| Channel.make_channel(@client, t) } : []
|
1206
|
-
@presences = Dictionary.new(data[:presences].
|
1231
|
+
@presences = Dictionary.new(data[:presences].to_h { |pr| [Snowflake.new(pr[:user][:id]), Presence.new(@client, pr)] })
|
1207
1232
|
@max_presences = data[:max_presences]
|
1208
|
-
@stage_instances = Dictionary.new(data[:stage_instances].
|
1209
|
-
@scheduled_events = Dictionary.new(data[:guild_scheduled_events].
|
1233
|
+
@stage_instances = Dictionary.new(data[:stage_instances].to_h { |s| [Snowflake.new(s[:id]), StageInstance.new(@client, s)] })
|
1234
|
+
@scheduled_events = Dictionary.new(data[:guild_scheduled_events].to_h { |s| [Snowflake.new(s[:id]), ScheduledEvent.new(@client, s)] })
|
1210
1235
|
@data.update(data)
|
1211
1236
|
end
|
1212
1237
|
end
|
@@ -1241,7 +1266,14 @@ module Discorb
|
|
1241
1266
|
# @return [Discorb::Guild] The guild the welcome screen belongs to.
|
1242
1267
|
attr_reader :guild
|
1243
1268
|
|
1269
|
+
#
|
1270
|
+
# Initializes the welcome screen.
|
1244
1271
|
# @private
|
1272
|
+
#
|
1273
|
+
# @param [Discorb::Client] client The client.
|
1274
|
+
# @param [Discorb::Guild] guild The guild the welcome screen belongs to.
|
1275
|
+
# @param [Hash] data The data of the welcome screen.
|
1276
|
+
#
|
1245
1277
|
def initialize(client, guild, data)
|
1246
1278
|
@client = client
|
1247
1279
|
@description = data[:description]
|