mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-12-26 02:17:42 +01:00
[Bleeding] Add FastConsume, if available will replace instanteat.
Somewhat hacky still, not sure it actually works too well.
This commit is contained in:
parent
37f4881f6f
commit
c77dbff23e
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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),
|
||||
|
@ -74,7 +74,7 @@ public class InstantEat extends Check {
|
||||
}
|
||||
|
||||
data.instantEatInteract = 0;
|
||||
|
||||
data.instantEatFood = null;
|
||||
return cancel;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user