-
-
Notifications
You must be signed in to change notification settings - Fork 739
/
Copy pathModuleBuilder.cs
431 lines (386 loc) · 16.3 KB
/
ModuleBuilder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Discord.Interactions.Builders
{
/// <summary>
/// Represents a builder for creating <see cref="ModuleInfo"/>.
/// </summary>
public class ModuleBuilder
{
private readonly List<Attribute> _attributes;
private readonly List<PreconditionAttribute> _preconditions;
private readonly List<ModuleBuilder> _subModules;
private readonly List<SlashCommandBuilder> _slashCommands;
private readonly List<ContextCommandBuilder> _contextCommands;
private readonly List<ComponentCommandBuilder> _componentCommands;
private readonly List<AutocompleteCommandBuilder> _autocompleteCommands;
private readonly List<ModalCommandBuilder> _modalCommands;
/// <summary>
/// Gets the underlying Interaction Service.
/// </summary>
public InteractionService InteractionService { get; }
/// <summary>
/// Gets the parent module if this module is a sub-module.
/// </summary>
public ModuleBuilder Parent { get; }
/// <summary>
/// Gets the name of this module.
/// </summary>
public string Name { get; internal set; }
/// <summary>
/// Gets and sets the group name of this module.
/// </summary>
public string SlashGroupName { get; set; }
/// <summary>
/// Gets whether this has a <see cref="GroupAttribute"/>.
/// </summary>
public bool IsSlashGroup => !string.IsNullOrEmpty(SlashGroupName);
/// <summary>
/// Gets and sets the description of this module.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Gets and sets the default permission of this module.
/// </summary>
[Obsolete($"To be deprecated soon, use {nameof(IsEnabledInDm)} and {nameof(DefaultMemberPermissions)} instead.")]
public bool DefaultPermission { get; set; } = true;
/// <summary>
/// Gets whether this command can be used in DMs.
/// </summary>
public bool IsEnabledInDm { get; set; } = true;
/// <summary>
/// Gets whether this command is age restricted.
/// </summary>
public bool IsNsfw { get; set; } = false;
/// <summary>
/// Gets the default permissions needed for executing this command.
/// </summary>
public GuildPermission? DefaultMemberPermissions { get; set; } = null;
/// <summary>
/// Gets and sets whether this has a <see cref="DontAutoRegisterAttribute"/>.
/// </summary>
public bool DontAutoRegister { get; set; } = false;
/// <summary>
/// Gets a collection of the attributes of this module.
/// </summary>
public IReadOnlyList<Attribute> Attributes => _attributes;
/// <summary>
/// Gets a collection of the preconditions of this module.
/// </summary>
public IReadOnlyCollection<PreconditionAttribute> Preconditions => _preconditions;
/// <summary>
/// Gets a collection of the sub-modules of this module.
/// </summary>
public IReadOnlyList<ModuleBuilder> SubModules => _subModules;
/// <summary>
/// Gets a collection of the Slash Commands of this module.
/// </summary>
public IReadOnlyList<SlashCommandBuilder> SlashCommands => _slashCommands;
/// <summary>
/// Gets a collection of the Context Commands of this module.
/// </summary>
public IReadOnlyList<ContextCommandBuilder> ContextCommands => _contextCommands;
/// <summary>
/// Gets a collection of the Component Commands of this module.
/// </summary>
public IReadOnlyList<ComponentCommandBuilder> ComponentCommands => _componentCommands;
/// <summary>
/// Gets a collection of the Autocomplete Commands of this module.
/// </summary>
public IReadOnlyList<AutocompleteCommandBuilder> AutocompleteCommands => _autocompleteCommands;
/// <summary>
/// Gets a collection of the Modal Commands of this module.
/// </summary>
public IReadOnlyList<ModalCommandBuilder> ModalCommands => _modalCommands;
internal TypeInfo TypeInfo { get; set; }
internal ModuleBuilder(InteractionService interactionService, ModuleBuilder parent = null)
{
InteractionService = interactionService;
Parent = parent;
_attributes = new List<Attribute>();
_subModules = new List<ModuleBuilder>();
_slashCommands = new List<SlashCommandBuilder>();
_contextCommands = new List<ContextCommandBuilder>();
_componentCommands = new List<ComponentCommandBuilder>();
_autocompleteCommands = new List<AutocompleteCommandBuilder>();
_modalCommands = new List<ModalCommandBuilder>();
_preconditions = new List<PreconditionAttribute>();
}
/// <summary>
/// Initializes a new <see cref="ModuleBuilder"/>.
/// </summary>
/// <param name="interactionService">The underlying Interaction Service.</param>
/// <param name="name">Name of this module.</param>
/// <param name="parent">Parent module of this sub-module.</param>
public ModuleBuilder(InteractionService interactionService, string name, ModuleBuilder parent = null) : this(interactionService, parent)
{
Name = name;
}
/// <summary>
/// Sets <see cref="SlashGroupName"/>.
/// </summary>
/// <param name="name">New value of the <see cref="SlashGroupName"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder WithGroupName(string name)
{
SlashGroupName = name;
return this;
}
/// <summary>
/// Sets <see cref="Description"/>.
/// </summary>
/// <param name="description">New value of the <see cref="Description"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder WithDescription(string description)
{
Description = description;
return this;
}
/// <summary>
/// Sets <see cref="DefaultPermission"/>.
/// </summary>
/// <param name="permission">New value of the <see cref="DefaultPermission"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
[Obsolete($"To be deprecated soon, use {nameof(SetEnabledInDm)} and {nameof(WithDefaultMemberPermissions)} instead.")]
public ModuleBuilder WithDefaultPermission(bool permission)
{
DefaultPermission = permission;
return this;
}
/// <summary>
/// Sets <see cref="IsEnabledInDm"/>.
/// </summary>
/// <param name="isEnabled">New value of the <see cref="IsEnabledInDm"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder SetEnabledInDm(bool isEnabled)
{
IsEnabledInDm = isEnabled;
return this;
}
/// <summary>
/// Sets <see cref="IsNsfw"/>.
/// </summary>
/// <param name="isNsfw">New value of the <see cref="IsNsfw"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder SetNsfw(bool isNsfw)
{
IsNsfw = isNsfw;
return this;
}
/// <summary>
/// Sets <see cref="DefaultMemberPermissions"/>.
/// </summary>
/// <param name="permissions">New value of the <see cref="DefaultMemberPermissions"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder WithDefaultMemberPermissions(GuildPermission permissions)
{
DefaultMemberPermissions = permissions;
return this;
}
/// <summary>
/// Adds attributes to <see cref="Attributes"/>.
/// </summary>
/// <param name="attributes">New attributes to be added to <see cref="Attributes"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddAttributes(params Attribute[] attributes)
{
_attributes.AddRange(attributes);
return this;
}
/// <summary>
/// Adds preconditions to <see cref="Preconditions"/>.
/// </summary>
/// <param name="preconditions">New preconditions to be added to <see cref="Preconditions"/>.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddPreconditions(params PreconditionAttribute[] preconditions)
{
_preconditions.AddRange(preconditions);
return this;
}
/// <summary>
/// Adds slash command builder to <see cref="SlashCommands"/>.
/// </summary>
/// <param name="configure"><see cref="SlashCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddSlashCommand(Action<SlashCommandBuilder> configure)
{
var command = new SlashCommandBuilder(this);
configure(command);
_slashCommands.Add(command);
return this;
}
/// <summary>
/// Adds slash command builder to <see cref="SlashCommands"/>.
/// </summary>
/// <param name="name">Name of the command.</param>
/// <param name="callback">Command callback to be executed.</param>
/// <param name="configure"><see cref="SlashCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddSlashCommand(string name, ExecuteCallback callback, Action<SlashCommandBuilder> configure)
{
var command = new SlashCommandBuilder(this, name, callback);
configure(command);
_slashCommands.Add(command);
return this;
}
/// <summary>
/// Adds context command builder to <see cref="ContextCommands"/>.
/// </summary>
/// <param name="configure"><see cref="ContextCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddContextCommand(Action<ContextCommandBuilder> configure)
{
var command = new ContextCommandBuilder(this);
configure(command);
_contextCommands.Add(command);
return this;
}
/// <summary>
/// Adds context command builder to <see cref="ContextCommands"/>.
/// </summary>
/// <param name="name">Name of the command.</param>
/// <param name="callback">Command callback to be executed.</param>
/// <param name="configure"><see cref="ContextCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddContextCommand(string name, ExecuteCallback callback, Action<ContextCommandBuilder> configure)
{
var command = new ContextCommandBuilder(this, name, callback);
configure(command);
_contextCommands.Add(command);
return this;
}
/// <summary>
/// Adds component command builder to <see cref="ComponentCommands"/>.
/// </summary>
/// <param name="configure"><see cref="ComponentCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddComponentCommand(Action<ComponentCommandBuilder> configure)
{
var command = new ComponentCommandBuilder(this);
configure(command);
_componentCommands.Add(command);
return this;
}
/// <summary>
/// Adds component command builder to <see cref="ComponentCommands"/>.
/// </summary>
/// <param name="name">Name of the command.</param>
/// <param name="callback">Command callback to be executed.</param>
/// <param name="configure"><see cref="ComponentCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddComponentCommand(string name, ExecuteCallback callback, Action<ComponentCommandBuilder> configure)
{
var command = new ComponentCommandBuilder(this, name, callback);
configure(command);
_componentCommands.Add(command);
return this;
}
/// <summary>
/// Adds autocomplete command builder to <see cref="AutocompleteCommands"/>.
/// </summary>
/// <param name="configure"><see cref="AutocompleteCommands"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddAutocompleteCommand(Action<AutocompleteCommandBuilder> configure)
{
var command = new AutocompleteCommandBuilder(this);
configure(command);
_autocompleteCommands.Add(command);
return this;
}
/// <summary>
/// Adds autocomplete command builder to <see cref="AutocompleteCommands"/>.
/// </summary>
/// <param name="name">Name of the command.</param>
/// <param name="callback">Command callback to be executed.</param>
/// <param name="configure"><see cref="AutocompleteCommandBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddAutocompleteCommand(string name, ExecuteCallback callback, Action<AutocompleteCommandBuilder> configure)
{
var command = new AutocompleteCommandBuilder(this, name, callback);
configure(command);
_autocompleteCommands.Add(command);
return this;
}
/// <summary>
/// Adds a modal command builder to <see cref="ModalCommands"/>.
/// </summary>
/// <param name="configure"><see cref="ModalCommands"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddModalCommand(Action<ModalCommandBuilder> configure)
{
var command = new ModalCommandBuilder(this);
configure(command);
_modalCommands.Add(command);
return this;
}
/// <summary>
/// Adds sub-module builder to <see cref="SubModules"/>.
/// </summary>
/// <param name="configure"><see cref="ModuleBuilder"/> factory.</param>
/// <returns>
/// The builder instance.
/// </returns>
public ModuleBuilder AddModule(Action<ModuleBuilder> configure)
{
var subModule = new ModuleBuilder(InteractionService, this);
configure(subModule);
_subModules.Add(subModule);
return this;
}
internal ModuleInfo Build(InteractionService interactionService, IServiceProvider services, ModuleInfo parent = null)
{
if (TypeInfo is not null && ModuleClassBuilder.IsValidModuleDefinition(TypeInfo))
{
var instance = ReflectionUtils<IInteractionModuleBase>.CreateObject(TypeInfo, interactionService, services);
try
{
instance.Construct(this, interactionService);
var moduleInfo = new ModuleInfo(this, interactionService, services, parent);
instance.OnModuleBuilding(interactionService, moduleInfo);
return moduleInfo;
}
finally
{
(instance as IDisposable)?.Dispose();
}
}
else
return new(this, interactionService, services, parent);
}
}
}