mij-discord 1.0.9 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,176 +1,174 @@
1
- # frozen_string_literal: true
2
-
3
- module MijDiscord::Data
4
- class Member < DelegateClass(User)
5
- include PermissionObject
6
-
7
- attr_reader :bot
8
-
9
- attr_reader :joined_at
10
-
11
- attr_reader :nickname
12
- alias_method :nick, :nickname
13
-
14
- attr_reader :roles
15
-
16
- attr_reader :server
17
-
18
- def mute?
19
- voice_state_attribute(:mute)
20
- end
21
-
22
- def deaf?
23
- voice_state_attribute(:deaf)
24
- end
25
-
26
- def self_mute?
27
- voice_state_attribute(:self_mute)
28
- end
29
-
30
- def self_deaf?
31
- voice_state_attribute(:self_deaf)
32
- end
33
-
34
- def voice_channel
35
- voice_state_attribute(:voice_channel)
36
- end
37
-
38
- def initialize(data, server, bot)
39
- @bot = bot
40
-
41
- @user = @bot.cache.put_user(data['user'])
42
- super @user
43
-
44
- raise ArgumentError, 'Cannot create member with no server' unless server || data['guild_id']
45
- @server = server || @bot.servers(data['guild_id'])
46
-
47
- @joined_at = Time.parse(data['joined_at']).utc if data['joined_at']
48
-
49
- update_data(data)
50
- end
51
-
52
- def update_data(data)
53
- @user.update_data(data['user'])
54
-
55
- @nickname = data.fetch('nick', @nickname || '')
56
-
57
- if (roles = data['roles'])
58
- @roles = roles.map {|x| @server.role(x) }
59
- end
60
- end
61
-
62
- def member?
63
- true
64
- end
65
-
66
- def owner?
67
- @server.owner == self
68
- end
69
-
70
- def role?(role)
71
- role = role.to_id
72
- @roles.any? {|x| x.id == role }
73
- end
74
-
75
- def set_roles(roles, reason = nil)
76
- roles = roles.map(&:to_id)
77
- MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, roles: roles)
78
- end
79
-
80
- def modify_roles(add, remove, reason = nil)
81
- add, remove = add.map(&:to_id), remove.map(&:to_id)
82
- roles = (@roles.map(&:id) - remove + add).uniq
83
- MijDiscord::Core::API::Server.update_member(@bot.tolen, @server.id, @user.id, reason, roles: roles)
84
- end
85
-
86
- def add_role(role, reason = nil)
87
- if role.is_a?(Array)
88
- modify_roles(role, [], reason)
89
- else
90
- role = role.to_id
91
- MijDiscord::Core::API::Server.add_member_role(@bot.auth, @server.id, @user.id, role, reason)
92
- end
93
- end
94
-
95
- def remove_role(role, reason = nil)
96
- if role.is_a?(Array)
97
- modify_roles([], role, reason)
98
- else
99
- role = role.to_id
100
- MijDiscord::Core::API::Server.remove_member_role(@bot.auth, @server.id, @user.id, role, reason)
101
- end
102
- end
103
-
104
- def highest_role
105
- @roles.sort_by(&:position).last
106
- end
107
-
108
- def hoist_role
109
- roles = @roles.select(&:hoist)
110
- roles.sort_by(&:position).last
111
- end
112
-
113
- def color_role
114
- roles = @roles.select {|x| x.color.to_i.nonzero? }
115
- roles.sort_by(&:position).last
116
- end
117
-
118
- def color
119
- color_role&.color
120
- end
121
-
122
- def set_nickname(nick, reason = nil)
123
- nick ||= ''
124
-
125
- if @user.current_bot?
126
- MijDiscord::Core::API::User.change_own_nickname(@bot.auth, @server.id, nick, reason)
127
- else
128
- MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, nick: nick)
129
- end
130
- end
131
-
132
- alias_method :nickname=, :set_nickname
133
-
134
- def display_name
135
- nickname.empty? ? username : nickname
136
- end
137
-
138
- def inspect
139
- MijDiscord.make_inspect(self,
140
- :id, :username, :discriminator, :avatar_id, :bot_account, :joined_at, :nickname, :roles)
141
- end
142
-
143
- private
144
-
145
- def voice_state_attribute(key)
146
- @server.voice_states[@user.id]&.send(key)
147
- end
148
- end
149
-
150
- class Recipient < DelegateClass(User)
151
- attr_reader :joined_at
152
-
153
- attr_reader :nickname
154
- alias_method :nick, :nickname
155
-
156
- attr_reader :roles
157
-
158
- attr_reader :server
159
-
160
- def initialize(user, channel, bot)
161
- @bot, @channel, @user = bot, channel, user
162
- raise ArgumentError, 'Recipient for public channel' unless channel.private?
163
-
164
- super @user
165
-
166
- @mute = @deaf = @self_mute = @self_deaf = false
167
- @voice_channel, @server, @roles = nil, nil, []
168
- @nickname, @joined_at = '', @channel.creation_time
169
- end
170
-
171
- def inspect
172
- MijDiscord.make_inspect(self,
173
- :id, :username, :discriminator, :avatar_id, :bot_account, :joined_at)
174
- end
175
- end
1
+ # frozen_string_literal: true
2
+
3
+ module MijDiscord::Data
4
+ class Member < DelegateClass(User)
5
+ include PermissionObject
6
+
7
+ attr_reader :bot
8
+
9
+ attr_reader :joined_at
10
+
11
+ attr_reader :nickname
12
+ alias_method :nick, :nickname
13
+
14
+ attr_reader :roles
15
+
16
+ attr_reader :server
17
+
18
+ def mute?
19
+ voice_state_attribute(:mute)
20
+ end
21
+
22
+ def deaf?
23
+ voice_state_attribute(:deaf)
24
+ end
25
+
26
+ def self_mute?
27
+ voice_state_attribute(:self_mute)
28
+ end
29
+
30
+ def self_deaf?
31
+ voice_state_attribute(:self_deaf)
32
+ end
33
+
34
+ def voice_channel
35
+ voice_state_attribute(:voice_channel)
36
+ end
37
+
38
+ def initialize(data, server, bot)
39
+ @bot = bot
40
+
41
+ @user = @bot.cache.put_user(data['user'])
42
+ super @user
43
+
44
+ raise ArgumentError, 'Cannot create member with no server' unless server || data['guild_id']
45
+ @server = server || @bot.servers(data['guild_id'])
46
+
47
+ @joined_at = Time.parse(data['joined_at']).utc if data['joined_at']
48
+
49
+ update_data(data)
50
+ end
51
+
52
+ def update_data(data)
53
+ @user.update_data(data['user'])
54
+
55
+ @nickname = data.fetch('nick', @nickname || '')
56
+
57
+ if (roles = data['roles'])
58
+ @roles = roles.map {|x| @server.role(x) }
59
+ end
60
+ end
61
+
62
+ def member?
63
+ true
64
+ end
65
+
66
+ def owner?
67
+ @server.owner == self
68
+ end
69
+
70
+ def role?(role)
71
+ role = role.to_id
72
+ @roles.any? {|x| x.id == role }
73
+ end
74
+
75
+ def set_roles(roles, reason = nil)
76
+ roles = roles.map(&:to_id)
77
+ MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, roles: roles)
78
+ end
79
+
80
+ def modify_roles(add, remove, reason = nil)
81
+ add, remove = add.map(&:to_id), remove.map(&:to_id)
82
+ roles = (@roles.map(&:id) - remove + add).uniq
83
+ MijDiscord::Core::API::Server.update_member(@bot.tolen, @server.id, @user.id, reason, roles: roles)
84
+ end
85
+
86
+ def add_role(role, reason = nil)
87
+ if role.is_a?(Array)
88
+ modify_roles(role, [], reason)
89
+ else
90
+ role = role.to_id
91
+ MijDiscord::Core::API::Server.add_member_role(@bot.auth, @server.id, @user.id, role, reason)
92
+ end
93
+ end
94
+
95
+ def remove_role(role, reason = nil)
96
+ if role.is_a?(Array)
97
+ modify_roles([], role, reason)
98
+ else
99
+ role = role.to_id
100
+ MijDiscord::Core::API::Server.remove_member_role(@bot.auth, @server.id, @user.id, role, reason)
101
+ end
102
+ end
103
+
104
+ def highest_role
105
+ @roles.sort_by(&:position).last
106
+ end
107
+
108
+ def hoist_role
109
+ roles = @roles.select(&:hoist)
110
+ roles.sort_by(&:position).last
111
+ end
112
+
113
+ def color_role
114
+ roles = @roles.select {|x| x.color.to_i.nonzero? }
115
+ roles.sort_by(&:position).last
116
+ end
117
+
118
+ def color
119
+ color_role&.color
120
+ end
121
+
122
+ def set_nickname(nick, reason = nil)
123
+ nick ||= ''
124
+
125
+ if @user.current_bot?
126
+ MijDiscord::Core::API::User.change_own_nickname(@bot.auth, @server.id, nick, reason)
127
+ else
128
+ MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, nick: nick)
129
+ end
130
+ end
131
+
132
+ alias_method :nickname=, :set_nickname
133
+
134
+ def display_name
135
+ nickname.empty? ? username : nickname
136
+ end
137
+
138
+ def inspect
139
+ MijDiscord.make_inspect(self, :user, :joined_at, :nickname, :roles)
140
+ end
141
+
142
+ private
143
+
144
+ def voice_state_attribute(key)
145
+ @server.voice_states[@user.id]&.send(key)
146
+ end
147
+ end
148
+
149
+ class Recipient < DelegateClass(User)
150
+ attr_reader :joined_at
151
+
152
+ attr_reader :nickname
153
+ alias_method :nick, :nickname
154
+
155
+ attr_reader :roles
156
+
157
+ attr_reader :server
158
+
159
+ def initialize(user, channel, bot)
160
+ @bot, @channel, @user = bot, channel, user
161
+ raise ArgumentError, 'Recipient for public channel' unless channel.private?
162
+
163
+ super @user
164
+
165
+ @mute = @deaf = @self_mute = @self_deaf = false
166
+ @voice_channel, @server, @roles = nil, nil, []
167
+ @nickname, @joined_at = '', @channel.creation_time
168
+ end
169
+
170
+ def inspect
171
+ MijDiscord.make_inspect(self, :user, :joined_at)
172
+ end
173
+ end
176
174
  end
@@ -1,468 +1,405 @@
1
- # frozen_string_literal: true
2
-
3
- module MijDiscord::Data
4
- class Server
5
- VERIFICATION_LEVEL = {
6
- 0 => :none,
7
- 1 => :low,
8
- 2 => :medium,
9
- 3 => :high,
10
- 4 => :very_high,
11
- }.freeze
12
-
13
- CONTENT_FILTER_LEVEL = {
14
- 0 => :none,
15
- 1 => :no_roles,
16
- 2 => :all,
17
- }.freeze
18
-
19
- DEFAULT_NOTIFICATIONS = {
20
- 0 => :all,
21
- 1 => :mentions,
22
- }.freeze
23
-
24
- CHANNEL_TYPES = {
25
- :text => 0,
26
- :voice => 2,
27
- :category => 4,
28
- }.freeze
29
-
30
- include IDObject
31
-
32
- attr_reader :bot
33
-
34
- attr_reader :name
35
-
36
- attr_reader :icon_id
37
-
38
- attr_reader :owner
39
-
40
- attr_reader :large
41
- alias_method :large?, :large
42
-
43
- attr_reader :features
44
-
45
- attr_reader :embed_enabled
46
- alias_method :embed_enabled?, :embed_enabled
47
- alias_method :has_embed?, :embed_enabled
48
-
49
- attr_reader :member_count
50
-
51
- attr_reader :verification_level
52
-
53
- attr_reader :content_filter_level
54
- alias_method :content_filter, :content_filter_level
55
-
56
- attr_reader :default_notifications
57
-
58
- attr_reader :afk_timeout
59
-
60
- attr_reader :afk_channel
61
-
62
- attr_reader :cache
63
-
64
- def initialize(data, bot, invalid = false)
65
- @bot = bot
66
-
67
- @id = data['id'].to_i
68
- @large = data['large']
69
- @member_count = data['member_count']
70
- @members_chunked = 0
71
-
72
- @cache = MijDiscord::Cache::ServerCache.new(self, @bot)
73
-
74
- data['channels']&.each {|ch| @cache.put_channel(ch) }
75
-
76
- data['roles']&.each {|ro| @cache.put_role(ro) }
77
-
78
- update_synced_data(data)
79
-
80
- @voice_states = {}
81
- data['voice_states']&.each {|vs| update_voice_state(vs) }
82
-
83
- update_emojis(data)
84
- update_data(data)
85
-
86
- @owner = member(data['owner_id'])
87
- end
88
-
89
- def update_data(data)
90
- @name = data.fetch('name', @name)
91
- @region_id = data.fetch('region', @region_id)
92
- @icon_id = data.fetch('icon', @icon_id)
93
- @afk_timeout = data.fetch('afk_timeout', @afk_timeout)
94
- @embed_enabled = data.fetch('embed_enabled', @embed_enabled)
95
- @verification_level = VERIFICATION_LEVEL.fetch(data['verification_level'], @verification_level)
96
- @content_filter_level = CONTENT_FILTER_LEVEL.fetch(data['explicit_content_filter'], @content_filter_level)
97
- @default_notifications = DEFAULT_NOTIFICATIONS.fetch(data['default_message_notifications'], @default_notifications)
98
-
99
- begin
100
- if data.has_key?('afk_channel_id')
101
- id = data['afk_channel_id'].to_i
102
- @afk_channel = @bot.channel(id, self)
103
- end
104
- rescue MijDiscord::Errors::Forbidden
105
- @afk_channel = nil
106
- end
107
- end
108
-
109
- def update_emojis(data)
110
- @emojis = {}
111
- data['emojis'].each do |em|
112
- emoji = MijDiscord::Data::Emoji.new(em, self)
113
- @emojis[emoji.id] = emoji
114
- end
115
- end
116
-
117
- def update_voice_state(data)
118
- user = @cache.get_member(data['user_id'])
119
-
120
- if (chan_id = data['channel_id']&.to_i)
121
- state = (@voice_states[user.id] ||= VoiceState.new(user))
122
- channel = @cache.get_channel(chan_id)
123
-
124
- state.update_data(channel, data) if channel
125
- state
126
- else
127
- state = @voice_states.delete(user.id)
128
- state ||= VoiceState.new(user)
129
-
130
- state.update_data(nil, data)
131
- state
132
- end
133
- end
134
-
135
- def update_members_chunk(data)
136
- return if @members_chunked.nil?
137
-
138
- @members_chunked += data.length
139
- data.each {|mb| @cache.put_member(mb) }
140
-
141
- @members_chunked = nil if @members_chunked == @member_count
142
- end
143
-
144
- def update_synced_data(data)
145
- data['members']&.each {|mb| @cache.put_member(mb, update: true) }
146
-
147
- data['presences']&.each do |pr|
148
- next unless pr['user']
149
-
150
- user_id = pr['user']['id'].to_i
151
- user = @cache.get_member(user_id, local: true)
152
- user.update_presence(pr) if user
153
- end
154
- end
155
-
156
- def update_member(data, mode)
157
- case mode
158
- when :add
159
- @member_count += 1
160
- @cache.put_member(data)
161
- when :remove
162
- @member_count -= 1
163
- key = data['user']['id']
164
- @cache.remove_member(key)
165
- when :update
166
- @cache.put_member(data, update: true)
167
- end
168
- end
169
-
170
- def channels
171
- @cache.list_channels
172
- end
173
-
174
- def channel(id)
175
- @cache.get_channel(id)
176
- end
177
-
178
- def roles
179
- @cache.list_roles
180
- end
181
-
182
- def role(id)
183
- @cache.get_role(id)
184
- end
185
-
186
- def members
187
- unless @members_chunked.nil?
188
- @bot.gateway.send_request_members(@id, '', 0)
189
- sleep(0.05) while @members_chunked
190
- end
191
-
192
- @cache.list_members
193
- end
194
-
195
- def member(id)
196
- @cache.get_member(id)
197
- end
198
-
199
- def emojis
200
- @emojis.values
201
- end
202
-
203
- def emoji(id)
204
- @emojis[id&.to_id]
205
- end
206
-
207
- def everyone_role
208
- role(@id)
209
- end
210
-
211
- def voice_states
212
- @voice_states.values
213
- end
214
-
215
- def voice_state(id)
216
- @voice_states[id&.to_id]
217
- end
218
-
219
- def default_channel(can_send = false)
220
- text_channels.sort_by {|ch| [ch.position, ch.id] }.find do |ch|
221
- if (overwrite = ch.permission_overwrites[id])
222
- if can_send
223
- overwrite.allow.send_messages? || !overwrite.deny.send_messages?
224
- else
225
- overwrite.allow.read_messages? || !overwrite.deny.read_messages?
226
- end
227
- else
228
- if can_send
229
- everyone_role.permissions.send_messages
230
- else
231
- everyone_role.permissions.read_messages
232
- end
233
- end
234
- end
235
- end
236
-
237
- alias_method :general_channel, :default_channel
238
-
239
- def online_members(idle: true, bots: false)
240
- members.select! do |m|
241
- ((idle ? m.idle? : false) || m.online?) && (bots ? true : !m.bot_account?)
242
- end
243
- end
244
-
245
- def invites
246
- response = MijDiscord::Core::API::Server.invites(@bot.auth, @id)
247
- JSON.parse(response).map {|x| Invite.new(x, @bot) }
248
- end
249
-
250
- def webhooks
251
- response = MijDiscord::Core::API::Server.webhooks(@bot.auth, @id)
252
- JSON.parse(response).map {|x| Webhook.new(x, @bot) }
253
- end
254
-
255
- def prune_count(days)
256
- raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
257
-
258
- response = MijDiscord::Core::API::Server.prune_count(@bot.auth, @id, days)
259
- JSON.parse(response)['pruned']
260
- end
261
-
262
- def prune(days, reason = nil)
263
- raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
264
-
265
- response = MijDiscord::Core::API::Server.begin_prune(@bot.auth, @id, days, reason)
266
- JSON.parse(response)['pruned']
267
- end
268
-
269
- def text_channels
270
- channels.select!(&:text?)
271
- end
272
-
273
- def voice_channels
274
- channels.select!(&:voice?)
275
- end
276
-
277
- def create_channel(name, reason = nil, type: :text, bitrate: nil, user_limit: nil, permissions: [], nsfw: false)
278
- raise ArgumentError, 'Invalid channel type specified' unless CHANNEL_TYPES.has_key?(type)
279
-
280
- permissions = permissions.map {|x| x.is_a(Overwrite) ? x.to_hash : x }
281
- response = MijDiscord::Core::API::Server.create_channel(@bot.auth, @id,
282
- name, CHANNEL_TYPES[type], bitrate, user_limit, permissions, nsfw, reason)
283
- @cache.put_channel(JSON.parse(response))
284
- end
285
-
286
- def create_role(name, reason = nil, color: 0, hoist: false, mentionable: false, permissions: 104_324_161)
287
- response = MijDiscord::Core::API::Server.create_role(@bot.auth, @id,
288
- name, color.to_i, hoist, mentionable, permissions.to_i, reason)
289
- @cache.put_role(JSON.parse(response))
290
- end
291
-
292
- def bans
293
- response = MijDiscord::Core::API::Server.bans(@bot.auth, @id)
294
- JSON.parse(response).map {|x| @bot.cache.put_user(x['user']) }
295
- end
296
-
297
- def ban(user, message_days = 0, reason = nil)
298
- MijDiscord::Core::API::Server.ban_user(@bot.auth, @id, user.to_id, message_days, reason)
299
- nil
300
- end
301
-
302
- def unban(user, reason = nil)
303
- MijDiscord::Core::API::Server.unban_user(@bot.auth, @id, user.to_id, reason)
304
- nil
305
- end
306
-
307
- def kick(user, reason = nil)
308
- MijDiscord::Core::API::Server.remove_member(@bot.auth, @id, user.to_id, reason)
309
- nil
310
- end
311
-
312
- def leave
313
- MijDiscord::Core::API::User.leave_server(@bot.auth, @id)
314
- nil
315
- end
316
-
317
- def delete
318
- MijDiscord::Core::API::Server.delete(@bot.auth, @id)
319
- nil
320
- end
321
-
322
- def set_owner(user, reason = nil)
323
- MijDiscord::Core::API::Server.transfer_ownership(@bot.auth, @id, user.to_id, reason)
324
- end
325
-
326
- alias_method :owner=, :set_owner
327
-
328
- def set_options(reason = nil, name: nil, region: nil, icon: nil, afk_channel: nil, afk_timeout: nil)
329
- response = MijDiscord::Core::API::Server.update(@bot.auth, @id,
330
- name, region, icon, afk_channel&.to_id, afk_timeout, reason)
331
- @bot.cache.put_server(JSON.parse(response), update: true)
332
- end
333
-
334
- def set_name(name, reason = nil)
335
- set_options(reason, name: name)
336
- nil
337
- end
338
-
339
- alias_method :name=, :set_name
340
-
341
- def available_regions
342
- return @voice_regions if @voice_regions
343
-
344
- response = MijDiscord::Core::API::Server.regions(@bot.auth, @id)
345
- @voice_regions = JSON.parse(response).map {|x| VoiceRegion.new(x) }
346
- end
347
-
348
- def region
349
- available_regions.find {|x| x.id == @region_id }
350
- end
351
-
352
- def set_region(region, reason = nil)
353
- region = region.to_s
354
- raise ArgumentError, 'Invalid region' unless available_regions.find {|x| x.id == region }
355
-
356
- set_options(reason, region: region)
357
- nil
358
- end
359
-
360
- alias_method :region=, :set_region
361
-
362
- def set_icon(icon, reason = nil)
363
- if icon.respond_to?(:read)
364
- buffer = Base64.strict_encode64(icon.read)
365
- icon = "data:image/jpg;base64,#{buffer}"
366
- set_options(reason, icon: icon)
367
- else
368
- set_options(reason, icon: icon.to_s)
369
- end
370
- nil
371
- end
372
-
373
- alias_method :icon=, :set_icon
374
-
375
- def set_afk_channel(channel, reason = nil)
376
- set_options(reason, afk_channel: channel.to_id)
377
- nil
378
- end
379
-
380
- alias_method :afk_channel=, :set_afk_channel
381
-
382
- def set_afk_timeout(timeout, reason = nil)
383
- set_options(reason, afk_timeout: timeout)
384
- nil
385
- end
386
-
387
- alias_method :afk_timeout=, :set_afk_timeout
388
-
389
- def icon_url(format = :webp)
390
- return nil unless @icon_id
391
- MijDiscord::Core::API.icon_url(@id, @icon_id, format)
392
- end
393
-
394
- def embed_url(style = :shield)
395
- return nil unless @embed_enabled
396
- MijDiscord::Core::API.widget_url(@id, style)
397
- end
398
-
399
- def search_messages(limit: 25, offset: 0, sort_by: nil, sort_asc: false,
400
- nsfw: true, around: 2, content: nil, author: nil, channel: nil, mentions: nil,
401
- author_is: nil, author_not: nil, has: nil, has_not: nil, before: nil, after: nil)
402
- author = author ? [*author].map(&:to_id) : nil
403
- channel = channel ? [*channel].map(&:to_id) : nil
404
- mentions = mentions ? [*mentions].map(&:to_id) : nil
405
-
406
- has_not = has_not ? [*has_not].map {|x| "-#{x}" } : []
407
- author_not = author_not ? [*author_not].map {|x| "-#{x}" } : []
408
-
409
- has = has_not | (has ? [*has].map(&:to_s) : [])
410
- author_is = author_not | (author_is ? [*author_is].map(&:to_s) : [])
411
-
412
- before = before ? IDObject.synthesize(before) : nil
413
- after = after ? IDObject.synthesize(after) : nil
414
-
415
- options = {
416
- limit: limit,
417
- offset: offset,
418
- sort_by: sort_by,
419
- sort_order: sort_asc ? 'asc' : 'desc',
420
- context_size: around,
421
- include_nsfw: nsfw,
422
- author_id: author,
423
- author_type: author_is,
424
- channel_id: channel,
425
- mentions: mentions,
426
- max_id: before,
427
- min_id: after,
428
- content: content,
429
- has: has,
430
- }.delete_if {|_,v| v.nil? }
431
-
432
- response = MijDiscord::Core::API::Server.search_messages(@bot.auth, @id, options)
433
- SearchResults.new(JSON.parse(response), @bot)
434
- end
435
-
436
- def inspect
437
- MijDiscord.make_inspect(self,
438
- :id, :name, :owner, :member_count, :features, :embed_enabled, :verification_level,
439
- :content_filter_level, :default_notifications, :afk_timeout, :afk_channel)
440
- end
441
- end
442
-
443
- class SearchResults
444
- ResultData = Struct.new(:result, :context) do
445
- def inspect
446
- MijDiscord.make_inspect(self, :result, :context)
447
- end
448
- end
449
-
450
- attr_reader :total_count
451
-
452
- attr_reader :messages
453
-
454
- def initialize(data, bot)
455
- @total_count = data['total_results']
456
-
457
- @messages = data['messages'].map do |group|
458
- context = group.map {|x| Message.new(x, bot) }
459
- result = context.delete_at(context.length / 2)
460
- ResultData.new(result, context)
461
- end
462
- end
463
-
464
- def inspect
465
- MijDiscord.make_inspect(self, :total_count, :messages)
466
- end
467
- end
1
+ # frozen_string_literal: true
2
+
3
+ module MijDiscord::Data
4
+ class Server
5
+ VERIFICATION_LEVEL = {
6
+ 0 => :none,
7
+ 1 => :low,
8
+ 2 => :medium,
9
+ 3 => :high,
10
+ 4 => :very_high,
11
+ }.freeze
12
+
13
+ CONTENT_FILTER_LEVEL = {
14
+ 0 => :none,
15
+ 1 => :no_roles,
16
+ 2 => :all,
17
+ }.freeze
18
+
19
+ DEFAULT_NOTIFICATIONS = {
20
+ 0 => :all,
21
+ 1 => :mentions,
22
+ }.freeze
23
+
24
+ CHANNEL_TYPES = {
25
+ :text => 0,
26
+ :voice => 2,
27
+ :category => 4,
28
+ }.freeze
29
+
30
+ include IDObject
31
+
32
+ attr_reader :bot
33
+
34
+ attr_reader :name
35
+
36
+ attr_reader :icon_id
37
+
38
+ attr_reader :owner
39
+
40
+ attr_reader :large
41
+ alias_method :large?, :large
42
+
43
+ attr_reader :features
44
+
45
+ attr_reader :embed_enabled
46
+ alias_method :embed_enabled?, :embed_enabled
47
+ alias_method :has_embed?, :embed_enabled
48
+
49
+ attr_reader :member_count
50
+
51
+ attr_reader :verification_level
52
+
53
+ attr_reader :content_filter_level
54
+ alias_method :content_filter, :content_filter_level
55
+
56
+ attr_reader :default_notifications
57
+
58
+ attr_reader :afk_timeout
59
+
60
+ attr_reader :afk_channel
61
+
62
+ attr_reader :cache
63
+
64
+ def initialize(data, bot, invalid = false)
65
+ @bot = bot
66
+
67
+ @id = data['id'].to_i
68
+ @large = data['large']
69
+ @member_count = data['member_count']
70
+ @members_chunked = 0
71
+
72
+ @cache = MijDiscord::Cache::ServerCache.new(self, @bot)
73
+
74
+ data['channels']&.each {|ch| @cache.put_channel(ch) }
75
+
76
+ data['roles']&.each {|ro| @cache.put_role(ro) }
77
+
78
+ update_synced_data(data)
79
+
80
+ @voice_states = {}
81
+ data['voice_states']&.each {|vs| update_voice_state(vs) }
82
+
83
+ update_emojis(data)
84
+ update_data(data)
85
+
86
+ @owner = member(data['owner_id'])
87
+ end
88
+
89
+ def update_data(data)
90
+ @name = data.fetch('name', @name)
91
+ @region_id = data.fetch('region', @region_id)
92
+ @icon_id = data.fetch('icon', @icon_id)
93
+ @afk_timeout = data.fetch('afk_timeout', @afk_timeout)
94
+ @embed_enabled = data.fetch('embed_enabled', @embed_enabled)
95
+ @verification_level = VERIFICATION_LEVEL.fetch(data['verification_level'], @verification_level)
96
+ @content_filter_level = CONTENT_FILTER_LEVEL.fetch(data['explicit_content_filter'], @content_filter_level)
97
+ @default_notifications = DEFAULT_NOTIFICATIONS.fetch(data['default_message_notifications'], @default_notifications)
98
+
99
+ begin
100
+ if data.has_key?('afk_channel_id')
101
+ id = data['afk_channel_id'].to_i
102
+ @afk_channel = @bot.channel(id, self)
103
+ end
104
+ rescue MijDiscord::Errors::Forbidden
105
+ @afk_channel = nil
106
+ end
107
+ end
108
+
109
+ def update_emojis(data)
110
+ @emojis = {}
111
+ data['emojis'].each do |em|
112
+ emoji = MijDiscord::Data::Emoji.new(em, self)
113
+ @emojis[emoji.id] = emoji
114
+ end
115
+ end
116
+
117
+ def update_voice_state(data)
118
+ user = @cache.get_member(data['user_id'])
119
+
120
+ if (chan_id = data['channel_id']&.to_i)
121
+ state = (@voice_states[user.id] ||= VoiceState.new(user))
122
+ channel = @cache.get_channel(chan_id)
123
+
124
+ state.update_data(channel, data) if channel
125
+ state
126
+ else
127
+ state = @voice_states.delete(user.id)
128
+ state ||= VoiceState.new(user)
129
+
130
+ state.update_data(nil, data)
131
+ state
132
+ end
133
+ end
134
+
135
+ def update_members_chunk(data)
136
+ return if @members_chunked.nil?
137
+
138
+ @members_chunked += data.length
139
+ data.each {|mb| @cache.put_member(mb) }
140
+
141
+ @members_chunked = nil if @members_chunked == @member_count
142
+ end
143
+
144
+ def update_synced_data(data)
145
+ data['members']&.each {|mb| @cache.put_member(mb, update: true) }
146
+
147
+ data['presences']&.each do |pr|
148
+ next unless pr['user']
149
+
150
+ user_id = pr['user']['id'].to_i
151
+ user = @cache.get_member(user_id, local: true)
152
+ user.update_presence(pr) if user
153
+ end
154
+ end
155
+
156
+ def update_member(data, mode)
157
+ case mode
158
+ when :add
159
+ @member_count += 1
160
+ @cache.put_member(data)
161
+ when :remove
162
+ @member_count -= 1
163
+ key = data['user']['id']
164
+ @cache.remove_member(key)
165
+ when :update
166
+ @cache.put_member(data, update: true)
167
+ end
168
+ end
169
+
170
+ def channels
171
+ @cache.list_channels
172
+ end
173
+
174
+ def channel(id)
175
+ @cache.get_channel(id)
176
+ end
177
+
178
+ def roles
179
+ @cache.list_roles
180
+ end
181
+
182
+ def role(id)
183
+ @cache.get_role(id)
184
+ end
185
+
186
+ def members
187
+ unless @members_chunked.nil?
188
+ @bot.gateway.send_request_members(@id, '', 0)
189
+ sleep(0.05) while @members_chunked
190
+ end
191
+
192
+ @cache.list_members
193
+ end
194
+
195
+ def member(id)
196
+ @cache.get_member(id)
197
+ end
198
+
199
+ def emojis
200
+ @emojis.values
201
+ end
202
+
203
+ def emoji(id)
204
+ @emojis[id&.to_id]
205
+ end
206
+
207
+ def everyone_role
208
+ role(@id)
209
+ end
210
+
211
+ def voice_states
212
+ @voice_states.values
213
+ end
214
+
215
+ def voice_state(id)
216
+ @voice_states[id&.to_id]
217
+ end
218
+
219
+ def default_channel(can_send = false)
220
+ text_channels.sort_by {|ch| [ch.position, ch.id] }.find do |ch|
221
+ if (overwrite = ch.permission_overwrites[id])
222
+ if can_send
223
+ overwrite.allow.send_messages? || !overwrite.deny.send_messages?
224
+ else
225
+ overwrite.allow.read_messages? || !overwrite.deny.read_messages?
226
+ end
227
+ else
228
+ if can_send
229
+ everyone_role.permissions.send_messages
230
+ else
231
+ everyone_role.permissions.read_messages
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ alias_method :general_channel, :default_channel
238
+
239
+ def online_members(idle: true, bots: false)
240
+ members.select! do |m|
241
+ ((idle ? m.idle? : false) || m.online?) && (bots ? true : !m.bot_account?)
242
+ end
243
+ end
244
+
245
+ def invites
246
+ response = MijDiscord::Core::API::Server.invites(@bot.auth, @id)
247
+ JSON.parse(response).map {|x| Invite.new(x, @bot) }
248
+ end
249
+
250
+ def webhooks
251
+ response = MijDiscord::Core::API::Server.webhooks(@bot.auth, @id)
252
+ JSON.parse(response).map {|x| Webhook.new(x, @bot) }
253
+ end
254
+
255
+ def prune_count(days)
256
+ raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
257
+
258
+ response = MijDiscord::Core::API::Server.prune_count(@bot.auth, @id, days)
259
+ JSON.parse(response)['pruned']
260
+ end
261
+
262
+ def prune(days, reason = nil)
263
+ raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
264
+
265
+ response = MijDiscord::Core::API::Server.begin_prune(@bot.auth, @id, days, reason)
266
+ JSON.parse(response)['pruned']
267
+ end
268
+
269
+ def text_channels
270
+ channels.select!(&:text?)
271
+ end
272
+
273
+ def voice_channels
274
+ channels.select!(&:voice?)
275
+ end
276
+
277
+ def create_channel(name, reason = nil, type: :text, bitrate: nil, user_limit: nil, permissions: [], nsfw: false)
278
+ raise ArgumentError, 'Invalid channel type specified' unless CHANNEL_TYPES.has_key?(type)
279
+
280
+ permissions = permissions.map {|x| x.is_a(Overwrite) ? x.to_hash : x }
281
+ response = MijDiscord::Core::API::Server.create_channel(@bot.auth, @id,
282
+ name, CHANNEL_TYPES[type], bitrate, user_limit, permissions, nsfw, reason)
283
+ @cache.put_channel(JSON.parse(response))
284
+ end
285
+
286
+ def create_role(name, reason = nil, color: 0, hoist: false, mentionable: false, permissions: 104_324_161)
287
+ response = MijDiscord::Core::API::Server.create_role(@bot.auth, @id,
288
+ name, color.to_i, hoist, mentionable, permissions.to_i, reason)
289
+ @cache.put_role(JSON.parse(response))
290
+ end
291
+
292
+ def bans
293
+ response = MijDiscord::Core::API::Server.bans(@bot.auth, @id)
294
+ JSON.parse(response).map {|x| @bot.cache.put_user(x['user']) }
295
+ end
296
+
297
+ def ban(user, message_days = 0, reason = nil)
298
+ MijDiscord::Core::API::Server.ban_user(@bot.auth, @id, user.to_id, message_days, reason)
299
+ nil
300
+ end
301
+
302
+ def unban(user, reason = nil)
303
+ MijDiscord::Core::API::Server.unban_user(@bot.auth, @id, user.to_id, reason)
304
+ nil
305
+ end
306
+
307
+ def kick(user, reason = nil)
308
+ MijDiscord::Core::API::Server.remove_member(@bot.auth, @id, user.to_id, reason)
309
+ nil
310
+ end
311
+
312
+ def leave
313
+ MijDiscord::Core::API::User.leave_server(@bot.auth, @id)
314
+ nil
315
+ end
316
+
317
+ def delete
318
+ MijDiscord::Core::API::Server.delete(@bot.auth, @id)
319
+ nil
320
+ end
321
+
322
+ def set_owner(user, reason = nil)
323
+ MijDiscord::Core::API::Server.transfer_ownership(@bot.auth, @id, user.to_id, reason)
324
+ end
325
+
326
+ alias_method :owner=, :set_owner
327
+
328
+ def set_options(reason = nil, name: nil, region: nil, icon: nil, afk_channel: nil, afk_timeout: nil)
329
+ response = MijDiscord::Core::API::Server.update(@bot.auth, @id,
330
+ name, region, icon, afk_channel&.to_id, afk_timeout, reason)
331
+ @bot.cache.put_server(JSON.parse(response), update: true)
332
+ end
333
+
334
+ def set_name(name, reason = nil)
335
+ set_options(reason, name: name)
336
+ nil
337
+ end
338
+
339
+ alias_method :name=, :set_name
340
+
341
+ def available_regions
342
+ return @voice_regions if @voice_regions
343
+
344
+ response = MijDiscord::Core::API::Server.regions(@bot.auth, @id)
345
+ @voice_regions = JSON.parse(response).map {|x| VoiceRegion.new(x) }
346
+ end
347
+
348
+ def region
349
+ available_regions.find {|x| x.id == @region_id }
350
+ end
351
+
352
+ def set_region(region, reason = nil)
353
+ region = region.to_s
354
+ raise ArgumentError, 'Invalid region' unless available_regions.find {|x| x.id == region }
355
+
356
+ set_options(reason, region: region)
357
+ nil
358
+ end
359
+
360
+ alias_method :region=, :set_region
361
+
362
+ def set_icon(icon, reason = nil)
363
+ if icon.respond_to?(:read)
364
+ buffer = Base64.strict_encode64(icon.read)
365
+ icon = "data:image/jpg;base64,#{buffer}"
366
+ set_options(reason, icon: icon)
367
+ else
368
+ set_options(reason, icon: icon.to_s)
369
+ end
370
+ nil
371
+ end
372
+
373
+ alias_method :icon=, :set_icon
374
+
375
+ def set_afk_channel(channel, reason = nil)
376
+ set_options(reason, afk_channel: channel.to_id)
377
+ nil
378
+ end
379
+
380
+ alias_method :afk_channel=, :set_afk_channel
381
+
382
+ def set_afk_timeout(timeout, reason = nil)
383
+ set_options(reason, afk_timeout: timeout)
384
+ nil
385
+ end
386
+
387
+ alias_method :afk_timeout=, :set_afk_timeout
388
+
389
+ def icon_url(format = :png)
390
+ return nil unless @icon_id
391
+ MijDiscord::Core::API.icon_url(@id, @icon_id, format)
392
+ end
393
+
394
+ def embed_url(style = :shield)
395
+ return nil unless @embed_enabled
396
+ MijDiscord::Core::API.widget_url(@id, style)
397
+ end
398
+
399
+ def inspect
400
+ MijDiscord.make_inspect(self,
401
+ :id, :name, :owner, :member_count, :features, :embed_enabled, :verification_level,
402
+ :content_filter_level, :default_notifications, :afk_timeout, :afk_channel)
403
+ end
404
+ end
468
405
  end