From 3a405a5ba4836ba5772a55b54f9b5d0756171fea Mon Sep 17 00:00:00 2001 From: HypherionMC Date: Sun, 6 Aug 2023 02:37:27 +0200 Subject: [PATCH] [FEAT] New Commands system --- gradle.properties | 2 +- .../sdlink/core/config/SDLinkConfig.java | 6 +-- .../config/impl/LinkedCommandsConfig.java | 9 +--- .../core/config/impl/MinecraftCommands.java | 31 +++++++++++++ .../core/discord/commands/CommandManager.java | 3 +- .../commands/slash/mc/MCSlashCommand.java | 19 +++++--- .../discord/events/DiscordEventHandler.java | 2 + .../discord/hooks/DiscordMessageHooks.java | 3 ++ .../discord/hooks/MinecraftCommandHook.java | 44 +++++++++++++++++++ .../sdlink/core/managers/RoleManager.java | 21 +++++---- .../services/helpers/IMinecraftHelper.java | 5 ++- 11 files changed, 115 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/hypherionmc/sdlink/core/config/impl/MinecraftCommands.java create mode 100644 src/main/java/com/hypherionmc/sdlink/core/discord/hooks/MinecraftCommandHook.java diff --git a/gradle.properties b/gradle.properties index 6edae45..7067b06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ version_major=0 version_minor=0 -version_patch=15 +version_patch=16 shade_group=com.hypherionmc.sdlink.shaded. diff --git a/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java b/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java index a4d8210..a2122f7 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java +++ b/src/main/java/com/hypherionmc/sdlink/core/config/SDLinkConfig.java @@ -24,7 +24,7 @@ public class SDLinkConfig extends ModuleConfig { // DO NOT REMOVE TRANSIENT HERE... OTHERWISE, THE STUPID CONFIG LIBRARY // WILL TRY TO WRITE THESE TO THE CONFIG public transient static SDLinkConfig INSTANCE; - public transient static int configVer = 6; + public transient static int configVer = 7; @Path("general") @SpecComment("General Mod Config") @@ -58,9 +58,9 @@ public class SDLinkConfig extends ModuleConfig { @SpecComment("Enable or Disable certain bot commands") public BotCommandsConfig botCommands = new BotCommandsConfig(); - @Path("linkedCommands") + @Path("minecraftCommands") @SpecComment("Execute Minecraft commands in Discord") - public LinkedCommandsConfig linkedCommands = new LinkedCommandsConfig(); + public MinecraftCommands linkedCommands = new MinecraftCommands(); @Path("ignoredMessages") @SpecComment("Configure messages that will be ignored when relaying to discord") diff --git a/src/main/java/com/hypherionmc/sdlink/core/config/impl/LinkedCommandsConfig.java b/src/main/java/com/hypherionmc/sdlink/core/config/impl/LinkedCommandsConfig.java index e4ae3c7..62affea 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/config/impl/LinkedCommandsConfig.java +++ b/src/main/java/com/hypherionmc/sdlink/core/config/impl/LinkedCommandsConfig.java @@ -4,17 +4,11 @@ */ package com.hypherionmc.sdlink.core.config.impl; -import me.hypherionmc.moonconfig.core.conversion.Path; -import me.hypherionmc.moonconfig.core.conversion.SpecComment; - -import java.util.ArrayList; -import java.util.List; - /** * @author HypherionSA * Main Config Structure to control Discord -> MC Commands */ -public class LinkedCommandsConfig { +/*public class LinkedCommandsConfig { @Path("enabled") @SpecComment("Should linked commands be enabled") @@ -39,3 +33,4 @@ public class LinkedCommandsConfig { } } +*/ \ No newline at end of file diff --git a/src/main/java/com/hypherionmc/sdlink/core/config/impl/MinecraftCommands.java b/src/main/java/com/hypherionmc/sdlink/core/config/impl/MinecraftCommands.java new file mode 100644 index 0000000..3e398ce --- /dev/null +++ b/src/main/java/com/hypherionmc/sdlink/core/config/impl/MinecraftCommands.java @@ -0,0 +1,31 @@ +package com.hypherionmc.sdlink.core.config.impl; + +import me.hypherionmc.moonconfig.core.conversion.Path; +import me.hypherionmc.moonconfig.core.conversion.SpecComment; + +import java.util.ArrayList; +import java.util.List; + +public class MinecraftCommands { + + @Path("enabled") + @SpecComment("Allow executing Minecraft commands from Discord") + public boolean enabled = false; + + @Path("prefix") + @SpecComment("Command Prefix. For example ?weather clear") + public String prefix = "?"; + + @Path("permissions") + @SpecComment("List of command permissions") + public List permissions = new ArrayList<>(); + + public static class Command { + public String role = "0"; + + public List commands = new ArrayList<>(); + + public int permissionLevel = 1; + } + +} diff --git a/src/main/java/com/hypherionmc/sdlink/core/discord/commands/CommandManager.java b/src/main/java/com/hypherionmc/sdlink/core/discord/commands/CommandManager.java index 12af504..c37673c 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/discord/commands/CommandManager.java +++ b/src/main/java/com/hypherionmc/sdlink/core/discord/commands/CommandManager.java @@ -12,7 +12,6 @@ import com.hypherionmc.sdlink.core.discord.commands.slash.linking.ConfirmAccount import com.hypherionmc.sdlink.core.discord.commands.slash.linking.LinkAccountCommand; import com.hypherionmc.sdlink.core.discord.commands.slash.linking.UnlinkAccountSlashCommand; import com.hypherionmc.sdlink.core.discord.commands.slash.linking.ViewLinkedAccountsCommand; -import com.hypherionmc.sdlink.core.discord.commands.slash.mc.MCSlashCommand; import com.hypherionmc.sdlink.core.discord.commands.slash.whitelist.ConfirmWhitelistSlashCommand; import com.hypherionmc.sdlink.core.discord.commands.slash.whitelist.UnWhitelistAccountSlashCommand; import com.hypherionmc.sdlink.core.discord.commands.slash.whitelist.ViewWhitelistedAccountsSlashCommand; @@ -70,7 +69,7 @@ public class CommandManager { } if (SDLinkConfig.INSTANCE.linkedCommands.enabled) { - commands.add(new MCSlashCommand()); + //commands.add(new MCSlashCommand()); } } diff --git a/src/main/java/com/hypherionmc/sdlink/core/discord/commands/slash/mc/MCSlashCommand.java b/src/main/java/com/hypherionmc/sdlink/core/discord/commands/slash/mc/MCSlashCommand.java index e8844ef..80057f7 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/discord/commands/slash/mc/MCSlashCommand.java +++ b/src/main/java/com/hypherionmc/sdlink/core/discord/commands/slash/mc/MCSlashCommand.java @@ -4,8 +4,10 @@ */ package com.hypherionmc.sdlink.core.discord.commands.slash.mc; +/*import com.hypherionmc.sdlink.core.accounts.MinecraftAccount; import com.hypherionmc.sdlink.core.config.SDLinkConfig; import com.hypherionmc.sdlink.core.config.impl.LinkedCommandsConfig; +import com.hypherionmc.sdlink.core.database.SDLinkAccount; import com.hypherionmc.sdlink.core.discord.commands.slash.SDLinkSlashCommand; import com.hypherionmc.sdlink.core.managers.RoleManager; import com.hypherionmc.sdlink.core.messaging.Result; @@ -17,8 +19,11 @@ import net.dv8tion.jda.api.interactions.commands.OptionType; import net.dv8tion.jda.api.interactions.commands.build.OptionData; import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import static com.hypherionmc.sdlink.core.managers.DatabaseManager.sdlinkDatabase; + public class MCSlashCommand extends SDLinkSlashCommand { public MCSlashCommand() { @@ -64,18 +69,22 @@ public class MCSlashCommand extends SDLinkSlashCommand { if (!args5.isEmpty()) args.append(" ").append(args5); + sdlinkDatabase.reloadCollection("accounts"); + List accounts = sdlinkDatabase.findAll(SDLinkAccount.class); + Optional account = accounts.stream().filter(u -> u.getDiscordID().equals(event.getMember().getId())).findFirst(); + linkedCommand.ifPresent(command -> { if (!command.discordRole.isEmpty()) { Role role = RoleManager.getCommandRoles().isEmpty() ? null : RoleManager.getCommandRoles().get(command.discordCommand); boolean userRole = role != null && event.getMember().getRoles().stream().anyMatch(r -> r.getIdLong() == role.getIdLong()); if (userRole) { - executeCommand(event, command, args.toString(), event.getMember()); + executeCommand(event, command, args.toString(), event.getMember(), account.orElse(null)); } else { event.reply("You need the " + role.getName() + " role to perform this action").setEphemeral(true).queue(); } } else { - executeCommand(event, command, args.toString(), event.getMember()); + executeCommand(event, command, args.toString(), event.getMember(), account.orElse(null)); } }); @@ -88,8 +97,8 @@ public class MCSlashCommand extends SDLinkSlashCommand { } } - private void executeCommand(SlashCommandEvent event, LinkedCommandsConfig.Command mcCommand, String args, Member member) { - Result result = SDLinkPlatform.minecraftHelper.executeMinecraftCommand(mcCommand.mcCommand, args, member); + private void executeCommand(SlashCommandEvent event, LinkedCommandsConfig.Command mcCommand, String args, Member member, SDLinkAccount account) { + Result result = SDLinkPlatform.minecraftHelper.executeMinecraftCommand(mcCommand.mcCommand, args, member, account); event.reply(result.getMessage()).setEphemeral(true).queue(); } -} +}*/ diff --git a/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java b/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java index 28be6c6..89f9b15 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java +++ b/src/main/java/com/hypherionmc/sdlink/core/discord/events/DiscordEventHandler.java @@ -9,6 +9,7 @@ import com.hypherionmc.sdlink.core.discord.BotController; import com.hypherionmc.sdlink.core.discord.commands.slash.general.ServerStatusSlashCommand; import com.hypherionmc.sdlink.core.discord.hooks.BotReadyHooks; import com.hypherionmc.sdlink.core.discord.hooks.DiscordMessageHooks; +import com.hypherionmc.sdlink.core.discord.hooks.MinecraftCommandHook; import com.hypherionmc.sdlink.core.events.SDLinkReadyEvent; import com.hypherionmc.sdlink.core.managers.CacheManager; import com.hypherionmc.sdlink.core.managers.ChannelManager; @@ -48,6 +49,7 @@ public class DiscordEventHandler extends ListenerAdapter { if (!event.isFromGuild()) return; + MinecraftCommandHook.discordMessageEvent(event); DiscordMessageHooks.discordMessageEvent(event); } diff --git a/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/DiscordMessageHooks.java b/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/DiscordMessageHooks.java index 8d74118..c046001 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/DiscordMessageHooks.java +++ b/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/DiscordMessageHooks.java @@ -28,6 +28,9 @@ public class DiscordMessageHooks { if (event.getAuthor().isBot() && SDLinkConfig.INSTANCE.chatConfig.ignoreBots) return; + if (SDLinkConfig.INSTANCE.linkedCommands.enabled && !SDLinkConfig.INSTANCE.linkedCommands.permissions.isEmpty() && event.getMessage().getContentRaw().startsWith(SDLinkConfig.INSTANCE.linkedCommands.prefix)) + return; + if (SDLinkConfig.INSTANCE.generalConfig.debugging) { BotController.INSTANCE.getLogger().info("Sending Message from {}: {}", event.getAuthor().getName(), event.getMessage().getContentStripped()); } diff --git a/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/MinecraftCommandHook.java b/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/MinecraftCommandHook.java new file mode 100644 index 0000000..85d385e --- /dev/null +++ b/src/main/java/com/hypherionmc/sdlink/core/discord/hooks/MinecraftCommandHook.java @@ -0,0 +1,44 @@ +package com.hypherionmc.sdlink.core.discord.hooks; + +import com.hypherionmc.sdlink.core.config.SDLinkConfig; +import com.hypherionmc.sdlink.core.database.SDLinkAccount; +import com.hypherionmc.sdlink.core.services.SDLinkPlatform; +import net.dv8tion.jda.api.entities.ISnowflake; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; + +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.hypherionmc.sdlink.core.managers.DatabaseManager.sdlinkDatabase; + +public class MinecraftCommandHook { + + public static void discordMessageEvent(MessageReceivedEvent event) { + if (!SDLinkConfig.INSTANCE.linkedCommands.enabled || SDLinkConfig.INSTANCE.linkedCommands.permissions.isEmpty()) + return; + + if (!event.getMessage().getContentRaw().startsWith(SDLinkConfig.INSTANCE.linkedCommands.prefix)) + return; + + Set roles = event.getMember().getRoles().stream().map(ISnowflake::getIdLong).collect(Collectors.toSet()); + roles.add(event.getMember().getIdLong()); + roles.add(0L); + + sdlinkDatabase.reloadCollection("accounts"); + List accounts = sdlinkDatabase.findAll(SDLinkAccount.class); + Optional account = accounts.stream().filter(u -> u.getDiscordID().equals(event.getMember().getId())).findFirst(); + + Integer permLevel = SDLinkConfig.INSTANCE.linkedCommands.permissions.stream().filter(r -> roles.contains(Long.parseLong(r.role))).map(r -> r.permissionLevel).max(Integer::compareTo).orElse(-1); + List commands = SDLinkConfig.INSTANCE.linkedCommands.permissions.stream().filter(c -> roles.contains(Long.parseLong(c.role))).flatMap(c -> c.commands.stream()).filter(s -> !s.isEmpty()).toList(); + + String raw = event.getMessage().getContentRaw().substring(SDLinkConfig.INSTANCE.linkedCommands.prefix.length()); + + if (commands.stream().anyMatch(raw::startsWith)) { + SDLinkPlatform.minecraftHelper.executeMinecraftCommand(raw, Integer.MAX_VALUE, event, account.orElse(null)); + } else { + SDLinkPlatform.minecraftHelper.executeMinecraftCommand(raw, permLevel, event, account.orElse(null)); + } + } +} diff --git a/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java b/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java index d91262c..cd86ab4 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java +++ b/src/main/java/com/hypherionmc/sdlink/core/managers/RoleManager.java @@ -9,7 +9,6 @@ import com.hypherionmc.sdlink.core.discord.BotController; import com.hypherionmc.sdlink.core.util.SystemUtils; import net.dv8tion.jda.api.entities.Role; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,7 +22,7 @@ public class RoleManager { private static Role whitelistedRole; private static Role linkedRole; - private static final HashMap commandRoles = new HashMap<>(); + //private static final HashMap commandRoles = new HashMap<>(); private static final Set autoWhitelistRoles = new HashSet<>(); /** @@ -49,17 +48,17 @@ public class RoleManager { }); } - if (SDLinkConfig.INSTANCE.linkedCommands.enabled) { + /*if (SDLinkConfig.INSTANCE.linkedCommands.enabled) { commandRoles.clear(); - SDLinkConfig.INSTANCE.linkedCommands.commands.forEach(cmd -> { - if (!cmd.discordRole.isEmpty()) { - Role role = getRole(errCount, builder, cmd.discordCommand + " usage", cmd.discordRole); + SDLinkConfig.INSTANCE.linkedCommands.permissions.forEach(cmd -> { + if (!cmd.role.isEmpty() && !cmd.role.equals("0")) { + Role role = getRole(errCount, builder, "Command Usage", cmd.role); if (role != null) { - commandRoles.putIfAbsent(cmd.discordCommand, role); + cmd.commands.forEach(c -> commandRoles.putIfAbsent(c, role)); } } }); - } + }*/ } /** @@ -106,9 +105,9 @@ public class RoleManager { return whitelistedRole; } - public static HashMap getCommandRoles() { - return commandRoles; - } + //public static HashMap getCommandRoles() { + //return commandRoles; + //} public static Set getAutoWhitelistRoles() { return autoWhitelistRoles; diff --git a/src/main/java/com/hypherionmc/sdlink/core/services/helpers/IMinecraftHelper.java b/src/main/java/com/hypherionmc/sdlink/core/services/helpers/IMinecraftHelper.java index c5530bc..9e7856a 100644 --- a/src/main/java/com/hypherionmc/sdlink/core/services/helpers/IMinecraftHelper.java +++ b/src/main/java/com/hypherionmc/sdlink/core/services/helpers/IMinecraftHelper.java @@ -5,9 +5,12 @@ package com.hypherionmc.sdlink.core.services.helpers; import com.hypherionmc.sdlink.core.accounts.MinecraftAccount; +import com.hypherionmc.sdlink.core.database.SDLinkAccount; import com.hypherionmc.sdlink.core.messaging.Result; import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -27,7 +30,7 @@ public interface IMinecraftHelper { List getOnlinePlayers(); long getServerUptime(); String getServerVersion(); - Result executeMinecraftCommand(String command, String args, Member member); + void executeMinecraftCommand(String command, int permLevel, MessageReceivedEvent event, @Nullable SDLinkAccount account); boolean isOnlineMode(); }