initial version on server

This commit is contained in:
asofold 2012-06-13 02:13:18 +02:00
commit 981bc7d28f
16 changed files with 1367 additions and 0 deletions

4
CompatNoCheatPlus/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/.settings
/.classpath
/.project
/jar_desc.jardesc

View File

@ -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]

View File

@ -0,0 +1,9 @@
name: CompatNoCheatPlus
main: me.asofold.bukkit.cncp.CompatNoCheatPlus
version: 0.0.0 beta
depend:
- NoCheatPlus
softdepend:
- mcMMO
- PluginLibSharedLibrary
- CustomPlg

View File

@ -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<Hook> hooksAll = new ArrayList<Hook>(10);
/**
* Storage of hooks that are called for certain groups and checks.
*/
private static final Map<String, GroupHooks> hooksGroups = new HashMap<String, GroupHooks>(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<Hook> hooks = gh.byCheck.get(check);
if (hooks == null){
hooks = new ArrayList<Hook>(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<String> oldForceEnableLater = new HashSet<String>();
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<Hook> 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<Hook> 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));
}
}
}
}

View File

@ -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<Integer> getIntList(String path, List<Integer> defaultValue){
if ( !hasEntry(path) ) return defaultValue;
List<String> strings = getStringList(path, null);
if ( strings == null ) return defaultValue;
List<Integer> out = new LinkedList<Integer>();
for ( String s : strings){
try{
out.add(Integer.parseInt(s));
} catch(NumberFormatException exc){
// ignore
}
}
return out;
}
@Override
public List<Double> getDoubleList(String path, List<Double> defaultValue) {
if ( !hasEntry(path) ) return defaultValue;
List<String> strings = getStringList(path, null);
if ( strings == null ) return defaultValue;
List<Double> out = new LinkedList<Double>();
for ( String s : strings){
try{
out.add(Double.parseDouble(s));
} catch(NumberFormatException exc){
// ignore
}
}
return out;
}
@Override
public Set<String> getStringKeys(String path, boolean deep) {
if (deep) return getStringKeysDeep(path);
Set<String> keys = new HashSet<String>();
keys.addAll(getStringKeys(path));
return keys;
}
@Override
public Set<String> getStringKeysDeep(String path) {
// NOTE: pretty inefficient, but aimed at seldomly read sections.
Map<String, Object> values = getValuesDeep();
Set<String> out = new HashSet<String>();
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<Double> getDoubleList(String path) {
return getDoubleList(path, null);
}
@Override
public Integer getInt(String path) {
return getInt(path, null);
}
@Override
public List<Integer> getIntList(String path) {
return getIntList(path, null);
}
@Override
public Integer getInteger(String path) {
return getInt(path, null);
}
@Override
public List<Integer> getIntegerList(String path) {
return getIntList(path, null);
}
@Override
public String getString(String path) {
return getString(path, null);
}
@Override
public List<String> 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<Integer> getIntegerList(String path, List<Integer> defaultValue) {
return getIntList(path, defaultValue);
}
@Override
public Long getLong(String path) {
return getLong(path, null);
}
}

View File

@ -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<String> getStringKeys(String path) {
// TODO policy: only strings or all keys as strings ?
List<String> out = new LinkedList<String>();
List<Object> 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<Object> getKeys(String path) {
List<Object> out = new LinkedList<Object>();
Set<String> 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<Object> 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<String> getStringKeys() {
return getStringKeys(null);
}
@Override
public void setProperty(String path, Object obj) {
config.set(path, obj);
}
@Override
public List<String> getStringList(String path, List<String> defaultValue) {
if ( !hasEntry(path)) return defaultValue;
List<String> out = new LinkedList<String>();
List<String> 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<String, Object> 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<Integer> getIntList(String path, List<Integer> defaultValue) {
// TODO Auto-generated method stub
return super.getIntList(path, defaultValue);
}
@Override
public List<Double> getDoubleList(String path, List<Double> defaultValue) {
// TODO Auto-generated method stub
return super.getDoubleList(path, defaultValue);
}
void addAll(Configuration source, Configuration target){
Map<String, Object> 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;
}
}

View File

@ -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<Double> getDoubleList(String path);
public List<Double> getDoubleList(String path , List<Double> defaultValue);
// Integer (abbreviation)
public Integer getInt(String path);
public Integer getInt(String path, Integer defaultValue);
public List<Integer> getIntList(String path);
public List<Integer> getIntList(String path, List<Integer> defaultValue);
// Integer (full name)
public Integer getInteger(String path);
public Integer getInteger(String path, Integer defaultValue);
public List<Integer> getIntegerList(String path);
public List<Integer> getIntegerList(String path, List<Integer> defaultValue);
// String
public String getString(String path);
public String getString(String path, String defaultValue);
public List<String> getStringList(String path);
public List<String> getStringList(String path, List<String> 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<Object> getKeys(String path);
/**
* @deprecated Seems not to be supported anymore by new configuration, use getStringKeys();
* @return
*/
public List<Object> getKeys();
// Keys (String):
/**
*
* @return never null
*/
public List<String> getStringKeys();
public List<String> getStringKeys(String path);
/**
* Get all keys from the section (deep or shallow).
* @param path
* @param deep
* @return Never null.
*/
public Set<String> getStringKeys(String path, boolean deep);
/**
* convenience method.
* @param path
* @return never null
*
*/
public Set<String> getStringKeysDeep(String path);
// Values:
/**
* Equivalent to new config: values(true)
* @return
*/
public Map<String, Object> getValuesDeep();
// Technical / IO:
/**
* False if not supported.
* @param sep
* @return
*/
public boolean setPathSeparatorChar(char sep);
public void load();
public boolean save();
}

View File

@ -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<split.length; i++){
builder.append(sep+stringPart(split[i]));
}
return builder.toString();
}
/**
* Aimed at numbers in paths.
* @param cfg
* @param path
* @return
*/
public static String bestPath(CompatConfig cfg, String path){
return bestPath(cfg, path, '.');
}
/**
* Aimed at numbers in paths.
* @param cfg
* @param path
* @param sep
* @return
*/
public static String bestPath(CompatConfig cfg, String path, char sep){
String useSep = (sep=='.')?"\\.":""+sep;
String[] split = path.split(useSep);
String res;
if (cfg.hasEntry(split[0]) )res = split[0];
else{
res = stringPart(split[0]);
if ( !cfg.hasEntry(res)) return path;
}
for (int i = 1; i<split.length; i++){
if (cfg.hasEntry(res+sep+split[i]) ) res += sep+split[i];
else{
res += sep+stringPart(split[i]);
if ( !cfg.hasEntry(res)) return path;
}
}
return res;
}
public static String stringPart(String input){
try{
Double.parseDouble(input);
return "'"+input+"'";
} catch (NumberFormatException e){
}
try{
Long.parseLong(input);
return "'"+input+"'";
} catch (NumberFormatException e){
}
try{
Integer.parseInt(input);
return "'"+input+"'";
} catch (NumberFormatException e){
}
return input;
}
public static boolean forceDefaults(CompatConfig defaults, CompatConfig config){
Map<String ,Object> 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<String> set, boolean clear, boolean trim, boolean lowerCase){
if (clear) set.clear();
List<String> 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);
}
}
}
}

View File

@ -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<String, Object> getValuesDeep() {
return config.getValues(true);
}
}

View File

@ -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.<br>
* Probable changes:<br>
* - 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;
}
}

View File

@ -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.<br>
*
* @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.<br>
* <hr>
* The return value should be an array of arrays, each of which specifies the group name and the check names within that group.<br>
* You can return null to register for ALL checks.<br>
* You can just register the group name to get all checks for that group.<br>
* <hr>
* 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 !<br>
* 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);
}

View File

@ -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<String, Integer> cancelChecksBlockBreak = new HashMap<String, Integer>();
private static final Map<String, Integer> cancelChecksBlockDamage = new HashMap<String, Integer>();
private static final Map<String, Integer> cancelChecksDamage = new HashMap<String, Integer>();
static{
cancelChecksBlockBreak.put("fastbreak", 2);
cancelChecksBlockDamage.put("fastbreak", 1);
cancelChecksDamage.put("angle", 1);
cancelChecksDamage.put("speed", 1);
}
private final PluginGetter<mcMMO> fetch = new PluginGetter<mcMMO>("mcMMO");
private String cancel = null;
private long cancelTicks = 0;
private final Map<String, Integer> cancelChecks = new HashMap<String, Integer>();
@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<String, Integer> cancelChecks){
if (entity instanceof Player){
setPlayer((Player) entity, cancelChecks);
}
// no projectiles etc.
}
private final void setPlayer(final Player player, Map<String, Integer> 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);
}
}
}
}

View File

@ -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<Hook> all = new ArrayList<Hook>();
/**
* Hooks that want a certain check.<br>
*/
public final Map<String , ArrayList<Hook>> byCheck = new HashMap<String, ArrayList<Hook>>(10);
}

View File

@ -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<String> forceEnableLater = new HashSet<String>();
public static CompatConfig getDefaultConfig(){
CompatConfig cfg = new NewConfig(null);
List<String> tempList = new LinkedList<String>();
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();
}
}

View File

@ -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 <T>
*/
public final class PluginGetter<T extends Plugin> 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>("X").registerEvents(this);
* @param other
* @return
*/
public final PluginGetter<T> registerEvents(final Plugin other){
Bukkit.getPluginManager().registerEvents(this, plugin);
return this;
}
public final T getPlugin(){
return plugin;
}
}

View File

@ -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();
}
}