From a7b45fc3d4b75a06d4b7de5493279470541c2746 Mon Sep 17 00:00:00 2001 From: asofold Date: Fri, 9 Nov 2012 13:51:24 +0100 Subject: [PATCH] Add basic support for getting an optimized ActionList. --- .../nocheatplus/actions/Action.java | 11 ++++ .../nocheatplus/actions/ActionList.java | 59 +++++++++++++++++-- .../actions/types/DummyAction.java | 8 +++ .../nocheatplus/actions/types/LogAction.java | 57 +++++++++++------- 4 files changed, 108 insertions(+), 27 deletions(-) diff --git a/src/fr/neatmonster/nocheatplus/actions/Action.java b/src/fr/neatmonster/nocheatplus/actions/Action.java index 6b71128a..76707830 100644 --- a/src/fr/neatmonster/nocheatplus/actions/Action.java +++ b/src/fr/neatmonster/nocheatplus/actions/Action.java @@ -1,6 +1,7 @@ package fr.neatmonster.nocheatplus.actions; import fr.neatmonster.nocheatplus.checks.ViolationData; +import fr.neatmonster.nocheatplus.config.ConfigFile; /* * MMP"""""""MM dP oo @@ -75,4 +76,14 @@ public abstract class Action { public boolean executesAlways() { return delay == 0 && repeat == 0; } + + /** + * Get an optimized copy, given the config in use. The default implementation returns this instance. + * @param config + * @param threshold + * @return Can return this (unchanged), null (not to be executed ever) or a new instance (changed, optimized). + */ + public Action getOptimizedCopy(final ConfigFile config, final Integer threshold) { + return this; + } } diff --git a/src/fr/neatmonster/nocheatplus/actions/ActionList.java b/src/fr/neatmonster/nocheatplus/actions/ActionList.java index 66f9355f..79144945 100644 --- a/src/fr/neatmonster/nocheatplus/actions/ActionList.java +++ b/src/fr/neatmonster/nocheatplus/actions/ActionList.java @@ -5,6 +5,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; + +import fr.neatmonster.nocheatplus.config.ConfigFile; /* @@ -19,15 +22,17 @@ import java.util.Map; /** * A list of actions, that associates actions to thresholds. It allows to retrieve all actions that match a certain * threshold. + *
+ * TODO: refactor to an array of Actions entries (threshold + Action[]) + sort that one. */ public class ActionList { + + /** Something to return if nothing is set. */ + private static final Action[] emptyArray = new Action[0]; /** This is a very bad design decision, but it's also really convenient to define this here. */ public final String permissionSilent; - /** If there are no actions registered, we still return an Array. It's just empty/size=0. */ - private final static Action[] emptyArray = new Action[0]; - /** The actions of this ActionList, "bundled" by treshold (violation level). */ private final Map actions = new HashMap(); @@ -37,11 +42,11 @@ public class ActionList { /** * Instantiates a new action list. * - * @param permission + * @param permissionSilent * the permission */ - public ActionList(final String permission) { - permissionSilent = permission + ".silent"; + public ActionList(final String permissionSilent) { + this.permissionSilent = permissionSilent + ".silent"; } /** @@ -89,4 +94,46 @@ public class ActionList { this.actions.put(threshold, actions); } + + /** + * Return a copy of this list, but optimize it, i.e. remove entries that are + * never called, possibly do other optimizations which are possible given + * the specific configuration. + * + * @param config Configuration to adapt to. + * @return Optimized ActionList, individual Actions can be identical instances, altered Action instances must always be new instances, arrays are always new arrays. + */ + public ActionList getOptimizedCopy(final ConfigFile config) { + final ActionList newList = new ActionList(this.permissionSilent); + for (final Entry entry : actions.entrySet()){ + final Integer t = entry.getKey(); + final Action[] a = getOptimizedCopy(config, t, entry.getValue()); + if (a != null && a.length > 0){ + newList.setActions(t, a); + } + } + + return newList; + } + + /** + * Get an optimized copy of the Actions array, given the config in use. + * @param config + * @param threshold + * @param actions + * @return Copy with optimized entries, null or empty arrays are possible. Contained Actions might be identical to the given ones, just changed actions must be new instances to preserve consistency, Action instances are not to be altered. + */ + public Action[] getOptimizedCopy(final ConfigFile config, final Integer threshold, final Action[] actions) + { + if (actions == null || actions.length == 0) return null; + final ArrayList optimized = new ArrayList(); + for (final Action action : actions){ + final Action optAction = action.getOptimizedCopy(config, threshold); + if (optAction != null) optimized.add(optAction); + } + if (optimized.isEmpty()) return null; + final Action[] optActions = new Action[optimized.size()]; + optimized.toArray(optActions); + return optActions; + } } diff --git a/src/fr/neatmonster/nocheatplus/actions/types/DummyAction.java b/src/fr/neatmonster/nocheatplus/actions/types/DummyAction.java index 7e2a24a2..b77f432a 100644 --- a/src/fr/neatmonster/nocheatplus/actions/types/DummyAction.java +++ b/src/fr/neatmonster/nocheatplus/actions/types/DummyAction.java @@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.actions.types; import fr.neatmonster.nocheatplus.actions.Action; import fr.neatmonster.nocheatplus.checks.ViolationData; +import fr.neatmonster.nocheatplus.config.ConfigFile; /* * M""""""'YMM MMP"""""""MM dP oo @@ -48,4 +49,11 @@ public class DummyAction extends Action { return definition; } + @Override + public Action getOptimizedCopy(final ConfigFile config, final Integer threshold) + { + // Never execute this. + return null; + } + } diff --git a/src/fr/neatmonster/nocheatplus/actions/types/LogAction.java b/src/fr/neatmonster/nocheatplus/actions/types/LogAction.java index 17662611..e981139c 100644 --- a/src/fr/neatmonster/nocheatplus/actions/types/LogAction.java +++ b/src/fr/neatmonster/nocheatplus/actions/types/LogAction.java @@ -4,6 +4,7 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import fr.neatmonster.nocheatplus.actions.Action; import fr.neatmonster.nocheatplus.checks.ViolationData; import fr.neatmonster.nocheatplus.config.ConfPaths; import fr.neatmonster.nocheatplus.config.ConfigFile; @@ -63,27 +64,30 @@ public class LogAction extends ActionWithParameters { // TODO: already use && flagfromconfig. } - /* (non-Javadoc) - * @see fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus.checks.ViolationData) - */ - @Override - public boolean execute(final ViolationData violationData) { - final ConfigFile configurationFile = ConfigManager.getConfigFile(); - if (configurationFile.getBoolean(ConfPaths.LOGGING_ACTIVE) - && !violationData.player.hasPermission(violationData.getPermissionSilent())) { - final String message = super.getMessage(violationData); - if (toChat && configurationFile.getBoolean(ConfPaths.LOGGING_INGAMECHAT)) - for (final Player otherPlayer : Bukkit.getServer().getOnlinePlayers()) - if (otherPlayer.hasPermission(Permissions.ADMINISTRATION_NOTIFY)) - otherPlayer.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE - + CheckUtils.replaceColors(message)); - if (toConsole && configurationFile.getBoolean(ConfPaths.LOGGING_CONSOLE)) - LogUtil.logInfo("[NoCheatPlus] " + CheckUtils.removeColors(message)); - if (toFile && configurationFile.getBoolean(ConfPaths.LOGGING_FILE)) - CheckUtils.fileLogger.info(CheckUtils.removeColors(message)); - } - return false; - } + /* + * (non-Javadoc) + * + * @see + * fr.neatmonster.nocheatplus.actions.Action#execute(fr.neatmonster.nocheatplus + * .checks.ViolationData) + */ + @Override + public boolean execute(final ViolationData violationData) { + final ConfigFile configurationFile = ConfigManager.getConfigFile(); + if (configurationFile.getBoolean(ConfPaths.LOGGING_ACTIVE) && !violationData.player.hasPermission(violationData.getPermissionSilent())) { + final String message = super.getMessage(violationData); + if (toChat && configurationFile.getBoolean(ConfPaths.LOGGING_INGAMECHAT)) { + // TODO: ingame chat perms: more efficient + for (final Player otherPlayer : Bukkit.getServer().getOnlinePlayers()){ + if (otherPlayer.hasPermission(Permissions.ADMINISTRATION_NOTIFY)) otherPlayer.sendMessage(ChatColor.RED + "NCP: " + ChatColor.WHITE + CheckUtils.replaceColors(message)); + } + } + + if (toConsole && configurationFile.getBoolean(ConfPaths.LOGGING_CONSOLE)) LogUtil.logInfo("[NoCheatPlus] " + CheckUtils.removeColors(message)); + if (toFile && configurationFile.getBoolean(ConfPaths.LOGGING_FILE)) CheckUtils.fileLogger.info(CheckUtils.removeColors(message)); + } + return false; + } /** * Create the string that's used to define the action in the logfile. @@ -95,4 +99,15 @@ public class LogAction extends ActionWithParameters { return "log:" + name + ":" + delay + ":" + repeat + ":" + (toConsole ? "c" : "") + (toChat ? "i" : "") + (toFile ? "f" : ""); } + + @Override + public Action getOptimizedCopy(final ConfigFile config, final Integer threshold) { + if (!config.getBoolean(ConfPaths.LOGGING_ACTIVE)) return null; + final boolean toConsole = this.toConsole && config.getBoolean(ConfPaths.LOGGING_CONSOLE); + final boolean toFile = this.toFile&& config.getBoolean(ConfPaths.LOGGING_FILE); + final boolean toChat= this.toChat&& config.getBoolean(ConfPaths.LOGGING_INGAMECHAT); + if (!toChat && ! toConsole && !toFile) return null; + return new LogAction(name, delay, repeat, toChat, toConsole, toFile, message); + } + }