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