summaryrefslogtreecommitdiffstats
path: root/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config
diff options
context:
space:
mode:
Diffstat (limited to 'EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config')
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ActionFactory.java183
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfPaths.java142
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationCacheStore.java45
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationManager.java257
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/DefaultConfiguration.java154
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/LoggingConfig.java29
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/NoCheatConfiguration.java82
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/Permissions.java44
8 files changed, 936 insertions, 0 deletions
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ActionFactory.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ActionFactory.java
new file mode 100644
index 000000000..5e07661c1
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ActionFactory.java
@@ -0,0 +1,183 @@
+package com.earth2me.essentials.anticheat.config;
+
+import com.earth2me.essentials.anticheat.actions.Action;
+import com.earth2me.essentials.anticheat.actions.types.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * Helps with creating Actions out of text string definitions
+ *
+ */
+public class ActionFactory
+{
+ private static final Map<String, Object> lib = new HashMap<String, Object>();
+
+ public ActionFactory(Map<String, Object> library)
+ {
+ lib.putAll(library);
+ }
+
+ public Action createAction(String actionDefinition)
+ {
+
+ actionDefinition = actionDefinition.toLowerCase();
+
+ if (actionDefinition.equals("cancel"))
+ {
+ return new SpecialAction();
+ }
+
+ if (actionDefinition.startsWith("log:"))
+ {
+ return parseLogAction(actionDefinition.split(":", 2)[1]);
+ }
+
+ if (actionDefinition.startsWith("cmd:"))
+ {
+ return parseCmdAction(actionDefinition.split(":", 2)[1]);
+ }
+
+ throw new IllegalArgumentException("NoCheat doesn't understand action '" + actionDefinition + "' at all");
+ }
+
+ private Action parseCmdAction(String definition)
+ {
+ String[] parts = definition.split(":");
+ String name = parts[0];
+ Object command = lib.get(parts[0]);
+ int delay = 0;
+ int repeat = 1;
+
+ if (command == null)
+ {
+ throw new IllegalArgumentException("NoCheat doesn't know command '" + name + "'. Have you forgotten to define it?");
+ }
+
+ if (parts.length > 1)
+ {
+ try
+ {
+ delay = Integer.parseInt(parts[1]);
+ repeat = Integer.parseInt(parts[2]);
+ }
+ catch (Exception e)
+ {
+ // TODO
+ System.out.println("NoCheat couldn't parse details of command '" + definition + "', will use default values instead.");
+ delay = 0;
+ repeat = 1;
+ }
+ }
+
+ return new ConsolecommandAction(name, delay, repeat, command.toString());
+ }
+
+ private Action parseLogAction(String definition)
+ {
+ String[] parts = definition.split(":");
+ String name = parts[0];
+ Object message = lib.get(parts[0]);
+ int delay = 0;
+ int repeat = 1;
+ boolean toConsole = true;
+ boolean toFile = true;
+ boolean toChat = true;
+
+ if (message == null)
+ {
+ throw new IllegalArgumentException("NoCheat doesn't know log message '" + name + "'. Have you forgotten to define it?");
+ }
+
+ try
+ {
+ delay = Integer.parseInt(parts[1]);
+ repeat = Integer.parseInt(parts[2]);
+ toConsole = parts[3].contains("c");
+ toChat = parts[3].contains("i");
+ toFile = parts[3].contains("f");
+ }
+ catch (Exception e)
+ {
+ System.out.println("NoCheat couldn't parse details of log action '" + definition + "', will use default values instead.");
+ e.printStackTrace();
+ delay = 0;
+ repeat = 1;
+ toConsole = true;
+ toFile = true;
+ toChat = true;
+ }
+
+ return new LogAction(name, delay, repeat, toChat, toConsole, toFile, message.toString());
+ }
+
+ public Action[] createActions(String... definitions)
+ {
+ List<Action> actions = new ArrayList<Action>();
+
+ for (String def : definitions)
+ {
+ if (def.length() == 0)
+ {
+ continue;
+ }
+ try
+ {
+ actions.add(createAction(def));
+ }
+ catch (IllegalArgumentException e)
+ {
+ System.out.println(e.getMessage());
+ actions.add(new DummyAction(def));
+ }
+ }
+
+ return actions.toArray(new Action[actions.size()]);
+ }
+
+ public ActionList createActionList(String definition, String permission)
+ {
+ ActionList list = new ActionList(permission);
+
+ boolean first = true;
+
+ for (String s : definition.split("vl>"))
+ {
+ s = s.trim();
+
+ if (s.length() == 0)
+ {
+ first = false;
+ continue;
+ }
+
+ try
+ {
+ Integer vl;
+ String def;
+ if (first)
+ {
+ first = false;
+ vl = 0;
+ def = s;
+ }
+ else
+ {
+ String[] listEntry = s.split("\\s+", 2);
+ vl = Integer.parseInt(listEntry[0]);
+ def = listEntry[1];
+ }
+ list.setActions(vl, createActions(def.split("\\s+")));
+ }
+ catch (Exception e)
+ {
+ System.out.println("NoCheat couldn't parse action definition 'vl:" + s + "'");
+ }
+ }
+
+ return list;
+ }
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfPaths.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfPaths.java
new file mode 100644
index 000000000..66473633d
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfPaths.java
@@ -0,0 +1,142 @@
+package com.earth2me.essentials.anticheat.config;
+
+/**
+ * Paths for the configuration options Making everything final static prevents accidentially modifying any of these
+ *
+ */
+public abstract class ConfPaths
+{
+ // TODO
+ private final static String LOGGING = "logging.";
+ public final static String LOGGING_ACTIVE = LOGGING + "active";
+ public final static String LOGGING_PREFIX = LOGGING + "prefix";
+ public final static String LOGGING_FILENAME = LOGGING + "filename";
+ public final static String LOGGING_LOGTOFILE = LOGGING + "file";
+ public final static String LOGGING_LOGTOCONSOLE = LOGGING + "console";
+ public final static String LOGGING_LOGTOINGAMECHAT = LOGGING + "ingamechat";
+ public final static String LOGGING_SHOWACTIVECHECKS = LOGGING + "showactivechecks";
+ public final static String LOGGING_DEBUGMESSAGES = LOGGING + "debugmessages";
+
+ private final static String CHECKS = "checks.";
+
+ private final static String INVENTORY = CHECKS + "inventory.";
+
+ private final static String INVENTORY_DROP = INVENTORY + "drop.";
+ public final static String INVENTORY_DROP_CHECK = INVENTORY_DROP + "active";
+ public final static String INVENTORY_DROP_TIMEFRAME = INVENTORY_DROP + "time";
+ public final static String INVENTORY_DROP_LIMIT = INVENTORY_DROP + "limit";
+ public final static String INVENTORY_DROP_ACTIONS = INVENTORY_DROP + "actions";
+
+ private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
+ public final static String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";
+ public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions";
+
+ private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";
+ public final static String INVENTORY_INSTANTEAT_CHECK = INVENTORY_INSTANTEAT + "active";
+ public static final String INVENTORY_INSTANTEAT_ACTIONS = INVENTORY_INSTANTEAT + "actions";
+
+ private final static String MOVING = CHECKS + "moving.";
+
+ private final static String MOVING_RUNFLY = MOVING + "runfly.";
+ public final static String MOVING_RUNFLY_CHECK = MOVING_RUNFLY + "active";
+
+ // These four are not automatically shown in the config
+ public final static String MOVING_RUNFLY_WALKSPEED = MOVING_RUNFLY + "walkspeed";
+ public final static String MOVING_RUNFLY_SNEAKSPEED = MOVING_RUNFLY + "sneakspeed";
+ public final static String MOVING_RUNFLY_SWIMSPEED = MOVING_RUNFLY + "swimspeed";
+ public final static String MOVING_RUNFLY_SPRINTSPEED = MOVING_RUNFLY + "sprintspeed";
+
+ public final static String MOVING_RUNFLY_ALLOWFASTSNEAKING = MOVING_RUNFLY + "allowfastsneaking";
+ public final static String MOVING_RUNFLY_ACTIONS = MOVING_RUNFLY + "actions";
+
+ public final static String MOVING_RUNFLY_CHECKNOFALL = MOVING_RUNFLY + "checknofall";
+ public final static String MOVING_RUNFLY_NOFALLAGGRESSIVE = MOVING_RUNFLY + "nofallaggressivemode";
+ public final static String MOVING_RUNFLY_NOFALLACTIONS = MOVING_RUNFLY + "nofallactions";
+
+ private final static String MOVING_RUNFLY_FLYING = MOVING_RUNFLY + "flying.";
+ public final static String MOVING_RUNFLY_FLYING_ALLOWALWAYS = MOVING_RUNFLY_FLYING + "allowflyingalways";
+ public final static String MOVING_RUNFLY_FLYING_ALLOWINCREATIVE = MOVING_RUNFLY_FLYING + "allowflyingincreative";
+ public final static String MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL = MOVING_RUNFLY_FLYING + "flyingspeedlimitvertical";
+ public final static String MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL = MOVING_RUNFLY_FLYING + "flyingspeedlimithorizontal";
+ public final static String MOVING_RUNFLY_FLYING_HEIGHTLIMIT = MOVING_RUNFLY_FLYING + "flyingheightlimit";
+ public final static String MOVING_RUNFLY_FLYING_ACTIONS = MOVING_RUNFLY_FLYING + "actions";
+
+ private final static String MOVING_MOREPACKETS = MOVING + "morepackets.";
+ public final static String MOVING_MOREPACKETS_CHECK = MOVING_MOREPACKETS + "active";
+ public final static String MOVING_MOREPACKETS_ACTIONS = MOVING_MOREPACKETS + "actions";
+
+ private final static String BLOCKBREAK = CHECKS + "blockbreak.";
+
+ private final static String BLOCKBREAK_REACH = BLOCKBREAK + "reach.";
+ public final static String BLOCKBREAK_REACH_CHECK = BLOCKBREAK_REACH + "active";
+ public final static String BLOCKBREAK_REACH_ACTIONS = BLOCKBREAK_REACH + "actions";
+
+ private final static String BLOCKBREAK_DIRECTION = BLOCKBREAK + "direction.";
+ public final static String BLOCKBREAK_DIRECTION_CHECK = BLOCKBREAK_DIRECTION + "active";
+ public final static String BLOCKBREAK_DIRECTION_PRECISION = BLOCKBREAK_DIRECTION + "precision";
+ public final static String BLOCKBREAK_DIRECTION_PENALTYTIME = BLOCKBREAK_DIRECTION + "penaltytime";
+ public final static String BLOCKBREAK_DIRECTION_ACTIONS = BLOCKBREAK_DIRECTION + "actions";
+
+ private final static String BLOCKBREAK_NOSWING = BLOCKBREAK + "noswing.";
+ public static final String BLOCKBREAK_NOSWING_CHECK = BLOCKBREAK_NOSWING + "active";
+ public static final String BLOCKBREAK_NOSWING_ACTIONS = BLOCKBREAK_NOSWING + "actions";
+
+ private final static String BLOCKPLACE = CHECKS + "blockplace.";
+
+ private final static String BLOCKPLACE_REACH = BLOCKPLACE + "reach.";
+ public final static String BLOCKPLACE_REACH_CHECK = BLOCKPLACE_REACH + "active";
+ public final static String BLOCKPLACE_REACH_ACTIONS = BLOCKPLACE_REACH + "actions";
+
+ private final static String BLOCKPLACE_DIRECTION = BLOCKPLACE + "direction.";
+ public final static String BLOCKPLACE_DIRECTION_CHECK = BLOCKPLACE_DIRECTION + "active";
+ public final static String BLOCKPLACE_DIRECTION_PRECISION = BLOCKPLACE_DIRECTION + "precision";
+ public final static String BLOCKPLACE_DIRECTION_PENALTYTIME = BLOCKPLACE_DIRECTION + "penaltytime";
+ public final static String BLOCKPLACE_DIRECTION_ACTIONS = BLOCKPLACE_DIRECTION + "actions";
+
+ private final static String CHAT = CHECKS + "chat.";
+
+ private final static String CHAT_COLOR = CHAT + "color.";
+ public final static String CHAT_COLOR_CHECK = CHAT_COLOR + "active";
+ public final static String CHAT_COLOR_ACTIONS = CHAT_COLOR + "actions";
+
+ private final static String CHAT_SPAM = CHAT + "spam.";
+ public final static String CHAT_SPAM_CHECK = CHAT_SPAM + "active";
+ public final static String CHAT_SPAM_WHITELIST = CHAT_SPAM + "whitelist";
+ public final static String CHAT_SPAM_TIMEFRAME = CHAT_SPAM + "timeframe";
+ public final static String CHAT_SPAM_MESSAGELIMIT = CHAT_SPAM + "messagelimit";
+ public final static String CHAT_SPAM_COMMANDLIMIT = CHAT_SPAM + "commandlimit";
+ public final static String CHAT_SPAM_ACTIONS = CHAT_SPAM + "actions";
+
+ private final static String FIGHT = CHECKS + "fight.";
+
+ private final static String FIGHT_DIRECTION = FIGHT + "direction.";
+ public final static String FIGHT_DIRECTION_CHECK = FIGHT_DIRECTION + "active";
+ public final static String FIGHT_DIRECTION_PRECISION = FIGHT_DIRECTION + "precision";
+ public final static String FIGHT_DIRECTION_PENALTYTIME = FIGHT_DIRECTION + "penaltytime";
+ public final static String FIGHT_DIRECTION_ACTIONS = FIGHT_DIRECTION + "actions";
+
+ private final static String FIGHT_NOSWING = FIGHT + "noswing.";
+ public final static String FIGHT_NOSWING_CHECK = FIGHT_NOSWING + "active";
+ public final static String FIGHT_NOSWING_ACTIONS = FIGHT_NOSWING + "actions";
+
+ private final static String FIGHT_REACH = FIGHT + "reach.";
+ public static final String FIGHT_REACH_CHECK = FIGHT_REACH + "active";
+ public static final String FIGHT_REACH_LIMIT = FIGHT_REACH + "distance";
+ public static final String FIGHT_REACH_PENALTYTIME = FIGHT_REACH + "penaltytime";
+ public static final String FIGHT_REACH_ACTIONS = FIGHT_REACH + "actions";
+
+ private final static String FIGHT_SPEED = FIGHT + "speed.";
+ public final static String FIGHT_SPEED_CHECK = FIGHT_SPEED + "active";
+ public final static String FIGHT_SPEED_ATTACKLIMIT = FIGHT_SPEED + "attacklimit";
+ public final static String FIGHT_SPEED_ACTIONS = FIGHT_SPEED + "actions";
+
+ private final static String FIGHT_GODMODE = FIGHT + "godmode.";
+ public static final String FIGHT_GODMODE_CHECK = FIGHT_GODMODE + "active";
+ public final static String FIGHT_GODMODE_ACTIONS = FIGHT_GODMODE + "actions";
+
+ private final static String FIGHT_INSTANTHEAL = FIGHT + "instantheal.";
+ public static final String FIGHT_INSTANTHEAL_CHECK = FIGHT_INSTANTHEAL + "active";
+ public final static String FIGHT_INSTANTHEAL_ACTIONS = FIGHT_INSTANTHEAL + "actions";
+
+ public final static String STRINGS = "strings";
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationCacheStore.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationCacheStore.java
new file mode 100644
index 000000000..fa404d5ea
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationCacheStore.java
@@ -0,0 +1,45 @@
+package com.earth2me.essentials.anticheat.config;
+
+import com.earth2me.essentials.anticheat.ConfigItem;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * A class to keep all configurables of the plugin associated with a world
+ *
+ */
+public class ConfigurationCacheStore
+{
+ public final LoggingConfig logging;
+ private final Map<String, ConfigItem> configMap = new HashMap<String, ConfigItem>();
+ private final NoCheatConfiguration data;
+
+ /**
+ * Instantiate a config cache and populate it with the data of a Config tree (and its parent tree)
+ */
+ public ConfigurationCacheStore(NoCheatConfiguration data)
+ {
+
+ logging = new LoggingConfig(data);
+
+ this.data = data;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends ConfigItem> T get(String id)
+ {
+ return (T)configMap.get(id);
+ }
+
+ public void set(String id, ConfigItem config)
+ {
+
+ configMap.put(id, config);
+ }
+
+ public NoCheatConfiguration getConfiguration()
+ {
+ return this.data;
+ }
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationManager.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationManager.java
new file mode 100644
index 000000000..283ad88d2
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/ConfigurationManager.java
@@ -0,0 +1,257 @@
+package com.earth2me.essentials.anticheat.config;
+
+import com.earth2me.essentials.anticheat.NoCheat;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.*;
+
+
+/**
+ * Central location for everything that's described in the configuration file(s)
+ *
+ */
+public class ConfigurationManager
+{
+ private final static String configFileName = "config.yml";
+ private final Map<String, ConfigurationCacheStore> worldnameToConfigCacheMap = new HashMap<String, ConfigurationCacheStore>();
+ private FileHandler fileHandler;
+ private final NoCheat plugin;
+
+
+ private static class LogFileFormatter extends Formatter
+ {
+ private final SimpleDateFormat date;
+
+ public LogFileFormatter()
+ {
+ date = new SimpleDateFormat("yy.MM.dd HH:mm:ss");
+ }
+
+ @Override
+ public String format(LogRecord record)
+ {
+ StringBuilder builder = new StringBuilder();
+ Throwable ex = record.getThrown();
+
+ builder.append(date.format(record.getMillis()));
+ builder.append(" [");
+ builder.append(record.getLevel().getLocalizedName().toUpperCase());
+ builder.append("] ");
+ builder.append(record.getMessage());
+ builder.append('\n');
+
+ if (ex != null)
+ {
+ StringWriter writer = new StringWriter();
+ ex.printStackTrace(new PrintWriter(writer));
+ builder.append(writer);
+ }
+
+ return builder.toString();
+ }
+ }
+
+ public ConfigurationManager(NoCheat plugin, File rootConfigFolder)
+ {
+
+ this.plugin = plugin;
+
+ // Setup the real configuration
+ initializeConfig(rootConfigFolder);
+
+ }
+
+ /**
+ * Read the configuration file and assign either standard values or whatever is declared in the file
+ *
+ * @param configurationFile
+ */
+ private void initializeConfig(File rootConfigFolder)
+ {
+
+ // First try to obtain and parse the global config file
+ NoCheatConfiguration root = new NoCheatConfiguration();
+ root.setDefaults(new DefaultConfiguration());
+ root.options().copyDefaults(true);
+ root.options().copyHeader(true);
+
+ File globalConfigFile = getGlobalConfigFile(rootConfigFolder);
+
+ if (globalConfigFile.exists())
+ {
+ try
+ {
+ root.load(globalConfigFile);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ try
+ {
+ root.save(globalConfigFile);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ root.regenerateActionLists();
+
+ // Create a corresponding Configuration Cache
+ // put the global config on the config map
+ worldnameToConfigCacheMap.put(null, new ConfigurationCacheStore(root));
+
+ plugin.setFileLogger(setupFileLogger(new File(rootConfigFolder, root.getString(ConfPaths.LOGGING_FILENAME))));
+
+ // Try to find world-specific config files
+ Map<String, File> worldFiles = getWorldSpecificConfigFiles(rootConfigFolder);
+
+ for (Entry<String, File> worldEntry : worldFiles.entrySet())
+ {
+
+ File worldConfigFile = worldEntry.getValue();
+
+ NoCheatConfiguration world = new NoCheatConfiguration();
+ world.setDefaults(root);
+
+ try
+ {
+ world.load(worldConfigFile);
+
+ worldnameToConfigCacheMap.put(worldEntry.getKey(), new ConfigurationCacheStore(world));
+
+ // write the config file back to disk immediately
+ world.save(worldConfigFile);
+
+ }
+ catch (Exception e)
+ {
+ plugin.getLogger().warning("Couldn't load world-specific config for " + worldEntry.getKey());
+ e.printStackTrace();
+ }
+
+ world.regenerateActionLists();
+ }
+ }
+
+ private static File getGlobalConfigFile(File rootFolder)
+ {
+
+ File globalConfig = new File(rootFolder, configFileName);
+
+ return globalConfig;
+ }
+
+ private static Map<String, File> getWorldSpecificConfigFiles(File rootFolder)
+ {
+
+ HashMap<String, File> files = new HashMap<String, File>();
+
+ if (rootFolder.isDirectory())
+ {
+ for (File f : rootFolder.listFiles())
+ {
+ if (f.isFile())
+ {
+ String filename = f.getName();
+ if (filename.matches(".+_" + configFileName + "$"))
+ {
+ // Get the first part = world name
+ String worldname = filename.substring(0, filename.length() - (configFileName.length() + 1));
+ files.put(worldname, f);
+ }
+ }
+ }
+ }
+ return files;
+ }
+
+ private Logger setupFileLogger(File logfile)
+ {
+
+ Logger l = Logger.getAnonymousLogger();
+ l.setLevel(Level.INFO);
+ // Ignore parent's settings
+ l.setUseParentHandlers(false);
+ for (Handler h : l.getHandlers())
+ {
+ l.removeHandler(h);
+ }
+
+ if (fileHandler != null)
+ {
+ fileHandler.close();
+ l.removeHandler(fileHandler);
+ fileHandler = null;
+ }
+
+ try
+ {
+ try
+ {
+ logfile.getParentFile().mkdirs();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ fileHandler = new FileHandler(logfile.getCanonicalPath(), true);
+ fileHandler.setLevel(Level.ALL);
+ fileHandler.setFormatter(new LogFileFormatter());
+
+ l.addHandler(fileHandler);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ return l;
+ }
+
+ /**
+ * Reset the loggers and flush and close the fileHandlers to be able to use them next time without problems
+ */
+ public void cleanup()
+ {
+ fileHandler.flush();
+ fileHandler.close();
+ Logger l = Logger.getLogger("NoCheat");
+ l.removeHandler(fileHandler);
+ fileHandler = null;
+ }
+
+ /**
+ * Get the cache of the specified world, or the default cache, if no cache exists for that world.
+ *
+ * @param worldname
+ * @return
+ */
+ public ConfigurationCacheStore getConfigurationCacheForWorld(String worldname)
+ {
+
+ ConfigurationCacheStore cache = worldnameToConfigCacheMap.get(worldname);
+
+ if (cache != null)
+ {
+ return cache;
+ }
+ else
+ {
+ // Enter a reference to the cache under the new name
+ // to be faster in looking it up later
+ cache = worldnameToConfigCacheMap.get(null);
+ worldnameToConfigCacheMap.put(worldname, cache);
+
+ return cache;
+ }
+ }
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/DefaultConfiguration.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/DefaultConfiguration.java
new file mode 100644
index 000000000..fd61cac5d
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/DefaultConfiguration.java
@@ -0,0 +1,154 @@
+package com.earth2me.essentials.anticheat.config;
+
+
+/**
+ * These are the default settings for NoCheat. They will be used in addition to/in replacement of configurations given
+ * in the config.yml file
+ *
+ */
+public class DefaultConfiguration extends NoCheatConfiguration
+{
+ public DefaultConfiguration()
+ {
+
+ super();
+
+ this.options().header("Main configuration file for NoCheat. Read \"Instructions.txt\"");
+
+ /**
+ * LOGGING *
+ */
+ set(ConfPaths.LOGGING_ACTIVE, true);
+ set(ConfPaths.LOGGING_SHOWACTIVECHECKS, false);
+ set(ConfPaths.LOGGING_DEBUGMESSAGES, false);
+ set(ConfPaths.LOGGING_PREFIX, "&4NC&f: ");
+ set(ConfPaths.LOGGING_FILENAME, "nocheat.log");
+ set(ConfPaths.LOGGING_LOGTOFILE, true);
+ set(ConfPaths.LOGGING_LOGTOCONSOLE, true);
+ set(ConfPaths.LOGGING_LOGTOINGAMECHAT, true);
+
+ /**
+ * * INVENTORY **
+ */
+ set(ConfPaths.INVENTORY_DROP_CHECK, true);
+ set(ConfPaths.INVENTORY_DROP_TIMEFRAME, 20);
+ set(ConfPaths.INVENTORY_DROP_LIMIT, 100);
+ set(ConfPaths.INVENTORY_DROP_ACTIONS, "log:drop:0:1:cif cmd:kick");
+
+ set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true);
+ set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "log:ibow:2:5:if cancel");
+
+ set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
+ set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:ieat:2:5:if cancel");
+
+ /**
+ * * MOVING **
+ */
+ set(ConfPaths.MOVING_RUNFLY_CHECK, true);
+ set(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING, false);
+ set(ConfPaths.MOVING_RUNFLY_ACTIONS, "log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");
+
+ set(ConfPaths.MOVING_RUNFLY_CHECKNOFALL, true);
+ set(ConfPaths.MOVING_RUNFLY_NOFALLAGGRESSIVE, true);
+ set(ConfPaths.MOVING_RUNFLY_NOFALLACTIONS, "log:nofall:0:5:cif cancel");
+
+ set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWALWAYS, false);
+ set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWINCREATIVE, true);
+ set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL, 60);
+ set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL, 100);
+ set(ConfPaths.MOVING_RUNFLY_FLYING_HEIGHTLIMIT, 128);
+ set(ConfPaths.MOVING_RUNFLY_FLYING_ACTIONS, "log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");
+
+ set(ConfPaths.MOVING_MOREPACKETS_CHECK, true);
+ set(ConfPaths.MOVING_MOREPACKETS_ACTIONS, "log:morepackets:3:2:if cancel vl>20 log:morepackets:0:2:if cancel");
+
+ /**
+ * * BLOCKBREAK **
+ */
+ set(ConfPaths.BLOCKBREAK_REACH_CHECK, true);
+ set(ConfPaths.BLOCKBREAK_REACH_ACTIONS, "cancel vl>5 log:bbreach:0:2:if cancel");
+
+ set(ConfPaths.BLOCKBREAK_DIRECTION_CHECK, true);
+ set(ConfPaths.BLOCKBREAK_DIRECTION_PRECISION, 50);
+ set(ConfPaths.BLOCKBREAK_DIRECTION_PENALTYTIME, 300);
+ set(ConfPaths.BLOCKBREAK_DIRECTION_ACTIONS, "cancel vl>10 log:bbdirection:0:5:if cancel");
+
+ set(ConfPaths.BLOCKBREAK_NOSWING_CHECK, true);
+ set(ConfPaths.BLOCKBREAK_NOSWING_ACTIONS, "log:bbnoswing:3:2:if cancel");
+
+ /**
+ * * BLOCKPLACE **
+ */
+ set(ConfPaths.BLOCKPLACE_REACH_CHECK, true);
+ set(ConfPaths.BLOCKPLACE_REACH_ACTIONS, "cancel vl>5 log:bpreach:0:2:if cancel");
+
+ set(ConfPaths.BLOCKPLACE_DIRECTION_CHECK, true);
+ set(ConfPaths.BLOCKPLACE_DIRECTION_PRECISION, 75);
+ set(ConfPaths.BLOCKPLACE_DIRECTION_PENALTYTIME, 100);
+ set(ConfPaths.BLOCKPLACE_DIRECTION_ACTIONS, "cancel vl>10 log:bpdirection:0:3:if cancel");
+
+ /**
+ * * CHAT **
+ */
+ set(ConfPaths.CHAT_COLOR_CHECK, true);
+ set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
+
+ set(ConfPaths.CHAT_SPAM_CHECK, true);
+ set(ConfPaths.CHAT_SPAM_WHITELIST, "");
+ set(ConfPaths.CHAT_SPAM_TIMEFRAME, 3);
+ set(ConfPaths.CHAT_SPAM_MESSAGELIMIT, 3);
+ set(ConfPaths.CHAT_SPAM_COMMANDLIMIT, 12);
+ set(ConfPaths.CHAT_SPAM_ACTIONS, "log:spam:0:3:if cancel vl>30 log:spam:0:3:cif cancel cmd:kick");
+
+ /**
+ * * FIGHT **
+ */
+ set(ConfPaths.FIGHT_DIRECTION_CHECK, true);
+ set(ConfPaths.FIGHT_DIRECTION_PRECISION, 75);
+ set(ConfPaths.FIGHT_DIRECTION_PENALTYTIME, 500);
+ set(ConfPaths.FIGHT_DIRECTION_ACTIONS, "cancel vl>5 log:fdirection:3:5:f cancel vl>20 log:fdirection:0:5:if cancel vl>50 log:fdirection:0:5:cif cancel");
+
+ set(ConfPaths.FIGHT_NOSWING_CHECK, true);
+ set(ConfPaths.FIGHT_NOSWING_ACTIONS, "log:fnoswing:0:5:cif cancel");
+
+ set(ConfPaths.FIGHT_REACH_CHECK, true);
+ set(ConfPaths.FIGHT_REACH_LIMIT, 400);
+ set(ConfPaths.FIGHT_REACH_PENALTYTIME, 500);
+ set(ConfPaths.FIGHT_REACH_ACTIONS, "cancel vl>10 log:freach:2:5:if cancel");
+
+ set(ConfPaths.FIGHT_SPEED_CHECK, true);
+ set(ConfPaths.FIGHT_SPEED_ATTACKLIMIT, 15);
+ set(ConfPaths.FIGHT_SPEED_ACTIONS, "log:fspeed:0:5:if cancel");
+
+ set(ConfPaths.FIGHT_GODMODE_CHECK, true);
+ set(ConfPaths.FIGHT_GODMODE_ACTIONS, "log:fgod:2:5:if cancel");
+
+ set(ConfPaths.FIGHT_INSTANTHEAL_CHECK, true);
+ set(ConfPaths.FIGHT_INSTANTHEAL_ACTIONS, "log:fheal:1:1:if cancel");
+
+ set(ConfPaths.STRINGS + ".drop", "[player] failed [check]: Tried to drop more items than allowed. VL [violations]");
+ set(ConfPaths.STRINGS + ".moveshort", "[player] failed [check]. VL [violations]");
+ set(ConfPaths.STRINGS + ".movelong", "[player] in [world] at [location] moving to [locationto] over distance [movedistance] failed check [check]. Total violation level so far [violations]");
+ set(ConfPaths.STRINGS + ".nofall", "[player] failed [check]: tried to avoid fall damage for ~[falldistance] blocks. VL [violations]");
+ set(ConfPaths.STRINGS + ".morepackets", "[player] failed [check]: Sent [packets] more packets than expected. Total violation level [violations]");
+ set(ConfPaths.STRINGS + ".bbreach", "[player] failed [check]: tried to interact with a block over distance [reachdistance]. VL [violations]");
+ set(ConfPaths.STRINGS + ".bbdirection", "[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
+ set(ConfPaths.STRINGS + ".bbnoswing", "[player] failed [check]: Didn't swing arm. VL [violations]");
+ set(ConfPaths.STRINGS + ".bpreach", "[player] failed [check]: tried to interact with a block over distance [reachdistance]. VL [violations]");
+ set(ConfPaths.STRINGS + ".bpdirection", "[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
+ set(ConfPaths.STRINGS + ".color", "[player] failed [check]: Sent colored chat message '[text]'. VL [violations]");
+ set(ConfPaths.STRINGS + ".spam", "[player] failed [check]: Last sent message '[text]'. VL [violations]");
+ set(ConfPaths.STRINGS + ".fdirection", "[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
+ set(ConfPaths.STRINGS + ".freach", "[player] failed [check]: tried to attack entity out of reach. VL [violations]");
+ set(ConfPaths.STRINGS + ".fspeed", "[player] failed [check]: tried to attack more than [limit] times per second. VL [violations]");
+ set(ConfPaths.STRINGS + ".fnoswing", "[player] failed [check]: Didn't swing arm. VL [violations]");
+ set(ConfPaths.STRINGS + ".fgod", "[player] failed [check]: Avoided taking damage or lagging. VL [violations]");
+ set(ConfPaths.STRINGS + ".fheal", "[player] failed [check]: Tried to regenerate health faster than normal. VL [violations]");
+ set(ConfPaths.STRINGS + ".ibow", "[player] failed [check]: Fires bow to fast. VL [violations]");
+ set(ConfPaths.STRINGS + ".ieat", "[player] failed [check]: Eats food [food] too fast. VL [violations]");
+ set(ConfPaths.STRINGS + ".kick", "kick [player]");
+
+ // Update internal factory based on all the new entries to the "actions" section
+ regenerateActionLists();
+ }
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/LoggingConfig.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/LoggingConfig.java
new file mode 100644
index 000000000..9875c7715
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/LoggingConfig.java
@@ -0,0 +1,29 @@
+package com.earth2me.essentials.anticheat.config;
+
+
+/**
+ * Configurations specific for logging. Every world gets one of these.
+ *
+ */
+public class LoggingConfig
+{
+ public final boolean active;
+ public final boolean showactivechecks;
+ public final boolean toFile;
+ public final boolean toConsole;
+ public final boolean toChat;
+ public final String prefix;
+ public final boolean debugmessages;
+
+ public LoggingConfig(NoCheatConfiguration data)
+ {
+
+ active = data.getBoolean(ConfPaths.LOGGING_ACTIVE);
+ showactivechecks = data.getBoolean(ConfPaths.LOGGING_SHOWACTIVECHECKS);
+ debugmessages = data.getBoolean(ConfPaths.LOGGING_DEBUGMESSAGES);
+ prefix = data.getString(ConfPaths.LOGGING_PREFIX);
+ toFile = data.getBoolean(ConfPaths.LOGGING_LOGTOFILE);
+ toConsole = data.getBoolean(ConfPaths.LOGGING_LOGTOCONSOLE);
+ toChat = data.getBoolean(ConfPaths.LOGGING_LOGTOINGAMECHAT);
+ }
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/NoCheatConfiguration.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/NoCheatConfiguration.java
new file mode 100644
index 000000000..e137ff480
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/NoCheatConfiguration.java
@@ -0,0 +1,82 @@
+package com.earth2me.essentials.anticheat.config;
+
+import com.earth2me.essentials.anticheat.actions.Action;
+import com.earth2me.essentials.anticheat.actions.types.ActionList;
+import java.lang.reflect.Field;
+import org.bukkit.configuration.MemorySection;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.yaml.snakeyaml.DumperOptions;
+
+
+public class NoCheatConfiguration extends YamlConfiguration
+{
+ private ActionFactory factory;
+
+ @Override
+ public String saveToString()
+ {
+ // Some reflection wizardry to avoid having a lot of
+ // linebreaks in the yml file, and get a "footer" into the file
+ try
+ {
+ Field op;
+ op = YamlConfiguration.class.getDeclaredField("yamlOptions");
+ op.setAccessible(true);
+ DumperOptions options = (DumperOptions)op.get(this);
+ options.setWidth(200);
+ }
+ catch (Exception e)
+ {
+ }
+
+ String result = super.saveToString();
+
+ return result;
+ }
+
+ /**
+ * Do this after reading new data
+ */
+ public void regenerateActionLists()
+ {
+ factory = new ActionFactory(((MemorySection)this.get(ConfPaths.STRINGS)).getValues(false));
+ }
+
+ /**
+ * A convenience method to get action lists from the config
+ *
+ * @param path
+ * @return
+ */
+ public ActionList getActionList(String path, String permission)
+ {
+
+ String value = this.getString(path);
+ return factory.createActionList(value, permission);
+ }
+
+ /**
+ * Savely store ActionLists back into the yml file
+ *
+ * @param path
+ * @param list
+ */
+ public void set(String path, ActionList list)
+ {
+ StringBuilder string = new StringBuilder();
+
+ for (int treshold : list.getTresholds())
+ {
+ if (treshold > 0)
+ {
+ string.append(" vl>").append(treshold);
+ }
+ for (Action action : list.getActions(treshold))
+ {
+ string.append(" ").append(action);
+ }
+ }
+
+ set(path, string.toString().trim());
+ }
+}
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/Permissions.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/Permissions.java
new file mode 100644
index 000000000..ab55d7b48
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config/Permissions.java
@@ -0,0 +1,44 @@
+package com.earth2me.essentials.anticheat.config;
+
+
+/**
+ * The various permission nodes used by NoCheat
+ *
+ */
+public class Permissions
+{
+ private static final String NOCHEAT = "nocheat";
+ private static final String ADMIN = NOCHEAT + ".admin";
+ private static final String CHECKS = NOCHEAT + ".checks";
+ public static final String MOVING = CHECKS + ".moving";
+ public static final String MOVING_RUNFLY = MOVING + ".runfly";
+ public static final String MOVING_SWIMMING = MOVING + ".swimming";
+ public static final String MOVING_SNEAKING = MOVING + ".sneaking";
+ public static final String MOVING_FLYING = MOVING + ".flying";
+ public static final String MOVING_NOFALL = MOVING + ".nofall";
+ public static final String MOVING_MOREPACKETS = MOVING + ".morepackets";
+ public static final String BLOCKBREAK = CHECKS + ".blockbreak";
+ public static final String BLOCKBREAK_REACH = BLOCKBREAK + ".reach";
+ public static final String BLOCKBREAK_DIRECTION = BLOCKBREAK + ".direction";
+ public static final String BLOCKBREAK_NOSWING = BLOCKBREAK + ".noswing";
+ public static final String BLOCKPLACE = CHECKS + ".blockplace";
+ public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach";
+ public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction";
+ public static final String CHAT = CHECKS + ".chat";
+ public static final String CHAT_SPAM = CHAT + ".spam";
+ public static final String CHAT_COLOR = CHAT + ".color";
+ public static final String FIGHT = CHECKS + ".fight";
+ public static final String FIGHT_DIRECTION = FIGHT + ".direction";
+ public static final String FIGHT_NOSWING = FIGHT + ".noswing";
+ public static final String FIGHT_REACH = FIGHT + ".reach";
+ public static final String FIGHT_SPEED = FIGHT + ".speed";
+ public static final String FIGHT_GODMODE = FIGHT + ".godmode";
+ public static final String FIGHT_INSTANTHEAL = FIGHT + ".instantheal";
+ public static final String ADMIN_CHATLOG = ADMIN + ".chatlog";
+ public static final String ADMIN_COMMANDS = ADMIN + ".commands";
+ public static final String ADMIN_RELOAD = ADMIN + ".reload";
+ public static final String INVENTORY = CHECKS + ".inventory";
+ public static final String INVENTORY_DROP = INVENTORY + ".drop";
+ public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow";
+ public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat";
+}