[BREAKING] Change ActionFactoryFactory related API.

This commit is contained in:
asofold 2018-04-07 15:22:17 +02:00
parent 3b8e34d192
commit ba13fa8c72
6 changed files with 161 additions and 77 deletions

View File

@ -0,0 +1,21 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.neatmonster.nocheatplus.actions;
import java.util.Map;
public interface ActionFactoryFactory {
public ActionFactory newActionFactory(Map<String, Object> library);
}

View File

@ -18,6 +18,7 @@ import java.util.Collection;
import java.util.Map;
import java.util.Set;
import fr.neatmonster.nocheatplus.actions.ActionFactoryFactory;
import fr.neatmonster.nocheatplus.compat.blocks.changetracker.BlockChangeTracker;
import fr.neatmonster.nocheatplus.components.registry.ComponentRegistry;
import fr.neatmonster.nocheatplus.components.registry.ComponentRegistryProvider;
@ -233,4 +234,39 @@ public interface NoCheatPlusAPI extends ComponentRegistry<Object>, ComponentRegi
*/
public void register(RegistrationContext context);
/**
* Get the registered factory for retrieving config-dependent ActionFactory
* instances.
*
* @return
*/
public ActionFactoryFactory getActionFactoryFactory();
/**
* Register a factory for retrieving config-dependent ActionFactory
* instances. The given instance will be the one returned by
* {@link #getActionFactoryFactory()}. Pass null to reset to default.
* <hr/>
* For all stored raw configurations,
* {@link fr.neatmonster.nocheatplus.config.ConfigFile#setActionFactory(ActionFactoryFactory)})
* will be called.<br/>
* To ensure that configurations are newly created with altered actions, you
* should first call
* {@link fr.neatmonster.nocheatplus.worlds.IWorldDataManager#removeCachedConfigs()}
* and finally
* {@link fr.neatmonster.nocheatplus.players.IPlayerDataManager#removeCachedConfigs()}
* <hr/>
* To Hook into NCP for setting the factories, you could register a
* INotifyReload instance with the NoCheatPlusAPI using the annotation
* SetupOrder (to be deprecated, later: RegisterWithOrder) with a larger
* negative value (-1000, see INotifyReload javadoc).
* <hr/>
*
* @param actionFactoryFactory
* The instance to set. Pass null to reset to the default
* factory.
* @return The previously registered instance.
*/
public ActionFactoryFactory setActionFactoryFactory(final ActionFactoryFactory actionFactoryFactory);
}

View File

@ -16,6 +16,8 @@ package fr.neatmonster.nocheatplus.config;
import org.bukkit.configuration.MemorySection;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.actions.ActionFactoryFactory;
import fr.neatmonster.nocheatplus.actions.ActionList;
import fr.neatmonster.nocheatplus.checks.ViolationData;
@ -23,10 +25,14 @@ import fr.neatmonster.nocheatplus.checks.ViolationData;
* A special configuration class created to handle the loading/saving of actions lists. This is for normal use with the plugin.
*/
public class ConfigFile extends ConfigFileWithActions<ViolationData, ActionList> {
@Override
public void setActionFactory() {
factory = ConfigManager.getActionFactory(((MemorySection) this.get(ConfPaths.STRINGS)).getValues(false));
setActionFactory(NCPAPIProvider.getNoCheatPlusAPI().getActionFactoryFactory());
}
public void setActionFactory(final ActionFactoryFactory actionFactoryFactory) {
setActionFactory(actionFactoryFactory.newActionFactory(((MemorySection) this.get(ConfPaths.STRINGS)).getValues(false)));
}
}

View File

@ -33,7 +33,6 @@ import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.plugin.Plugin;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.actions.ActionFactory;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
@ -47,17 +46,6 @@ import fr.neatmonster.nocheatplus.worlds.WorldDataManager;
*/
public class ConfigManager {
public static interface ActionFactoryFactory{
public ActionFactory newActionFactory(Map<String, Object> library);
}
private static ActionFactoryFactory actionFactoryFactory = new ActionFactoryFactory() {
@Override
public final ActionFactory newActionFactory(final Map<String, Object> library) {
return new ActionFactory(library);
}
};
private static final WorldConfigProvider<ConfigFile> worldConfigProvider = new WorldConfigProvider<ConfigFile>() {
@Override
@ -86,63 +74,6 @@ public class ConfigManager {
private static boolean isInitialized = false;
/**
* Factory method.
* @param library
* @return
*/
public static ActionFactory getActionFactory(final Map<String, Object> library){
return actionFactoryFactory.newActionFactory(library);
}
/**
* Set the factory to get actions from.
* This will reset all ActionFactories to null (lazy initialization),
* call setAllActionFactories to ensure action factories are ready.
* To be on the safe side also call DataManager.clearConfigs().
* <hr>
* To Hook into NCP for setting the factories, you should register a INotifyReload instance
* with the NoCheatPlusAPI using the annotation SetupOrder with a higher negative value (-1000, see INotifyReload javadoc).
* @param factory
*/
// TODO: Register at GenericInstanceRegistry instead, store a handle at best (get rid of 'the other' static registries).
public static void setActionFactoryFactory(ActionFactoryFactory factory){
if (factory != null){
actionFactoryFactory = factory;
}
else{
actionFactoryFactory = new ActionFactoryFactory() {
@Override
public final ActionFactory newActionFactory(final Map<String, Object> library) {
return new ActionFactory(library);
}
};
}
// Use lazy resetting.
final IWorldDataManager worldMan = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
final Iterator<Entry<String, IWorldData>> it = worldMan.getWorldDataIterator();
while (it.hasNext()){
it.next().getValue().getRawConfiguration().setActionFactory(null);
}
// TODO: Update WorldData is skipped for now.
}
public static ActionFactoryFactory getActionFactoryFactory(){
return actionFactoryFactory;
}
/**
* Force setting up all configs action factories.
*/
public static void setAllActionFactories(){
final IWorldDataManager worldMan = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
final Iterator<Entry<String, IWorldData>> it = worldMan.getWorldDataIterator();
while (it.hasNext()){
it.next().getValue().getRawConfiguration().setActionFactory();
}
// TODO: Update WorldData is skipped for now.
}
/**
* Get the WorldConfigProvider in use.
* @return
@ -156,8 +87,6 @@ public class ConfigManager {
*/
public static void cleanup() {
isInitialized = false;
setActionFactoryFactory(null);
// TODO: Remove references of config files ?
}
/**
@ -466,10 +395,13 @@ public class ConfigManager {
}
/**
* Get the maximally found number for the given config path. This does not throw errors. It will return null, if nothing is found or all lookups failed otherwise.
* <br>
* Get the maximally found number for the given config path. This does not
* throw errors. It will return null, if nothing is found or all lookups
* failed otherwise. <br>
* Note: What happens with things like NaN is unspecified.
* @param path Config path.
*
* @param path
* Config path.
* @return Value or null.
*/
public static Double getMaxNumberForAllConfigs(final String path){

View File

@ -52,6 +52,8 @@ import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import fr.neatmonster.nocheatplus.actions.ActionFactory;
import fr.neatmonster.nocheatplus.actions.ActionFactoryFactory;
import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakListener;
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractListener;
import fr.neatmonster.nocheatplus.checks.blockplace.BlockPlaceListener;
@ -138,6 +140,7 @@ import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.entity.PassengerUtil;
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
import fr.neatmonster.nocheatplus.worlds.IWorldDataManager;
import fr.neatmonster.nocheatplus.worlds.WorldDataManager;
@ -860,6 +863,10 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
if (ServerVersion.getMinecraftVersion() == GenericVersion.UNKNOWN_VERSION) {
BukkitVersion.init();
}
// Pre config setup.
if (getGenericInstance(ActionFactoryFactory.class) == null) {
setActionFactoryFactory(null); // Set to default.
}
// Configuration.
if (!ConfigManager.isInitialized()) {
ConfigManager.init(this, worldDataManager);
@ -1540,4 +1547,39 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
return new RegistrationContext();
}
@Override
public ActionFactoryFactory getActionFactoryFactory() {
ActionFactoryFactory factory = getGenericInstance(ActionFactoryFactory.class);
if (factory == null) {
setActionFactoryFactory(null);
factory = getGenericInstance(ActionFactoryFactory.class);
}
return factory;
}
@Override
public ActionFactoryFactory setActionFactoryFactory(
ActionFactoryFactory actionFactoryFactory) {
if (actionFactoryFactory == null) {
actionFactoryFactory = new ActionFactoryFactory() {
@Override
public final ActionFactory newActionFactory(
final Map<String, Object> library) {
return new ActionFactory(library);
}
};
}
final ActionFactoryFactory previous = registerGenericInstance(
ActionFactoryFactory.class, actionFactoryFactory);
// Use lazy resetting.
final IWorldDataManager worldMan = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
final Iterator<Entry<String, IWorldData>> it = worldMan.getWorldDataIterator();
while (it.hasNext()) {
final ConfigFile config = it.next().getValue().getRawConfiguration();
config.setActionFactory(actionFactoryFactory);
}
// (Removing cached configurations and update are to be called externally.)
return previous;
}
}

View File

@ -16,9 +16,13 @@ package fr.neatmonster.nocheatplus;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import fr.neatmonster.nocheatplus.actions.ActionFactory;
import fr.neatmonster.nocheatplus.actions.ActionFactoryFactory;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.compat.blocks.changetracker.BlockChangeTracker;
import fr.neatmonster.nocheatplus.compat.bukkit.MCAccessBukkit;
@ -36,6 +40,8 @@ import fr.neatmonster.nocheatplus.permissions.PermissionRegistry;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.permissions.RegisteredPermission;
import fr.neatmonster.nocheatplus.players.IPlayerDataManager;
import fr.neatmonster.nocheatplus.worlds.IWorldData;
import fr.neatmonster.nocheatplus.worlds.IWorldDataManager;
import fr.neatmonster.nocheatplus.worlds.WorldDataManager;
public class PluginTests {
@ -50,6 +56,12 @@ public class PluginTests {
*/
public static class UnitTestNoCheatPlusAPI implements NoCheatPlusAPI {
/*
* TODO: Mix-in style base functionality, common for testing API and
* live plugin. ALT: DefaultNoCheatPlusAPI class and a common base class
* (plugin would no further implement that API).
*/
private final WorldDataManager worldDataManager = new WorldDataManager();
private final DefaultGenericInstanceRegistry genericInstanceRegistry = new DefaultGenericInstanceRegistry();
private final PermissionRegistry permissionRegistry = new PermissionRegistry(10000);
@ -212,6 +224,41 @@ public class PluginTests {
throw new UnsupportedOperationException();
}
@Override
public ActionFactoryFactory getActionFactoryFactory() {
ActionFactoryFactory factory = getGenericInstance(ActionFactoryFactory.class);
if (factory == null) {
setActionFactoryFactory(null);
factory = getGenericInstance(ActionFactoryFactory.class);
}
return factory;
}
@Override
public ActionFactoryFactory setActionFactoryFactory(
ActionFactoryFactory actionFactoryFactory) {
if (actionFactoryFactory == null) {
actionFactoryFactory = new ActionFactoryFactory() {
@Override
public final ActionFactory newActionFactory(
final Map<String, Object> library) {
return new ActionFactory(library);
}
};
}
final ActionFactoryFactory previous = registerGenericInstance(
ActionFactoryFactory.class, actionFactoryFactory);
// Use lazy resetting.
final IWorldDataManager worldMan = NCPAPIProvider.getNoCheatPlusAPI().getWorldDataManager();
final Iterator<Entry<String, IWorldData>> it = worldMan.getWorldDataIterator();
while (it.hasNext()) {
final ConfigFile config = it.next().getValue().getRawConfiguration();
config.setActionFactory(actionFactoryFactory);
}
// (Removing cached configurations and update are to be called externally.)
return previous;
}
}
public static void setUnitTestNoCheatPlusAPI(boolean force) {