discordrb 1.7.5 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of discordrb might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d661448f2825e14545bff5ef277d349bdc9fe944
4
- data.tar.gz: f4c846fde0f3248e6c6d3be8d69b4dabfdd6f098
3
+ metadata.gz: 79ffeb9b74702dcf9a25f0e92fcc0c06b0af8eb9
4
+ data.tar.gz: bf9eca745cecae8bd9078f3fbd27aeab1ae7d0e9
5
5
  SHA512:
6
- metadata.gz: 49aaa4b14e1da63c24fa1dcb03500b3926c71781e6cbd20e5cd7af296b060dd01082baa6dceaa9630ac55520b316c0fd98d1027df34c6b1e5996303117193196
7
- data.tar.gz: 9a8d93545ce59f3334fa785ffaa85fd47f511ace03175045614a69441735da09fffe7305b4b6dfe95316d7e1fc2b0c8407a1fc381596d9882ab52b681311e74e
6
+ metadata.gz: 5cb906cf412f9e5147bbf0196d9b15c0bafbc00fad70c17e9606404770bad93b0a0eca0beb0da2f67b85ec6a4b5c643cc6ba654193404df4abaf103c0ab2b4ba
7
+ data.tar.gz: 187edc158381c52b3778f3d364fb399eba254963efcc28380e37371f67225d001543274331aec48138348e100a31abfe4d02e264a99cd71d901595467d9e0fbb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.8.0
4
+ * The built-in logger has been somewhat redone.
5
+ * It now has a fancy mode, settable using `Discordrb::LOGGER.fancy = true/false`, that makes use of ANSI escape codes to prettify the log output.
6
+ * It now supports more things than just `debug`, there's also `warn`, `error`, `good`, `info`, `in`, and `out`.
7
+ * You now have finer control over what gets output, using `Discordrb::LOGGER.mode=` which accepts one of `:debug`, `:verbose`, `:normal`, `:quiet`, `:silent`.
8
+ * You can now log in with just a token by setting the email parameter to `:token` and the password to the token you want to log in with.
9
+ * DCA playback now supports `DCA1`.
10
+ * All data classes (now generalized using the `IDObject` mixin) have a `creation_date` parameter that specifies when the object was created.
11
+ * `Channel#mention` was added that mentions a channel analogous to `User#mention`.
12
+ * The aliases `tag` and `discord_tag` have been added to the discriminator because that's what Discord calls them now.
13
+
14
+ ### Bugfixes
15
+ * A problem some users had where voice playback would leak FFmpeg processes has been fixed.
16
+ * The VWS internal thread now has a name in debug messages (`vws-i`)
17
+ * Users' voice channels should now always be set if they are in one
18
+
3
19
  ## 1.7.5
4
20
  * `Channel#send_message` and `Bot#send_message` now have an extra `tts` parameter (false by default) to specify whether the message should use TTS.
5
21
 
data/lib/discordrb.rb CHANGED
@@ -8,7 +8,7 @@ module Discordrb
8
8
  Thread.current[:discordrb_name] = 'main'
9
9
 
10
10
  # The default debug logger used by discordrb.
11
- LOGGER = Logger.new
11
+ LOGGER = Logger.new(ENV['DISCORDRB_FANCY_LOG'])
12
12
  end
13
13
 
14
14
  # In discordrb, Integer and {String} are monkey-patched to allow for easy resolution of IDs
data/lib/discordrb/bot.rb CHANGED
@@ -70,7 +70,7 @@ module Discordrb
70
70
  # @param debug [Boolean] Whether or not the bug should run in debug mode, which gives increased console output.
71
71
  def initialize(email, password, debug = false)
72
72
  # Make sure people replace the login details in the example files...
73
- if email.end_with? 'example.com'
73
+ if email.is_a?(String) && email.end_with?('example.com')
74
74
  puts 'You have to replace the login details in the example files with your own!'
75
75
  exit
76
76
  end
@@ -373,6 +373,8 @@ module Discordrb
373
373
  # * `:frankfurt`
374
374
  # * `:us-east`
375
375
  # * `:us-west`
376
+ # * `:us-south`
377
+ # * `:us-central`
376
378
  # * `:singapore`
377
379
  # * `:sydney`
378
380
  # @return [Server] The server that was created.
@@ -437,6 +439,12 @@ module Discordrb
437
439
  LOGGER.debug = new_debug
438
440
  end
439
441
 
442
+ # Sets the logging mode
443
+ # @see Logger#mode=
444
+ def mode=(new_mode)
445
+ LOGGER.mode = new_mode
446
+ end
447
+
440
448
  # Prevents the READY packet from being printed regardless of debug mode.
441
449
  def suppress_ready_debug
442
450
  @prevent_ready = true
@@ -457,8 +465,8 @@ module Discordrb
457
465
  end
458
466
 
459
467
  # @see Logger#debug
460
- def debug(message, important = false)
461
- LOGGER.debug(message, important)
468
+ def debug(message)
469
+ LOGGER.debug(message)
462
470
  end
463
471
 
464
472
  # @see Logger#log_exception
@@ -547,7 +555,7 @@ module Discordrb
547
555
 
548
556
  channel_id = data['channel_id']
549
557
  channel = nil
550
- channel = @channels[channel_id.to_i] if channel_id
558
+ channel = self.channel(channel_id.to_i) if channel_id
551
559
  user.move(channel)
552
560
 
553
561
  @session_id = data['session_id']
@@ -719,6 +727,13 @@ module Discordrb
719
727
  ######## ####### ###### #### ## ##
720
728
 
721
729
  def login
730
+ if @email == :token
731
+ debug('Logging in using static token')
732
+
733
+ # The password is the token!
734
+ return @password
735
+ end
736
+
722
737
  debug('Logging in')
723
738
  login_attempts ||= 0
724
739
 
@@ -803,7 +818,7 @@ module Discordrb
803
818
  elsif @prevent_ready && packet['t'] == 'GUILD_MEMBERS_CHUNK'
804
819
  # Ignore chunks as they will be handled later anyway
805
820
  else
806
- debug("Received packet #{event.data}")
821
+ LOGGER.in(event.data.to_s)
807
822
  end
808
823
 
809
824
  raise 'Invalid Packet' unless packet['op'] == 0 # TODO
@@ -851,6 +866,8 @@ module Discordrb
851
866
  }.to_json
852
867
  @ws.send(chunk_packet)
853
868
 
869
+ LOGGER.good 'Ready'
870
+
854
871
  # Tell the run method that everything was successful
855
872
  @ws_success = true
856
873
  when :GUILD_MEMBERS_CHUNK
@@ -1008,9 +1025,9 @@ module Discordrb
1008
1025
  end
1009
1026
 
1010
1027
  def websocket_close(event)
1011
- debug('Disconnected from WebSocket!')
1012
- debug(" (Reason: #{event.reason})")
1013
- debug(" (Code: #{event.code})")
1028
+ LOGGER.error('Disconnected from WebSocket!')
1029
+ LOGGER.error(" (Reason: #{event.reason})")
1030
+ LOGGER.error(" (Code: #{event.code})")
1014
1031
  raise_event(DisconnectEvent.new)
1015
1032
  EM.stop
1016
1033
  end
@@ -1038,7 +1055,7 @@ module Discordrb
1038
1055
 
1039
1056
  def send_heartbeat
1040
1057
  millis = Time.now.strftime('%s%L').to_i
1041
- debug("Sending heartbeat at #{millis}")
1058
+ LOGGER.out("Sending heartbeat at #{millis}")
1042
1059
  data = {
1043
1060
  op: 1,
1044
1061
  d: millis
@@ -9,21 +9,46 @@ require 'base64'
9
9
 
10
10
  # Discordrb module
11
11
  module Discordrb
12
+ # The unix timestamp Discord IDs are based on
13
+ DISCORD_EPOCH = 1420070400000
14
+
12
15
  # Compares two objects based on IDs - either the objects' IDs are equal, or one object is equal to the other's ID.
13
16
  def self.id_compare(one_id, other)
14
17
  other.respond_to?(:resolve_id) ? (one_id.resolve_id == other.resolve_id) : (one_id == other)
15
18
  end
16
19
 
20
+ # Mixin for objects that have IDs
21
+ module IDObject
22
+ # @return [Integer] the ID which uniquely identifies this object across Discord.
23
+ attr_reader :id
24
+ alias_method :resolve_id, :id
25
+
26
+ # ID based comparison
27
+ def ==(other)
28
+ Discordrb.id_compare(@id, other)
29
+ end
30
+
31
+ # Estimates the time this object was generated on based on the beginning of the ID. This is fairly accurate but
32
+ # shouldn't be relied on as Discord might change its algorithm at any time
33
+ # @return [Time] when this object was created at
34
+ def creation_time
35
+ # Milliseconds
36
+ ms = (@id >> 22) + DISCORD_EPOCH
37
+ Time.at(ms / 1000.0)
38
+ end
39
+ end
40
+
17
41
  # User on Discord, including internal data like discriminators
18
42
  class User
43
+ include IDObject
44
+
19
45
  # @return [String] this user's username
20
46
  attr_reader :username
21
47
 
22
- # @return [Integer] this user's ID which uniquely identifies them across Discord.
23
- attr_reader :id
24
-
25
48
  # @return [String] this user's discriminator which is used internally to identify users with identical usernames.
26
49
  attr_reader :discriminator
50
+ alias_method :tag, :discriminator
51
+ alias_method :discord_tag, :discriminator
27
52
 
28
53
  # @return [String] the ID of this user's current avatar, can be used to generate an avatar URL.
29
54
  # @see #avatar_url
@@ -52,7 +77,6 @@ module Discordrb
52
77
  attr_accessor :server_mute, :server_deaf, :self_deaf
53
78
 
54
79
  alias_method :name, :username
55
- alias_method :resolve_id, :id
56
80
 
57
81
  def initialize(data, bot)
58
82
  @bot = bot
@@ -66,11 +90,6 @@ module Discordrb
66
90
  @status = :offline
67
91
  end
68
92
 
69
- # ID based comparison
70
- def ==(other)
71
- Discordrb.id_compare(@id, other)
72
- end
73
-
74
93
  # Gets the user's avatar ID.
75
94
  # @deprecated Use {#avatar_id} instead.
76
95
  def avatar
@@ -224,6 +243,7 @@ module Discordrb
224
243
  end
225
244
  end
226
245
 
246
+ # The inspect method is overwritten to give more useful output
227
247
  def inspect
228
248
  "<User username=#{@username} id=#{@id} discriminator=#{@discriminator}>"
229
249
  end
@@ -285,6 +305,7 @@ module Discordrb
285
305
  @avatar_id = new_data[:avatar_id] || @avatar_id
286
306
  end
287
307
 
308
+ # The inspect method is overwritten to give more useful output
288
309
  def inspect
289
310
  "<Profile email=#{@email} user=#{super}>"
290
311
  end
@@ -304,15 +325,14 @@ module Discordrb
304
325
 
305
326
  # A Discord role that contains permissions and applies to certain users
306
327
  class Role
328
+ include IDObject
329
+
307
330
  # @return [Permissions] this role's permissions.
308
331
  attr_reader :permissions
309
332
 
310
333
  # @return [String] this role's name ("new role" if it hasn't been changed)
311
334
  attr_reader :name
312
335
 
313
- # @return [Integer] the ID used to identify this role internally
314
- attr_reader :id
315
-
316
336
  # @return [true, false] whether or not this role should be displayed separately from other users
317
337
  attr_reader :hoist
318
338
 
@@ -320,7 +340,6 @@ module Discordrb
320
340
  attr_reader :colour
321
341
 
322
342
  alias_method :color, :colour
323
- alias_method :resolve_id, :id
324
343
 
325
344
  # This class is used internally as a wrapper to a Role object that allows easy writing of permission data.
326
345
  class RoleWriter
@@ -348,11 +367,6 @@ module Discordrb
348
367
  @colour = ColourRGB.new(data['color'])
349
368
  end
350
369
 
351
- # ID based comparison
352
- def ==(other)
353
- Discordrb.id_compare(@id, other)
354
- end
355
-
356
370
  # Updates the data cache from another Role object
357
371
  # @note For internal use only
358
372
  # @!visibility private
@@ -407,6 +421,7 @@ module Discordrb
407
421
  @server.delete_role(@id)
408
422
  end
409
423
 
424
+ # The inspect method is overwritten to give more useful output
410
425
  def inspect
411
426
  "<Role name=#{@name} permissions=#{@permissions.inspect} hoist=#{@hoist} colour=#{@colour.inspect} server=#{@server.inspect}>"
412
427
  end
@@ -483,6 +498,7 @@ module Discordrb
483
498
 
484
499
  alias_method :revoke, :delete
485
500
 
501
+ # The inspect method is overwritten to give more useful output
486
502
  def inspect
487
503
  "<Invite code=#{@code} channel=#{@channel} uses=#{@uses} temporary=#{@temporary} revoked=#{@revoked} xkcd=#{@xkcd}>"
488
504
  end
@@ -490,9 +506,16 @@ module Discordrb
490
506
 
491
507
  # A Discord channel, including data like the topic
492
508
  class Channel
509
+ # The type string that stands for a text channel
510
+ # @see Channel#type
493
511
  TEXT_TYPE = 'text'.freeze
512
+
513
+ # The type string that stands for a voice channel
514
+ # @see Channel#type
494
515
  VOICE_TYPE = 'voice'.freeze
495
516
 
517
+ include IDObject
518
+
496
519
  # @return [String] this channel's name.
497
520
  attr_reader :name
498
521
 
@@ -502,10 +525,6 @@ module Discordrb
502
525
  # @return [String] the type of this channel (currently either 'text' or 'voice')
503
526
  attr_reader :type
504
527
 
505
- # @note If this channel is a #general channel, its ID will be equal to the server on which it is on.
506
- # @return [Integer] the channel's unique ID.
507
- attr_reader :id
508
-
509
528
  # @note This data is sent by Discord and it's possible for this to falsely be true for certain kinds of integration
510
529
  # channels (like Twitch subscriber ones). This appears to be a Discord bug that I can't reproduce myself, due to
511
530
  # not having any integrations in place. If this occurs to you please tell me.
@@ -527,13 +546,16 @@ module Discordrb
527
546
  # @return [Hash<Integer => OpenStruct>] the channel's permission overwrites
528
547
  attr_reader :permission_overwrites
529
548
 
530
- alias_method :resolve_id, :id
531
-
532
549
  # @return [true, false] whether or not this channel is a PM channel, with more accuracy than {#is_private}.
533
550
  def private?
534
551
  @server.nil?
535
552
  end
536
553
 
554
+ # @return [String] a string that will mention the channel as a clickable link on Discord.
555
+ def mention
556
+ "<##{@id}>"
557
+ end
558
+
537
559
  # @!visibility private
538
560
  def initialize(data, bot, server = nil)
539
561
  @bot = bot
@@ -569,11 +591,6 @@ module Discordrb
569
591
  end
570
592
  end
571
593
 
572
- # ID based comparison
573
- def ==(other)
574
- Discordrb.id_compare(@id, other)
575
- end
576
-
577
594
  # @return [true, false] whether or not this channel is a text channel
578
595
  def text?
579
596
  @type == TEXT_TYPE
@@ -717,6 +734,7 @@ module Discordrb
717
734
  alias_method :message, :send_message
718
735
  alias_method :invite, :make_invite
719
736
 
737
+ # The inspect method is overwritten to give more useful output
720
738
  def inspect
721
739
  "<Channel name=#{@name} id=#{@id} topic=\"#{@topic}\" type=#{@type} position=#{@position} server=#{@server}>"
722
740
  end
@@ -730,6 +748,8 @@ module Discordrb
730
748
 
731
749
  # A message on Discord that was sent to a text channel
732
750
  class Message
751
+ include IDObject
752
+
733
753
  # @return [String] the content of this message.
734
754
  attr_reader :content
735
755
 
@@ -742,16 +762,12 @@ module Discordrb
742
762
  # @return [Time] the timestamp at which this message was sent.
743
763
  attr_reader :timestamp
744
764
 
745
- # @return [Integer] the ID used to uniquely identify this message.
746
- attr_reader :id
747
-
748
765
  # @return [Array<User>] the users that were mentioned in this message.
749
766
  attr_reader :mentions
750
767
 
751
768
  alias_method :user, :author
752
769
  alias_method :text, :content
753
770
  alias_method :to_s, :content
754
- alias_method :resolve_id, :id
755
771
 
756
772
  # @!visibility private
757
773
  def initialize(data, bot)
@@ -769,11 +785,6 @@ module Discordrb
769
785
  end
770
786
  end
771
787
 
772
- # ID based comparison
773
- def ==(other)
774
- Discordrb.id_compare(@id, other)
775
- end
776
-
777
788
  # Replies to this message with the specified content.
778
789
  # @see Channel#send_message
779
790
  def reply(content)
@@ -802,6 +813,7 @@ module Discordrb
802
813
  @author.bot?
803
814
  end
804
815
 
816
+ # The inspect method is overwritten to give more useful output
805
817
  def inspect
806
818
  "<Message content=\"#{@content}\" id=#{@id} timestamp=#{@timestamp} author=#{@author} channel=#{@channel}>"
807
819
  end
@@ -809,22 +821,21 @@ module Discordrb
809
821
 
810
822
  # A server on Discord
811
823
  class Server
824
+ include IDObject
825
+
812
826
  # @return [String] the region the server is on (e. g. `amsterdam`).
813
827
  attr_reader :region
814
828
 
815
829
  # @return [String] this server's name.
816
830
  attr_reader :name
817
831
 
818
- # @deprecated Use #owner instead, then get the resulting {User}'s {User#id}.
832
+ # @deprecated Use #owner instead, then get the resulting {User}'s ID.
819
833
  # @return [Integer] the server owner's user ID.
820
834
  attr_reader :owner_id
821
835
 
822
836
  # @return [User] The server owner.
823
837
  attr_reader :owner
824
838
 
825
- # @return [Integer] the ID used to uniquely identify this server.
826
- attr_reader :id
827
-
828
839
  # @return [Array<User>] an array of all the users on this server.
829
840
  attr_reader :members
830
841
  alias_method :users, :members
@@ -854,8 +865,6 @@ module Discordrb
854
865
  # @return [Integer] the channel ID of the AFK channel, or `nil` if none is set.
855
866
  attr_reader :afk_channel_id
856
867
 
857
- alias_method :resolve_id, :id
858
-
859
868
  # @!visibility private
860
869
  def initialize(data, bot)
861
870
  @bot = bot
@@ -874,11 +883,6 @@ module Discordrb
874
883
  process_voice_states(data['voice_states'])
875
884
  end
876
885
 
877
- # ID based comparison
878
- def ==(other)
879
- Discordrb.id_compare(@id, other)
880
- end
881
-
882
886
  # @return [Channel] The default channel on this server (usually called #general)
883
887
  def default_channel
884
888
  @bot.channel(@id)
@@ -1045,6 +1049,7 @@ module Discordrb
1045
1049
  @afk_channel = @bot.channel(@afk_channel_id) if @afk_channel_id != 0 && (!@afk_channel || @afk_channel_id != @afk_channel.id)
1046
1050
  end
1047
1051
 
1052
+ # The inspect method is overwritten to give more useful output
1048
1053
  def inspect
1049
1054
  "<Server name=#{@name} id=#{@id} large=#{@large} region=#{@region} owner=#{@owner} afk_channel_id=#{@afk_channel_id} afk_timeout=#{@afk_timeout}>"
1050
1055
  end
@@ -1,23 +1,94 @@
1
1
  module Discordrb
2
- LOG_TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S.%L %z'.freeze
2
+ # The format log timestamps should be in, in strftime format
3
+ LOG_TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S.%L'.freeze
3
4
 
4
5
  # Logs debug messages
5
6
  class Logger
6
- # @return [true, false] whether or not this logger should be in debug mode (all debug messages will be printed)
7
- attr_writer :debug
7
+ # @return [true, false] whether this logger is in extra-fancy mode!
8
+ attr_writer :fancy
8
9
 
9
- # Writes a debug message to the console.
10
- # @param important [true, false] Whether this message should be printed regardless of debug mode being on or off.
11
- def debug(message, important = false)
12
- puts "[DEBUG : #{Thread.current[:discordrb_name]} @ #{Time.now.strftime(LOG_TIMESTAMP_FORMAT)}] #{message}" if @debug || important
10
+ def initialize(fancy = false)
11
+ @fancy = fancy
12
+ self.mode = :normal
13
+ end
14
+
15
+ # The modes this logger can have. This is probably useless unless you want to write your own Logger
16
+ MODES = {
17
+ debug: { long: 'DEBUG', short: 'D', format_code: '' },
18
+ good: { long: 'GOOD', short: '✓', format_code: "\u001B[32m" }, # green
19
+ info: { long: 'INFO', short: 'i', format_code: '' },
20
+ warn: { long: 'WARN', short: '!', format_code: "\u001B[33m" }, # yellow
21
+ error: { long: 'ERROR', short: '✗', format_code: "\u001B[31m" }, # red
22
+ out: { long: 'OUT', short: '→', format_code: "\u001B[36m" }, # cyan
23
+ in: { long: 'IN', short: '←', format_code: "\u001B[35m" } # purple
24
+ }.freeze
25
+
26
+ # The ANSI format code that resets formatting
27
+ FORMAT_RESET = "\u001B[0m".freeze
28
+
29
+ # The ANSI format code that makes something bold
30
+ FORMAT_BOLD = "\u001B[1m".freeze
31
+
32
+ MODES.each do |mode, hash|
33
+ define_method(mode) do |message|
34
+ write(message, hash) if @enabled_modes.include? mode
35
+ end
36
+ end
37
+
38
+ # Sets the logging mode to :debug
39
+ # @param value [true, false] Whether debug mode should be on. If it is off the mode will be set to :normal.
40
+ def debug=(value)
41
+ self.mode = value ? :debug : :normal
42
+ end
43
+
44
+ # Sets the logging mode
45
+ # Possible modes are:
46
+ # * :debug logs everything
47
+ # * :verbose logs everything except for debug messages
48
+ # * :normal logs useful information, warnings and errors
49
+ # * :quiet only logs warnings and errors
50
+ # * :silent logs nothing
51
+ # @param value [Symbol] What logging mode to use
52
+ def mode=(value)
53
+ case value
54
+ when :debug
55
+ @enabled_modes = [:debug, :good, :info, :warn, :error, :out, :in]
56
+ when :verbose
57
+ @enabled_modes = [:good, :info, :warn, :error, :out, :in]
58
+ when :normal
59
+ @enabled_modes = [:info, :warn, :error]
60
+ when :quiet
61
+ @enabled_modes = [:warn, :error]
62
+ when :silent
63
+ @enabled_modes = []
64
+ end
13
65
  end
14
66
 
15
67
  # Logs an exception to the console.
16
68
  # @param e [Exception] The exception to log.
17
- # @param important [true, false] Whether this exception should be printed regardless of debug mode being on or off.
18
- def log_exception(e, important = true)
19
- debug("Exception: #{e.inspect}", important)
20
- e.backtrace.each { |line| debug(line, important) }
69
+ def log_exception(e)
70
+ error("Exception: #{e.inspect}")
71
+ e.backtrace.each { |line| error(line) }
72
+ end
73
+
74
+ private
75
+
76
+ def write(message, mode)
77
+ thread_name = Thread.current[:discordrb_name]
78
+ timestamp = Time.now.strftime(LOG_TIMESTAMP_FORMAT)
79
+ if @fancy
80
+ fancy_write(message, mode, thread_name, timestamp)
81
+ else
82
+ simple_write(message, mode, thread_name, timestamp)
83
+ end
84
+ end
85
+
86
+ def fancy_write(message, mode, thread_name, timestamp)
87
+ puts "#{timestamp} #{FORMAT_BOLD}#{thread_name.ljust(16)}#{FORMAT_RESET} #{mode[:format_code]}#{mode[:short]}#{FORMAT_RESET} #{message}"
88
+ end
89
+
90
+ def simple_write(message, mode, thread_name, timestamp)
91
+ puts "[#{mode[:long]} : #{thread_name} @ #{timestamp}] #{message}"
21
92
  end
22
93
  end
23
94
  end
@@ -169,8 +169,8 @@ module Discordrb
169
169
  private
170
170
 
171
171
  def fail_token(msg, email = nil, e = nil)
172
- LOGGER.debug("Token not retrieved from cache - #{msg}")
173
- LOGGER.log_exception(e, false) if e
172
+ LOGGER.warn("Token not retrieved from cache - #{msg}")
173
+ LOGGER.log_exception(e) if e
174
174
  @data.delete(email) if email
175
175
  nil
176
176
  end
@@ -1,5 +1,5 @@
1
1
  # Discordrb and all its functionality, in this case only the version.
2
2
  module Discordrb
3
3
  # The current version of discordrb.
4
- VERSION = '1.7.5'.freeze
4
+ VERSION = '1.8.0'.freeze
5
5
  end
@@ -194,6 +194,9 @@ module Discordrb::Voice
194
194
  # Event handlers; public for websocket-simple to work correctly
195
195
  # @!visibility private
196
196
  def websocket_open
197
+ # Give the current thread a name ('Voice Web Socket Internal')
198
+ Thread.current[:discordrb_name] = 'vws-i'
199
+
197
200
  # Send the init packet
198
201
  send_init(@channel.server.id, @bot.bot_user.id, @session, @token)
199
202
  end
@@ -180,6 +180,12 @@ module Discordrb::Voice
180
180
  # Encode data
181
181
  @encoder.encode(buf)
182
182
  end
183
+
184
+ # If the stream is a process, kill it
185
+ Process.kill('TERM', encoded_io.pid) if encoded_io.respond_to? :pid
186
+
187
+ # Close the stream
188
+ encoded_io.close
183
189
  end
184
190
 
185
191
  # Plays an encoded audio file of arbitrary format to the channel.
@@ -206,11 +212,20 @@ module Discordrb::Voice
206
212
  @bot.debug "Reading DCA file #{file}"
207
213
  input_stream = open(file)
208
214
 
215
+ magic = input_stream.read(4)
216
+ raise ArgumentError, 'Not a DCA1 file! The file might have been corrupted, please recreate it.' unless magic == 'DCA1'
217
+
218
+ # Read the metadata header, then read the metadata and discard it as we don't care about it
219
+ metadata_header = input_stream.read(4).unpack('l<')[0]
220
+ input_stream.read(metadata_header)
221
+
209
222
  # Play the data, without re-encoding it to opus
210
223
  play_internal do
211
224
  begin
212
225
  # Read header
213
- header = input_stream.read(2).unpack('S')[0]
226
+ header = input_stream.read(2).unpack('s<')[0]
227
+
228
+ raise RuntimeError, 'Negative header in DCA file! Your file is likely corrupted.' if header < 0
214
229
  rescue EOFError
215
230
  @bot.debug 'Finished DCA parsing'
216
231
  break
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discordrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.5
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - meew0
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-03 00:00:00.000000000 Z
11
+ date: 2016-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye-websocket