-
-
Notifications
You must be signed in to change notification settings - Fork 108
Expand file tree
/
Copy pathBotCommandAdapter.java
More file actions
166 lines (146 loc) · 6.99 KB
/
BotCommandAdapter.java
File metadata and controls
166 lines (146 loc) · 6.99 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
166
package org.togetherjava.tjbot.features;
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.EntitySelectInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import org.jetbrains.annotations.Contract;
import org.togetherjava.tjbot.features.componentids.ComponentIdGenerator;
import org.togetherjava.tjbot.features.componentids.ComponentIdInteractor;
import org.togetherjava.tjbot.features.componentids.Lifespan;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Adapter implementation of a {@link BotCommand}. The minimal setup only requires implementation of
* their respective command method. A new command can then be registered by adding it to
* {@link Features}.
* <p>
* Further, {@link #onButtonClick(ButtonInteractionEvent, List)},
* {@link #onEntitySelectSelection(EntitySelectInteractionEvent, List)} and
* {@link #onStringSelectSelection(StringSelectInteractionEvent, List)} can be overridden if
* desired. The default implementation is empty, the adapter will not react to such events.
* <p>
* The adapter manages some getters for you, you've to create the {@link CommandData} yourself. See
* {@link #BotCommandAdapter(CommandData, CommandVisibility)}} for more info on that. Minimal
* modifications can be done on the {@link CommandData} returned by {@link #getData()}.
* <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(SlashCommandInteractionEvent)}.
* <p>
* Some example commands are available in {@link org.togetherjava.tjbot.features.basic}.
* Registration of commands can be done in {@link Features}.
*/
public abstract class BotCommandAdapter implements BotCommand {
private final String name;
private final UserInteractionType interactionType;
private final CommandVisibility visibility;
private final CommandData data;
private final ComponentIdInteractor componentIdInteractor;
/**
* Creates a new adapter with the given data.
*
* @param data the data for this command
* @param visibility the visibility of the command
*/
protected BotCommandAdapter(CommandData data, CommandVisibility visibility) {
this.data = data;
Set<InteractionContextType> contexts = switch (visibility) {
case GUILD -> Set.of(InteractionContextType.GUILD);
case GLOBAL -> InteractionContextType.ALL;
};
data.setContexts(contexts);
this.visibility = Objects.requireNonNull(visibility, "The visibility shouldn't be null");
name = data.getName();
interactionType = commandTypeToInteractionType(data.getType());
componentIdInteractor = new ComponentIdInteractor(interactionType, name);
}
private static UserInteractionType commandTypeToInteractionType(Command.Type type) {
return switch (type) {
case SLASH -> UserInteractionType.SLASH_COMMAND;
case USER -> UserInteractionType.USER_CONTEXT_COMMAND;
case MESSAGE -> UserInteractionType.MESSAGE_CONTEXT_COMMAND;
case UNKNOWN -> throw new IllegalArgumentException(
"Can not infer the type of user interaction for this command, it is unknown.");
};
}
@Override
public final String getName() {
return name;
}
@Override
public final UserInteractionType getInteractionType() {
return interactionType;
}
@Override
public final CommandVisibility getVisibility() {
return visibility;
}
@Override
public CommandData getData() {
return data;
}
@Override
@Contract(mutates = "this")
public final void acceptComponentIdGenerator(ComponentIdGenerator generator) {
componentIdInteractor.acceptComponentIdGenerator(generator);
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onButtonClick(ButtonInteractionEvent event, List<String> args) {
// Adapter does not react by default, subclasses may change this behavior
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onEntitySelectSelection(EntitySelectInteractionEvent event, List<String> args) {
// Adapter does not react by default, subclasses may change this behavior
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onStringSelectSelection(StringSelectInteractionEvent event, List<String> args) {
// Adapter does not react by default, subclasses may change this behavior
}
@SuppressWarnings("NoopMethodInAbstractClass")
@Override
public void onModalSubmitted(ModalInteractionEvent event, 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 #acceptComponentIdGenerator(ComponentIdGenerator)}.
* <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 String generateComponentId(String... args) {
return componentIdInteractor.generateComponentId(args);
}
/**
* Helper method to generate component IDs that are considered valid per
* {@link #acceptComponentIdGenerator(ComponentIdGenerator)}.
* <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 String generateComponentId(Lifespan lifespan, String... args) {
return componentIdInteractor.generateComponentId(lifespan, args);
}
}