Bleeding: Sharpen inventory.instantbow and instanteat [expect false

positives
with lag and plugin incompatibilities if they use shootBow].
This commit is contained in:
asofold 2012-10-25 14:32:00 +02:00
parent 5c138d5787
commit 7a14c7fc1f
7 changed files with 87 additions and 47 deletions

View File

@ -20,6 +20,8 @@ import fr.neatmonster.nocheatplus.players.Permissions;
* The InstantBow check will find out if a player pulled the string of his bow too fast. * The InstantBow check will find out if a player pulled the string of his bow too fast.
*/ */
public class InstantBow extends Check { public class InstantBow extends Check {
private static final float maxTime = 800f;
/** /**
* Instantiates a new instant bow check. * Instantiates a new instant bow check.
@ -37,9 +39,7 @@ public class InstantBow extends Check {
* the force * the force
* @return true, if successful * @return true, if successful
*/ */
public boolean check(final Player player, final float force) { public boolean check(final Player player, final float force, final long now) {
// Take time once.
final long time = System.currentTimeMillis();
final InventoryData data = InventoryData.getData(player); final InventoryData data = InventoryData.getData(player);
final InventoryConfig cc = InventoryConfig.getConfig(player); final InventoryConfig cc = InventoryConfig.getConfig(player);
@ -47,16 +47,22 @@ public class InstantBow extends Check {
boolean cancel = false; boolean cancel = false;
// Rough estimation of how long pulling the string should've taken. // Rough estimation of how long pulling the string should've taken.
final long expectedTimeWhenStringDrawn = data.instantBowLastTime + (int) (force * force * 700F); final long expectedPullDuration = (long) (maxTime - maxTime * (1f - force) * (1f - force)) - cc.instantBowDelay;
// Time taken to pull the string.
final long pullDuration = now - data.instantBowInteractTime;
if (expectedTimeWhenStringDrawn < time) if (data.instantBowInteractTime > 0 && pullDuration >= expectedPullDuration){
// The player was slow enough, reward him by lowering his violation level. // The player was slow enough, reward him by lowering his violation level.
data.instantBowVL *= 0.9D; data.instantBowVL *= 0.9D;
else if (data.instantBowLastTime > time) }
// Security check if time ran backwards, reset else if (data.instantBowInteractTime > now){
data.instantBowLastTime = 0L; // Security check if time ran backwards.
// TODO: Maybe this can be removed, though TickTask does not reset at the exact moment.
}
else { else {
final double difference = (expectedTimeWhenStringDrawn - time) / 100D; // TODO: Consider: Allow one time but set yawrate penalty time ?
final double difference = (expectedPullDuration - pullDuration) / 100D;
// Player was too fast, increase his violation level. // Player was too fast, increase his violation level.
data.instantBowVL += difference; data.instantBowVL += difference;
@ -68,8 +74,11 @@ public class InstantBow extends Check {
} }
if (cc.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){ if (cc.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
player.sendMessage(ChatColor.YELLOW + "NCP: " + ChatColor.GRAY + "Bow force: " + force); player.sendMessage(ChatColor.YELLOW + "NCP: " + ChatColor.GRAY + "Bow shot - force: " + force +", pull time: " + pullDuration + "(" + expectedPullDuration +")");
} }
// Reset data here.
data.instantBowInteractTime = 0;
return cancel; return cancel;
} }

View File

@ -52,14 +52,15 @@ public class InstantEat extends Check {
return false; return false;
// Rough estimation about how long it should take to eat // Rough estimation about how long it should take to eat
final long expectedTimeWhenEatingFinished = Math.max(data.instantEatLastTime, data.fastClickLastTime) + 700L; final long expectedTimeWhenEatingFinished = Math.max(data.instantEatInteract, data.fastClickLastTime) + 700L;
if (expectedTimeWhenEatingFinished < time) if (data.instantEatInteract > 0 && expectedTimeWhenEatingFinished < time){
// Acceptable, reduce VL to reward the player. // Acceptable, reduce VL to reward the player.
data.instantEatVL *= 0.6D; data.instantEatVL *= 0.6D;
else if (data.instantEatLastTime > time) }
// Security test, if time ran backwards, reset. else if (data.instantEatInteract > time){
data.instantEatLastTime = 0; // Security test, if time ran backwards.
}
else { else {
final double difference = (expectedTimeWhenEatingFinished - time) / 100D; final double difference = (expectedTimeWhenEatingFinished - time) / 100D;
@ -71,6 +72,8 @@ public class InstantEat extends Check {
cancel = executeActions(player, data.instantEatVL, difference, cancel = executeActions(player, data.instantEatVL, difference,
InventoryConfig.getConfig(player).instantEatActions); InventoryConfig.getConfig(player).instantEatActions);
} }
data.instantEatInteract = 0;
return cancel; return cancel;
} }

View File

@ -73,18 +73,19 @@ public class InventoryConfig extends ACheckConfig {
return worldsMap.get(player.getWorld().getName()); return worldsMap.get(player.getWorld().getName());
} }
public final boolean dropCheck; public final boolean dropCheck;
public final int dropLimit; public final int dropLimit;
public final long dropTimeFrame; public final long dropTimeFrame;
public final ActionList dropActions; public final ActionList dropActions;
public final boolean fastClickCheck; public final boolean fastClickCheck;
public final ActionList fastClickActions; public final ActionList fastClickActions;
public final boolean instantBowCheck; public final boolean instantBowCheck;
public final long instantBowDelay;
public final ActionList instantBowActions; public final ActionList instantBowActions;
public final boolean instantEatCheck; public final boolean instantEatCheck;
public final ActionList instantEatActions; public final ActionList instantEatActions;
/** /**
@ -107,6 +108,7 @@ public class InventoryConfig extends ACheckConfig {
Permissions.INVENTORY_FASTCLICK); Permissions.INVENTORY_FASTCLICK);
instantBowCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_CHECK); instantBowCheck = data.getBoolean(ConfPaths.INVENTORY_INSTANTBOW_CHECK);
instantBowDelay = data.getInt(ConfPaths.INVENTORY_INSTANTBOW_DELAY);
instantBowActions = data.getActionList( instantBowActions = data.getActionList(
ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, ConfPaths.INVENTORY_INSTANTBOW_ACTIONS,
Permissions.INVENTORY_INSTANTBOW); Permissions.INVENTORY_INSTANTBOW);

View File

@ -82,9 +82,9 @@ public class InventoryData extends ACheckData {
public long fastClickLastTime; public long fastClickLastTime;
// Data of the instant bow check. // Data of the instant bow check.
public long instantBowLastTime; public long instantBowInteractTime;
// Data of the instant eat check. // Data of the instant eat check.
public Material instantEatFood; public Material instantEatFood;
public long instantEatLastTime; public long instantEatInteract;
} }

View File

@ -13,6 +13,8 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryEvent; import org.bukkit.event.inventory.InventoryEvent;
import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.inventory.ItemStack;
import fr.neatmonster.nocheatplus.checks.combined.Combined; import fr.neatmonster.nocheatplus.checks.combined.Combined;
import fr.neatmonster.nocheatplus.checks.combined.Improbable; import fr.neatmonster.nocheatplus.checks.combined.Improbable;
@ -77,15 +79,19 @@ public class InventoryListener implements Listener {
if (instantBow.isEnabled(player)){ if (instantBow.isEnabled(player)){
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
final Location loc = player.getLocation(); final Location loc = player.getLocation();
if (Combined.checkYawRate(player, loc.getYaw(), now, loc.getWorld().getName())) if (Combined.checkYawRate(player, loc.getYaw(), now, loc.getWorld().getName())){
// No else if with this, could be cancelled due to other checks feeding, does not have actions.
event.setCancelled(true); event.setCancelled(true);
// Still check instantBow. }
if (instantBow.check(player, event.getForce())) // Still check instantBow, whatever yawrate says.
// The check requested the event to be cancelled. if (instantBow.check(player, event.getForce(), now)){
// The check requested the event to be cancelled.
event.setCancelled(true);
}
else if (Improbable.check(player, 1f, now)){
// Combined fighting speed (Else if: Matter of taste, preventing extreme cascading and actions spam).
event.setCancelled(true); event.setCancelled(true);
else if (Improbable.check(player, 1f, now)) }
// COmbined fighting speed.
event.setCancelled(true);
} }
} }
} }
@ -191,8 +197,7 @@ public class InventoryListener implements Listener {
* @param event * @param event
* the event * the event
*/ */
@EventHandler( @EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteractEvent(final PlayerInteractEvent event) { public void onPlayerInteractEvent(final PlayerInteractEvent event) {
/* /*
* ____ _ ___ _ _ * ____ _ ___ _ _
@ -203,24 +208,43 @@ public class InventoryListener implements Listener {
* |___/ * |___/
*/ */
// Only interested in right-clicks while holding an item. // Only interested in right-clicks while holding an item.
if (!event.hasItem() if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK)
|| !(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK))
return; return;
final InventoryData data = InventoryData.getData(event.getPlayer()); final InventoryData data = InventoryData.getData(event.getPlayer());
if (event.getItem().getType() == Material.BOW) boolean resetAll = false;
// It was a bow, the player starts to pull the string, remember this time.
data.instantBowLastTime = System.currentTimeMillis();
else if (event.getItem().getType().isEdible()) { if (event.hasItem()){
// It was food, the player starts to eat some food, remember this time and the type of food. final ItemStack item = event.getItem();
data.instantEatFood = event.getItem().getType(); final Material type = item.getType();
data.instantEatLastTime = System.currentTimeMillis(); if (type == Material.BOW)
} else { // It was a bow, the player starts to pull the string, remember this time.
data.instantBowInteractTime = System.currentTimeMillis();
else if (type.isEdible()) {
// It was food, the player starts to eat some food, remember this time and the type of food.
data.instantEatFood = type;
data.instantEatInteract = System.currentTimeMillis();
data.instantBowInteractTime = 0;
} else resetAll = true;
}
else resetAll = true;
if (resetAll){
// Nothing that we are interested in, reset data. // Nothing that we are interested in, reset data.
data.instantBowLastTime = 0; data.instantBowInteractTime = 0;
data.instantEatLastTime = 0; data.instantEatInteract = 0;
data.instantEatFood = null; data.instantEatFood = null;
} }
} }
@EventHandler(priority = EventPriority.MONITOR)
public void onItemHeldChange(final PlayerItemHeldEvent event){
final Player player = event.getPlayer();
final InventoryData data = InventoryData.getData(player);
data.instantBowInteractTime = 0;
data.instantEatInteract = 0;
data.instantEatFood = null;
}
} }

View File

@ -417,6 +417,7 @@ public abstract class ConfPaths {
private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow."; private static final String INVENTORY_INSTANTBOW = INVENTORY + "instantbow.";
public static final String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active"; public static final String INVENTORY_INSTANTBOW_CHECK = INVENTORY_INSTANTBOW + "active";
public static final String INVENTORY_INSTANTBOW_DELAY = INVENTORY_INSTANTBOW + "delay";
public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions"; public static final String INVENTORY_INSTANTBOW_ACTIONS = INVENTORY_INSTANTBOW + "actions";
private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat."; private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";

View File

@ -22,7 +22,7 @@ import org.bukkit.Material;
public class DefaultConfig extends ConfigFile { public class DefaultConfig extends ConfigFile {
/** NCP build needed for this config. */ /** NCP build needed for this config. */
public static final int buildNumber = 176; public static final int buildNumber = 185;
/** /**
* Instantiates a new default configuration. * Instantiates a new default configuration.
@ -318,7 +318,8 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.INVENTORY_FASTCLICK_ACTIONS, "cancel vl>50 log:fastclick:3:5:cif cancel"); set(ConfPaths.INVENTORY_FASTCLICK_ACTIONS, "cancel vl>50 log:fastclick:3:5:cif cancel");
set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true); set(ConfPaths.INVENTORY_INSTANTBOW_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "log:instantbow:2:5:if cancel"); set(ConfPaths.INVENTORY_INSTANTBOW_DELAY, 95);
set(ConfPaths.INVENTORY_INSTANTBOW_ACTIONS, "cancel vl>15 log:instantbow:2:5:if cancel");
set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true); set(ConfPaths.INVENTORY_INSTANTEAT_CHECK, true);
set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:instanteat:2:5:if cancel"); set(ConfPaths.INVENTORY_INSTANTEAT_ACTIONS, "log:instanteat:2:5:if cancel");