Add info about version-dependent features to the "ncp version" command.

* Add methods to NoCheatPlusAPI to add/set/get version tags.
* Display all tags in the ncp reload command.
* Alter test framework to set a dummy API.
* Add tags for blocks, net checks, FastConsume.
This commit is contained in:
asofold 2015-01-05 16:12:05 +01:00
parent 39cc75c162
commit 41e9d89efa
9 changed files with 265 additions and 24 deletions

View File

@ -48,6 +48,7 @@ public class ProtocolLibComponent implements DisableListener, INotifyReload{
names.add(adapter.getClass().getSimpleName());
}
StaticLog.logInfo("[NoCheatPlus] Available (and activated) packet level hooks: " + StringUtil.join(names, " | "));
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags("checks", names);
}
}

View File

@ -4,6 +4,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
@ -36,7 +39,18 @@ public class VersionCommand extends BaseCommand{
"Plugin: " + access.getDescription().getVersion(),
"MCAccess: " + mc.getMCVersion() + " / " + mc.getServerVersionTag(),
});
final Map<String, Set<String>> featureTags = NCPAPIProvider.getNoCheatPlusAPI().getAllFeatureTags();
if (!featureTags.isEmpty()) {
final List<String> features = new LinkedList<String>();
// Add present features.
for (final Entry<String, Set<String>> entry : featureTags.entrySet()) {
features.add(" " + entry.getKey() + ": " + StringUtil.join(entry.getValue(), " | "));
}
// Sort and add.
Collections.sort(features, String.CASE_INSENSITIVE_ORDER);
features.add(0, "Features:");
sender.sendMessage(features.toArray(new String[features.size()]));
}
final Collection<NCPHook> hooks = NCPHookManager.getAllHooks();
if (!hooks.isEmpty()){
final List<String> fullNames = new LinkedList<String>();

View File

@ -1,5 +1,6 @@
package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@ -7,12 +8,12 @@ import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup;
import fr.neatmonster.nocheatplus.config.WorldConfigProvider;
import fr.neatmonster.nocheatplus.logging.StaticLog;
public class VanillaBlocksFactory implements BlockPropertiesSetup{
public class VanillaBlocksFactory {
@Override
public void setupBlockProperties(final WorldConfigProvider<?> worldConfigProvider) {
public Collection<String> setupVanillaBlocks(final WorldConfigProvider<?> worldConfigProvider) {
// Standard setups (abort with first failure, low to high MC version).
final List<BlockPropertiesSetup> setups = new LinkedList<BlockPropertiesSetup>();
final List<String> success = new LinkedList<String>();
try{
setups.add(new BlocksMC1_5());
setups.add(new BlocksMC1_6_1());
@ -24,6 +25,8 @@ public class VanillaBlocksFactory implements BlockPropertiesSetup{
try{
// Assume the blocks setup to message success.
setup.setupBlockProperties(worldConfigProvider);
success.add(setup.getClass().getSimpleName());
// TODO: Do logging from here ?
}
catch(Throwable t){
StaticLog.logSevere("[NoCheatPlus] " + setup.getClass().getSimpleName() + ".setupBlockProperties could not execute properly: " + t.getClass().getSimpleName() + " - " + t.getMessage());
@ -32,6 +35,7 @@ public class VanillaBlocksFactory implements BlockPropertiesSetup{
break;
}
}
return success;
}
}

View File

@ -1,5 +1,9 @@
package fr.neatmonster.nocheatplus.components;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import fr.neatmonster.nocheatplus.logging.LogManager;
@ -23,10 +27,36 @@ public interface NoCheatPlusAPI extends ComponentRegistry<Object>, ComponentRegi
/**
* By default addComponent(Object) will register ComponentFactories as well.
* @param obj
* @param allowComponentRegistry If to allow registering ComponentFactories.
* @param allowComponentFactory If to allow registering ComponentFactories.
* @return
*/
public boolean addComponent(Object obj, boolean allowComponentRegistry);
public boolean addComponent(Object obj, boolean allowComponentFactory);
/**
* Tell NCP that certain features are present, e.g. for display with the
* "ncp version" command. Version tags get cleared with disabling the
* plugin.
*
* @param key
* @param featureTags
*/
public void addFeatureTags(String key, Collection<String> featureTags);
/**
* Tell NCP that certain features are present, e.g. for display with the
* "ncp version" command. Overrides all present definitions for the given
* key. Version tags get cleared with disabling the plugin.
*
* @param key
* @param featureTags
*/
public void setFeatureTags(String key, Collection<String> featureTags);
/**
* Get a map with all feature tags that have been set.
* @return
*/
public Map<String, Set<String>> getAllFeatureTags();
/**
* Send all players with the nocheatplus.admin.notify permission a message.<br>

View File

@ -6,10 +6,12 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.InputMismatchException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -21,6 +23,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffectType;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup;
import fr.neatmonster.nocheatplus.compat.blocks.init.vanilla.VanillaBlocksFactory;
@ -420,12 +423,14 @@ public class BlockProperties {
public static void init(final MCAccess mcAccess, final WorldConfigProvider<?> worldConfigProvider) {
blockCache = mcAccess.getBlockCache(null);
pLoc = new PlayerLocation(mcAccess, null);
final Set<String> blocksFeatures = new LinkedHashSet<String>(); // getClass().getName() or some abstract.
try{
initTools(mcAccess, worldConfigProvider);
initBlocks(mcAccess, worldConfigProvider);
blocksFeatures.add("BlocksMC1_4(base)");
// Extra hand picked setups.
try{
new VanillaBlocksFactory().setupBlockProperties(worldConfigProvider);
blocksFeatures.addAll(new VanillaBlocksFactory().setupVanillaBlocks(worldConfigProvider));
}
catch(Throwable t) {
StaticLog.logSevere("[NoCheatPlus] Could not initialize vanilla blocks: " + t.getClass().getSimpleName() + " - " + t.getMessage());
@ -435,6 +440,7 @@ public class BlockProperties {
if (mcAccess instanceof BlockPropertiesSetup) {
try{
((BlockPropertiesSetup) mcAccess).setupBlockProperties(worldConfigProvider);
blocksFeatures.add(mcAccess.getClass().getSimpleName());
}
catch(Throwable t) {
StaticLog.logSevere("[NoCheatPlus] McAccess.setupBlockProperties (" + mcAccess.getClass().getSimpleName() + ") could not execute properly: " + t.getClass().getSimpleName() + " - " + t.getMessage());
@ -446,6 +452,8 @@ public class BlockProperties {
catch(Throwable t) {
StaticLog.logSevere(t);
}
// Override feature tags for blocks.
NCPAPIProvider.getNoCheatPlusAPI().setFeatureTags("blocks", blocksFeatures);
}
private static void initTools(final MCAccess mcAccess, final WorldConfigProvider<?> worldConfigProvider) {

View File

@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
@ -106,7 +107,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
}
// Not static.
/** Central logging access point. */
private BukkitLogManager logManager = null; // Not final, but intended to stay, once set [change to init=syso?].
@ -179,6 +180,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
/** All registered components. */
protected Set<Object> allComponents = new LinkedHashSet<Object>(50);
/** Feature tags by keys, for features that might not be available. */
private final LinkedHashMap<String, LinkedHashSet<String>> featureTags = new LinkedHashMap<String, LinkedHashSet<String>>();
/** Tick listener that is only needed sometimes (component registration). */
protected final OnDemandTickListener onDemandTickListener = new OnDemandTickListener() {
@Override
@ -634,6 +638,8 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
subComponentholders.clear();
// Generic instances registry.
genericInstances.clear();
// Feature tags.
featureTags.clear();
// Clear command changes list (compatibility issues with NPCs, leads to recalculation of perms).
if (changedCommands != null){
@ -734,10 +740,10 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
TickTask.purge();
TickTask.cancel();
TickTask.reset();
// Allow entries to TickTask (just in case).
TickTask.setLocked(false);
// Initialize configuration, if needed.
if (!ConfigManager.isInitialized()) {
// Read the configuration files (should only happen on reloading).
@ -745,13 +751,13 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
}
final ConfigFile config = ConfigManager.getConfigFile();
useSubscriptions = config.getBoolean(ConfPaths.LOGGING_BACKEND_INGAMECHAT_SUBSCRIPTIONS);
// Start logger task(s).
logManager.startTasks();
manageListeners = config.getBoolean(ConfPaths.COMPATIBILITY_MANAGELISTENERS);
if (manageListeners) {
listenerManager.setRegisterDirectly(true);
@ -776,7 +782,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
// Initialize data manager.
disableListeners.add(0, dataMan);
dataMan.onEnable();
// Register components.
@SetupOrder(priority = - 100)
class ReloadHook implements INotifyReload{
@ -896,7 +902,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
);
}
});
// Set StaticLog to more efficient output.
StaticLog.setStreamID(Streams.STATUS);
// Tell the server administrator that we finished loading NoCheatPlus now.
@ -963,7 +969,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
// Cache some things.
useSubscriptions = config.getBoolean(ConfPaths.LOGGING_BACKEND_INGAMECHAT_SUBSCRIPTIONS);
}
@Override
public LogManager getLogManager() {
return logManager;
@ -1251,4 +1257,30 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
return registered;
}
@Override
public void addFeatureTags(String key, Collection<String> featureTags) {
LinkedHashSet<String> present = this.featureTags.get(key);
if (present == null) {
present = new LinkedHashSet<String>();
this.featureTags.put(key, present);
}
present.addAll(featureTags);
}
@Override
public void setFeatureTags(String key, Collection<String> featureTags) {
LinkedHashSet<String> present = new LinkedHashSet<String>();
this.featureTags.put(key, present);
present.addAll(featureTags);
}
@Override
public Map<String, Set<String>> getAllFeatureTags() {
final LinkedHashMap<String, Set<String>> allTags = new LinkedHashMap<String, Set<String>>();
for (final Entry<String, LinkedHashSet<String>> entry : this.featureTags.entrySet()) {
allTags.put(entry.getKey(), Collections.unmodifiableSet(entry.getValue()));
}
return Collections.unmodifiableMap(allTags);
}
}

View File

@ -1,9 +1,11 @@
package fr.neatmonster.nocheatplus.compat;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.checks.inventory.FastConsume;
import fr.neatmonster.nocheatplus.logging.StaticLog;
@ -30,6 +32,7 @@ public class DefaultComponentFactory {
// TODO: Static test methods !?
FastConsume.testAvailability();
available.add(new FastConsume());
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags("checks", Arrays.asList(FastConsume.class.getSimpleName()));
}
catch (Throwable t){
StaticLog.logInfo("[NoCheatPlus] Inventory checks: FastConsume is not available.");

View File

@ -0,0 +1,146 @@
package fr.neatmonster.nocheatplus;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.compat.bukkit.MCAccessBukkit;
import fr.neatmonster.nocheatplus.components.ComponentRegistry;
import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI;
import fr.neatmonster.nocheatplus.logging.LogManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
public class PluginTests {
/**
* Dummy API, providing only a minimal subset of functionality for offline-testing. Some methods do nothing, some throw an UnsupportedOperationException, some will do something (set/get MCAccess).
* @author web4web1
*
*/
public static class DummyNoCheatPlusAPI implements NoCheatPlusAPI {
private MCAccess mcAccess = new MCAccessBukkit();
@Override
public void setMCAccess(MCAccess mcAccess) {
this.mcAccess = mcAccess;
}
@Override
public MCAccess getMCAccess() {
return mcAccess;
}
@Override
public boolean addComponent(Object component) {
throw new UnsupportedOperationException();
}
@Override
public void removeComponent(Object component) {
throw new UnsupportedOperationException();
}
@Override
public <T> Collection<ComponentRegistry<T>> getComponentRegistries(Class<ComponentRegistry<T>> clazz) {
throw new UnsupportedOperationException();
}
@Override
public <T> T registerGenericInstance(T instance) {
throw new UnsupportedOperationException();
}
@Override
public <T, TI extends T> T registerGenericInstance(Class<T> registerFor, TI instance) {
throw new UnsupportedOperationException();
}
@Override
public <T> T getGenericInstance(Class<T> registeredFor) {
throw new UnsupportedOperationException();
}
@Override
public <T> T unregisterGenericInstance(Class<T> registeredFor) {
throw new UnsupportedOperationException();
}
@Override
public boolean addComponent(Object obj, boolean allowComponentFactory) {
throw new UnsupportedOperationException();
}
@Override
public void addFeatureTags(String key, Collection<String> featureTags) {
// IGNORE
}
@Override
public void setFeatureTags(String key, Collection<String> featureTags) {
// IGNORE
}
@Override
public Map<String, Set<String>> getAllFeatureTags() {
throw new UnsupportedOperationException();
}
@Override
public int sendAdminNotifyMessage(String message) {
StaticLog.logInfo("AdminNotifyMessage: " + message);
return 1;
}
@Override
public void sendMessageOnTick(String playerName, String message) {
StaticLog.logInfo("sendMessageOnTick (-> " + playerName + "): " + message);
}
@Override
public boolean allowLogin(String playerName) {
throw new UnsupportedOperationException();
}
@Override
public int allowLoginAll() {
throw new UnsupportedOperationException();
}
@Override
public void denyLogin(String playerName, long duration) {
throw new UnsupportedOperationException();
}
@Override
public boolean isLoginDenied(String playerName) {
throw new UnsupportedOperationException();
}
@Override
public String[] getLoginDeniedPlayers() {
throw new UnsupportedOperationException();
}
@Override
public boolean isLoginDenied(String playerName, long time) {
throw new UnsupportedOperationException();
}
@Override
public LogManager getLogManager() {
// TODO: Maybe do implement a dummy log manager (with file?)
throw new UnsupportedOperationException();
}
}
public static void setDummNoCheatPlusAPI(boolean force) {
if (force || NCPAPIProvider.getNoCheatPlusAPI() == null) {
NCPAPIProvider.setNoCheatPlusAPI(new DummyNoCheatPlusAPI());
}
}
}

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.PluginTests;
import fr.neatmonster.nocheatplus.compat.bukkit.MCAccessBukkit;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
@ -17,9 +19,9 @@ import fr.neatmonster.nocheatplus.utilities.BlockProperties;
*
*/
public class BlockTests {
public static class SimpleWorldConfigProvider <C extends RawConfigFile> implements WorldConfigProvider <C>{
private final C config;
public SimpleWorldConfigProvider(C config) {
@ -42,20 +44,21 @@ public class BlockTests {
list.add(config);
return list;
}
}
public static class DefaultConfigWorldConfigProvider extends SimpleWorldConfigProvider<ConfigFile> {
public DefaultConfigWorldConfigProvider() {
super(new DefaultConfig());
}
}
/**
* Initialize BlockProperties with default config and Bukkit-API compliance :p.
*/
public static void initBlockProperties() {
BlockProperties.init(new MCAccessBukkit(), new DefaultConfigWorldConfigProvider());
PluginTests.setDummNoCheatPlusAPI(false);
BlockProperties.init(NCPAPIProvider.getNoCheatPlusAPI().getMCAccess(), new DefaultConfigWorldConfigProvider());
}
}