discordrb 2.0.0 → 2.0.1

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: ca5ae97de9345328dac0b9f9e8c14f38e2d70bc9
4
- data.tar.gz: fe60d3642cecec76594a3356d93c923be5f27997
3
+ metadata.gz: 62c28a349c8f96a8a2774df678a355ea648ffada
4
+ data.tar.gz: fa5f7258abac813c417549a9a9a56aaa76c42de0
5
5
  SHA512:
6
- metadata.gz: fa6c978e90c0f5338a9f6b67f0cf1fafd6d2c847c76b1fb6aadacfb820c95248ecdb8962ab84d63c2811b0bd28dd6913b72ae1463b671822f8716d526d04e9dc
7
- data.tar.gz: b0eab7396be2942e2c7f9370c49fa1b45e70c2836d1281bf31e9fc98bc44919ac276c6a453000758b90a502cbde65ced78782a5b5b82c5472a20f429dc710bb7
6
+ metadata.gz: 8ccbce3f46ad696ed1e285c7fc6625eb06c7855d21afe41768093e82d126557b68b8acc27b530ff6864745077d27879d95c7119b043de9d117a4cce41e0a2c89
7
+ data.tar.gz: a308092e8dba4c4d7e491b921576c39ea5b40a2c362fe2df8a98c946f8f8cd0bb6e7a3c6f68e2189c8734041282c654d8353b0989dbedffad8a828b25d336882
data/.rubocop.yml CHANGED
@@ -48,4 +48,9 @@ Style/Alias:
48
48
  # So RuboCop doesn't complain about application IDs
49
49
  Style/NumericLiterals:
50
50
  Exclude:
51
- - examples/*
51
+ - examples/*
52
+
53
+ # Ignore `eval` in the examples folder
54
+ Lint/Eval:
55
+ Exclude:
56
+ - examples/*
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.1
4
+
5
+ - Added some more examples ([#75](https://github.com/meew0/discordrb/pull/75), thanks @greenbigfrog)
6
+ - Users can now be ignored from messages at gateway level (`Bot#ignore_user`, `Bot#unignore_user`)
7
+ - `Member#add_role` and `Member#remove_role` were re-added from User - they were missing before
8
+
9
+
10
+ ### Bugfixes
11
+
12
+ - Fixed some typos in the documentation
13
+ - If a server is actually unavailable it will no longer spam the console with timeout messages
14
+ - VoiceBot now sends five frames of silence after finishing a track. This fixes an issue where the sound from the last track would bleed over into the new one due to interpolation.
15
+ - Fixed a bug where playing something right after connecting to voice would sometimes cause the encryption key to not be set
16
+
3
17
  ## 2.0.0
4
18
 
5
19
  This is the first major update with some breaking changes! Those are highlighted in bold with migration advice after them. Ask in the Discord channel (see the README) if you have questions.
data/README.md CHANGED
@@ -7,8 +7,6 @@
7
7
 
8
8
  An implementation of the [Discord](https://discordapp.com/) API using Ruby.
9
9
 
10
- **News**: Please help test version 2 of discordrb with a lot of changes! A preliminary changelog can be found [here](https://gist.github.com/meew0/ea120051da52604e7873b7cfaed4c40b). The code can be found on the `v2` branch; if you're using bundler you can change the gem reference to `gem 'discordrb', git: 'git://github.com/meew0/discordrb.git', branch: 'v2'`. A downloadable gem file for everybody else will follow here shortly.
11
-
12
10
  ## Quick links to sections
13
11
 
14
12
  * [Dependencies](https://github.com/meew0/discordrb#dependencies)
@@ -78,7 +76,7 @@ You can make a simple bot like this:
78
76
  ```ruby
79
77
  require 'discordrb'
80
78
 
81
- bot = Discordrb::Bot.new token: '<token here>'
79
+ bot = Discordrb::Bot.new token: '<token here>', application_id: 168123456789123456
82
80
 
83
81
  bot.message(with_text: 'Ping!') do |event|
84
82
  event.respond 'Pong!'
data/examples/eval.rb ADDED
@@ -0,0 +1,17 @@
1
+ # Gives you the ability to execute code on the fly
2
+
3
+ require 'discordrb'
4
+
5
+ bot = Discordrb::Commands::CommandBot.new 'email@example.com', 'hunter2'
6
+
7
+ bot.command(:eval, help_available: false) do |event, code|
8
+ break if event.user.id == 000000 # Replace number with your ID
9
+
10
+ begin
11
+ eval(code)
12
+ rescue
13
+ "An error occured 😞"
14
+ end
15
+ end
16
+
17
+ bot.run
@@ -0,0 +1,13 @@
1
+ # Pinging the bot will also tell you the time it takes the bot to send the message
2
+
3
+ require 'discordrb'
4
+
5
+ bot = Discordrb::Commands::CommandBot.new 'email@example.com', 'hunter2'
6
+
7
+ bot.command(:ping) do |event|
8
+ m = event.respond('Pong!')
9
+ m.edit "Pong! Time taken: #{Time.now - event.timestamp} seconds."
10
+ nil
11
+ end
12
+
13
+ bot.run
@@ -0,0 +1,14 @@
1
+ # This script allows you to shutdown the bot on command
2
+
3
+ require 'discordrb'
4
+
5
+ bot = Discordrb::Commands::CommandBot.new 'email@example.com', 'hunter2'
6
+
7
+ bot.command(:exit, help_available: false) do |event|
8
+ break if event.user.id == 000000 # Replace number with your ID
9
+
10
+ bot.send_message(event.channel.id, 'Bot is shutting down')
11
+ exit
12
+ end
13
+
14
+ bot.run
data/lib/discordrb/bot.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'rest-client'
4
4
  require 'zlib'
5
+ require 'set'
5
6
 
6
7
  require 'discordrb/events/message'
7
8
  require 'discordrb/events/typing'
@@ -81,11 +82,11 @@ module Discordrb
81
82
  # Represents a Discord bot, including servers, users, etc.
82
83
  class Bot
83
84
  # The list of users the bot shares a server with.
84
- # @return [Array<User>] The users.
85
+ # @return [Hash<Integer => User>] The users by ID.
85
86
  attr_reader :users
86
87
 
87
88
  # The list of servers the bot is currently in.
88
- # @return [Array<Server>] The servers.
89
+ # @return [Hash<Integer => Server>] The servers by ID.
89
90
  attr_reader :servers
90
91
 
91
92
  # The list of currently running threads used to parse and call events.
@@ -184,6 +185,8 @@ module Discordrb
184
185
  @voices = {}
185
186
  @should_connect_to_voice = {}
186
187
 
188
+ @ignored_ids = Set.new
189
+
187
190
  @event_threads = []
188
191
  @current_thread = 0
189
192
  end
@@ -525,6 +528,20 @@ module Discordrb
525
528
  @awaits[key] = await
526
529
  end
527
530
 
531
+ # Add a user to the list of ignored users. Those users will be ignored in message events at event processing level.
532
+ # @note Ignoring a user only prevents any message events (including mentions, commands etc.) from them! Typing and
533
+ # presence and any other events will still be received.
534
+ # @param user [User, Integer, #resolve_id] The user, or its ID, to be ignored.
535
+ def ignore_user(user)
536
+ @ignored_ids << user.resolve_id
537
+ end
538
+
539
+ # Remove a user from the ignore list.
540
+ # @param user [User, Integer, #resolve_id] The user, or its ID, to be unignored.
541
+ def unignore_user(user)
542
+ @ignored_ids.delete(user.resolve_id)
543
+ end
544
+
528
545
  # @see Logger#debug
529
546
  def debug(message)
530
547
  LOGGER.debug(message)
@@ -966,6 +983,10 @@ module Discordrb
966
983
  # The server streaming timed out!
967
984
  LOGGER.warn("Server streaming timed out with #{@unavailable_servers} servers remaining")
968
985
  LOGGER.warn("This means some servers are unavailable due to an outage. Notifying ready now, we'll have to live without these servers")
986
+
987
+ # Unset the unavailable server count so this doesn't get triggered again
988
+ @unavailable_servers = nil
989
+
969
990
  notify_ready
970
991
  end
971
992
 
@@ -1039,6 +1060,11 @@ module Discordrb
1039
1060
  server = server(id)
1040
1061
  server.process_chunk(data['members'])
1041
1062
  when :MESSAGE_CREATE
1063
+ if @ignored_ids.include?(data['author']['id'].to_i)
1064
+ debug("Ignored author with ID #{data['author']['id']}")
1065
+ return
1066
+ end
1067
+
1042
1068
  create_message(data)
1043
1069
 
1044
1070
  message = Message.new(data, self)
@@ -26,7 +26,6 @@ module Discordrb
26
26
  # @option attributes [String, Integer, Channel] :in Matches the channel the message was sent in.
27
27
  # @option attributes [String, Integer, User] :from Matches the user that sent the message.
28
28
  # @option attributes [String] :content Exactly matches the entire content of the message.
29
- # @option attributes [String] :content Exactly matches the entire content of the message.
30
29
  # @option attributes [Time] :after Matches a time after the time the message was sent at.
31
30
  # @option attributes [Time] :before Matches a time before the time the message was sent at.
32
31
  # @option attributes [Boolean] :private Matches whether or not the channel is private.
@@ -124,7 +123,6 @@ module Discordrb
124
123
  # @option attributes [String, Integer, Channel] :in Matches the channel the message was sent in.
125
124
  # @option attributes [String, Integer, User] :from Matches the user that sent the message.
126
125
  # @option attributes [String] :content Exactly matches the entire content of the message.
127
- # @option attributes [String] :content Exactly matches the entire content of the message.
128
126
  # @option attributes [Time] :after Matches a time after the time the message was sent at.
129
127
  # @option attributes [Time] :before Matches a time before the time the message was sent at.
130
128
  # @option attributes [Boolean] :private Matches whether or not the channel is private.
@@ -157,7 +155,7 @@ module Discordrb
157
155
  register_event(ChannelUpdateEvent, attributes, block)
158
156
  end
159
157
 
160
- # This **event** is raised when a channel is updated.
158
+ # This **event** is raised when a channel is deleted.
161
159
  # @param attributes [Hash] The event's attributes.
162
160
  # @option attributes [String] :type Matches the type of channel that is being deleted (text or voice)
163
161
  # @option attributes [String] :name Matches the name of the deleted channel.
@@ -288,7 +286,6 @@ module Discordrb
288
286
  # @option attributes [String, Integer, Channel] :in Matches the channel the message was sent in.
289
287
  # @option attributes [String, Integer, User] :from Matches the user that sent the message.
290
288
  # @option attributes [String] :content Exactly matches the entire content of the message.
291
- # @option attributes [String] :content Exactly matches the entire content of the message.
292
289
  # @option attributes [Time] :after Matches a time after the time the message was sent at.
293
290
  # @option attributes [Time] :before Matches a time before the time the message was sent at.
294
291
  # @option attributes [Boolean] :private Matches whether or not the channel is private.
@@ -338,6 +338,26 @@ module Discordrb
338
338
  @server.owner == self
339
339
  end
340
340
 
341
+ # Adds one or more roles to this member.
342
+ # @param role [Role, Array<Role>] The role(s) to add.
343
+ def add_role(role)
344
+ role_ids = role_id_array(role)
345
+ old_role_ids = @roles.map(&:id)
346
+ new_role_ids = (old_role_ids + role_ids).uniq
347
+
348
+ API.update_user_roles(@bot.token, @server.id, @user.id, new_role_ids)
349
+ end
350
+
351
+ # Removes one or more roles from this member.
352
+ # @param role [Role, Array<Role>] The role(s) to remove.
353
+ def remove_role(role)
354
+ old_role_ids = @roles.map(&:id)
355
+ role_ids = role_id_array(role)
356
+ new_role_ids = old_role_ids.reject { |i| role_ids.include?(i) }
357
+
358
+ API.update_user_roles(@bot.token, @server.id, @user.id, new_role_ids)
359
+ end
360
+
341
361
  # Update this member's roles
342
362
  # @note For internal use only.
343
363
  # @!visibility private
@@ -364,6 +384,17 @@ module Discordrb
364
384
  def inspect
365
385
  "<Member user=#{@user.inspect} server=#{@server.inspect} joined_at=#{@joined_at} roles=#{@roles.inspect} voice_channel=#{@voice_channel.inspect} mute=#{@mute} deaf=#{@deaf} self_mute=#{@self_mute} self_deaf=#{@self_deaf}>"
366
386
  end
387
+
388
+ private
389
+
390
+ # Utility method to get a list of role IDs from one role or an array of roles
391
+ def role_id_array(role)
392
+ if role.is_a? Array
393
+ role.map(&:resolve_id)
394
+ else
395
+ [role.resolve_id]
396
+ end
397
+ end
367
398
  end
368
399
 
369
400
  # Recipients are members on private channels - they exist for completeness purposes, but all
@@ -81,6 +81,8 @@ module Discordrb::Events
81
81
  attr_reader :server
82
82
 
83
83
  def initialize(data, bot)
84
+ @bot = bot
85
+
84
86
  @type = data['type']
85
87
  @topic = data['topic']
86
88
  @position = data['position']
@@ -10,6 +10,8 @@ module Discordrb::Events
10
10
  attr_reader :server
11
11
 
12
12
  def initialize(data, bot)
13
+ @bot = bot
14
+
13
15
  init_server(data, bot)
14
16
  end
15
17
 
@@ -18,6 +18,8 @@ module Discordrb::Events
18
18
  alias_method :member, :user
19
19
 
20
20
  def initialize(data, bot)
21
+ @bot = bot
22
+
21
23
  @server = bot.server(data['guild_id'].to_i)
22
24
  return unless @server
23
25
 
@@ -16,6 +16,8 @@ module Discordrb::Events
16
16
  attr_reader :status
17
17
 
18
18
  def initialize(data, bot)
19
+ @bot = bot
20
+
19
21
  @user = bot.user(data['user']['id'].to_i)
20
22
  @status = data['status'].to_sym
21
23
  @server = bot.server(data['guild_id'].to_i)
@@ -61,10 +63,10 @@ module Discordrb::Events
61
63
  attr_reader :game
62
64
 
63
65
  def initialize(data, bot)
64
- @user = bot.user(data['user']['id'].to_i)
66
+ @bot = bot
65
67
 
68
+ @user = bot.user(data['user']['id'].to_i)
66
69
  @game = data['game'] ? data['game']['name'] : nil
67
-
68
70
  @server = bot.server(data['guild_id'].to_i)
69
71
  end
70
72
  end
@@ -13,6 +13,8 @@ module Discordrb::Events
13
13
  attr_reader :server
14
14
 
15
15
  def initialize(data, bot)
16
+ @bot = bot
17
+
16
18
  @server = bot.server(data['guild_id'].to_i)
17
19
  return unless @server
18
20
 
@@ -48,6 +50,8 @@ module Discordrb::Events
48
50
  attr_reader :server
49
51
 
50
52
  def initialize(data, bot)
53
+ @bot = bot
54
+
51
55
  # The role should already be deleted from the server's list
52
56
  # by the time we create this event, so we'll create a temporary
53
57
  # role object for event consumers to use.
@@ -16,6 +16,8 @@ module Discordrb::Events
16
16
  attr_reader :timestamp
17
17
 
18
18
  def initialize(data, bot)
19
+ @bot = bot
20
+
19
21
  @user_id = data['user_id'].to_i
20
22
 
21
23
  @channel_id = data['channel_id'].to_i
@@ -9,6 +9,8 @@ module Discordrb::Events
9
9
  attr_reader :user, :token, :suppress, :session_id, :self_mute, :self_deaf, :mute, :deaf, :server, :channel
10
10
 
11
11
  def initialize(data, bot)
12
+ @bot = bot
13
+
12
14
  @token = data['token']
13
15
  @suppress = data['suppress']
14
16
  @session_id = data['session_id']
@@ -3,5 +3,5 @@
3
3
  # Discordrb and all its functionality, in this case only the version.
4
4
  module Discordrb
5
5
  # The current version of discordrb.
6
- VERSION = '2.0.0'.freeze
6
+ VERSION = '2.0.1'.freeze
7
7
  end
@@ -49,6 +49,9 @@ module Discordrb::Voice
49
49
  @opus.encode(buffer, 1920)
50
50
  end
51
51
 
52
+ # One frame of complete silence Opus encoded
53
+ OPUS_SILENCE = [0xF8, 0xFF, 0xFE].pack('C*').freeze
54
+
52
55
  # Adjusts the volume of a given buffer of s16le PCM data.
53
56
  # @param buf [String] An unencoded PCM (s16le) buffer.
54
57
  # @param mult [Float] The volume multiplier, 1 for same volume.
@@ -260,6 +260,11 @@ module Discordrb::Voice
260
260
 
261
261
  # Send UDP init packet with received UDP data
262
262
  send_udp_connection(ip, port, @udp_mode)
263
+
264
+ @bot.debug('Waiting for op 4 now')
265
+
266
+ # Wait for op 4, then finish
267
+ sleep 0.05 until @ready
263
268
  end
264
269
 
265
270
  # Disconnects the websocket and kills the thread
@@ -227,6 +227,9 @@ module Discordrb::Voice
227
227
 
228
228
  # Plays a stream of audio data in the DCA format. This format has the advantage that no recoding has to be
229
229
  # done - the file contains the data exactly as Discord needs it.
230
+ # @note DCA playback will not be affected by the volume modifier ({volume=}) because the modifier operates on raw
231
+ # PCM, not opus data. Modifying the volume of DCA data would involve decoding it, multiplying the samples and
232
+ # re-encoding it, which defeats its entire purpose (no recoding).
230
233
  # @see https://github.com/bwmarrin/dca
231
234
  # @see #play
232
235
  def play_dca(file)
@@ -290,8 +293,7 @@ module Discordrb::Voice
290
293
 
291
294
  # Track packet count, sequence and time (Discord requires this)
292
295
  count += 1
293
- (@sequence + 10 < 65_535) ? @sequence += 1 : @sequence = 0
294
- (@time + 9600 < 4_294_967_295) ? @time += 960 : @time = 0
296
+ increment_packet_headers
295
297
 
296
298
  # Get packet data
297
299
  buf = yield
@@ -335,10 +337,26 @@ module Discordrb::Voice
335
337
  sleep @length / 1000.0
336
338
  end
337
339
 
340
+ @bot.debug('Sending five silent frames to clear out buffers')
341
+
342
+ 5.times do
343
+ increment_packet_headers
344
+ @udp.send_audio(Encoder::OPUS_SILENCE, @sequence, @time)
345
+
346
+ # Length adjustments don't matter here, we can just wait 20 ms since nobody is going to hear it anyway
347
+ sleep IDEAL_LENGTH / 1000.0
348
+ end
349
+
338
350
  @bot.debug('Performing final cleanup after stream ended')
339
351
 
340
352
  # Final cleanup
341
353
  stop_playing
342
354
  end
355
+
356
+ # Increment sequence and time
357
+ def increment_packet_headers
358
+ (@sequence + 10 < 65_535) ? @sequence += 1 : @sequence = 0
359
+ (@time + 9600 < 4_294_967_295) ? @time += 960 : @time = 0
360
+ end
343
361
  end
344
362
  end
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: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - meew0
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-08 00:00:00.000000000 Z
11
+ date: 2016-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -172,8 +172,11 @@ files:
172
172
  - bin/setup
173
173
  - discordrb.gemspec
174
174
  - examples/commands.rb
175
+ - examples/eval.rb
175
176
  - examples/ping.rb
177
+ - examples/ping_with_respond_time.rb
176
178
  - examples/pm_send.rb
179
+ - examples/shutdown.rb
177
180
  - lib/discordrb.rb
178
181
  - lib/discordrb/api.rb
179
182
  - lib/discordrb/await.rb