diff --git a/plugin.yml b/plugin.yml index 0322235c..c3e7f690 100644 --- a/plugin.yml +++ b/plugin.yml @@ -15,17 +15,12 @@ commands: # permissions: nocheatplus.admin.(...) usage: | / reload: reload NoCheatPlus configuration - /:Player violations: / info (player): Display the violations of a player / removeplayer (player) [(check type)]: Remove data - /:Auxiliary: - / ban [delay=(ticks)] (player) [(reason)...]: ban player - / kick [delay=(ticks)] (player) [(reason)...]: kick player - / kicklist: Show temporarily kicked players. - / tempkick [delay=(ticks)] (player) (minutes) [(reason)...] - / unkick (player): Allow a player to login again. - / tell [delay=(ticks)] (player) (message)...: tell a message - / delay [delay=(ticks)] (command)...: delay a command + / exemptions (player) [(check type)]: Show exemptions + / exempt (player) [(check type)]: Exempt the player + / unexempt (player) [(check type)]: Unexempt the player + / commands: List all commands, more than shown here permissions: nocheatplus: @@ -41,7 +36,13 @@ permissions: nocheatplus.admin.reload: description: Allow the player to reload NoCheatPlus configuration. nocheatplus.admin.info: - description: Allow to see violation info about a player (/ncp info (player)). + description: Allow to see violation info about a player. + nocheatplus.admin.exemptions: + description: Allow to see exemptions for a player. + nocheatplus.admin.exempt: + description: Allow to add exemptions for a player. + nocheatplus.admin.unexempt: + description: Allow to remove exemptions from a player. nocheatplus.admin.ban: description: Allow use of the ncp ban command. nocheatplus.admin.kick: @@ -58,6 +59,8 @@ permissions: description: Allow use of the ncp unkick command. nocheatplus.admin.removeplayer: description: Allow use of the ncp removeplayer command. + nocheatplus.admin.commands: + description: Allow use of the ncp commands command. nocheatplus.bypass: description: Bypass permission other than command permissions. children: diff --git a/src/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakListener.java b/src/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakListener.java index 66e3d05d..8edbf201 100644 --- a/src/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakListener.java +++ b/src/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakListener.java @@ -12,8 +12,6 @@ import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.player.PlayerAnimationEvent; import org.bukkit.event.player.PlayerInteractEvent; -import fr.neatmonster.nocheatplus.players.Permissions; - /* * M#"""""""'M dP dP M#"""""""'M dP * ## mmmm. `M 88 88 ## mmmm. `M 88 @@ -81,6 +79,8 @@ public class BlockBreakListener implements Listener { return; } + // TODO: maybe invalidate instaBreak on some occasions. + final Player player = event.getPlayer(); final Block block = event.getBlock(); @@ -102,7 +102,7 @@ public class BlockBreakListener implements Listener { cancelled = true; // Has the player broken blocks faster than possible? - if (!isInstaBreak && !cancelled && fastBreak.isEnabled(player) && fastBreak.check(player, block, cc, data)) + if (!cancelled && fastBreak.isEnabled(player) && fastBreak.check(player, block, isInstaBreak, cc, data)) cancelled = true; // Did the arm of the player move before breaking this block? @@ -131,7 +131,6 @@ public class BlockBreakListener implements Listener { } if (isInstaBreak){ - if (cc.fastBreakDebug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)) player.sendMessage("[InstaBreak]"); data.wasInstaBreak = now; } else @@ -189,7 +188,8 @@ public class BlockBreakListener implements Listener { // The following is to set the "first damage time" for a block. // Return if it is not left clicking a block. - // (Allows right click to be ignored.) + // (Allows right click to be ignored.) + isInstaBreak = false; if (event.getAction() != Action.LEFT_CLICK_BLOCK) return; checkBlockDamage(event.getPlayer(), event.getClickedBlock(), event); @@ -200,6 +200,7 @@ public class BlockBreakListener implements Listener { public void onBlockDamage(final BlockDamageEvent event) { // System.out.println("Damage("+event.isCancelled()+"): " + event.getBlock()); if (!event.isCancelled() && event.getInstaBreak()) isInstaBreak = true; + else isInstaBreak = false; checkBlockDamage(event.getPlayer(), event.getBlock(), event); } diff --git a/src/fr/neatmonster/nocheatplus/command/CommandHandler.java b/src/fr/neatmonster/nocheatplus/command/CommandHandler.java index 627d517f..7db9f289 100644 --- a/src/fr/neatmonster/nocheatplus/command/CommandHandler.java +++ b/src/fr/neatmonster/nocheatplus/command/CommandHandler.java @@ -17,13 +17,17 @@ import fr.neatmonster.nocheatplus.NoCheatPlus; import fr.neatmonster.nocheatplus.command.actions.BanCommand; import fr.neatmonster.nocheatplus.command.actions.DelayCommand; import fr.neatmonster.nocheatplus.command.actions.KickCommand; +import fr.neatmonster.nocheatplus.command.actions.KickListCommand; import fr.neatmonster.nocheatplus.command.actions.TellCommand; import fr.neatmonster.nocheatplus.command.actions.TempKickCommand; import fr.neatmonster.nocheatplus.command.actions.UnKickCommand; +import fr.neatmonster.nocheatplus.command.admin.CommandsCommand; +import fr.neatmonster.nocheatplus.command.admin.ExemptCommand; +import fr.neatmonster.nocheatplus.command.admin.ExemptionsCommand; import fr.neatmonster.nocheatplus.command.admin.InfoCommand; -import fr.neatmonster.nocheatplus.command.admin.KickListCommand; import fr.neatmonster.nocheatplus.command.admin.ReloadCommand; import fr.neatmonster.nocheatplus.command.admin.RemovePlayerCommand; +import fr.neatmonster.nocheatplus.command.admin.UnexemptCommand; import fr.neatmonster.nocheatplus.config.ConfPaths; import fr.neatmonster.nocheatplus.config.ConfigManager; @@ -100,6 +104,10 @@ public class CommandHandler implements CommandExecutor { new RemovePlayerCommand(plugin), new KickListCommand(plugin), new UnKickCommand(plugin), + new ExemptionsCommand(plugin), + new ExemptCommand(plugin), + new UnexemptCommand(plugin), + new CommandsCommand(plugin), }){ addCommand(cmd); } diff --git a/src/fr/neatmonster/nocheatplus/command/admin/KickListCommand.java b/src/fr/neatmonster/nocheatplus/command/actions/KickListCommand.java similarity index 91% rename from src/fr/neatmonster/nocheatplus/command/admin/KickListCommand.java rename to src/fr/neatmonster/nocheatplus/command/actions/KickListCommand.java index 0bc47151..3fc00870 100644 --- a/src/fr/neatmonster/nocheatplus/command/admin/KickListCommand.java +++ b/src/fr/neatmonster/nocheatplus/command/actions/KickListCommand.java @@ -1,4 +1,4 @@ -package fr.neatmonster.nocheatplus.command.admin; +package fr.neatmonster.nocheatplus.command.actions; import java.util.Arrays; diff --git a/src/fr/neatmonster/nocheatplus/command/admin/CommandsCommand.java b/src/fr/neatmonster/nocheatplus/command/admin/CommandsCommand.java new file mode 100644 index 00000000..cfea93da --- /dev/null +++ b/src/fr/neatmonster/nocheatplus/command/admin/CommandsCommand.java @@ -0,0 +1,53 @@ +package fr.neatmonster.nocheatplus.command.admin; + +import java.util.Arrays; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import fr.neatmonster.nocheatplus.NoCheatPlus; +import fr.neatmonster.nocheatplus.command.NCPCommand; +import fr.neatmonster.nocheatplus.players.Permissions; +import fr.neatmonster.nocheatplus.utilities.CheckUtils; + +/** + * This command just shows a list of all commands. + * @author mc_dev + * + */ +public class CommandsCommand extends NCPCommand { + + final String[] moreCommands = new String[]{ + "/ ban [delay=(ticks)] (player) [(reason)...]: ban player", + "/ kick [delay=(ticks)] (player) [(reason)...]: kick player", + "/ tempkick [delay=(ticks)] (player) (minutes) [(reason)...]", + "/ unkick (player): Allow a player to login again.", + "/ kicklist: Show temporarily kicked players.", + "/ tell [delay=(ticks)] (player) (message)...: tell a message", + "/ delay [delay=(ticks)] (command)...: delay a command", + }; + + final String allCommands; + + public CommandsCommand(NoCheatPlus plugin) { + super(plugin, "commands", Permissions.ADMINISTRATION_COMMANDS, new String[]{"cmds"}); + for (int i = 0; i < moreCommands.length; i++){ + moreCommands[i] = moreCommands[i].replace("", "ncp"); + } + String all = TAG + "All commands info:\n"; + Command cmd = plugin.getCommand("nocheatplus"); + if (cmd != null){ + all += cmd.getUsage().replace("", "ncp") + "\n"; + } + all += CheckUtils.join(Arrays.asList(moreCommands), "\n"); + allCommands = all; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, + String label, String[] args) { + sender.sendMessage(allCommands); + return true; + } + +} diff --git a/src/fr/neatmonster/nocheatplus/command/admin/ExemptCommand.java b/src/fr/neatmonster/nocheatplus/command/admin/ExemptCommand.java new file mode 100644 index 00000000..6767b315 --- /dev/null +++ b/src/fr/neatmonster/nocheatplus/command/admin/ExemptCommand.java @@ -0,0 +1,52 @@ +package fr.neatmonster.nocheatplus.command.admin; + +import java.util.Arrays; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import fr.neatmonster.nocheatplus.NoCheatPlus; +import fr.neatmonster.nocheatplus.checks.CheckType; +import fr.neatmonster.nocheatplus.command.NCPCommand; +import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; +import fr.neatmonster.nocheatplus.players.Permissions; +import fr.neatmonster.nocheatplus.utilities.CheckUtils; + +public class ExemptCommand extends NCPCommand { + + public ExemptCommand(NoCheatPlus plugin) { + super(plugin, "exempt", Permissions.ADMINISTRATION_EXEMPT); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, + String label, String[] args) { + // TODO: Reduce copy and paste by introducing some super class. + if (args.length < 2 || args.length > 3) return false; + String playerName = args[1]; + final CheckType checkType; + if (args.length == 3){ + try{ + checkType = CheckType.valueOf(args[2].toUpperCase().replace('-', '_').replace('.', '_')); + } catch (Exception e){ + sender.sendMessage(TAG + "Could not interpret: " + args[2]); + sender.sendMessage(TAG + "Check type should be one of: " + CheckUtils.join(Arrays.asList(CheckType.values()), " | ")); + return true; + } + } + else checkType = CheckType.ALL; + + final Player player = Bukkit.getPlayerExact(playerName); + if (player == null){ + sender.sendMessage(TAG + "Player not online: " + playerName); + return true; + } + else playerName = player.getName(); + NCPExemptionManager.exemptPermanently(player, checkType); + sender.sendMessage(TAG + "Player " + playerName + " is now exempted from: " + checkType); + return true; + } + +} diff --git a/src/fr/neatmonster/nocheatplus/command/admin/ExemptionsCommand.java b/src/fr/neatmonster/nocheatplus/command/admin/ExemptionsCommand.java new file mode 100644 index 00000000..5348e8b1 --- /dev/null +++ b/src/fr/neatmonster/nocheatplus/command/admin/ExemptionsCommand.java @@ -0,0 +1,40 @@ +package fr.neatmonster.nocheatplus.command.admin; + +import java.util.LinkedList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import fr.neatmonster.nocheatplus.NoCheatPlus; +import fr.neatmonster.nocheatplus.checks.CheckType; +import fr.neatmonster.nocheatplus.command.NCPCommand; +import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; +import fr.neatmonster.nocheatplus.players.Permissions; +import fr.neatmonster.nocheatplus.utilities.CheckUtils; + +public class ExemptionsCommand extends NCPCommand { + + public ExemptionsCommand(NoCheatPlus plugin) { + super(plugin, "exemptions", Permissions.ADMINISTRATION_EXEMPTIONS, new String[]{"exe"}); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, + String label, String[] args) { + if (args.length != 2) return false; + String playerName = args[1].trim(); + Player player = Bukkit.getPlayerExact(playerName); + if (player != null) playerName = player.getName(); + final List entries = new LinkedList(); + for (CheckType type : CheckType.values()){ + if (NCPExemptionManager.isExempted(playerName, type)) entries.add(type.toString()); + } + if (entries.isEmpty()) sender.sendMessage(TAG + "No exemption entries available for " + playerName +" ."); + else sender.sendMessage(TAG + "Exemptions for " + playerName + ": " + CheckUtils.join(entries, ", ")); + return true; + } + +} diff --git a/src/fr/neatmonster/nocheatplus/command/admin/UnexemptCommand.java b/src/fr/neatmonster/nocheatplus/command/admin/UnexemptCommand.java new file mode 100644 index 00000000..d399ab96 --- /dev/null +++ b/src/fr/neatmonster/nocheatplus/command/admin/UnexemptCommand.java @@ -0,0 +1,47 @@ +package fr.neatmonster.nocheatplus.command.admin; + +import java.util.Arrays; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import fr.neatmonster.nocheatplus.NoCheatPlus; +import fr.neatmonster.nocheatplus.checks.CheckType; +import fr.neatmonster.nocheatplus.command.NCPCommand; +import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; +import fr.neatmonster.nocheatplus.players.Permissions; +import fr.neatmonster.nocheatplus.utilities.CheckUtils; + +public class UnexemptCommand extends NCPCommand { + + public UnexemptCommand(NoCheatPlus plugin) { + super(plugin, "unexempt", Permissions.ADMINISTRATION_UNEXEMPT); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, + String label, String[] args) { + // TODO: Reduce copy and paste by introducing some super class. + if (args.length < 2 || args.length > 3) return false; + String playerName = args[1]; + final CheckType checkType; + if (args.length == 3){ + try{ + checkType = CheckType.valueOf(args[2].toUpperCase().replace('-', '_').replace('.', '_')); + } catch (Exception e){ + sender.sendMessage(TAG + "Could not interpret: " + args[2]); + sender.sendMessage(TAG + "Check type should be one of: " + CheckUtils.join(Arrays.asList(CheckType.values()), " | ")); + return true; + } + } + else checkType = CheckType.ALL; + final Player player = Bukkit.getPlayerExact(playerName); + if (player != null) playerName = player.getName(); + NCPExemptionManager.unexempt(playerName, checkType); + sender.sendMessage(TAG + "Player " + playerName + " will not be exempted from: " + checkType); + return true; + } + +} diff --git a/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java b/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java index 609093fd..e19c3148 100644 --- a/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java +++ b/src/fr/neatmonster/nocheatplus/config/DefaultConfig.java @@ -69,7 +69,7 @@ public class DefaultConfig extends ConfigFile { set(ConfPaths.BLOCKBREAK_DIRECTION_ACTIONS, "cancel vl>10 log:bdirection:0:5:if cancel"); set(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK, true); - set(ConfPaths.BLOCKBREAK_FASTBREAK_DELAY, 60); + set(ConfPaths.BLOCKBREAK_FASTBREAK_DELAY, 90); set(ConfPaths.BLOCKBREAK_FASTBREAK_MOD_SURVIVAL, 100); set(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, "cancel vl>500 log:fastbreak:3:5:cif cancel"); diff --git a/src/fr/neatmonster/nocheatplus/players/Permissions.java b/src/fr/neatmonster/nocheatplus/players/Permissions.java index 01e347e7..22cf9c33 100644 --- a/src/fr/neatmonster/nocheatplus/players/Permissions.java +++ b/src/fr/neatmonster/nocheatplus/players/Permissions.java @@ -26,7 +26,13 @@ public class Permissions { public static final String ADMINISTRATION_BAN = ADMINISTRATION + ".ban"; public static final String ADMINISTRATION_DELAY = ADMINISTRATION + ".delay"; + + public static final String ADMINISTRATION_EXEMPT = ADMINISTRATION + ".exempt"; + public static final String ADMINISTRATION_UNEXEMPT = ADMINISTRATION + ".unexempt"; + public static final String ADMINISTRATION_EXEMPTIONS = ADMINISTRATION + ".exemptions"; + public static final String ADMINISTRATION_INFO = ADMINISTRATION + ".info"; + public static final String ADMINISTRATION_COMMANDS = ADMINISTRATION + ".commands"; public static final String ADMINISTRATION_KICK = ADMINISTRATION + ".kick"; public static final String ADMINISTRATION_KICKLIST = ADMINISTRATION + ".kicklist"; public static final String ADMINISTRATION_NOTIFY = ADMINISTRATION + ".notify";