discorb 0.15.1 → 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.
@@ -581,115 +581,129 @@ module Discorb
581
581
  private
582
582
 
583
583
  def connect_gateway(reconnect)
584
- if reconnect
585
- @log.info "Reconnecting to gateway..."
586
- else
587
- @log.info "Connecting to gateway..."
588
- end
589
584
  Async do
590
- if @connection && !@connection.closed?
591
- Async do
592
- @connection.close
593
- end
594
- end
595
- @http = HTTP.new(self)
596
- _, gateway_response = @http.request(Route.new("/gateway", "//gateway", :get)).wait
597
- gateway_url = gateway_response[:url]
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
585
+ @mutex["gateway_#{shard_id}"] ||= Mutex.new
586
+ @mutex["gateway_#{shard_id}"].synchronize do
587
+ if reconnect
588
+ logger.info "Reconnecting to gateway..."
601
589
  else
602
- 10
590
+ logger.info "Connecting to gateway..."
603
591
  end
604
- endpoint = Async::HTTP::Endpoint.parse("#{gateway_url}?v=#{gateway_version}&encoding=json&compress=zlib-stream",
605
- alpn_protocols: Async::HTTP::Protocol::HTTP11.names)
606
- begin
607
- @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 = +""
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
+ )
610
606
  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
- @log.error "Received invalid JSON from gateway."
621
- @log.debug "#{data}"
622
- else
623
- handle_gateway(message, reconnect)
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
624
625
  end
625
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
626
639
  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
- @log.error "Gateway connection closed accidentally: #{e.class}: #{e.message}"
635
- @connection.force_close
636
- connect_gateway(true)
637
- else # should never happen
638
- connect_gateway(true)
639
- end
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
- @log.info "Session timed out, reconnecting."
647
- connect_gateway(true)
648
- when 4014
649
- raise ClientError.new("Disallowed intents were specified"), cause: nil
650
- when 4002, 4003, 4005, 4007
651
- raise ClientError.new(<<~ERROR), cause: e
652
- Disconnected from gateway, probably due to library issues.
653
- #{e.message}
654
-
655
- Please report this to the library issue tracker.
656
- https://github.com/discorb-lib/discorb/issues
657
- ERROR
658
- when 1001
659
- @log.info "Gateway closed with code 1001, reconnecting."
660
- connect_gateway(true)
661
- else
662
- @log.error "Discord WebSocket closed with code #{e.code}."
663
- @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
664
675
  connect_gateway(false)
676
+ next
665
677
  end
666
- rescue StandardError => e
667
- @log.error "Discord WebSocket error: #{e.full_message}"
668
- @connection.force_close
669
- connect_gateway(false)
670
678
  end
671
679
  end
672
680
  end
673
681
 
674
682
  def send_gateway(opcode, **value)
675
- @connection.write({ op: opcode, d: value }.to_json)
676
- @connection.flush
677
- @log.debug "Sent message #{{ op: opcode, d: value }.to_json.gsub(@token, "[Token]")}"
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]")}"
678
692
  end
679
693
 
680
694
  def handle_gateway(payload, reconnect)
681
695
  Async do |_task|
682
696
  data = payload[:d]
683
697
  @last_s = payload[:s] if payload[:s]
684
- @log.debug "Received message with opcode #{payload[:op]} from gateway:"
685
- @log.debug "#{payload.to_json.gsub(@token, "[Token]")}"
698
+ logger.debug "Received message with opcode #{payload[:op]} from gateway."
699
+ logger.debug "#{payload.to_json.gsub(@token, "[Token]")}"
686
700
  case payload[:op]
687
701
  when 10
688
702
  @heartbeat_interval = data[:heartbeat_interval]
689
703
  if reconnect
690
704
  payload = {
691
705
  token: @token,
692
- session_id: @session_id,
706
+ session_id: session_id,
693
707
  seq: @last_s,
694
708
  }
695
709
  send_gateway(6, **payload)
@@ -700,27 +714,29 @@ module Discorb
700
714
  compress: false,
701
715
  properties: { "$os" => RUBY_PLATFORM, "$browser" => "discorb", "$device" => "discorb" },
702
716
  }
717
+ payload[:shard] = [shard_id, @shard_count] if shard_id
703
718
  payload[:presence] = @identify_presence if @identify_presence
704
719
  send_gateway(2, **payload)
705
720
  end
706
721
  when 7
707
- @log.info "Received opcode 7, stopping tasks"
722
+ logger.info "Received opcode 7, stopping tasks"
708
723
  @tasks.map(&:stop)
709
724
  when 9
710
- @log.warn "Received opcode 9, closed connection"
725
+ logger.warn "Received opcode 9, closed connection"
711
726
  @tasks.map(&:stop)
712
727
  if data
713
- @log.info "Connection is resumable, reconnecting"
714
- @connection.close
728
+ logger.info "Connection is resumable, reconnecting"
729
+ connection.force_close
715
730
  connect_gateway(true)
716
731
  else
717
- @log.info "Connection is not resumable, reconnecting with opcode 2"
718
- @connection.close
732
+ logger.info "Connection is not resumable, reconnecting with opcode 2"
733
+ connection.force_close
734
+
719
735
  sleep(2)
720
736
  connect_gateway(false)
721
737
  end
722
738
  when 11
723
- @log.debug "Received opcode 11"
739
+ logger.debug "Received opcode 11"
724
740
  @ping = Time.now.to_f - @heartbeat_before
725
741
  when 0
726
742
  handle_event(payload[:t], data)
@@ -733,12 +749,12 @@ module Discorb
733
749
  interval = @heartbeat_interval
734
750
  sleep((interval / 1000.0 - 1) * rand)
735
751
  loop do
736
- unless @connection.closed?
752
+ unless connection.closed?
737
753
  @heartbeat_before = Time.now.to_f
738
- @connection.write({ op: 1, d: @last_s }.to_json)
739
- @connection.flush
740
- @log.debug "Sent opcode 1."
741
- @log.debug "Waiting for heartbeat."
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."
742
758
  end
743
759
  sleep(interval / 1000.0 - 1)
744
760
  end
@@ -746,25 +762,26 @@ module Discorb
746
762
  end
747
763
 
748
764
  def handle_event(event_name, data)
749
- return @log.debug "Client isn't ready; event #{event_name} wasn't handled" if @wait_until_ready && !@ready && !%w[READY GUILD_CREATE].include?(event_name)
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)
750
766
 
751
767
  dispatch(:event_receive, event_name, data)
752
- @log.debug "Handling event #{event_name}"
768
+ logger.debug "Handling event #{event_name}"
753
769
  case event_name
754
770
  when "READY"
755
771
  @api_version = data[:v]
756
- @session_id = data[:session_id]
772
+ self.session_id = data[:session_id]
757
773
  @user = ClientUser.new(self, data[:user])
758
774
  @uncached_guilds = data[:guilds].map { |g| g[:id] }
759
775
  ready if (@uncached_guilds == []) || !@intents.guilds
760
776
  dispatch(:ready)
777
+
761
778
  @tasks << handle_heartbeat
762
779
  when "GUILD_CREATE"
763
780
  if @uncached_guilds.include?(data[:id])
764
781
  Guild.new(self, data, true)
765
782
  @uncached_guilds.delete(data[:id])
766
783
  if @uncached_guilds == []
767
- @log.debug "All guilds cached"
784
+ logger.debug "All guilds cached"
768
785
  ready
769
786
  end
770
787
  elsif @guilds.has?(data[:id])
@@ -785,10 +802,10 @@ module Discorb
785
802
  current.send(:_set_data, data, false)
786
803
  dispatch(:guild_update, before, current)
787
804
  else
788
- @log.warn "Unknown guild id #{data[:id]}, ignoring"
805
+ logger.warn "Unknown guild id #{data[:id]}, ignoring"
789
806
  end
790
807
  when "GUILD_DELETE"
791
- return @log.warn "Unknown guild id #{data[:id]}, ignoring" unless (guild = @guilds.delete(data[:id]))
808
+ return logger.warn "Unknown guild id #{data[:id]}, ignoring" unless (guild = @guilds.delete(data[:id]))
792
809
 
793
810
  dispatch(:guild_delete, guild)
794
811
  if data[:unavailable]
@@ -797,39 +814,39 @@ module Discorb
797
814
  dispatch(:guild_leave, guild)
798
815
  end
799
816
  when "GUILD_ROLE_CREATE"
800
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
817
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
801
818
 
802
819
  nr = Role.new(@client, guild, data[:role])
803
820
  guild.roles[data[:role][:id]] = nr
804
821
  dispatch(:role_create, nr)
805
822
  when "GUILD_ROLE_UPDATE"
806
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
807
- return @log.warn "Unknown role id #{data[:role][:id]}, ignoring" unless guild.roles.has?(data[:role][:id])
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])
808
825
 
809
826
  current = guild.roles[data[:role][:id]]
810
827
  before = Role.new(@client, guild, current.instance_variable_get(:@data).update({ no_cache: true }))
811
828
  current.send(:_set_data, data[:role])
812
829
  dispatch(:role_update, before, current)
813
830
  when "GUILD_ROLE_DELETE"
814
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
815
- return @log.warn "Unknown role id #{data[:role_id]}, ignoring" unless (role = guild.roles.delete(data[:role_id]))
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]))
816
833
 
817
834
  dispatch(:role_delete, role)
818
835
  when "CHANNEL_CREATE"
819
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
836
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
820
837
 
821
838
  nc = Channel.make_channel(self, data)
822
839
  guild.channels[data[:id]] = nc
823
840
 
824
841
  dispatch(:channel_create, nc)
825
842
  when "CHANNEL_UPDATE"
826
- return @log.warn "Unknown channel id #{data[:id]}, ignoring" unless (current = @channels[data[:id]])
843
+ return logger.warn "Unknown channel id #{data[:id]}, ignoring" unless (current = @channels[data[:id]])
827
844
 
828
845
  before = Channel.make_channel(self, current.instance_variable_get(:@data), no_cache: true)
829
846
  current.send(:_set_data, data)
830
847
  dispatch(:channel_update, before, current)
831
848
  when "CHANNEL_DELETE"
832
- return @log.warn "Unknown channel id #{data[:id]}, ignoring" unless (channel = @channels.delete(data[:id]))
849
+ return logger.warn "Unknown channel id #{data[:id]}, ignoring" unless (channel = @channels.delete(data[:id]))
833
850
 
834
851
  @guilds[data[:guild_id]]&.channels&.delete(data[:id])
835
852
  dispatch(:channel_delete, channel)
@@ -845,13 +862,13 @@ module Discorb
845
862
  dispatch(:thread_new, thread)
846
863
  end
847
864
  when "THREAD_UPDATE"
848
- return @log.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
865
+ return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
849
866
 
850
867
  before = Channel.make_channel(self, thread.instance_variable_get(:@data), no_cache: true)
851
868
  thread.send(:_set_data, data)
852
869
  dispatch(:thread_update, before, thread)
853
870
  when "THREAD_DELETE"
854
- return @log.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels.delete(data[:id]))
871
+ return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels.delete(data[:id]))
855
872
 
856
873
  @guilds[data[:guild_id]]&.channels&.delete(data[:id])
857
874
  dispatch(:thread_delete, thread)
@@ -861,7 +878,7 @@ module Discorb
861
878
  @channels[thread.id] = thread
862
879
  end
863
880
  when "THREAD_MEMBER_UPDATE"
864
- return @log.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
881
+ return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
865
882
 
866
883
  if (member = thread.members[data[:id]])
867
884
  old = ThreadChannel::Member.new(self, member.instance_variable_get(:@data))
@@ -873,7 +890,7 @@ module Discorb
873
890
  end
874
891
  dispatch(:thread_member_update, thread, old, member)
875
892
  when "THREAD_MEMBERS_UPDATE"
876
- return @log.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
893
+ return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
877
894
 
878
895
  thread.instance_variable_set(:@member_count, data[:member_count])
879
896
  members = []
@@ -891,37 +908,37 @@ module Discorb
891
908
  instance = StageInstance.new(self, data)
892
909
  dispatch(:stage_instance_create, instance)
893
910
  when "STAGE_INSTANCE_UPDATE"
894
- return @log.warn "Unknown channel id #{data[:channel_id]} , ignoring" unless (channel = @channels[data[:channel_id]])
895
- return @log.warn "Unknown stage instance id #{data[:id]}, ignoring" unless (instance = channel.stage_instances[data[:id]])
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]])
896
913
 
897
914
  old = StageInstance.new(self, instance.instance_variable_get(:@data), no_cache: true)
898
915
  current.send(:_set_data, data)
899
916
  dispatch(:stage_instance_update, old, current)
900
917
  when "STAGE_INSTANCE_DELETE"
901
- return @log.warn "Unknown channel id #{data[:channel_id]} , ignoring" unless (channel = @channels[data[:channel_id]])
902
- return @log.warn "Unknown stage instance id #{data[:id]}, ignoring" unless (instance = channel.stage_instances.delete(data[:id]))
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]))
903
920
 
904
921
  dispatch(:stage_instance_delete, instance)
905
922
  when "GUILD_MEMBER_ADD"
906
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
923
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
907
924
 
908
925
  nm = Member.new(self, data[:guild_id], data[:user].update({ no_cache: true }), data)
909
926
  guild.members[nm.id] = nm
910
927
  dispatch(:member_add, nm)
911
928
  when "GUILD_MEMBER_UPDATE"
912
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
913
- return @log.warn "Unknown member id #{data[:user][:id]}, ignoring" unless (nm = guild.members[data[:user][:id]])
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]])
914
931
 
915
932
  old = Member.new(self, data[:guild_id], data[:user], data.update({ no_cache: true }))
916
933
  nm.send(:_set_data, data[:user], data)
917
934
  dispatch(:member_update, old, nm)
918
935
  when "GUILD_MEMBER_REMOVE"
919
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
920
- return @log.warn "Unknown member id #{data[:user][:id]}, ignoring" unless (member = guild.members.delete(data[:user][:id]))
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]))
921
938
 
922
939
  dispatch(:member_remove, member)
923
940
  when "GUILD_BAN_ADD"
924
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
941
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
925
942
 
926
943
  user = if @users.has? data[:user][:id]
927
944
  @users[data[:user][:id]]
@@ -931,7 +948,7 @@ module Discorb
931
948
 
932
949
  dispatch(:guild_ban_add, guild, user)
933
950
  when "GUILD_BAN_REMOVE"
934
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
951
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
935
952
 
936
953
  user = if @users.has? data[:user][:id]
937
954
  @users[data[:user][:id]]
@@ -941,7 +958,7 @@ module Discorb
941
958
 
942
959
  dispatch(:guild_ban_remove, guild, user)
943
960
  when "GUILD_EMOJIS_UPDATE"
944
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
961
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
945
962
 
946
963
  before_emojis = guild.emojis.values.map(&:id).to_set
947
964
  data[:emojis].each do |emoji|
@@ -956,12 +973,12 @@ module Discorb
956
973
  when "INTEGRATION_CREATE"
957
974
  dispatch(:integration_create, Integration.new(self, data, data[:guild_id]))
958
975
  when "INTEGRATION_UPDATE"
959
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
976
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
960
977
 
961
978
  integration = Integration.new(self, data, data[:guild_id])
962
979
  dispatch(:integration_update, integration)
963
980
  when "INTEGRATION_DELETE"
964
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
981
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
965
982
 
966
983
  dispatch(:integration_delete, IntegrationDeleteEvent.new(self, data))
967
984
  when "WEBHOOKS_UPDATE"
@@ -971,7 +988,7 @@ module Discorb
971
988
  when "INVITE_DELETE"
972
989
  dispatch(:invite_delete, InviteDeleteEvent.new(self, data))
973
990
  when "VOICE_STATE_UPDATE"
974
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
991
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
975
992
 
976
993
  current = guild.voice_states[data[:user_id]]
977
994
  if current.nil?
@@ -1068,7 +1085,7 @@ module Discorb
1068
1085
  end
1069
1086
  end
1070
1087
  when "PRESENCE_UPDATE"
1071
- return @log.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
1088
+ return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
1072
1089
 
1073
1090
  guild.presences[data[:user][:id]] = Presence.new(self, data)
1074
1091
  when "MESSAGE_UPDATE"
@@ -1153,17 +1170,21 @@ module Discorb
1153
1170
 
1154
1171
  dispatch(interaction.class.event_name, interaction)
1155
1172
  when "RESUMED"
1156
- @log.info("Successfully resumed connection")
1173
+ logger.info("Successfully resumed connection")
1157
1174
  @tasks << handle_heartbeat
1158
- dispatch(:resumed)
1175
+ if shard
1176
+ dispatch(:shard_resumed, shard)
1177
+ else
1178
+ dispatch(:resumed)
1179
+ end
1159
1180
  when "GUILD_SCHEDULED_EVENT_CREATE"
1160
- @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1181
+ logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1161
1182
  event = ScheduledEvent.new(self, data)
1162
1183
  guild.scheduled_events[data[:id]] = event
1163
1184
  dispatch(:scheduled_event_create, event)
1164
1185
  when "GUILD_SCHEDULED_EVENT_UPDATE"
1165
- @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1166
- @log.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
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]])
1167
1188
  old = event.dup
1168
1189
  event.send(:_set_data, data)
1169
1190
  dispatch(:scheduled_event_update, old, event)
@@ -1178,22 +1199,22 @@ module Discorb
1178
1199
  end
1179
1200
  end
1180
1201
  when "GUILD_SCHEDULED_EVENT_DELETE"
1181
- @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1182
- @log.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
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]])
1183
1204
  guild.scheduled_events.remove(data[:id])
1184
1205
  dispatch(:scheduled_event_delete, event)
1185
1206
  dispatch(:scheduled_event_cancel, event)
1186
1207
  when "GUILD_SCHEDULED_EVENT_USER_ADD"
1187
- @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1208
+ logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1188
1209
  dispatch(:scheduled_event_user_add, ScheduledEventUserEvent.new(self, data))
1189
1210
  when "GUILD_SCHEDULED_EVENT_USER_REMOVE"
1190
- @log.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1211
+ logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1191
1212
  dispatch(:scheduled_event_user_remove, ScheduledEventUserEvent.new(self, data))
1192
1213
  else
1193
1214
  if respond_to?("event_" + event_name.downcase)
1194
1215
  __send__("event_" + event_name.downcase, data)
1195
1216
  else
1196
- @log.debug "Unhandled event: #{event_name}\n#{data.inspect}"
1217
+ logger.debug "Unhandled event: #{event_name}\n#{data.inspect}"
1197
1218
  end
1198
1219
  end
1199
1220
  end
@@ -1201,7 +1222,7 @@ module Discorb
1201
1222
  def ready
1202
1223
  Async do
1203
1224
  if @fetch_member
1204
- @log.debug "Fetching members"
1225
+ logger.debug "Fetching members"
1205
1226
  barrier = Async::Barrier.new
1206
1227
 
1207
1228
  @guilds.each do |guild|
@@ -1212,8 +1233,25 @@ module Discorb
1212
1233
  barrier.wait
1213
1234
  end
1214
1235
  @ready = true
1215
- dispatch(:standby)
1216
- @log.info("Client is ready!")
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
1217
1255
  end
1218
1256
  end
1219
1257
  end
data/lib/discorb/http.rb CHANGED
@@ -107,7 +107,7 @@ module Discorb
107
107
  def handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
108
108
  case resp.code
109
109
  when "429"
110
- @client.log.info("Rate limit exceeded for #{path.method} #{path.url}, waiting #{data[:retry_after]} seconds")
110
+ @client.logger.info("Rate limit exceeded for #{path.method} #{path.url}, waiting #{data[:retry_after]} seconds")
111
111
  sleep(data[:retry_after])
112
112
  request(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
113
113
  when "400"
@@ -128,7 +128,7 @@ module Discorb
128
128
  { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}" }
129
129
  else
130
130
  { "User-Agent" => USER_AGENT, "authorization" => "Bot #{@client.token}",
131
- "content-type" => "application/json", }
131
+ "content-type" => "application/json" }
132
132
  end
133
133
  ret.merge!(headers) if !headers.nil? && headers.length.positive?
134
134
  ret["X-Audit-Log-Reason"] = audit_log_reason unless audit_log_reason.nil?
@@ -15,7 +15,7 @@ module Discorb
15
15
  name, options = Discorb::CommandInteraction::SlashCommand.get_command_data(data)
16
16
 
17
17
  unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
18
- @client.log.warn "Unknown command name #{name}, ignoring"
18
+ @client.logger.warn "Unknown command name #{name}, ignoring"
19
19
  next
20
20
  end
21
21
 
@@ -40,7 +40,7 @@ module Discorb
40
40
  },
41
41
  }).wait
42
42
  rescue Discorb::NotFoundError
43
- @client.log.warn "Failed to send auto complete result, This may be caused by the suggestion is taking too long (over 3 seconds) to respond", fallback: $stderr
43
+ @client.logger.warn "Failed to send auto complete result, This may be caused by the suggestion is taking too long (over 3 seconds) to respond", fallback: $stderr
44
44
  end
45
45
 
46
46
  class << self
@@ -24,7 +24,7 @@ module Discorb
24
24
  name, options = SlashCommand.get_command_data(data)
25
25
 
26
26
  unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
27
- @client.log.warn "Unknown command name #{name}, ignoring"
27
+ @client.logger.warn "Unknown command name #{name}, ignoring"
28
28
  return
29
29
  end
30
30
 
@@ -180,7 +180,7 @@ module Discorb
180
180
  return interaction
181
181
  end
182
182
  end
183
- client.log.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
183
+ client.logger.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
184
184
  CommandInteraction.new(client, data)
185
185
  end
186
186
 
@@ -43,7 +43,7 @@ module Discorb
43
43
  nested_classes.each do |klass|
44
44
  return klass.new(client, data) if !klass.component_type.nil? && klass.component_type == data[:data][:component_type]
45
45
  end
46
- client.log.warn("Unknown component type #{data[:component_type]}, initialized Interaction")
46
+ client.logger.warn("Unknown component type #{data[:component_type]}, initialized Interaction")
47
47
  MessageComponentInteraction.new(client, data)
48
48
  end
49
49