commit 981bc7d28f9666ecfccc3990b706f1686fcba3f6 Author: asofold Date: Wed Jun 13 02:13:18 2012 +0200 initial version on server diff --git a/CompatNoCheatPlus/.gitignore b/CompatNoCheatPlus/.gitignore new file mode 100644 index 0000000..bb25ed3 --- /dev/null +++ b/CompatNoCheatPlus/.gitignore @@ -0,0 +1,4 @@ +/.settings +/.classpath +/.project +/jar_desc.jardesc diff --git a/CompatNoCheatPlus/cncp_lists.txt b/CompatNoCheatPlus/cncp_lists.txt new file mode 100644 index 0000000..e16f16c --- /dev/null +++ b/CompatNoCheatPlus/cncp_lists.txt @@ -0,0 +1,18 @@ +CompatNoCheatPlus lists file +------------------------------------------------------- + + + +STACK +--------- +?(add) more intricate load order stuff ? +!(add) Limit blockbreaking speed by mcmmo (config) ! + + +*** +!(add) reload command + + +VERSION HISTORY +--------------------------- +(0.0.0) [initial version] diff --git a/CompatNoCheatPlus/plugin.yml b/CompatNoCheatPlus/plugin.yml new file mode 100644 index 0000000..c680cd1 --- /dev/null +++ b/CompatNoCheatPlus/plugin.yml @@ -0,0 +1,9 @@ +name: CompatNoCheatPlus +main: me.asofold.bukkit.cncp.CompatNoCheatPlus +version: 0.0.0 beta +depend: +- NoCheatPlus +softdepend: +- mcMMO +- PluginLibSharedLibrary +- CustomPlg diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/CompatNoCheatPlus.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/CompatNoCheatPlus.java new file mode 100644 index 0000000..d13b9cc --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/CompatNoCheatPlus.java @@ -0,0 +1,252 @@ +package me.asofold.bukkit.cncp; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +import me.asofold.bukkit.cncp.config.compatlayer.CompatConfig; +import me.asofold.bukkit.cncp.config.compatlayer.NewConfig; +import me.asofold.bukkit.cncp.hooks.Hook; +import me.asofold.bukkit.cncp.hooks.mcmmo.HookmcMMO; +import me.asofold.bukkit.cncp.setttings.GroupHooks; +import me.asofold.bukkit.cncp.setttings.Settings; +import me.asofold.bukkit.cncp.utils.Utils; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitScheduler; + +import fr.neatmonster.nocheatplus.checks.Check; +import fr.neatmonster.nocheatplus.checks.CheckEvent; + +/** + * Quick attempt to provide compatibility to NoCheatPlus for some other plugins that change the vanilla game mechanichs, for instance by fast block breaking. + * @author mc_dev + * + */ +public class CompatNoCheatPlus extends JavaPlugin implements Listener { + + /** + * Storage of hooks that are called for all events. + */ + private static final ArrayList hooksAll = new ArrayList(10); + + /** + * Storage of hooks that are called for certain groups and checks. + */ + private static final Map hooksGroups = new HashMap(20); + + private final Settings settings = new Settings(); + + /** + * Flag if plugin is enabled. + */ + private static boolean enabled = false; + + /** + * Experimental: static method to enable this plugin, only enables if it is not already enabled. + * @return + */ + public static boolean enableCncp(){ + if (enabled) return true; + return enablePlugin("CompatNoCheatPlus"); + } + + /** + * Static method to enable a plugin (might also be useful for hooks). + * @param plgName + * @return + */ + public static boolean enablePlugin(String plgName) { + PluginManager pm = Bukkit.getPluginManager(); + Plugin plugin = pm.getPlugin(plgName); + if (plugin == null) return false; + if (pm.isPluginEnabled(plugin)) return true; + pm.enablePlugin(plugin); + return true; + } + + /** + * Static method to disable a plugin (might also be useful for hooks). + * @param plgName + * @return + */ + public static boolean disablePlugin(String plgName){ + PluginManager pm = Bukkit.getPluginManager(); + Plugin plugin = pm.getPlugin(plgName); + if (plugin == null) return false; + if (!pm.isPluginEnabled(plugin)) return true; + pm.disablePlugin(plugin); + return true; + } + + /** + * API to add a hook. + * @param hook + * @return + */ + public static boolean addHook(Hook hook){ + if (!enabled) return false; + Listener[] listeners = hook.getListeners(); + if (listeners != null){ + // attempt to register events: + PluginManager pm = Bukkit.getPluginManager(); + Plugin plg = pm.getPlugin("CompatNoCheatPlus"); + if (plg == null) return false; + for (Listener listener : listeners) { + pm.registerEvents(listener, plg); + } + } + String[][] specs = hook.getCheckSpec(); + if (specs == null) hooksAll.add(hook); + else{ + for (String[] spec : specs){ + String group = spec[0].trim().toLowerCase(); + GroupHooks gh = hooksGroups.get(group); + if (gh == null){ + gh = new GroupHooks(); + hooksGroups.put(group, gh); + } + if (spec.length == 1) gh.all.add(hook); + else{ + for (int i = 1; i < spec.length; i++){ + String check = spec[i].trim().toLowerCase(); + ArrayList hooks = gh.byCheck.get(check); + if (hooks == null){ + hooks = new ArrayList(10); + gh.byCheck.put(check, hooks); + } + hooks.add(hook); + } + } + } + } + System.out.println("[cncp] Added hook: "+hook.getHookName() + " / " + hook.getHookVersion()); + return true; + } + + + public void clearHooks() { + hooksAll.clear(); + hooksGroups.clear(); + } + + /** + * Add standard hooks if available. + */ + private void addAvailableHooks() { + try{ + addHook(new HookmcMMO()); + } + catch (Throwable t){} + } + + @Override + public void onEnable() { + // cleanup + clearHooks(); + // Settings: + settings.clear(); + reloadSettings(); + // Register own listener: + final PluginManager pm = getServer().getPluginManager(); + pm.registerEvents(this, this); + super.onEnable(); + enabled = true; + // Add Hooks: + addAvailableHooks(); + } + + public boolean reloadSettings() { + final Set oldForceEnableLater = new HashSet(); + oldForceEnableLater.addAll(settings.forceEnableLater); + // Read and apply config to settings: + File file = new File(getDataFolder() , "cncp.yml"); + CompatConfig cfg = new NewConfig(file); + cfg.load(); + if (Settings.addDefaults(cfg)) cfg.save(); + settings.fromConfig(cfg); + // Re-enable plugins that were not yet on the list: + Server server = getServer(); + BukkitScheduler sched = server.getScheduler(); + for (String plgName : settings.forceEnableLater){ + if (!oldForceEnableLater.remove(plgName)) oldForceEnableLater.add(plgName); + } + if (!oldForceEnableLater.isEmpty()){ + System.out.println("[cncp] Schedule task to re-enable plugins later..."); + sched.scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() { + // (Later maybe re-enabling this plugin could be added.) + // TODO: log levels ! + for (String plgName : oldForceEnableLater){ + try{ + if (disablePlugin(plgName)){ + if (enablePlugin(plgName)) System.out.println("[cncp] Re-enabled plugin: " + plgName); + else System.out.println("[cncp] Could not re-enable plugin: "+plgName); + } + else{ + System.out.println("[cncp] Could not disable plugin (already disabled?): "+plgName); + } + } + catch(Throwable t){ + // TODO: maybe log ? + } + } + } + }); + } + return true; + } + + @Override + public void onDisable() { + enabled = false; + clearHooks(); + super.onDisable(); + } + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true) + final void onCheckFail(final CheckEvent event){ + // Check hooks, most specific first: + final Check check = event.getCheck(); + final String gn = check.getGroup(); + final String cn = check.getName(); + final GroupHooks gh = hooksGroups.get(gn.trim().toLowerCase()); + if (gh != null){ + final ArrayList hooks = gh.byCheck.get(cn.trim().toLowerCase()); + if (hooks != null) applyHooks(gn, cn, event, hooks); + if (event.isCancelled()) return; + if (!gh.all.isEmpty()) applyHooks(gn, cn, event, gh.all); + } + if (event.isCancelled()) return; + if (!hooksAll.isEmpty()) applyHooks(gn, cn, event, hooksAll); + } + + private final void applyHooks(final String group, final String check, final CheckEvent event, final ArrayList hooks) { + for (int i = 0; i < hooks.size(); i++){ + if (event.isCancelled()) return; + final Hook hook = hooks.get(i); + try{ + hook.processEvent(group, check, event); + } + catch (final Throwable t){ + final Logger logger = getServer().getLogger(); + logger.warning("[cncp][" + group + "/" + check + "] Unexpected exception on for hook ("+hook.getHookName()+" / "+hook.getHookVersion()+"):"); + // TODO: maybe add more info about the CheckEvent ? + logger.warning(Utils.toString(t)); + } + } + } + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/AbstractConfig.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/AbstractConfig.java new file mode 100644 index 0000000..7aa7e53 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/AbstractConfig.java @@ -0,0 +1,213 @@ +package me.asofold.bukkit.cncp.config.compatlayer; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * Some generic checks and stuff using getString, hasEntry, getStringList, ... + * @author mc_dev + * + */ +public abstract class AbstractConfig implements CompatConfig { + + protected char sep = '.'; + + @Override + public Boolean getBoolean(String path, Boolean defaultValue) { + String val = getString(path, null); + if ( val == null ) return defaultValue; + try{ + // return Boolean.parseBoolean(val); + String t = val.trim().toLowerCase(); + if ( t.equals("true")) return true; + else if ( t.equals("false")) return false; + else return defaultValue; + } catch( NumberFormatException exc){ + return defaultValue; + } + } + + @Override + public Double getDouble(String path, Double defaultValue) { + String val = getString(path, null); + if ( val == null ) return defaultValue; + try{ + return Double.parseDouble(val); + } catch( NumberFormatException exc){ + return defaultValue; + } + } + + @Override + public Long getLong(String path, Long defaultValue) { + String val = getString(path, null); + if ( val == null ) return defaultValue; + try{ + return Long.parseLong(val); + } catch( NumberFormatException exc){ + return defaultValue; + } + } + + @Override + public Integer getInt(String path, Integer defaultValue) { + String val = getString(path, null); + if ( val == null ) return defaultValue; + try{ + return Integer.parseInt(val); + } catch( NumberFormatException exc){ + return defaultValue; + } + } + + @Override + public List getIntList(String path, List defaultValue){ + if ( !hasEntry(path) ) return defaultValue; + List strings = getStringList(path, null); + if ( strings == null ) return defaultValue; + List out = new LinkedList(); + for ( String s : strings){ + try{ + out.add(Integer.parseInt(s)); + } catch(NumberFormatException exc){ + // ignore + } + } + return out; + } + + @Override + public List getDoubleList(String path, List defaultValue) { + if ( !hasEntry(path) ) return defaultValue; + List strings = getStringList(path, null); + if ( strings == null ) return defaultValue; + List out = new LinkedList(); + for ( String s : strings){ + try{ + out.add(Double.parseDouble(s)); + } catch(NumberFormatException exc){ + // ignore + } + } + return out; + } + + @Override + public Set getStringKeys(String path, boolean deep) { + if (deep) return getStringKeysDeep(path); + Set keys = new HashSet(); + keys.addAll(getStringKeys(path)); + return keys; + + } + + @Override + public Set getStringKeysDeep(String path) { + // NOTE: pretty inefficient, but aimed at seldomly read sections. + Map values = getValuesDeep(); + Set out = new HashSet(); + final int len = path.length(); + for (String key : values.keySet()){ + if (!key.startsWith(path)) continue; + else if (key.length() == len) continue; + else if (key.charAt(len) == sep) out.add(key); + } + return out; + } + + @Override + public Object get(String path, Object defaultValue) { + return getProperty(path, defaultValue); + } + + @Override + public void set(String path, Object value) { + setProperty(path, value); + } + + @Override + public void remove(String path) { + removeProperty(path); + } + + @Override + public Boolean getBoolean(String path) { + return getBoolean(path, null); + } + + @Override + public Double getDouble(String path) { + return getDouble(path, null); + } + + @Override + public List getDoubleList(String path) { + return getDoubleList(path, null); + } + + @Override + public Integer getInt(String path) { + return getInt(path, null); + } + + @Override + public List getIntList(String path) { + return getIntList(path, null); + } + + @Override + public Integer getInteger(String path) { + return getInt(path, null); + } + + @Override + public List getIntegerList(String path) { + return getIntList(path, null); + } + + @Override + public String getString(String path) { + return getString(path, null); + } + + @Override + public List getStringList(String path) { + return getStringList(path, null); + } + + @Override + public Object get(String path) { + return getProperty(path, null); + } + + @Override + public Object getProperty(String path) { + return getProperty(path, null); + } + + @Override + public boolean contains(String path) { + return hasEntry(path); + } + + @Override + public Integer getInteger(String path, Integer defaultValue) { + return getInt(path, defaultValue); + } + + @Override + public List getIntegerList(String path, List defaultValue) { + return getIntList(path, defaultValue); + } + + @Override + public Long getLong(String path) { + return getLong(path, null); + } + + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/AbstractNewConfig.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/AbstractNewConfig.java new file mode 100644 index 0000000..4ade8a2 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/AbstractNewConfig.java @@ -0,0 +1,220 @@ +package me.asofold.bukkit.cncp.config.compatlayer; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.ConfigurationOptions; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.MemoryConfiguration; + +public abstract class AbstractNewConfig extends AbstractConfig { + File file = null; + MemoryConfiguration config = null; + + public AbstractNewConfig(File file){ + this.file = file; + this.config = new MemoryConfiguration(); + setOptions(config); + } + + @Override + public boolean hasEntry(String path) { + return config.contains(path) || (config.get(path) != null); + } + + + + + @Override + public String getString(String path, String defaultValue) { + if (!hasEntry(path)) return defaultValue; + return config.getString(path, defaultValue); + } + + + + @Override + public List getStringKeys(String path) { + // TODO policy: only strings or all keys as strings ? + List out = new LinkedList(); + List keys = getKeys(path); + if ( keys == null ) return out; + for ( Object obj : keys){ + if ( obj instanceof String ) out.add((String) obj); + else{ + try{ + out.add(obj.toString()); + } catch ( Throwable t){ + // ignore. + } + } + } + return out; + } + + @Override + public List getKeys(String path) { + List out = new LinkedList(); + Set keys; + if ( path == null) keys = config.getKeys(false); + else{ + ConfigurationSection sec = config.getConfigurationSection(path); + if (sec == null) return out; + keys = sec.getKeys(false); + } + if ( keys == null) return out; + out.addAll(keys); + return out; + } + + @Override + public List getKeys() { + return getKeys(null); + } + + @Override + public Object getProperty(String path, Object defaultValue) { + Object obj = config.get(path); + if ( obj == null ) return defaultValue; + else return obj; + } + + @Override + public List getStringKeys() { + return getStringKeys(null); + } + + @Override + public void setProperty(String path, Object obj) { + config.set(path, obj); + } + + @Override + public List getStringList(String path, List defaultValue) { + if ( !hasEntry(path)) return defaultValue; + List out = new LinkedList(); + List entries = config.getStringList(path); + if ( entries == null ) return defaultValue; + for ( String entry : entries){ + if ( entry instanceof String) out.add(entry); + else{ + try{ + out.add(entry.toString()); + } catch (Throwable t){ + // ignore + } + } + } + return out; + } + + @Override + public void removeProperty(String path) { + // VERY EXPENSIVE + MemoryConfiguration temp = new MemoryConfiguration(); + setOptions(temp); + Map values = config.getValues(true); + values.remove(path); + for ( String p : values.keySet()){ + temp.set(p, values.get(p)); + } + config = temp; + } + + @Override + public Boolean getBoolean(String path, Boolean defaultValue) { + if (!config.contains(path)) return defaultValue; + String val = config.getString(path, null); + if (val != null){ + if (val.equalsIgnoreCase("true")) return true; + else if (val.equalsIgnoreCase("false")) return false; + else return defaultValue; + } + Boolean res = defaultValue; + if ( val == null ){ + if ( defaultValue == null) defaultValue = false; + res = config.getBoolean(path, defaultValue); + } + return res; + } + + + + + @Override + public Double getDouble(String path, Double defaultValue) { + if (!config.contains(path)) return defaultValue; + Double res = super.getDouble(path, null); + if ( res == null ) res = config.getDouble(path, ConfigUtil.canaryDouble); + if ( res == ConfigUtil.canaryDouble) return defaultValue; + return res; + } + + + + + @Override + public Long getLong(String path, Long defaultValue) { + if (!config.contains(path)) return defaultValue; + Long res = super.getLong(path, null); + if ( res == null ) res = config.getLong(path, ConfigUtil.canaryLong); + if ( res == ConfigUtil.canaryLong) return defaultValue; + return res; + } + + + + + @Override + public Integer getInt(String path, Integer defaultValue) { + if (!config.contains(path)) return defaultValue; + Integer res = super.getInt(path, null); + if ( res == null ) res = config.getInt(path, ConfigUtil.canaryInt); + if ( res == ConfigUtil.canaryInt) return defaultValue; + return res; + } + + + + + @Override + public List getIntList(String path, List defaultValue) { + // TODO Auto-generated method stub + return super.getIntList(path, defaultValue); + } + + + + + @Override + public List getDoubleList(String path, List defaultValue) { + // TODO Auto-generated method stub + return super.getDoubleList(path, defaultValue); + } + + + void addAll(Configuration source, Configuration target){ + Map all = source.getValues(true); + for ( String path: all.keySet()){ + target.set(path, source.get(path)); + } + } + + void setOptions(Configuration cfg){ + ConfigurationOptions opt = cfg.options(); + opt.pathSeparator(this.sep); + //opt.copyDefaults(true); + } + + @Override + public boolean setPathSeparatorChar(char sep) { + this.sep = sep; + setOptions(config); + return true; + } + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/CompatConfig.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/CompatConfig.java new file mode 100644 index 0000000..3ef2261 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/CompatConfig.java @@ -0,0 +1,128 @@ +package me.asofold.bukkit.cncp.config.compatlayer; + + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * CONVENTIONS: + * - Return strings if objects can be made strings. + * - No exceptions, rather leave elements out of lists. + * - Lists of length 0 and null can not always be distinguished (?->extra safe wrapper ?) + * - All contents are treated alike, even if given as a string (!): true and 'true', 1 and '1' + * @author mc_dev + * + */ +public interface CompatConfig { + + // Boolean + /** + * Only accepts true and false , 'true' and 'false'. + * @param path + * @param defaultValue + * @return + */ + public Boolean getBoolean(String path, Boolean defaultValue); + public Boolean getBoolean(String path); + + // Long + public Long getLong(String path); + public Long getLong(String path, Long defaultValue); + + // Double + public Double getDouble(String path); + public Double getDouble(String path, Double defaultValue); + public List getDoubleList(String path); + public List getDoubleList(String path , List defaultValue); + + // Integer (abbreviation) + public Integer getInt(String path); + public Integer getInt(String path, Integer defaultValue); + public List getIntList(String path); + public List getIntList(String path, List defaultValue); + // Integer (full name) + public Integer getInteger(String path); + public Integer getInteger(String path, Integer defaultValue); + public List getIntegerList(String path); + public List getIntegerList(String path, List defaultValue); + + // String + public String getString(String path); + public String getString(String path, String defaultValue); + public List getStringList(String path); + public List getStringList(String path, List defaultValue); + + // Generic methods: + public Object get(String path); + public Object get(String path, Object defaultValue); + public Object getProperty(String path); + public Object getProperty(String path, Object defaultValue); + public void set(String path, Object value); + public void setProperty(String path, Object value); + public void remove(String path); + public void removeProperty(String path); + + // Contains/has + public boolean hasEntry(String path); + public boolean contains(String path); + + // Keys (Object): [possibly deprecated] + /** + * @deprecated Seems not to be supported anymore by new configuration, use getStringKeys(String path); + * @param path + * @return + */ + public List getKeys(String path); + /** + * @deprecated Seems not to be supported anymore by new configuration, use getStringKeys(); + * @return + */ + public List getKeys(); + + // Keys (String): + /** + * + * @return never null + */ + public List getStringKeys(); + + public List getStringKeys(String path); + + /** + * Get all keys from the section (deep or shallow). + * @param path + * @param deep + * @return Never null. + */ + public Set getStringKeys(String path, boolean deep); + + /** + * convenience method. + * @param path + * @return never null + * + */ + public Set getStringKeysDeep(String path); + + // Values: + /** + * Equivalent to new config: values(true) + * @return + */ + public Map getValuesDeep(); + + // Technical / IO: + /** + * False if not supported. + * @param sep + * @return + */ + public boolean setPathSeparatorChar(char sep); + + public void load(); + + public boolean save(); + + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/ConfigUtil.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/ConfigUtil.java new file mode 100644 index 0000000..55bcdf5 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/ConfigUtil.java @@ -0,0 +1,116 @@ +package me.asofold.bukkit.cncp.config.compatlayer; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class ConfigUtil { + + public static final int canaryInt = Integer.MIN_VALUE +7; + public static final long canaryLong = Long.MIN_VALUE + 7L; + public static final double canaryDouble = Double.MIN_VALUE*.7; + + public static String stringPath( String path){ + return stringPath(path, '.'); + } + + public static String stringPath( String path , char sep ){ + String useSep = (sep=='.')?"\\.":""+sep; + String[] split = path.split(useSep); + StringBuilder builder = new StringBuilder(); + builder.append(stringPart(split[0])); + for (int i = 1; i all = defaults.getValuesDeep(); + boolean changed = false; + for ( String path : all.keySet()){ + if ( !config.hasEntry(path)){ + config.setProperty(path, defaults.getProperty(path, null)); + changed = true; + } + } + return changed; + } + + /** + * Add StringList entries to a set. + * @param cfg + * @param path + * @param set + * @param clear If to clear the set. + * @param trim + * @param lowerCase + */ + public static void readStringSetFromList(CompatConfig cfg, String path, Set set, boolean clear, boolean trim, boolean lowerCase){ + if (clear) set.clear(); + List tempList = cfg.getStringList(path , null); + if (tempList != null){ + for (String entry : tempList){ + if (trim) entry = entry.trim(); + if (lowerCase) entry = entry.toLowerCase(); + set.add(entry); + } + } + } +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/NewConfig.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/NewConfig.java new file mode 100644 index 0000000..7debfc4 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/config/compatlayer/NewConfig.java @@ -0,0 +1,48 @@ +package me.asofold.bukkit.cncp.config.compatlayer; + +import java.io.File; +import java.util.Map; + +import org.bukkit.configuration.MemoryConfiguration; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +public class NewConfig extends AbstractNewConfig{ + + + public NewConfig(File file) { + super(file); + } + + + @Override + public void load(){ + config = new MemoryConfiguration(); + setOptions(config); + FileConfiguration cfg = YamlConfiguration.loadConfiguration(file); + setOptions(cfg); + addAll(cfg, config); + } + + + @Override + public boolean save(){ + YamlConfiguration cfg = new YamlConfiguration(); + setOptions(cfg); + addAll(config, cfg); + try{ + cfg.save(file); + return true; + } catch (Throwable t){ + return false; + } + } + + + @Override + public Map getValuesDeep() { + return config.getValues(true); + } + + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/AbstractHook.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/AbstractHook.java new file mode 100644 index 0000000..ac5cf59 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/AbstractHook.java @@ -0,0 +1,26 @@ +package me.asofold.bukkit.cncp.hooks; + +import org.bukkit.event.Listener; + +/** + * Extend this to make sure that future changes will not break your hooks.
+ * Probable changes:
+ * - Adding onReload method. + * @author mc_dev + * + */ +public abstract class AbstractHook implements Hook{ + + @Override + public String[][] getCheckSpec() { + // Handle all CheckEvents (improbable). + return null; + } + + @Override + public Listener[] getListeners() { + // No listeners (improbable). + return null; + } + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/Hook.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/Hook.java new file mode 100644 index 0000000..71ef9fe --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/Hook.java @@ -0,0 +1,53 @@ +package me.asofold.bukkit.cncp.hooks; + +import org.bukkit.event.Listener; + +import fr.neatmonster.nocheatplus.checks.CheckEvent; + +/** + * Interface for hooking into another plugin.
+ * + * @author mc_dev + * + */ +public interface Hook{ + /** + * Must not cause exceptions. + * @return + */ + public String getHookName(); + + /** + * Must not cause exceptions. + * @return + */ + public String getHookVersion(); + + /** + * Get the specification for which checks to call this.
+ *
+ * The return value should be an array of arrays, each of which specifies the group name and the check names within that group.
+ * You can return null to register for ALL checks.
+ * You can just register the group name to get all checks for that group.
+ *
+ * Currently group and check names are processed with trim().toLowerCase() ! + * @return (see description) + */ + public String[][] getCheckSpec(); + + /** + * Get listener instances to be registered with cncp. + * @return null if unused. + */ + public Listener[] getListeners(); + + /** + * This will only be called if the event has not yet been cancelled !
+ * Cancel the event, and no further hooks will process this. + * @param group Name of check group + * @param check Name of check . + * @param event + */ + public void processEvent(final String group, final String check, final CheckEvent event); + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/mcmmo/HookmcMMO.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/mcmmo/HookmcMMO.java new file mode 100644 index 0000000..6f0850f --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/hooks/mcmmo/HookmcMMO.java @@ -0,0 +1,151 @@ +package me.asofold.bukkit.cncp.hooks.mcmmo; + +import java.util.HashMap; +import java.util.Map; + +import me.asofold.bukkit.cncp.hooks.AbstractHook; +import me.asofold.bukkit.cncp.utils.PluginGetter; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.events.fake.FakeBlockBreakEvent; +import com.gmail.nossr50.events.fake.FakeBlockDamageEvent; +import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent; + +import fr.neatmonster.nocheatplus.checks.CheckEvent; +import fr.neatmonster.nocheatplus.players.NCPPlayer; + +public final class HookmcMMO extends AbstractHook implements Listener { + + private static final Map cancelChecksBlockBreak = new HashMap(); + private static final Map cancelChecksBlockDamage = new HashMap(); + private static final Map cancelChecksDamage = new HashMap(); + static{ + cancelChecksBlockBreak.put("fastbreak", 2); + cancelChecksBlockDamage.put("fastbreak", 1); + cancelChecksDamage.put("angle", 1); + cancelChecksDamage.put("speed", 1); + } + + + private final PluginGetter fetch = new PluginGetter("mcMMO"); + + private String cancel = null; + private long cancelTicks = 0; + + private final Map cancelChecks = new HashMap(); + + + + @Override + public String getHookName() { + return "mcMMO(default)"; + } + + @Override + public String getHookVersion() { + return "0.0"; + } + + @Override + public String[][] getCheckSpec() { + return new String[][]{ + {"blockbreak", "fastbreak"}, + {"fight", "angle", "speed"}, + }; + } + + @Override + public Listener[] getListeners() { + fetch.fetchPlugin(); + return new Listener[]{this, fetch}; + } + + private final void setPlayer(final Entity entity, Map cancelChecks){ + if (entity instanceof Player){ + setPlayer((Player) entity, cancelChecks); + } + // no projectiles etc. + } + + private final void setPlayer(final Player player, Map cancelChecks){ + cancel = player.getName(); + cancelTicks = player.getTicksLived(); + this.cancelChecks.clear(); + this.cancelChecks.putAll(cancelChecks); + } + + @EventHandler(priority=EventPriority.LOWEST) + final void onDamageLowest(final FakeEntityDamageByEntityEvent event){ + // TODO might change with API + setPlayer(event.getDamager(), cancelChecksDamage); +// System.out.println("Damage: "+cancel +" / "+event.getEntity().getLocation()); + } + +// @EventHandler(priority=EventPriority.MONITOR) +// final void onDamageMonitor(final FakeEntityDamageByEntityEvent event){ +// cancel = null; +// } + + @EventHandler(priority=EventPriority.LOWEST) + final void onBlockBreakLowest(final FakeBlockBreakEvent event){ + setPlayer(event.getPlayer(), cancelChecksBlockBreak); +// System.out.println("BlockBreak: "+cancel + " / " + event.getBlock()); + } + +// @EventHandler(priority=EventPriority.MONITOR) +// final void onBlockBreakMonitor(final FakeBlockBreakEvent event){ +// cancel = null; +// } + + @EventHandler(priority=EventPriority.LOWEST) + final void onBlockDamageLowest(final FakeBlockDamageEvent event){ + setPlayer(event.getPlayer(), cancelChecksBlockDamage); +// System.out.println("BlockDamage: "+cancel + " / insta=" + event.getInstaBreak() + "/" + event.getBlock()); + } + +// @EventHandler(priority=EventPriority.MONITOR) +// final void onBlockDamageMonitor(final FakeBlockDamageEvent event){ +// cancel = null; +// } + + @Override + public void processEvent(final String group, final String check, final CheckEvent event) { +// System.out.println("[cncp] Handle event: " + event.getEventName()); + if (cancel == null){ +// System.out.println("[cncp] Return on cancel == null: "+event.getPlayer().getName()); + return; + } + final NCPPlayer ncpPlayer = event.getPlayer(); + + final String name = ncpPlayer.getName(); + if (cancel.equals(name)){ + final Player player = ncpPlayer.getBukkitPlayer(); + if (player == null || player.getTicksLived() != cancelTicks){ +// System.out.println("[cncp] No cancel (ticks/player): "+event.getPlayer().getName()); + cancel = null; + } + else{ + final Integer n = cancelChecks.get(check); + if (n == null){ +// System.out.println("[cncp] Expired("+check+"): "+event.getPlayer().getName()); + return; + } + else if (n > 0){ +// System.out.println("Check with n = "+n); + if (n == 1) cancelChecks.remove(check); + else cancelChecks.put(check, n - 1); + } + // else: allow arbitrary numbers +// System.out.println("[cncp] Cancel: "+event.getPlayer().getName()); + event.setCancelled(true); + } + } + } + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/setttings/GroupHooks.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/setttings/GroupHooks.java new file mode 100644 index 0000000..561dd9f --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/setttings/GroupHooks.java @@ -0,0 +1,25 @@ +package me.asofold.bukkit.cncp.setttings; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import me.asofold.bukkit.cncp.hooks.Hook; + +/** + * Check group specific lists of hooks. + * @author mc_dev + * + */ +public final class GroupHooks { + + /** + * Hooks that want all. + */ + public final ArrayList all = new ArrayList(); + + /** + * Hooks that want a certain check.
+ */ + public final Map> byCheck = new HashMap>(10); +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/setttings/Settings.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/setttings/Settings.java new file mode 100644 index 0000000..d75f2df --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/setttings/Settings.java @@ -0,0 +1,38 @@ +package me.asofold.bukkit.cncp.setttings; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import me.asofold.bukkit.cncp.config.compatlayer.CompatConfig; +import me.asofold.bukkit.cncp.config.compatlayer.ConfigUtil; +import me.asofold.bukkit.cncp.config.compatlayer.NewConfig; + +public class Settings { + public Set forceEnableLater = new HashSet(); + + + public static CompatConfig getDefaultConfig(){ + CompatConfig cfg = new NewConfig(null); + List tempList = new LinkedList(); + tempList.add("NoCheatPlus"); + cfg.set("plugins.force-enable-later", tempList); + return cfg; + } + + public static boolean addDefaults(CompatConfig cfg){ + return ConfigUtil.forceDefaults(getDefaultConfig(), cfg); + } + + public boolean fromConfig(CompatConfig cfg){ + // plugins to force enabling after this plugin. + ConfigUtil.readStringSetFromList(cfg, "plugins.force-enable-later", forceEnableLater, true, true, false); + return true; + } + + public void clear() { + forceEnableLater.clear(); + } + +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/utils/PluginGetter.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/utils/PluginGetter.java new file mode 100644 index 0000000..f23e7d3 --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/utils/PluginGetter.java @@ -0,0 +1,50 @@ +package me.asofold.bukkit.cncp.utils; + +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.Plugin; + +/** + * Simple plugin fetching. + * @author mc_dev + * + * @param + */ +public final class PluginGetter implements Listener{ + private T plugin = null; + private final String pluginName; + public PluginGetter(final String pluginName){ + this.pluginName = pluginName; + fetchPlugin(); + } + + /** + * Fetch from Bukkit and set , might set to null, though. + */ + @SuppressWarnings("unchecked") + public final void fetchPlugin() { + final Plugin ref = Bukkit.getPluginManager().getPlugin(pluginName); + plugin = (T) ref; + } + + @SuppressWarnings("unchecked") + final void onPluginEnable(final PluginEnableEvent event){ + final Plugin ref = event.getPlugin(); + if (plugin.getName().equals(pluginName)) plugin = (T) ref; + } + + /** + * For convenience with chaining: getX = new PluginGetter("X").registerEvents(this); + * @param other + * @return + */ + public final PluginGetter registerEvents(final Plugin other){ + Bukkit.getPluginManager().registerEvents(this, plugin); + return this; + } + + public final T getPlugin(){ + return plugin; + } +} diff --git a/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/utils/Utils.java b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/utils/Utils.java new file mode 100644 index 0000000..ac81fcf --- /dev/null +++ b/CompatNoCheatPlus/src/me/asofold/bukkit/cncp/utils/Utils.java @@ -0,0 +1,16 @@ +package me.asofold.bukkit.cncp.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; + +public class Utils { + + public static final String toString(final Throwable t) { + final Writer buf = new StringWriter(500); + final PrintWriter writer = new PrintWriter(buf); + t.printStackTrace(writer); + return buf.toString(); + } + +}