/* * Skybot, a multipurpose discord bot * Copyright (C) 2017 - 2020 Duncan "duncte123" Sterken & Ramid "ramidzkh" Khan & Maurice R S "Sanduhr32" * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package ml.duncte123.skybot.commands.guild.owner; import kotlin.Triple; import ml.duncte123.skybot.Author; import ml.duncte123.skybot.Authors; import ml.duncte123.skybot.CommandManager; import ml.duncte123.skybot.objects.command.Command; import ml.duncte123.skybot.objects.command.CommandCategory; import ml.duncte123.skybot.objects.command.CommandContext; import ml.duncte123.skybot.objects.command.custom.CustomCommand; import ml.duncte123.skybot.objects.command.custom.CustomCommandImpl; import ml.duncte123.skybot.objects.guild.GuildSettings; import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import javax.annotation.Nonnull; import java.util.List; import static me.duncte123.botcommons.messaging.MessageUtils.*; @Authors(authors = { @Author(nickname = "Sanduhr32", author = "Maurice R S"), @Author(nickname = "duncte123", author = "Duncan Sterken") }) public class CustomCommandCommand extends Command { private final List<String> systemInvokes = List.of("add", "new", "edit", "change", "delete", "remove", "raw"); public CustomCommandCommand() { this.category = CommandCategory.ADMINISTRATION; this.name = "customcommand"; this.aliases = new String[]{ "cc", "customcommands", }; this.help = "Create, edit and delete custom commands"; // FIXME: figure out a better way of showing the subcommands this.usage = "list` => Shows a list of all the custom commands\n" + " `{prefix}" + this.name + " new <name> <text>` => Creates a new custom command\n" + " `{prefix}" + this.name + " edit <name> <text>` => Edits a custom command\n" + " `{prefix}" + this.name + " raw <name>` => Shows the raw value of a custom command\n" + " `{prefix}" + this.name + " delete <name>` => Deletes a custom command"; } @Override public void execute(@Nonnull CommandContext ctx) { final GuildMessageReceivedEvent event = ctx.getEvent(); final List<String> args = ctx.getArgsWithQuotes(); final CommandManager manager = ctx.getCommandManager(); if (args.isEmpty()) { sendMsg(event, "Insufficient arguments use `" + ctx.getPrefix() + "help customcommand`"); return; } switch (args.size()) { case 1: listCustomCommands(args.get(0), event, manager, ctx); break; case 2: deleteOrShowCustomCommand(args, event, manager, ctx.getPrefix()); break; default: addOrEditCustomCommand(args, event, manager, ctx.getPrefix()); break; } } private void listCustomCommands(String arg, GuildMessageReceivedEvent event, CommandManager manager, CommandContext ctx) { if (arg.equalsIgnoreCase("list")) { final GuildSettings s = ctx.getGuildSettings(); final StringBuilder sb = new StringBuilder(); manager.getCustomCommands().stream() .filter(c -> c.getGuildId() == event.getGuild().getIdLong()) .forEach(cmd -> sb.append(s.getCustomPrefix()) .append(cmd.getName()) .append("\n") ); sendMsg(event, new MessageBuilder().append("Custom Commands for this server").append('\n') .appendCodeBlock(sb.toString(), "ldif").build()); } else { sendMsg(event, "Insufficient arguments use `" + ctx.getPrefix() + "help customcommand`"); } } private void deleteOrShowCustomCommand(List<String> args, GuildMessageReceivedEvent event, CommandManager manager, String prefix) { final String commandName = args.get(1); final long guildId = event.getGuild().getIdLong(); //Check for deleting if (args.get(0).equalsIgnoreCase("raw")) { if (!commandExists(commandName, guildId, manager)) { sendMsg(event, "No command was found for this name"); return; } final CustomCommand cmd = manager.getCustomCommand(commandName, guildId); final String escaped = cmd.getMessage().replaceAll("`", ""); sendMsg(event, "Raw data for `" + commandName + "`:```pascal\n" + escaped + "\n```"); } else if (args.get(0).equalsIgnoreCase("delete") || args.get(0).equalsIgnoreCase("remove")) { if (!isAdmin(event)) { sendMsg(event, "You need the \"Administrator\" permission to add or remove commands"); return; } if (!commandExists(commandName, guildId, manager)) { sendMsg(event, "No command was found for this name"); return; } final boolean success = manager.removeCustomCommand(commandName, guildId); final Message msg = event.getMessage(); if (!success) { sendErrorWithMessage(msg, "Failed to delete custom command."); return; } sendSuccess(msg); } else { sendMsg(event, "Invalid arguments use `" + prefix + "help customcommand`"); } } private void addOrEditCustomCommand(List<String> args, GuildMessageReceivedEvent event, CommandManager manager, String prefix) { if (args.size() < 3 && !systemInvokes.contains(args.get(0))) { sendMsg(event, "Invalid arguments use `" + prefix + "help customcommand`"); return; } if (!isAdmin(event)) { sendMsg(event, "You need the \"Administrator\" permission to add or remove commands"); return; } //new command final String commandName = args.get(1); if (commandName.length() > 25) { sendErrorWithMessage(event.getMessage(), "The maximum length of the command name is 25 characters"); return; } final String commandAction = String.join(" ", args.subList(2, args.size())); final long guildId = event.getGuild().getIdLong(); if (commandExists(commandName, guildId, manager)) { editCustomCommand(args, event, manager, commandName, commandAction, guildId); return; } createCustomCommand(event, manager, commandName, commandAction, guildId); } private void createCustomCommand(GuildMessageReceivedEvent event, CommandManager manager, String commandName, String commandAction, long guildId) { try { final Triple<Boolean, Boolean, Boolean> result = registerCustomCommand(commandName, commandAction, guildId, manager); if (result.getFirst()) { sendMsg(event, "Command added."); return; } final String error = "Failed to add custom command. \n Reason(s): %s"; String reason = ""; if (result.getSecond()) { reason += "The command was already found.\n"; } else if (result.getThird()) { reason += "You reached the limit of 50 custom commands on this server.\n"; } else if (!result.getSecond() && !result.getThird()) { reason += "We have an database issue."; } sendMsg(event, String.format(error, reason)); } catch (IllegalArgumentException e) { sendMsg(event, "Could not add command: " + e.getMessage()); } } private void editCustomCommand(List<String> args, GuildMessageReceivedEvent event, CommandManager manager, String commandName, String commandAction, long guildId) { if (!args.get(0).equalsIgnoreCase("edit") && !args.get(0).equalsIgnoreCase("change")) { sendMsg(event, "A command already exists for this server."); return; } if (editCustomCommand(manager.getCustomCommand(commandName, guildId), commandAction, manager)) { sendMsg(event, "The command has been updated."); } } @SuppressWarnings("BooleanMethodIsAlwaysInverted") private boolean isAdmin(GuildMessageReceivedEvent event) { return event.getMember().hasPermission(event.getChannel(), Permission.ADMINISTRATOR); } private Triple<Boolean, Boolean, Boolean> registerCustomCommand(String name, String action, long guildId, CommandManager manager) { return registerCustomCommand(name, action, guildId, false, manager); } private boolean editCustomCommand(CustomCommand customCommand, String newMessage, CommandManager manager) { return editCustomCommand(customCommand, newMessage, false, manager); } public static boolean commandExists(String name, long guild, CommandManager manager) { return manager.getCustomCommand(name, guild) != null; } public static Triple<Boolean, Boolean, Boolean> registerCustomCommand(String name, String action, long guildId, boolean autoresponse, CommandManager manager) { return manager.registerCustomCommand(new CustomCommandImpl(name, action, guildId, autoresponse)); } public static boolean editCustomCommand(CustomCommand customCommand, String newMessage, boolean autoresponse, CommandManager manager) { final CustomCommand cmd = new CustomCommandImpl( customCommand.getName(), newMessage, customCommand.getGuildId(), autoresponse ); return manager.editCustomCommand(cmd); } }