-
-
Notifications
You must be signed in to change notification settings - Fork 109
Expand file tree
/
Copy pathSlashCommandAdapter.java
More file actions
165 lines (150 loc) · 6.52 KB
/
SlashCommandAdapter.java
File metadata and controls
165 lines (150 loc) · 6.52 KB
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
package org.togetherjava.tjbot.commands;
import net.dv8tion.jda.api.events.ReadyEvent;
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
import net.dv8tion.jda.api.events.interaction.SelectionMenuEvent;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import org.jetbrains.annotations.NotNull;
import org.togetherjava.tjbot.commands.componentids.ComponentId;
import org.togetherjava.tjbot.commands.componentids.ComponentIdGenerator;
import org.togetherjava.tjbot.commands.componentids.Lifespan;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
/**
* Adapter implementation of a {@link SlashCommand}. The minimal setup only requires implementation
* of {@link #onSlashCommand(SlashCommandEvent)}. A new command can then be registered by adding it
* to {@link Commands}.
* <p>
* Further, {@link #onButtonClick(ButtonClickEvent, List)} and
* {@link #onSelectionMenu(SelectionMenuEvent, List)} can be overridden if desired. The default
* implementation is empty, the adapter will not react to such events.
* <p>
* <p>
* The adapter manages all command related data itself, which can be provided during construction
* (see {@link #SlashCommandAdapter(String, String, SlashCommandVisibility)}). In order to add
* options, subcommands or similar command configurations, use {@link #getData()} and mutate the
* returned data object (see {@link CommandData} for details on how to work with this class).
* <p>
* <p>
* If implementations want to add buttons or selection menus, it is highly advised to use component
* IDs generated by {@link #generateComponentId(String...)}, which will automatically create IDs
* that are valid per {@link SlashCommand#onSlashCommand(SlashCommandEvent)}.
* <p>
* <p>
* Some example commands are available in {@link org.togetherjava.tjbot.commands.basic}. A minimal
* setup would consist of a class like
*
* <pre>
* {
* @code
* public class PingCommand extends SlashCommandAdapter {
* public PingCommand() {
* super("ping", "Responds with 'Pong!'", SlashCommandVisibility.GUILD);
* }
*
* @Override
* public void onSlashCommand(@NotNull SlashCommandEvent event) {
* event.reply("Pong!").queue();
* }
* }
* }
* </pre>
* <p>
* and registration of an instance of that class in {@link Commands}.
*/
public abstract class SlashCommandAdapter extends ListenerAdapter implements SlashCommand {
private final String name;
private final String description;
private final SlashCommandVisibility visibility;
private final CommandData data;
private ComponentIdGenerator componentIdGenerator;
/**
* Creates a new adapter with the given data.
*
* @param name the name of this command, requirements for this are documented in
* {@link CommandData#CommandData(String, String)}
* @param description the description of this command, requirements for this are documented in
* {@link CommandData#CommandData(String, String)}
* @param visibility the visibility of the command
*/
protected SlashCommandAdapter(@NotNull String name, @NotNull String description,
SlashCommandVisibility visibility) {
this.name = name;
this.description = description;
this.visibility = visibility;
data = new CommandData(name, description);
}
@Override
public final @NotNull String getName() {
return name;
}
@Override
public final @NotNull String getDescription() {
return description;
}
@Override
public final @NotNull SlashCommandVisibility getVisibility() {
return visibility;
}
@Override
public final @NotNull CommandData getData() {
return data;
}
@Override
public final void acceptComponentIdGenerator(@NotNull ComponentIdGenerator generator) {
componentIdGenerator = generator;
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onReady(@NotNull ReadyEvent event) {
// Adapter does not react by default, subclasses may change this behavior
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onButtonClick(@NotNull ButtonClickEvent event, @NotNull List<String> args) {
// Adapter does not react by default, subclasses may change this behavior
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onSelectionMenu(@NotNull SelectionMenuEvent event, @NotNull List<String> args) {
// Adapter does not react by default, subclasses may change this behavior
}
/**
* Helper method to generate component IDs that are considered valid per
* {@link SlashCommand#onSlashCommand(SlashCommandEvent)}.
* <p>
* They can be used to create buttons or selection menus and transport additional data
* throughout the event (e.g. the user id who created the button dialog).
* <p>
* IDs generated by this method have a regular lifespan, meaning that they might get evicted and
* expire after not being used for a long time. Use
* {@link #generateComponentId(Lifespan, String...)} to set other lifespans, if desired.
*
* @param args the extra arguments that should be part of the ID
* @return the generated component ID
*/
@SuppressWarnings("OverloadedVarargsMethod")
protected final @NotNull String generateComponentId(@NotNull String... args) {
return generateComponentId(Lifespan.REGULAR, args);
}
/**
* Helper method to generate component IDs that are considered valid per
* {@link SlashCommand#onSlashCommand(SlashCommandEvent)}.
* <p>
* They can be used to create buttons or selection menus and transport additional data
* throughout the event (e.g. the user id who created the button dialog).
*
* @param lifespan the lifespan of the component id, controls when an id that was not used for a
* long time might be evicted and expire
* @param args the extra arguments that should be part of the ID
* @return the generated component ID
*/
@SuppressWarnings({"OverloadedVarargsMethod", "WeakerAccess"})
protected final @NotNull String generateComponentId(@NotNull Lifespan lifespan,
@NotNull String... args) {
return Objects.requireNonNull(componentIdGenerator)
.generate(new ComponentId(getName(), Arrays.asList(args)), lifespan);
}
}