From 8f45b7039a279e50fe06f50f196540c3deb5fdb0 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Thu, 31 Mar 2022 22:08:50 +0200 Subject: [PATCH] did a lot of work on poll command --- build.gradle.kts | 4 +- gradlew | 2 +- .../alttd/commandManager/CommandManager.java | 38 +++- .../alttd/commandManager/CommandScope.java | 5 + .../alttd/commandManager/DiscordCommand.java | 12 +- .../com/alttd/commandManager/ScopeInfo.java | 20 ++ .../com/alttd/commandManager/SubCommand.java | 27 +++ .../commandManager/commands/CommandEmbed.java | 4 - .../commandManager/commands/CommandHelp.java | 162 +++++++-------- .../commands/PollCommand/CommandPoll.java | 186 ++++++++++++++++++ .../commands/PollCommand/SubCommandAdd.java | 27 +++ .../PollCommand/SubCommandAddButton.java | 26 +++ .../commands/PollCommand/SubCommandClose.java | 26 +++ .../SubCommandEditDescription.java | 26 +++ .../PollCommand/SubCommandEditTitle.java | 26 +++ .../commands/PollCommand/SubCommandOpen.java | 26 +++ .../PollCommand/SubCommandRemoveButton.java | 26 +++ .../PollCommand/SubCommandResults.java | 26 +++ .../java/com/alttd/config/MessagesConfig.java | 20 +- .../java/com/alttd/config/SettingsConfig.java | 17 ++ .../java/com/alttd/database/Database.java | 74 +++++++ .../alttd/permissions/PermissionManager.java | 14 ++ src/main/java/com/alttd/util/Logger.java | 73 ++++++- .../com/alttd/util/OptionMappingParsing.java | 33 ++++ src/main/java/com/alttd/util/Util.java | 42 ++++ 25 files changed, 826 insertions(+), 116 deletions(-) create mode 100644 src/main/java/com/alttd/commandManager/CommandScope.java create mode 100644 src/main/java/com/alttd/commandManager/ScopeInfo.java create mode 100644 src/main/java/com/alttd/commandManager/SubCommand.java delete mode 100644 src/main/java/com/alttd/commandManager/commands/CommandEmbed.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/CommandPoll.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAdd.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAddButton.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandClose.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditDescription.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditTitle.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandOpen.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandRemoveButton.java create mode 100644 src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandResults.java create mode 100644 src/main/java/com/alttd/database/Database.java create mode 100644 src/main/java/com/alttd/util/OptionMappingParsing.java diff --git a/build.gradle.kts b/build.gradle.kts index d8842ee..2458d32 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,8 +52,8 @@ tasks { dependencies { // JDA - implementation("net.dv8tion:JDA:5.0.0-alpha.3") { - shadow("net.dv8tion:JDA:5.0.0-alpha.3") { + implementation("net.dv8tion:JDA:5.0.0-alpha.9") { + shadow("net.dv8tion:JDA:5.0.0-alpha.9") { exclude("opus-java") // exclude audio } // MySQL diff --git a/gradlew b/gradlew index 4f906e0..744e882 100755 --- a/gradlew +++ b/gradlew @@ -72,7 +72,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) diff --git a/src/main/java/com/alttd/commandManager/CommandManager.java b/src/main/java/com/alttd/commandManager/CommandManager.java index 28cbb23..d381f0b 100644 --- a/src/main/java/com/alttd/commandManager/CommandManager.java +++ b/src/main/java/com/alttd/commandManager/CommandManager.java @@ -1,9 +1,16 @@ package com.alttd.commandManager; +import com.alttd.database.Database; +import com.alttd.util.Logger; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.jetbrains.annotations.NotNull; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -11,27 +18,38 @@ import java.util.List; public class CommandManager extends ListenerAdapter { private final List commands; - private final HashMap commandPrefixes; public CommandManager() { commands = List.of(); - commandPrefixes = null;//TODO query; } @Override - public void onMessageReceived(@NotNull MessageReceivedEvent event) { - String[] s = event.getMessage().getContentRaw().split(" "); - if (s.length < 1) - return; - String command = s[0]; - String[] args = Arrays.copyOfRange(s, 1, s.length); + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + } public List getCommands() { return commands; } - public String getPrefix(long guildId) { - return commandPrefixes.getOrDefault(guildId, "!"); + public List getActiveLocations(String command) { //TODO make this cache results + String sql = "SELECT FROM commands WHERE command_name = ?"; + List scopeInfoList = new ArrayList<>(); + + try { + PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql); + statement.setString(1, command.toLowerCase()); + + ResultSet resultSet = statement.executeQuery(); + + while (resultSet.next()) { + scopeInfoList.add(new ScopeInfo( + CommandScope.valueOf(resultSet.getString("scope")), + resultSet.getLong("location_id"))); + } + } catch (SQLException exception) { + Logger.sql(exception); + } + return scopeInfoList; } } diff --git a/src/main/java/com/alttd/commandManager/CommandScope.java b/src/main/java/com/alttd/commandManager/CommandScope.java new file mode 100644 index 0000000..4b517de --- /dev/null +++ b/src/main/java/com/alttd/commandManager/CommandScope.java @@ -0,0 +1,5 @@ +package com.alttd.commandManager; + +public enum CommandScope { + GLOBAL, GUILD, USER +} diff --git a/src/main/java/com/alttd/commandManager/DiscordCommand.java b/src/main/java/com/alttd/commandManager/DiscordCommand.java index 021a0f3..a83941f 100644 --- a/src/main/java/com/alttd/commandManager/DiscordCommand.java +++ b/src/main/java/com/alttd/commandManager/DiscordCommand.java @@ -1,10 +1,6 @@ package com.alttd.commandManager; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.User; - -import java.util.List; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; public abstract class DiscordCommand { @@ -14,9 +10,7 @@ public abstract class DiscordCommand { return "command." + getName(); } - public abstract String execute(String[] args, Member commandSource, TextChannel textChannel); - - public abstract String execute(String[] args, User commandSource, TextChannel textChannel); + public abstract void execute(SlashCommandInteractionEvent event); public abstract String getHelpMessage(); @@ -24,6 +18,4 @@ public abstract class DiscordCommand { return getHelpMessage(); } - public abstract List getAliases(); - } diff --git a/src/main/java/com/alttd/commandManager/ScopeInfo.java b/src/main/java/com/alttd/commandManager/ScopeInfo.java new file mode 100644 index 0000000..a5339c5 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/ScopeInfo.java @@ -0,0 +1,20 @@ +package com.alttd.commandManager; + +public class ScopeInfo { + + CommandScope scope; + long id; + + public ScopeInfo(CommandScope scope, long id) { + this.scope = scope; + this.id = id; + } + + public CommandScope getScope() { + return scope; + } + + public long getId() { + return id; + } +} diff --git a/src/main/java/com/alttd/commandManager/SubCommand.java b/src/main/java/com/alttd/commandManager/SubCommand.java new file mode 100644 index 0000000..c284d78 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/SubCommand.java @@ -0,0 +1,27 @@ +package com.alttd.commandManager; + +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public abstract class SubCommand { + + private final DiscordCommand parent; + + protected SubCommand(DiscordCommand parent) { + this.parent = parent; + } + + public DiscordCommand getParent() { + return parent; + } + + public abstract String getName(); + + public String getPermission() { + return getParent().getPermission() + "." + getName(); + } + + public abstract void execute(SlashCommandInteractionEvent event); + + public abstract String getHelpMessage(); + +} diff --git a/src/main/java/com/alttd/commandManager/commands/CommandEmbed.java b/src/main/java/com/alttd/commandManager/commands/CommandEmbed.java deleted file mode 100644 index 378f1b9..0000000 --- a/src/main/java/com/alttd/commandManager/commands/CommandEmbed.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.alttd.commandManager.commands; - -public class CommandEmbed { -} diff --git a/src/main/java/com/alttd/commandManager/commands/CommandHelp.java b/src/main/java/com/alttd/commandManager/commands/CommandHelp.java index 4f20133..5275d35 100644 --- a/src/main/java/com/alttd/commandManager/commands/CommandHelp.java +++ b/src/main/java/com/alttd/commandManager/commands/CommandHelp.java @@ -1,81 +1,81 @@ -package com.alttd.commandManager.commands; - -import com.alttd.AltitudeBot; -import com.alttd.commandManager.CommandManager; -import com.alttd.commandManager.DiscordCommand; -import com.alttd.config.MessagesConfig; -import com.alttd.permissions.PermissionManager; -import com.alttd.templates.Parser; -import com.alttd.templates.Template; -import com.alttd.util.Logger; -import com.alttd.util.Util; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.PrivateChannel; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.User; - -import java.util.List; -import java.util.Optional; - -public class CommandHelp extends DiscordCommand { - - private final CommandManager commandManager; - - public CommandHelp(CommandManager commandManager) { - this.commandManager = commandManager; - } - - @Override - public String getName() { - return "help"; - } - - @Override - public String execute(String[] args, Member commandSource, TextChannel textChannel) { - return execute(args, textChannel, commandSource.getIdLong(), textChannel.getGuild().getIdLong(), Util.getGroupIds(commandSource)); - } - - @Override - public String execute(String[] args, User commandSource, TextChannel textChannel) { - if (!(textChannel instanceof PrivateChannel)) - Logger.warning("Using User when executing command on Member: % Command: %", commandSource.getAsMention(), getName()); - return execute(args, textChannel, commandSource.getIdLong(), 0, null); - } - - public String execute(String[] args, TextChannel textChannel, long userId, long guildId, List groupIds) { - PermissionManager permissionManager = AltitudeBot.getInstance().getPermissionManager(); - StringBuilder helpMessage = new StringBuilder(); - if (args.length == 0) { - commandManager.getCommands().stream() - .filter(command -> permissionManager.hasPermission( - textChannel, - userId, - groupIds, - command.getPermission())) - .forEach(command -> helpMessage.append(command.getHelpMessage())); - } else { - String arg = args[0].toLowerCase(); - Optional first = commandManager.getCommands().stream() - .filter(command -> command.getName().equals(arg) - || command.getAliases().contains(arg)).findFirst(); - if (first.isEmpty()) - return Parser.parse(MessagesConfig.INVALID_COMMAND_ARGS, - Template.of("args", arg), - Template.of("command", getName()), - Template.of("prefix", commandManager.getPrefix(guildId))); - DiscordCommand discordCommand = first.get(); - helpMessage.append(discordCommand.getExtendedHelpMessage()); - } - return Parser.parse(MessagesConfig.HELP_MESSAGE_TEMPLATE, Template.of("commands", helpMessage.toString())); - } - - @Override - public String getHelpMessage() { - return MessagesConfig.HELP_HELP; - } - - @Override - public List getAliases() { - return null; - } -} +//package com.alttd.commandManager.commands; +// +//import com.alttd.AltitudeBot; +//import com.alttd.commandManager.CommandManager; +//import com.alttd.commandManager.DiscordCommand; +//import com.alttd.config.MessagesConfig; +//import com.alttd.permissions.PermissionManager; +//import com.alttd.templates.Parser; +//import com.alttd.templates.Template; +//import com.alttd.util.Logger; +//import com.alttd.util.Util; +//import net.dv8tion.jda.api.entities.Member; +//import net.dv8tion.jda.api.entities.PrivateChannel; +//import net.dv8tion.jda.api.entities.TextChannel; +//import net.dv8tion.jda.api.entities.User; +// +//import java.util.List; +//import java.util.Optional; +// +//public class CommandHelp extends DiscordCommand { +// +// private final CommandManager commandManager; +// +// public CommandHelp(CommandManager commandManager) { +// this.commandManager = commandManager; +// } +// +// @Override +// public String getName() { +// return "help"; +// } +// +// @Override +// public String execute(String[] args, Member commandSource, TextChannel textChannel) { +// return execute(args, textChannel, commandSource.getIdLong(), textChannel.getGuild().getIdLong(), Util.getGroupIds(commandSource)); +// } +// +// @Override +// public String execute(String[] args, User commandSource, TextChannel textChannel) { +// if (!(textChannel instanceof PrivateChannel)) +// Logger.warning("Using User when executing command on Member: % Command: %", commandSource.getAsMention(), getName()); +// return execute(args, textChannel, commandSource.getIdLong(), 0, null); +// } +// +// public String execute(String[] args, TextChannel textChannel, long userId, long guildId, List groupIds) { +// PermissionManager permissionManager = AltitudeBot.getInstance().getPermissionManager(); +// StringBuilder helpMessage = new StringBuilder(); +// if (args.length == 0) { +// commandManager.getCommands().stream() +// .filter(command -> permissionManager.hasPermission( +// textChannel, +// userId, +// groupIds, +// command.getPermission())) +// .forEach(command -> helpMessage.append(command.getHelpMessage())); +// } else { +// String arg = args[0].toLowerCase(); +// Optional first = commandManager.getCommands().stream() +// .filter(command -> command.getName().equals(arg) +// || command.getAliases().contains(arg)).findFirst(); +// if (first.isEmpty()) +// return Parser.parse(MessagesConfig.INVALID_COMMAND_ARGS, +// Template.of("args", arg), +// Template.of("command", getName()), +// Template.of("prefix", commandManager.getPrefix(guildId))); +// DiscordCommand discordCommand = first.get(); +// helpMessage.append(discordCommand.getExtendedHelpMessage()); +// } +// return Parser.parse(MessagesConfig.HELP_MESSAGE_TEMPLATE, Template.of("commands", helpMessage.toString())); +// } +// +// @Override +// public String getHelpMessage() { +// return MessagesConfig.HELP_HELP; +// } +// +// @Override +// public List getAliases() { +// return null; +// } +//} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/CommandPoll.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/CommandPoll.java new file mode 100644 index 0000000..6b5a30c --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/CommandPoll.java @@ -0,0 +1,186 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.CommandManager; +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.ScopeInfo; +import com.alttd.permissions.PermissionManager; +import com.alttd.util.Logger; +import com.alttd.util.OptionMappingParsing; +import com.alttd.util.Util; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.GuildMessageChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.Commands; +import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.requests.RestAction; + +public class CommandPoll extends DiscordCommand { + + private final CommandManager commandManager; + + public CommandPoll(JDA jda, CommandManager commandManager) { + this.commandManager = commandManager; + SlashCommandData slashCommandData = Commands.slash(getName(), "Create, edit, and manage polls") + .addSubcommands( + new SubcommandData("add", "Add a new poll to a channel") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll should go into", true, true) + .addOption(OptionType.STRING, "title", "Title of the embed (max 256 characters)", true), + new SubcommandData("edit_title", "Edit the title of a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you're editing", true) + .addOption(OptionType.STRING, "title", "The new title for the poll (max 256 characters)", true), + new SubcommandData("edit_description", "Edit the description of a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you're editing", true) + .addOption(OptionType.STRING, "description", "The new description for the poll (max 2048 characters)", true), + new SubcommandData("add_button", "Add a button to a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you're adding a button to", true) + .addOption(OptionType.INTEGER, "button_row", "Row the button should go in (1-5)", true) + .addOption(OptionType.STRING, "button_name", "Name of the button you're adding"), + new SubcommandData("remove_button", "Remove a button from a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you're removing a button from", true) + .addOption(OptionType.STRING, "button_name", "Name of the button you're removing"), + new SubcommandData("open", "Open a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you're opening", true), + new SubcommandData("close", "Close a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you're closing", true), + new SubcommandData("results", "Get the results for a poll") + .addOption(OptionType.CHANNEL, "channel", "Channel this poll is in", true, true) + .addOption(OptionType.INTEGER, "message_id", "Id of the poll you want the results for", true)); + for (ScopeInfo info : commandManager.getActiveLocations(getName())) { + switch (info.getScope()) { + case GLOBAL -> jda.updateCommands().addCommands(slashCommandData).queue(); + case GUILD -> { + Guild guildById = jda.getGuildById(info.getId()); + if (guildById == null) + { + Logger.warning("Tried to add command % to invalid guild %", getName(), String.valueOf(info.getId())); + continue; + } + guildById.updateCommands().addCommands(slashCommandData).queue(RestAction.getDefaultSuccess(), Util::handleFailure); + } + case USER -> Logger.warning("Tried to add command % to user, this is not implemented yet since I don't know how this should work."); + } + } + } + + @Override + public String getName() { + return "poll"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + if (event.getGuild() == null || event.getMember() == null) + { + event.replyEmbeds(Util.guildOnlyCommand(getName())).setEphemeral(true).queue(); + return; + } + if (PermissionManager.getInstance().hasPermission(event.getTextChannel(), event.getMember(), getPermission())) { + event.replyEmbeds(Util.noPermission(getName())).setEphemeral(true).queue(); + return; + } + + String subcommandName = event.getInteraction().getSubcommandName(); + if (subcommandName == null) { + Logger.severe("No subcommand found for %", getName()); + return; + } + + switch (subcommandName) { + case "add" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + String title = OptionMappingParsing.getString("title", event, getName()); + if (title == null) + return; + } + case "edit_title" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + String title = OptionMappingParsing.getString("title", event, getName()); + if (title == null) + return; + } + case "edit_description" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + String description = OptionMappingParsing.getString("description", event, getName()); + if (description == null) + return; + } + case "add_button" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + Long rowLong = OptionMappingParsing.getLong("button_row", event, getName()); + if (rowLong == null) + return; + int row = rowLong.intValue(); + String buttonName = OptionMappingParsing.getString("button_name", event, getName()); + if (buttonName == null) + return; + } + case "remove_button" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + String buttonName = OptionMappingParsing.getString("button_name", event, getName()); + if (buttonName == null) + return; + } + case "open" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + } + case "close" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + } + case "results" -> { + GuildMessageChannel channel = OptionMappingParsing.getGuildChannel("channel", event, getName()); + if (channel == null) + return; + Long messageId = OptionMappingParsing.getLong("message_id", event, getName()); + if (messageId == null) + return; + } + default -> throw new IllegalStateException("Unexpected value: " + subcommandName); + } + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAdd.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAdd.java new file mode 100644 index 0000000..629678e --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAdd.java @@ -0,0 +1,27 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandAdd extends SubCommand { + + protected SubCommandAdd(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "add"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAddButton.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAddButton.java new file mode 100644 index 0000000..3fa1240 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandAddButton.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandAddButton extends SubCommand { + protected SubCommandAddButton(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "add_button"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandClose.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandClose.java new file mode 100644 index 0000000..46de8f4 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandClose.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandClose extends SubCommand { + protected SubCommandClose(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "close"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditDescription.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditDescription.java new file mode 100644 index 0000000..d7de5c5 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditDescription.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandEditDescription extends SubCommand { + protected SubCommandEditDescription(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "edit_description"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditTitle.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditTitle.java new file mode 100644 index 0000000..87fedce --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandEditTitle.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandEditTitle extends SubCommand { + protected SubCommandEditTitle(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "edit_title"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandOpen.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandOpen.java new file mode 100644 index 0000000..b633506 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandOpen.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandOpen extends SubCommand { + protected SubCommandOpen(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "open"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandRemoveButton.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandRemoveButton.java new file mode 100644 index 0000000..2b0be49 --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandRemoveButton.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandRemoveButton extends SubCommand { + protected SubCommandRemoveButton(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "remove_button"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandResults.java b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandResults.java new file mode 100644 index 0000000..5c9a33b --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/PollCommand/SubCommandResults.java @@ -0,0 +1,26 @@ +package com.alttd.commandManager.commands.PollCommand; + +import com.alttd.commandManager.DiscordCommand; +import com.alttd.commandManager.SubCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +public class SubCommandResults extends SubCommand { + protected SubCommandResults(DiscordCommand parent) { + super(parent); + } + + @Override + public String getName() { + return "results"; + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + + } + + @Override + public String getHelpMessage() { + return null; + } +} diff --git a/src/main/java/com/alttd/config/MessagesConfig.java b/src/main/java/com/alttd/config/MessagesConfig.java index 608d844..29d51ef 100644 --- a/src/main/java/com/alttd/config/MessagesConfig.java +++ b/src/main/java/com/alttd/config/MessagesConfig.java @@ -1,5 +1,7 @@ package com.alttd.config; +import net.dv8tion.jda.api.entities.MessageEmbed; + public class MessagesConfig extends AbstractConfig { static MessagesConfig messagesConfig; @@ -21,10 +23,22 @@ public class MessagesConfig extends AbstractConfig { HELP_MESSAGE_TEMPLATE = messagesConfig.getString("help.message-template", HELP_MESSAGE_TEMPLATE); } - public static String INVALID_COMMAND = " is not a valid command."; - public static String INVALID_COMMAND_ARGS = "`` is/are not valid argument(s) for ``.\nFor more info see help "; - private static void loadInvalidCommands() { + + private static void loadPollHelp() { } + public static String INVALID_COMMAND = " is not a valid command."; + public static String INVALID_COMMAND_ARGS = "`` is/are not valid argument(s) for ``.\nFor more info see help "; + public static String GUILD_ONLY_MESSAGE = "Sorry, can only be executed from within a guild."; + public static String NO_PERMISSION_MESSAGE = "Sorry, can only be executed from within a guild."; + public static String INVALID_COMMAND_ARGUMENTS = "Some of the arguments in your command were invalid: "; + private static void loadInvalidCommands() { + INVALID_COMMAND = messagesConfig.getString("messages.invalid_command", INVALID_COMMAND); + INVALID_COMMAND_ARGS = messagesConfig.getString("messages.invalid_command_args", INVALID_COMMAND_ARGS); + GUILD_ONLY_MESSAGE = messagesConfig.getString("messages.guild_only_message", GUILD_ONLY_MESSAGE); + NO_PERMISSION_MESSAGE = messagesConfig.getString("messages.no_permission_message", NO_PERMISSION_MESSAGE); + INVALID_COMMAND_ARGUMENTS = messagesConfig.getString("messages.invalid_command_arguments", INVALID_COMMAND_ARGUMENTS); + } + } diff --git a/src/main/java/com/alttd/config/SettingsConfig.java b/src/main/java/com/alttd/config/SettingsConfig.java index 045a013..f0bd65c 100644 --- a/src/main/java/com/alttd/config/SettingsConfig.java +++ b/src/main/java/com/alttd/config/SettingsConfig.java @@ -15,8 +15,25 @@ public class SettingsConfig extends AbstractConfig { } public static String TOKEN = "token"; + private void loadSettings() { TOKEN = settingsConfig.getString("settings.token", TOKEN); } + public static String DATABASE_DRIVER = "mysql"; + public static String DATABASE_IP = "localhost"; + public static String DATABASE_PORT = "3306"; + public static String DATABASE_NAME = "discordLink"; + public static String DATABASE_USERNAME = "root"; + public static String DATABASE_PASSWORD = "root"; + + private void loadDatabase() { + DATABASE_DRIVER = settingsConfig.getString("settings.database_driver", DATABASE_DRIVER); + DATABASE_IP = settingsConfig.getString("settings.database_ip", DATABASE_IP); + DATABASE_PORT = settingsConfig.getString("settings.database_port", DATABASE_PORT); + DATABASE_NAME = settingsConfig.getString("settings.database_name", DATABASE_NAME); + DATABASE_USERNAME = settingsConfig.getString("settings.database_username", DATABASE_USERNAME); + DATABASE_PASSWORD = settingsConfig.getString("settings.database_password", DATABASE_PASSWORD); + } + } diff --git a/src/main/java/com/alttd/database/Database.java b/src/main/java/com/alttd/database/Database.java new file mode 100644 index 0000000..fabad35 --- /dev/null +++ b/src/main/java/com/alttd/database/Database.java @@ -0,0 +1,74 @@ +package com.alttd.database; + +import com.alttd.config.SettingsConfig; +import com.alttd.util.Logger; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Objects; + +public class Database { + private static Database instance = null; + private Connection connection; + + private Database() { + instance = this; + + try { + instance.openConnection(); + } catch (Exception e) { + Logger.exception(e); + } + } + + private void openConnection() throws SQLException { + if (connection != null && !connection.isClosed()) { + return; + } + + synchronized (this) { + if (connection != null && !connection.isClosed()) { + return; + } + try { + Class.forName("com.mysql.jdbc.Driver"); + } catch (ClassNotFoundException e) { + Logger.exception(e); + } + connection = DriverManager.getConnection( + "jdbc:" + SettingsConfig.DATABASE_DRIVER + + "://" + SettingsConfig.DATABASE_IP + + ":" + SettingsConfig.DATABASE_PORT + + "/" + + SettingsConfig.DATABASE_NAME, + SettingsConfig.DATABASE_USERNAME, + SettingsConfig.DATABASE_PASSWORD); + } + } + + /** + * Returns the connection for the database + * @return Returns the connection. + */ + public Connection getConnection() { + try { + instance.openConnection(); + } + catch (SQLException e) { + Logger.sql(e); + } + catch (Exception e){ + Logger.exception(e); + } + + return instance.connection; + } + + /** + * Sets the connection for this instance + */ + public static Database getDatabase() { + return Objects.requireNonNullElseGet(instance, Database::new); + } +} diff --git a/src/main/java/com/alttd/permissions/PermissionManager.java b/src/main/java/com/alttd/permissions/PermissionManager.java index fa37ac3..a686d62 100644 --- a/src/main/java/com/alttd/permissions/PermissionManager.java +++ b/src/main/java/com/alttd/permissions/PermissionManager.java @@ -1,6 +1,7 @@ package com.alttd.permissions; import com.alttd.util.Logger; +import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.*; import java.util.HashMap; @@ -9,6 +10,7 @@ import java.util.stream.Collectors; public class PermissionManager { + private static PermissionManager instance = null; HashMap> userPermissions; HashMap> groupPermissions; HashMap> channelEnabledCommands; @@ -22,6 +24,14 @@ public class PermissionManager { this.groupPermissions = groupPermissions; this.channelEnabledCommands = channelEnabledCommands; this.privateEnabledCommands = privateEnabledCommands; + instance = this; + } + + public boolean hasPermission(TextChannel textChannel, Member member, String permission) { + return hasPermission(textChannel, + member.getIdLong(), + member.getRoles().stream().map(ISnowflake::getIdLong).collect(Collectors.toList()), + permission); } public boolean hasPermission(TextChannel textChannel, long userId, List groupIds, String permission) { @@ -60,4 +70,8 @@ public class PermissionManager { return permissions.contains(permission); } + public static PermissionManager getInstance() { + return instance; + } + } diff --git a/src/main/java/com/alttd/util/Logger.java b/src/main/java/com/alttd/util/Logger.java index 998702b..d32f558 100644 --- a/src/main/java/com/alttd/util/Logger.java +++ b/src/main/java/com/alttd/util/Logger.java @@ -1,26 +1,89 @@ package com.alttd.util; +import com.alttd.AltitudeBot; + +import java.io.File; +import java.io.IOException; +import java.sql.SQLException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.FileHandler; +import java.util.logging.Level; + public class Logger { //TODO make this log to a file - private static final java.util.logging.Logger logger; + private static final java.util.logging.Logger info; + private static final java.util.logging.Logger error; + private static final java.util.logging.Logger sql; static { - logger = java.util.logging.Logger.getLogger("DiscordBot"); + File logDir = new File(AltitudeBot.getInstance().getDataFolder() + File.pathSeparator + "logs"); + if (!logDir.exists()) + { + try { + if (!logDir.createNewFile() || !logDir.mkdir()) { + System.out.println("UNABLE TO CREATE LOGGING DIRECTORY"); + System.exit(1); + } + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + + info = java.util.logging.Logger.getLogger("info"); + error = java.util.logging.Logger.getLogger("error"); + sql = java.util.logging.Logger.getLogger("sql"); + info.setLevel(Level.ALL); + error.setLevel(Level.ALL); + sql.setLevel(Level.ALL); + + DateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd"); + Date date = new Date(); + String formattedTime = dateFormat.format(date.getTime()); + + try { + info.addHandler(new FileHandler(logDir.getAbsolutePath() + File.pathSeparator + + formattedTime + "info.log")); + error.addHandler(new FileHandler(logDir.getAbsolutePath() + File.pathSeparator + + formattedTime + "error.log")); + sql.addHandler(new FileHandler(logDir.getAbsolutePath() + File.pathSeparator + + formattedTime + "sql.log")); + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } } public static void info(String message, String... replacements) { message = replace(message, replacements); - logger.info(message); + info.info(message); } public static void warning(String message, String... replacements) { message = replace(message, replacements); - logger.warning(message); + error.warning(message); } public static void severe(String message, String... replacements) { message = replace(message, replacements); - logger.severe(message); + error.severe(message); + } + + public static void sql(String message) { + sql.info(message); + } + + public static void sql(SQLException exception) { + exception.printStackTrace(); + sql.info("SQLState: " + exception.getSQLState() + "\n"); + sql.severe("Error:\n" + exception.getMessage()); + } + + public static void exception(Exception exception) { + exception.printStackTrace(); + error.severe("Error:\n" + exception.getMessage()); } private static String replace(String message, String... replacements) { diff --git a/src/main/java/com/alttd/util/OptionMappingParsing.java b/src/main/java/com/alttd/util/OptionMappingParsing.java new file mode 100644 index 0000000..b3f7c93 --- /dev/null +++ b/src/main/java/com/alttd/util/OptionMappingParsing.java @@ -0,0 +1,33 @@ +package com.alttd.util; + +import net.dv8tion.jda.api.entities.GuildMessageChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; + +public class OptionMappingParsing { + + public static String getString(String optionName, SlashCommandInteractionEvent event, String commandName) { + OptionMapping optionMappingString = event.getInteraction().getOption(optionName); + String text = optionMappingString == null ? null : optionMappingString.getAsString(); + if (text == null) + event.replyEmbeds(Util.invalidCommand(commandName, "Not a valid string or didn't give input for " + optionName, event.getInteraction())).setEphemeral(true).queue(); + return text; + } + + public static GuildMessageChannel getGuildChannel(String optionName, SlashCommandInteractionEvent event, String commandName) { + OptionMapping optionMappingChannel = event.getInteraction().getOption(optionName); + GuildMessageChannel messageChannel = optionMappingChannel == null ? null : optionMappingChannel.getAsMessageChannel(); + if (messageChannel == null) + event.replyEmbeds(Util.invalidCommand(commandName, "Not a valid text channel or didn't give input for " + optionName, event.getInteraction())).setEphemeral(true).queue(); + return messageChannel; + } + + public static Long getLong(String optionName, SlashCommandInteractionEvent event, String commandName) { + OptionMapping optionMappingLong = event.getInteraction().getOption(optionName); + if (optionMappingLong == null) { + event.replyEmbeds(Util.invalidCommand(commandName, "Not a valid number or didn't give input for " + optionName, event.getInteraction())).setEphemeral(true).queue(); + return null; + } + return optionMappingLong.getAsLong(); + } +} diff --git a/src/main/java/com/alttd/util/Util.java b/src/main/java/com/alttd/util/Util.java index 0a76f13..f074859 100644 --- a/src/main/java/com/alttd/util/Util.java +++ b/src/main/java/com/alttd/util/Util.java @@ -1,8 +1,17 @@ package com.alttd.util; +import com.alttd.config.MessagesConfig; +import com.alttd.templates.Parser; +import com.alttd.templates.Template; +import net.dv8tion.jda.api.EmbedBuilder; 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.Command; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction; +import java.awt.*; import java.util.List; import java.util.stream.Collectors; @@ -12,4 +21,37 @@ public class Util { .map(Role::getIdLong) .collect(Collectors.toList()); } + + public static void handleFailure(Throwable failure) { + Logger.warning(failure.getMessage()); + } + + public static MessageEmbed guildOnlyCommand(String commandName) { + return new EmbedBuilder() + .setTitle("Guild Only") + .setDescription(Parser.parse(MessagesConfig.GUILD_ONLY_MESSAGE, Template.of("command", commandName))) + .setColor(Color.RED) + .build(); + } + + public static MessageEmbed noPermission(String commandName) { + return new EmbedBuilder() + .setTitle("No Permission") + .setDescription(Parser.parse(MessagesConfig.NO_PERMISSION_MESSAGE, Template.of("command", commandName))) + .setColor(Color.RED) + .build(); + } + + public static MessageEmbed invalidCommand(String commandName, String error, SlashCommandInteraction interaction) { + EmbedBuilder embedBuilder = new EmbedBuilder() + .setTitle("Invalid Command") + .setDescription(Parser.parse(MessagesConfig.INVALID_COMMAND_ARGUMENTS, + Template.of("command", commandName), + Template.of("error", error))) + .setColor(Color.RED); + for (OptionMapping option : interaction.getOptions()) { + embedBuilder.addField(option.getName(), option.getAsString(), false); + } + return embedBuilder.build(); + } }