Optimize/correct block-interact checking.

This commit is contained in:
asofold 2013-02-17 17:04:06 +01:00
parent 5f5d571264
commit 89cbbfdddb
3 changed files with 33 additions and 32 deletions

View File

@ -2,7 +2,6 @@ package fr.neatmonster.nocheatplus.checks.blockinteract;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
@ -12,8 +11,6 @@ import org.bukkit.event.player.PlayerInteractEvent;
import fr.neatmonster.nocheatplus.checks.CheckListener;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.InteractRayTracing;
/*
* M#"""""""'M dP dP M""M dP dP
@ -66,6 +63,9 @@ public class BlockInteractListener extends CheckListener {
* |_| |_|\__,_|\__, |\___|_| |___|_| |_|\__\___|_| \__,_|\___|\__|
* |___/
*/
// TODO: Cancelled events: might still have to check for use of blocks etc?
final Player player = event.getPlayer();
final Action action = event.getAction();
@ -79,17 +79,26 @@ public class BlockInteractListener extends CheckListener {
if (block == null){
return;
}
final BlockInteractData data = BlockInteractData.getData(player);
final BlockInteractConfig cc = BlockInteractConfig.getConfig(player);
boolean cancelled = false;
final Location loc = player.getLocation();
// TODO: fast-interact !
// First the reach check.
if (!cancelled && reach.isEnabled(player) && reach.check(player, block.getLocation()))
cancelled = true;
if (!cancelled && reach.isEnabled(player) && reach.check(player, loc, block, data, cc)){
cancelled = true;
}
// Second the direction check
if (!cancelled && direction.isEnabled(player) && direction.check(player, block.getLocation()))
cancelled = true;
if (!cancelled && direction.isEnabled(player) && direction.check(player, loc, block, data, cc)){
cancelled = true;
}
// If one of the checks requested to cancel the event, do so.
if (cancelled) {
event.setUseInteractedBlock(Result.DENY);

View File

@ -1,6 +1,7 @@
package fr.neatmonster.nocheatplus.checks.blockinteract;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
@ -34,33 +35,32 @@ public class Direction extends Check {
*
* @param player
* the player
* @param location
* @param blockLocation
* the location
* @return true, if successful
*/
public boolean check(final Player player, final Location location) {
final BlockInteractData data = BlockInteractData.getData(player);
public boolean check(final Player player, final Location loc, final Block block, final BlockInteractData data, final BlockInteractConfig cc) {
boolean cancel = false;
// How far "off" is the player with his aim. We calculate from the players eye location and view direction to
// the center of the target block. If the line of sight is more too far off, "off" will be bigger than 0.
final double off = CheckUtils.directionCheck(player, location.getX() + 0.5D, location.getY() + 0.5D,
location.getZ() + 0.5D, 1D, 1D, 50);
final double off = CheckUtils.directionCheck(player, 0.5 + block.getX(), 0.5 + block.getY(), 0.5 + block.getZ(), 1D, 1D, 50);
if (off > 0.1D) {
// Player failed the check. Let's try to guess how far he was from looking directly to the block...
final Vector direction = player.getEyeLocation().getDirection();
final Vector blockEyes = location.add(0.5D, 0.5D, 0.5D).subtract(player.getEyeLocation()).toVector();
final Vector direction = loc.getDirection();
final Vector blockEyes = new Vector(0.5 + block.getX() - loc.getX(), 0.5 + block.getY() - loc.getY() - player.getEyeHeight(), 0.5 + block.getZ() - loc.getZ());
final double distance = blockEyes.crossProduct(direction).length() / direction.length();
// Add the overall violation level of the check.
data.directionVL += distance;
// TODO: Set distance parameter.
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.directionVL, distance,
BlockInteractConfig.getConfig(player).directionActions);
cancel = executeActions(player, data.directionVL, distance, cc.directionActions);
} else
// Player did likely nothing wrong, reduce violation counter to reward him.
data.directionVL *= 0.9D;

View File

@ -1,9 +1,8 @@
package fr.neatmonster.nocheatplus.checks.blockinteract;
import java.util.Map;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.actions.ParameterName;
@ -44,12 +43,11 @@ public class Reach extends Check {
*
* @param player
* the player
* @param location
* @param blockLocation
* the location
* @return true, if successful
*/
public boolean check(final Player player, final Location location) {
final BlockInteractData data = BlockInteractData.getData(player);
public boolean check(final Player player, final Location loc, final Block block, final BlockInteractData data, final BlockInteractConfig cc) {
boolean cancel = false;
@ -57,8 +55,7 @@ public class Reach extends Check {
// Distance is calculated from eye location to center of targeted block. If the player is further away from his
// target than allowed, the difference will be assigned to "distance".
final double distance = CheckUtils.distance(player.getEyeLocation(), location.add(0.5D, 0.5D, 0.5D))
- distanceLimit;
final double distance = CheckUtils.distance(loc.getX(), loc.getY() + player.getEyeHeight(), loc.getZ(), 0.5 + block.getX(), 0.5 + block.getY(), 0.5 + block.getZ()) - distanceLimit;
if (distance > 0) {
// He failed, increment violation level.
@ -69,19 +66,14 @@ public class Reach extends Check {
// Execute whatever actions are associated with this check and the violation level and find out if we should
// cancel the event.
cancel = executeActions(player, data.reachVL, distance, BlockInteractConfig.getConfig(player).reachActions);
final ViolationData vd = new ViolationData(this, player, data.reachVL, distance, cc.reachActions);
vd.setParameter(ParameterName.REACH_DISTANCE, String.valueOf(Math.round(data.reachDistance)));
cancel = executeActions(vd);
} else
// Player passed the check, reward him.
data.reachVL *= 0.9D;
return cancel;
}
@Override
protected Map<ParameterName, String> getParameterMap(final ViolationData violationData) {
final Map<ParameterName, String> parameters = super.getParameterMap(violationData);
parameters.put(ParameterName.REACH_DISTANCE, String.valueOf(Math.round(BlockInteractData.getData(violationData.player).reachDistance)));
return parameters;
}
}