Change design of exemption bookkeeping (ExemptionManager), adjust

visibility.
This commit is contained in:
asofold 2012-09-12 12:10:54 +02:00
parent 15230ebdb3
commit 5d4a2ac5cb
5 changed files with 236 additions and 87 deletions

View File

@ -8,19 +8,21 @@ import java.util.List;
import me.asofold.bpl.cncp.config.compatlayer.CompatConfig;
import me.asofold.bpl.cncp.config.compatlayer.CompatConfigFactory;
import me.asofold.bpl.cncp.config.compatlayer.ConfigUtil;
import me.asofold.bpl.cncp.hooks.AbstractHook;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
/**
* Exempting players by class names for some class.
* @author mc_dev
*
*/
public abstract class ClassExemptionHook extends ExemptionHook implements ConfigurableHook{
public abstract class ClassExemptionHook extends AbstractHook implements ConfigurableHook{
protected final ExemptionManager man = new ExemptionManager();
protected final List<String> defaultClasses = new LinkedList<String>();
protected final LinkedHashSet<String> classes = new LinkedHashSet<String>();
@ -47,9 +49,7 @@ public abstract class ClassExemptionHook extends ExemptionHook implements Config
*/
public boolean checkExempt(final Player player, final Class<?> clazz, final CheckType checkType){
if (!classes.contains(clazz.getSimpleName())) return false;
addExemption(player.getName());
exempt(player, checkType);
return true;
return man.addExemption(player, checkType);
}
/**
@ -60,29 +60,7 @@ public abstract class ClassExemptionHook extends ExemptionHook implements Config
*/
public boolean checkUnexempt(final Player player, final Class<?> clazz, final CheckType checkType){
if (!classes.contains(clazz.getSimpleName())) return false;
if (removeExemption(player.getName())) return true;
else {
unexempt(player, checkType);
return false;
}
}
/**
* Hides the API access from listeners potentially.
* @param player
* @param checkType
*/
public void exempt(final Player player, final CheckType checkType){
NCPExemptionManager.exemptPermanently(player, checkType);
}
/**
* Hides the API access from listeners potentially.
* @param player
* @param checkType
*/
public void unexempt(final Player player, final CheckType checkType){
NCPExemptionManager.unexempt(player, checkType);
return man.removeExemption(player, checkType);
}
@Override

View File

@ -1,48 +0,0 @@
package me.asofold.bpl.cncp.hooks.generic;
import java.util.LinkedHashMap;
import java.util.Map;
import me.asofold.bpl.cncp.hooks.AbstractHook;
/**
* Auxiliary methods and data structure to handle simple sort of exemption.
* @author mc_dev
*
*/
public abstract class ExemptionHook extends AbstractHook{
protected final Map<String, Integer> exemptions = new LinkedHashMap<String, Integer>(30);
/**
* Increment exemption count.
* @param name
*/
public void addExemption(final String name){
final Integer count = exemptions.get(name);
if (count == null){
exemptions.put(name, 1);
}
else{
exemptions.put(name, count.intValue() + 1);
}
}
/**
* Decrement exemption count.
* @param name
* @return If the player is still exempted.
*/
public boolean removeExemption(final String name){
final Integer count = exemptions.remove(name);
if (count == null) return false;
final int v = count.intValue();
if (v == 1) return false;
else{
exemptions.put(name, v - 1);
return true;
}
}
}

View File

@ -0,0 +1,219 @@
package me.asofold.bpl.cncp.hooks.generic;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
/**
* Auxiliary methods and data structure to handle simple sort of exemption. <br>
* NOTER: Not thread safe.
* @author mc_dev
*
*/
public class ExemptionManager{
public static enum Status{
EXEMPTED,
NOT_EXEMPTED,
NEEDS_EXEMPTION,
NEEDS_UNEXEMPTION,
}
public static class ExemptionInfo{
public static class CheckEntry{
public int skip = 0;
public int exempt = 0;
}
/** Counts per type, for players being exempted already, to prevent unexempting. */
public final Map<CheckType, CheckEntry> entries = new HashMap<CheckType, CheckEntry>();
/**
* If empty, it can get removed.
* @return
*/
public boolean isEmpty(){
return entries.isEmpty();
}
/**
*
* @param type
* @param isExempted If the player is currently exempted, to be filled in with NCPHookManager.isExempted(player, type)
* @return EXEMPTED or NEEDS_EXEMPTION. The latter means the player has to be exempted.
*/
public Status increase(final CheckType type, final boolean isExempted){
final CheckEntry entry = entries.get(type);
if (entry == null){
final CheckEntry newEntry = new CheckEntry();
entries.put(type, newEntry);
if (isExempted){
newEntry.skip = 1;
return Status.EXEMPTED;
}
else{
newEntry.exempt = 1;
return Status.NEEDS_EXEMPTION;
}
}
if (entry.skip > 0){
if (isExempted){
entry.skip ++;
return Status.EXEMPTED;
}
else{
entry.exempt = entry.skip + 1;
entry.skip = 0;
return Status.NEEDS_EXEMPTION;
}
}
else{
// entry.exempt > 0
entry.exempt ++;
return isExempted ? Status.EXEMPTED : Status.NEEDS_EXEMPTION;
}
}
/**
*
* @param type
* @param isExempted If the player is currently exempted, to be filled in with NCPHookManager.isExempted(player, type)
* @return Status, if NEEDS_EXEMPTION the player has to be exempted. If NEEDS_UNEXEMPTION, the player has to be unexempted.
*/
public Status decrease(final CheckType type, final boolean isExempted){
final CheckEntry info = entries.get(type);
if (info == null) return isExempted ? Status.EXEMPTED : Status.NOT_EXEMPTED;
if (info.skip > 0){
info.skip --;
if (info.skip == 0){
entries.remove(type);
return isExempted ? Status.EXEMPTED : Status.NOT_EXEMPTED;
}
else if (isExempted) return Status.EXEMPTED;
else{
info.exempt = info.skip;
info.skip = 0;
return Status.NEEDS_EXEMPTION;
}
}
else{
info.exempt --;
if (info.exempt == 0){
entries.remove(type);
return isExempted ? Status.NEEDS_UNEXEMPTION : Status.NOT_EXEMPTED;
}
else{
return isExempted ? Status.EXEMPTED : Status.NEEDS_EXEMPTION;
}
}
}
}
/** Exact player name -> ExemptionInfo */
protected final Map<String, ExemptionInfo> exemptions;
public ExemptionManager(){
this(30, 0.75f);
}
/**
*
* @param initialCapacity For the exemption HashMap.
* @param loadFactor For the exemption HashMap.
*/
public ExemptionManager(int initialCapacity, float loadFactor) {
exemptions = new HashMap<String, ExemptionManager.ExemptionInfo>(initialCapacity, loadFactor);
}
/**
* Add exemption count and exempt, if necessary.
* @param player
* @param type
* @return If the player was exempted already.
*/
public boolean addExemption(final Player player, final CheckType type){
final Status status = addExemption(player.getName(), type, NCPExemptionManager.isExempted(player, type));
if (status == Status.NEEDS_EXEMPTION) NCPExemptionManager.exemptPermanently(player, type);
return status == Status.EXEMPTED;
}
/**
* Increment exemption count.
* @param name
* @return If exemption is needed (NEEDS_EXEMPTION).
*/
public Status addExemption(final String name, final CheckType type, boolean isExempted){
final ExemptionInfo info = exemptions.get(name);
final Status status;
if (info == null){
final ExemptionInfo newInfo = new ExemptionInfo();
status = newInfo.increase(type, isExempted);
exemptions.put(name, newInfo);
}
else{
status = info.increase(type, isExempted);
}
return status;
}
/**
* Decrement exemption count, exempt or unexempt if necessary.
* @param player
* @param type
* @return If the player is still exempted.
*/
public boolean removeExemption(final Player player, final CheckType type){
final Status status = removeExemption(player.getName(), type, NCPExemptionManager.isExempted(player, type));
if (status == Status.NEEDS_EXEMPTION) NCPExemptionManager.exemptPermanently(player, type);
else if (status == Status.NEEDS_UNEXEMPTION) NCPExemptionManager.unexempt(player, type);
return status == Status.EXEMPTED || status == Status.NEEDS_EXEMPTION;
}
/**
* Decrement exemption count.
* @param name
* @return Status, NEEDS_EXEMPTION and NEEDS_UNEXEMPTION make it necessary to call NCP API.
*/
public Status removeExemption(final String name, final CheckType type, boolean isExempted){
final ExemptionInfo info = exemptions.get(name);
if (info == null) return isExempted ? Status.EXEMPTED : Status.NOT_EXEMPTED;
final Status status = info.decrease(type, isExempted);
if (info.isEmpty()) exemptions.remove(name);
return status;
}
/**
* Check if the player should be exempted right now according to stored info.
* @param name
* @param type
* @return
*/
public boolean shouldBeExempted(final String name, final CheckType type){
final ExemptionInfo info = exemptions.get(name);
if (info == null) return false;
return !info.isEmpty();
}
/**
* Hides the API access from listeners potentially.
* @param player
* @param checkType
*/
public void exempt(final Player player, final CheckType checkType){
NCPExemptionManager.exemptPermanently(player, checkType);
}
/**
* Hides the API access from listeners potentially.
* @param player
* @param checkType
*/
public void unexempt(final Player player, final CheckType checkType){
NCPExemptionManager.unexempt(player, checkType);
}
}

View File

@ -16,20 +16,20 @@ import fr.neatmonster.nocheatplus.hooks.NCPHook;
public final class HookPlayerClass extends AbstractHook implements ConfigurableHook {
private final Set<String> classNames = new HashSet<String>();
protected final Set<String> classNames = new HashSet<String>();
private boolean exemptAll = true;
protected boolean exemptAll = true;
private boolean checkSuperClass = true;
protected boolean checkSuperClass = true;
private Object ncpHook = null;
protected Object ncpHook = null;
private boolean enabled = true;
protected boolean enabled = true;
/**
* Normal class name.
*/
private String playerClassName = "CraftPlayer";
protected String playerClassName = "CraftPlayer";
public HookPlayerClass(){
this.classNames.addAll(classNames);
@ -42,7 +42,7 @@ public final class HookPlayerClass extends AbstractHook implements ConfigurableH
@Override
public final String getHookVersion() {
return "1.0";
return "1.1";
}
@Override

View File

@ -14,11 +14,11 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
public class HookSetSpeed extends AbstractHook implements Listener, ConfigurableHook{
private float flySpeed = 1.0f;
protected float flySpeed = 1.0f;
private float walkSpeed = 1.0f;
protected float walkSpeed = 1.0f;
private boolean enabled = false;
protected boolean enabled = false;
// private String allowFlightPerm = "cncp.allow-flight";
@ -39,7 +39,7 @@ public class HookSetSpeed extends AbstractHook implements Listener, Configurable
@Override
public String getHookVersion() {
return "2.0";
return "2.1";
}
@Override