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 +4 -4
- data/.rubocop.yml +6 -1
- data/CHANGELOG.md +14 -0
- data/README.md +1 -3
- data/examples/eval.rb +17 -0
- data/examples/ping_with_respond_time.rb +13 -0
- data/examples/shutdown.rb +14 -0
- data/lib/discordrb/bot.rb +28 -2
- data/lib/discordrb/container.rb +1 -4
- data/lib/discordrb/data.rb +31 -0
- data/lib/discordrb/events/channels.rb +2 -0
- data/lib/discordrb/events/guilds.rb +2 -0
- data/lib/discordrb/events/members.rb +2 -0
- data/lib/discordrb/events/presence.rb +4 -2
- data/lib/discordrb/events/roles.rb +4 -0
- data/lib/discordrb/events/typing.rb +2 -0
- data/lib/discordrb/events/voice_state_update.rb +2 -0
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +3 -0
- data/lib/discordrb/voice/network.rb +5 -0
- data/lib/discordrb/voice/voice_bot.rb +20 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62c28a349c8f96a8a2774df678a355ea648ffada
|
4
|
+
data.tar.gz: fa5f7258abac813c417549a9a9a56aaa76c42de0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ccbce3f46ad696ed1e285c7fc6625eb06c7855d21afe41768093e82d126557b68b8acc27b530ff6864745077d27879d95c7119b043de9d117a4cce41e0a2c89
|
7
|
+
data.tar.gz: a308092e8dba4c4d7e491b921576c39ea5b40a2c362fe2df8a98c946f8f8cd0bb6e7a3c6f68e2189c8734041282c654d8353b0989dbedffad8a828b25d336882
|
data/.rubocop.yml
CHANGED
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 [
|
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 [
|
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)
|
data/lib/discordrb/container.rb
CHANGED
@@ -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
|
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.
|
data/lib/discordrb/data.rb
CHANGED
@@ -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
|
@@ -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
|
-
@
|
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.
|
@@ -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']
|
data/lib/discordrb/version.rb
CHANGED
@@ -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
|
-
|
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.
|
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-
|
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
|