Consistency fixes for reloading the configuration.

Mostly MCAccess must be reset after reloading the configuration, a rare
case, but wanted for testing. For this a component has been added, which
allows automatic setting of MCAccess on reload, in consequence the
CheckListener registers all checks as components with the NoCheatPlusAPI
(CheckListener.addCheck).

Components can not be registered twice anymore.

All TickListeners will be removed in onDisable.

Possibly others.
This commit is contained in:
asofold 2013-01-30 04:22:06 +01:00
parent abe22f8104
commit dc5a1bd19f
16 changed files with 163 additions and 62 deletions

View File

@ -45,6 +45,7 @@ import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.compat.MCAccessFactory; import fr.neatmonster.nocheatplus.compat.MCAccessFactory;
import fr.neatmonster.nocheatplus.components.ComponentWithName; import fr.neatmonster.nocheatplus.components.ComponentWithName;
import fr.neatmonster.nocheatplus.components.INeedConfig; import fr.neatmonster.nocheatplus.components.INeedConfig;
import fr.neatmonster.nocheatplus.components.MCAccessHolder;
import fr.neatmonster.nocheatplus.components.NCPListener; import fr.neatmonster.nocheatplus.components.NCPListener;
import fr.neatmonster.nocheatplus.components.NameSetPermState; import fr.neatmonster.nocheatplus.components.NameSetPermState;
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI; import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
@ -253,31 +254,40 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
private int dataManTaskId = -1; private int dataManTaskId = -1;
/**
* Interfaces checked for managed listeners: IHaveMethodOrder (method), ComponentWithName (tag)<br>
*/
@Override @Override
public void addComponent(final Object obj) { public boolean addComponent(final Object obj) {
allComponents.add(obj); if (allComponents.contains(obj)) return false;
boolean added = false;
if (obj instanceof Listener) { if (obj instanceof Listener) {
addListener((Listener) obj); addListener((Listener) obj);
added = true;
} }
if (obj instanceof INotifyReload) { if (obj instanceof INotifyReload) {
notifyReload.add((INotifyReload) obj); notifyReload.add((INotifyReload) obj);
if (obj instanceof INeedConfig) { if (obj instanceof INeedConfig) {
((INeedConfig) obj).onReload(); ((INeedConfig) obj).onReload();
} }
added = true;
} }
if (obj instanceof TickListener){ if (obj instanceof TickListener){
TickTask.addTickListener((TickListener) obj); TickTask.addTickListener((TickListener) obj);
added = true;
} }
if (obj instanceof PermStateReceiver){ if (obj instanceof PermStateReceiver){
// No immediate update done. // No immediate update done.
permStateReceivers.add((PermStateReceiver) obj); permStateReceivers.add((PermStateReceiver) obj);
added = true;
}
if (obj instanceof MCAccessHolder){
// Add to allComponents.
((MCAccessHolder) obj).setMCAccess(getMCAccess());
added = true;
} }
// Also add to DataManager, which will pick what it needs. // Also add to DataManager, which will pick what it needs.
// TODO: This is fishy in principle, something more concise? // TODO: This is fishy in principle, something more concise?
dataMan.addComponent(obj); if (dataMan.addComponent(obj)) added = true;
if (added) allComponents.add(obj);
return added;
} }
/** /**
@ -361,6 +371,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
TickTask.setLocked(true); TickTask.setLocked(true);
TickTask.purge(); TickTask.purge();
TickTask.cancel(); TickTask.cancel();
TickTask.removeAllTickListeners();
// (Keep the tick task locked!) // (Keep the tick task locked!)
// Stop metrics task. // Stop metrics task.
@ -502,6 +513,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
public void onReload() { public void onReload() {
final ConfigFile config = ConfigManager.getConfigFile(); final ConfigFile config = ConfigManager.getConfigFile();
// Initialize BlockProperties // Initialize BlockProperties
initMCAccess(config);
initBlockProperties(config); initBlockProperties(config);
// Reset Command protection. // Reset Command protection.
undoCommandChanges(); undoCommandChanges();
@ -619,11 +631,24 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
} }
/** /**
* Reset MCAccess and (re-) initialize BlockProperties, including config. * Re-setup MCAccess and pass it to MCAccessHolder components.
* @param config
*/
protected void initMCAccess(final ConfigFile config) {
// Reset MCAccess.
NoCheatPlus.mcAccess = null;
final MCAccess mcAccess = getMCAccess();
for (final Object obj : this.allComponents){
if (obj instanceof MCAccessHolder){
((MCAccessHolder) obj).setMCAccess(mcAccess);
}
}
}
/**
* Initialize BlockProperties, including config.
*/ */
protected void initBlockProperties(ConfigFile config){ protected void initBlockProperties(ConfigFile config){
// Reset MCAccess.
mcAccess = null;
// Set up BlockProperties. // Set up BlockProperties.
BlockProperties.init(getMCAccess()); BlockProperties.init(getMCAccess());
BlockProperties.applyConfig(config, ConfPaths.COMPATIBILITY_BLOCKS); BlockProperties.applyConfig(config, ConfPaths.COMPATIBILITY_BLOCKS);

View File

@ -9,6 +9,7 @@ import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.actions.ActionList; import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.components.MCAccessHolder;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.hooks.NCPHookManager; import fr.neatmonster.nocheatplus.hooks.NCPHookManager;
import fr.neatmonster.nocheatplus.logging.LogUtil; import fr.neatmonster.nocheatplus.logging.LogUtil;
@ -27,9 +28,9 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
* MMMMMMMMMMM * MMMMMMMMMMM
*/ */
/** /**
* The parent class of all checks. * The parent class of all checks. Don't let this implement Listener without knowing that this might be registered as component with NCP before the check-listeners.
*/ */
public abstract class Check { public abstract class Check implements MCAccessHolder{
/** The execution histories of each check. */ /** The execution histories of each check. */
protected static Map<String, ExecutionHistory> histories = new HashMap<String, ExecutionHistory>(); protected static Map<String, ExecutionHistory> histories = new HashMap<String, ExecutionHistory>();
@ -50,7 +51,7 @@ public abstract class Check {
/** The type. */ /** The type. */
protected final CheckType type; protected final CheckType type;
protected final MCAccess mcAccess; protected MCAccess mcAccess;
/** /**
* Instantiates a new check. * Instantiates a new check.
@ -183,4 +184,15 @@ public abstract class Check {
} }
return !NCPExemptionManager.isExempted(player, type); return !NCPExemptionManager.isExempted(player, type);
} }
@Override
public void setMCAccess(MCAccess mcAccess) {
this.mcAccess = mcAccess;
}
@Override
public MCAccess getMCAccess() {
return mcAccess;
}
} }

View File

@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.checks;
import fr.neatmonster.nocheatplus.NoCheatPlus; import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.components.MCAccessHolder;
import fr.neatmonster.nocheatplus.components.NCPListener; import fr.neatmonster.nocheatplus.components.NCPListener;
/** /**
@ -10,11 +11,11 @@ import fr.neatmonster.nocheatplus.components.NCPListener;
* @author mc_dev * @author mc_dev
* *
*/ */
public class CheckListener extends NCPListener{ public class CheckListener extends NCPListener implements MCAccessHolder{
/** Check group / type which this listener is for. */ /** Check group / type which this listener is for. */
protected final CheckType checkType; protected final CheckType checkType;
protected final MCAccess mcAccess; protected MCAccess mcAccess;
public CheckListener(){ public CheckListener(){
this(null); this(null);
@ -30,4 +31,25 @@ public class CheckListener extends NCPListener{
final String part = super.getComponentName(); final String part = super.getComponentName();
return checkType == null ? part : part + "_" + checkType.name(); return checkType == null ? part : part + "_" + checkType.name();
} }
@Override
public void setMCAccess(MCAccess mcAccess) {
this.mcAccess = mcAccess;
}
@Override
public MCAccess getMCAccess() {
return mcAccess;
}
/**
* Convenience method to add checks as components to NCP.
* @param check
* @return
*/
protected <C extends Check> C addCheck(C check){
// Could also set up a map from check type to check, etc.
NoCheatPlus.getAPI().addComponent(check);
return check;
}
} }

View File

@ -44,22 +44,22 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
public class BlockBreakListener extends CheckListener { public class BlockBreakListener extends CheckListener {
/** The direction check. */ /** The direction check. */
private final Direction direction = new Direction(); private final Direction direction = addCheck(new Direction());
/** The fast break check (per block breaking speed). */ /** The fast break check (per block breaking speed). */
private final FastBreak fastBreak = new FastBreak(); private final FastBreak fastBreak = addCheck(new FastBreak());
/** The frequency check (number of blocks broken) */ /** The frequency check (number of blocks broken) */
private final Frequency frequency = new Frequency(); private final Frequency frequency = addCheck(new Frequency());
/** The no swing check. */ /** The no swing check. */
private final NoSwing noSwing = new NoSwing(); private final NoSwing noSwing = addCheck(new NoSwing());
/** The reach check. */ /** The reach check. */
private final Reach reach = new Reach(); private final Reach reach = addCheck(new Reach());
/** The wrong block check. */ /** The wrong block check. */
private final WrongBlock wrongBlock = new WrongBlock(); private final WrongBlock wrongBlock = addCheck(new WrongBlock());
private boolean isInstaBreak = false; private boolean isInstaBreak = false;

View File

@ -35,10 +35,10 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
public class BlockInteractListener extends CheckListener { public class BlockInteractListener extends CheckListener {
/** The direction check. */ /** The direction check. */
private final Direction direction = new Direction(); private final Direction direction = addCheck(new Direction());
/** The reach check. */ /** The reach check. */
private final Reach reach = new Reach(); private final Reach reach = addCheck(new Reach());
public BlockInteractListener(){ public BlockInteractListener(){
super(CheckType.BLOCKINTERACT); super(CheckType.BLOCKINTERACT);

View File

@ -46,19 +46,19 @@ import fr.neatmonster.nocheatplus.utilities.BlockProperties;
public class BlockPlaceListener extends CheckListener { public class BlockPlaceListener extends CheckListener {
/** The direction check. */ /** The direction check. */
private final Direction direction = new Direction(); private final Direction direction = addCheck(new Direction());
/** The fast place check. */ /** The fast place check. */
private final FastPlace fastPlace = new FastPlace(); private final FastPlace fastPlace = addCheck(new FastPlace());
/** The no swing check. */ /** The no swing check. */
private final NoSwing noSwing = new NoSwing(); private final NoSwing noSwing = addCheck(new NoSwing());
/** The reach check. */ /** The reach check. */
private final Reach reach = new Reach(); private final Reach reach = addCheck(new Reach());
/** The speed check. */ /** The speed check. */
private final Speed speed = new Speed(); private final Speed speed = addCheck(new Speed());
public BlockPlaceListener(){ public BlockPlaceListener(){
super(CheckType.BLOCKPLACE); super(CheckType.BLOCKPLACE);

View File

@ -41,22 +41,22 @@ public class ChatListener extends CheckListener implements INotifyReload {
// Checks. // Checks.
/** Captcha handler. */ /** Captcha handler. */
private final Captcha captcha = new Captcha(); private final Captcha captcha = addCheck(new Captcha());
/** The color check. */ /** The color check. */
private final Color color = new Color(); private final Color color = addCheck(new Color());
/** Commands repetition check. */ /** Commands repetition check. */
private final Commands commands = new Commands(); private final Commands commands = addCheck(new Commands());
/** Logins check (global) */ /** Logins check (global) */
private final Logins logins = new Logins(); private final Logins logins = addCheck(new Logins());
/** Chat message check. */ /** Chat message check. */
private final Text text = new Text(); private final Text text = addCheck(new Text());
/** Relogging check. */ /** Relogging check. */
private final Relog relog = new Relog(); private final Relog relog = addCheck(new Relog());
// Auxiliary stuff. // Auxiliary stuff.

View File

@ -22,13 +22,12 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
*/ */
public class CombinedListener extends CheckListener { public class CombinedListener extends CheckListener {
protected final Improbable improbable; protected final Improbable improbable = addCheck(new Improbable());
protected final MunchHausen munchHausen = new MunchHausen(); protected final MunchHausen munchHausen = addCheck(new MunchHausen());
public CombinedListener(){ public CombinedListener(){
super(CheckType.COMBINED); super(CheckType.COMBINED);
this.improbable = new Improbable();
} }
/** /**

View File

@ -41,28 +41,28 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
public class FightListener extends CheckListener { public class FightListener extends CheckListener {
/** The angle check. */ /** The angle check. */
private final Angle angle = new Angle(); private final Angle angle = addCheck(new Angle());
/** The critical check. */ /** The critical check. */
private final Critical critical = new Critical(); private final Critical critical = addCheck(new Critical());
/** The direction check. */ /** The direction check. */
private final Direction direction = new Direction(); private final Direction direction = addCheck(new Direction());
/** The god mode check. */ /** The god mode check. */
private final GodMode godMode = new GodMode(); private final GodMode godMode = addCheck(new GodMode());
/** The knockback check. */ /** The knockback check. */
private final Knockback knockback = new Knockback(); private final Knockback knockback = addCheck(new Knockback());
/** The no swing check. */ /** The no swing check. */
private final NoSwing noSwing = new NoSwing(); private final NoSwing noSwing = addCheck(new NoSwing());
/** The reach check. */ /** The reach check. */
private final Reach reach = new Reach(); private final Reach reach = addCheck(new Reach());
/** The self hit check */ /** The self hit check */
private final SelfHit selfHit = new SelfHit(); private final SelfHit selfHit = addCheck(new SelfHit());
/** The speed check. */ /** The speed check. */
private final Speed speed = new Speed(); private final Speed speed = new Speed();

View File

@ -50,18 +50,18 @@ import fr.neatmonster.nocheatplus.checks.combined.Improbable;
public class InventoryListener extends CheckListener { public class InventoryListener extends CheckListener {
/** The drop check. */ /** The drop check. */
private final Drop drop = new Drop(); private final Drop drop = addCheck(new Drop());
/** The fast click check. */ /** The fast click check. */
private final FastClick fastClick = new FastClick(); private final FastClick fastClick = addCheck(new FastClick());
/** The instant bow check. */ /** The instant bow check. */
private final InstantBow instantBow = new InstantBow(); private final InstantBow instantBow = addCheck(new InstantBow());
/** The instant eat check. */ /** The instant eat check. */
private final InstantEat instantEat = new InstantEat(); private final InstantEat instantEat = addCheck(new InstantEat());
protected final Items items = new Items(); protected final Items items = addCheck(new Items());
public InventoryListener(){ public InventoryListener(){
super(CheckType.INVENTORY); super(CheckType.INVENTORY);

View File

@ -197,28 +197,28 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
/** The instance of NoCheatPlus. */ /** The instance of NoCheatPlus. */
private final NoCheatPlus plugin = (NoCheatPlus) Bukkit.getPluginManager().getPlugin( private final NoCheatPlus plugin = (NoCheatPlus) Bukkit.getPluginManager().getPlugin("NoCheatPlus");
"NoCheatPlus");
/** The no fall check. **/ /** The no fall check. **/
public final NoFall noFall = new NoFall(); public final NoFall noFall = new NoFall();
/** The creative fly check. */ /** The creative fly check. */
private final CreativeFly creativeFly = new CreativeFly(); private final CreativeFly creativeFly = addCheck(new CreativeFly());
/** The more packets check. */ /** The more packets check. */
private final MorePackets morePackets = new MorePackets(); private final MorePackets morePackets = addCheck(new MorePackets());
/** The more packets vehicle check. */ /** The more packets vehicle check. */
private final MorePacketsVehicle morePacketsVehicle = new MorePacketsVehicle(); private final MorePacketsVehicle morePacketsVehicle = addCheck(new MorePacketsVehicle());
/** The survival fly check. */ /** The survival fly check. */
private final SurvivalFly survivalFly = new SurvivalFly(); private final SurvivalFly survivalFly = addCheck(new SurvivalFly());
/** The Passable (simple no-clip) check.*/ /** The Passable (simple no-clip) check.*/
private final Passable passable = new Passable(); private final Passable passable = addCheck(new Passable());
/** Combined check but handled here (subject to change!) */ /** Combined check but handled here (subject to change!) */
private final BedLeave bedLeave = new BedLeave(); private final BedLeave bedLeave = addCheck(new BedLeave());
/** /**
* Unused instances.<br> * Unused instances.<br>

View File

@ -3,8 +3,8 @@ package fr.neatmonster.nocheatplus.components;
/** /**
* A ComponentRegistry allows registering components, that then are delegated to where they belong.<br> * A ComponentRegistry allows registering components, that then are delegated to where they belong.<br>
* Notes: * Notes:
* <li>Implementations should somehow specify when components can be registered and when they are unregistered automatically.</li>
* <li>Implementations should somehow specify what components can be registered.</li> * <li>Implementations should somehow specify what components can be registered.</li>
* <li>Implementations should somehow specify if/when they are unregistered automatically.</li>
* @author mc_dev * @author mc_dev
* *
*/ */
@ -14,8 +14,9 @@ public interface ComponentRegistry {
* like Listener, INotifyReload, INeedConfig.<br> * like Listener, INotifyReload, INeedConfig.<br>
* For the NoCheatPlus instance this must be done after the configuration has been initialized. * For the NoCheatPlus instance this must be done after the configuration has been initialized.
* @param obj * @param obj
* @return If (newly) added. Adding an already present component should do nothing.
*/ */
public void addComponent(final Object obj); public boolean addComponent(final Object obj);
/** /**
* Remove a registered component. <br> * Remove a registered component. <br>

View File

@ -0,0 +1,23 @@
package fr.neatmonster.nocheatplus.components;
import fr.neatmonster.nocheatplus.compat.MCAccess;
/**
* MCAccessHolder will be updated automatically with the current MCAccess.
* <br>How to name this...
* @author mc_dev
*
*/
public interface MCAccessHolder {
/**
* Set access.
* @param mcAccess
*/
public void setMCAccess(MCAccess mcAccess);
/**
* Getter.
* @return
*/
public MCAccess getMCAccess();
}

View File

@ -3,9 +3,10 @@ package fr.neatmonster.nocheatplus.components;
/** /**
* ComponentRegistry: * ComponentRegistry:
* <li>Supported components: Listener, TickListener, PermStateReceiver, INotifyReload, INeedConfig, IRemoveData</li> * <li>Supported components: Listener, TickListener, PermStateReceiver, INotifyReload, INeedConfig, IRemoveData, MCAccessHolder</li>
* <li>Registering components should be done during onEnable or any time while the plugin is enabled, all components will be unregistered in onDisable.</li> * <li>Registering components should be done during onEnable or any time while the plugin is enabled, all components will be unregistered in onDisable.</li>
* <li>References to all components will be held until onDisable is finished.</li> * <li>References to all components will be held until onDisable is finished.</li>
* <li>Interfaces checked for managed listeners: IHaveMethodOrder (method), ComponentWithName (tag)</li>
* @author mc_dev * @author mc_dev
* *
*/ */

View File

@ -314,9 +314,18 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
@Override @Override
public void addComponent(Object obj) { public boolean addComponent(Object obj) {
if (obj instanceof IRemoveData) { if (obj instanceof IRemoveData) {
iRemoveData.add((IRemoveData) obj); if (iRemoveData.contains(obj)){
return false;
}
else{
iRemoveData.add((IRemoveData) obj);
return true;
}
}
else{
return true;
} }
} }

View File

@ -190,6 +190,15 @@ public class TickTask implements Runnable {
} }
} }
/**
* Remove all of them.
*/
public static void removeAllTickListeners() {
synchronized (tickListeners) {
tickListeners.clear();
}
}
/** /**
* Get the tasks tick count. It is increased with every server tick.<br> * Get the tasks tick count. It is increased with every server tick.<br>
* NOTE: Can be called from other threads. * NOTE: Can be called from other threads.