Skip to content

Commit e2db7ab

Browse files
authored
Merge pull request #15 from S3nS3IW00/dev
Update to v4.2.0
2 parents 5bc7b9d + 152fde6 commit e2db7ab

File tree

19 files changed

+690
-215
lines changed

19 files changed

+690
-215
lines changed

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# JCommands [![](https://img.shields.io/badge/Version-4.1.1-blue)](https://github.com/S3nS3IW00/JCommands) [![](https://img.shields.io/badge/Javadoc-Latest-green)](https://s3ns3iw00.github.io/JCommands/javadoc/) [![](https://img.shields.io/badge/Javacord-3.4.0-red)](https://github.com/Javacord/Javacord)
1+
# JCommands [![](https://img.shields.io/badge/Version-4.2.0-blue)](https://github.com/S3nS3IW00/JCommands) [![](https://img.shields.io/badge/Javadoc-Latest-green)](https://s3ns3iw00.github.io/JCommands/javadoc/) [![](https://img.shields.io/badge/Javacord-3.4.0-red)](https://github.com/Javacord/Javacord)
22

33
With this Javacord extension you can create Slash commands within 1 minute with built-in validating, converting,
4-
concatenating and extended permission checking for channels and categories. There are so many useful pre-written
5-
argument types that can be used while creating a command.
4+
concatenating, argument autocompleting and extended permission checking for channels and categories. There are so many
5+
useful pre-written argument types that can be used while creating a command.
66

77
### Example command
88

@@ -41,5 +41,10 @@ bots with it.
4141
```java
4242
CommandHandler.setApi(DiscordApi);
4343
```
44-
3. Create an error listener and as many command as you want.
45-
4. Enjoy!
44+
3. Give a star if you like it and enjoy!
45+
46+
## Contact
47+
48+
If you found a bug, or you just want a new feature in the next version, don't hesitate to report it on
49+
the [issues](https://github.com/S3nS3IW00/JCommands/issues) page. You can contact me through
50+
discord: [🆂🅴🅽🆂🅴🆈#0054](https://discord.com/users/249674530077802496)

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ plugins {
33
}
44

55
group 'me.s3ns3iw00'
6-
version '4.1.1'
6+
version '4.2.0'
77

88
repositories {
99
mavenCentral()

src/main/java/me/s3ns3iw00/jcommands/Command.java

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import me.s3ns3iw00.jcommands.argument.concatenation.Concatenator;
2424
import me.s3ns3iw00.jcommands.event.listener.ArgumentMismatchEventListener;
2525
import me.s3ns3iw00.jcommands.event.listener.CommandActionEventListener;
26-
import me.s3ns3iw00.jcommands.listener.CommandActionListener;
2726

2827
import java.util.*;
2928

@@ -108,17 +107,6 @@ public void addConcatenator(Concatenator concatenator, Argument... arguments) {
108107
concatenators.get(concatenator).addAll(Arrays.asList(arguments));
109108
}
110109

111-
/**
112-
* Sets the action listener of the command
113-
*
114-
* @param action is the listener object
115-
* @deprecated because of the new event system
116-
* use {@link Command#setOnAction(CommandActionEventListener)} instead
117-
*/
118-
@Deprecated
119-
public void setAction(CommandActionListener action) {
120-
}
121-
122110
/**
123111
* Sets the action listener
124112
*
@@ -156,15 +144,6 @@ public Map<Concatenator, LinkedList<Argument>> getConcatenators() {
156144
return concatenators;
157145
}
158146

159-
/**
160-
* @return the command action instance
161-
* @deprecated because of the new event system
162-
*/
163-
@Deprecated
164-
Optional<CommandActionEventListener> getAction() {
165-
return Optional.empty();
166-
}
167-
168147
/**
169148
* Gets the action listener
170149
*

src/main/java/me/s3ns3iw00/jcommands/CommandHandler.java

Lines changed: 106 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@
2222
import me.s3ns3iw00.jcommands.argument.ArgumentResult;
2323
import me.s3ns3iw00.jcommands.argument.InputArgument;
2424
import me.s3ns3iw00.jcommands.argument.SubArgument;
25+
import me.s3ns3iw00.jcommands.argument.ability.Autocompletable;
26+
import me.s3ns3iw00.jcommands.argument.autocomplete.AutocompleteState;
2527
import me.s3ns3iw00.jcommands.argument.concatenation.Concatenator;
2628
import me.s3ns3iw00.jcommands.argument.converter.ArgumentResultConverter;
2729
import me.s3ns3iw00.jcommands.argument.converter.type.URLConverter;
30+
import me.s3ns3iw00.jcommands.argument.type.ComboArgument;
31+
import me.s3ns3iw00.jcommands.argument.util.Choice;
2832
import me.s3ns3iw00.jcommands.builder.CommandBuilder;
29-
import me.s3ns3iw00.jcommands.event.listener.ArgumentMismatchEventListener;
30-
import me.s3ns3iw00.jcommands.event.listener.BadCategoryEventListener;
31-
import me.s3ns3iw00.jcommands.event.listener.BadChannelEventListener;
3233
import me.s3ns3iw00.jcommands.event.type.ArgumentMismatchEvent;
3334
import me.s3ns3iw00.jcommands.event.type.BadCategoryEvent;
3435
import me.s3ns3iw00.jcommands.event.type.BadChannelEvent;
@@ -38,7 +39,6 @@
3839
import me.s3ns3iw00.jcommands.limitation.type.ChannelLimitable;
3940
import me.s3ns3iw00.jcommands.limitation.type.RoleLimitable;
4041
import me.s3ns3iw00.jcommands.limitation.type.UserLimitable;
41-
import me.s3ns3iw00.jcommands.listener.CommandErrorListener;
4242
import org.javacord.api.DiscordApi;
4343
import org.javacord.api.entity.channel.ChannelCategory;
4444
import org.javacord.api.entity.channel.ChannelType;
@@ -81,6 +81,7 @@ public class CommandHandler {
8181
public static void setApi(DiscordApi api) {
8282
CommandHandler.api = api;
8383
api.addSlashCommandCreateListener(event -> handleCommand(event.getSlashCommandInteraction()));
84+
api.addAutocompleteCreateListener(event -> handleAutocomplete(event.getAutocompleteInteraction()));
8485
}
8586

8687
/**
@@ -186,6 +187,62 @@ private static void handleCommand(SlashCommandInteraction interaction) {
186187
});
187188
}
188189

190+
/**
191+
* Handles autocomplete requests for arguments
192+
*
193+
* @param interaction the interaction
194+
*/
195+
private static void handleAutocomplete(AutocompleteInteraction interaction) {
196+
Optional<Command> commandOptional = commands.stream()
197+
.filter(c -> c.getName().equalsIgnoreCase(interaction.getCommandName()))
198+
.findFirst();
199+
200+
commandOptional.ifPresent(command -> {
201+
SlashCommandInteractionOption option = interaction.getFocusedOption();
202+
203+
User sender = interaction.getUser();
204+
Optional<TextChannel> channel = interaction.getChannel();
205+
List<Argument> allArguments = collectArguments(command.getArguments());
206+
Optional<Argument> argumentOptional = allArguments.stream()
207+
.filter(arg -> arg.getName().equalsIgnoreCase(option.getName()))
208+
.findFirst();
209+
argumentOptional.ifPresent(argument -> {
210+
if (argument instanceof Autocompletable) {
211+
Autocompletable autocompletable = (Autocompletable) argument;
212+
AutocompleteState autocompleteState = new AutocompleteState(
213+
command,
214+
channel.orElse(null),
215+
sender,
216+
argument,
217+
getOptionValue(option, argument.getType()),
218+
interaction.getArguments().stream()
219+
.collect(Collectors.toMap(
220+
key -> allArguments.stream()
221+
.filter(arg -> arg.getName().equalsIgnoreCase(key.getName()))
222+
.findFirst().orElse(null),
223+
value -> value
224+
))
225+
.entrySet().stream()
226+
.collect(Collectors.toMap(
227+
Map.Entry::getKey,
228+
value -> getOptionValue(value.getValue(), value.getKey().getType())
229+
)));
230+
231+
/* Collect results from autocompletes and construct the list */
232+
List<Choice> choices = autocompletable.getAutocompletes().stream()
233+
.map(autocomplete -> autocomplete.getResult(autocompleteState))
234+
.filter(Objects::nonNull)
235+
.flatMap(List::stream)
236+
.collect(Collectors.toList());
237+
238+
if (choices.size() > 0) {
239+
interaction.respondWithChoices(choices.stream().map(Choice::getChoice).collect(Collectors.toList()));
240+
}
241+
}
242+
});
243+
});
244+
}
245+
189246
/**
190247
* Processes arguments and every argument of the arguments recursively:
191248
* - Adjusts values to the arguments
@@ -221,6 +278,14 @@ private static Optional<Map<Argument, ArgumentResult>> processArguments(SlashCom
221278
} else {
222279
return Optional.empty();
223280
}
281+
} else if (argument instanceof ComboArgument) {
282+
/* Choose the value that the user picked
283+
Checking is unnecessary since the user only can pick a valid value
284+
*/
285+
ComboArgument ca = (ComboArgument) argument;
286+
287+
ca.choose(value);
288+
results.put(argument, new ArgumentResult(ca));
224289
} else if (argument instanceof InputArgument) {
225290
/* Adjusts the value to the argument and checks that the value is null
226291
If it is not then it will be added to the list,
@@ -273,6 +338,9 @@ private static Object getOptionValue(SlashCommandInteractionOption option, Slash
273338
case LONG:
274339
value = option.getLongValue().orElse(null);
275340
break;
341+
case DECIMAL:
342+
value = option.getDecimalValue().orElse(null);
343+
break;
276344
case BOOLEAN:
277345
value = option.getBooleanValue().orElse(null);
278346
break;
@@ -282,6 +350,40 @@ private static Object getOptionValue(SlashCommandInteractionOption option, Slash
282350
return value;
283351
}
284352

353+
/**
354+
* Returns the {@link Argument} of {@link Command} by {@link SlashCommandInteractionOption}
355+
*
356+
* @param command the command
357+
* @param option the option
358+
* @return an {@link Optional} with the {@link Argument} in it if found,
359+
* otherwise an empty {@link Optional}
360+
*/
361+
private static Optional<Argument> getArgumentByOption(Command command, SlashCommandInteractionOption option) {
362+
return collectArguments(command.getArguments()).stream()
363+
.filter(arg -> arg.getName().equalsIgnoreCase(option.getName()))
364+
.findFirst();
365+
}
366+
367+
/**
368+
* Collects all arguments of a list of arguments in one list
369+
* For collecting a command's all arguments {@link Command#getArguments()} need to be passed as parameter
370+
*
371+
* @param arguments a list of argument
372+
* @return the collection
373+
*/
374+
private static List<Argument> collectArguments(List<Argument> arguments) {
375+
List<Argument> allArguments = new ArrayList<>();
376+
for (Argument argument : arguments) {
377+
if (argument instanceof SubArgument) {
378+
allArguments.addAll(collectArguments(((SubArgument) argument).getArguments()));
379+
} else {
380+
allArguments.add(argument);
381+
}
382+
}
383+
384+
return allArguments;
385+
}
386+
285387
/**
286388
* Registers the command for the listener on the specified servers
287389
* and sets up permissions with discord's default permission system
@@ -420,19 +522,6 @@ public static void registerCommand(CommandBuilder<?> builder) {
420522
registerCommand(builder.getCommand());
421523
}
422524

423-
/**
424-
* Registers an error listener where the errors will be managed
425-
*
426-
* @param error the listener interface
427-
* @deprecated because of the new event system
428-
* use {@link CategoryLimitable#setOnBadCategory(BadCategoryEventListener)},
429-
* {@link ChannelLimitable#setOnBadChannel(BadChannelEventListener)} and
430-
* {@link Argument#setOnMismatch(ArgumentMismatchEventListener)} instead
431-
*/
432-
@Deprecated
433-
public static void setOnError(CommandErrorListener error) {
434-
}
435-
436525
/**
437526
* @return the list of the commands
438527
*/

src/main/java/me/s3ns3iw00/jcommands/argument/InputArgument.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,31 @@
1818
*/
1919
package me.s3ns3iw00.jcommands.argument;
2020

21+
import me.s3ns3iw00.jcommands.argument.ability.Autocompletable;
22+
import me.s3ns3iw00.jcommands.argument.ability.Optionality;
23+
import me.s3ns3iw00.jcommands.argument.autocomplete.Autocomplete;
2124
import org.javacord.api.entity.channel.TextChannel;
2225
import org.javacord.api.entity.permission.Role;
2326
import org.javacord.api.entity.user.User;
2427
import org.javacord.api.interaction.SlashCommandOption;
28+
import org.javacord.api.interaction.SlashCommandOptionBuilder;
2529
import org.javacord.api.interaction.SlashCommandOptionType;
2630

31+
import java.util.ArrayList;
32+
import java.util.List;
33+
2734
/**
2835
* Represents argument that can have multiple value depends on the user input and the restrictions of the argument
2936
* These arguments can be optional
3037
*/
31-
public abstract class InputArgument extends Argument {
38+
public abstract class InputArgument extends Argument implements Optionality, Autocompletable {
3239

3340
private Object input;
3441
private final Class<?> resultType;
3542
private boolean optional = false;
3643

44+
private final List<Autocomplete> autocompletes = new ArrayList<>();
45+
3746
/**
3847
* Constructs the argument with the default requirements
3948
*
@@ -83,9 +92,16 @@ public InputArgument(String name, String description, SlashCommandOptionType typ
8392

8493
@Override
8594
public SlashCommandOption getCommandOption() {
86-
return SlashCommandOption.create(getType(), getName(), getDescription(), !optional);
95+
return new SlashCommandOptionBuilder()
96+
.setName(getName())
97+
.setDescription(getDescription())
98+
.setType(getType())
99+
.setRequired(!isOptional())
100+
.setAutocompletable(autocompletes.size() > 0)
101+
.build();
87102
}
88103

104+
@Override
89105
public boolean isOptional() {
90106
return optional;
91107
}
@@ -98,6 +114,10 @@ public void setOptional() {
98114
optional = true;
99115
}
100116

117+
public List<Autocomplete> getAutocompletes() {
118+
return autocompletes;
119+
}
120+
101121
/**
102122
* Sets the input
103123
*
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2021 S3nS3IW00
2+
* Copyright (C) 2022 S3nS3IW00
33
*
44
* This file is part of JCommands.
55
*
@@ -16,30 +16,21 @@
1616
* You should have received a copy of the GNU Lesser General Public
1717
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
1818
*/
19-
package me.s3ns3iw00.jcommands;
19+
package me.s3ns3iw00.jcommands.argument.ability;
20+
21+
import me.s3ns3iw00.jcommands.argument.autocomplete.Autocomplete;
22+
23+
import java.util.List;
2024

2125
/**
22-
* Enum with error type constants
23-
*
24-
* @author S3nS3IW00
25-
* @deprecated see {@link me.s3ns3iw00.jcommands.listener.CommandErrorListener} for more information
26+
* Identifies whether an argument is autocompletable
2627
*/
27-
@Deprecated
28-
public enum CommandErrorType {
29-
30-
/**
31-
* Occurs when one or more of the arguments are missing or not matching the pattern.
32-
*/
33-
BAD_ARGUMENTS,
28+
public interface Autocompletable {
3429

35-
/**
36-
* Occurs when the sender wants to use the command in a category where it is not allowed.
37-
*/
38-
BAD_CATEGORY,
30+
List<Autocomplete> getAutocompletes();
3931

40-
/**
41-
* Occurs when the sender wants to use the command in a channel where it is not allowed.
42-
*/
43-
BAD_CHANNEL
32+
default void addAutocomplete(Autocomplete autocomplete) {
33+
getAutocompletes().add(autocomplete);
34+
}
4435

4536
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2022 S3nS3IW00
3+
*
4+
* This file is part of JCommands.
5+
*
6+
* JCommands is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU Lesser general Public License as
8+
* published by the Free Software Foundation; either version 3 of
9+
* the License, or (at your option) any later version.
10+
*
11+
* JCommands is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
package me.s3ns3iw00.jcommands.argument.ability;
20+
21+
/**
22+
* Identifies whether an argument can be optional or not
23+
*/
24+
public interface Optionality {
25+
26+
boolean isOptional();
27+
28+
}

0 commit comments

Comments
 (0)