diff options
Diffstat (limited to 'EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/config')
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"; +} |