discorb 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +10 -0
  5. data/Rakefile +482 -454
  6. data/lib/discorb/allowed_mentions.rb +68 -72
  7. data/lib/discorb/app_command/command.rb +466 -398
  8. data/lib/discorb/app_command/common.rb +65 -25
  9. data/lib/discorb/app_command/handler.rb +304 -266
  10. data/lib/discorb/app_command.rb +5 -5
  11. data/lib/discorb/application.rb +198 -197
  12. data/lib/discorb/asset.rb +101 -101
  13. data/lib/discorb/attachment.rb +134 -119
  14. data/lib/discorb/audit_logs.rb +412 -385
  15. data/lib/discorb/automod.rb +279 -269
  16. data/lib/discorb/channel/base.rb +107 -108
  17. data/lib/discorb/channel/category.rb +32 -32
  18. data/lib/discorb/channel/container.rb +44 -44
  19. data/lib/discorb/channel/dm.rb +26 -28
  20. data/lib/discorb/channel/guild.rb +311 -246
  21. data/lib/discorb/channel/stage.rb +156 -140
  22. data/lib/discorb/channel/text.rb +430 -336
  23. data/lib/discorb/channel/thread.rb +374 -325
  24. data/lib/discorb/channel/voice.rb +85 -79
  25. data/lib/discorb/channel.rb +5 -5
  26. data/lib/discorb/client.rb +635 -621
  27. data/lib/discorb/color.rb +178 -182
  28. data/lib/discorb/common.rb +168 -164
  29. data/lib/discorb/components/button.rb +107 -106
  30. data/lib/discorb/components/select_menu.rb +157 -145
  31. data/lib/discorb/components/text_input.rb +103 -106
  32. data/lib/discorb/components.rb +68 -66
  33. data/lib/discorb/dictionary.rb +135 -135
  34. data/lib/discorb/embed.rb +404 -398
  35. data/lib/discorb/emoji.rb +309 -302
  36. data/lib/discorb/emoji_table.rb +16099 -8857
  37. data/lib/discorb/error.rb +131 -131
  38. data/lib/discorb/event.rb +360 -314
  39. data/lib/discorb/event_handler.rb +39 -39
  40. data/lib/discorb/exe/about.rb +17 -17
  41. data/lib/discorb/exe/irb.rb +72 -67
  42. data/lib/discorb/exe/new.rb +323 -315
  43. data/lib/discorb/exe/run.rb +69 -68
  44. data/lib/discorb/exe/setup.rb +57 -55
  45. data/lib/discorb/exe/show.rb +12 -12
  46. data/lib/discorb/extend.rb +25 -45
  47. data/lib/discorb/extension.rb +89 -83
  48. data/lib/discorb/flag.rb +126 -128
  49. data/lib/discorb/gateway.rb +984 -804
  50. data/lib/discorb/gateway_events.rb +670 -638
  51. data/lib/discorb/gateway_requests.rb +45 -48
  52. data/lib/discorb/guild.rb +2115 -1626
  53. data/lib/discorb/guild_template.rb +280 -241
  54. data/lib/discorb/http.rb +247 -232
  55. data/lib/discorb/image.rb +42 -42
  56. data/lib/discorb/integration.rb +169 -161
  57. data/lib/discorb/intents.rb +161 -163
  58. data/lib/discorb/interaction/autocomplete.rb +76 -62
  59. data/lib/discorb/interaction/command.rb +279 -224
  60. data/lib/discorb/interaction/components.rb +114 -104
  61. data/lib/discorb/interaction/modal.rb +36 -32
  62. data/lib/discorb/interaction/response.rb +379 -336
  63. data/lib/discorb/interaction/root.rb +271 -257
  64. data/lib/discorb/interaction.rb +5 -5
  65. data/lib/discorb/invite.rb +154 -153
  66. data/lib/discorb/member.rb +344 -311
  67. data/lib/discorb/message.rb +615 -544
  68. data/lib/discorb/message_meta.rb +197 -186
  69. data/lib/discorb/modules.rb +371 -290
  70. data/lib/discorb/permission.rb +305 -291
  71. data/lib/discorb/presence.rb +352 -346
  72. data/lib/discorb/rate_limit.rb +81 -76
  73. data/lib/discorb/reaction.rb +55 -54
  74. data/lib/discorb/role.rb +272 -240
  75. data/lib/discorb/shard.rb +76 -74
  76. data/lib/discorb/sticker.rb +193 -171
  77. data/lib/discorb/user.rb +205 -188
  78. data/lib/discorb/utils/colored_puts.rb +16 -16
  79. data/lib/discorb/utils.rb +12 -16
  80. data/lib/discorb/voice_state.rb +305 -281
  81. data/lib/discorb/webhook.rb +537 -507
  82. data/lib/discorb.rb +62 -56
  83. data/sig/discorb/application.rbs +2 -0
  84. data/sig/discorb/automod.rbs +10 -1
  85. data/sig/discorb/guild.rbs +2 -0
  86. data/sig/discorb/message.rbs +2 -0
  87. data/sig/discorb/user.rbs +22 -20
  88. metadata +2 -2
data/lib/discorb/role.rb CHANGED
@@ -1,240 +1,272 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a role in the guild.
6
- #
7
- class Role < DiscordModel
8
- # @return [Discorb::Snowflake] The ID of the role.
9
- attr_reader :id
10
- # @return [String] The name of the role.
11
- attr_reader :name
12
- # @return [Discorb::Color] The color of the role.
13
- attr_reader :color
14
- # @return [Discorb::Permission] The permissions of the role.
15
- attr_reader :permissions
16
- # @return [Integer] The position of the role.
17
- attr_reader :position
18
- # @return [Discorb::Guild] The guild this role belongs to.
19
- attr_reader :guild
20
- # @return [Boolean] Whether the role is hoisted.
21
- attr_reader :hoist
22
- alias hoist? hoist
23
- # @return [Boolean] Whether the role is managed.
24
- attr_reader :managed
25
- alias managed? managed
26
- # @return [Boolean] Whether the role is a default role.
27
- attr_reader :mentionable
28
- alias mentionable? mentionable
29
- # @return [Discorb::Asset, nil] The icon of the role.
30
- attr_reader :custom_icon
31
- # @return [Discorb::Emoji, nil] The emoji of the role.
32
- attr_reader :emoji
33
-
34
- # @!attribute [r] mention
35
- # @return [String] The mention of the role.
36
- # @!attribute [r] color?
37
- # @return [Boolean] Whether the role has a color.
38
- # @!attribute [r] tag
39
- # @return [Discorb::Role::Tag] The tag of the role.
40
- # @!attribute [r] icon
41
- # @return [Discorb::Asset, Discorb::Emoji] The icon of the role.
42
-
43
- include Comparable
44
-
45
- #
46
- # Initializes a new role.
47
- # @private
48
- #
49
- # @param [Discorb::Client] client The client.
50
- # @param [Discorb::Guild] guild The guild the role belongs to.
51
- # @param [Hash] data The data of the role.
52
- #
53
- def initialize(client, guild, data)
54
- @client = client
55
- @guild = guild
56
- @data = {}
57
- _set_data(data)
58
- end
59
-
60
- def icon
61
- @custom_icon || @emoji
62
- end
63
-
64
- #
65
- # Compares two roles by their position.
66
- #
67
- # @param [Discorb::Role] other The role to compare to.
68
- #
69
- # @return [Integer] -1 if the other role is higher, 0 if they are equal, 1 if the other role is lower.
70
- #
71
- def <=>(other)
72
- return nil unless other.is_a?(Role)
73
-
74
- @position <=> other.position
75
- end
76
-
77
- #
78
- # Formats the role as a string.
79
- #
80
- # @return [String] The formatted string.
81
- #
82
- def to_s
83
- "@#{@name}"
84
- end
85
-
86
- def mention
87
- "<@&#{@id}>"
88
- end
89
-
90
- def color?
91
- @color != 0
92
- end
93
-
94
- def inspect
95
- "#<#{self.class} @#{@name} id=#{@id}>"
96
- end
97
-
98
- #
99
- # Moves the role to a new position.
100
- # @async
101
- #
102
- # @param [Integer] position The new position.
103
- # @param [String] reason The reason for moving the role.
104
- #
105
- # @return [Async::Task<void>] The task.
106
- #
107
- def move(position, reason: nil)
108
- Async do
109
- @client.http.request(Route.new("/guilds/#{@guild.id}/roles", "//guilds/:guild_id/roles", :patch),
110
- { id: @id, position: position }, audit_log_reason: reason).wait
111
- end
112
- end
113
-
114
- #
115
- # Edits the role.
116
- # @async
117
- # @macro edit
118
- #
119
- # @param [String] name The new name of the role.
120
- # @param [Integer] position The new position of the role.
121
- # @param [Discorb::Color] color The new color of the role.
122
- # @param [Boolean] hoist Whether the role should be hoisted.
123
- # @param [Boolean] mentionable Whether the role should be mentionable.
124
- # @param [Discorb::Image, Discorb::UnicodeEmoji] icon The new icon or emoji of the role.
125
- # @param [String] reason The reason for editing the role.
126
- #
127
- # @return [Async::Task<void>] The task.
128
- #
129
- def edit(
130
- name: Discorb::Unset,
131
- position: Discorb::Unset,
132
- color: Discorb::Unset,
133
- hoist: Discorb::Unset,
134
- mentionable: Discorb::Unset,
135
- icon: Discorb::Unset,
136
- reason: nil
137
- )
138
- Async do
139
- payload = {}
140
- payload[:name] = name if name != Discorb::Unset
141
- payload[:position] = position if position != Discorb::Unset
142
- payload[:color] = color.to_i if color != Discorb::Unset
143
- payload[:hoist] = hoist if hoist != Discorb::Unset
144
- payload[:mentionable] = mentionable if mentionable != Discorb::Unset
145
- if icon != Discorb::Unset
146
- if icon.is_a?(Discorb::Image)
147
- payload[:icon] = icon.to_s
148
- else
149
- payload[:unicode_emoji] = icon.to_s
150
- end
151
- end
152
- @client.http.request(
153
- Route.new("/guilds/#{@guild.id}/roles/#{@id}", "//guilds/:guild_id/roles/:role_id",
154
- :patch), payload, audit_log_reason: reason,
155
- ).wait
156
- end
157
- end
158
-
159
- alias modify edit
160
-
161
- #
162
- # Deletes the role.
163
- #
164
- # @param [String] reason The reason for deleting the role.
165
- #
166
- # @return [Async::Task<void>] The task.
167
- #
168
- def delete(reason: nil)
169
- Async do
170
- @client.http.request(
171
- Route.new("/guilds/#{@guild.id}/roles/#{@id}", "//guilds/:guild_id/roles/:role_id",
172
- :delete), {}, audit_log_reason: reason,
173
- ).wait
174
- end
175
- end
176
-
177
- alias destroy delete
178
-
179
- def tag
180
- Tag.new(@tags)
181
- end
182
-
183
- alias tags tag
184
-
185
- #
186
- # Represents a tag of a role.
187
- #
188
- class Tag < DiscordModel
189
- # @return [Discorb::Snowflake] The ID of the bot that owns the role.
190
- attr_reader :bot_id
191
- # @return [Discorb::Snowflake] The ID of the integration.
192
- attr_reader :integration_id
193
- # @return [Boolean] Whether the tag is a premium subscriber role.
194
- attr_reader :premium_subscriber
195
- alias premium_subscriber? premium_subscriber
196
- # @!attribute [r] bot?
197
- # @return [Boolean] Whether the role is a bot role.
198
- # @!attribute [r] integration?
199
- # @return [Boolean] Whether the role is an integration role.
200
-
201
- #
202
- # Initializes a new tag.
203
- # @private
204
- #
205
- # @param [Hash] data The data of the tag.
206
- #
207
- def initialize(data)
208
- @bot_id = Snowflake.new(data[:bot_id])
209
- @integration_id = Snowflake.new(data[:integration_id])
210
- @premium_subscriber = data.key?(:premium_subscriber)
211
- end
212
-
213
- def bot?
214
- !@bot_id.nil?
215
- end
216
-
217
- def integration?
218
- !@integration_id.nil?
219
- end
220
- end
221
-
222
- private
223
-
224
- def _set_data(data)
225
- @id = Snowflake.new(data[:id])
226
- @name = data[:name]
227
- @color = Color.new(data[:color])
228
- @hoist = data[:hoist]
229
- @position = data[:position]
230
- @permissions = Permission.new(data[:permissions].to_i)
231
- @managed = data[:managed]
232
- @mentionable = data[:mentionable]
233
- @tags = data[:tags] || {}
234
- @custom_icon = data[:icon] ? Asset.new(self, data[:icon], path: "role-icons/#{@id}") : nil
235
- @emoji = data[:unicode_emoji] ? UnicodeEmoji.new(data[:unicode_emoji]) : nil
236
- @guild.roles[@id] = self unless data[:no_cache]
237
- @data.update(data)
238
- end
239
- end
240
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a role in the guild.
6
+ #
7
+ class Role < DiscordModel
8
+ # @return [Discorb::Snowflake] The ID of the role.
9
+ attr_reader :id
10
+ # @return [String] The name of the role.
11
+ attr_reader :name
12
+ # @return [Discorb::Color] The color of the role.
13
+ attr_reader :color
14
+ # @return [Discorb::Permission] The permissions of the role.
15
+ attr_reader :permissions
16
+ # @return [Integer] The position of the role.
17
+ attr_reader :position
18
+ # @return [Discorb::Guild] The guild this role belongs to.
19
+ attr_reader :guild
20
+ # @return [Boolean] Whether the role is hoisted.
21
+ attr_reader :hoist
22
+ alias hoist? hoist
23
+ # @return [Boolean] Whether the role is managed.
24
+ attr_reader :managed
25
+ alias managed? managed
26
+ # @return [Boolean] Whether the role is a default role.
27
+ attr_reader :mentionable
28
+ alias mentionable? mentionable
29
+ # @return [Discorb::Asset, nil] The icon of the role.
30
+ attr_reader :custom_icon
31
+ # @return [Discorb::Emoji, nil] The emoji of the role.
32
+ attr_reader :emoji
33
+
34
+ # @!attribute [r] mention
35
+ # @return [String] The mention of the role.
36
+ # @!attribute [r] color?
37
+ # @return [Boolean] Whether the role has a color.
38
+ # @!attribute [r] tag
39
+ # @return [Discorb::Role::Tag] The tag of the role.
40
+ # @!attribute [r] icon
41
+ # @return [Discorb::Asset, Discorb::Emoji] The icon of the role.
42
+
43
+ include Comparable
44
+
45
+ #
46
+ # Initializes a new role.
47
+ # @private
48
+ #
49
+ # @param [Discorb::Client] client The client.
50
+ # @param [Discorb::Guild] guild The guild the role belongs to.
51
+ # @param [Hash] data The data of the role.
52
+ #
53
+ def initialize(client, guild, data)
54
+ @client = client
55
+ @guild = guild
56
+ @data = {}
57
+ _set_data(data)
58
+ end
59
+
60
+ def icon
61
+ @custom_icon || @emoji
62
+ end
63
+
64
+ #
65
+ # Compares two roles by their position.
66
+ #
67
+ # @param [Discorb::Role] other The role to compare to.
68
+ #
69
+ # @return [Integer] -1 if the other role is higher, 0 if they are equal, 1 if the other role is lower.
70
+ #
71
+ def <=>(other)
72
+ return nil unless other.is_a?(Role)
73
+
74
+ @position <=> other.position
75
+ end
76
+
77
+ #
78
+ # Formats the role as a string.
79
+ #
80
+ # @return [String] The formatted string.
81
+ #
82
+ def to_s
83
+ "@#{@name}"
84
+ end
85
+
86
+ def mention
87
+ "<@&#{@id}>"
88
+ end
89
+
90
+ def color?
91
+ @color != 0
92
+ end
93
+
94
+ def inspect
95
+ "#<#{self.class} @#{@name} id=#{@id}>"
96
+ end
97
+
98
+ #
99
+ # Moves the role to a new position.
100
+ # @async
101
+ #
102
+ # @param [Integer] position The new position.
103
+ # @param [String] reason The reason for moving the role.
104
+ #
105
+ # @return [Async::Task<void>] The task.
106
+ #
107
+ def move(position, reason: nil)
108
+ Async do
109
+ @client
110
+ .http
111
+ .request(
112
+ Route.new(
113
+ "/guilds/#{@guild.id}/roles",
114
+ "//guilds/:guild_id/roles",
115
+ :patch
116
+ ),
117
+ { id: @id, position: position },
118
+ audit_log_reason: reason
119
+ )
120
+ .wait
121
+ end
122
+ end
123
+
124
+ #
125
+ # Edits the role.
126
+ # @async
127
+ # @macro edit
128
+ #
129
+ # @param [String] name The new name of the role.
130
+ # @param [Integer] position The new position of the role.
131
+ # @param [Discorb::Color] color The new color of the role.
132
+ # @param [Boolean] hoist Whether the role should be hoisted.
133
+ # @param [Boolean] mentionable Whether the role should be mentionable.
134
+ # @param [Discorb::Image, Discorb::UnicodeEmoji] icon The new icon or emoji of the role.
135
+ # @param [String] reason The reason for editing the role.
136
+ #
137
+ # @return [Async::Task<void>] The task.
138
+ #
139
+ def edit(
140
+ name: Discorb::Unset,
141
+ position: Discorb::Unset,
142
+ color: Discorb::Unset,
143
+ hoist: Discorb::Unset,
144
+ mentionable: Discorb::Unset,
145
+ icon: Discorb::Unset,
146
+ reason: nil
147
+ )
148
+ Async do
149
+ payload = {}
150
+ payload[:name] = name if name != Discorb::Unset
151
+ payload[:position] = position if position != Discorb::Unset
152
+ payload[:color] = color.to_i if color != Discorb::Unset
153
+ payload[:hoist] = hoist if hoist != Discorb::Unset
154
+ payload[:mentionable] = mentionable if mentionable != Discorb::Unset
155
+ if icon != Discorb::Unset
156
+ if icon.is_a?(Discorb::Image)
157
+ payload[:icon] = icon.to_s
158
+ else
159
+ payload[:unicode_emoji] = icon.to_s
160
+ end
161
+ end
162
+ @client
163
+ .http
164
+ .request(
165
+ Route.new(
166
+ "/guilds/#{@guild.id}/roles/#{@id}",
167
+ "//guilds/:guild_id/roles/:role_id",
168
+ :patch
169
+ ),
170
+ payload,
171
+ audit_log_reason: reason
172
+ )
173
+ .wait
174
+ end
175
+ end
176
+
177
+ alias modify edit
178
+
179
+ #
180
+ # Deletes the role.
181
+ #
182
+ # @param [String] reason The reason for deleting the role.
183
+ #
184
+ # @return [Async::Task<void>] The task.
185
+ #
186
+ def delete(reason: nil)
187
+ Async do
188
+ @client
189
+ .http
190
+ .request(
191
+ Route.new(
192
+ "/guilds/#{@guild.id}/roles/#{@id}",
193
+ "//guilds/:guild_id/roles/:role_id",
194
+ :delete
195
+ ),
196
+ {},
197
+ audit_log_reason: reason
198
+ )
199
+ .wait
200
+ end
201
+ end
202
+
203
+ alias destroy delete
204
+
205
+ def tag
206
+ Tag.new(@tags)
207
+ end
208
+
209
+ alias tags tag
210
+
211
+ #
212
+ # Represents a tag of a role.
213
+ #
214
+ class Tag < DiscordModel
215
+ # @return [Discorb::Snowflake] The ID of the bot that owns the role.
216
+ attr_reader :bot_id
217
+ # @return [Discorb::Snowflake] The ID of the integration.
218
+ attr_reader :integration_id
219
+ # @return [Boolean] Whether the tag is a premium subscriber role.
220
+ attr_reader :premium_subscriber
221
+ alias premium_subscriber? premium_subscriber
222
+ # @!attribute [r] bot?
223
+ # @return [Boolean] Whether the role is a bot role.
224
+ # @!attribute [r] integration?
225
+ # @return [Boolean] Whether the role is an integration role.
226
+
227
+ #
228
+ # Initializes a new tag.
229
+ # @private
230
+ #
231
+ # @param [Hash] data The data of the tag.
232
+ #
233
+ def initialize(data)
234
+ @bot_id = Snowflake.new(data[:bot_id])
235
+ @integration_id = Snowflake.new(data[:integration_id])
236
+ @premium_subscriber = data.key?(:premium_subscriber)
237
+ end
238
+
239
+ def bot?
240
+ !@bot_id.nil?
241
+ end
242
+
243
+ def integration?
244
+ !@integration_id.nil?
245
+ end
246
+ end
247
+
248
+ private
249
+
250
+ def _set_data(data)
251
+ @id = Snowflake.new(data[:id])
252
+ @name = data[:name]
253
+ @color = Color.new(data[:color])
254
+ @hoist = data[:hoist]
255
+ @position = data[:position]
256
+ @permissions = Permission.new(data[:permissions].to_i)
257
+ @managed = data[:managed]
258
+ @mentionable = data[:mentionable]
259
+ @tags = data[:tags] || {}
260
+ @custom_icon =
261
+ (
262
+ if data[:icon]
263
+ Asset.new(self, data[:icon], path: "role-icons/#{@id}")
264
+ end
265
+ )
266
+ @emoji =
267
+ data[:unicode_emoji] ? UnicodeEmoji.new(data[:unicode_emoji]) : nil
268
+ @guild.roles[@id] = self unless data[:no_cache]
269
+ @data.update(data)
270
+ end
271
+ end
272
+ end
data/lib/discorb/shard.rb CHANGED
@@ -1,74 +1,76 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a shard.
6
- #
7
- class Shard
8
- # @return [Integer] The ID of the shard.
9
- attr_reader :id
10
- # @return [Thread] The thread of the shard.
11
- attr_reader :thread
12
- # @return [Logger] The logger of the shard.
13
- attr_reader :logger
14
- # @private
15
- # @return [Integer] The internal index of the shard.
16
- attr_reader :index
17
- # @private
18
- attr_accessor :status, :connection, :session_id, :next_shard, :main_task
19
-
20
- #
21
- # Initializes a new shard.
22
- # @private
23
- #
24
- # @param [Discorb::Client] client The client.
25
- # @param [Integer] id The ID of the shard.
26
- # @param [Integer] count The number of shards.
27
- # @param [Integer] index The index of the shard.
28
- #
29
- def initialize(client, id, count, index)
30
- @client = client
31
- @id = id
32
- @shard_count = count
33
- @status = :idle
34
- @index = index
35
- @session_id = nil
36
- @next_shard = nil
37
- @main_task = nil
38
- @logger = client.logger.dup.tap { |l| l.progname = "discorb: shard #{id}" }
39
- @thread = Thread.new do
40
- Thread.current.thread_variable_set("shard_id", id)
41
- Thread.current.thread_variable_set("shard", self)
42
- if @index.positive?
43
- Thread.stop
44
- sleep 5 # Somehow discord disconnects the shard without a little sleep.
45
- end
46
- client.send(:main_loop, id)
47
- end
48
- end
49
-
50
- #
51
- # Starts the shard.
52
- #
53
- # @return [void]
54
- #
55
- def start
56
- @thread.wakeup
57
- end
58
-
59
- #
60
- # Stops the shard.
61
- #
62
- # @return [void]
63
- #
64
- def close
65
- @status = :closed
66
- @main_task&.stop
67
- @thread.kill
68
- end
69
-
70
- def inspect
71
- "#<#{self.class} #{id}/#{@shard_count} #{@status}>"
72
- end
73
- end
74
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a shard.
6
+ #
7
+ class Shard
8
+ # @return [Integer] The ID of the shard.
9
+ attr_reader :id
10
+ # @return [Thread] The thread of the shard.
11
+ attr_reader :thread
12
+ # @return [Logger] The logger of the shard.
13
+ attr_reader :logger
14
+ # @private
15
+ # @return [Integer] The internal index of the shard.
16
+ attr_reader :index
17
+ # @private
18
+ attr_accessor :status, :connection, :session_id, :next_shard, :main_task
19
+
20
+ #
21
+ # Initializes a new shard.
22
+ # @private
23
+ #
24
+ # @param [Discorb::Client] client The client.
25
+ # @param [Integer] id The ID of the shard.
26
+ # @param [Integer] count The number of shards.
27
+ # @param [Integer] index The index of the shard.
28
+ #
29
+ def initialize(client, id, count, index)
30
+ @client = client
31
+ @id = id
32
+ @shard_count = count
33
+ @status = :idle
34
+ @index = index
35
+ @session_id = nil
36
+ @next_shard = nil
37
+ @main_task = nil
38
+ @logger =
39
+ client.logger.dup.tap { |l| l.progname = "discorb: shard #{id}" }
40
+ @thread =
41
+ Thread.new do
42
+ Thread.current.thread_variable_set("shard_id", id)
43
+ Thread.current.thread_variable_set("shard", self)
44
+ if @index.positive?
45
+ Thread.stop
46
+ sleep 5 # Somehow discord disconnects the shard without a little sleep.
47
+ end
48
+ client.send(:main_loop, id)
49
+ end
50
+ end
51
+
52
+ #
53
+ # Starts the shard.
54
+ #
55
+ # @return [void]
56
+ #
57
+ def start
58
+ @thread.wakeup
59
+ end
60
+
61
+ #
62
+ # Stops the shard.
63
+ #
64
+ # @return [void]
65
+ #
66
+ def close
67
+ @status = :closed
68
+ @main_task&.stop
69
+ @thread.kill
70
+ end
71
+
72
+ def inspect
73
+ "#<#{self.class} #{id}/#{@shard_count} #{@status}>"
74
+ end
75
+ end
76
+ end