[Bleeding] Add FastConsume, if available will replace instanteat.

Somewhat hacky still, not sure it actually works too well.
This commit is contained in:
asofold 2013-05-23 09:44:24 +02:00
parent 37f4881f6f
commit c77dbff23e
10 changed files with 212 additions and 40 deletions

View File

@ -0,0 +1,107 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigManager;
import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
/**
* Quick replacement for InstantEat, partly reusing InstantEat data.
* @author mc_dev
*
*/
public class FastConsume extends Check implements Listener{
public static void testAvailability(){
if (!PlayerItemConsumeEvent.class.getSimpleName().equals("PlayerItemConsumeEvent")){
throw new RuntimeException("This exception should not even get thrown.");
}
}
public FastConsume() {
super(CheckType.INVENTORY_FASTCONSUME);
// Overrides the instant-eat check.
ConfigManager.setForAllConfigs(ConfPaths.INVENTORY_INSTANTEAT_CHECK, false);
LogUtil.logInfo("[NoCheatPlus] Inventory checks: FastConsume is available, disabled InstantEat.");
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onItemConsume(final PlayerItemConsumeEvent event){
final Player player = event.getPlayer();
if (!isEnabled(player)) return;
final InventoryData data = InventoryData.getData(player);
if (check(player, event.getItem(), data)){
event.setCancelled(true);
}
data.instantEatInteract = 0;
data.instantEatFood = null;
}
private boolean check(final Player player, final ItemStack stack, final InventoryData data){
// Uses the instant-eat data for convenience.
// Consistency checks...
if (stack == null){ // || stack.getType() != data.instantEatFood){
// TODO: Strict version should prevent other material (?).
return false;
}
final long time = System.currentTimeMillis();
final long ref = Math.max(data.instantEatInteract, data.lastClickTime);
if (time < ref){
return false;
}
// Check exceptions.
final InventoryConfig cc = InventoryConfig.getConfig(player);
final Material mat = stack == null ? null : stack.getType();
if (mat != null){
if (cc.fastConsumeWhitelist){
if (!cc.fastConsumeItems.contains(mat.getId())){
return false;
}
}
else if (cc.fastConsumeItems.contains(mat.getId())){
return false;
}
}
// Actually check.
final long timeSpent = ref == 0 ? 0 : (time - ref); // Not interact = instant.
final long expectedDuration = cc.fastConsumeDuration;
if (timeSpent < expectedDuration){
// TODO: Might have to do a specialized check for lag spikes here instead.
final float lag = TickTask.getLag(expectedDuration);
if (timeSpent * lag < expectedDuration){
final double difference = (expectedDuration - timeSpent * lag) / 100.0;
data.instantEatVL += difference;
final ViolationData vd = new ViolationData(this, player, data.instantEatVL, difference, cc.fastConsumeActions);
vd.setParameter(ParameterName.FOOD, "" + mat);
if (data.instantEatFood != mat){
vd.setParameter(ParameterName.TAGS, "inconsistent(" + data.instantEatFood + ")");
}
else{
vd.setParameter(ParameterName.TAGS, "");
}
if (executeActions(vd)){
return true;
}
}
}
else{
data.instantEatVL *= 0.6;
}
return false;
}
}

View File

@ -93,6 +93,7 @@ public enum CheckType {
INVENTORY(InventoryConfig.factory, InventoryData.factory, Permissions.INVENTORY),
INVENTORY_DROP(INVENTORY, Permissions.INVENTORY_DROP),
INVENTORY_FASTCLICK(INVENTORY, Permissions.INVENTORY_FASTCLICK),
INVENTORY_FASTCONSUME(INVENTORY, Permissions.INVENTORY_FASTCONSUME),
INVENTORY_INSTANTBOW(INVENTORY, Permissions.INVENTORY_INSTANTBOW),
INVENTORY_INSTANTEAT(INVENTORY, Permissions.INVENTORY_INSTANTEAT),
INVENTORY_ITEMS(INVENTORY, Permissions.INVENTORY_ITEMS),

View File

@ -74,7 +74,7 @@ public class InstantEat extends Check {
}
data.instantEatInteract = 0;
data.instantEatFood = null;
return cancel;
}

View File

@ -1,7 +1,9 @@
package fr.neatmonster.nocheatplus.checks.inventory;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.entity.Player;
@ -84,6 +86,12 @@ public class InventoryConfig extends ACheckConfig {
public final float fastClickShortTermLimit;
public final float fastClickNormalLimit;
public final ActionList fastClickActions;
public final boolean fastConsumeCheck;
public final long fastConsumeDuration;
public final boolean fastConsumeWhitelist;
public final Set<Integer> fastConsumeItems = new HashSet<Integer>();
public final ActionList fastConsumeActions;
public final boolean instantBowCheck;
public final boolean instantBowStrict;
@ -106,29 +114,28 @@ public class InventoryConfig extends ACheckConfig {
dropCheck = data.getBoolean(ConfPaths.INVENTORY_DROP_CHECK);
dropLimit = data.getInt(ConfPaths.INVENTORY_DROP_LIMIT);
dropTimeFrame = data.getLong(ConfPaths.INVENTORY_DROP_TIMEFRAME);
dropActions = data.getOptimizedActionList(ConfPaths.INVENTORY_DROP_ACTIONS,
Permissions.INVENTORY_DROP);
dropActions = data.getOptimizedActionList(ConfPaths.INVENTORY_DROP_ACTIONS, Permissions.INVENTORY_DROP);
fastClickCheck = data.getBoolean(ConfPaths.INVENTORY_FASTCLICK_CHECK);
fastClickSpareCreative = data.getBoolean(ConfPaths.INVENTORY_FASTCLICK_SPARECREATIVE);
fastClickTweaks1_5 = data.getBoolean(ConfPaths.INVENTORY_FASTCLICK_TWEAKS1_5);
fastClickShortTermLimit = (float) data.getDouble(ConfPaths.INVENTORY_FASTCLICK_LIMIT_SHORTTERM);
fastClickNormalLimit = (float) data.getDouble(ConfPaths.INVENTORY_FASTCLICK_LIMIT_NORMAL);
fastClickActions = data.getOptimizedActionList(
ConfPaths.INVENTORY_FASTCLICK_ACTIONS,
Permissions.INVENTORY_FASTCLICK);
fastClickActions = data.getOptimizedActionList(ConfPaths.INVENTORY_FASTCLICK_ACTIONS, Permissions.INVENTORY_FASTCLICK);
fastConsumeCheck = data.getBoolean(ConfPaths.INVENTORY_FASTCONSUME_CHECK);
fastConsumeDuration = (long) (1000.0 * data.getDouble(ConfPaths.INVENTORY_FASTCONSUME_DURATION));
fastConsumeWhitelist = data.getBoolean(ConfPaths.INVENTORY_FASTCONSUME_WHITELIST);
data.readMaterialFromList(ConfPaths.INVENTORY_FASTCONSUME_ITEMS, fastConsumeItems);
fastConsumeActions = data.getOptimizedActionList(ConfPaths.INVENTORY_FASTCONSUME_ACTIONS, Permissions.INVENTORY_FASTCONSUME);
instantBowCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_CHECK);
instantBowStrict = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_STRICT);
instantBowDelay = data.getInt(ConfPaths.INVENTORY_INSTANTBOW_DELAY);
instantBowActions = data.getOptimizedActionList(
ConfPaths.INVENTORY_INSTANTBOW_ACTIONS,
Permissions.INVENTORY_INSTANTBOW);
instantBowActions = data.getOptimizedActionList(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, Permissions.INVENTORY_INSTANTBOW);
instantEatCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTEAT_CHECK);
instantEatActions = data.getOptimizedActionList(
ConfPaths.INVENTORY_INSTANTEAT_ACTIONS,
Permissions.INVENTORY_INSTANTEAT);
instantEatActions = data.getOptimizedActionList(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, Permissions.INVENTORY_INSTANTEAT);
itemsCheck = data.getBoolean(ConfPaths.INVENTORY_ITEMS_CHECK);
}
@ -143,16 +150,18 @@ public class InventoryConfig extends ACheckConfig {
@Override
public final boolean isEnabled(final CheckType checkType) {
switch (checkType) {
case INVENTORY_DROP:
return dropCheck;
case INVENTORY_FASTCLICK:
return fastClickCheck;
case INVENTORY_ITEMS:
return itemsCheck;
case INVENTORY_DROP:
return dropCheck;
case INVENTORY_INSTANTBOW:
return instantBowCheck;
case INVENTORY_INSTANTEAT:
return instantEatCheck;
case INVENTORY_ITEMS:
return itemsCheck;
case INVENTORY_FASTCONSUME:
return fastConsumeCheck;
default:
return true;
}

View File

@ -130,10 +130,9 @@ public class InventoryListener extends CheckListener {
// Only if a player ate food.
if (event.getEntity() instanceof Player) {
final Player player = (Player) event.getEntity();
if (instantEat.isEnabled(player) && instantEat.check(player, event.getFoodLevel()))
event.setCancelled(true);
// Forget the food material, as the info is no longer needed.
InventoryData.getData(player).instantEatFood = null;
if (instantEat.isEnabled(player) && instantEat.check(player, event.getFoodLevel())){
event.setCancelled(true);
}
}
}
@ -275,7 +274,7 @@ public class InventoryListener extends CheckListener {
// It was a bow, the player starts to pull the string, remember this time.
data.instantBowInteract = (data.instantBowInteract > 0 && now - data.instantBowInteract < 800) ? Math.min(System.currentTimeMillis(), data.instantBowInteract) : System.currentTimeMillis();
}
else if (type.isEdible()) {
else if (type.isEdible() || type == Material.POTION) {
final long now = System.currentTimeMillis();
// It was food, the player starts to eat some food, remember this time and the type of food.
data.instantEatFood = type;

View File

@ -481,6 +481,13 @@ public abstract class ConfPaths {
public static final String INVENTORY_FASTCLICK_LIMIT_SHORTTERM = INVENTORY_FASTCLICK_LIMIT + "shortterm";
public static final String INVENTORY_FASTCLICK_LIMIT_NORMAL = INVENTORY_FASTCLICK_LIMIT + "normal";
public static final String INVENTORY_FASTCLICK_ACTIONS = INVENTORY_FASTCLICK + "actions";
private static final String INVENTORY_FASTCONSUME = INVENTORY + "fastconsume.";
public static final String INVENTORY_FASTCONSUME_CHECK = INVENTORY_FASTCONSUME + "active";
public static final String INVENTORY_FASTCONSUME_DURATION = INVENTORY_FASTCONSUME + "duration";
public static final String INVENTORY_FASTCONSUME_WHITELIST = INVENTORY_FASTCONSUME + "whitelist";
public static final String INVENTORY_FASTCONSUME_ITEMS = INVENTORY_FASTCONSUME + "items";
public static final String INVENTORY_FASTCONSUME_ACTIONS = INVENTORY_FASTCONSUME + "actions";
private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
public static final String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";

View File

@ -380,6 +380,12 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:instanteat:2:5:if cancel");
set(ConfPaths.INVENTORY_FASTCONSUME_CHECK, true);
set(ConfPaths.INVENTORY_FASTCONSUME_DURATION, 0.7);
set(ConfPaths.INVENTORY_FASTCONSUME_WHITELIST, false);
set(ConfPaths.INVENTORY_FASTCONSUME_ITEMS, new LinkedList<String>());
set(ConfPaths.INVENTORY_FASTCONSUME_ACTIONS, "log:fastconsume:2:5:if cancel");
set(ConfPaths.INVENTORY_ITEMS_CHECK, true);
/*
@ -486,6 +492,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".dropkick", "ncp delay ncp kick [player] Dropping items too fast.");
set(ConfPaths.STRINGS + ".fastbreak", start + "tried to break blocks ([blockid]) faster than possible" + end);
set(ConfPaths.STRINGS + ".fastclick", start + "tried to move items in his inventory too quickly" + end);
set(ConfPaths.STRINGS + ".fastconsume", start + "consumes [food] [tags] too fast" + end);
set(ConfPaths.STRINGS + ".fastheal", start + "regenerates health faster than usual" + end);
set(ConfPaths.STRINGS + ".fastplace", start + "tried to place too many blocks" + end);
set(ConfPaths.STRINGS + ".fdirection", start + "tried to hit an entity out of line of sight" + end);

View File

@ -1,13 +1,41 @@
package fr.neatmonster.nocheatplus.config;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.configuration.file.YamlConfiguration;
import org.yaml.snakeyaml.DumperOptions;
import fr.neatmonster.nocheatplus.logging.LogUtil;
public class RawConfigFile extends YamlConfiguration{
/**
* Attempt to get an int id from a string.<br>
* Will return out of range numbers, attempts to parse materials.
* @param content
* @return
*/
public static Integer parseTypeId(String content) {
content = content.trim().toUpperCase();
try{
return Integer.parseInt(content);
}
catch(NumberFormatException e){}
try{
Material mat = Material.matchMaterial(content.replace(' ', '_').replace('-', '_').replace('.', '_'));
if (mat != null) return mat.getId();
}
catch (Exception e) {}
return null;
}
////////////////
// Not static.
////////////////
/**
* Return a double value within given bounds, with preset.
*
@ -85,26 +113,25 @@ public class RawConfigFile extends YamlConfiguration{
int id = getInt(path, Integer.MAX_VALUE);
return id == Integer.MAX_VALUE ? preset : id;
}
/**
* Attempt to get an int id from a string.<br>
* Will return out of range numbers, attempts to parse materials.
* @param content
* @return
* Outputs warnings to console.
* @param path
* @param target Collection to fill ids into.
*/
public static Integer parseTypeId(String content) {
content = content.trim().toUpperCase();
try{
return Integer.parseInt(content);
}
catch(NumberFormatException e){}
try{
Material mat = Material.matchMaterial(content.replace(' ', '_').replace('-', '_').replace('.', '_'));
if (mat != null) return mat.getId();
}
catch (Exception e) {}
return null;
}
public void readMaterialFromList(final String path, final Collection<Integer> target) {
final List<String> content = getStringList(path);
if (content == null || content.isEmpty()) return;
for (final String entry : content){
final Integer id = parseTypeId(entry);
if (id == null){
LogUtil.logWarning("[NoCheatPlus] Bad material entry (" + path +"): " + entry);
}
else{
target.add(id);
}
}
}
/* (non-Javadoc)
* @see org.bukkit.configuration.file.YamlConfiguration#saveToString()

View File

@ -162,6 +162,7 @@ public class Permissions {
public static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
public static final String INVENTORY_FASTCLICK = INVENTORY + ".fastclick";
public static final String INVENTORY_FASTCONSUME = INVENTORY + ".fastconsume";
public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow";
public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat";
public static final String INVENTORY_ITEMS = INVENTORY + ".items";

View File

@ -4,6 +4,9 @@ import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import fr.neatmonster.nocheatplus.checks.inventory.FastConsume;
import fr.neatmonster.nocheatplus.logging.LogUtil;
/**
* Default factory for add-in components which might only be available under certain circumstances.
*
@ -18,7 +21,18 @@ public class DefaultComponentFactory {
public Collection<Object> getAvailableComponentsOnEnable(){
final List<Object> available = new LinkedList<Object>();
// Add components here (try-catch).
//////////////////////////////////////
// Add components (try-catch).
//////////////////////////////////////
// Check: inventory.fastconsume.
try{
FastConsume.testAvailability();
available.add(new FastConsume());
}
catch (Throwable t){
LogUtil.logInfo("[NoCheatPlus] Inventory checks: FastConsume is not available.");
}
return available;
}