diff --git a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 974dd1cf3..f632e18b3 100644 --- a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -460,7 +460,7 @@ public class NPCCommands { @Command( aliases = { "npc" }, - usage = "command|cmd (add [command] | remove [id|all] | permissions [permissions] | sequential | cycle | random | clearerror [type] (name|uuid) | errormsg [type] [msg] | persistsequence [true|false] | cost [cost] (id) | expcost [cost] (id) | itemcost (id)) (-s(hift)) (-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|all] | permissions [permissions] | sequential | cycle | random | forgetplayer (uuid) | clearerror [type] (name|uuid) | errormsg [type] [msg] | persistsequence [true|false] | cost [cost] (id) | expcost [cost] (id) | itemcost (id)) (-s(hift)) (-l[eft]/-r[ight]) (-p[layer] -o[p]), --cooldown --gcooldown [seconds] --delay [ticks] --permissions [perms] --n [max # of uses]", desc = "", modifiers = { "command", "cmd" }, min = 1, @@ -476,7 +476,8 @@ public class NPCCommands { @Arg( value = 1, completions = { "add", "remove", "permissions", "persistsequence", "sequential", "cycle", "random", - "hideerrors", "errormsg", "clearerror", "expcost", "itemcost", "cost" }) String action) + "forgetplayer", "hideerrors", "errormsg", "clearerror", "expcost", "itemcost", + "cost" }) String action) throws CommandException { CommandTrait commands = npc.getOrAddTrait(CommandTrait.class); if (args.argsLength() == 1) { @@ -509,6 +510,21 @@ public class NPCCommands { } catch (NumberFormatException ex) { throw new CommandException(CommandMessages.INVALID_NUMBER); } + } else if (action.equalsIgnoreCase("forgetplayer")) { + if (args.argsLength() < 3) { + commands.clearPlayerHistory(null); + Messaging.sendTr(sender, Messages.NPC_COMMAND_ALL_PLAYERS_FORGOTTEN, npc.getName()); + return; + } + String raw = args.getString(2); + OfflinePlayer who = Bukkit.getPlayerExact(raw); + if (who == null) { + who = Bukkit.getOfflinePlayer(UUID.fromString(raw)); + } + if (who == null || !who.hasPlayedBefore()) + throw new CommandException(Messages.NPC_COMMAND_INVALID_PLAYER, raw); + commands.clearPlayerHistory(who.getUniqueId()); + Messaging.sendTr(sender, Messages.NPC_COMMAND_PLAYER_FORGOTTEN, who.getUniqueId()); } else if (action.equalsIgnoreCase("clearerror")) { if (args.argsLength() < 3) throw new CommandException(Messages.NPC_COMMAND_INVALID_ERROR_MESSAGE, @@ -518,9 +534,21 @@ public class NPCCommands { if (which == null) throw new CommandException(Messages.NPC_COMMAND_INVALID_ERROR_MESSAGE, Util.listValuesPretty(CommandTraitError.values())); - - commands.clearHistory(which, args.argsLength() > 3 ? args.getString(3) : null); - Messaging.send(sender, Messages.NPC_COMMAND_ERRORS_CLEARED, Util.prettyEnum(which)); + if (args.argsLength() < 4) { + commands.clearHistory(which, null); + Messaging.sendTr(sender, Messages.NPC_COMMAND_ALL_ERRORS_CLEARED, npc.getName(), + Util.prettyEnum(which)); + return; + } + String raw = args.getString(3); + OfflinePlayer who = Bukkit.getPlayerExact(raw); + if (who == null) { + who = Bukkit.getOfflinePlayer(UUID.fromString(raw)); + } + if (who == null || !who.hasPlayedBefore()) + throw new CommandException(Messages.NPC_COMMAND_INVALID_PLAYER, raw); + commands.clearHistory(which, who.getUniqueId()); + Messaging.sendTr(sender, Messages.NPC_COMMAND_ERRORS_CLEARED, Util.prettyEnum(which), who.getUniqueId()); } else if (action.equalsIgnoreCase("sequential")) { commands.setExecutionMode(commands.getExecutionMode() == ExecutionMode.SEQUENTIAL ? ExecutionMode.LINEAR : ExecutionMode.SEQUENTIAL); diff --git a/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java b/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java index 7f955c713..0dc1f6fcf 100644 --- a/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java +++ b/main/src/main/java/net/citizensnpcs/trait/CommandTrait.java @@ -147,21 +147,10 @@ public class CommandTrait extends Trait { commands.clear(); } - public void clearHistory(CommandTraitError which, String raw) { - if (which == CommandTraitError.ON_GLOBAL_COOLDOWN && raw != null) { - globalCooldowns.remove(BaseEncoding.base64().encode(raw.getBytes())); - return; - } - Player who = null; - if (raw != null) { - who = Bukkit.getPlayerExact(raw); - if (who == null) { - who = Bukkit.getPlayer(UUID.fromString(raw)); - } - } + public void clearHistory(CommandTraitError which, UUID who) { Collection toClear = Lists.newArrayList(); if (who != null) { - toClear.add(playerTracking.get(who.getUniqueId())); + toClear.add(playerTracking.get(who)); } else { toClear.addAll(playerTracking.values()); } @@ -186,6 +175,14 @@ public class CommandTrait extends Trait { } } + public void clearPlayerHistory(UUID who) { + if (who == null) { + playerTracking.clear(); + } else { + playerTracking.remove(who); + } + } + /** * Send a brief description of the current state of the trait to the supplied {@link CommandSender}. */ diff --git a/main/src/main/java/net/citizensnpcs/util/Messages.java b/main/src/main/java/net/citizensnpcs/util/Messages.java index a9d6dd364..540d1bf72 100644 --- a/main/src/main/java/net/citizensnpcs/util/Messages.java +++ b/main/src/main/java/net/citizensnpcs/util/Messages.java @@ -268,8 +268,12 @@ public class Messages { public static final String NOT_USING_MINECRAFT_AI = "citizens.commands.npc.ai.stopped"; public static final String NPC_ALREADY_SELECTED = "citizens.commands.npc.select.already-selected"; public static final String NPC_ALREADY_SPAWNED = "citizens.commands.npc.spawn.already-spawned"; + public static final String NPC_COMMAND_ALL_ERRORS_CLEARED = "citizens.commands.npc.command.all-errors-cleared"; + public static final String NPC_COMMAND_ALL_PLAYERS_FORGOTTEN = "citizens.commands.npc.command.all-players-forgotten"; public static final String NPC_COMMAND_ERRORS_CLEARED = "citizens.commands.npc.command.errors-cleared"; public static final String NPC_COMMAND_INVALID_ERROR_MESSAGE = "citizens.commands.npc.command.invalid-error-message"; + public static final String NPC_COMMAND_INVALID_PLAYER = "citizens.commands.npc.command.invalid-player"; + public static final String NPC_COMMAND_PLAYER_FORGOTTEN = "citizens.commands.npc.command.player-forgotten"; public static final String NPC_COPIED = "citizens.commands.npc.copy.copied"; public static final String NPC_CREATE_INVALID_MOBTYPE = "citizens.commands.npc.create.invalid-mobtype"; public static final String NPC_CREATE_MISSING_MOBTYPE = "citizens.commands.npc.create.mobtype-missing"; diff --git a/main/src/main/resources/en.json b/main/src/main/resources/en.json index aaf7a9ac7..e78ab5621 100644 --- a/main/src/main/resources/en.json +++ b/main/src/main/resources/en.json @@ -84,6 +84,10 @@ "citizens.commands.npc.collidable.help" : "", "citizens.commands.npc.collidable.set" : "[[{0}]] will now collide with entities.", "citizens.commands.npc.collidable.unset" : "[[{0}]] will no longer collide with entities.", + "citizens.commands.npc.command.all-players-forgotten" : "[[{0}]] forgot all player command history.", + "citizens.commands.npc.command.all-errors-cleared" : "[[{0}]] cleared all [[{1}]] errors.", + "citizens.commands.npc.command.invalid-player" : "[[{0}]] could not be found as a player.", + "citizens.commands.npc.command.player-forgotten" : "Forgot player command history for [[{0}]].", "citizens.commands.npc.command.cleared" : "[[{0}]]''s commands cleared.", "citizens.commands.npc.command.command-added" : "Command [[{0}]] added with id [[{1}]].", "citizens.commands.npc.command.command-removed" : "Command [[{0}]] removed.", @@ -97,7 +101,9 @@ "citizens.commands.npc.command.experience-cost-set" : "Set xp level cost per click to [[{0}]].", "citizens.commands.npc.command.help" : "
Use the [[-l]] flag to make the command run on left click, [[-r]] on right click (default).
Set the per-player cooldown before the command can be used again using [[--cooldown]] (in [[seconds]]).
Set the server-wide cooldown in seconds using [[--gcooldown]].
[[--delay]] will wait the specified amount in [[ticks]] before executing the command.
[[--permissions]] will set the command to require specific permissions (separate multiple with commas).
[[--n]] will only let the player run the command that number of times.
Use [[-o]] to temporarily execute the command as an op and [[-p]] to run the command as the clicking player instead of the server.
To give the player temporary permissions instead of op, use [[/npc command permissions]].
Set the cost of each click with [[/npc command cost/expcost/itemcost]].
Commands can be executed one by one instead of all at once by using [[/npc command sequential]] or [[/npc command cycle]].", "citizens.commands.npc.command.hide-error-messages-set" : "Now hiding error messages.", - "citizens.commands.npc.command.hide-error-messages-unset" : "No longer hiding error messages.", + "citizens.commands.npc.command.hide-error-messages-unset" : "No longer hiding error messages.", + "citizens.commands.npc.command.individual-cost-set" : "Set cost per click to [[{0}]] for command id [[{1}]].", + "citizens.commands.npc.command.individual-experience-cost-set" : "Set xp level cost per click to [[{0}]] for command id [[{1}]].", "citizens.commands.npc.command.invalid-error-message" : "Invalid error message. Valid messages are [[{0}]].", "citizens.commands.npc.command.left-hand-header" : "Commands to run on [[left click]]:", "citizens.commands.npc.command.none-added" : "No commands have been added.",