discordrb 3.1.1 → 3.2.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.

@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/module'
4
-
5
3
  # Events used by discordrb
6
4
  module Discordrb::Events
7
5
  # A negated object, used to not match something in event parameters.
@@ -55,6 +53,24 @@ module Discordrb::Events
55
53
  class Event
56
54
  # @return [Bot] the bot used to initialize this event.
57
55
  attr_reader :bot
56
+
57
+ class << self
58
+ protected
59
+
60
+ # Delegates a list of methods to a particular object. This is essentially a reimplementation of ActiveSupport's
61
+ # `#delegate`, but without the overhead provided by the rest. Used in subclasses of `Event` to delegate properties
62
+ # on events to properties on data objects.
63
+ # @param methods [Array<Symbol>] The methods to delegate.
64
+ # @param hash [Hash<Symbol => Symbol>] A hash with one `:to` key and the value the method to be delegated to.
65
+ def delegate(*methods, hash)
66
+ methods.each do |e|
67
+ define_method(e) do
68
+ object = __send__(hash[:to])
69
+ object.__send__(e)
70
+ end
71
+ end
72
+ end
73
+ end
58
74
  end
59
75
 
60
76
  # Generic event handler that can be extended
@@ -32,7 +32,7 @@ module Discordrb::Events
32
32
  matches_all(@attributes[:server], event.server) do |a, e|
33
33
  a == if a.is_a? String
34
34
  e.name
35
- elsif a.is_a? Fixnum
35
+ elsif a.is_a? Integer
36
36
  e.id
37
37
  else
38
38
  e
@@ -59,7 +59,7 @@ module Discordrb::Events
59
59
  # Server is deleted
60
60
  # @see Discordrb::EventContainer#server_delete
61
61
  class ServerDeleteEvent < ServerEvent
62
- # Overide init_server to account for the deleted server
62
+ # Override init_server to account for the deleted server
63
63
  def init_server(data, bot)
64
64
  @server = Discordrb::Server.new(data, bot, false)
65
65
  end
@@ -67,4 +67,119 @@ module Discordrb::Events
67
67
 
68
68
  # Event handler for {ServerDeleteEvent}
69
69
  class ServerDeleteEventHandler < ServerEventHandler; end
70
+
71
+ # Emoji is created/deleted/updated
72
+ class ServerEmojiChangeEvent < ServerEvent
73
+ # @return [Server] the server in question.
74
+ attr_reader :server
75
+
76
+ # @return [Array<Emoji>] array of emojis.
77
+ attr_reader :emoji
78
+
79
+ def initialize(server, data, bot)
80
+ @bot = bot
81
+ @server = server
82
+ process_emoji(data)
83
+ end
84
+
85
+ def process_emoji(data)
86
+ @emoji = data['emojis'].map do |e|
87
+ @server.emoji[e['id']]
88
+ end
89
+ end
90
+ end
91
+
92
+ # Generic event helper for when an emoji is either created or deleted
93
+ class ServerEmojiCDEvent < ServerEvent
94
+ # @return [Server] the server in question.
95
+ attr_reader :server
96
+
97
+ # @return [Emoji] the emoji data.
98
+ attr_reader :emoji
99
+
100
+ def initialize(server, emoji, bot)
101
+ @bot = bot
102
+ @emoji = emoji
103
+ @server = server
104
+ end
105
+ end
106
+
107
+ # Emoji is created
108
+ class ServerEmojiCreateEvent < ServerEmojiCDEvent; end
109
+
110
+ # Emoji is deleted
111
+ class ServerEmojiDeleteEvent < ServerEmojiCDEvent; end
112
+
113
+ # Emoji is updated
114
+ class ServerEmojiUpdateEvent < ServerEvent
115
+ # @return [Server] the server in question.
116
+ attr_reader :server
117
+
118
+ # @return [Emoji, nil] the emoji data before the event.
119
+ attr_reader :old_emoji
120
+
121
+ # @return [Emoji, nil] the updated emoji data.
122
+ attr_reader :emoji
123
+
124
+ def initialize(server, old_emoji, emoji, bot)
125
+ @bot = bot
126
+ @old_emoji = old_emoji
127
+ @emoji = emoji
128
+ @server = server
129
+ end
130
+ end
131
+
132
+ # Event handler for {ServerEmojiChangeEvent}
133
+ class ServerEmojiChangeEventHandler < ServerEventHandler; end
134
+
135
+ # Generic handler for emoji create and delete
136
+ class ServerEmojiCDEventHandler < ServerEventHandler
137
+ def matches?(event)
138
+ # Check for the proper event type
139
+ return false unless event.is_a? ServerEmojiCDEvent
140
+
141
+ [
142
+ matches_all(@attributes[:server], event.server) do |a, e|
143
+ a == if a.is_a? String
144
+ e.name
145
+ elsif a.is_a? Integer
146
+ e.id
147
+ else
148
+ e
149
+ end
150
+ end,
151
+ matches_all(@attributes[:id], event.emoji.id) { |a, e| a.resolve_id == e.resolve_id },
152
+ matches_all(@attributes[:name], event.emoji.name) { |a, e| a == e }
153
+ ].reduce(true, &:&)
154
+ end
155
+ end
156
+
157
+ # Event handler for {ServerEmojiCreateEvent}
158
+ class ServerEmojiCreateEventHandler < ServerEmojiCDEventHandler; end
159
+
160
+ # Event handler for {ServerEmojiDeleteEvent}
161
+ class ServerEmojiDeleteEventHandler < ServerEmojiCDEventHandler; end
162
+
163
+ # Event handler for {ServerEmojiUpdateEvent}
164
+ class ServerEmojiUpdateEventHandler < EventHandler
165
+ def matches?(event)
166
+ # Check for the proper event type
167
+ return false unless event.is_a? ServerEmojiUpdateEvent
168
+
169
+ [
170
+ matches_all(@attributes[:server], event.server) do |a, e|
171
+ a == if a.is_a? String
172
+ e.name
173
+ elsif a.is_a? Integer
174
+ e.id
175
+ else
176
+ e
177
+ end
178
+ end,
179
+ matches_all(@attributes[:id], event.old_emoji.id) { |a, e| a.resolve_id == e.resolve_id },
180
+ matches_all(@attributes[:old_name], event.old_emoji.name) { |a, e| a == e },
181
+ matches_all(@attributes[:name], event.emoji.name) { |a, e| a == e }
182
+ ].reduce(true, &:&)
183
+ end
184
+ end
70
185
  end
@@ -14,14 +14,14 @@ module Discordrb::Events
14
14
  # @param content [String] The message to send to the channel
15
15
  # @return [Discordrb::Message] the message that was sent
16
16
  def send_message(content)
17
- @channel.send_message(content)
17
+ channel.send_message(content)
18
18
  end
19
19
 
20
20
  # Sends a temporary message to the channel this message was sent in, right now.
21
21
  # @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
22
22
  # @param timeout [Float] The amount of time in seconds after which the message sent will be deleted.
23
23
  def send_temporary_message(content, timeout)
24
- @channel.send_temporary_message(content, timeout)
24
+ channel.send_temporary_message(content, timeout)
25
25
  end
26
26
 
27
27
  # Adds a string to be sent after the event has finished execution. Avoids problems with rate limiting because only
@@ -62,6 +62,7 @@ module Discordrb::Events
62
62
  # Event raised when a text message is sent to a channel
63
63
  class MessageEvent < Event
64
64
  include Respondable
65
+
65
66
  # @return [Message] the message which triggered this event.
66
67
  attr_reader :message
67
68
 
@@ -72,7 +73,7 @@ module Discordrb::Events
72
73
  attr_reader :file
73
74
 
74
75
  # @!attribute [r] author
75
- # @return [Member] who sent this message.
76
+ # @return [Member, User] who sent this message.
76
77
  # @see Message#author
77
78
  # @!attribute [r] channel
78
79
  # @return [Channel] the channel in which this message was sent.
@@ -178,7 +179,7 @@ module Discordrb::Events
178
179
  if a.is_a? String
179
180
  # Make sure to remove the "#" from channel names in case it was specified
180
181
  a.delete('#') == e.name
181
- elsif a.is_a? Fixnum
182
+ elsif a.is_a? Integer
182
183
  a == e.id
183
184
  else
184
185
  a == e
@@ -187,7 +188,7 @@ module Discordrb::Events
187
188
  matches_all(@attributes[:from], event.author) do |a, e|
188
189
  if a.is_a? String
189
190
  a == e.name
190
- elsif a.is_a? Fixnum
191
+ elsif a.is_a? Integer
191
192
  a == e.id
192
193
  elsif a == :bot
193
194
  e.current_bot?
@@ -234,6 +235,7 @@ module Discordrb::Events
234
235
  # A subset of MessageEvent that only contains a message ID and a channel
235
236
  class MessageIDEvent < Event
236
237
  include Respondable
238
+
237
239
  # @return [Integer] the ID associated with this event
238
240
  attr_reader :id
239
241
 
@@ -34,7 +34,7 @@ module Discordrb::Events
34
34
  matches_all(@attributes[:from], event.user) do |a, e|
35
35
  a == if a.is_a? String
36
36
  e.name
37
- elsif a.is_a? Fixnum
37
+ elsif a.is_a? Integer
38
38
  e.id
39
39
  else
40
40
  e
@@ -89,25 +89,17 @@ module Discordrb::Events
89
89
  matches_all(@attributes[:from], event.user) do |a, e|
90
90
  a == if a.is_a? String
91
91
  e.name
92
- elsif a.is_a? Fixnum
92
+ elsif a.is_a? Integer
93
93
  e.id
94
94
  else
95
95
  e
96
96
  end
97
97
  end,
98
98
  matches_all(@attributes[:game], event.game) do |a, e|
99
- a == if a.is_a? String
100
- e.name
101
- else
102
- e
103
- end
99
+ a == e
104
100
  end,
105
101
  matches_all(@attributes[:type], event.type) do |a, e|
106
- a == if a.is_a? Integer
107
- e.type
108
- else
109
- e
110
- end
102
+ a == e
111
103
  end
112
104
  ].reduce(true, &:&)
113
105
  end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'discordrb/events/generic'
4
+
5
+ # Event classes and handlers
6
+ module Discordrb::Events
7
+ # Event raised when any dispatch is received
8
+ class RawEvent < Event
9
+ # @return [Symbol] the type of this dispatch.
10
+ attr_reader :type
11
+ alias_method :t, :type
12
+
13
+ # @return [Hash] the data of this dispatch.
14
+ attr_reader :data
15
+ alias_method :d, :data
16
+
17
+ def initialize(type, data, bot)
18
+ @type = type
19
+ @data = data
20
+ @bot = bot
21
+ end
22
+ end
23
+
24
+ # Event handler for {RawEvent}
25
+ class RawEventHandler < EventHandler
26
+ def matches?(event)
27
+ # Check for the proper event type
28
+ return false unless event.is_a? RawEvent
29
+
30
+ [
31
+ matches_all(@attributes[:type] || @attributes[:t], event.type) do |a, e|
32
+ if a.is_a? Regexp
33
+ # 24: update to matches?
34
+ match = a.match(e)
35
+ match ? (e == match[0]) : false
36
+ else
37
+ e.to_s.casecmp(a.to_s).zero?
38
+ end
39
+ end
40
+ ].reduce(true, &:&)
41
+ end
42
+ end
43
+
44
+ # Event raised when an unknown dispatch is received
45
+ class UnknownEvent < RawEvent; end
46
+
47
+ # Event handler for {UnknownEvent}
48
+ class UnknownEventHandler < RawEventHandler; end
49
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'discordrb/events/generic'
4
+ require 'discordrb/data'
5
+
6
+ module Discordrb::Events
7
+ # Generic superclass for events about adding and removing reactions
8
+ class ReactionEvent
9
+ include Respondable
10
+
11
+ # @return [Emoji] the emoji that was reacted with.
12
+ attr_reader :emoji
13
+
14
+ def initialize(data, bot)
15
+ @bot = bot
16
+
17
+ @emoji = Discordrb::Emoji.new(data['emoji'], bot, nil)
18
+ @user_id = data['user_id'].to_i
19
+ @message_id = data['message_id'].to_i
20
+ @channel_id = data['channel_id'].to_i
21
+ end
22
+
23
+ # @return [User] the user that reacted to this message.
24
+ def user
25
+ # Cache the user so we don't do requests all the time
26
+ @user ||= @bot.user(@user_id)
27
+ end
28
+
29
+ # @return [Message] the message that was reacted to.
30
+ def message
31
+ @message ||= channel.load_message(@message_id)
32
+ end
33
+
34
+ # @return [Channel] the channel that was reacted in.
35
+ def channel
36
+ @channel ||= @bot.channel(@channel_id)
37
+ end
38
+ end
39
+
40
+ # Generic superclass for event handlers pertaining to adding and removing reactions
41
+ class ReactionEventHandler < EventHandler
42
+ def matches?(event)
43
+ # Check for the proper event type
44
+ return false unless event.is_a? ReactionEvent
45
+
46
+ [
47
+ matches_all(@attributes[:emoji], event.emoji) do |a, e|
48
+ if a.is_a? Integer
49
+ e.id == a
50
+ elsif a.is_a? String
51
+ e.name == a || e.name == a.delete(':') || e.id == a.resolve_id
52
+ else
53
+ e == a
54
+ end
55
+ end
56
+ ].reduce(true, &:&)
57
+ end
58
+ end
59
+
60
+ # Event raised when somebody reacts to a message
61
+ class ReactionAddEvent < ReactionEvent; end
62
+
63
+ # Event handler for {ReactionAddEvent}
64
+ class ReactionAddEventHandler < ReactionEventHandler; end
65
+
66
+ # Event raised when somebody removes a reaction to a message
67
+ class ReactionRemoveEvent < ReactionEvent; end
68
+
69
+ # Event handler for {ReactionRemoveEvent}
70
+ class ReactionRemoveEventHandler < ReactionEventHandler; end
71
+
72
+ # Event raised when somebody removes all reactions from a message
73
+ class ReactionRemoveAllEvent
74
+ include Respondable
75
+
76
+ def initialize(data, bot)
77
+ @bot = bot
78
+
79
+ @message_id = data['message_id'].to_i
80
+ @channel_id = data['channel_id'].to_i
81
+ end
82
+
83
+ # @return [Channel] the channel where the removal occurred.
84
+ def channel
85
+ @channel ||= @bot.channel(@channel_id)
86
+ end
87
+
88
+ # @return [Message] the message all reactions were removed from.
89
+ def message
90
+ @message ||= channel.load_message(@message_id)
91
+ end
92
+ end
93
+
94
+ # Event handler for {ReactionRemoveAllEvent}
95
+ class ReactionRemoveAllEventHandler < EventHandler
96
+ def matches?(event)
97
+ # Check for the proper event type
98
+ return false unless event.is_a? ReactionRemoveAllEvent
99
+
100
+ # No attributes yet as there is no property available on the event that doesn't involve doing a resolution request
101
+ [].reduce(true, &:&)
102
+ end
103
+ end
104
+ end
@@ -5,6 +5,8 @@ require 'discordrb/events/generic'
5
5
  module Discordrb::Events
6
6
  # Event raised when a user starts typing
7
7
  class TypingEvent < Event
8
+ include Respondable
9
+
8
10
  # @return [Channel] the channel on which a user started typing.
9
11
  attr_reader :channel
10
12
 
@@ -45,7 +47,7 @@ module Discordrb::Events
45
47
  matches_all(@attributes[:in], event.channel) do |a, e|
46
48
  if a.is_a? String
47
49
  a.delete('#') == e.name
48
- elsif a.is_a? Fixnum
50
+ elsif a.is_a? Integer
49
51
  a == e.id
50
52
  else
51
53
  a == e
@@ -54,7 +56,7 @@ module Discordrb::Events
54
56
  matches_all(@attributes[:from], event.user) do |a, e|
55
57
  a == if a.is_a? String
56
58
  e.name
57
- elsif a.is_a? Fixnum
59
+ elsif a.is_a? Integer
58
60
  e.id
59
61
  else
60
62
  e
@@ -8,7 +8,10 @@ module Discordrb::Events
8
8
  class VoiceStateUpdateEvent < Event
9
9
  attr_reader :user, :token, :suppress, :session_id, :self_mute, :self_deaf, :mute, :deaf, :server, :channel
10
10
 
11
- def initialize(data, bot)
11
+ # @return [Channel, nil] the old channel this user was on, or nil if the user is newly joining voice.
12
+ attr_reader :old_channel
13
+
14
+ def initialize(data, old_channel_id, bot)
12
15
  @bot = bot
13
16
 
14
17
  @token = data['token']
@@ -22,6 +25,7 @@ module Discordrb::Events
22
25
  return unless @server
23
26
 
24
27
  @channel = bot.channel(data['channel_id'].to_i) if data['channel_id']
28
+ @old_channel = bot.channel(old_channel_id) if old_channel_id
25
29
  @user = bot.user(data['user_id'].to_i)
26
30
  end
27
31
  end
@@ -71,9 +75,20 @@ module Discordrb::Events
71
75
  end
72
76
  end,
73
77
  matches_all(@attributes[:channel], event.channel) do |a, e|
78
+ next unless e # Don't bother if the channel is nil
79
+ a == if a.is_a? String
80
+ e.name
81
+ elsif a.is_a? Integer
82
+ e.id
83
+ else
84
+ e
85
+ end
86
+ end,
87
+ matches_all(@attributes[:old_channel], event.old_channel) do |a, e|
88
+ next unless e # Don't bother if the channel is nil
74
89
  a == if a.is_a? String
75
90
  e.name
76
- elsif a.is_a? Fixnum
91
+ elsif a.is_a? Integer
77
92
  e.id
78
93
  else
79
94
  e