From de5f152df9187c6ae068bd3fb394cc971b9258b6 Mon Sep 17 00:00:00 2001 From: asofold Date: Mon, 15 Apr 2013 16:11:08 +0200 Subject: [PATCH] [BLEEDING] Flesh out aspects of ComponentRegistry. * Fixes data removal ignoring chat.logins and chat.text for a part. * Move some components interfaces and ReflectionUtil to NCPCommons. * Unregister components in reverse order. * Add ComponentRegistryProvider for generic sub-registries (DataManager for instance). * Add IHoldSUbComponents for delayed sub-component registration (convenient for iteration over parent-components with later registration of sub components not missing out any registered parent components for those). [Partly implemented: Using this during runtime does not yet work, only used in onEnable.] * Let CheckListener implement IHoldSubComponents and use this with addCheck to register the queued checks after all the listeners. * Register the core system components in a bunch before the CheckListenerS, to allow sub-registries to work directly and to allow getAPI().addComponent on the plugin class during construction of CheckListeners. --- .../components/ComponentRegistry.java | 17 +- .../components/ComponentRegistryProvider.java | 20 +++ .../components/ComponentWithName.java | 0 .../nocheatplus/utilities/ReflectionUtil.java | 78 +++++++++ .../nocheatplus/utilities/ReflectionUtil.java | 27 --- .../neatmonster/nocheatplus/NoCheatPlus.java | 160 +++++++++++++++--- .../nocheatplus/checks/CheckListener.java | 24 ++- .../nocheatplus/checks/chat/Text.java | 2 +- .../checks/moving/MovingListener.java | 2 +- .../compat/DefaultComponentFactory.java | 11 ++ .../components/IHoldSubComponents.java | 19 +++ .../components/NoCheatPlusAPI.java | 12 +- .../nocheatplus/players/DataManager.java | 21 +-- 13 files changed, 310 insertions(+), 83 deletions(-) rename {NCPPlugin => NCPCommons}/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java (53%) create mode 100644 NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistryProvider.java rename {NCPPlugin => NCPCommons}/src/main/java/fr/neatmonster/nocheatplus/components/ComponentWithName.java (100%) create mode 100644 NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java delete mode 100644 NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java create mode 100644 NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/compat/DefaultComponentFactory.java create mode 100644 NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/IHoldSubComponents.java diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java similarity index 53% rename from NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java rename to NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java index 96e8fb1a..d3939247 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java +++ b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistry.java @@ -1,27 +1,26 @@ package fr.neatmonster.nocheatplus.components; /** - * A ComponentRegistry allows registering components, that then are delegated to where they belong.
+ * A ComponentRegistry allows registering components, that then should be delegated to where they belong or just be ignored.
* Notes: *
  • Implementations should somehow specify what components can be registered.
  • *
  • Implementations should somehow specify if/when they are unregistered automatically.
  • * @author mc_dev * */ -public interface ComponentRegistry { +public interface ComponentRegistry{ + /** - * Convenience method to add components according to implemented interfaces, - * like Listener, INotifyReload, INeedConfig.
    - * For the NoCheatPlus instance this must be done after the configuration has been initialized. - * @param obj + * Register a component. + * @param component * @return If (newly) added. Adding an already present component should do nothing. */ - public boolean addComponent(final Object obj); + public boolean addComponent(final T component); /** * Remove a registered component.
    * Does not unregister listeners currently. - * @param obj + * @param component */ - public void removeComponent(final Object obj); + public void removeComponent(final T component); } diff --git a/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistryProvider.java b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistryProvider.java new file mode 100644 index 00000000..dcd8921c --- /dev/null +++ b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentRegistryProvider.java @@ -0,0 +1,20 @@ +package fr.neatmonster.nocheatplus.components; + +import java.util.Collection; + +/** + * An object allowing to get ComponentRegistry implementations of a specific type. + * This class is not specialized to maintain flexibility. + * @author mc_dev + * + */ +public interface ComponentRegistryProvider{ + + /** + * Get all available specialized ComponentFactory instances matching the given signature. This is not meant as a factory method but for more efficient registration for the case of the regestry being present. + * @param clazz + * @return Some collection, empty collection in case no matches are found. + */ + public Collection> getComponentRegistries(Class> clazz); + +} diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/ComponentWithName.java b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentWithName.java similarity index 100% rename from NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/ComponentWithName.java rename to NCPCommons/src/main/java/fr/neatmonster/nocheatplus/components/ComponentWithName.java diff --git a/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java new file mode 100644 index 00000000..ef73fa31 --- /dev/null +++ b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java @@ -0,0 +1,78 @@ +package fr.neatmonster.nocheatplus.utilities; + +import java.lang.reflect.Method; + +public class ReflectionUtil { + + /** + * Convenience method to check if members exist and fail if not. + * @param prefix + * @param specs + * @throws RuntimeException + */ + public static void checkMembers(String prefix, String[]... specs){ + try { + for (String[] spec : specs){ + Class clazz = Class.forName(prefix + spec[0]); + for (int i = 1; i < spec.length; i++){ + if (clazz.getField(spec[i]) == null) throw new NoSuchFieldException(prefix + spec[0] + " : " + spec[i]); + } + } + } catch (SecurityException e) { + // Let this one pass. + //throw new RuntimeException(e); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + /** + * Dirty method. Does try.catch and return null for method invokation. + * @param obj + * @param methodName + * @param arg + * @return + */ + public static Object invokeGenericMethodOneArg(final Object obj, final String methodName, final Object arg){ + // TODO: Isn't there a one-line-call for this ?? + final Class objClass = obj.getClass(); + final Class argClass = arg.getClass(); + // Collect methods that might work. + Method methodFound = null; + boolean denyObject = false; + for (final Method method : objClass.getDeclaredMethods()){ + if (method.getName().equals(methodName)){ + final Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 1 ){ + // Prevent using Object as argument if there exists a method with a specialized argument. + if (parameterTypes[0] != Object.class && !parameterTypes[0].isAssignableFrom(argClass)){ + denyObject = true; + } + // Override the found method if none found yet and assignment is possible, or if it has a specialized argument of an already found one. + if ((methodFound == null && parameterTypes[0].isAssignableFrom(argClass) || methodFound != null && methodFound.getParameterTypes()[0].isAssignableFrom(parameterTypes[0]))){ + methodFound = method; + } + } + } + } + if (denyObject && methodFound.getParameterTypes()[0] == Object.class){ + // TODO: Throw something !? + return null; + } + else if (methodFound != null && methodFound.getParameterTypes()[0].isAssignableFrom(argClass)){ + try{ + final Object res = methodFound.invoke(obj, arg); + return res; + } + catch (Throwable t){ + // TODO: Throw something !? + return null; + } + } + else{ + // TODO: Throw something !? + return null; + } + } + +} diff --git a/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java b/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java deleted file mode 100644 index 300961cf..00000000 --- a/NCPCompat/src/main/java/fr/neatmonster/nocheatplus/utilities/ReflectionUtil.java +++ /dev/null @@ -1,27 +0,0 @@ -package fr.neatmonster.nocheatplus.utilities; - -public class ReflectionUtil { - - /** - * Convenience method to check if members exist and fail if not. - * @param prefix - * @param specs - * @throws RuntimeException - */ - public static void checkMembers(String prefix, String[]... specs){ - try { - for (String[] spec : specs){ - Class clazz = Class.forName(prefix + spec[0]); - for (int i = 1; i < spec.length; i++){ - if (clazz.getField(spec[i]) == null) throw new NoSuchFieldException(prefix + spec[0] + " : " + spec[i]); - } - } - } catch (SecurityException e) { - // Let this one pass. - //throw new RuntimeException(e); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } - -} diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java index 5e58a9d5..410dd610 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/NoCheatPlus.java @@ -3,6 +3,7 @@ package fr.neatmonster.nocheatplus; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -46,8 +47,10 @@ import fr.neatmonster.nocheatplus.command.CommandHandler; import fr.neatmonster.nocheatplus.command.INotifyReload; import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.compat.MCAccessFactory; +import fr.neatmonster.nocheatplus.components.ComponentRegistry; import fr.neatmonster.nocheatplus.components.ComponentWithName; import fr.neatmonster.nocheatplus.components.ConsistencyChecker; +import fr.neatmonster.nocheatplus.components.IHoldSubComponents; import fr.neatmonster.nocheatplus.components.INeedConfig; import fr.neatmonster.nocheatplus.components.JoinLeaveListener; import fr.neatmonster.nocheatplus.components.MCAccessHolder; @@ -74,6 +77,7 @@ import fr.neatmonster.nocheatplus.permissions.PermissionUtil.CommandProtectionEn import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.players.DataManager; import fr.neatmonster.nocheatplus.utilities.BlockProperties; +import fr.neatmonster.nocheatplus.utilities.ReflectionUtil; import fr.neatmonster.nocheatplus.utilities.TickTask; import fr.neatmonster.nocheatplus.utilities.Updates; @@ -326,16 +330,59 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { /** Listeners for players joining and leaving (monitor level) */ protected final List joinLeaveListeners = new ArrayList(); + /** Sub component registries. */ + protected final List> subRegistries = new ArrayList>(); + + /** Queued sub component holders, emptied on the next tick usually. */ + protected final List subComponentholders = new ArrayList(20); + /** All registered components. */ protected Set allComponents = new LinkedHashSet(50); - + @SuppressWarnings("unchecked") + @Override + public Collection> getComponentRegistries(final Class> clazz) { + final List> result = new LinkedList>(); + for (final ComponentRegistry registry : subRegistries){ + if (clazz.isAssignableFrom(registry.getClass())){ + try{ + result.add((ComponentRegistry) registry); + } + catch(Throwable t){ + // Ignore. + } + } + } + return result; + } + + /** + * Convenience method to add components according to implemented interfaces, + * like Listener, INotifyReload, INeedConfig.
    + * For the NoCheatPlus instance this must be done after the configuration has been initialized. + * This will also register ComponentRegistry instances if given. + */ @Override public boolean addComponent(final Object obj) { + return addComponent(obj, true); + } + + /** + * Convenience method to add components according to implemented interfaces, + * like Listener, INotifyReload, INeedConfig.
    + * For the NoCheatPlus instance this must be done after the configuration has been initialized. + * @param allowComponentRegistry Only registers ComponentRegistry instances if this is set to true. + */ + @Override + public boolean addComponent(final Object obj, final boolean allowComponentRegistry) { // TODO: Allow to add ComponentFactory + contract (renew with reload etc.)? + if (obj == this) throw new IllegalArgumentException("Can not register NoCheatPlus with itself."); - if (allComponents.contains(obj)) return false; + if (allComponents.contains(obj)){ + // All added components are in here. + return false; + } boolean added = false; if (obj instanceof Listener) { addListener((Listener) obj); @@ -370,9 +417,26 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { joinLeaveListeners.add((JoinLeaveListener) obj); added = true; } - // Also add to DataManager, which will pick what it needs. - // TODO: This is fishy in principle, something more concise? - if (dataMan.addComponent(obj)) added = true; + + // Add to sub registries. + for (final ComponentRegistry registry : subRegistries){ + final Object res = ReflectionUtil.invokeGenericMethodOneArg(registry, "addComponent", obj); + if (res != null && (res instanceof Boolean) && ((Boolean) res).booleanValue()){ + added = true; + } + } + + // Add ComponentRegistry instances after adding to sub registries to prevent adding it to itself. + if (allowComponentRegistry && (obj instanceof ComponentRegistry)){ + subRegistries.add((ComponentRegistry) obj); + added = true; + } + + if (obj instanceof IHoldSubComponents){ + subComponentholders.add((IHoldSubComponents) obj); + added = true; // Convention. + } + // Add to allComponents if in fact added. if (added) allComponents.add(obj); return added; @@ -382,7 +446,8 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { * Interfaces checked for managed listeners: IHaveMethodOrder (method), ComponentWithName (tag)
    * @param listener */ - protected void addListener(final Listener listener) { + private void addListener(final Listener listener) { + // private: Use addComponent. if (manageListeners){ String tag = "NoCheatPlus"; if (listener instanceof ComponentWithName){ @@ -430,7 +495,16 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { if (obj instanceof JoinLeaveListener){ joinLeaveListeners.remove((JoinLeaveListener) obj); } - dataMan.removeComponent(obj); + + // Remove sub registries. + if (obj instanceof ComponentRegistry){ + subRegistries.remove(obj); + } + // Remove from present registries, order prevents to remove from itself. + for (final ComponentRegistry registry : subRegistries){ + ReflectionUtil.invokeGenericMethodOneArg(registry, "removeComponent", obj); + } + allComponents.remove(obj); } @@ -503,8 +577,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { // Unregister all added components explicitly. if (verbose) LogUtil.logInfo("[NoCheatPlus] Unregister all registered components..."); - for (Object obj : new ArrayList(allComponents)){ - removeComponent(obj); + final ArrayList allComponents = new ArrayList(this.allComponents); + for (int i = allComponents.size() - 1; i >= 0; i--){ + removeComponent(allComponents.get(i)); } // Cleanup BlockProperties. @@ -518,6 +593,10 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { notifyReload.clear(); // World specific permissions. permStateReceivers.clear(); + // Sub registries. + subRegistries.clear(); + // Just in case: clear the subComponentHolders. + subComponentholders.clear(); // Clear command changes list (compatibility issues with NPCs, leads to recalculation of perms). if (changedCommands != null){ @@ -610,25 +689,35 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { listenerManager.setRegisterDirectly(false); listenerManager.clear(); } - addComponent(nameSetPerms); - addListener(getCoreListener()); + // Add the "low level" system components first. + for (final Object obj : new Object[]{ + nameSetPerms, + getCoreListener(), + // Put ReloadListener first, because Checks could also listen to it. + new INotifyReload() { + // Only for reloading, not INeedConfig. + @Override + public void onReload() { + processReload(); + } + }, + NCPExemptionManager.getListener(), + new ConsistencyChecker() { + @Override + public void checkConsistency(final Player[] onlinePlayers) { + NCPExemptionManager.checkConsistency(onlinePlayers); + } + }, + dataMan, + }){ + addComponent(obj); + } + + // Register sub-components (!). + processQueuedSubComponentHolders(); + + // Register "highe level" components (check listeners). for (final Object obj : new Object[]{ - // Put ReloadListener first, because Checks could also listen to it. - new INotifyReload() { - // Only for reloading, not INeedConfig. - @Override - public void onReload() { - processReload(); - } - }, - NCPExemptionManager.getListener(), - new ConsistencyChecker() { - @Override - public void checkConsistency(final Player[] onlinePlayers) { - NCPExemptionManager.checkConsistency(onlinePlayers); - } - }, - dataMan, new BlockInteractListener(), new BlockBreakListener(), new BlockPlaceListener(), @@ -642,6 +731,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { addComponent(obj); } + // Register sub-components (!). + processQueuedSubComponentHolders(); + // Register the commands handler. PluginCommand command = getCommand("nocheatplus"); CommandHandler commandHandler = new CommandHandler(this, notifyReload); @@ -736,6 +828,20 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI { LogUtil.logInfo("[NoCheatPlus] Version " + getDescription().getVersion() + " is enabled."); } + /** + * Empties and registers the subComponentHolders list. + */ + protected void processQueuedSubComponentHolders(){ + if (subComponentholders.isEmpty()) return; + final List copied = new ArrayList(subComponentholders); + subComponentholders.clear(); + for (final IHoldSubComponents holder : copied){ + for (final Object component : holder.getSubComponents()){ + addComponent(component); + } + } + } + /** * All action done on reload. */ diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/CheckListener.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/CheckListener.java index 3c606cd3..82250d92 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/CheckListener.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/CheckListener.java @@ -1,7 +1,13 @@ package fr.neatmonster.nocheatplus.checks; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + import fr.neatmonster.nocheatplus.NoCheatPlus; import fr.neatmonster.nocheatplus.compat.MCAccess; +import fr.neatmonster.nocheatplus.components.IHoldSubComponents; import fr.neatmonster.nocheatplus.components.MCAccessHolder; import fr.neatmonster.nocheatplus.components.NCPListener; @@ -11,12 +17,15 @@ import fr.neatmonster.nocheatplus.components.NCPListener; * @author mc_dev * */ -public class CheckListener extends NCPListener implements MCAccessHolder{ +public class CheckListener extends NCPListener implements MCAccessHolder, IHoldSubComponents{ /** Check group / type which this listener is for. */ protected final CheckType checkType; protected MCAccess mcAccess; + /** */ + protected final List queuedComponents = new LinkedList(); + public CheckListener(){ this(null); } @@ -43,13 +52,22 @@ public class CheckListener extends NCPListener implements MCAccessHolder{ } /** - * Convenience method to add checks as components to NCP. + * Convenience method to add checks as components to NCP with a delay (IHoldSubComponent). + * This should not be used after having added the check to the ComponentRegistry (NCP-API). * @param check * @return The given Check instance, for chaining. */ protected C addCheck(C check){ // Could also set up a map from check type to check, etc. - NoCheatPlus.getAPI().addComponent(check); + queuedComponents.add(check); return check; } + + @Override + public Collection getSubComponents() { + final List res = new ArrayList(this.queuedComponents); + this.queuedComponents.clear(); + return res; + } + } diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/chat/Text.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/chat/Text.java index 87057a71..344e58f1 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/chat/Text.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/chat/Text.java @@ -31,7 +31,7 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil; */ public class Text extends AsyncCheck implements INotifyReload{ - private LetterEngine engine; + private LetterEngine engine = null; /** Not really cancelled but above threshold for actions. */ private String lastCancelledMessage = ""; diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index 070a2d3d..aecf9704 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -205,7 +205,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo private final NoCheatPlus plugin = (NoCheatPlus) Bukkit.getPluginManager().getPlugin("NoCheatPlus"); /** The no fall check. **/ - public final NoFall noFall = new NoFall(); + public final NoFall noFall = addCheck(new NoFall()); /** The creative fly check. */ private final CreativeFly creativeFly = addCheck(new CreativeFly()); diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/compat/DefaultComponentFactory.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/compat/DefaultComponentFactory.java new file mode 100644 index 00000000..b4e9e77c --- /dev/null +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/compat/DefaultComponentFactory.java @@ -0,0 +1,11 @@ +package fr.neatmonster.nocheatplus.compat; + +/** + * Default factory for add-in components which might only be available under certain circumstances. + * This will be called from within the plugin from within onEnable to register components in a flexible way. + * @author mc_dev + * + */ +public class DefaultComponentFactory { + +} diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/IHoldSubComponents.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/IHoldSubComponents.java new file mode 100644 index 00000000..2c1cd63a --- /dev/null +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/IHoldSubComponents.java @@ -0,0 +1,19 @@ +package fr.neatmonster.nocheatplus.components; + +import java.util.Collection; + +/** + * This component queues other components to automatically register "later", i.e. with an unspecified but finite delay, depending on specification coming with the implementation. + * The convention is to add this as a component "officially", even if only the sub-components are used. + * @author mc_dev + * + */ +public interface IHoldSubComponents { + + /** + * This is to be called after the specified delay after registering the implementation in a registry. + * It is recommended to not return the same elements again on a second call, for the case of delegating to further registries supporting this interface. + * @return Always a collection, may be empty, should be empty on the second call. + */ + public Collection getSubComponents(); +} diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/NoCheatPlusAPI.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/NoCheatPlusAPI.java index 4ae4a148..d9e59646 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/NoCheatPlusAPI.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/components/NoCheatPlusAPI.java @@ -4,12 +4,22 @@ package fr.neatmonster.nocheatplus.components; /** * ComponentRegistry: *
  • Supported components: Listener, TickListener, PermStateReceiver, INotifyReload, INeedConfig, IRemoveData, MCAccessHolder, ConsistencyChecker, JoinLeaveListener
  • + *
  • ComponentRegistry instances will be registered as sub registries unless you use the addComponent(Object, boolean) method appropriately.
  • + *
  • IHoldSubComponents instances will be registered in the next tick (scheduled task), those added within onEnable will get registered after looping in onEnable.
  • *
  • Registering components should be done during onEnable or any time while the plugin is enabled, all components will be unregistered in onDisable.
  • *
  • References to all components will be held until onDisable is finished.
  • *
  • Interfaces checked for managed listeners: IHaveMethodOrder (method), ComponentWithName (tag)
  • * @author mc_dev * */ -public interface NoCheatPlusAPI extends ComponentRegistry{ +public interface NoCheatPlusAPI extends ComponentRegistry, ComponentRegistryProvider{ + + /** + * By default addComponent(Object) will register ComponentFactories as well. + * @param obj + * @param allowComponentRegistry If to allow registering ComponentFactories. + * @return + */ + public boolean addComponent(Object obj, boolean allowComponentRegistry); } diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/players/DataManager.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/players/DataManager.java index 9dfaf56f..8b18ace6 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/players/DataManager.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/players/DataManager.java @@ -58,7 +58,7 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil; * @author mc_dev * */ -public class DataManager implements Listener, INotifyReload, INeedConfig, ComponentRegistry, ComponentWithName, ConsistencyChecker{ +public class DataManager implements Listener, INotifyReload, INeedConfig, ComponentRegistry, ComponentWithName, ConsistencyChecker{ protected static DataManager instance = null; @@ -351,26 +351,19 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon } @Override - public boolean addComponent(Object obj) { - if (obj instanceof IRemoveData) { - if (iRemoveData.contains(obj)){ - return false; - } - else{ - iRemoveData.add((IRemoveData) obj); - return true; - } + public boolean addComponent(IRemoveData obj) { + if (iRemoveData.contains(obj)){ + return false; } else{ + iRemoveData.add((IRemoveData) obj); return true; } } @Override - public void removeComponent(Object obj) { - if (obj instanceof IRemoveData) { - iRemoveData.remove((IRemoveData) obj); - } + public void removeComponent(IRemoveData obj) { + iRemoveData.remove((IRemoveData) obj); } /**