From 653e94e0b7a3b4f82caf15a741595ef3c1c5d19f Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 13 Aug 2018 21:24:08 -0700 Subject: [PATCH] Made sub-class of CompositeCommand called ConfirmableCommand This class inherits CompositeCommand and adds the confirming system. It could be renamed Confirmable, like Bukkit has Cancellable for Events. --- .../api/commands/CompositeCommand.java | 99 +------------- .../api/commands/ConfirmableCommand.java | 123 ++++++++++++++++++ .../admin/AdminClearResetsAllCommand.java | 3 +- .../commands/admin/AdminDeleteCommand.java | 9 +- .../commands/admin/AdminRegisterCommand.java | 15 ++- .../api/commands/admin/AdminSchemCommand.java | 3 +- .../commands/island/IslandResetCommand.java | 3 +- .../island/team/IslandTeamKickCommand.java | 3 +- .../island/team/IslandTeamLeaveCommand.java | 7 +- .../commands/BentoBoxReloadCommand.java | 7 +- 10 files changed, 156 insertions(+), 116 deletions(-) create mode 100644 src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java diff --git a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java index f626a4c48..677ca33e5 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/CompositeCommand.java @@ -13,13 +13,11 @@ import java.util.UUID; import java.util.logging.Logger; import java.util.stream.Collectors; -import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitTask; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.Settings; @@ -45,12 +43,12 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi * True if the command is for the player only (not for the console) */ private boolean onlyPlayer = false; - + /** * True if command is a configurable rank */ private boolean configurableRankCommand = false; - + /** * The parameters string for this command. It is the commands followed by a locale reference. */ @@ -102,11 +100,6 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi */ private String topLabel = ""; - /** - * Confirmation tracker - */ - private static Map toBeConfirmed = new HashMap<>(); - /** * Cool down tracker */ @@ -142,19 +135,8 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi if (!getSubCommand("help").isPresent() && !label.equals("help")) { new DefaultHelpCommand(this); } - + } - } - -/* - * This will eventually need to replace the tabComplete method - private static void registerCompletions(Commodore commodore, CompositeCommand command) { - commodore.register(command, LiteralArgumentBuilder.literal(command.getLabel()) - .then(RequiredArgumentBuilder.argument("some-argument", com.mojang.brigadier.arguments.StringArgumentType.string())) - .then(RequiredArgumentBuilder.argument("some-other-argument", BoolArgumentType.bool())) - ); - } -*/ /** * This is the top-level command constructor for commands that have no parent. * @param label - string for this command @@ -201,7 +183,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi this.permissionPrefix = parent.getPermissionPrefix(); // Inherit world this.world = parent.getWorld(); - + // Default references to description and parameters StringBuilder reference = new StringBuilder(); reference.append(label); @@ -677,79 +659,6 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi return topLabel; } - /** - * Tells user to confirm command by retyping - * @param user - user - * @param confirmed - runnable to be executed if confirmed - */ - public void askConfirmation(User user, Runnable confirmed) { - // Check for pending confirmations - if (toBeConfirmed.containsKey(user)) { - if (toBeConfirmed.get(user).getTopLabel().equals(getTopLabel()) && toBeConfirmed.get(user).getLabel().equalsIgnoreCase(getLabel())) { - toBeConfirmed.get(user).getTask().cancel(); - Bukkit.getScheduler().runTask(getPlugin(), toBeConfirmed.get(user).getRunnable()); - toBeConfirmed.remove(user); - return; - } else { - // Player has another outstanding confirmation request that will now be cancelled - user.sendMessage("commands.confirmation.previous-request-cancelled"); - } - } - // Tell user that they need to confirm - user.sendMessage("commands.confirmation.confirm", "[seconds]", String.valueOf(getSettings().getConfirmationTime())); - // Set up a cancellation task - BukkitTask task = Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { - user.sendMessage("commands.confirmation.request-cancelled"); - toBeConfirmed.remove(user); - }, getPlugin().getSettings().getConfirmationTime() * 20L); - - // Add to the global confirmation map - toBeConfirmed.put(user, new Confirmer(getTopLabel(), getLabel(), confirmed, task)); - } - - private class Confirmer { - private final String topLabel; - private final String label; - private final Runnable runnable; - private final BukkitTask task; - - /** - * @param label - command label - * @param runnable - runnable to run when confirmed - * @param task - task ID to cancel when confirmed - */ - Confirmer(String topLabel, String label, Runnable runnable, BukkitTask task) { - this.topLabel = topLabel; - this.label = label; - this.runnable = runnable; - this.task = task; - } - /** - * @return the topLabel - */ - public String getTopLabel() { - return topLabel; - } - /** - * @return the label - */ - public String getLabel() { - return label; - } - /** - * @return the runnable - */ - public Runnable getRunnable() { - return runnable; - } - /** - * @return the task - */ - public BukkitTask getTask() { - return task; - } - } - /** * Set a cool down - can be set by other commands on this one * @param uniqueId - the caller diff --git a/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java new file mode 100644 index 000000000..0687900e5 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java @@ -0,0 +1,123 @@ +package world.bentobox.bentobox.api.commands; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import world.bentobox.bentobox.api.addons.Addon; +import world.bentobox.bentobox.api.user.User; + +/** + * BentoBox Confirmable Command + * Adds ability to confirm a command before execution + * @author tastybento + * @author Poslovitch + */ +public abstract class ConfirmableCommand extends CompositeCommand { + + /** + * Confirmation tracker + */ + private static Map toBeConfirmed = new HashMap<>(); + + /** + * Top level command + * @param addon - addon creating the command + * @param label - string for this command + * @param aliases - aliases + */ + public ConfirmableCommand(Addon addon, String label, String... aliases) { + super(addon, label, aliases); + } + + /** + * Command to register a command from an addon under a parent command (that could be from another addon) + * @param addon - this command's addon + * @param parent - parent command + * @param aliases - aliases for this command + */ + public ConfirmableCommand(Addon addon, CompositeCommand parent, String label, String... aliases ) { + super(addon, parent, label, aliases); + } + + + public ConfirmableCommand(CompositeCommand parent, String label, String... aliases) { + super(parent, label, aliases); + } + + /** + * Tells user to confirm command by retyping + * @param user - user + * @param confirmed - runnable to be executed if confirmed + */ + public void askConfirmation(User user, Runnable confirmed) { + // Check for pending confirmations + if (toBeConfirmed.containsKey(user)) { + if (toBeConfirmed.get(user).getTopLabel().equals(getTopLabel()) && toBeConfirmed.get(user).getLabel().equalsIgnoreCase(getLabel())) { + toBeConfirmed.get(user).getTask().cancel(); + Bukkit.getScheduler().runTask(getPlugin(), toBeConfirmed.get(user).getRunnable()); + toBeConfirmed.remove(user); + return; + } else { + // Player has another outstanding confirmation request that will now be cancelled + user.sendMessage("commands.confirmation.previous-request-cancelled"); + } + } + // Tell user that they need to confirm + user.sendMessage("commands.confirmation.confirm", "[seconds]", String.valueOf(getSettings().getConfirmationTime())); + // Set up a cancellation task + BukkitTask task = Bukkit.getScheduler().runTaskLater(getPlugin(), () -> { + user.sendMessage("commands.confirmation.request-cancelled"); + toBeConfirmed.remove(user); + }, getPlugin().getSettings().getConfirmationTime() * 20L); + + // Add to the global confirmation map + toBeConfirmed.put(user, new Confirmer(getTopLabel(), getLabel(), confirmed, task)); + } + + private class Confirmer { + private final String topLabel; + private final String label; + private final Runnable runnable; + private final BukkitTask task; + + /** + * @param label - command label + * @param runnable - runnable to run when confirmed + * @param task - task ID to cancel when confirmed + */ + Confirmer(String topLabel, String label, Runnable runnable, BukkitTask task) { + this.topLabel = topLabel; + this.label = label; + this.runnable = runnable; + this.task = task; + } + /** + * @return the topLabel + */ + public String getTopLabel() { + return topLabel; + } + /** + * @return the label + */ + public String getLabel() { + return label; + } + /** + * @return the runnable + */ + public Runnable getRunnable() { + return runnable; + } + /** + * @return the task + */ + public BukkitTask getTask() { + return task; + } + } + +} diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminClearResetsAllCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminClearResetsAllCommand.java index a4cd16540..66fda6a51 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminClearResetsAllCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminClearResetsAllCommand.java @@ -6,9 +6,10 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.user.User; -public class AdminClearResetsAllCommand extends CompositeCommand { +public class AdminClearResetsAllCommand extends ConfirmableCommand { public AdminClearResetsAllCommand(CompositeCommand parent) { super(parent, "clearresetsall"); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java index 06db34ebf..1fdf40f6f 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminDeleteCommand.java @@ -6,15 +6,16 @@ import java.util.Optional; import java.util.UUID; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.util.Util; -public class AdminDeleteCommand extends CompositeCommand { +public class AdminDeleteCommand extends ConfirmableCommand { public AdminDeleteCommand(CompositeCommand parent) { super(parent, "delete"); } - + @Override public void setup() { setPermission("admin.delete"); @@ -48,13 +49,13 @@ public class AdminDeleteCommand extends CompositeCommand { askConfirmation(user, () -> deletePlayer(user, targetUUID)); return false; } - + private void deletePlayer(User user, UUID targetUUID) { // Delete player and island user.sendMessage("commands.admin.delete.deleted-island", "[xyz]", Util.xyz(getIslands().getIsland(getWorld(), targetUUID).getCenter().toVector())); getIslands().deleteIsland(getIslands().getIsland(getWorld(), targetUUID), true); getIslands().removePlayer(getWorld(), targetUUID); - getPlayers().clearHomeLocations(getWorld(), targetUUID); + getPlayers().clearHomeLocations(getWorld(), targetUUID); user.sendMessage("general.success"); } diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminRegisterCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminRegisterCommand.java index dec4673d7..78abe8d85 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminRegisterCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminRegisterCommand.java @@ -9,16 +9,17 @@ import org.bukkit.Location; import org.bukkit.Material; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.util.Util; -public class AdminRegisterCommand extends CompositeCommand { +public class AdminRegisterCommand extends ConfirmableCommand { public AdminRegisterCommand(CompositeCommand parent) { super(parent, "register"); } - + @Override public void setup() { setPermission("admin.register"); @@ -47,8 +48,8 @@ public class AdminRegisterCommand extends CompositeCommand { if (getIslands().inTeam(getWorld(), targetUUID)) { user.sendMessage("commands.admin.register.cannot-register-team-player"); return false; - } - + } + // Check if island is owned Optional island = getIslands().getIslandAt(user.getLocation()); if (island.map(i -> i.getOwner() != null).orElse(false)) { @@ -66,7 +67,7 @@ public class AdminRegisterCommand extends CompositeCommand { // Island does not exist user.sendMessage("commands.admin.register.no-island-here"); this.askConfirmation(user, () -> { - // Make island here + // Make island here Island i = getIslands().createIsland(getClosestIsland(user.getLocation()), targetUUID); getIslands().makeLeader(user, targetUUID, i, getPermissionPrefix()); getWorld().getBlockAt(i.getCenter()).setType(Material.BEDROCK); @@ -77,7 +78,7 @@ public class AdminRegisterCommand extends CompositeCommand { } return true; } - + @Override public Optional> tabComplete(User user, String alias, List args) { String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; @@ -88,7 +89,7 @@ public class AdminRegisterCommand extends CompositeCommand { List options = new ArrayList<>(Util.getOnlinePlayerList(user)); return Optional.of(Util.tabLimit(options, lastArg)); } - + /** * This returns the coordinate of where an island should be on the grid. * diff --git a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSchemCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSchemCommand.java index 599446056..06b91fa46 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSchemCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/admin/AdminSchemCommand.java @@ -11,11 +11,12 @@ import org.bukkit.Material; import org.bukkit.block.Block; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.schems.Clipboard; import world.bentobox.bentobox.util.Util; -public class AdminSchemCommand extends CompositeCommand { +public class AdminSchemCommand extends ConfirmableCommand { private Map clipboards; public AdminSchemCommand(CompositeCommand parent) { diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java index 21bfc86e5..724d3db36 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/IslandResetCommand.java @@ -10,13 +10,14 @@ import org.bukkit.GameMode; import org.bukkit.entity.Player; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.managers.island.NewIsland; -public class IslandResetCommand extends CompositeCommand { +public class IslandResetCommand extends ConfirmableCommand { private Map cooldown; diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java index 9a8365433..c6cc9c103 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamKickCommand.java @@ -4,9 +4,10 @@ import java.util.List; import java.util.UUID; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.user.User; -public class IslandTeamKickCommand extends CompositeCommand { +public class IslandTeamKickCommand extends ConfirmableCommand { public IslandTeamKickCommand(CompositeCommand islandTeamCommand) { super(islandTeamCommand, "kick"); diff --git a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java index b5915b287..7b0f02bac 100644 --- a/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java +++ b/src/main/java/world/bentobox/bentobox/api/commands/island/team/IslandTeamLeaveCommand.java @@ -4,10 +4,11 @@ import java.util.List; import java.util.UUID; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; -public class IslandTeamLeaveCommand extends CompositeCommand { +public class IslandTeamLeaveCommand extends ConfirmableCommand { public IslandTeamLeaveCommand(CompositeCommand islandTeamCommand) { super(islandTeamCommand, "leave"); @@ -25,7 +26,7 @@ public class IslandTeamLeaveCommand extends CompositeCommand { if (!getIslands().inTeam(getWorld(), user.getUniqueId())) { user.sendMessage("general.errors.no-team"); return false; - } + } if (getIslands().hasIsland(getWorld(), user.getUniqueId())) { user.sendMessage("commands.island.team.leave.cannot-leave"); return false; @@ -36,7 +37,7 @@ public class IslandTeamLeaveCommand extends CompositeCommand { } else { this.askConfirmation(user, () -> leave(user)); return false; - } + } } private void leave(User user) { diff --git a/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java b/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java index 605371d9e..c50365f35 100644 --- a/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java +++ b/src/main/java/world/bentobox/bentobox/commands/BentoBoxReloadCommand.java @@ -3,6 +3,7 @@ package world.bentobox.bentobox.commands; import java.util.List; import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.commands.ConfirmableCommand; import world.bentobox.bentobox.api.user.User; /** @@ -10,7 +11,7 @@ import world.bentobox.bentobox.api.user.User; * * @author tastybento */ -public class BentoBoxReloadCommand extends CompositeCommand { +public class BentoBoxReloadCommand extends ConfirmableCommand { /** * Reloads locales command @@ -19,7 +20,7 @@ public class BentoBoxReloadCommand extends CompositeCommand { public BentoBoxReloadCommand(CompositeCommand parent) { super(parent, "reload"); } - + @Override public void setup() { setPermission("admin.reload"); @@ -34,7 +35,7 @@ public class BentoBoxReloadCommand extends CompositeCommand { /** * Reloads the languages - * @param user + * @param user */ public void reloadLocales(User user) { getPlugin().getLocalesManager().reloadLanguages();