discorb 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/build_version.yml +1 -1
- data/.github/workflows/lint-push.yml +4 -2
- data/.rubocop.yml +6 -2
- data/Changelog.md +27 -0
- data/Rakefile +6 -0
- data/docs/events.md +71 -5
- data/docs/faq.md +8 -8
- data/examples/simple/rolepanel.rb +1 -1
- data/examples/simple/shard.rb +17 -0
- data/lib/discorb/allowed_mentions.rb +7 -0
- data/lib/discorb/app_command/command.rb +64 -2
- data/lib/discorb/app_command/handler.rb +1 -1
- data/lib/discorb/application.rb +16 -7
- data/lib/discorb/asset.rb +9 -0
- data/lib/discorb/{file.rb → attachment.rb} +55 -33
- data/lib/discorb/audit_logs.rb +42 -4
- data/lib/discorb/channel.rb +47 -12
- data/lib/discorb/client.rb +135 -51
- data/lib/discorb/common.rb +18 -4
- data/lib/discorb/components/button.rb +5 -6
- data/lib/discorb/components/select_menu.rb +2 -16
- data/lib/discorb/dictionary.rb +2 -0
- data/lib/discorb/embed.rb +71 -38
- data/lib/discorb/emoji.rb +29 -2
- data/lib/discorb/emoji_table.rb +1 -1
- data/lib/discorb/error.rb +7 -1
- data/lib/discorb/event.rb +27 -17
- data/lib/discorb/exe/new.rb +5 -5
- data/lib/discorb/exe/run.rb +1 -15
- data/lib/discorb/gateway.rb +262 -161
- data/lib/discorb/gateway_requests.rb +4 -7
- data/lib/discorb/guild.rb +67 -33
- data/lib/discorb/guild_template.rb +24 -3
- data/lib/discorb/http.rb +25 -3
- data/lib/discorb/integration.rb +23 -8
- data/lib/discorb/intents.rb +15 -10
- data/lib/discorb/interaction/autocomplete.rb +4 -4
- data/lib/discorb/interaction/command.rb +34 -5
- data/lib/discorb/interaction/components.rb +15 -2
- data/lib/discorb/interaction/response.rb +12 -0
- data/lib/discorb/interaction/root.rb +16 -1
- data/lib/discorb/invite.rb +11 -7
- data/lib/discorb/member.rb +21 -0
- data/lib/discorb/message.rb +59 -3
- data/lib/discorb/message_meta.rb +36 -55
- data/lib/discorb/modules.rb +38 -14
- data/lib/discorb/permission.rb +14 -5
- data/lib/discorb/presence.rb +41 -8
- data/lib/discorb/rate_limit.rb +7 -2
- data/lib/discorb/reaction.rb +6 -0
- data/lib/discorb/role.rb +12 -0
- data/lib/discorb/shard.rb +74 -0
- data/lib/discorb/sticker.rb +22 -14
- data/lib/discorb/user.rb +11 -0
- data/lib/discorb/voice_state.rb +20 -2
- data/lib/discorb/webhook.rb +53 -2
- data/lib/discorb.rb +5 -3
- data/sig/discorb.rbs +7234 -6714
- metadata +5 -4
- data/lib/discorb/log.rb +0 -81
data/lib/discorb/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,7 +137,14 @@ 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
|
143
|
+
#
|
144
|
+
#
|
145
|
+
# @param [Hash] data The data of the event.
|
146
|
+
#
|
147
|
+
#
|
125
148
|
def initialize(_client, data)
|
126
149
|
@id = Snowflake.new(data[:id])
|
127
150
|
@guild_id = data[:guild_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])
|
@@ -305,8 +346,8 @@ module Discorb
|
|
305
346
|
@timestamp = Time.iso8601(data[:edited_timestamp])
|
306
347
|
@mention_everyone = data[:mention_everyone]
|
307
348
|
@mention_roles = data[:mention_roles].map { |r| guild.roles[r] } if data.key?(:mention_roles)
|
308
|
-
@attachments = data[:attachments].map { |a| Attachment.
|
309
|
-
@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)
|
310
351
|
end
|
311
352
|
|
312
353
|
def channel
|
@@ -342,7 +383,13 @@ module Discorb
|
|
342
383
|
# @macro client_cache
|
343
384
|
# @return [Discorb::Guild] The guild the message was sent in.
|
344
385
|
|
386
|
+
#
|
387
|
+
# Initialize a new instance of the UnknownDeleteBulkMessage class.
|
345
388
|
# @private
|
389
|
+
#
|
390
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
391
|
+
# @param [Hash] data The data of the event.
|
392
|
+
#
|
346
393
|
def initialize(client, id, data)
|
347
394
|
@client = client
|
348
395
|
@id = id
|
@@ -374,7 +421,13 @@ module Discorb
|
|
374
421
|
# @macro client_cache
|
375
422
|
# @return [Discorb::Guild] The guild the message was sent in.
|
376
423
|
|
424
|
+
#
|
425
|
+
# Initialize a new instance of the InviteDeleteEvent class.
|
377
426
|
# @private
|
427
|
+
#
|
428
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
429
|
+
# @param [Hash] data The data of the event.
|
430
|
+
#
|
378
431
|
def initialize(client, data)
|
379
432
|
@client = client
|
380
433
|
@data = data
|
@@ -392,21 +445,6 @@ module Discorb
|
|
392
445
|
end
|
393
446
|
end
|
394
447
|
|
395
|
-
#
|
396
|
-
# Represents a `GUILD_INTEGRATIONS_UPDATE` event.
|
397
|
-
#
|
398
|
-
class GuildIntegrationsUpdateEvent < GatewayEvent
|
399
|
-
def initialize(client, data)
|
400
|
-
@client = client
|
401
|
-
@data = data
|
402
|
-
@guild_id = Snowflake.new(data[:guild_id])
|
403
|
-
end
|
404
|
-
|
405
|
-
def guild
|
406
|
-
@client.guilds[@guild_id]
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
448
|
#
|
411
449
|
# Represents a `TYPING_START` event.
|
412
450
|
#
|
@@ -430,7 +468,13 @@ module Discorb
|
|
430
468
|
# @macro client_cache
|
431
469
|
# @return [Discorb::Member, Discorb::User] The member or user that started typing.
|
432
470
|
|
471
|
+
#
|
472
|
+
# Initialize a new instance of the TypingStartEvent class.
|
433
473
|
# @private
|
474
|
+
#
|
475
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
476
|
+
# @param [Hash] data The data of the event.
|
477
|
+
#
|
434
478
|
def initialize(client, data)
|
435
479
|
@client = client
|
436
480
|
@data = data
|
@@ -507,7 +551,13 @@ module Discorb
|
|
507
551
|
# @macro client_cache
|
508
552
|
# @return [Discorb::Guild] The guild where the webhook was updated.
|
509
553
|
|
554
|
+
#
|
555
|
+
# Initialize a new instance of the WebhooksUpdateEvent class.
|
510
556
|
# @private
|
557
|
+
#
|
558
|
+
# @param [Discorb::Client] client The client that instantiated the object.
|
559
|
+
# @param [Hash] data The data of the event.
|
560
|
+
#
|
511
561
|
def initialize(client, data)
|
512
562
|
@client = client
|
513
563
|
@data = data
|
@@ -531,109 +581,129 @@ module Discorb
|
|
531
581
|
private
|
532
582
|
|
533
583
|
def connect_gateway(reconnect)
|
534
|
-
if reconnect
|
535
|
-
@log.info "Reconnecting to gateway..."
|
536
|
-
else
|
537
|
-
@log.info "Connecting to gateway..."
|
538
|
-
end
|
539
584
|
Async do
|
540
|
-
|
541
|
-
|
542
|
-
|
585
|
+
@mutex["gateway_#{shard_id}"] ||= Mutex.new
|
586
|
+
@mutex["gateway_#{shard_id}"].synchronize do
|
587
|
+
if reconnect
|
588
|
+
logger.info "Reconnecting to gateway..."
|
589
|
+
else
|
590
|
+
logger.info "Connecting to gateway..."
|
543
591
|
end
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
592
|
+
|
593
|
+
@http = HTTP.new(self)
|
594
|
+
_, gateway_response = @http.request(Route.new("/gateway", "//gateway", :get)).wait
|
595
|
+
gateway_url = gateway_response[:url]
|
596
|
+
gateway_version = if @intents.to_h[:message_content].nil?
|
597
|
+
warn "message_content intent not set, using gateway version 9. You should specify `message_content` intent for preventing unexpected changes in the future."
|
598
|
+
9
|
599
|
+
else
|
600
|
+
10
|
601
|
+
end
|
602
|
+
endpoint = Async::HTTP::Endpoint.parse(
|
603
|
+
"#{gateway_url}?v=#{gateway_version}&encoding=json&compress=zlib-stream&_=#{Time.now.to_i}",
|
604
|
+
alpn_protocols: Async::HTTP::Protocol::HTTP11.names,
|
605
|
+
)
|
554
606
|
begin
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
607
|
+
self.connection = Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
|
608
|
+
zlib_stream = Zlib::Inflate.new(Zlib::MAX_WBITS)
|
609
|
+
buffer = +""
|
610
|
+
begin
|
611
|
+
while (message = connection.read)
|
612
|
+
buffer << message
|
613
|
+
if message.end_with?((+"\x00\x00\xff\xff").force_encoding("ASCII-8BIT"))
|
614
|
+
begin
|
615
|
+
data = zlib_stream.inflate(buffer)
|
616
|
+
buffer = +""
|
617
|
+
message = JSON.parse(data, symbolize_names: true)
|
618
|
+
rescue JSON::ParserError
|
619
|
+
buffer = +""
|
620
|
+
logger.error "Received invalid JSON from gateway."
|
621
|
+
logger.debug "#{data}"
|
622
|
+
else
|
623
|
+
handle_gateway(message, reconnect)
|
624
|
+
end
|
568
625
|
end
|
569
626
|
end
|
627
|
+
rescue Async::Wrapper::Cancelled,
|
628
|
+
OpenSSL::SSL::SSLError,
|
629
|
+
Async::Wrapper::WaitError,
|
630
|
+
EOFError,
|
631
|
+
Errno::EPIPE,
|
632
|
+
Errno::ECONNRESET,
|
633
|
+
IOError => e
|
634
|
+
next if @status == :closed
|
635
|
+
logger.error "Gateway connection closed accidentally: #{e.class}: #{e.message}"
|
636
|
+
connection.force_close
|
637
|
+
connect_gateway(true)
|
638
|
+
next
|
570
639
|
end
|
571
|
-
rescue
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
@log.error "Discord WebSocket closed with code #{e.code}."
|
607
|
-
@log.debug "#{e.message}"
|
640
|
+
rescue Protocol::WebSocket::ClosedError => e
|
641
|
+
@tasks.map(&:stop)
|
642
|
+
case e.code
|
643
|
+
when 4004
|
644
|
+
raise ClientError.new("Authentication failed"), cause: nil
|
645
|
+
when 4009
|
646
|
+
logger.info "Session timed out, reconnecting."
|
647
|
+
connection.force_close
|
648
|
+
connect_gateway(true)
|
649
|
+
next
|
650
|
+
when 4014
|
651
|
+
raise ClientError.new("Disallowed intents were specified"), cause: nil
|
652
|
+
when 4001, 4002, 4003, 4005, 4007
|
653
|
+
raise ClientError.new(<<~ERROR), cause: e
|
654
|
+
Disconnected from gateway, probably due to library issues.
|
655
|
+
#{e.message}
|
656
|
+
|
657
|
+
Please report this to the library issue tracker.
|
658
|
+
https://github.com/discorb-lib/discorb/issues
|
659
|
+
ERROR
|
660
|
+
when 1001
|
661
|
+
logger.info "Gateway closed with code 1001, reconnecting."
|
662
|
+
connection.force_close
|
663
|
+
connect_gateway(true)
|
664
|
+
next
|
665
|
+
else
|
666
|
+
logger.error "Discord WebSocket closed with code #{e.code}."
|
667
|
+
logger.debug "#{e.message}"
|
668
|
+
connection.force_close
|
669
|
+
connect_gateway(false)
|
670
|
+
next
|
671
|
+
end
|
672
|
+
rescue StandardError => e
|
673
|
+
logger.error "Discord WebSocket error: #{e.full_message}"
|
674
|
+
connection.force_close
|
608
675
|
connect_gateway(false)
|
676
|
+
next
|
609
677
|
end
|
610
|
-
rescue StandardError => e
|
611
|
-
@log.error "Discord WebSocket error: #{e.full_message}"
|
612
|
-
@connection.force_close
|
613
|
-
connect_gateway(false)
|
614
678
|
end
|
615
679
|
end
|
616
680
|
end
|
617
681
|
|
618
682
|
def send_gateway(opcode, **value)
|
619
|
-
@
|
620
|
-
|
621
|
-
|
683
|
+
if @shards.any? && shard.nil?
|
684
|
+
@shards.map(&:connection)
|
685
|
+
else
|
686
|
+
[connection]
|
687
|
+
end.each do |con|
|
688
|
+
con.write({ op: opcode, d: value }.to_json)
|
689
|
+
con.flush
|
690
|
+
end
|
691
|
+
logger.debug "Sent message to fd #{connection.io.fileno}: #{{ op: opcode, d: value }.to_json.gsub(@token, "[Token]")}"
|
622
692
|
end
|
623
693
|
|
624
694
|
def handle_gateway(payload, reconnect)
|
625
695
|
Async do |_task|
|
626
696
|
data = payload[:d]
|
627
697
|
@last_s = payload[:s] if payload[:s]
|
628
|
-
|
629
|
-
|
698
|
+
logger.debug "Received message with opcode #{payload[:op]} from gateway."
|
699
|
+
logger.debug "#{payload.to_json.gsub(@token, "[Token]")}"
|
630
700
|
case payload[:op]
|
631
701
|
when 10
|
632
702
|
@heartbeat_interval = data[:heartbeat_interval]
|
633
703
|
if reconnect
|
634
704
|
payload = {
|
635
705
|
token: @token,
|
636
|
-
session_id:
|
706
|
+
session_id: session_id,
|
637
707
|
seq: @last_s,
|
638
708
|
}
|
639
709
|
send_gateway(6, **payload)
|
@@ -644,27 +714,29 @@ module Discorb
|
|
644
714
|
compress: false,
|
645
715
|
properties: { "$os" => RUBY_PLATFORM, "$browser" => "discorb", "$device" => "discorb" },
|
646
716
|
}
|
717
|
+
payload[:shard] = [shard_id, @shard_count] if shard_id
|
647
718
|
payload[:presence] = @identify_presence if @identify_presence
|
648
719
|
send_gateway(2, **payload)
|
649
720
|
end
|
650
721
|
when 7
|
651
|
-
|
722
|
+
logger.info "Received opcode 7, stopping tasks"
|
652
723
|
@tasks.map(&:stop)
|
653
724
|
when 9
|
654
|
-
|
725
|
+
logger.warn "Received opcode 9, closed connection"
|
655
726
|
@tasks.map(&:stop)
|
656
727
|
if data
|
657
|
-
|
658
|
-
|
728
|
+
logger.info "Connection is resumable, reconnecting"
|
729
|
+
connection.force_close
|
659
730
|
connect_gateway(true)
|
660
731
|
else
|
661
|
-
|
662
|
-
|
732
|
+
logger.info "Connection is not resumable, reconnecting with opcode 2"
|
733
|
+
connection.force_close
|
734
|
+
|
663
735
|
sleep(2)
|
664
736
|
connect_gateway(false)
|
665
737
|
end
|
666
738
|
when 11
|
667
|
-
|
739
|
+
logger.debug "Received opcode 11"
|
668
740
|
@ping = Time.now.to_f - @heartbeat_before
|
669
741
|
when 0
|
670
742
|
handle_event(payload[:t], data)
|
@@ -677,12 +749,12 @@ module Discorb
|
|
677
749
|
interval = @heartbeat_interval
|
678
750
|
sleep((interval / 1000.0 - 1) * rand)
|
679
751
|
loop do
|
680
|
-
unless
|
752
|
+
unless connection.closed?
|
681
753
|
@heartbeat_before = Time.now.to_f
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
754
|
+
connection.write({ op: 1, d: @last_s }.to_json)
|
755
|
+
connection.flush
|
756
|
+
logger.debug "Sent opcode 1."
|
757
|
+
logger.debug "Waiting for heartbeat."
|
686
758
|
end
|
687
759
|
sleep(interval / 1000.0 - 1)
|
688
760
|
end
|
@@ -690,29 +762,30 @@ module Discorb
|
|
690
762
|
end
|
691
763
|
|
692
764
|
def handle_event(event_name, data)
|
693
|
-
return
|
765
|
+
return logger.debug "Client isn't ready; event #{event_name} wasn't handled" if @wait_until_ready && !@ready && !%w[READY GUILD_CREATE].include?(event_name)
|
694
766
|
|
695
767
|
dispatch(:event_receive, event_name, data)
|
696
|
-
|
768
|
+
logger.debug "Handling event #{event_name}"
|
697
769
|
case event_name
|
698
770
|
when "READY"
|
699
771
|
@api_version = data[:v]
|
700
|
-
|
772
|
+
self.session_id = data[:session_id]
|
701
773
|
@user = ClientUser.new(self, data[:user])
|
702
774
|
@uncached_guilds = data[:guilds].map { |g| g[:id] }
|
703
775
|
ready if (@uncached_guilds == []) || !@intents.guilds
|
704
776
|
dispatch(:ready)
|
777
|
+
|
705
778
|
@tasks << handle_heartbeat
|
706
779
|
when "GUILD_CREATE"
|
707
780
|
if @uncached_guilds.include?(data[:id])
|
708
781
|
Guild.new(self, data, true)
|
709
782
|
@uncached_guilds.delete(data[:id])
|
710
783
|
if @uncached_guilds == []
|
711
|
-
|
784
|
+
logger.debug "All guilds cached"
|
712
785
|
ready
|
713
786
|
end
|
714
787
|
elsif @guilds.has?(data[:id])
|
715
|
-
@guilds[data[:id]].send(:_set_data, data)
|
788
|
+
@guilds[data[:id]].send(:_set_data, data, true)
|
716
789
|
dispatch(:guild_available, guild)
|
717
790
|
else
|
718
791
|
guild = Guild.new(self, data, true)
|
@@ -729,51 +802,51 @@ module Discorb
|
|
729
802
|
current.send(:_set_data, data, false)
|
730
803
|
dispatch(:guild_update, before, current)
|
731
804
|
else
|
732
|
-
|
805
|
+
logger.warn "Unknown guild id #{data[:id]}, ignoring"
|
733
806
|
end
|
734
807
|
when "GUILD_DELETE"
|
735
|
-
return
|
808
|
+
return logger.warn "Unknown guild id #{data[:id]}, ignoring" unless (guild = @guilds.delete(data[:id]))
|
736
809
|
|
737
810
|
dispatch(:guild_delete, guild)
|
738
|
-
if
|
811
|
+
if data[:unavailable]
|
739
812
|
dispatch(:guild_destroy, guild)
|
740
813
|
else
|
741
814
|
dispatch(:guild_leave, guild)
|
742
815
|
end
|
743
816
|
when "GUILD_ROLE_CREATE"
|
744
|
-
return
|
817
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
745
818
|
|
746
819
|
nr = Role.new(@client, guild, data[:role])
|
747
820
|
guild.roles[data[:role][:id]] = nr
|
748
821
|
dispatch(:role_create, nr)
|
749
822
|
when "GUILD_ROLE_UPDATE"
|
750
|
-
return
|
751
|
-
return
|
823
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
824
|
+
return logger.warn "Unknown role id #{data[:role][:id]}, ignoring" unless guild.roles.has?(data[:role][:id])
|
752
825
|
|
753
826
|
current = guild.roles[data[:role][:id]]
|
754
827
|
before = Role.new(@client, guild, current.instance_variable_get(:@data).update({ no_cache: true }))
|
755
828
|
current.send(:_set_data, data[:role])
|
756
829
|
dispatch(:role_update, before, current)
|
757
830
|
when "GUILD_ROLE_DELETE"
|
758
|
-
return
|
759
|
-
return
|
831
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
832
|
+
return logger.warn "Unknown role id #{data[:role_id]}, ignoring" unless (role = guild.roles.delete(data[:role_id]))
|
760
833
|
|
761
834
|
dispatch(:role_delete, role)
|
762
835
|
when "CHANNEL_CREATE"
|
763
|
-
return
|
836
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
764
837
|
|
765
838
|
nc = Channel.make_channel(self, data)
|
766
839
|
guild.channels[data[:id]] = nc
|
767
840
|
|
768
841
|
dispatch(:channel_create, nc)
|
769
842
|
when "CHANNEL_UPDATE"
|
770
|
-
return
|
843
|
+
return logger.warn "Unknown channel id #{data[:id]}, ignoring" unless (current = @channels[data[:id]])
|
771
844
|
|
772
845
|
before = Channel.make_channel(self, current.instance_variable_get(:@data), no_cache: true)
|
773
846
|
current.send(:_set_data, data)
|
774
847
|
dispatch(:channel_update, before, current)
|
775
848
|
when "CHANNEL_DELETE"
|
776
|
-
return
|
849
|
+
return logger.warn "Unknown channel id #{data[:id]}, ignoring" unless (channel = @channels.delete(data[:id]))
|
777
850
|
|
778
851
|
@guilds[data[:guild_id]]&.channels&.delete(data[:id])
|
779
852
|
dispatch(:channel_delete, channel)
|
@@ -789,13 +862,13 @@ module Discorb
|
|
789
862
|
dispatch(:thread_new, thread)
|
790
863
|
end
|
791
864
|
when "THREAD_UPDATE"
|
792
|
-
return
|
865
|
+
return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
|
793
866
|
|
794
867
|
before = Channel.make_channel(self, thread.instance_variable_get(:@data), no_cache: true)
|
795
868
|
thread.send(:_set_data, data)
|
796
869
|
dispatch(:thread_update, before, thread)
|
797
870
|
when "THREAD_DELETE"
|
798
|
-
return
|
871
|
+
return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels.delete(data[:id]))
|
799
872
|
|
800
873
|
@guilds[data[:guild_id]]&.channels&.delete(data[:id])
|
801
874
|
dispatch(:thread_delete, thread)
|
@@ -805,11 +878,11 @@ module Discorb
|
|
805
878
|
@channels[thread.id] = thread
|
806
879
|
end
|
807
880
|
when "THREAD_MEMBER_UPDATE"
|
808
|
-
return
|
881
|
+
return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
|
809
882
|
|
810
883
|
if (member = thread.members[data[:id]])
|
811
884
|
old = ThreadChannel::Member.new(self, member.instance_variable_get(:@data))
|
812
|
-
member._set_data
|
885
|
+
member.send(:_set_data, data)
|
813
886
|
else
|
814
887
|
old = nil
|
815
888
|
member = ThreadChannel::Member.new(self, data)
|
@@ -817,7 +890,7 @@ module Discorb
|
|
817
890
|
end
|
818
891
|
dispatch(:thread_member_update, thread, old, member)
|
819
892
|
when "THREAD_MEMBERS_UPDATE"
|
820
|
-
return
|
893
|
+
return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
|
821
894
|
|
822
895
|
thread.instance_variable_set(:@member_count, data[:member_count])
|
823
896
|
members = []
|
@@ -835,37 +908,37 @@ module Discorb
|
|
835
908
|
instance = StageInstance.new(self, data)
|
836
909
|
dispatch(:stage_instance_create, instance)
|
837
910
|
when "STAGE_INSTANCE_UPDATE"
|
838
|
-
return
|
839
|
-
return
|
911
|
+
return logger.warn "Unknown channel id #{data[:channel_id]} , ignoring" unless (channel = @channels[data[:channel_id]])
|
912
|
+
return logger.warn "Unknown stage instance id #{data[:id]}, ignoring" unless (instance = channel.stage_instances[data[:id]])
|
840
913
|
|
841
914
|
old = StageInstance.new(self, instance.instance_variable_get(:@data), no_cache: true)
|
842
915
|
current.send(:_set_data, data)
|
843
916
|
dispatch(:stage_instance_update, old, current)
|
844
917
|
when "STAGE_INSTANCE_DELETE"
|
845
|
-
return
|
846
|
-
return
|
918
|
+
return logger.warn "Unknown channel id #{data[:channel_id]} , ignoring" unless (channel = @channels[data[:channel_id]])
|
919
|
+
return logger.warn "Unknown stage instance id #{data[:id]}, ignoring" unless (instance = channel.stage_instances.delete(data[:id]))
|
847
920
|
|
848
921
|
dispatch(:stage_instance_delete, instance)
|
849
922
|
when "GUILD_MEMBER_ADD"
|
850
|
-
return
|
923
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
851
924
|
|
852
925
|
nm = Member.new(self, data[:guild_id], data[:user].update({ no_cache: true }), data)
|
853
926
|
guild.members[nm.id] = nm
|
854
927
|
dispatch(:member_add, nm)
|
855
928
|
when "GUILD_MEMBER_UPDATE"
|
856
|
-
return
|
857
|
-
return
|
929
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
930
|
+
return logger.warn "Unknown member id #{data[:user][:id]}, ignoring" unless (nm = guild.members[data[:user][:id]])
|
858
931
|
|
859
932
|
old = Member.new(self, data[:guild_id], data[:user], data.update({ no_cache: true }))
|
860
933
|
nm.send(:_set_data, data[:user], data)
|
861
934
|
dispatch(:member_update, old, nm)
|
862
935
|
when "GUILD_MEMBER_REMOVE"
|
863
|
-
return
|
864
|
-
return
|
936
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
937
|
+
return logger.warn "Unknown member id #{data[:user][:id]}, ignoring" unless (member = guild.members.delete(data[:user][:id]))
|
865
938
|
|
866
939
|
dispatch(:member_remove, member)
|
867
940
|
when "GUILD_BAN_ADD"
|
868
|
-
return
|
941
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
869
942
|
|
870
943
|
user = if @users.has? data[:user][:id]
|
871
944
|
@users[data[:user][:id]]
|
@@ -875,7 +948,7 @@ module Discorb
|
|
875
948
|
|
876
949
|
dispatch(:guild_ban_add, guild, user)
|
877
950
|
when "GUILD_BAN_REMOVE"
|
878
|
-
return
|
951
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
879
952
|
|
880
953
|
user = if @users.has? data[:user][:id]
|
881
954
|
@users[data[:user][:id]]
|
@@ -885,7 +958,7 @@ module Discorb
|
|
885
958
|
|
886
959
|
dispatch(:guild_ban_remove, guild, user)
|
887
960
|
when "GUILD_EMOJIS_UPDATE"
|
888
|
-
return
|
961
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
889
962
|
|
890
963
|
before_emojis = guild.emojis.values.map(&:id).to_set
|
891
964
|
data[:emojis].each do |emoji|
|
@@ -896,17 +969,16 @@ module Discorb
|
|
896
969
|
guild.emojis.delete(emoji)
|
897
970
|
end
|
898
971
|
when "GUILD_INTEGRATIONS_UPDATE"
|
899
|
-
|
900
|
-
# Currently not implemented
|
972
|
+
dispatch(:guild_integrations_update, @guilds[data[:guild_id]])
|
901
973
|
when "INTEGRATION_CREATE"
|
902
974
|
dispatch(:integration_create, Integration.new(self, data, data[:guild_id]))
|
903
975
|
when "INTEGRATION_UPDATE"
|
904
|
-
return
|
976
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
905
977
|
|
906
978
|
integration = Integration.new(self, data, data[:guild_id])
|
907
979
|
dispatch(:integration_update, integration)
|
908
980
|
when "INTEGRATION_DELETE"
|
909
|
-
return
|
981
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
910
982
|
|
911
983
|
dispatch(:integration_delete, IntegrationDeleteEvent.new(self, data))
|
912
984
|
when "WEBHOOKS_UPDATE"
|
@@ -916,7 +988,7 @@ module Discorb
|
|
916
988
|
when "INVITE_DELETE"
|
917
989
|
dispatch(:invite_delete, InviteDeleteEvent.new(self, data))
|
918
990
|
when "VOICE_STATE_UPDATE"
|
919
|
-
return
|
991
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
920
992
|
|
921
993
|
current = guild.voice_states[data[:user_id]]
|
922
994
|
if current.nil?
|
@@ -1013,7 +1085,7 @@ module Discorb
|
|
1013
1085
|
end
|
1014
1086
|
end
|
1015
1087
|
when "PRESENCE_UPDATE"
|
1016
|
-
return
|
1088
|
+
return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
|
1017
1089
|
|
1018
1090
|
guild.presences[data[:user][:id]] = Presence.new(self, data)
|
1019
1091
|
when "MESSAGE_UPDATE"
|
@@ -1089,7 +1161,7 @@ module Discorb
|
|
1089
1161
|
(target_reaction = target_message.reactions.find { |r| data[:emoji][:id].nil? ? r.name == data[:emoji][:name] : r.id == data[:emoji][:id] })
|
1090
1162
|
target_message.reactions.delete(target_reaction)
|
1091
1163
|
end
|
1092
|
-
dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(data))
|
1164
|
+
dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(self, data))
|
1093
1165
|
when "TYPING_START"
|
1094
1166
|
dispatch(:typing_start, TypingStartEvent.new(self, data))
|
1095
1167
|
when "INTERACTION_CREATE"
|
@@ -1098,17 +1170,21 @@ module Discorb
|
|
1098
1170
|
|
1099
1171
|
dispatch(interaction.class.event_name, interaction)
|
1100
1172
|
when "RESUMED"
|
1101
|
-
|
1173
|
+
logger.info("Successfully resumed connection")
|
1102
1174
|
@tasks << handle_heartbeat
|
1103
|
-
|
1175
|
+
if shard
|
1176
|
+
dispatch(:shard_resumed, shard)
|
1177
|
+
else
|
1178
|
+
dispatch(:resumed)
|
1179
|
+
end
|
1104
1180
|
when "GUILD_SCHEDULED_EVENT_CREATE"
|
1105
|
-
|
1181
|
+
logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
|
1106
1182
|
event = ScheduledEvent.new(self, data)
|
1107
1183
|
guild.scheduled_events[data[:id]] = event
|
1108
1184
|
dispatch(:scheduled_event_create, event)
|
1109
1185
|
when "GUILD_SCHEDULED_EVENT_UPDATE"
|
1110
|
-
|
1111
|
-
|
1186
|
+
logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
|
1187
|
+
logger.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
|
1112
1188
|
old = event.dup
|
1113
1189
|
event.send(:_set_data, data)
|
1114
1190
|
dispatch(:scheduled_event_update, old, event)
|
@@ -1123,22 +1199,22 @@ module Discorb
|
|
1123
1199
|
end
|
1124
1200
|
end
|
1125
1201
|
when "GUILD_SCHEDULED_EVENT_DELETE"
|
1126
|
-
|
1127
|
-
|
1202
|
+
logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
|
1203
|
+
logger.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
|
1128
1204
|
guild.scheduled_events.remove(data[:id])
|
1129
1205
|
dispatch(:scheduled_event_delete, event)
|
1130
1206
|
dispatch(:scheduled_event_cancel, event)
|
1131
1207
|
when "GUILD_SCHEDULED_EVENT_USER_ADD"
|
1132
|
-
|
1208
|
+
logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
|
1133
1209
|
dispatch(:scheduled_event_user_add, ScheduledEventUserEvent.new(self, data))
|
1134
1210
|
when "GUILD_SCHEDULED_EVENT_USER_REMOVE"
|
1135
|
-
|
1211
|
+
logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
|
1136
1212
|
dispatch(:scheduled_event_user_remove, ScheduledEventUserEvent.new(self, data))
|
1137
1213
|
else
|
1138
1214
|
if respond_to?("event_" + event_name.downcase)
|
1139
1215
|
__send__("event_" + event_name.downcase, data)
|
1140
1216
|
else
|
1141
|
-
|
1217
|
+
logger.debug "Unhandled event: #{event_name}\n#{data.inspect}"
|
1142
1218
|
end
|
1143
1219
|
end
|
1144
1220
|
end
|
@@ -1146,7 +1222,7 @@ module Discorb
|
|
1146
1222
|
def ready
|
1147
1223
|
Async do
|
1148
1224
|
if @fetch_member
|
1149
|
-
|
1225
|
+
logger.debug "Fetching members"
|
1150
1226
|
barrier = Async::Barrier.new
|
1151
1227
|
|
1152
1228
|
@guilds.each do |guild|
|
@@ -1157,8 +1233,25 @@ module Discorb
|
|
1157
1233
|
barrier.wait
|
1158
1234
|
end
|
1159
1235
|
@ready = true
|
1160
|
-
|
1161
|
-
|
1236
|
+
|
1237
|
+
if self.shard
|
1238
|
+
logger.info("Shard #{shard_id} is ready!")
|
1239
|
+
self.shard&.tap do |shard|
|
1240
|
+
if shard.next_shard
|
1241
|
+
dispatch(:shard_standby, shard)
|
1242
|
+
shard.next_shard.tap do |next_shard|
|
1243
|
+
logger.debug("Starting shard #{next_shard.id}")
|
1244
|
+
next_shard.start
|
1245
|
+
end
|
1246
|
+
else
|
1247
|
+
logger.info("All shards are ready!")
|
1248
|
+
dispatch(:standby)
|
1249
|
+
end
|
1250
|
+
end
|
1251
|
+
else
|
1252
|
+
logger.info("Client is ready!")
|
1253
|
+
dispatch(:standby)
|
1254
|
+
end
|
1162
1255
|
end
|
1163
1256
|
end
|
1164
1257
|
end
|
@@ -1173,6 +1266,10 @@ module Discorb
|
|
1173
1266
|
@closed = false
|
1174
1267
|
end
|
1175
1268
|
|
1269
|
+
def inspect
|
1270
|
+
"<#{self.class.name} #{io.fileno}>"
|
1271
|
+
end
|
1272
|
+
|
1176
1273
|
def closed?
|
1177
1274
|
@closed
|
1178
1275
|
end
|
@@ -1185,10 +1282,14 @@ module Discorb
|
|
1185
1282
|
end
|
1186
1283
|
|
1187
1284
|
def force_close
|
1188
|
-
|
1285
|
+
io.close
|
1189
1286
|
@closed = true
|
1190
1287
|
end
|
1191
1288
|
|
1289
|
+
def io
|
1290
|
+
@framer.instance_variable_get(:@stream).instance_variable_get(:@io).instance_variable_get(:@io).instance_variable_get(:@io)
|
1291
|
+
end
|
1292
|
+
|
1192
1293
|
def parse(buffer)
|
1193
1294
|
# noop
|
1194
1295
|
buffer.to_s
|