discordrb 1.8.1 → 2.0.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.

Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.overcommit.yml +7 -0
  3. data/.rubocop.yml +5 -4
  4. data/CHANGELOG.md +77 -0
  5. data/README.md +25 -15
  6. data/discordrb.gemspec +2 -3
  7. data/examples/commands.rb +14 -2
  8. data/examples/ping.rb +1 -1
  9. data/examples/pm_send.rb +1 -1
  10. data/lib/discordrb.rb +9 -0
  11. data/lib/discordrb/api.rb +176 -50
  12. data/lib/discordrb/await.rb +3 -0
  13. data/lib/discordrb/bot.rb +607 -372
  14. data/lib/discordrb/cache.rb +208 -0
  15. data/lib/discordrb/commands/command_bot.rb +50 -18
  16. data/lib/discordrb/commands/container.rb +11 -2
  17. data/lib/discordrb/commands/events.rb +2 -0
  18. data/lib/discordrb/commands/parser.rb +10 -8
  19. data/lib/discordrb/commands/rate_limiter.rb +2 -0
  20. data/lib/discordrb/container.rb +24 -25
  21. data/lib/discordrb/data.rb +521 -219
  22. data/lib/discordrb/errors.rb +6 -7
  23. data/lib/discordrb/events/await.rb +2 -0
  24. data/lib/discordrb/events/bans.rb +3 -1
  25. data/lib/discordrb/events/channels.rb +124 -0
  26. data/lib/discordrb/events/generic.rb +2 -0
  27. data/lib/discordrb/events/guilds.rb +16 -13
  28. data/lib/discordrb/events/lifetime.rb +12 -2
  29. data/lib/discordrb/events/members.rb +26 -15
  30. data/lib/discordrb/events/message.rb +20 -7
  31. data/lib/discordrb/events/presence.rb +18 -2
  32. data/lib/discordrb/events/roles.rb +83 -0
  33. data/lib/discordrb/events/typing.rb +15 -2
  34. data/lib/discordrb/events/voice_state_update.rb +2 -0
  35. data/lib/discordrb/light.rb +8 -0
  36. data/lib/discordrb/light/data.rb +62 -0
  37. data/lib/discordrb/light/integrations.rb +73 -0
  38. data/lib/discordrb/light/light_bot.rb +56 -0
  39. data/lib/discordrb/logger.rb +4 -0
  40. data/lib/discordrb/permissions.rb +16 -12
  41. data/lib/discordrb/token_cache.rb +3 -0
  42. data/lib/discordrb/version.rb +3 -1
  43. data/lib/discordrb/voice/encoder.rb +2 -0
  44. data/lib/discordrb/voice/network.rb +21 -14
  45. data/lib/discordrb/voice/voice_bot.rb +26 -3
  46. data/lib/discordrb/websocket.rb +69 -0
  47. metadata +15 -26
  48. data/lib/discordrb/events/channel_create.rb +0 -44
  49. data/lib/discordrb/events/channel_delete.rb +0 -44
  50. data/lib/discordrb/events/channel_update.rb +0 -46
  51. data/lib/discordrb/events/guild_role_create.rb +0 -35
  52. data/lib/discordrb/events/guild_role_delete.rb +0 -36
  53. data/lib/discordrb/events/guild_role_update.rb +0 -35
@@ -1,14 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Discordrb
2
4
  # Custom errors raised in various places
3
5
  module Errors
4
6
  # Raised when authentication data is invalid or incorrect.
5
- class InvalidAuthenticationError < RuntimeError; end
6
-
7
- # Raised when a HTTP status code indicates a failure
8
- class HTTPStatusError < RuntimeError
9
- attr_reader :status
10
- def initialize(status)
11
- @status = status
7
+ class InvalidAuthenticationError < RuntimeError
8
+ # Default message for this exception
9
+ def message
10
+ 'User login failed due to an invalid email or password!'
12
11
  end
13
12
  end
14
13
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
  require 'discordrb/await'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
 
3
5
  module Discordrb::Events
@@ -30,7 +32,7 @@ module Discordrb::Events
30
32
  elsif a.is_a? Integer
31
33
  a == e.id
32
34
  elsif a == :bot
33
- e.bot?
35
+ e.current_bot?
34
36
  else
35
37
  a == e
36
38
  end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'discordrb/events/generic'
4
+ require 'discordrb/data'
5
+
6
+ module Discordrb::Events
7
+ # Raised when a channel is created
8
+ class ChannelCreateEvent < Event
9
+ # @return [Channel] the channel in question.
10
+ attr_reader :channel
11
+
12
+ # @!attribute [r] type
13
+ # @return [String] the channel's type.
14
+ # @see Channel#type
15
+ # @!attribute [r] topic
16
+ # @return [String] the channel's topic.
17
+ # @see Channel#topic
18
+ # @!attribute [r] position
19
+ # @return [Integer] the position of the channel in the channels list.
20
+ # @see Channel#position
21
+ # @!attribute [r] name
22
+ # @return [String] the channel's name
23
+ # @see Channel#name
24
+ # @!attribute [r] id
25
+ # @return [Integer] the channel's unique ID.
26
+ # @see Channel#id
27
+ # @!attribute [r] server
28
+ # @return [Server] the server the channel belongs to.
29
+ # @see Channel#server
30
+ delegate :type, :topic, :position, :name, :id, :server, to: :channel
31
+
32
+ def initialize(data, bot)
33
+ @bot = bot
34
+ @channel = bot.channel(data['id'].to_i)
35
+ end
36
+ end
37
+
38
+ # Event handler for ChannelCreateEvent
39
+ class ChannelCreateEventHandler < EventHandler
40
+ def matches?(event)
41
+ # Check for the proper event type
42
+ return false unless event.is_a? ChannelCreateEvent
43
+
44
+ [
45
+ matches_all(@attributes[:type], event.type) do |a, e|
46
+ a == if a.is_a? String
47
+ e.name
48
+ else
49
+ e
50
+ end
51
+ end,
52
+ matches_all(@attributes[:name], event.name) do |a, e|
53
+ a == if a.is_a? String
54
+ e.to_s
55
+ else
56
+ e
57
+ end
58
+ end
59
+ ].reduce(true, &:&)
60
+ end
61
+ end
62
+
63
+ # Raised when a channel is deleted
64
+ class ChannelDeleteEvent < Event
65
+ # @return [String] the channel's type (text or voice)
66
+ attr_reader :type
67
+
68
+ # @return [String] the channel's topic
69
+ attr_reader :topic
70
+
71
+ # @return [Integer] the position of the channel on the list
72
+ attr_reader :position
73
+
74
+ # @return [String] the channel's name
75
+ attr_reader :name
76
+
77
+ # @return [Integer] the channel's ID
78
+ attr_reader :id
79
+
80
+ # @return [Server] the channel's server
81
+ attr_reader :server
82
+
83
+ def initialize(data, bot)
84
+ @type = data['type']
85
+ @topic = data['topic']
86
+ @position = data['position']
87
+ @name = data['name']
88
+ @is_private = data['is_private']
89
+ @id = data['id'].to_i
90
+ @server = bot.server(data['guild_id'].to_i) if data['guild_id']
91
+ end
92
+ end
93
+
94
+ # Event handler for ChannelDeleteEvent
95
+ class ChannelDeleteEventHandler < EventHandler
96
+ def matches?(event)
97
+ # Check for the proper event type
98
+ return false unless event.is_a? ChannelDeleteEvent
99
+
100
+ [
101
+ matches_all(@attributes[:type], event.type) do |a, e|
102
+ a == if a.is_a? String
103
+ e.name
104
+ else
105
+ e
106
+ end
107
+ end,
108
+ matches_all(@attributes[:name], event.name) do |a, e|
109
+ a == if a.is_a? String
110
+ e.to_s
111
+ else
112
+ e
113
+ end
114
+ end
115
+ ].reduce(true, &:&)
116
+ end
117
+ end
118
+
119
+ # Raised when a channel is updated (e.g. topic changes)
120
+ class ChannelUpdateEvent < ChannelCreateEvent; end
121
+
122
+ # Event handler for ChannelUpdateEvent
123
+ class ChannelUpdateEventHandler < ChannelCreateEventHandler; end
124
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/module'
2
4
 
3
5
  # Events used by discordrb
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
  require 'discordrb/data'
3
5
 
4
6
  module Discordrb::Events
5
7
  # Generic subclass for server events (create/update/delete)
6
- class GuildEvent < Event
8
+ class ServerEvent < Event
9
+ # @return [Server] the server in question.
7
10
  attr_reader :server
8
11
 
9
12
  def initialize(data, bot)
@@ -11,17 +14,17 @@ module Discordrb::Events
11
14
  end
12
15
 
13
16
  # Initializes this event with server data. Should be overwritten in case the server doesn't exist at the time
14
- # of event creation (e. g. {GuildDeleteEvent})
17
+ # of event creation (e. g. {ServerDeleteEvent})
15
18
  def init_server(data, bot)
16
19
  @server = bot.server(data['id'].to_i)
17
20
  end
18
21
  end
19
22
 
20
23
  # Generic event handler for member events
21
- class GuildEventHandler < EventHandler
24
+ class ServerEventHandler < EventHandler
22
25
  def matches?(event)
23
26
  # Check for the proper event type
24
- return false unless event.is_a? GuildEvent
27
+ return false unless event.is_a? ServerEvent
25
28
 
26
29
  [
27
30
  matches_all(@attributes[:server], event.server) do |a, e|
@@ -39,27 +42,27 @@ module Discordrb::Events
39
42
 
40
43
  # Server is created
41
44
  # @see Discordrb::EventContainer#server_create
42
- class GuildCreateEvent < GuildEvent; end
45
+ class ServerCreateEvent < ServerEvent; end
43
46
 
44
- # Event handler for {GuildCreateEvent}
45
- class GuildCreateEventHandler < GuildEventHandler; end
47
+ # Event handler for {ServerCreateEvent}
48
+ class ServerCreateEventHandler < ServerEventHandler; end
46
49
 
47
50
  # Server is updated (e.g. name changed)
48
51
  # @see Discordrb::EventContainer#server_update
49
- class GuildUpdateEvent < GuildEvent; end
52
+ class ServerUpdateEvent < ServerEvent; end
50
53
 
51
- # Event handler for {GuildUpdateEvent}
52
- class GuildUpdateEventHandler < GuildEventHandler; end
54
+ # Event handler for {ServerUpdateEvent}
55
+ class ServerUpdateEventHandler < ServerEventHandler; end
53
56
 
54
57
  # Server is deleted
55
58
  # @see Discordrb::EventContainer#server_delete
56
- class GuildDeleteEvent < GuildEvent
59
+ class ServerDeleteEvent < ServerEvent
57
60
  # Overide init_server to account for the deleted server
58
61
  def init_server(data, bot)
59
62
  @server = Discordrb::Server.new(data, bot)
60
63
  end
61
64
  end
62
65
 
63
- # Event handler for {GuildDeleteEvent}
64
- class GuildDeleteEventHandler < GuildEventHandler; end
66
+ # Event handler for {ServerDeleteEvent}
67
+ class ServerDeleteEventHandler < ServerEventHandler; end
65
68
  end
@@ -1,14 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
 
3
5
  module Discordrb::Events
6
+ # Common superclass for all lifetime events
7
+ class LifetimeEvent < Event
8
+ # @!visibility private
9
+ def initialize(bot)
10
+ @bot = bot
11
+ end
12
+ end
13
+
4
14
  # @see Discordrb::EventContainer#ready
5
- class ReadyEvent < Event; end
15
+ class ReadyEvent < LifetimeEvent; end
6
16
 
7
17
  # Event handler for {ReadyEvent}
8
18
  class ReadyEventHandler < TrueEventHandler; end
9
19
 
10
20
  # @see Discordrb::EventContainer#disconnected
11
- class DisconnectEvent < Event; end
21
+ class DisconnectEvent < LifetimeEvent; end
12
22
 
13
23
  # Event handler for {DisconnectEvent}
14
24
  class DisconnectEventHandler < TrueEventHandler; end
@@ -1,10 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
  require 'discordrb/data'
3
5
 
4
6
  module Discordrb::Events
5
7
  # Generic subclass for server member events (add/update/delete)
6
- class GuildMemberEvent < Event
7
- attr_reader :user, :roles, :server
8
+ class ServerMemberEvent < Event
9
+ # @return [Member] the member in question.
10
+ attr_reader :user
11
+
12
+ # @return [Array<Role>] the member's roles.
13
+ attr_reader :roles
14
+
15
+ # @return [Server] the server on which the event happened.
16
+ attr_reader :server
17
+
18
+ alias_method :member, :user
8
19
 
9
20
  def initialize(data, bot)
10
21
  @server = bot.server(data['guild_id'].to_i)
@@ -18,7 +29,7 @@ module Discordrb::Events
18
29
 
19
30
  def init_user(data, _)
20
31
  user_id = data['user']['id'].to_i
21
- @user = @server.members.find { |u| u.id == user_id }
32
+ @user = @server.member(user_id)
22
33
  end
23
34
 
24
35
  def init_roles(data, _)
@@ -32,10 +43,10 @@ module Discordrb::Events
32
43
  end
33
44
 
34
45
  # Generic event handler for member events
35
- class GuildMemberEventHandler < EventHandler
46
+ class ServerMemberEventHandler < EventHandler
36
47
  def matches?(event)
37
48
  # Check for the proper event type
38
- return false unless event.is_a? GuildMemberEvent
49
+ return false unless event.is_a? ServerMemberEvent
39
50
 
40
51
  [
41
52
  matches_all(@attributes[:username], event.user.name) do |a, e|
@@ -51,27 +62,27 @@ module Discordrb::Events
51
62
 
52
63
  # Member joins
53
64
  # @see Discordrb::EventContainer#member_join
54
- class GuildMemberAddEvent < GuildMemberEvent; end
65
+ class ServerMemberAddEvent < ServerMemberEvent; end
55
66
 
56
- # Event handler for {GuildMemberAddEvent}
57
- class GuildMemberAddEventHandler < GuildMemberEventHandler; end
67
+ # Event handler for {ServerMemberAddEvent}
68
+ class ServerMemberAddEventHandler < ServerMemberEventHandler; end
58
69
 
59
- # Member is updated (e.g. name changed)
70
+ # Member is updated (roles added or deleted)
60
71
  # @see Discordrb::EventContainer#member_update
61
- class GuildMemberUpdateEvent < GuildMemberEvent; end
72
+ class ServerMemberUpdateEvent < ServerMemberEvent; end
62
73
 
63
- # Event handler for {GuildMemberUpdateEvent}
64
- class GuildMemberUpdateEventHandler < GuildMemberEventHandler; end
74
+ # Event handler for {ServerMemberUpdateEvent}
75
+ class ServerMemberUpdateEventHandler < ServerMemberEventHandler; end
65
76
 
66
77
  # Member leaves
67
78
  # @see Discordrb::EventContainer#member_leave
68
- class GuildMemberDeleteEvent < GuildMemberEvent
79
+ class ServerMemberDeleteEvent < ServerMemberEvent
69
80
  # Overide init_user to account for the deleted user on the server
70
81
  def init_user(data, bot)
71
82
  @user = Discordrb::User.new(data['user'], bot)
72
83
  end
73
84
  end
74
85
 
75
- # Event handler for {GuildMemberDeleteEvent}
76
- class GuildMemberDeleteEventHandler < GuildMemberEventHandler; end
86
+ # Event handler for {ServerMemberDeleteEvent}
87
+ class ServerMemberDeleteEventHandler < ServerMemberEventHandler; end
77
88
  end
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
 
3
5
  module Discordrb::Events
4
6
  # Event raised when a text message is sent to a channel
5
7
  class MessageEvent < Event
6
- attr_reader :message, :saved_message
8
+ # @return [Message] the message which triggered this event.
9
+ attr_reader :message
10
+
11
+ # @return [String] the message that has been saved by calls to {#<<} and will be sent to Discord upon completion.
12
+ attr_reader :saved_message
7
13
 
8
14
  # @!attribute [r] author
9
15
  # @return [User] who sent this message.
@@ -40,7 +46,13 @@ module Discordrb::Events
40
46
 
41
47
  # @return [true, false] whether or not this message was sent by the bot itself
42
48
  def from_bot?
43
- @message.user.id == @bot.bot_user.id
49
+ @message.user.id == @bot.profile.id
50
+ end
51
+
52
+ # Utility method to get the voice bot for the current server
53
+ # @return [VoiceBot, nil] the voice bot connected to this message's server, or nil if there is none connected
54
+ def voice
55
+ @bot.voice(@message.channel.server.id)
44
56
  end
45
57
 
46
58
  # Adds a string to be sent after the event has finished execution. Avoids problems with rate limiting because only
@@ -102,16 +114,17 @@ module Discordrb::Events
102
114
  elsif a.is_a? Fixnum
103
115
  a == e.id
104
116
  elsif a == :bot
105
- e.bot?
117
+ e.current_bot?
106
118
  else
107
119
  a == e
108
120
  end
109
121
  end,
110
- matches_all(@attributes[:with_text] || @attributes[:content], event.content) do |a, e|
122
+ matches_all(@attributes[:with_text] || @attributes[:content] || @attributes[:exact_text], event.content) do |a, e|
111
123
  if a.is_a? String
112
124
  e == a
113
125
  elsif a.is_a? Regexp
114
- a.match(e) ? (e == (a.match(e)[0])) : false
126
+ match = a.match(e)
127
+ match ? (e == match[0]) : false
115
128
  end
116
129
  end,
117
130
  matches_all(@attributes[:after], event.timestamp) { |a, e| a > e },
@@ -180,10 +193,10 @@ module Discordrb::Events
180
193
 
181
194
  # Raised when a message is edited
182
195
  # @see Discordrb::EventContainer#message_edit
183
- class MessageEditEvent < MessageIDEvent; end
196
+ class MessageEditEvent < MessageEvent; end
184
197
 
185
198
  # Event handler for {MessageEditEvent}
186
- class MessageEditEventHandler < MessageIDEventHandler; end
199
+ class MessageEditEventHandler < MessageEventHandler; end
187
200
 
188
201
  # Raised when a message is deleted
189
202
  # @see Discordrb::EventContainer#message_delete
@@ -1,10 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'discordrb/events/generic'
2
4
  require 'discordrb/data'
3
5
 
4
6
  module Discordrb::Events
5
7
  # Event raised when a user's presence state updates (idle or online)
6
8
  class PresenceEvent < Event
7
- attr_reader :server, :user, :status
9
+ # @return [Server] the server on which the presence update happened.
10
+ attr_reader :server
11
+
12
+ # @return [User] the user whose status got updated.
13
+ attr_reader :user
14
+
15
+ # @return [String] the new status.
16
+ attr_reader :status
8
17
 
9
18
  def initialize(data, bot)
10
19
  @user = bot.user(data['user']['id'].to_i)
@@ -42,7 +51,14 @@ module Discordrb::Events
42
51
 
43
52
  # Event raised when a user starts or stops playing a game
44
53
  class PlayingEvent < Event
45
- attr_reader :server, :user, :game
54
+ # @return [Server] the server on which the presence update happened.
55
+ attr_reader :server
56
+
57
+ # @return [User] the user whose status got updated.
58
+ attr_reader :user
59
+
60
+ # @return [String] the new game the user is playing.
61
+ attr_reader :game
46
62
 
47
63
  def initialize(data, bot)
48
64
  @user = bot.user(data['user']['id'].to_i)