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.
This commit is contained in:
tastybento 2018-08-13 21:24:08 -07:00 committed by Florian CUNY
parent 8fb4e58994
commit 653e94e0b7
10 changed files with 156 additions and 116 deletions

View File

@ -13,13 +13,11 @@ import java.util.UUID;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings; 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) * True if the command is for the player only (not for the console)
*/ */
private boolean onlyPlayer = false; private boolean onlyPlayer = false;
/** /**
* True if command is a configurable rank * True if command is a configurable rank
*/ */
private boolean configurableRankCommand = false; private boolean configurableRankCommand = false;
/** /**
* The parameters string for this command. It is the commands followed by a locale reference. * 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 = ""; private String topLabel = "";
/**
* Confirmation tracker
*/
private static Map<User, Confirmer> toBeConfirmed = new HashMap<>();
/** /**
* Cool down tracker * Cool down tracker
*/ */
@ -142,19 +135,8 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
if (!getSubCommand("help").isPresent() && !label.equals("help")) { if (!getSubCommand("help").isPresent() && !label.equals("help")) {
new DefaultHelpCommand(this); 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. * This is the top-level command constructor for commands that have no parent.
* @param label - string for this command * @param label - string for this command
@ -201,7 +183,7 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
this.permissionPrefix = parent.getPermissionPrefix(); this.permissionPrefix = parent.getPermissionPrefix();
// Inherit world // Inherit world
this.world = parent.getWorld(); this.world = parent.getWorld();
// Default references to description and parameters // Default references to description and parameters
StringBuilder reference = new StringBuilder(); StringBuilder reference = new StringBuilder();
reference.append(label); reference.append(label);
@ -677,79 +659,6 @@ public abstract class CompositeCommand extends Command implements PluginIdentifi
return topLabel; 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 * Set a cool down - can be set by other commands on this one
* @param uniqueId - the caller * @param uniqueId - the caller

View File

@ -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<User, Confirmer> 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;
}
}
}

View File

@ -6,9 +6,10 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.api.user.User;
public class AdminClearResetsAllCommand extends CompositeCommand { public class AdminClearResetsAllCommand extends ConfirmableCommand {
public AdminClearResetsAllCommand(CompositeCommand parent) { public AdminClearResetsAllCommand(CompositeCommand parent) {
super(parent, "clearresetsall"); super(parent, "clearresetsall");

View File

@ -6,15 +6,16 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.api.user.User;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
public class AdminDeleteCommand extends CompositeCommand { public class AdminDeleteCommand extends ConfirmableCommand {
public AdminDeleteCommand(CompositeCommand parent) { public AdminDeleteCommand(CompositeCommand parent) {
super(parent, "delete"); super(parent, "delete");
} }
@Override @Override
public void setup() { public void setup() {
setPermission("admin.delete"); setPermission("admin.delete");
@ -48,13 +49,13 @@ public class AdminDeleteCommand extends CompositeCommand {
askConfirmation(user, () -> deletePlayer(user, targetUUID)); askConfirmation(user, () -> deletePlayer(user, targetUUID));
return false; return false;
} }
private void deletePlayer(User user, UUID targetUUID) { private void deletePlayer(User user, UUID targetUUID) {
// Delete player and island // Delete player and island
user.sendMessage("commands.admin.delete.deleted-island", "[xyz]", Util.xyz(getIslands().getIsland(getWorld(), targetUUID).getCenter().toVector())); user.sendMessage("commands.admin.delete.deleted-island", "[xyz]", Util.xyz(getIslands().getIsland(getWorld(), targetUUID).getCenter().toVector()));
getIslands().deleteIsland(getIslands().getIsland(getWorld(), targetUUID), true); getIslands().deleteIsland(getIslands().getIsland(getWorld(), targetUUID), true);
getIslands().removePlayer(getWorld(), targetUUID); getIslands().removePlayer(getWorld(), targetUUID);
getPlayers().clearHomeLocations(getWorld(), targetUUID); getPlayers().clearHomeLocations(getWorld(), targetUUID);
user.sendMessage("general.success"); user.sendMessage("general.success");
} }

View File

@ -9,16 +9,17 @@ import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
public class AdminRegisterCommand extends CompositeCommand { public class AdminRegisterCommand extends ConfirmableCommand {
public AdminRegisterCommand(CompositeCommand parent) { public AdminRegisterCommand(CompositeCommand parent) {
super(parent, "register"); super(parent, "register");
} }
@Override @Override
public void setup() { public void setup() {
setPermission("admin.register"); setPermission("admin.register");
@ -47,8 +48,8 @@ public class AdminRegisterCommand extends CompositeCommand {
if (getIslands().inTeam(getWorld(), targetUUID)) { if (getIslands().inTeam(getWorld(), targetUUID)) {
user.sendMessage("commands.admin.register.cannot-register-team-player"); user.sendMessage("commands.admin.register.cannot-register-team-player");
return false; return false;
} }
// Check if island is owned // Check if island is owned
Optional<Island> island = getIslands().getIslandAt(user.getLocation()); Optional<Island> island = getIslands().getIslandAt(user.getLocation());
if (island.map(i -> i.getOwner() != null).orElse(false)) { if (island.map(i -> i.getOwner() != null).orElse(false)) {
@ -66,7 +67,7 @@ public class AdminRegisterCommand extends CompositeCommand {
// Island does not exist // Island does not exist
user.sendMessage("commands.admin.register.no-island-here"); user.sendMessage("commands.admin.register.no-island-here");
this.askConfirmation(user, () -> { this.askConfirmation(user, () -> {
// Make island here // Make island here
Island i = getIslands().createIsland(getClosestIsland(user.getLocation()), targetUUID); Island i = getIslands().createIsland(getClosestIsland(user.getLocation()), targetUUID);
getIslands().makeLeader(user, targetUUID, i, getPermissionPrefix()); getIslands().makeLeader(user, targetUUID, i, getPermissionPrefix());
getWorld().getBlockAt(i.getCenter()).setType(Material.BEDROCK); getWorld().getBlockAt(i.getCenter()).setType(Material.BEDROCK);
@ -77,7 +78,7 @@ public class AdminRegisterCommand extends CompositeCommand {
} }
return true; return true;
} }
@Override @Override
public Optional<List<String>> tabComplete(User user, String alias, List<String> args) { public Optional<List<String>> tabComplete(User user, String alias, List<String> args) {
String lastArg = !args.isEmpty() ? args.get(args.size()-1) : ""; String lastArg = !args.isEmpty() ? args.get(args.size()-1) : "";
@ -88,7 +89,7 @@ public class AdminRegisterCommand extends CompositeCommand {
List<String> options = new ArrayList<>(Util.getOnlinePlayerList(user)); List<String> options = new ArrayList<>(Util.getOnlinePlayerList(user));
return Optional.of(Util.tabLimit(options, lastArg)); return Optional.of(Util.tabLimit(options, lastArg));
} }
/** /**
* This returns the coordinate of where an island should be on the grid. * This returns the coordinate of where an island should be on the grid.
* *

View File

@ -11,11 +11,12 @@ import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.api.user.User;
import world.bentobox.bentobox.schems.Clipboard; import world.bentobox.bentobox.schems.Clipboard;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
public class AdminSchemCommand extends CompositeCommand { public class AdminSchemCommand extends ConfirmableCommand {
private Map<UUID, Clipboard> clipboards; private Map<UUID, Clipboard> clipboards;
public AdminSchemCommand(CompositeCommand parent) { public AdminSchemCommand(CompositeCommand parent) {

View File

@ -10,13 +10,14 @@ import org.bukkit.GameMode;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.island.NewIsland; import world.bentobox.bentobox.managers.island.NewIsland;
public class IslandResetCommand extends CompositeCommand { public class IslandResetCommand extends ConfirmableCommand {
private Map<UUID, Long> cooldown; private Map<UUID, Long> cooldown;

View File

@ -4,9 +4,10 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.api.user.User;
public class IslandTeamKickCommand extends CompositeCommand { public class IslandTeamKickCommand extends ConfirmableCommand {
public IslandTeamKickCommand(CompositeCommand islandTeamCommand) { public IslandTeamKickCommand(CompositeCommand islandTeamCommand) {
super(islandTeamCommand, "kick"); super(islandTeamCommand, "kick");

View File

@ -4,10 +4,11 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
public class IslandTeamLeaveCommand extends CompositeCommand { public class IslandTeamLeaveCommand extends ConfirmableCommand {
public IslandTeamLeaveCommand(CompositeCommand islandTeamCommand) { public IslandTeamLeaveCommand(CompositeCommand islandTeamCommand) {
super(islandTeamCommand, "leave"); super(islandTeamCommand, "leave");
@ -25,7 +26,7 @@ public class IslandTeamLeaveCommand extends CompositeCommand {
if (!getIslands().inTeam(getWorld(), user.getUniqueId())) { if (!getIslands().inTeam(getWorld(), user.getUniqueId())) {
user.sendMessage("general.errors.no-team"); user.sendMessage("general.errors.no-team");
return false; return false;
} }
if (getIslands().hasIsland(getWorld(), user.getUniqueId())) { if (getIslands().hasIsland(getWorld(), user.getUniqueId())) {
user.sendMessage("commands.island.team.leave.cannot-leave"); user.sendMessage("commands.island.team.leave.cannot-leave");
return false; return false;
@ -36,7 +37,7 @@ public class IslandTeamLeaveCommand extends CompositeCommand {
} else { } else {
this.askConfirmation(user, () -> leave(user)); this.askConfirmation(user, () -> leave(user));
return false; return false;
} }
} }
private void leave(User user) { private void leave(User user) {

View File

@ -3,6 +3,7 @@ package world.bentobox.bentobox.commands;
import java.util.List; import java.util.List;
import world.bentobox.bentobox.api.commands.CompositeCommand; 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.api.user.User;
/** /**
@ -10,7 +11,7 @@ import world.bentobox.bentobox.api.user.User;
* *
* @author tastybento * @author tastybento
*/ */
public class BentoBoxReloadCommand extends CompositeCommand { public class BentoBoxReloadCommand extends ConfirmableCommand {
/** /**
* Reloads locales command * Reloads locales command
@ -19,7 +20,7 @@ public class BentoBoxReloadCommand extends CompositeCommand {
public BentoBoxReloadCommand(CompositeCommand parent) { public BentoBoxReloadCommand(CompositeCommand parent) {
super(parent, "reload"); super(parent, "reload");
} }
@Override @Override
public void setup() { public void setup() {
setPermission("admin.reload"); setPermission("admin.reload");
@ -34,7 +35,7 @@ public class BentoBoxReloadCommand extends CompositeCommand {
/** /**
* Reloads the languages * Reloads the languages
* @param user * @param user
*/ */
public void reloadLocales(User user) { public void reloadLocales(User user) {
getPlugin().getLocalesManager().reloadLanguages(); getPlugin().getLocalesManager().reloadLanguages();