From d602d4cd6135873ae4a79927d9d2b20e5cb1d3ab Mon Sep 17 00:00:00 2001 From: Magnus Ulf Date: Sat, 19 Jan 2019 12:19:20 +0100 Subject: [PATCH] Create ConfirmationUtil This is a util primarily used for commands that need extra confirmation --- .../massivecore/command/MassiveCommand.java | 88 +++++---- .../primitive/TypeStringConfirmation.java | 41 +++++ .../massivecore/util/ConfirmationUtil.java | 174 ++++++++++++++++++ 3 files changed, 269 insertions(+), 34 deletions(-) create mode 100644 src/com/massivecraft/massivecore/command/type/primitive/TypeStringConfirmation.java create mode 100644 src/com/massivecraft/massivecore/util/ConfirmationUtil.java diff --git a/src/com/massivecraft/massivecore/command/MassiveCommand.java b/src/com/massivecraft/massivecore/command/MassiveCommand.java index e5b7ec49..e553aa1b 100644 --- a/src/com/massivecraft/massivecore/command/MassiveCommand.java +++ b/src/com/massivecraft/massivecore/command/MassiveCommand.java @@ -1263,41 +1263,10 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand public Mson getTemplate(boolean addDesc, boolean onlyFirstAlias, CommandSender sender) { - // Create Ret - Mson ret = TEMPLATE_CORE; - - // Get commands - List commands = this.getChain(true); - - // Add commands - boolean first = true; - for (MassiveCommand command : commands) - { - Mson mson = null; - - if (first && onlyFirstAlias) - { - mson = mson(command.getAliases().get(0)); - } - else - { - mson = mson(Txt.implode(command.getAliases(), ",")); - } - - if (sender != null && ! command.isRequirementsMet(sender, false)) - { - mson = mson.color(ChatColor.RED); - } - else - { - mson = mson.color(ChatColor.AQUA); - } - - if ( ! first) ret = ret.add(Mson.SPACE); - ret = ret.add(mson); - first = false; - } + // Get base + Mson ret = this.getTemplateChain(onlyFirstAlias, sender); + List commands = this.getChain(true); // Check if last command is parentCommand and make command suggestable/clickable if (commands.get(commands.size() - 1).isParent()) { @@ -1325,6 +1294,57 @@ public class MassiveCommand implements Active, PluginIdentifiableCommand // Return Ret return ret; } + + public Mson getTemplateWithArgs(CommandSender sender, List args) + { + Mson ret = this.getTemplateChain(true, sender); + + for (String arg : args) + { + ret = ret.add(Mson.SPACE); + ret = ret.add(mson(arg).color(ChatColor.DARK_AQUA)); + } + + return ret; + } + + public Mson getTemplateChain(boolean onlyFirstAlias, CommandSender sender) + { + Mson ret = TEMPLATE_CORE; + + List commands = this.getChain(true); + + // Add commands + boolean first = true; + for (MassiveCommand command : commands) + { + Mson mson = null; + + if (first && onlyFirstAlias) + { + mson = mson(command.getAliases().get(0)); + } + else + { + mson = mson(Txt.implode(command.getAliases(), ",")); + } + + if (sender != null && ! command.isRequirementsMet(sender, false)) + { + mson = mson.color(ChatColor.RED); + } + else + { + mson = mson.color(ChatColor.AQUA); + } + + if ( ! first) ret = ret.add(Mson.SPACE); + ret = ret.add(mson); + first = false; + } + + return ret; + } protected List getTemplateParameters(CommandSender sender) { diff --git a/src/com/massivecraft/massivecore/command/type/primitive/TypeStringConfirmation.java b/src/com/massivecraft/massivecore/command/type/primitive/TypeStringConfirmation.java new file mode 100644 index 00000000..5d66bf49 --- /dev/null +++ b/src/com/massivecraft/massivecore/command/type/primitive/TypeStringConfirmation.java @@ -0,0 +1,41 @@ +package com.massivecraft.massivecore.command.type.primitive; + +import com.massivecraft.massivecore.command.type.TypeAbstract; +import org.bukkit.command.CommandSender; + +import java.util.Collection; +import java.util.Collections; + +public class TypeStringConfirmation extends TypeAbstract +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static TypeStringConfirmation i = new TypeStringConfirmation(); + public static TypeStringConfirmation get() { return i; } + public TypeStringConfirmation() { super(String.class); } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public String getName() + { + return "confirmation text"; + } + + @Override + public String read(String arg, CommandSender sender) + { + return arg; + } + + @Override + public Collection getTabList(CommandSender sender, String arg) + { + return Collections.emptySet(); + } + +} diff --git a/src/com/massivecraft/massivecore/util/ConfirmationUtil.java b/src/com/massivecraft/massivecore/util/ConfirmationUtil.java new file mode 100644 index 00000000..bd5fe666 --- /dev/null +++ b/src/com/massivecraft/massivecore/util/ConfirmationUtil.java @@ -0,0 +1,174 @@ +package com.massivecraft.massivecore.util; + +import com.massivecraft.massivecore.Lang; +import com.massivecraft.massivecore.MassiveCore; +import com.massivecraft.massivecore.MassiveException; +import com.massivecraft.massivecore.collections.MassiveList; +import com.massivecraft.massivecore.command.MassiveCommand; +import com.massivecraft.massivecore.command.type.Type; +import com.massivecraft.massivecore.command.type.primitive.TypeStringConfirmation; +import com.massivecraft.massivecore.mixin.MixinMessage; +import com.massivecraft.massivecore.mson.Mson; +import org.apache.commons.lang.RandomStringUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +public class ConfirmationUtil +{ + // -------------------------------------------- // + // STORE + // -------------------------------------------- // + + private static Map> objectToConfirmationMap = new HashMap<>(); + + // -------------------------------------------- // + // DERP + // -------------------------------------------- // + + private static Map getConfirmationMap(Object obj) + { + if (obj == null) throw new NullPointerException("obj"); + + objectToConfirmationMap.putIfAbsent(obj, new WeakHashMap<>()); + return objectToConfirmationMap.get(obj); + } + + public static String createConfirmationString(Object obj, CommandSender sender) + { + if (obj == null) throw new NullPointerException("obj"); + if (sender == null) throw new NullPointerException("sender"); + + String str = RandomStringUtils.randomAlphanumeric(6); + getConfirmationMap(obj).put(sender, str); + + scheduleRemove(obj, sender, 5 * 60); + + return str; + } + + public static void scheduleRemove(Object obj, CommandSender sender, long seconds) + { + if (obj == null) throw new NullPointerException("obj"); + if (sender == null) throw new NullPointerException("sender"); + + Bukkit.getScheduler().runTaskLater(MassiveCore.get(), () -> removeConfirmationString(obj, sender), 20L * seconds); + } + + public static boolean removeConfirmationString(Object obj, CommandSender sender) + { + if (obj == null) throw new NullPointerException("obj"); + if (sender == null) throw new NullPointerException("sender"); + + return getConfirmationMap(obj).remove(sender) != null; + } + + public static String getConfirmationString(Object obj, CommandSender sender) + { + if (obj == null) throw new NullPointerException("obj"); + if (sender == null) throw new NullPointerException("sender"); + + return getConfirmationMap(obj).get(sender); + } + + public static boolean isConfirmationString(Object obj, CommandSender sender, String str) + { + if (obj == null) throw new NullPointerException("obj"); + if (sender == null) throw new NullPointerException("sender"); + if (str == null) throw new NullPointerException("str"); + + return str.equals(getConfirmationString(obj, sender)); + } + + public static boolean hasConfirmationString(Object obj, CommandSender sender) + { + if (obj == null) throw new NullPointerException("obj"); + if (sender == null) throw new NullPointerException("sender"); + + return getConfirmationMap(obj).containsKey(sender); + } + + public static void tryConfirm(MassiveCommand object) throws MassiveException + { + if (object == null) throw new NullPointerException("object"); + + CommandSender sender = object.sender; + if (sender == null) throw new NullPointerException("sender"); + + int idx = getConfirmationIdx(object); + + boolean hasConfirmationString = hasConfirmationString(object, sender); + boolean hasTypedConfirmationString = object.argIsSet(idx); + boolean hasTypedOther = object.argIsSet(idx-1); + + // Assetion should not happen + if (hasTypedConfirmationString && !hasTypedOther) throw new RuntimeException(); + + if (!hasTypedOther) + { + MassiveException ex = new MassiveException(); + ex.addMsg(Lang.COMMAND_TOO_FEW_ARGUMENTS); + ex.addMessage(object.getTemplate(false, true, sender)); + throw ex; + } + else if (hasConfirmationString && !hasTypedConfirmationString) + { + throw getException(object); + } + else if (hasConfirmationString && hasTypedConfirmationString) + { + // If they typed the wrong thing + String typedString = object.argAt(idx); + if (!isConfirmationString(object, sender, typedString)) + { + // Make them type the right string + throw getException(object); + } + // Otherwise do nothing, because success + } + else if (!hasConfirmationString && hasTypedOther) + { + String confirmationString = createConfirmationString(object, sender); + MixinMessage.get().msgOne(sender, "Created confirmation text %s for you.", confirmationString); + + throw getException(object); + } + + } + + private static int getConfirmationIdx(MassiveCommand command) + { + int idx = -1; + for (int i = 0; i < command.getParameters().size(); i++) + { + Type type = command.getParameterType(i); + if (!(type instanceof TypeStringConfirmation)) continue; + + idx = i; + } + if (idx == -1) throw new IllegalStateException("no confirmation string type"); + + return idx; + } + + private static MassiveException getException(MassiveCommand command) + { + CommandSender sender = command.sender; + if (sender == null) throw new NullPointerException("sender"); + + int idx = getConfirmationIdx(command); + + List args = new MassiveList<>(command.getArgs()); + args.set(idx, getConfirmationString(command, sender)); + Mson template = command.getTemplateWithArgs(sender, args); + MassiveException ex = new MassiveException(); + ex.addMsg("To %s confirm it by typing:", command.getDesc()); + ex.addMessage(template); + return ex; + } + +}