From cfeb04fe6e14b49a19364846da04162d11322421 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Mon, 19 Dec 2022 02:27:41 +0100 Subject: [PATCH] Added Nick and Unlink command --- .../bot/commandManager/CommandManager.java | 6 +- .../bot/commandManager/SubCommand.java | 29 ++++++ .../bot/commandManager/SubCommandGroup.java | 7 ++ .../bot/commandManager/SubOption.java | 21 ++++ .../commands/CommandUnlink.java | 55 +++++++++++ .../commands/NickCommand/CommandNick.java | 98 +++++++++++++++++++ .../commands/NickCommand/SubCommandNick.java | 36 +++++++ .../NickCommand/SubCommandUserName.java | 36 +++++++ .../proxydiscordlink/util/Utilities.java | 22 +++++ 9 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommand.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommandGroup.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubOption.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandUnlink.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/CommandNick.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandNick.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandUserName.java diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/CommandManager.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/CommandManager.java index 4c0b1f4..94c5147 100644 --- a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/CommandManager.java +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/CommandManager.java @@ -1,6 +1,8 @@ package com.alttd.proxydiscordlink.bot.commandManager; import com.alttd.proxydiscordlink.bot.commandManager.commands.CommandLink; +import com.alttd.proxydiscordlink.bot.commandManager.commands.CommandUnlink; +import com.alttd.proxydiscordlink.bot.commandManager.commands.NickCommand.CommandNick; import com.alttd.proxydiscordlink.util.ALogger; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; @@ -20,7 +22,9 @@ public class CommandManager extends ListenerAdapter { public CommandManager(JDA jda/*, ChatListener chatListener*/) { ALogger.info("Loading commands..."); commands = List.of( - new CommandLink(jda) + new CommandLink(jda), + new CommandUnlink(jda), + new CommandNick(jda) ); } diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommand.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommand.java new file mode 100644 index 0000000..f2ed23b --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommand.java @@ -0,0 +1,29 @@ +package com.alttd.proxydiscordlink.bot.commandManager; + +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; + +import java.util.ArrayList; + +public abstract class SubCommand extends SubOption{ + + private final SubCommandGroup parentGroup; + private final boolean inSubGroup; + + protected SubCommand(SubCommandGroup parentGroup, DiscordCommand parent) { + super(parent); + this.parentGroup = parentGroup; + this.inSubGroup = parentGroup != null; + } + + public SubCommandGroup getParentGroup() { + return parentGroup; + } + + public boolean isInSubGroup() { + return inSubGroup; + } + + public void suggest(CommandAutoCompleteInteractionEvent event) { + event.replyChoices(new ArrayList<>()).queue(); + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommandGroup.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommandGroup.java new file mode 100644 index 0000000..3b62f89 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubCommandGroup.java @@ -0,0 +1,7 @@ +package com.alttd.proxydiscordlink.bot.commandManager; + +public abstract class SubCommandGroup extends SubOption{ + protected SubCommandGroup(DiscordCommand parent) { + super(parent); + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubOption.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubOption.java new file mode 100644 index 0000000..f639296 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/SubOption.java @@ -0,0 +1,21 @@ +package com.alttd.proxydiscordlink.bot.commandManager; + +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public abstract class SubOption { + private final DiscordCommand parent; + + protected SubOption(DiscordCommand parent) { + this.parent = parent; + } + + public DiscordCommand getParent() { + return parent; + } + + public abstract String getName(); + + public abstract void execute(SlashCommandInteractionEvent event); + + public abstract String getHelpMessage(); +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandUnlink.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandUnlink.java new file mode 100644 index 0000000..c14b8d5 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandUnlink.java @@ -0,0 +1,55 @@ +package com.alttd.proxydiscordlink.bot.commandManager.commands; + +import com.alttd.proxydiscordlink.bot.commandManager.DiscordCommand; +import com.alttd.proxydiscordlink.config.BotConfig; +import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; +import com.alttd.proxydiscordlink.util.Utilities; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.build.Commands; + +public class CommandUnlink extends DiscordCommand { + private final CommandData commandData; + public CommandUnlink(JDA jda) { + commandData = Commands.slash(getName(), "Unlink your Discord and Altitude Minecraft accounts") + .setDefaultPermissions(DefaultMemberPermissions.ENABLED); + + Utilities.registerCommand(jda, commandData); + } + @Override + public String getName() { + return "unlink"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + Member member = event.getMember(); + if (member == null) { + Utilities.commandErrAutoRem("Unable to find you", event); + return; + } + + DiscordLinkPlayer discordLinkPlayer = DiscordLinkPlayer.getDiscordLinkPlayer(member.getIdLong()); + if (discordLinkPlayer == null) { + Utilities.commandErrAutoRem("Your accounts aren't linked", event); + return; + } + discordLinkPlayer.unlinkDiscordLinkPlayer(); + event.replyEmbeds(Utilities.genericSuccessEmbed("Success", "Your Discord and Minecraft accounts have been unlinked.")) + .setEphemeral(true) + .queue(); + } + + @Override + public CommandData getCommandData() { + return commandData; + } + + @Override + public long getChannelId() { + return BotConfig.DISCORD.LINK_CHANNEL; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/CommandNick.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/CommandNick.java new file mode 100644 index 0000000..cdaa7d1 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/CommandNick.java @@ -0,0 +1,98 @@ +package com.alttd.proxydiscordlink.bot.commandManager.commands.NickCommand; + +import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.bot.commandManager.DiscordCommand; +import com.alttd.proxydiscordlink.bot.commandManager.SubOption; +import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; +import com.alttd.proxydiscordlink.util.ALogger; +import com.alttd.proxydiscordlink.util.Utilities; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.build.Commands; + +import java.util.HashMap; + +public class CommandNick extends DiscordCommand { + CommandData commandData; + private final HashMap subOptionsMap = new HashMap<>(); + public CommandNick(JDA jda) { + commandData = Commands.slash(getName(), "Create an auction") + .addOption(OptionType.NUMBER, "code", "The code you got from doing /discord link on Altitude in Minecraft", true) + .setDefaultPermissions(DefaultMemberPermissions.ENABLED); + Utilities.registerSubOptions(subOptionsMap, + new SubCommandUserName(null,this), + new SubCommandNick(null,this) + ); + Utilities.registerCommand(jda, commandData); + } + + @Override + public String getName() { + return "nick"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + if (event.getGuild() == null || event.getMember() == null) { + Utilities.commandErrAutoRem("This command can only be used within a guild: " + getName(), event); + return; + } + + String subcommandName = event.getInteraction().getSubcommandGroup(); + subcommandName = subcommandName == null ? event.getInteraction().getSubcommandName() : subcommandName; + if (subcommandName == null) { + ALogger.error("No subcommand found for " + getName()); + return; + } + + SubOption subOption = subOptionsMap.get(subcommandName); + if (subOption == null) { + event.replyEmbeds(Utilities.invalidSubcommand(subcommandName)) + .setEphemeral(true) + .queue(); + return; + } + + subOption.execute(event); + } + + @Override + public CommandData getCommandData() { + return commandData; + } + + @Override + public long getChannelId() { + return 0; + } + + public String setNickname(SlashCommandInteractionEvent event, boolean hasNick) { + Member member = event.getMember(); + if (member == null) { + Utilities.commandErrAutoRem("This command can only be run in a guild.", event); + return null; + } + DiscordLinkPlayer discordLinkPlayer = DiscordLinkPlayer.getDiscordLinkPlayer(member.getIdLong()); + if (discordLinkPlayer == null) { + Utilities.commandErrAutoRem("You aren't linked, please link before using this command.", event); + return null; + } + + String nick; + if (hasNick) { + nick = DiscordLink.getPlugin().getDatabase().getNick(discordLinkPlayer.getUuid()); + if (nick == null || nick.isBlank()) + nick = discordLinkPlayer.getUsername(); + } else { + nick = discordLinkPlayer.getUsername(); + } + member.modifyNickname(nick).queue(); + discordLinkPlayer.setNick(hasNick); + DiscordLink.getPlugin().getDatabase().syncPlayer(discordLinkPlayer); + return nick; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandNick.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandNick.java new file mode 100644 index 0000000..9ef86d9 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandNick.java @@ -0,0 +1,36 @@ +package com.alttd.proxydiscordlink.bot.commandManager.commands.NickCommand; + +import com.alttd.proxydiscordlink.bot.commandManager.DiscordCommand; +import com.alttd.proxydiscordlink.bot.commandManager.SubCommand; +import com.alttd.proxydiscordlink.bot.commandManager.SubCommandGroup; +import com.alttd.proxydiscordlink.util.Utilities; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandNick extends SubCommand { + protected SubCommandNick(SubCommandGroup parentGroup, DiscordCommand parent) { + super(parentGroup, parent); + } + + @Override + public String getName() { + return "nickname"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + if (!(getParent() instanceof CommandNick commandNick)) { + Utilities.commandErrAutoRem("Couldn't find parent command", event); + return; + } + + String resultingName = commandNick.setNickname(event, true); + event.replyEmbeds(Utilities.genericSuccessEmbed("Success", + "Your nickname has been set to `" + resultingName + "`.")) + .setEphemeral(true).queue(); + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandUserName.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandUserName.java new file mode 100644 index 0000000..a422132 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/NickCommand/SubCommandUserName.java @@ -0,0 +1,36 @@ +package com.alttd.proxydiscordlink.bot.commandManager.commands.NickCommand; + +import com.alttd.proxydiscordlink.bot.commandManager.DiscordCommand; +import com.alttd.proxydiscordlink.bot.commandManager.SubCommand; +import com.alttd.proxydiscordlink.bot.commandManager.SubCommandGroup; +import com.alttd.proxydiscordlink.util.Utilities; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandUserName extends SubCommand { + protected SubCommandUserName(SubCommandGroup parentGroup, DiscordCommand parent) { + super(parentGroup, parent); + } + + @Override + public String getName() { + return "username"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + if (!(getParent() instanceof CommandNick commandNick)) { + Utilities.commandErrAutoRem("Couldn't find parent command", event); + return; + } + + String resultingName = commandNick.setNickname(event, false); + event.replyEmbeds(Utilities.genericSuccessEmbed("Success", + "Your nickname has been set to `" + resultingName + "`.")) + .setEphemeral(true).queue(); + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java b/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java index c69f4b3..42bc946 100644 --- a/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java +++ b/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java @@ -1,6 +1,7 @@ package com.alttd.proxydiscordlink.util; import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.bot.commandManager.SubOption; import com.alttd.proxydiscordlink.bot.objects.DiscordRole; import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.config.Config; @@ -12,6 +13,7 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.requests.RestAction; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -24,6 +26,7 @@ import net.luckperms.api.node.types.InheritanceNode; import java.awt.*; import java.util.List; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class Utilities { @@ -153,6 +156,19 @@ public class Utilities { guild.upsertCommand(commandData).queue(RestAction.getDefaultSuccess(), Utilities::handleFailure); } + public static void registerSubOptions(HashMap subCommandMap, SubOption... subOptions) { + for (SubOption subOption : subOptions) + subCommandMap.put(subOption.getName(), subOption); + } + + public static MessageEmbed invalidSubcommand(String subcommandName) { + return new EmbedBuilder() + .setTitle("Invalid sub command") + .setDescription("This is not a valid sub command: " + subcommandName) + .setColor(Color.RED) + .build(); + } + public static MessageEmbed genericErrorEmbed(String title, String desc) { return new EmbedBuilder() .setTitle(title) @@ -184,4 +200,10 @@ public class Utilities { public static void handleFailure(Throwable failure) { ALogger.error(failure.getMessage()); } + + public static void commandErrAutoRem(String text, SlashCommandInteractionEvent event) { + event.replyEmbeds(Utilities.genericErrorEmbed("Error", text)) + .setEphemeral(true) + .queue(res -> res.deleteOriginal().queueAfter(5, TimeUnit.SECONDS)); + } }