diff --git a/src/main/java/moe/oko/Kiafumi/Kiafumi.java b/src/main/java/moe/oko/Kiafumi/Kiafumi.java index a39be19..2624f96 100644 --- a/src/main/java/moe/oko/Kiafumi/Kiafumi.java +++ b/src/main/java/moe/oko/Kiafumi/Kiafumi.java @@ -12,6 +12,7 @@ import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.OnlineStatus; import net.dv8tion.jda.api.entities.Activity; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.restaction.CommandCreateAction; import net.dv8tion.jda.api.utils.ChunkingFilter; @@ -210,6 +211,13 @@ public class Kiafumi { //Any intelligent IDE will rage about the option not being used, it's added to the action then executed later, DO not edit this (please). cca.addOption(ci.getOptions().get(name), name, ci.getOptionDescriptions().get(name), ci.getOptionRequirements().get(name)); } + for(String name : ci.getSubCommands().keySet()) { + CommandInfo si = ci.getSubCommands().get(name); + SubcommandData sd = new SubcommandData(si.getName(), si.getDescription()); + for(String option : si.getOptions().keySet()) { + sd.addOption(si.getOptions().get(option), option, si.getOptionDescriptions().get(option), si.getOptionRequirements().get(option)); + } + } //Done cca.queue(); continue; diff --git a/src/main/java/moe/oko/Kiafumi/command/DreidelCommand.java b/src/main/java/moe/oko/Kiafumi/command/DreidelCommand.java index 74bb84e..b9c9fc7 100644 --- a/src/main/java/moe/oko/Kiafumi/command/DreidelCommand.java +++ b/src/main/java/moe/oko/Kiafumi/command/DreidelCommand.java @@ -1,6 +1,7 @@ package moe.oko.Kiafumi.command; import moe.oko.Kiafumi.util.CommandInfo; +import moe.oko.Kiafumi.util.CommandType; import moe.oko.Kiafumi.util.EmbedUI; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.User; @@ -70,7 +71,7 @@ public class DreidelCommand extends CommandClass { @Override public List getSlashCommandInfo() { List cil = new ArrayList<>(); - CommandInfo ci = new CommandInfo("dreidel", "picks a random person out of 4 values."); + CommandInfo ci = new CommandInfo("dreidel", "picks a random person out of 4 values.", CommandType.COMMAND); ci.addOption("value1", "first value for spin", OptionType.USER, true); ci.addOption("value2", "second value for spin", OptionType.USER, true); ci.addOption("value3", "third value for spin", OptionType.USER, false); diff --git a/src/main/java/moe/oko/Kiafumi/command/DuckCommand.java b/src/main/java/moe/oko/Kiafumi/command/DuckCommand.java index f32a6ee..51b65c4 100644 --- a/src/main/java/moe/oko/Kiafumi/command/DuckCommand.java +++ b/src/main/java/moe/oko/Kiafumi/command/DuckCommand.java @@ -1,6 +1,7 @@ package moe.oko.Kiafumi.command; import moe.oko.Kiafumi.util.CommandInfo; +import moe.oko.Kiafumi.util.CommandType; import moe.oko.Kiafumi.util.EmbedUI; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; @@ -68,7 +69,7 @@ public class DuckCommand extends CommandClass{ @Override public List getSlashCommandInfo() { List cil = new ArrayList<>(); - CommandInfo ci = new CommandInfo("search", "Looks up with DuckDuckGo your query!"); + CommandInfo ci = new CommandInfo("search", "Looks up with DuckDuckGo your query!", CommandType.COMMAND); ci.addOption("query", "The query to be searched", OptionType.STRING, true); cil.add(ci); return cil; diff --git a/src/main/java/moe/oko/Kiafumi/command/InviteCommand.java b/src/main/java/moe/oko/Kiafumi/command/InviteCommand.java index 713478e..31aac98 100644 --- a/src/main/java/moe/oko/Kiafumi/command/InviteCommand.java +++ b/src/main/java/moe/oko/Kiafumi/command/InviteCommand.java @@ -2,6 +2,7 @@ package moe.oko.Kiafumi.command; import moe.oko.Kiafumi.Kiafumi; import moe.oko.Kiafumi.util.CommandInfo; +import moe.oko.Kiafumi.util.CommandType; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; @@ -52,7 +53,7 @@ public class InviteCommand extends CommandClass{ @Override public List getSlashCommandInfo() { List cil = new ArrayList<>(); - CommandInfo ci = new CommandInfo("invite", "Returns an invite for Kiafumi."); + CommandInfo ci = new CommandInfo("invite", "Returns an invite for Kiafumi.", CommandType.COMMAND); cil.add(ci); return cil; } diff --git a/src/main/java/moe/oko/Kiafumi/command/PingCommand.java b/src/main/java/moe/oko/Kiafumi/command/PingCommand.java index 778f4c8..16c8d69 100644 --- a/src/main/java/moe/oko/Kiafumi/command/PingCommand.java +++ b/src/main/java/moe/oko/Kiafumi/command/PingCommand.java @@ -2,6 +2,7 @@ package moe.oko.Kiafumi.command; import moe.oko.Kiafumi.Kiafumi; import moe.oko.Kiafumi.util.CommandInfo; +import moe.oko.Kiafumi.util.CommandType; import moe.oko.Kiafumi.util.EmbedUI; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; @@ -72,7 +73,7 @@ public class PingCommand extends CommandClass{ @Override public List getSlashCommandInfo() { List si = new ArrayList<>(); - CommandInfo ci = new CommandInfo("ping", "Returns bot latency with a twist!"); + CommandInfo ci = new CommandInfo("ping", "Returns bot latency with a twist!", CommandType.COMMAND); si.add(ci); return si; } diff --git a/src/main/java/moe/oko/Kiafumi/command/SettingCommand.java b/src/main/java/moe/oko/Kiafumi/command/SettingCommand.java index 0d8c21d..2f13c4b 100644 --- a/src/main/java/moe/oko/Kiafumi/command/SettingCommand.java +++ b/src/main/java/moe/oko/Kiafumi/command/SettingCommand.java @@ -3,6 +3,7 @@ package moe.oko.Kiafumi.command; import moe.oko.Kiafumi.Kiafumi; import moe.oko.Kiafumi.model.Server; import moe.oko.Kiafumi.util.CommandInfo; +import moe.oko.Kiafumi.util.CommandType; import moe.oko.Kiafumi.util.EmbedUI; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; @@ -46,41 +47,44 @@ public class SettingCommand extends CommandClass { e.getHook().sendMessageEmbeds(eb.build()).queue(); return; case "setting": - e.deferReply().queue(); - String opt = e.getOption("setting_name").getAsString(); - EmbedBuilder eb1 = new EmbedBuilder() - .setColor(EmbedUI.INFO) - .setTitle(opt) - .setDescription("Value: `" + server.getOptionByString(opt) + '`') - .setFooter(EmbedUI.BRAND) - .setTimestamp(ZonedDateTime.now()); - e.getHook().sendMessageEmbeds(eb1.build()).queue(); - return; - case "setting_set": - e.deferReply().queue(); - String opt1 = e.getOption("setting_name").getAsString(); - String opt2 = e.getOption("setting_value").getAsString(); - String response = server.setOptionByString(opt1, opt2); - EmbedBuilder eb2 = new EmbedBuilder() - .setColor(EmbedUI.SUCCESS) - .setTitle(opt1) - .setDescription(response) - .setFooter(EmbedUI.BRAND) - .setTimestamp(ZonedDateTime.now()); - e.getHook().sendMessageEmbeds(eb2.build()).queue(); - return; - case "setting_clear": - e.deferReply().queue(); - String opt3 = e.getOption("setting_name").getAsString(); - String response1 = server.resetOptionByString(opt3); - EmbedBuilder eb3 = new EmbedBuilder() - .setColor(EmbedUI.SUCCESS) - .setTitle(opt3) - .setDescription(response1) - .setFooter(EmbedUI.BRAND) - .setTimestamp(ZonedDateTime.now()); - e.getHook().sendMessageEmbeds(eb3.build()).queue(); - return; + switch(e.getSubcommandName().toLowerCase()) { + case "view": + e.deferReply().queue(); + String opt = e.getOption("name").getAsString(); + EmbedBuilder eb1 = new EmbedBuilder() + .setColor(EmbedUI.INFO) + .setTitle(opt) + .setDescription("Value: `" + server.getOptionByString(opt) + '`') + .setFooter(EmbedUI.BRAND) + .setTimestamp(ZonedDateTime.now()); + e.getHook().sendMessageEmbeds(eb1.build()).queue(); + return; + case "set": + e.deferReply().queue(); + String opt1 = e.getOption("name").getAsString(); + String opt2 = e.getOption("value").getAsString(); + String response = server.setOptionByString(opt1, opt2); + EmbedBuilder eb2 = new EmbedBuilder() + .setColor(EmbedUI.SUCCESS) + .setTitle(opt1) + .setDescription(response) + .setFooter(EmbedUI.BRAND) + .setTimestamp(ZonedDateTime.now()); + e.getHook().sendMessageEmbeds(eb2.build()).queue(); + return; + case "clear": + e.deferReply().queue(); + String opt3 = e.getOption("name").getAsString(); + String response1 = server.resetOptionByString(opt3); + EmbedBuilder eb3 = new EmbedBuilder() + .setColor(EmbedUI.SUCCESS) + .setTitle(opt3) + .setDescription(response1) + .setFooter(EmbedUI.BRAND) + .setTimestamp(ZonedDateTime.now()); + e.getHook().sendMessageEmbeds(eb3.build()).queue(); + return; + } } } } @@ -98,24 +102,27 @@ public class SettingCommand extends CommandClass { @Override public List getSlashCommandInfo() { List si = new ArrayList<>(); - CommandInfo ci = new CommandInfo("setting", "displays a specific setting for the current guild"); - si.add(ci); - CommandInfo ci2 = new CommandInfo("setting", "views the current value for the setting"); - ci2.addOption("setting_name", "The name of the setting to view", OptionType.STRING, true); - si.add(ci2); + CommandInfo ci2 = new CommandInfo("setting", "Permits modification, viewing, and clearing of settings.", CommandType.COMMAND); + ci2.addOption("setting_modify", "The type of modification you would like to make.", OptionType.SUB_COMMAND, true); - CommandInfo ci3 = new CommandInfo("setting_set", "sets a setting for the guild you are in"); - ci3.addOption("setting_name", "The name of the setting to modify", OptionType.STRING, true); - ci3.addOption("setting_value", "The value to set the setting to", OptionType.STRING, true); - si.add(ci3); + CommandInfo ci = new CommandInfo("view", "Shows the current value for the setting provided.", CommandType.SUBCOMMAND); + ci.addOption("name", "The name of the setting to display", OptionType.STRING, true); + ci2.addSubcommand(ci); - CommandInfo ci4 = new CommandInfo("setting_clear", "reverts a setting back to its default value"); - ci4.addOption("setting_name", "Name of the setting to clear", OptionType.STRING, true); - si.add(ci4); + CommandInfo ci3 = new CommandInfo("set", "sets a setting for the guild you are in", CommandType.SUBCOMMAND); + ci3.addOption("name", "The name of the setting to modify", OptionType.STRING, true); + ci3.addOption("value", "The value to set the setting to", OptionType.STRING, true); + ci2.addSubcommand(ci3); - CommandInfo ci5 = new CommandInfo("settings", "displays all settings available for the guild."); + CommandInfo ci4 = new CommandInfo("clear", "reverts a setting back to its default value", CommandType.SUBCOMMAND); + ci4.addOption("name", "Name of the setting to clear", OptionType.STRING, true); + ci2.addSubcommand(ci4); + + CommandInfo ci5 = new CommandInfo("settings", "displays all settings available for the guild.", CommandType.COMMAND); si.add(ci5); + + si.add(ci2); return si; } } diff --git a/src/main/java/moe/oko/Kiafumi/util/CommandInfo.java b/src/main/java/moe/oko/Kiafumi/util/CommandInfo.java index b47d0b2..a1e04e1 100644 --- a/src/main/java/moe/oko/Kiafumi/util/CommandInfo.java +++ b/src/main/java/moe/oko/Kiafumi/util/CommandInfo.java @@ -4,24 +4,29 @@ import net.dv8tion.jda.api.interactions.commands.OptionType; import java.util.HashMap; +import static moe.oko.Kiafumi.Kiafumi.error; + /** * Helpful CommandInfo class to easily make slash commands. */ public class CommandInfo { private String name; private String description; + private CommandType type; private HashMap options; private HashMap optionDescriptions; private HashMap optionRequirements; + private HashMap subCommands; /** * Constructor to build CommandInfo with. * @param name - Name of the slash command (MUST BE ALL LOWERCASE) * @param description - Description of the slash command */ - public CommandInfo(String name, String description) { + public CommandInfo(String name, String description, CommandType type) { this.name = name; this.description = description; + this.type = type; this.options = new HashMap<>(); this.optionDescriptions = new HashMap<>(); this.optionRequirements = new HashMap<>(); @@ -55,6 +60,8 @@ public class CommandInfo { return optionDescriptions; } + public HashMap getSubCommands() { return subCommands; } + /** * The way you add options to a command. Use this function for EACH argument. * @param name - name of the field @@ -63,8 +70,16 @@ public class CommandInfo { * @param required - whether the command can be run without the field or not. */ public void addOption(String name, String description, OptionType type, boolean required) { + if(this.type.equals(CommandType.SUBCOMMAND) && (type.equals(OptionType.SUB_COMMAND) || type.equals(OptionType.SUB_COMMAND_GROUP))) { + error("Command " + this.name + " attempted to assign a SUB_COMMAND option despite it being a subcommand itself. Check code for this command."); + return; //You cannot add a subcommand option to a subcommand. + } options.put(name, type); optionDescriptions.put(name, description); optionRequirements.put(name, required); } + + public void addSubcommand(CommandInfo cmdInfo) { + subCommands.put(cmdInfo.name, cmdInfo); + } } diff --git a/src/main/java/moe/oko/Kiafumi/util/CommandType.java b/src/main/java/moe/oko/Kiafumi/util/CommandType.java new file mode 100644 index 0000000..a60085f --- /dev/null +++ b/src/main/java/moe/oko/Kiafumi/util/CommandType.java @@ -0,0 +1,14 @@ +package moe.oko.Kiafumi.util; + +public enum CommandType { + + /** + * Commands that are registered using the upsertCommand method. + */ + COMMAND, + + /** + * Commands that fall under above commands using the addSubcommand function. + */ + SUBCOMMAND +}