discordrb 1.5.4 → 1.6.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 +4 -4
- data/.rubocop.yml +11 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +27 -0
- data/README.md +4 -0
- data/discordrb.gemspec +2 -0
- data/lib/discordrb.rb +17 -0
- data/lib/discordrb/api.rb +57 -31
- data/lib/discordrb/await.rb +2 -1
- data/lib/discordrb/bot.rb +125 -49
- data/lib/discordrb/commands/command_bot.rb +7 -2
- data/lib/discordrb/commands/parser.rb +2 -0
- data/lib/discordrb/data.rb +471 -112
- data/lib/discordrb/events/bans.rb +54 -0
- data/lib/discordrb/events/channel_create.rb +10 -10
- data/lib/discordrb/events/channel_delete.rb +10 -10
- data/lib/discordrb/events/channel_update.rb +10 -10
- data/lib/discordrb/events/guild_role_create.rb +5 -5
- data/lib/discordrb/events/guild_role_delete.rb +5 -5
- data/lib/discordrb/events/guild_role_update.rb +5 -5
- data/lib/discordrb/events/guilds.rb +7 -8
- data/lib/discordrb/events/members.rb +5 -5
- data/lib/discordrb/events/message.rb +48 -0
- data/lib/discordrb/events/presence.rb +25 -29
- data/lib/discordrb/events/typing.rb +7 -7
- data/lib/discordrb/events/voice_state_update.rb +34 -34
- data/lib/discordrb/permissions.rb +1 -1
- data/lib/discordrb/token_cache.rb +2 -3
- data/lib/discordrb/version.rb +2 -1
- data/lib/discordrb/voice/encoder.rb +32 -2
- data/lib/discordrb/voice/network.rb +87 -11
- data/lib/discordrb/voice/voice_bot.rb +77 -20
- metadata +33 -3
@@ -82,7 +82,13 @@ module Discordrb::Commands
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def command(name, attributes = {}, &block)
|
85
|
-
|
85
|
+
if name.is_a? Array
|
86
|
+
new_command = Command.new(name[0], attributes, &block)
|
87
|
+
name.each { |n| @commands[n] = new_command }
|
88
|
+
new_command
|
89
|
+
else
|
90
|
+
@commands[name] = Command.new(name, attributes, &block)
|
91
|
+
end
|
86
92
|
end
|
87
93
|
|
88
94
|
def execute_command(name, event, arguments, chained = false)
|
@@ -98,7 +104,6 @@ module Discordrb::Commands
|
|
98
104
|
result.to_s
|
99
105
|
else
|
100
106
|
event.respond "You don't have permission to execute command `#{name}`!"
|
101
|
-
return
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
data/lib/discordrb/data.rb
CHANGED
@@ -11,15 +11,48 @@ require 'base64'
|
|
11
11
|
module Discordrb
|
12
12
|
# Compares two objects based on IDs - either the objects' IDs are equal, or one object is equal to the other's ID.
|
13
13
|
def self.id_compare(one_id, other)
|
14
|
-
other.respond_to?(:
|
14
|
+
other.respond_to?(:resolve_id) ? (one_id.resolve_id == other.resolve_id) : (one_id == other)
|
15
15
|
end
|
16
16
|
|
17
17
|
# User on Discord, including internal data like discriminators
|
18
18
|
class User
|
19
|
-
|
20
|
-
|
19
|
+
# @return [String] this user's username
|
20
|
+
attr_reader :username
|
21
|
+
|
22
|
+
# @return [Integer] this user's ID which uniquely identifies them across Discord.
|
23
|
+
attr_reader :id
|
24
|
+
|
25
|
+
# @return [String] this user's discriminator which is used internally to identify users with identical usernames.
|
26
|
+
attr_reader :discriminator
|
27
|
+
|
28
|
+
# @return [String] the ID of this user's current avatar, can be used to generate an avatar URL.
|
29
|
+
# @see #avatar_url
|
30
|
+
attr_reader :avatar_id
|
31
|
+
|
32
|
+
# @return [Channel, nil] the voice channel this user is on currently.
|
33
|
+
attr_reader :voice_channel
|
34
|
+
|
35
|
+
# @return [Hash<Integer => Array<Role>>] the roles this user has, grouped by server ID.
|
36
|
+
attr_reader :roles
|
37
|
+
|
38
|
+
# @!attribute [r] status
|
39
|
+
# @return [Symbol] the current online status of the user (`:online`, `:offline` or `:idle`)
|
40
|
+
attr_accessor :status
|
41
|
+
|
42
|
+
# @!attribute [r] game
|
43
|
+
# @return [String, nil] the game the user is currently playing, or `nil` if none is being played.
|
44
|
+
attr_accessor :game
|
45
|
+
|
46
|
+
# @!attribute [r] self_mute
|
47
|
+
# @return [true, false] whether or not the user is currently muted by the bot.
|
48
|
+
attr_accessor :self_mute
|
49
|
+
|
50
|
+
# @todo Fix these (server_mute and _deaf should be server specific, not sure about self_deaf or what it does anyway)
|
51
|
+
# @!visibility private
|
52
|
+
attr_accessor :server_mute, :server_deaf, :self_deaf
|
21
53
|
|
22
54
|
alias_method :name, :username
|
55
|
+
alias_method :resolve_id, :id
|
23
56
|
|
24
57
|
def initialize(data, bot)
|
25
58
|
@bot = bot
|
@@ -27,7 +60,7 @@ module Discordrb
|
|
27
60
|
@username = data['username']
|
28
61
|
@id = data['id'].to_i
|
29
62
|
@discriminator = data['discriminator']
|
30
|
-
@
|
63
|
+
@avatar_id = data['avatar']
|
31
64
|
@roles = {}
|
32
65
|
|
33
66
|
@status = :offline
|
@@ -38,12 +71,33 @@ module Discordrb
|
|
38
71
|
Discordrb.id_compare(@id, other)
|
39
72
|
end
|
40
73
|
|
74
|
+
# Gets the user's avatar ID.
|
75
|
+
# @deprecated Use {#avatar_id} instead.
|
76
|
+
def avatar
|
77
|
+
LOGGER.debug('Warning: Deprecated reader User.avatar was used! Use User.avatar_id (or User.avatar_url if you just want the URL) instead.', true)
|
78
|
+
@avatar_id
|
79
|
+
end
|
80
|
+
|
41
81
|
# Utility function to mention users in messages
|
82
|
+
# @return [String] the mention code in the form of <@id>
|
42
83
|
def mention
|
43
84
|
"<@#{@id}>"
|
44
85
|
end
|
45
86
|
|
46
|
-
# Utility function to
|
87
|
+
# Utility function to get a user's avatar URL.
|
88
|
+
# @return [String] the URL to the avatar image.
|
89
|
+
def avatar_url
|
90
|
+
API.avatar_url(@id, @avatar_id)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get a user's PM channel or send them a PM
|
94
|
+
# @overload pm
|
95
|
+
# Creates a private message channel for this user or returns an existing one if it already exists
|
96
|
+
# @return [Channel] the PM channel to this user.
|
97
|
+
# @overload pm(content)
|
98
|
+
# Sends a private to this user.
|
99
|
+
# @param content [String] The content to send.
|
100
|
+
# @return [Message] the message sent to this user.
|
47
101
|
def pm(content = nil)
|
48
102
|
if content
|
49
103
|
# Recursively call pm to get the channel, then send a message to it
|
@@ -55,12 +109,17 @@ module Discordrb
|
|
55
109
|
end
|
56
110
|
end
|
57
111
|
|
58
|
-
#
|
112
|
+
# Changes a user's voice channel.
|
113
|
+
# @note For internal use only
|
114
|
+
# @!visibility private
|
59
115
|
def move(to_channel)
|
60
116
|
return if to_channel && to_channel.type != 'voice'
|
61
117
|
@voice_channel = to_channel
|
62
118
|
end
|
63
119
|
|
120
|
+
# Adds a role to this user on the specified server.
|
121
|
+
# @param server [Server] The server on which to add the role.
|
122
|
+
# @param role [Role] The role to add.
|
64
123
|
def add_role(server, role)
|
65
124
|
user_roles = @roles[server.id] || []
|
66
125
|
user_roles << role
|
@@ -68,6 +127,9 @@ module Discordrb
|
|
68
127
|
API.update_user_roles(@bot.token, server.id, @id, ids)
|
69
128
|
end
|
70
129
|
|
130
|
+
# Removes a role from this user on the specified server.
|
131
|
+
# @param server [Server] The server on which to remove the role.
|
132
|
+
# @param role [Role] The role to remove.
|
71
133
|
def remove_role(server, role)
|
72
134
|
user_roles = @roles[server.id] || []
|
73
135
|
|
@@ -77,39 +139,50 @@ module Discordrb
|
|
77
139
|
API.update_user_roles(@bot.token, server.id, @id, ids)
|
78
140
|
end
|
79
141
|
|
80
|
-
# Set this user's roles
|
142
|
+
# Set this user's roles in the cache
|
143
|
+
# @note For internal use only
|
144
|
+
# @!visibility private
|
81
145
|
def update_roles(server, roles)
|
82
146
|
@roles ||= {}
|
83
147
|
@roles[server.id] = roles
|
84
148
|
end
|
85
149
|
|
86
150
|
# Merge this user's roles with the roles from another instance of this user (from another server)
|
151
|
+
# @note For internal use only
|
152
|
+
# @!visibility private
|
87
153
|
def merge_roles(server, roles)
|
88
|
-
if @roles[server.id]
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
154
|
+
@roles[server.id] = if @roles[server.id]
|
155
|
+
(@roles[server.id] + roles).uniq
|
156
|
+
else
|
157
|
+
roles
|
158
|
+
end
|
93
159
|
end
|
94
160
|
|
95
161
|
# Delete a specific server from the roles (in case a user leaves a server)
|
162
|
+
# @note For internal use only
|
163
|
+
# @!visibility private
|
96
164
|
def delete_roles(server_id)
|
97
165
|
@roles.delete(server_id)
|
98
166
|
end
|
99
167
|
|
100
|
-
# Add an await for a message from this user
|
168
|
+
# Add an await for a message from this user. Specifically, this adds a global await for a MessageEvent with this
|
169
|
+
# user's ID as a :from attribute.
|
170
|
+
# @see Bot#add_await
|
101
171
|
def await(key, attributes = {}, &block)
|
102
172
|
@bot.add_await(key, Discordrb::Events::MessageEvent, { from: @id }.merge(attributes), &block)
|
103
173
|
end
|
104
174
|
|
105
175
|
# Is the user the bot?
|
176
|
+
# @return [true, false] whether this user is the bot
|
106
177
|
def bot?
|
107
178
|
@bot.bot_user.id == @id
|
108
179
|
end
|
109
180
|
|
110
|
-
#
|
111
|
-
# action
|
112
|
-
#
|
181
|
+
# Determines whether this user has a specific permission on a server (and channel).
|
182
|
+
# @param action [Symbol] The permission that should be checked. See also {Permissions::Flags} for a list.
|
183
|
+
# @param server [Server] The server on which the permission should be checked.
|
184
|
+
# @param channel [Channel, nil] If channel overrides should be checked too, this channel specifies where the overrides should be checked.
|
185
|
+
# @return [true, false] whether or not this user has the permission.
|
113
186
|
def permission?(action, server, channel = nil)
|
114
187
|
# For each role, check if
|
115
188
|
# (1) the channel explicitly allows or permits an action for the role and
|
@@ -128,13 +201,11 @@ module Discordrb
|
|
128
201
|
end
|
129
202
|
# If the channel has nothing to say on the matter, we can defer to the role itself
|
130
203
|
end
|
131
|
-
if channel_allow
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
can_act = role.permissions.instance_variable_get("@#{action}") || can_act
|
137
|
-
end
|
204
|
+
can_act = if channel_allow.nil?
|
205
|
+
role.permissions.instance_variable_get("@#{action}") || can_act
|
206
|
+
else
|
207
|
+
channel_allow
|
208
|
+
end
|
138
209
|
can_act
|
139
210
|
end
|
140
211
|
end
|
@@ -147,7 +218,8 @@ module Discordrb
|
|
147
218
|
end
|
148
219
|
end
|
149
220
|
|
150
|
-
#
|
221
|
+
# This class is a special variant of User that represents the bot's user profile (things like email addresses and the avatar).
|
222
|
+
# It can be accessed using {Bot#profile}.
|
151
223
|
class Profile < User
|
152
224
|
def initialize(data, bot, email, password)
|
153
225
|
super(data, bot)
|
@@ -155,22 +227,33 @@ module Discordrb
|
|
155
227
|
@password = password
|
156
228
|
end
|
157
229
|
|
230
|
+
# Whether or not the user is the bot. The Profile can only ever be the bot user, so this always returns true.
|
231
|
+
# @return [true]
|
158
232
|
def bot?
|
159
233
|
true
|
160
234
|
end
|
161
235
|
|
236
|
+
# Sets the bot's username.
|
237
|
+
# @param username [String] The new username.
|
162
238
|
def username=(username)
|
163
239
|
update_server_data(username: username)
|
164
240
|
end
|
165
241
|
|
242
|
+
# Sets the bot's email address. If you use this method, make sure that the login email in the script matches this
|
243
|
+
# one afterwards, so the bot doesn't have any trouble logging in in the future.
|
244
|
+
# @param email [String] The new email address.
|
166
245
|
def email=(email)
|
167
246
|
update_server_data(email: email)
|
168
247
|
end
|
169
248
|
|
249
|
+
# Changes the bot's password. This will invalidate all tokens so you will have to relog the bot.
|
250
|
+
# @param password [String] The new password.
|
170
251
|
def password=(password)
|
171
252
|
update_server_data(new_password: password)
|
172
253
|
end
|
173
254
|
|
255
|
+
# Changes the bot's avatar.
|
256
|
+
# @param avatar [String, File] A JPG file to be used as the avatar, either as a File object or as a base64-encoded String.
|
174
257
|
def avatar=(avatar)
|
175
258
|
if avatar.is_a? File
|
176
259
|
avatar_string = 'data:image/jpg;base64,'
|
@@ -181,11 +264,14 @@ module Discordrb
|
|
181
264
|
end
|
182
265
|
end
|
183
266
|
|
267
|
+
# Updates the cached profile data with the new one.
|
268
|
+
# @note For internal use only.
|
269
|
+
# @!visibility private
|
184
270
|
def update_data(new_data)
|
185
271
|
@email = new_data[:email] || @email
|
186
272
|
@password = new_data[:new_password] || @password
|
187
273
|
@username = new_data[:username] || @username
|
188
|
-
@
|
274
|
+
@avatar_id = new_data[:avatar_id] || @avatar_id
|
189
275
|
end
|
190
276
|
|
191
277
|
private
|
@@ -195,7 +281,7 @@ module Discordrb
|
|
195
281
|
new_data[:email] || @email,
|
196
282
|
@password,
|
197
283
|
new_data[:username] || @username,
|
198
|
-
new_data[:
|
284
|
+
new_data[:avatar_id] || @avatar_id,
|
199
285
|
new_data[:new_password] || nil)
|
200
286
|
update_data(new_data)
|
201
287
|
end
|
@@ -203,21 +289,40 @@ module Discordrb
|
|
203
289
|
|
204
290
|
# A Discord role that contains permissions and applies to certain users
|
205
291
|
class Role
|
206
|
-
|
292
|
+
# @return [Permissions] this role's permissions.
|
293
|
+
attr_reader :permissions
|
294
|
+
|
295
|
+
# @return [String] this role's name ("new role" if it hasn't been changed)
|
296
|
+
attr_reader :name
|
297
|
+
|
298
|
+
# @return [Integer] the ID used to identify this role internally
|
299
|
+
attr_reader :id
|
300
|
+
|
301
|
+
# @return [true, false] whether or not this role should be displayed separately from other users
|
302
|
+
attr_reader :hoist
|
303
|
+
|
304
|
+
# @return [ColourRGB] the role colour
|
305
|
+
attr_reader :colour
|
306
|
+
|
207
307
|
alias_method :color, :colour
|
308
|
+
alias_method :resolve_id, :id
|
208
309
|
|
209
|
-
#
|
310
|
+
# This class is used internally as a wrapper to a Role object that allows easy writing of permission data.
|
210
311
|
class RoleWriter
|
312
|
+
# @!visibility private
|
211
313
|
def initialize(role, token)
|
212
314
|
@role = role
|
213
315
|
@token = token
|
214
316
|
end
|
215
317
|
|
318
|
+
# Write the specified permission data to the role, without updating the permission cache
|
319
|
+
# @param bits [Integer] The packed permissions to write.
|
216
320
|
def write(bits)
|
217
321
|
@role.send(:packed=, bits, false)
|
218
322
|
end
|
219
323
|
end
|
220
324
|
|
325
|
+
# @!visibility private
|
221
326
|
def initialize(data, bot, server = nil)
|
222
327
|
@bot = bot
|
223
328
|
@server = server
|
@@ -233,6 +338,9 @@ module Discordrb
|
|
233
338
|
Discordrb.id_compare(@id, other)
|
234
339
|
end
|
235
340
|
|
341
|
+
# Updates the data cache from another Role object
|
342
|
+
# @note For internal use only
|
343
|
+
# @!visibility private
|
236
344
|
def update_from(other)
|
237
345
|
@permissions = other.permissions
|
238
346
|
@name = other.name
|
@@ -240,6 +348,9 @@ module Discordrb
|
|
240
348
|
@colour = other.colour
|
241
349
|
end
|
242
350
|
|
351
|
+
# Updates the data cache from a hash containing data
|
352
|
+
# @note For internal use only
|
353
|
+
# @!visibility private
|
243
354
|
def update_data(new_data)
|
244
355
|
@name = new_data[:name] || new_data['name'] || @name
|
245
356
|
@hoist = new_data['hoist'] unless new_data['hoist'].nil?
|
@@ -247,25 +358,35 @@ module Discordrb
|
|
247
358
|
@colour = new_data[:colour] || (new_data['color'] ? ColourRGB.new(new_data['color']) : @colour)
|
248
359
|
end
|
249
360
|
|
361
|
+
# Sets the role name to something new
|
362
|
+
# @param name [String] The name that should be set
|
250
363
|
def name=(name)
|
251
364
|
update_role_data(name: name)
|
252
365
|
end
|
253
366
|
|
367
|
+
# Changes whether or not this role is displayed at the top of the user list
|
368
|
+
# @param hoist [true, false] The value it should be changed to
|
254
369
|
def hoist=(hoist)
|
255
370
|
update_role_data(hoist: hoist)
|
256
371
|
end
|
257
372
|
|
373
|
+
# Sets the role colour to something new
|
374
|
+
# @param colour [ColourRGB] The new colour
|
258
375
|
def colour=(colour)
|
259
376
|
update_role_data(colour: colour)
|
260
377
|
end
|
261
378
|
|
262
379
|
alias_method :color=, :colour=
|
263
380
|
|
381
|
+
# Changes the internal packed permissions
|
382
|
+
# @note For internal use only
|
383
|
+
# @!visibility private
|
264
384
|
def packed=(packed, update_perms = true)
|
265
385
|
update_role_data(permissions: packed)
|
266
386
|
@permissions.bits = packed if update_perms
|
267
387
|
end
|
268
388
|
|
389
|
+
# Delets this role. This cannot be undone without recreating the role!
|
269
390
|
def delete
|
270
391
|
API.delete_role(@bot.token, @server.id, @id)
|
271
392
|
@server.delete_role(@id)
|
@@ -277,7 +398,7 @@ module Discordrb
|
|
277
398
|
API.update_role(@bot.token, @server.id, @id,
|
278
399
|
new_data[:name] || @name,
|
279
400
|
(new_data[:colour] || @colour).combined,
|
280
|
-
|
401
|
+
new_data[:hoist].nil? ? false : !@hoist.nil?,
|
281
402
|
new_data[:permissions] || @permissions.bits)
|
282
403
|
update_data(new_data)
|
283
404
|
end
|
@@ -285,7 +406,30 @@ module Discordrb
|
|
285
406
|
|
286
407
|
# A Discord invite to a channel
|
287
408
|
class Invite
|
288
|
-
|
409
|
+
# @return [Channel] the channel this invite references.
|
410
|
+
attr_reader :channel
|
411
|
+
|
412
|
+
# @return [Server] the server this invite references.
|
413
|
+
attr_reader :server
|
414
|
+
|
415
|
+
# @return [Integer] the amount of uses left on this invite.
|
416
|
+
attr_reader :uses
|
417
|
+
|
418
|
+
# @return [User, nil] the user that made this invite. May also be nil if the user can't be determined.
|
419
|
+
attr_reader :inviter
|
420
|
+
|
421
|
+
# @return [true, false] whether or not this invite is temporary.
|
422
|
+
attr_reader :temporary
|
423
|
+
|
424
|
+
# @return [true, false] whether this invite is still valid.
|
425
|
+
attr_reader :revoked
|
426
|
+
|
427
|
+
# @return [true, false] whether this invite is in xkcd format (i. e. "Human readable" in the invite settings)
|
428
|
+
attr_reader :xkcd
|
429
|
+
|
430
|
+
# @return [String] this invite's code
|
431
|
+
attr_reader :code
|
432
|
+
|
289
433
|
alias_method :max_uses, :uses
|
290
434
|
alias_method :user, :inviter
|
291
435
|
|
@@ -293,14 +437,14 @@ module Discordrb
|
|
293
437
|
alias_method :revoked?, :revoked
|
294
438
|
alias_method :xkcd?, :xkcd
|
295
439
|
|
296
|
-
|
297
|
-
|
440
|
+
# @!visibility private
|
298
441
|
def initialize(data, bot)
|
299
442
|
@bot = bot
|
300
443
|
|
301
444
|
@channel = Channel.new(data['channel'], bot)
|
445
|
+
@server = Server.new(data['guild'], bot)
|
302
446
|
@uses = data['uses']
|
303
|
-
@inviter = @bot.user(data['inviter']['id'].to_i) || User.new(data['inviter'], bot)
|
447
|
+
@inviter = data['inviter'] ? (@bot.user(data['inviter']['id'].to_i) || User.new(data['inviter'], bot)) : nil
|
304
448
|
@temporary = data['temporary']
|
305
449
|
@revoked = data['revoked']
|
306
450
|
@xkcd = data['xkcdpass']
|
@@ -308,23 +452,63 @@ module Discordrb
|
|
308
452
|
@code = data['code']
|
309
453
|
end
|
310
454
|
|
455
|
+
# Code based comparison
|
311
456
|
def ==(other)
|
312
457
|
other.respond_to?(:code) ? (@code == other.code) : (@code == other)
|
313
458
|
end
|
314
459
|
|
460
|
+
# Deletes this invite
|
315
461
|
def delete
|
316
462
|
API.delete_invite(@bot.token, @code)
|
317
463
|
end
|
464
|
+
|
465
|
+
alias_method :revoke, :delete
|
318
466
|
end
|
319
467
|
|
320
468
|
# A Discord channel, including data like the topic
|
321
469
|
class Channel
|
322
|
-
|
470
|
+
# @return [String] this channel's name.
|
471
|
+
attr_reader :name
|
472
|
+
|
473
|
+
# @return [Server] the server this channel is on.
|
474
|
+
attr_reader :server
|
475
|
+
|
476
|
+
# @return [String] the type of this channel (currently either 'text' or 'voice')
|
477
|
+
attr_reader :type
|
478
|
+
|
479
|
+
# @note If this channel is a #general channel, its ID will be equal to the server on which it is on.
|
480
|
+
# @return [Integer] the channel's unique ID.
|
481
|
+
attr_reader :id
|
482
|
+
|
483
|
+
# @note This data is sent by Discord and it's possible for this to falsely be true for certain kinds of integration
|
484
|
+
# channels (like Twitch subscriber ones). This appears to be a Discord bug that I can't reproduce myself, due to
|
485
|
+
# not having any integrations in place. If this occurs to you please tell me.
|
486
|
+
# @deprecated Use {#private?} instead, it's guaranteed to be accurate.
|
487
|
+
# @return [true, false] whether or not this channel is a private messaging channel.
|
488
|
+
attr_reader :is_private
|
489
|
+
|
490
|
+
# @return [User, nil] the recipient of the private messages, or nil if this is not a PM channel
|
491
|
+
attr_reader :recipient
|
492
|
+
|
493
|
+
# @return [String] the channel's topic
|
494
|
+
attr_reader :topic
|
495
|
+
|
496
|
+
# @return [Integer] the channel's position on the channel list
|
497
|
+
attr_reader :position
|
498
|
+
|
499
|
+
# This channel's permission overwrites, represented as a hash of role/user ID to an OpenStruct which has the
|
500
|
+
# `allow` and `deny` properties which are {Permissions} objects respectively.
|
501
|
+
# @return [Hash<Integer => OpenStruct>] the channel's permission overwrites
|
502
|
+
attr_reader :permission_overwrites
|
323
503
|
|
504
|
+
alias_method :resolve_id, :id
|
505
|
+
|
506
|
+
# @return [true, false] whether or not this channel is a PM channel, with more accuracy than {#is_private}.
|
324
507
|
def private?
|
325
508
|
@server.nil?
|
326
509
|
end
|
327
510
|
|
511
|
+
# @!visibility private
|
328
512
|
def initialize(data, bot, server = nil)
|
329
513
|
@bot = bot
|
330
514
|
|
@@ -364,33 +548,48 @@ module Discordrb
|
|
364
548
|
Discordrb.id_compare(@id, other)
|
365
549
|
end
|
366
550
|
|
551
|
+
# Sends a message to this channel.
|
552
|
+
# @param content [String] The content to send. Should not be longer than 2000 characters or it will result in an error.
|
553
|
+
# @return [Message] the message that was sent.
|
367
554
|
def send_message(content)
|
368
555
|
@bot.send_message(@id, content)
|
369
556
|
end
|
370
557
|
|
558
|
+
# Sends a file to this channel. If it is an image, it will be embedded.
|
559
|
+
# @param file [File] The file to send. There's no clear size limit for this, you'll have to attempt it for yourself (most non-image files are fine, large images may fail to embed)
|
371
560
|
def send_file(file)
|
372
561
|
@bot.send_file(@id, file)
|
373
562
|
end
|
374
563
|
|
564
|
+
# Permanently deletes this channel
|
375
565
|
def delete
|
376
566
|
API.delete_channel(@bot.token, @id)
|
377
567
|
end
|
378
568
|
|
569
|
+
# Sets this channel's name. The name must be alphanumeric with dashes, unless this is a voice channel (then there are no limitations)
|
570
|
+
# @param name [String] The new name.
|
379
571
|
def name=(name)
|
380
572
|
@name = name
|
381
573
|
update_channel_data
|
382
574
|
end
|
383
575
|
|
576
|
+
# Sets this channel's topic.
|
577
|
+
# @param topic [String] The new topic.
|
384
578
|
def topic=(topic)
|
385
579
|
@topic = topic
|
386
580
|
update_channel_data
|
387
581
|
end
|
388
582
|
|
583
|
+
# Sets this channel's position in the list.
|
584
|
+
# @param position [Integer] The new position.
|
389
585
|
def position=(position)
|
390
586
|
@position = position
|
391
587
|
update_channel_data
|
392
588
|
end
|
393
589
|
|
590
|
+
# Updates the cached data from another channel.
|
591
|
+
# @note For internal use only
|
592
|
+
# @!visibility private
|
394
593
|
def update_from(other)
|
395
594
|
@topic = other.topic
|
396
595
|
@name = other.name
|
@@ -399,7 +598,9 @@ module Discordrb
|
|
399
598
|
@permission_overwrites = other.permission_overwrites
|
400
599
|
end
|
401
600
|
|
402
|
-
#
|
601
|
+
# The list of users currently in this channel. This is mostly useful for a voice channel, for a text channel it will
|
602
|
+
# just return the users on the server that are online.
|
603
|
+
# @return [Array<User>] the users in this channel
|
403
604
|
def users
|
404
605
|
if @type == 'text'
|
405
606
|
@server.members.select { |u| u.status != :offline }
|
@@ -410,16 +611,29 @@ module Discordrb
|
|
410
611
|
end
|
411
612
|
end
|
412
613
|
|
614
|
+
# Retrieves some of this channel's message history.
|
615
|
+
# @param amount [Integer] How many messages to retrieve. This must be less than or equal to 100, if it is higher
|
616
|
+
# than 100 it will be treated as 100 on Discord's side.
|
617
|
+
# @param before_id [Integer] The ID of the most recent message the retrieval should start at, or nil if it should
|
618
|
+
# start at the current message.
|
619
|
+
# @param after_id [Integer] The ID of the oldest message the retrieval should start at, or nil if it should start
|
620
|
+
# as soon as possible with the specified amount.
|
621
|
+
# @return [Array<Message>] the retrieved messages.
|
413
622
|
def history(amount, before_id = nil, after_id = nil)
|
414
623
|
logs = API.channel_log(@bot.token, @id, amount, before_id, after_id)
|
415
624
|
JSON.parse(logs).map { |message| Message.new(message, @bot) }
|
416
625
|
end
|
417
626
|
|
627
|
+
# Updates the cached permission overwrites
|
628
|
+
# @note For internal use only
|
629
|
+
# @!visibility private
|
418
630
|
def update_overwrites(overwrites)
|
419
631
|
@permission_overwrites = overwrites
|
420
632
|
end
|
421
633
|
|
422
|
-
# Add an
|
634
|
+
# Add an {Await} for a message in this channel. This is identical in functionality to adding a
|
635
|
+
# {Discordrb::Events::MessageEvent} await with the `in` attribute as this channel.
|
636
|
+
# @see Bot#add_await
|
423
637
|
def await(key, attributes = {}, &block)
|
424
638
|
@bot.add_await(key, Discordrb::Events::MessageEvent, { in: @id }.merge(attributes), &block)
|
425
639
|
end
|
@@ -449,11 +663,30 @@ module Discordrb
|
|
449
663
|
|
450
664
|
# A message on Discord that was sent to a text channel
|
451
665
|
class Message
|
452
|
-
|
666
|
+
# @return [String] the content of this message.
|
667
|
+
attr_reader :content
|
668
|
+
|
669
|
+
# @return [User] the user that sent this message.
|
670
|
+
attr_reader :author
|
671
|
+
|
672
|
+
# @return [Channel] the channel in which this message was sent.
|
673
|
+
attr_reader :channel
|
674
|
+
|
675
|
+
# @return [Time] the timestamp at which this message was sent.
|
676
|
+
attr_reader :timestamp
|
677
|
+
|
678
|
+
# @return [Integer] the ID used to uniquely identify this message.
|
679
|
+
attr_reader :id
|
680
|
+
|
681
|
+
# @return [Array<User>] the users that were mentioned in this message.
|
682
|
+
attr_reader :mentions
|
683
|
+
|
453
684
|
alias_method :user, :author
|
454
685
|
alias_method :text, :content
|
455
686
|
alias_method :to_s, :content
|
687
|
+
alias_method :resolve_id, :id
|
456
688
|
|
689
|
+
# @!visibility private
|
457
690
|
def initialize(data, bot)
|
458
691
|
@bot = bot
|
459
692
|
@content = data['content']
|
@@ -474,23 +707,30 @@ module Discordrb
|
|
474
707
|
Discordrb.id_compare(@id, other)
|
475
708
|
end
|
476
709
|
|
710
|
+
# Replies to this message with the specified content.
|
711
|
+
# @see Channel#send_message
|
477
712
|
def reply(content)
|
478
713
|
@channel.send_message(content)
|
479
714
|
end
|
480
715
|
|
716
|
+
# Edits this message to have the specified content instead.
|
717
|
+
# @param new_content [String] the new content the message should have.
|
481
718
|
def edit(new_content)
|
482
719
|
API.edit_message(@bot.token, @channel.id, @id, new_content)
|
483
720
|
end
|
484
721
|
|
722
|
+
# Deletes this message.
|
485
723
|
def delete
|
486
724
|
API.delete_message(@bot.token, @channel.id, @id)
|
487
725
|
end
|
488
726
|
|
489
|
-
# Add an
|
727
|
+
# Add an {Await} for a message with the same user and channel.
|
728
|
+
# @see Bot#add_await
|
490
729
|
def await(key, attributes = {}, &block)
|
491
730
|
@bot.add_await(key, Discordrb::Events::MessageEvent, { from: @author.id, in: @channel.id }.merge(attributes), &block)
|
492
731
|
end
|
493
732
|
|
733
|
+
# @return [true, false] whether this message was sent by the current {Bot}.
|
494
734
|
def from_bot?
|
495
735
|
@author.bot?
|
496
736
|
end
|
@@ -498,11 +738,49 @@ module Discordrb
|
|
498
738
|
|
499
739
|
# A server on Discord
|
500
740
|
class Server
|
501
|
-
|
741
|
+
# @return [String] the region the server is on (e. g. `amsterdam`).
|
742
|
+
attr_reader :region
|
743
|
+
|
744
|
+
# @return [String] this server's name.
|
745
|
+
attr_reader :name
|
746
|
+
|
747
|
+
# @deprecated Use #owner instead, then get the resulting {User}'s {User#id}.
|
748
|
+
# @return [Integer] the server owner's user ID.
|
749
|
+
attr_reader :owner_id
|
750
|
+
|
751
|
+
# @return [User] The server owner.
|
752
|
+
attr_reader :owner
|
753
|
+
|
754
|
+
# @return [Integer] the ID used to uniquely identify this server.
|
755
|
+
attr_reader :id
|
756
|
+
|
757
|
+
# @return [Array<User>] an array of all the users on this server.
|
758
|
+
attr_reader :members
|
502
759
|
|
760
|
+
# @return [Array<Channel>] an array of all the channels (text and voice) on this server.
|
761
|
+
attr_reader :channels
|
762
|
+
|
763
|
+
# @return [Array<Role>] an array of all the roles created on this server.
|
764
|
+
attr_reader :roles
|
765
|
+
|
766
|
+
# @todo Make this behave like user.avatar where a URL is available as well.
|
767
|
+
# @return [String] the hexadecimal ID used to identify this server's icon.
|
768
|
+
attr_reader :icon
|
769
|
+
|
770
|
+
# @return [Integer] the amount of time after which a voice user gets moved into the AFK channel, in seconds.
|
771
|
+
attr_reader :afk_timeout
|
772
|
+
|
773
|
+
# @todo Make this a reader that returns a {Channel}
|
774
|
+
# @return [Integer] the channel ID of the AFK channel, or `nil` if none is set.
|
775
|
+
attr_reader :afk_channel_id
|
776
|
+
|
777
|
+
alias_method :resolve_id, :id
|
778
|
+
|
779
|
+
# @!visibility private
|
503
780
|
def initialize(data, bot)
|
504
781
|
@bot = bot
|
505
782
|
@owner_id = data['owner_id'].to_i
|
783
|
+
@owner = bot.user(@owner_id)
|
506
784
|
@id = data['id'].to_i
|
507
785
|
update_data(data)
|
508
786
|
|
@@ -518,85 +796,29 @@ module Discordrb
|
|
518
796
|
Discordrb.id_compare(@id, other)
|
519
797
|
end
|
520
798
|
|
521
|
-
|
522
|
-
|
523
|
-
@
|
524
|
-
@roles_by_id = {}
|
525
|
-
roles.each do |element|
|
526
|
-
role = Role.new(element, @bot, self)
|
527
|
-
@roles << role
|
528
|
-
@roles_by_id[role.id] = role
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
def process_members(members)
|
533
|
-
@members = []
|
534
|
-
@members_by_id = {}
|
535
|
-
|
536
|
-
return unless members
|
537
|
-
members.each do |element|
|
538
|
-
user = User.new(element['user'], @bot)
|
539
|
-
@members << user
|
540
|
-
@members_by_id[user.id] = user
|
541
|
-
user_roles = []
|
542
|
-
element['roles'].each do |e|
|
543
|
-
role_id = e.to_i
|
544
|
-
user_roles << @roles_by_id[role_id]
|
545
|
-
end
|
546
|
-
user.update_roles(self, user_roles)
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
def process_presences(presences)
|
551
|
-
# Update user statuses with presence info
|
552
|
-
return unless presences
|
553
|
-
presences.each do |element|
|
554
|
-
next unless element['user']
|
555
|
-
user_id = element['user']['id'].to_i
|
556
|
-
user = @members_by_id[user_id]
|
557
|
-
if user
|
558
|
-
user.status = element['status'].to_sym
|
559
|
-
user.game = element['game'] ? element['game']['name'] : nil
|
560
|
-
end
|
561
|
-
end
|
562
|
-
end
|
563
|
-
|
564
|
-
def process_channels(channels)
|
565
|
-
@channels = []
|
566
|
-
@channels_by_id = {}
|
567
|
-
|
568
|
-
return unless channels
|
569
|
-
channels.each do |element|
|
570
|
-
channel = Channel.new(element, @bot, self)
|
571
|
-
@channels << channel
|
572
|
-
@channels_by_id[channel.id] = channel
|
573
|
-
end
|
799
|
+
# @return [Channel] The default channel on this server (usually called #general)
|
800
|
+
def default_channel
|
801
|
+
@bot.channel(@id)
|
574
802
|
end
|
575
803
|
|
576
|
-
|
577
|
-
return unless voice_states
|
578
|
-
voice_states.each do |element|
|
579
|
-
user_id = element['user_id'].to_i
|
580
|
-
user = @members_by_id[user_id]
|
581
|
-
next unless user
|
582
|
-
user.server_mute = element['mute']
|
583
|
-
user.server_deaf = element['deaf']
|
584
|
-
user.self_mute = element['self_mute']
|
585
|
-
user.self_mute = element['self_mute']
|
586
|
-
channel_id = element['channel_id'].to_i
|
587
|
-
channel = channel_id ? @channels_by_id[channel_id] : nil
|
588
|
-
user.move(channel)
|
589
|
-
end
|
590
|
-
end
|
804
|
+
alias_method :general_channel, :default_channel
|
591
805
|
|
806
|
+
# Gets a role on this server based on its ID.
|
807
|
+
# @param id [Integer] The role ID to look for.
|
592
808
|
def role(id)
|
593
809
|
@roles.find { |e| e.id == id }
|
594
810
|
end
|
595
811
|
|
812
|
+
# Adds a role to the role cache
|
813
|
+
# @note For internal use only
|
814
|
+
# @!visibility private
|
596
815
|
def add_role(role)
|
597
816
|
@roles << role
|
598
817
|
end
|
599
818
|
|
819
|
+
# Removes a role from the role cache
|
820
|
+
# @note For internal use only
|
821
|
+
# @!visibility private
|
600
822
|
def delete_role(role_id)
|
601
823
|
@roles.reject! { |r| r.id == role_id }
|
602
824
|
@members.each do |user|
|
@@ -609,19 +831,31 @@ module Discordrb
|
|
609
831
|
end
|
610
832
|
end
|
611
833
|
|
834
|
+
# Adds a user to the user cache.
|
835
|
+
# @note For internal use only
|
836
|
+
# @!visibility private
|
612
837
|
def add_user(user)
|
613
838
|
@members << user
|
614
839
|
end
|
615
840
|
|
841
|
+
# Removes a user from the user cache.
|
842
|
+
# @note For internal use only
|
843
|
+
# @!visibility private
|
616
844
|
def delete_user(user_id)
|
617
845
|
@members.reject! { |member| member.id == user_id }
|
618
846
|
end
|
619
847
|
|
848
|
+
# Creates a channel on this server with the given name.
|
849
|
+
# @return [Channel] the created channel.
|
620
850
|
def create_channel(name)
|
621
851
|
response = API.create_channel(@bot.token, @id, name, 'text')
|
622
852
|
Channel.new(JSON.parse(response), @bot)
|
623
853
|
end
|
624
854
|
|
855
|
+
# Creates a role on this server which can then be modified. It will be initialized (on Discord's side)
|
856
|
+
# with the regular role defaults the client uses, i. e. name is "new role", permissions are the default,
|
857
|
+
# colour is the default etc.
|
858
|
+
# @return [Role] the created role.
|
625
859
|
def create_role
|
626
860
|
response = API.create_role(@bot.token, @id)
|
627
861
|
role = Role.new(JSON.parse(response), @bot)
|
@@ -629,56 +863,94 @@ module Discordrb
|
|
629
863
|
role
|
630
864
|
end
|
631
865
|
|
866
|
+
# Bans a user from this server.
|
867
|
+
# @param user [User] The user to ban.
|
868
|
+
# @param message_days [Integer] How many days worth of messages sent by the user should be deleted.
|
632
869
|
def ban(user, message_days = 0)
|
633
870
|
API.ban_user(@bot.token, @id, user.id, message_days)
|
634
871
|
end
|
635
872
|
|
873
|
+
# Unbans a previously banned user from this server.
|
874
|
+
# @param user [User] The user to unban.
|
636
875
|
def unban(user)
|
637
876
|
API.unban_user(@bot.token, @id, user.id)
|
638
877
|
end
|
639
878
|
|
879
|
+
# Kicks a user from this server.
|
880
|
+
# @param user [User] The user to kick.
|
640
881
|
def kick(user)
|
641
882
|
API.kick_user(@bot.token, @id, user.id)
|
642
883
|
end
|
643
884
|
|
885
|
+
# Forcibly moves a user into a different voice channel. Only works if the bot has the permission needed.
|
886
|
+
# @param user [User] The user to move.
|
887
|
+
# @param channel [Channel] The voice channel to move into.
|
888
|
+
def move(user, channel)
|
889
|
+
API.move_user(@bot.token, @id, user.id, channel.id)
|
890
|
+
end
|
891
|
+
|
892
|
+
# Deletes this server. Be aware that this is permanent and impossible to undo, so be careful!
|
644
893
|
def delete
|
645
894
|
API.delete_server(@bot.token, @id)
|
646
895
|
end
|
647
896
|
|
897
|
+
# Leave the server - to Discord, leaving a server and deleting it are the same, so be careful if the bot
|
898
|
+
# is the server owner!
|
648
899
|
alias_method :leave, :delete
|
649
900
|
|
901
|
+
# Transfers server ownership to another user.
|
902
|
+
# @param user [User] The user who should become the new owner.
|
903
|
+
def owner=(user)
|
904
|
+
API.transfer_ownership(@bot.token, @id, user.id)
|
905
|
+
end
|
906
|
+
|
907
|
+
# Sets the server's name.
|
908
|
+
# @param name [String] The new server name.
|
650
909
|
def name=(name)
|
651
910
|
update_server_data(name: name)
|
652
911
|
end
|
653
912
|
|
913
|
+
# Moves the server to another region. This will cause a voice interruption of at most a second.
|
914
|
+
# @param region [String] The new region the server should be in.
|
654
915
|
def region=(region)
|
655
916
|
update_server_data(region: region.to_s)
|
656
917
|
end
|
657
918
|
|
919
|
+
# Sets the server's icon.
|
920
|
+
# @todo Make this behave in a similar way to User#avatar=.
|
921
|
+
# @param icon [String] The new icon, in base64-encoded JPG format.
|
658
922
|
def icon=(icon)
|
659
923
|
update_server_data(icon: icon)
|
660
924
|
end
|
661
925
|
|
926
|
+
# Sets the server's AFK channel.
|
927
|
+
# @param afk_channel [Channel, nil] The new AFK channel, or `nil` if there should be none set.
|
662
928
|
def afk_channel=(afk_channel)
|
663
|
-
update_server_data(afk_channel_id: afk_channel.
|
929
|
+
update_server_data(afk_channel_id: afk_channel.resolve_id)
|
664
930
|
end
|
665
931
|
|
932
|
+
# @deprecated Use #afk_channel= with the ID instead.
|
666
933
|
def afk_channel_id=(afk_channel_id)
|
667
934
|
update_server_data(afk_channel_id: afk_channel_id)
|
668
935
|
end
|
669
936
|
|
937
|
+
# Sets the amount of time after which a user gets moved into the AFK channel.
|
938
|
+
# @param afk_timeout [Integer] The AFK timeout, in seconds.
|
670
939
|
def afk_timeout=(afk_timeout)
|
671
940
|
update_server_data(afk_timeout: afk_timeout)
|
672
941
|
end
|
673
942
|
|
943
|
+
# Updates the cached data with new data
|
944
|
+
# @note For internal use only
|
945
|
+
# @!visibility private
|
674
946
|
def update_data(new_data)
|
675
947
|
@name = new_data[:name] || new_data['name'] || @name
|
676
948
|
@region = new_data[:region] || new_data['region'] || @region
|
677
949
|
@icon = new_data[:icon] || new_data['icon'] || @icon
|
678
950
|
@afk_timeout = new_data[:afk_timeout] || new_data['afk_timeout'].to_i || @afk_timeout
|
679
951
|
|
680
|
-
afk_channel_id = new_data[:afk_channel_id] || new_data['afk_channel_id'].to_i || @afk_channel.id
|
681
|
-
@afk_channel = @bot.channel(afk_channel_id) if afk_channel_id != 0 && (!@afk_channel || afk_channel_id != @afk_channel.id)
|
952
|
+
@afk_channel_id = new_data[:afk_channel_id] || new_data['afk_channel_id'].to_i || @afk_channel.id
|
953
|
+
@afk_channel = @bot.channel(@afk_channel_id) if @afk_channel_id != 0 && (!@afk_channel || @afk_channel_id != @afk_channel.id)
|
682
954
|
end
|
683
955
|
|
684
956
|
private
|
@@ -692,12 +964,98 @@ module Discordrb
|
|
692
964
|
new_data[:afk_timeout] || @afk_timeout)
|
693
965
|
update_data(new_data)
|
694
966
|
end
|
967
|
+
|
968
|
+
def process_roles(roles)
|
969
|
+
# Create roles
|
970
|
+
@roles = []
|
971
|
+
@roles_by_id = {}
|
972
|
+
|
973
|
+
return unless roles
|
974
|
+
roles.each do |element|
|
975
|
+
role = Role.new(element, @bot, self)
|
976
|
+
@roles << role
|
977
|
+
@roles_by_id[role.id] = role
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
def process_members(members)
|
982
|
+
@members = []
|
983
|
+
@members_by_id = {}
|
984
|
+
|
985
|
+
return unless members
|
986
|
+
members.each do |element|
|
987
|
+
user = User.new(element['user'], @bot)
|
988
|
+
@members << user
|
989
|
+
@members_by_id[user.id] = user
|
990
|
+
user_roles = []
|
991
|
+
element['roles'].each do |e|
|
992
|
+
role_id = e.to_i
|
993
|
+
user_roles << @roles_by_id[role_id]
|
994
|
+
end
|
995
|
+
user.update_roles(self, user_roles)
|
996
|
+
end
|
997
|
+
end
|
998
|
+
|
999
|
+
def process_presences(presences)
|
1000
|
+
# Update user statuses with presence info
|
1001
|
+
return unless presences
|
1002
|
+
presences.each do |element|
|
1003
|
+
next unless element['user']
|
1004
|
+
user_id = element['user']['id'].to_i
|
1005
|
+
user = @members_by_id[user_id]
|
1006
|
+
if user
|
1007
|
+
user.status = element['status'].to_sym
|
1008
|
+
user.game = element['game'] ? element['game']['name'] : nil
|
1009
|
+
end
|
1010
|
+
end
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
def process_channels(channels)
|
1014
|
+
@channels = []
|
1015
|
+
@channels_by_id = {}
|
1016
|
+
|
1017
|
+
return unless channels
|
1018
|
+
channels.each do |element|
|
1019
|
+
channel = Channel.new(element, @bot, self)
|
1020
|
+
@channels << channel
|
1021
|
+
@channels_by_id[channel.id] = channel
|
1022
|
+
end
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def process_voice_states(voice_states)
|
1026
|
+
return unless voice_states
|
1027
|
+
voice_states.each do |element|
|
1028
|
+
user_id = element['user_id'].to_i
|
1029
|
+
user = @members_by_id[user_id]
|
1030
|
+
next unless user
|
1031
|
+
user.server_mute = element['mute']
|
1032
|
+
user.server_deaf = element['deaf']
|
1033
|
+
user.self_mute = element['self_mute']
|
1034
|
+
user.self_mute = element['self_mute']
|
1035
|
+
channel_id = element['channel_id'].to_i
|
1036
|
+
channel = channel_id ? @channels_by_id[channel_id] : nil
|
1037
|
+
user.move(channel)
|
1038
|
+
end
|
1039
|
+
end
|
695
1040
|
end
|
696
1041
|
|
697
|
-
# A colour (red, green and blue values). Used for role colours
|
1042
|
+
# A colour (red, green and blue values). Used for role colours. If you prefer the American spelling, the alias
|
1043
|
+
# {ColorRGB} is also available.
|
698
1044
|
class ColourRGB
|
699
|
-
|
1045
|
+
# @return [Integer] the red part of this colour (0-255).
|
1046
|
+
attr_reader :red
|
1047
|
+
|
1048
|
+
# @return [Integer] the green part of this colour (0-255).
|
1049
|
+
attr_reader :green
|
1050
|
+
|
1051
|
+
# @return [Integer] the blue part of this colour (0-255).
|
1052
|
+
attr_reader :blue
|
1053
|
+
|
1054
|
+
# @return [Integer] the colour's RGB values combined into one integer.
|
1055
|
+
attr_reader :combined
|
700
1056
|
|
1057
|
+
# Make a new colour from the combined value.
|
1058
|
+
# @param combined [Integer] The colour's RGB values combined into one integer
|
701
1059
|
def initialize(combined)
|
702
1060
|
@combined = combined
|
703
1061
|
@red = (combined >> 16) & 0xFF
|
@@ -706,5 +1064,6 @@ module Discordrb
|
|
706
1064
|
end
|
707
1065
|
end
|
708
1066
|
|
1067
|
+
# Alias for the class {ColourRGB}
|
709
1068
|
ColorRGB = ColourRGB
|
710
1069
|
end
|