From 197c510d0dfd1009f140c745ce539cfd49d842c2 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Sun, 18 Dec 2022 22:43:20 +0100 Subject: [PATCH] Reworked link command --- .../bot/commandManager/CommandManager.java | 59 +++++++ .../bot/commandManager/DiscordCommand.java | 18 ++ .../commandManager/commands/CommandLink.java | 156 ++++++++++++++++++ .../proxydiscordlink/util/Utilities.java | 37 ++++- 4 files changed, 265 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/CommandManager.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/DiscordCommand.java create mode 100644 src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandLink.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 new file mode 100644 index 0000000..4c0b1f4 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/CommandManager.java @@ -0,0 +1,59 @@ +package com.alttd.proxydiscordlink.bot.commandManager; + +import com.alttd.proxydiscordlink.bot.commandManager.commands.CommandLink; +import com.alttd.proxydiscordlink.util.ALogger; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.List; +import java.util.Optional; + +public class CommandManager extends ListenerAdapter { + + private final List commands; + + public CommandManager(JDA jda/*, ChatListener chatListener*/) { + ALogger.info("Loading commands..."); + commands = List.of( + new CommandLink(jda) + ); + } + + @Override + public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { + String commandName = event.getName(); + Optional first = commands.stream() + .filter(discordCommand -> discordCommand.getName().equalsIgnoreCase(commandName)) + .findFirst(); + if (first.isEmpty()) { + event.replyEmbeds(new EmbedBuilder() + .setTitle("Invalid command") + .setDescription("We couldn't find a command called [" + commandName + "], please report this issue to a Teri") + .setColor(Color.RED) + .build()) + .setEphemeral(true) + .queue(); + return; + } + first.get().execute(event); + } + + @Override + public void onCommandAutoCompleteInteraction(@NotNull CommandAutoCompleteInteractionEvent event) { + Optional first = commands.stream() + .filter(discordCommand -> discordCommand.getName().equalsIgnoreCase(event.getName())) + .findFirst(); + if (first.isEmpty()) + return; + first.get().suggest(event); + } + + public List getCommands() { + return commands; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/DiscordCommand.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/DiscordCommand.java new file mode 100644 index 0000000..4603650 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/DiscordCommand.java @@ -0,0 +1,18 @@ +package com.alttd.proxydiscordlink.bot.commandManager; + +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; + +public abstract class DiscordCommand { + + public abstract String getName(); + + public abstract void execute(SlashCommandInteractionEvent event); + + public abstract void suggest(CommandAutoCompleteInteractionEvent event); + + public abstract CommandData getCommandData(); + + public abstract long getChannelId(); +} diff --git a/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandLink.java b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandLink.java new file mode 100644 index 0000000..1c460d7 --- /dev/null +++ b/src/main/java/com/alttd/proxydiscordlink/bot/commandManager/commands/CommandLink.java @@ -0,0 +1,156 @@ +package com.alttd.proxydiscordlink.bot.commandManager.commands; + +import com.alttd.proxydiscordlink.DiscordLink; +import com.alttd.proxydiscordlink.bot.commandManager.DiscordCommand; +import com.alttd.proxydiscordlink.bot.objects.DiscordRole; +import com.alttd.proxydiscordlink.config.BotConfig; +import com.alttd.proxydiscordlink.objects.DiscordLinkPlayer; +import com.alttd.proxydiscordlink.util.Utilities; +import com.velocitypowered.api.proxy.Player; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +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 net.luckperms.api.model.user.User; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public class CommandLink extends DiscordCommand { + + public CommandLink(JDA jda) { + CommandData 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.registerCommand(jda, commandData); + } + + @Override + public String getName() { + return "link"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + Member member = event.getMember(); + if (member == null) { + handleError("Unable to find you", event); + return; + } + + UUID uuid = getUUID(event.getOption("link", OptionMapping::getAsInt)); + if (uuid == null) { + handleError("This is not a valid link code, please check Minecraft and try again", event); + return; + } + + List discordRoles = Utilities.getDiscordRolesForUser(uuid, member); + + DiscordLinkPlayer discordLinkPlayer = new DiscordLinkPlayer( + member.getIdLong(), + uuid, + getUsername(uuid), + member.getUser().getName(), + false, + true, + discordRoles.stream() + .map(DiscordRole::getInternalName) + .collect(Collectors.toList())); + + linkAccount(discordLinkPlayer, event); + } + + private void linkAccount(DiscordLinkPlayer discordLinkPlayer, SlashCommandInteractionEvent event) { + discordLinkPlayer.updateDiscord( + DiscordRole.getDiscordRoles().stream() + .filter(role -> discordLinkPlayer.getRoles().contains(role.getInternalName())) + .collect(Collectors.toList()), + true); + discordLinkPlayer.updateMinecraft( + DiscordRole.getDiscordRoles().stream() + .filter(role -> discordLinkPlayer.getRoles().contains(role.getInternalName())) + .collect(Collectors.toList()), + true); + + discordLinkPlayer.linkedRole(true); + Player player = DiscordLink.getPlugin().getProxy().getPlayer(discordLinkPlayer.getUuid()).orElse(null); + User user = Utilities.getLuckPerms().getUserManager().getUser(discordLinkPlayer.getUuid()); + Guild guild = event.getGuild(); + Member member = event.getMember(); + if (guild == null || member == null) { + handleError("Unable to find guild", event); + return; + } + if (player != null || user != null) + DiscordLink.getPlugin().getBot().changeNick( + guild.getIdLong(), + member.getIdLong(), + player == null ? + user.getUsername() : + player.getUsername()); + else + DiscordLink.getPlugin().getBot().changeNick( + guild.getIdLong(), + member.getIdLong(), + discordLinkPlayer.getUsername()); + + event.replyEmbeds(Utilities.genericSuccessEmbed("Success","You have successfully linked " + + discordLinkPlayer.getUsername() + " with " + + discordLinkPlayer.getDiscordUsername() + "!")) + .setEphemeral(true) + .queue(result -> result.deleteOriginal().queueAfter(5, TimeUnit.SECONDS)); + + DiscordLinkPlayer.addDiscordLinkPlayer(discordLinkPlayer); + DiscordLink.getPlugin().getDatabase().syncPlayer(discordLinkPlayer); + DiscordLink.getPlugin().getDatabase().syncRoles(discordLinkPlayer); + DiscordLink.getPlugin().getCache().removeCachedPlayer(discordLinkPlayer.getUuid()); + } + + private String getUsername(UUID uuid) { + Optional player = DiscordLink.getPlugin().getProxy().getPlayer(uuid); + if (player.isPresent()) + return player.get().getUsername(); + + User user = Utilities.getLuckPerms().getUserManager().getUser(uuid); + if (user != null) + return user.getUsername(); + + return "No User"; + } + + private UUID getUUID(Integer code) { + if (code == null) + return null; + return DiscordLink.getPlugin().getCache().getUUID(String.valueOf(code)); + } + + private void handleError(String text, SlashCommandInteractionEvent event) { + event.replyEmbeds(Utilities.genericErrorEmbed("Error", text)) + .setEphemeral(true) + .queue(res -> res.deleteOriginal().queueAfter(5, TimeUnit.SECONDS)); + } + @Override + public void suggest(CommandAutoCompleteInteractionEvent event) { + + } + + @Override + public CommandData getCommandData() { + return null; + } + + @Override + public long getChannelId() { + return BotConfig.DISCORD.LINK_CHANNEL; + } +} diff --git a/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java b/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java index e77c736..c69f4b3 100644 --- a/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java +++ b/src/main/java/com/alttd/proxydiscordlink/util/Utilities.java @@ -1,15 +1,16 @@ package com.alttd.proxydiscordlink.util; import com.alttd.proxydiscordlink.DiscordLink; -import com.alttd.proxydiscordlink.bot.commandManager.CommandManager; import com.alttd.proxydiscordlink.bot.objects.DiscordRole; import com.alttd.proxydiscordlink.config.BotConfig; import com.alttd.proxydiscordlink.config.Config; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; +import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; 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.interactions.commands.build.CommandData; import net.dv8tion.jda.api.requests.RestAction; @@ -20,13 +21,15 @@ import net.luckperms.api.model.user.User; import net.luckperms.api.node.NodeType; import net.luckperms.api.node.types.InheritanceNode; +import java.awt.*; +import java.util.List; import java.util.*; import java.util.stream.Collectors; public class Utilities { private static LuckPerms luckPerms; - private static MiniMessage miniMessage = MiniMessage.miniMessage(); + private static final MiniMessage miniMessage = MiniMessage.miniMessage(); public static LuckPerms getLuckPerms() { if (luckPerms == null) @@ -137,19 +140,43 @@ public class Utilities { .collect(Collectors.toList()); } - public static void registerCommand(CommandManager commandManager, JDA jda, CommandData commandData, String commandName) { + public static void registerCommand(JDA jda, CommandData commandData) { Guild guild = jda.getGuildById(BotConfig.DISCORD.GUILD_ID); if (guild == null) { ALogger.error("Unable to find guild id to register commands"); return; } - registerCommand(guild, commandData, commandName); + registerCommand(guild, commandData); } - public static void registerCommand(Guild guild, CommandData commandData, String commandName) { + public static void registerCommand(Guild guild, CommandData commandData) { guild.upsertCommand(commandData).queue(RestAction.getDefaultSuccess(), Utilities::handleFailure); } + public static MessageEmbed genericErrorEmbed(String title, String desc) { + return new EmbedBuilder() + .setTitle(title) + .setDescription(desc) + .setColor(Color.RED) + .build(); + } + + public static MessageEmbed genericSuccessEmbed(String title, String desc) { + return new EmbedBuilder() + .setTitle(title) + .setDescription(desc) + .setColor(Color.GREEN) + .build(); + } + + public static MessageEmbed genericWaitingEmbed(String title, String desc) { + return new EmbedBuilder() + .setTitle(title) + .setDescription(desc) + .setColor(Color.BLUE) + .build(); + } + public static void ignoreSuccess(Object o) { // IDK I thought this looked nicer in the .queue call }