Skip to content

Commit b5c9859

Browse files
authored
Merge pull request #442 from danthe1st/config-improvements
Config improvements
2 parents 28bb131 + 11a31ff commit b5c9859

File tree

5 files changed

+124
-15
lines changed

5 files changed

+124
-15
lines changed

src/main/java/net/javadiscord/javabot/systems/configuration/ConfigCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class ConfigCommand extends SlashCommand implements CommandModerationPerm
1717
* @param getConfigSubcommand /config get
1818
* @param setConfigSubcommand /config set
1919
*/
20-
public ConfigCommand(BotConfig botConfig, ExportConfigSubcommand exportConfigSubcommand, GetConfigSubcommand getConfigSubcommand, SetConfigSubcommand setConfigSubcommand) {
20+
public ConfigCommand(BotConfig botConfig, ExportConfigSubcommand exportConfigSubcommand, GetConfigSubcommand getConfigSubcommand, ConfigSubcommand setConfigSubcommand) {
2121
setModerationSlashCommandData(Commands.slash("config", "Administrative Commands for managing the bot's configuration."));
2222
addSubcommands(exportConfigSubcommand, getConfigSubcommand, setConfigSubcommand);
2323
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());

src/main/java/net/javadiscord/javabot/systems/configuration/ConfigSubcommand.java

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
package net.javadiscord.javabot.systems.configuration;
22

33
import xyz.dynxsty.dih4jda.interactions.commands.application.SlashCommand;
4+
import xyz.dynxsty.dih4jda.util.AutoCompleteUtils;
5+
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
46
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
5-
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
7+
import net.dv8tion.jda.api.interactions.commands.Command;
8+
import net.dv8tion.jda.api.interactions.commands.Command.Choice;
9+
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
610
import net.javadiscord.javabot.data.config.BotConfig;
711
import net.javadiscord.javabot.data.config.GuildConfig;
812
import net.javadiscord.javabot.data.config.UnknownPropertyException;
913
import net.javadiscord.javabot.util.Checks;
1014
import net.javadiscord.javabot.util.Responses;
1115
import org.jetbrains.annotations.NotNull;
1216

17+
import java.lang.reflect.Field;
18+
import java.lang.reflect.Modifier;
19+
import java.util.Arrays;
20+
import java.util.List;
21+
import java.util.stream.Collectors;
22+
1323
import javax.annotation.Nonnull;
1424

1525
/**
@@ -44,5 +54,47 @@ public void execute(@NotNull SlashCommandInteractionEvent event) {
4454
}
4555
}
4656

47-
protected abstract ReplyCallbackAction handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException;
57+
protected abstract InteractionCallbackAction<?> handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException;
58+
59+
/**
60+
* autocompletes a property.
61+
* @param event the {@link CommandAutoCompleteInteractionEvent} used for sending the autocomplete information
62+
* @param partialText the entered text
63+
*/
64+
protected void handlePropertyAutocomplete(CommandAutoCompleteInteractionEvent event, String partialText) {
65+
int lastDot = partialText.lastIndexOf('.');
66+
String parentPropertyName;
67+
String childPropertyName;
68+
if (lastDot == -1) {
69+
parentPropertyName = "";
70+
childPropertyName = partialText;
71+
} else {
72+
parentPropertyName = partialText.substring(0,lastDot);
73+
childPropertyName = partialText.substring(lastDot+1);
74+
}
75+
76+
GuildConfig guildConfig = botConfig.get(event.getGuild());
77+
try {
78+
Object resolved;
79+
if(parentPropertyName.isEmpty()) {
80+
resolved = guildConfig;
81+
} else {
82+
resolved = guildConfig.resolve(parentPropertyName);
83+
}
84+
if (resolved == null || !resolved.getClass().getPackageName().startsWith(GuildConfig.class.getPackageName())) {
85+
event.replyChoices().queue();
86+
return;
87+
}
88+
List<Choice> choices = Arrays.stream(resolved.getClass().getDeclaredFields())
89+
.filter(f -> !Modifier.isTransient(f.getModifiers()))
90+
.map(Field::getName)
91+
.map(name -> parentPropertyName.isEmpty() ? name : parentPropertyName+"."+name)
92+
.map(name -> new Command.Choice(name, name))
93+
.collect(Collectors.toList());
94+
95+
event.replyChoices(AutoCompleteUtils.filterChoices(childPropertyName, choices)).queue();
96+
} catch (UnknownPropertyException e) {
97+
event.replyChoices().queue();
98+
}
99+
}
48100
}

src/main/java/net/javadiscord/javabot/systems/configuration/ExportConfigSubcommand.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public class ExportConfigSubcommand extends ConfigSubcommand {
2222
public ExportConfigSubcommand(BotConfig botConfig) {
2323
super(botConfig);
2424
setCommandData(new SubcommandData("export", "Exports a list of all configuration properties, and their current values."));
25-
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());
2625
}
2726

2827
@Override

src/main/java/net/javadiscord/javabot/systems/configuration/GetConfigSubcommand.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package net.javadiscord.javabot.systems.configuration;
22

3+
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
34
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
5+
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
46
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
57
import net.dv8tion.jda.api.interactions.commands.OptionType;
68
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
@@ -9,23 +11,23 @@
911
import net.javadiscord.javabot.data.config.GuildConfig;
1012
import net.javadiscord.javabot.data.config.UnknownPropertyException;
1113
import net.javadiscord.javabot.util.Responses;
14+
import xyz.dynxsty.dih4jda.interactions.AutoCompletable;
1215

1316
import javax.annotation.Nonnull;
1417

1518
/**
1619
* Subcommand that allows staff-members to get a single property variable from the guild config.
1720
*/
18-
public class GetConfigSubcommand extends ConfigSubcommand {
21+
public class GetConfigSubcommand extends ConfigSubcommand implements AutoCompletable {
1922
/**
2023
* The constructor of this class, which sets the corresponding {@link SubcommandData}.
2124
* @param botConfig The main configuration of the bot
2225
*/
2326
public GetConfigSubcommand(BotConfig botConfig) {
2427
super(botConfig);
2528
setCommandData(new SubcommandData("get", "Get the current value of a configuration property.")
26-
.addOption(OptionType.STRING, "property", "The name of a property.", true)
29+
.addOption(OptionType.STRING, "property", "The name of a property.", true, true)
2730
);
28-
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());
2931
}
3032

3133
@Override
@@ -38,4 +40,12 @@ public ReplyCallbackAction handleConfigSubcommand(@Nonnull SlashCommandInteracti
3840
Object value = config.resolve(property);
3941
return Responses.info(event, "Configuration Property", "The value of the property `%s` is:\n```\n%s\n```", property, value);
4042
}
43+
44+
@Override
45+
public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCompleteQuery target) {
46+
if (target.getName().equals("property")) {
47+
String partialText = target.getValue();
48+
handlePropertyAutocomplete(event, partialText);
49+
}
50+
}
4151
}
Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,92 @@
11
package net.javadiscord.javabot.systems.configuration;
22

3+
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
4+
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
35
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
6+
import net.dv8tion.jda.api.interactions.AutoCompleteQuery;
47
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
58
import net.dv8tion.jda.api.interactions.commands.OptionType;
69
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
7-
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
10+
import net.dv8tion.jda.api.interactions.components.text.TextInput;
11+
import net.dv8tion.jda.api.interactions.components.text.TextInputStyle;
12+
import net.dv8tion.jda.api.interactions.modals.Modal;
13+
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
14+
import net.dv8tion.jda.api.requests.restaction.interactions.InteractionCallbackAction;
15+
import net.javadiscord.javabot.annotations.AutoDetectableComponentHandler;
816
import net.javadiscord.javabot.data.config.BotConfig;
917
import net.javadiscord.javabot.data.config.GuildConfig;
1018
import net.javadiscord.javabot.data.config.UnknownPropertyException;
1119
import net.javadiscord.javabot.util.Responses;
20+
import xyz.dynxsty.dih4jda.interactions.AutoCompletable;
21+
import xyz.dynxsty.dih4jda.interactions.components.ModalHandler;
22+
import xyz.dynxsty.dih4jda.util.ComponentIdBuilder;
23+
24+
import java.util.List;
1225

1326
import javax.annotation.Nonnull;
1427

1528
/**
1629
* Subcommand that allows staff-members to edit the bot's configuration.
1730
*/
18-
public class SetConfigSubcommand extends ConfigSubcommand {
31+
@AutoDetectableComponentHandler("config-set")
32+
public class SetConfigSubcommand extends ConfigSubcommand implements ModalHandler, AutoCompletable {
1933
/**
2034
* The constructor of this class, which sets the corresponding {@link SubcommandData}.
2135
* @param botConfig The main configuration of the bot
2236
*/
2337
public SetConfigSubcommand(BotConfig botConfig) {
2438
super(botConfig);
2539
setCommandData(new SubcommandData("set", "Sets the value of a configuration property.")
26-
.addOption(OptionType.STRING, "property", "The name of a property.", true)
27-
.addOption(OptionType.STRING, "value", "The value to set for the property.", true)
40+
.addOption(OptionType.STRING, "property", "The name of a property.", true, true)
41+
.addOption(OptionType.STRING, "value", "The value to set for the property.", false)
2842
);
29-
setRequiredUsers(botConfig.getSystems().getAdminConfig().getAdminUsers());
3043
}
3144

3245
@Override
33-
public ReplyCallbackAction handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException {
46+
public InteractionCallbackAction<?> handleConfigSubcommand(@Nonnull SlashCommandInteractionEvent event, @Nonnull GuildConfig config) throws UnknownPropertyException {
3447
OptionMapping propertyOption = event.getOption("property");
3548
OptionMapping valueOption = event.getOption("value");
36-
if (propertyOption == null || valueOption == null) {
49+
if (propertyOption == null) {
3750
return Responses.replyMissingArguments(event);
3851
}
3952
String property = propertyOption.getAsString().trim();
53+
GuildConfig guildConfig = botConfig.get(event.getGuild());
54+
if (valueOption == null) {
55+
Object resolved = guildConfig.resolve(property);
56+
if (resolved == null) {
57+
return Responses.error(event, "Config `%s` not found", property);
58+
}
59+
return event.replyModal(
60+
Modal.create(ComponentIdBuilder.build("config-set", property), "Change configuration value")
61+
.addActionRow(TextInput.create("value", "new value", TextInputStyle.PARAGRAPH)
62+
.setValue(String.valueOf(resolved))
63+
.build())
64+
.build());
65+
}
4066
String valueString = valueOption.getAsString().trim();
41-
botConfig.get(event.getGuild()).set(property, valueString);
67+
guildConfig.set(property, valueString);
4268
return Responses.success(event, "Configuration Updated", "The property `%s` has been set to `%s`.", property, valueString);
4369
}
70+
71+
@Override
72+
public void handleModal(ModalInteractionEvent event, List<ModalMapping> values) {
73+
String[] id = ComponentIdBuilder.split(event.getModalId());
74+
String property = id[1];
75+
String valueString = event.getValue("value").getAsString();
76+
GuildConfig guildConfig = botConfig.get(event.getGuild());
77+
try {
78+
guildConfig.set(property, valueString);
79+
Responses.success(event, "Configuration Updated", "The property `%s` has been set to `%s`.", property, valueString).queue();
80+
} catch (UnknownPropertyException e) {
81+
Responses.error(event, "Property not found: %s", property).queue();
82+
}
83+
}
84+
85+
@Override
86+
public void handleAutoComplete(CommandAutoCompleteInteractionEvent event, AutoCompleteQuery target) {
87+
if (target.getName().equals("property")) {
88+
String partialText = target.getValue();
89+
handlePropertyAutocomplete(event, partialText);
90+
}
91+
}
4492
}

0 commit comments

Comments
 (0)