/
CommandData.java
262 lines (241 loc) · 9.55 KB
/
CommandData.java
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
/*
* Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.dv8tion.jda.api.interactions.commands.build;
import net.dv8tion.jda.api.interactions.DiscordLocale;
import net.dv8tion.jda.api.interactions.commands.Command;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction;
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationMap;
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.api.utils.data.SerializableData;
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
import net.dv8tion.jda.internal.utils.Checks;
import net.dv8tion.jda.internal.utils.localization.LocalizationUtils;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Map;
/**
* Builder for Application Commands.
* <br>Use the factory methods provided by {@link Commands} to create instances of this interface.
*
* @see Commands
*/
public interface CommandData extends SerializableData
{
/**
* The maximum length the name of a command can be.
*/
int MAX_NAME_LENGTH = 32;
/**
* The maximum length the description of a command can be.
*/
int MAX_DESCRIPTION_LENGTH = 100;
/**
* Sets the {@link LocalizationFunction} for this command
* <br>This enables you to have the entirety of this command to be localized.
*
* @param localizationFunction
* The localization function
*
* @throws IllegalArgumentException
* If the localization function is null
*
* @return The builder instance, for chaining
*/
@Nonnull
CommandData setLocalizationFunction(@Nonnull LocalizationFunction localizationFunction);
/**
* Configure the command name.
*
* @param name
* The name, 1-32 characters (lowercase and alphanumeric for {@link Command.Type#SLASH})
*
* @throws IllegalArgumentException
* If the name is not between 1-32 characters long, or not lowercase and alphanumeric for slash commands
*
* @return The builder instance, for chaining
*/
@Nonnull
CommandData setName(@Nonnull String name);
/**
* Sets a {@link DiscordLocale language-specific} localization of this command's name.
*
* @param locale
* The locale to associate the translated name with
*
* @param name
* The translated name to put
*
* @throws IllegalArgumentException
* <ul>
* <li>If the locale is null</li>
* <li>If the name is null</li>
* <li>If the locale is {@link DiscordLocale#UNKNOWN}</li>
* <li>If the name does not pass the corresponding {@link #setName(String) name check}</li>
* </ul>
*
* @return This builder instance, for chaining
*/
@Nonnull
CommandData setNameLocalization(@Nonnull DiscordLocale locale, @Nonnull String name);
/**
* Sets multiple {@link DiscordLocale language-specific} localizations of this command's name.
*
* @param map
* The map from which to transfer the translated names
*
* @throws IllegalArgumentException
* <ul>
* <li>If the map is null</li>
* <li>If the map contains an {@link DiscordLocale#UNKNOWN} key</li>
* <li>If the map contains a name which does not pass the corresponding {@link #setName(String) name check}</li>
* </ul>
*
* @return This builder instance, for chaining
*/
@Nonnull
CommandData setNameLocalizations(@Nonnull Map<DiscordLocale, String> map);
/**
* Sets the {@link net.dv8tion.jda.api.Permission Permissions} that a user must have in a specific channel to be able to use this command.
* <br>By default, everyone can use this command ({@link DefaultMemberPermissions#ENABLED}). Additionally, a command can be disabled for everyone but admins via {@link DefaultMemberPermissions#DISABLED}.
* <p>These configurations can be overwritten by moderators in each guild. See {@link Command#retrievePrivileges(net.dv8tion.jda.api.entities.Guild)} to get moderator defined overrides.
*
* @param permission
* {@link DefaultMemberPermissions} representing the default permissions of this command.
*
* @return The builder instance, for chaining
*
* @see DefaultMemberPermissions#ENABLED
* @see DefaultMemberPermissions#DISABLED
*/
@Nonnull
CommandData setDefaultPermissions(@Nonnull DefaultMemberPermissions permission);
/**
* Sets whether this command is only usable in a guild (Default: false).
* <br>This only has an effect if this command is registered globally.
*
* @param guildOnly
* Whether to restrict this command to guilds
*
* @return The builder instance, for chaining
*/
@Nonnull
CommandData setGuildOnly(boolean guildOnly);
/**
* The current command name
*
* @return The command name
*/
@Nonnull
String getName();
/**
* The localizations of this command's name for {@link DiscordLocale various languages}.
*
* @return The {@link LocalizationMap} containing the mapping from {@link DiscordLocale} to the localized name
*/
@Nonnull
LocalizationMap getNameLocalizations();
/**
* The {@link Command.Type}
*
* @return The {@link Command.Type}
*/
@Nonnull
Command.Type getType();
/**
* Gets the {@link DefaultMemberPermissions} of this command.
* <br>If no permissions have been set, this returns {@link DefaultMemberPermissions#ENABLED}.
*
* @return DefaultMemberPermissions of this command.
*
* @see DefaultMemberPermissions#ENABLED
* @see DefaultMemberPermissions#DISABLED
*/
@Nonnull
DefaultMemberPermissions getDefaultPermissions();
/**
* Whether the command can only be used inside a guild.
* <br>Always true for guild commands.
*
* @return True, if this command is restricted to guilds.
*/
boolean isGuildOnly();
/**
* Converts the provided {@link Command} into a CommandData instance.
*
* @param command
* The command to convert
*
* @throws IllegalArgumentException
* If null is provided or the command has illegal configuration
*
* @return An instance of CommandData
*
* @see SlashCommandData#fromCommand(Command)
*/
@Nonnull
static CommandData fromCommand(@Nonnull Command command)
{
Checks.notNull(command, "Command");
if (command.getType() != Command.Type.SLASH)
{
final CommandDataImpl data = new CommandDataImpl(command.getType(), command.getName());
return data.setDefaultPermissions(command.getDefaultPermissions())
.setGuildOnly(command.isGuildOnly())
.setNameLocalizations(command.getNameLocalizations().toMap())
.setDescriptionLocalizations(command.getDescriptionLocalizations().toMap());
}
return SlashCommandData.fromCommand(command);
}
/**
* Parses the provided serialization back into an CommandData instance.
* <br>This is the reverse function for {@link CommandData#toData()}.
*
* @param object
* The serialized {@link DataObject} representing the command
*
* @throws net.dv8tion.jda.api.exceptions.ParsingException
* If the serialized object is missing required fields
* @throws IllegalArgumentException
* If any of the values are failing the respective checks such as length
*
* @return The parsed CommandData instance, which can be further configured through setters
*
* @see SlashCommandData#fromData(DataObject)
* @see Commands#fromList(Collection)
*/
@Nonnull
static CommandData fromData(@Nonnull DataObject object)
{
Checks.notNull(object, "DataObject");
String name = object.getString("name");
Command.Type commandType = Command.Type.fromId(object.getInt("type", 1));
if (commandType != Command.Type.SLASH)
{
CommandDataImpl data = new CommandDataImpl(commandType, name);
if (!object.isNull("default_member_permissions"))
{
long defaultPermissions = object.getLong("default_member_permissions");
data.setDefaultPermissions(defaultPermissions == 0 ? DefaultMemberPermissions.DISABLED : DefaultMemberPermissions.enabledFor(defaultPermissions));
}
data.setGuildOnly(!object.getBoolean("dm_permission", true));
data.setNameLocalizations(LocalizationUtils.mapFromProperty(object, "name_localizations"));
data.setDescriptionLocalizations(LocalizationUtils.mapFromProperty(object, "description_localizations"));
return data;
}
return SlashCommandData.fromData(object);
}
}