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.
*/
public class InstantBow extends Check {
private static final float maxTime = 800f;
/**
* Instantiates a new instant bow check.
@ -37,9 +39,7 @@ public class InstantBow extends Check {
* the force
* @return true, if successful
*/
public boolean check(final Player player, final float force) {
// Take time once.
final long time = System.currentTimeMillis();
public boolean check(final Player player, final float force, final long now) {
final InventoryData data = InventoryData.getData(player);
final InventoryConfig cc = InventoryConfig.getConfig(player);
@ -47,16 +47,22 @@ public class InstantBow extends Check {
boolean cancel = false;
// 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.
data.instantBowVL *= 0.9D;
else if (data.instantBowLastTime > time)
// Security check if time ran backwards, reset
data.instantBowLastTime = 0L;
}
else if (data.instantBowInteractTime > now){
// Security check if time ran backwards.
// TODO: Maybe this can be removed, though TickTask does not reset at the exact moment.
}
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.
data.instantBowVL += difference;
@ -68,8 +74,11 @@ public class InstantBow extends Check {
}
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;
}

View File

@ -52,14 +52,15 @@ public class InstantEat extends Check {
return false;
// 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.
data.instantEatVL *= 0.6D;
else if (data.instantEatLastTime > time)
// Security test, if time ran backwards, reset.
data.instantEatLastTime = 0;
}
else if (data.instantEatInteract > time){
// Security test, if time ran backwards.
}
else {
final double difference = (expectedTimeWhenEatingFinished - time) / 100D;
@ -71,6 +72,8 @@ public class InstantEat extends Check {
cancel = executeActions(player, data.instantEatVL, difference,
InventoryConfig.getConfig(player).instantEatActions);
}
data.instantEatInteract = 0;
return cancel;
}

View File

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

View File

@ -82,9 +82,9 @@ public class InventoryData extends ACheckData {
public long fastClickLastTime;
// Data of the instant bow check.
public long instantBowLastTime;
public long instantBowInteractTime;
// Data of the instant eat check.
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.player.PlayerDropItemEvent;
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.Improbable;
@ -77,15 +79,19 @@ public class InventoryListener implements Listener {
if (instantBow.isEnabled(player)){
final long now = System.currentTimeMillis();
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);
// Still check instantBow.
if (instantBow.check(player, event.getForce()))
// The check requested the event to be cancelled.
}
// Still check instantBow, whatever yawrate says.
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);
else if (Improbable.check(player, 1f, now))
// COmbined fighting speed.
event.setCancelled(true);
}
}
}
}
@ -191,8 +197,7 @@ public class InventoryListener implements Listener {
* @param event
* the event
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
public void onPlayerInteractEvent(final PlayerInteractEvent event) {
/*
* ____ _ ___ _ _
@ -203,24 +208,43 @@ public class InventoryListener implements Listener {
* |___/
*/
// Only interested in right-clicks while holding an item.
if (!event.hasItem()
|| !(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK))
if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK)
return;
final InventoryData data = InventoryData.getData(event.getPlayer());
if (event.getItem().getType() == Material.BOW)
// It was a bow, the player starts to pull the string, remember this time.
data.instantBowLastTime = System.currentTimeMillis();
else if (event.getItem().getType().isEdible()) {
// It was food, the player starts to eat some food, remember this time and the type of food.
data.instantEatFood = event.getItem().getType();
data.instantEatLastTime = System.currentTimeMillis();
} else {
boolean resetAll = false;
if (event.hasItem()){
final ItemStack item = event.getItem();
final Material type = item.getType();
if (type == Material.BOW)
// 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.
data.instantBowLastTime = 0;
data.instantEatLastTime = 0;
data.instantBowInteractTime = 0;
data.instantEatInteract = 0;
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.";
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";
private static final String INVENTORY_INSTANTEAT = INVENTORY + "instanteat.";

View File

@ -22,7 +22,7 @@ import org.bukkit.Material;
public class DefaultConfig extends ConfigFile {
/** NCP build needed for this config. */
public static final int buildNumber = 176;
public static final int buildNumber = 185;
/**
* 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_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_ACTIONS, "log:instanteat:2:5:if cancel");