diff --git a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 33a38b067..6af308e52 100644 --- a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -102,7 +102,7 @@ import net.citizensnpcs.trait.Anchors; import net.citizensnpcs.trait.ArmorStandTrait; import net.citizensnpcs.trait.ClickRedirectTrait; import net.citizensnpcs.trait.CommandTrait; -import net.citizensnpcs.trait.CommandTrait.CommandTraitMessages; +import net.citizensnpcs.trait.CommandTrait.CommandTraitError; import net.citizensnpcs.trait.CommandTrait.ExecutionMode; import net.citizensnpcs.trait.CommandTrait.ItemRequirementGUI; import net.citizensnpcs.trait.CommandTrait.NPCCommandBuilder; @@ -401,7 +401,7 @@ public class NPCCommands { @Command( aliases = { "npc" }, - usage = "command|cmd (add [command] | remove [id] | permissions [permissions] | sequential | random | errormsg [type] [msg] | (exp|item)cost [cost]) (-l[eft]/-r[ight]) (-p[layer] -o[p]), --cooldown --gcooldown [seconds] --delay [ticks] --permissions [perms] --n [max # of uses]", + usage = "command|cmd (add [command] | remove [id] | permissions [permissions] | sequential | random | clearerror [type] (name|uuid) | errormsg [type] [msg] | (exp|item)cost [cost]) (-l[eft]/-r[ight]) (-p[layer] -o[p]), --cooldown --gcooldown [seconds] --delay [ticks] --permissions [perms] --n [max # of uses]", desc = "Controls commands which will be run when clicking on an NPC", help = Messages.NPC_COMMAND_HELP, modifiers = { "command", "cmd" }, @@ -415,7 +415,7 @@ public class NPCCommands { @Arg( value = 1, completions = { "add", "remove", "permissions", "sequential", "random", "hideerrors", "errormsg", - "expcost", "itemcost" }) String action) + "clearerror", "expcost", "itemcost" }) String action) throws CommandException { CommandTrait commands = npc.getOrAddTrait(CommandTrait.class); if (args.argsLength() == 1) { @@ -440,6 +440,19 @@ public class NPCCommands { } catch (NumberFormatException ex) { throw new CommandException(CommandMessages.INVALID_NUMBER); } + } else if (action.equalsIgnoreCase("clearerror")) { + CommandTraitError which = Util.matchEnum(CommandTraitError.values(), args.getString(2)); + if (which == null) + throw new CommandException(Messages.NPC_COMMAND_INVALID_ERROR_MESSAGE, + Util.listValuesPretty(CommandTraitError.values())); + Player player = null; + if (args.argsLength() > 3) { + player = Bukkit.getPlayerExact(args.getString(3)); + if (player == null) { + player = Bukkit.getPlayer(UUID.fromString(args.getString(3))); + } + } + commands.clearHistory(which, player); } else if (action.equalsIgnoreCase("sequential")) { commands.setExecutionMode(commands.getExecutionMode() == ExecutionMode.SEQUENTIAL ? ExecutionMode.LINEAR : ExecutionMode.SEQUENTIAL); @@ -481,10 +494,10 @@ public class NPCCommands { throw new CommandException(CommandMessages.MUST_BE_INGAME); InventoryMenu.createSelfRegistered(new ItemRequirementGUI(commands)).present(((Player) sender)); } else if (action.equalsIgnoreCase("errormsg")) { - CommandTraitMessages which = Util.matchEnum(CommandTraitMessages.values(), args.getString(2)); + CommandTraitError which = Util.matchEnum(CommandTraitError.values(), args.getString(2)); if (which == null) throw new CommandException(Messages.NPC_COMMAND_INVALID_ERROR_MESSAGE, - Util.listValuesPretty(CommandTraitMessages.values())); + Util.listValuesPretty(CommandTraitError.values())); commands.setCustomErrorMessage(which, args.getString(3)); } else { throw new CommandUsageException(); diff --git a/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java b/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java index e3ff14724..70366fd3d 100644 --- a/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java @@ -64,8 +64,8 @@ public class CommandTrait extends Trait { @Persist private double cost = -1; @Persist - private final Map customErrorMessages = Maps.newEnumMap(CommandTraitMessages.class); - private final Map> executionErrors = Maps.newHashMap(); + private final Map customErrorMessages = Maps.newEnumMap(CommandTraitError.class); + private final Map> executionErrors = Maps.newHashMap(); @Persist private ExecutionMode executionMode = ExecutionMode.LINEAR; @Persist @@ -99,7 +99,7 @@ public class CommandTrait extends Trait { if (provider != null && provider.getProvider() != null) { Economy economy = provider.getProvider(); if (!economy.has(player, cost)) { - sendErrorMessage(player, CommandTraitMessages.MISSING_MONEY, null, cost); + sendErrorMessage(player, CommandTraitError.MISSING_MONEY, null, cost); return false; } economy.withdrawPlayer(player, cost); @@ -110,7 +110,7 @@ public class CommandTrait extends Trait { } if (experienceCost > 0) { if (player.getLevel() < experienceCost) { - sendErrorMessage(player, CommandTraitMessages.MISSING_EXPERIENCE, null, experienceCost); + sendErrorMessage(player, CommandTraitError.MISSING_EXPERIENCE, null, experienceCost); return false; } player.setLevel((int) (player.getLevel() - experienceCost)); @@ -125,7 +125,7 @@ public class CommandTrait extends Trait { if (tempInventory.containsAtLeast(stack, stack.getAmount())) { tempInventory.removeItem(stack); } else { - sendErrorMessage(player, CommandTraitMessages.MISSING_ITEM, null, Util.prettyEnum(stack.getType()), + sendErrorMessage(player, CommandTraitError.MISSING_ITEM, null, Util.prettyEnum(stack.getType()), stack.getAmount()); return false; } @@ -137,6 +137,34 @@ public class CommandTrait extends Trait { return true; } + public void clearHistory(CommandTraitError which, Player who) { + Collection toClear = Lists.newArrayList(); + if (who != null) { + toClear.add(playerTracking.get(who.getUniqueId())); + } else { + toClear.addAll(playerTracking.values()); + } + switch (which) { + case MAXIMUM_TIMES_USED: + for (PlayerNPCCommand tracked : toClear) { + tracked.nUsed.clear(); + } + + break; + case ON_COOLDOWN: + for (PlayerNPCCommand tracked : toClear) { + tracked.lastUsed.clear(); + } + + break; + case ON_GLOBAL_COOLDOWN: + globalCooldowns.clear(); + break; + default: + return; + } + } + /** * Send a brief description of the current state of the trait to the supplied {@link CommandSender}. */ @@ -230,7 +258,7 @@ public class CommandTrait extends Trait { max = commandList.size() > 0 ? commandList.get(commandList.size() - 1).id : -1; } if (executionMode == ExecutionMode.LINEAR) { - executionErrors.put(player.getUniqueId().toString(), EnumSet.noneOf(CommandTraitMessages.class)); + executionErrors.put(player.getUniqueId().toString(), EnumSet.noneOf(CommandTraitError.class)); } for (NPCCommand command : commandList) { if (executionMode == ExecutionMode.SEQUENTIAL) { @@ -337,12 +365,12 @@ public class CommandTrait extends Trait { } } - private void sendErrorMessage(Player player, CommandTraitMessages msg, Function transform, + private void sendErrorMessage(Player player, CommandTraitError msg, Function transform, Object... objects) { if (hideErrorMessages) { return; } - Set sent = executionErrors.get(player.getUniqueId().toString()); + Set sent = executionErrors.get(player.getUniqueId().toString()); if (sent != null) { if (sent.contains(msg)) return; @@ -361,7 +389,7 @@ public class CommandTrait extends Trait { this.cost = cost; } - public void setCustomErrorMessage(CommandTraitMessages which, String message) { + public void setCustomErrorMessage(CommandTraitError which, String message) { customErrorMessages.put(which, message); } @@ -382,7 +410,7 @@ public class CommandTrait extends Trait { temporaryPermissions.addAll(permissions); } - public enum CommandTraitMessages { + public enum CommandTraitError { MAXIMUM_TIMES_USED(Setting.NPC_COMMAND_MAXIMUM_TIMES_USED_MESSAGE), MISSING_EXPERIENCE(Setting.NPC_COMMAND_NOT_ENOUGH_EXPERIENCE_MESSAGE), MISSING_ITEM(Setting.NPC_COMMAND_MISSING_ITEM_MESSAGE), @@ -393,7 +421,7 @@ public class CommandTrait extends Trait { private final Setting setting; - CommandTraitMessages(Setting setting) { + CommandTraitError(Setting setting) { this.setting = setting; } } @@ -647,7 +675,7 @@ public class CommandTrait extends Trait { public boolean canUse(CommandTrait trait, Player player, NPCCommand command) { for (String perm : command.perms) { if (!player.hasPermission(perm)) { - trait.sendErrorMessage(player, CommandTraitMessages.NO_PERMISSION, null); + trait.sendErrorMessage(player, CommandTraitError.NO_PERMISSION, null); return false; } } @@ -658,7 +686,7 @@ public class CommandTrait extends Trait { long deadline = ((Number) lastUsed.get(commandKey)).longValue() + command.cooldown + globalDelay; if (currentTimeSec < deadline) { long seconds = deadline - currentTimeSec; - trait.sendErrorMessage(player, CommandTraitMessages.ON_COOLDOWN, + trait.sendErrorMessage(player, CommandTraitError.ON_COOLDOWN, new TimeVariableFormatter(seconds, TimeUnit.SECONDS), seconds); return false; } @@ -668,7 +696,7 @@ public class CommandTrait extends Trait { long deadline = ((Number) trait.globalCooldowns.get(commandKey)).longValue() + command.globalCooldown; if (currentTimeSec < deadline) { long seconds = deadline - currentTimeSec; - trait.sendErrorMessage(player, CommandTraitMessages.ON_GLOBAL_COOLDOWN, + trait.sendErrorMessage(player, CommandTraitError.ON_GLOBAL_COOLDOWN, new TimeVariableFormatter(seconds, TimeUnit.SECONDS), seconds); return false; } @@ -676,7 +704,7 @@ public class CommandTrait extends Trait { } int previouslyUsed = nUsed.getOrDefault(commandKey, 0); if (command.n > 0 && command.n <= previouslyUsed) { - trait.sendErrorMessage(player, CommandTraitMessages.MAXIMUM_TIMES_USED, null, command.n); + trait.sendErrorMessage(player, CommandTraitError.MAXIMUM_TIMES_USED, null, command.n); return false; } if (command.cooldown > 0 || globalDelay > 0) {