Add basic support for getting an optimized ActionList.

This commit is contained in:
asofold 2012-11-09 13:51:24 +01:00
parent 71aaba2ea8
commit a7b45fc3d4
4 changed files with 108 additions and 27 deletions

View File

@ -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;
}
}

View File

@ -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.
* <hr>
* 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<Integer, Action[]> actions = new HashMap<Integer, Action[]>();
@ -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<Integer, Action[]> 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<Action> optimized = new ArrayList<Action>();
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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}