bentobox/src/main/java/world/bentobox/bentobox/api/commands/ConfirmableCommand.java

143 lines
4.7 KiB
Java

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 it.
* @param user User to ask confirmation to.
* @param message Optional message to send to the user to give them a bit more context. It must already be translated.
* @param confirmed Runnable to be executed if successfully confirmed.
*/
public void askConfirmation(User user, String message, 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");
}
}
// Send user the context message if it is not empty
if (!message.trim().isEmpty()) {
user.sendRawMessage(message);
}
// 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));
}
/**
* Tells user to confirm command by retyping it.
* @param user User to ask confirmation to.
* @param confirmed Runnable to be executed if successfully confirmed.
*/
public void askConfirmation(User user, Runnable confirmed) {
askConfirmation(user, "", confirmed);
}
/**
* Holds the data to run once the confirmation is given
* @author tastybento
*
*/
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;
}
}
}