[Development] Reversed Direction checks and fixed health regeneration

issue (stupid integers!).
This commit is contained in:
NeatMonster 2012-08-05 22:48:29 +02:00
parent cbbc904dd9
commit ad6af2bc14
12 changed files with 142 additions and 125 deletions

View File

@ -70,20 +70,20 @@ public class BlockBreakListener implements Listener {
// it may save us from doing the computationally expensive checks.
// Has the player broken blocks too quickly?
if (fastBreak.isEnabled(player))
cancelled = fastBreak.check(player, block);
if (fastBreak.isEnabled(player) && fastBreak.check(player, block))
cancelled = true;
// Did the arm of the player move before breaking this block?
if (!cancelled && noSwing.isEnabled(player))
cancelled = noSwing.check(player);
if (!cancelled && noSwing.isEnabled(player) && noSwing.check(player))
cancelled = true;
// Is the block really in reach distance?
if (!cancelled && reach.isEnabled(player))
cancelled = reach.check(player, block.getLocation());
if (!cancelled && reach.isEnabled(player) && reach.check(player, block.getLocation()))
cancelled = true;
// Did the player look at the block at all?
if (!cancelled && direction.isEnabled(player))
cancelled = direction.check(player, block.getLocation());
if (!cancelled && direction.isEnabled(player) && direction.check(player, block.getLocation()))
cancelled = true;
// At least one check failed and demanded to cancel the event.
if (cancelled)

View File

@ -41,8 +41,6 @@ public class Direction extends Check {
}
}
private final double OFFSET = 0.5D;
/**
* Checks a player.
*
@ -58,7 +56,12 @@ public class Direction extends Check {
boolean cancel = false;
if (!CheckUtils.intersects(player, location, location.add(1D, 1D, 1D), OFFSET)) {
// 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);
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();

View File

@ -60,7 +60,7 @@ public class BlockPlaceListener implements Listener {
return;
final Player player = event.getPlayer();
final Block block = event.getBlock();
final Block block = event.getBlockPlaced();
boolean cancelled = false;
@ -74,7 +74,7 @@ public class BlockPlaceListener implements Listener {
// Third, the direction check.
if (!cancelled && direction.isEnabled(player))
cancelled = direction.check(player, block.getLocation());
cancelled = direction.check(player, block.getLocation(), event.getBlockAgainst().getLocation());
// If one of the checks requested to cancel the event, do so.
if (cancelled)

View File

@ -41,8 +41,6 @@ public class Direction extends Check {
}
}
private final double OFFSET = 0.5D;
/**
* Checks a player.
*
@ -52,16 +50,44 @@ public class Direction extends Check {
* the location
* @return true, if successful
*/
public boolean check(final Player player, final Location location) {
public boolean check(final Player player, final Location placed, final Location against) {
final BlockPlaceConfig cc = BlockPlaceConfig.getConfig(player);
final BlockPlaceData data = BlockPlaceData.getData(player);
boolean cancel = false;
if (!CheckUtils.intersects(player, location, location.add(1D, 1D, 1D), OFFSET)) {
// 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.
double off = CheckUtils.directionCheck(player, against.getX() + 0.5D, against.getY() + 0.5D,
against.getZ() + 0.5D, 1D, 1D, 75);
// Now check if the player is looking at the block from the correct side.
double off2 = 0.0D;
// Find out against which face the player tried to build, and if he
// stood on the correct side of it
final Location eyes = player.getEyeLocation();
if (placed.getX() > against.getX())
off2 = against.getX() + 0.5D - eyes.getX();
else if (placed.getX() < against.getX())
off2 = -(against.getX() + 0.5D - eyes.getX());
else if (placed.getY() > against.getY())
off2 = against.getY() + 0.5D - eyes.getY();
else if (placed.getY() < against.getY())
off2 = -(against.getY() + 0.5D - eyes.getY());
else if (placed.getZ() > against.getZ())
off2 = against.getZ() + 0.5D - eyes.getZ();
else if (placed.getZ() < against.getZ())
off2 = -(against.getZ() + 0.5D - eyes.getZ());
// If he wasn't on the correct side, add that to the "off" value
if (off2 > 0.0D)
off += off2;
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 blockEyes = placed.add(0.5D, 0.5D, 0.5D).subtract(player.getEyeLocation()).toVector();
final double distance = blockEyes.crossProduct(direction).length() / direction.length();
// Add the overall violation level of the check.

View File

@ -9,6 +9,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerEvent;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.actions.types.ActionList;
import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckEvent;
import fr.neatmonster.nocheatplus.players.Permissions;
@ -268,6 +269,18 @@ public class NoPwnage extends Check {
return cancel;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#executeActions(org.bukkit.entity.Player, fr.neatmonster.nocheatplus.actions.types.ActionList, double)
*/
@Override
protected boolean executeActions(final Player player, final ActionList actionList, final double violationLevel) {
if (super.executeActions(player, actionList, violationLevel)) {
ChatData.getData(player).clearNoPwnageData();
return true;
}
return false;
}
/* (non-Javadoc)
* @see fr.neatmonster.nocheatplus.checks.Check#getParameter(fr.neatmonster.nocheatplus.actions.ParameterName, org.bukkit.entity.Player)
*/

View File

@ -66,6 +66,10 @@ public class Angle extends Check {
// Add the new location to the map.
data.angleHits.put(System.currentTimeMillis(), player.getLocation());
// Not enough data to calculate deltas.
if (data.angleHits.size() < 2)
return false;
// Declare variables.
double deltaMove = 0D;
long deltaTime = 0L;

View File

@ -1,6 +1,8 @@
package fr.neatmonster.nocheatplus.checks.fight;
import net.minecraft.server.Entity;
import net.minecraft.server.EntityComplex;
import net.minecraft.server.EntityComplexPart;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -43,8 +45,6 @@ public class Direction extends Check {
}
}
private final double OFFSET = 0.5D;
/**
* Checks a player.
*
@ -60,14 +60,26 @@ public class Direction extends Check {
boolean cancel = false;
final Location minimum = new Location(player.getWorld(), damaged.boundingBox.a, damaged.boundingBox.b,
damaged.boundingBox.c);
final Location maximum = new Location(player.getWorld(), damaged.boundingBox.d, damaged.boundingBox.e,
damaged.boundingBox.f);
if (!CheckUtils.intersects(player, minimum, maximum, OFFSET)) {
// Safeguard, if entity is complex, this check will fail due to giant and hard to define hitboxes.
if (damaged instanceof EntityComplex || damaged instanceof EntityComplexPart)
return false;
// Find out how wide the entity is.
final float width = damaged.length > damaged.width ? damaged.length : damaged.width;
// entity.height is broken and will always be 0, therefore. Calculate height instead based on boundingBox.
final double height = damaged.boundingBox.e - damaged.boundingBox.b;
// 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 entity. If the line of sight is more too far off, "off" will be bigger than 0.
final double off = CheckUtils.directionCheck(player, damaged.locX, damaged.locY + height / 2D, damaged.locZ,
width, height, 75);
if (off > 0.1) {
// Player failed the check. Let's try to guess how far he was from looking directly to the entity...
final Vector direction = player.getEyeLocation().getDirection();
final Vector blockEyes = minimum.add(maximum).multiply(0.5D).subtract(player.getEyeLocation()).toVector();
final Vector blockEyes = new Location(player.getWorld(), damaged.locX, damaged.locY + height / 2D,
damaged.locZ).subtract(player.getEyeLocation()).toVector();
final double distance = blockEyes.crossProduct(direction).length() / direction.length();
// Add the overall violation level of the check.

View File

@ -63,7 +63,7 @@ public class FightData {
public long godModeLastTime;
// Data of the instant heal check.
public int instantHealBuffer;
public long instantHealBuffer;
public long instantHealLastTime;
// Data of the knockback check.

View File

@ -65,7 +65,7 @@ public class InstantHeal extends Check {
data.instantHealVL -= data.instantHealBuffer / 1000D;
// Reset the buffer.
data.instantHealBuffer = 0;
data.instantHealBuffer = 0L;
// Dispatch an instant heal event (API).
final InstantHealEvent e = new InstantHealEvent(player);
@ -79,8 +79,8 @@ public class InstantHeal extends Check {
data.instantHealVL *= 0.9D;
// Buffer can't be bigger than 2 seconds.
if (data.instantHealBuffer > 2000)
data.instantHealBuffer = 2000;
if (data.instantHealBuffer > 2000L)
data.instantHealBuffer = 2000L;
if (!cancel)
// New reference time.

View File

@ -75,7 +75,7 @@ public class NoFall extends Check {
if (cc.noFallAggressive && (from.isInLiquid() || from.isOnGround() || from.isOnLadder())
&& (to.isInLiquid() || to.isOnGround() || to.isOnLadder()) && from.getY() <= to.getY()
&& player.getFallDistance() > 3F) {
Bukkit.broadcastMessage(ChatColor.RED + "Problem with the no fall check!"); // TODO
// Bukkit.broadcastMessage(ChatColor.RED + "Problem with the no fall check!"); // TODO
data.noFallDistance = player.getFallDistance();

View File

@ -6,7 +6,6 @@ import net.minecraft.server.EntityPlayer;
import net.minecraft.server.MobEffectList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
@ -282,7 +281,8 @@ public class SurvivalFly extends Check {
// Did the player move in unexpected ways?
if (result > 0D) {
Bukkit.broadcastMessage(ChatColor.RED + player.getName() + ": problem with the survival fly check!"); // TODO
// Bukkit.broadcastMessage(ChatColor.RED + player.getName() + ": problem with the survival fly check!"); //
// TODO
// Increment violation counter.
data.survivalFlyVL += result;

View File

@ -9,6 +9,57 @@ import org.bukkit.util.Vector;
*/
public class CheckUtils {
/**
* Check if a player looks at a target of a specific size, with a specific precision value (roughly).
*
* @param player
* the player
* @param targetX
* the target x
* @param targetY
* the target y
* @param targetZ
* the target z
* @param targetWidth
* the target width
* @param targetHeight
* the target height
* @param precision
* the precision
* @return the double
*/
public static double directionCheck(final Player player, final double targetX, final double targetY,
final double targetZ, final double targetWidth, final double targetHeight, final double precision) {
// Get the eye location of the player.
final Location eyes = player.getEyeLocation();
final double factor = Math.sqrt(Math.pow(eyes.getX() - targetX, 2) + Math.pow(eyes.getY() - targetY, 2)
+ Math.pow(eyes.getZ() - targetZ, 2));
// Get the view direction of the player.
final Vector direction = eyes.getDirection();
final double x = targetX - eyes.getX();
final double y = targetY - eyes.getY();
final double z = targetZ - eyes.getZ();
final double xPrediction = factor * direction.getX();
final double yPrediction = factor * direction.getY();
final double zPrediction = factor * direction.getZ();
double off = 0.0D;
off += Math.max(Math.abs(x - xPrediction) - (targetWidth / 2 + precision), 0.0D);
off += Math.max(Math.abs(z - zPrediction) - (targetWidth / 2 + precision), 0.0D);
off += Math.max(Math.abs(y - yPrediction) - (targetHeight / 2 + precision), 0.0D);
if (off > 1)
off = Math.sqrt(off);
return off;
}
/**
* Calculates the distance between the player and the intersection of the player's line of sight with the targeted
* block.
@ -36,98 +87,6 @@ public class CheckUtils {
return min;
}
/**
* Check if the location is in the line of sight of the player.
*
* @param player
* the player
* @param minimum
* the minimum location
* @param maximum
* the maximum location
* @param offset
* the offset
* @return true, if successful
*/
public static boolean intersects(final Player player, final Location minimum, final Location maximum,
final double offset) {
final double x1 = minimum.getX() - offset;
final double y1 = minimum.getY() - offset;
final double z1 = minimum.getZ() - offset;
final double xH = maximum.getX() + offset;
final double yH = maximum.getY() + offset;
final double zH = maximum.getZ() + offset;
final double x0 = player.getEyeLocation().getX();
final double y0 = player.getEyeLocation().getY();
final double z0 = player.getEyeLocation().getZ();
final double xD = player.getEyeLocation().getDirection().getX();
final double yD = player.getEyeLocation().getDirection().getY();
final double zD = player.getEyeLocation().getDirection().getZ();
double tNear = Double.NEGATIVE_INFINITY;
double tFar = Double.POSITIVE_INFINITY;
if (xD == 0D) {
if (x0 < x1 || x0 > xH)
return false;
} else {
double t1 = (x1 - x0) / xD;
double t2 = (xH - x0) / xD;
if (t1 > t2) {
final double tTemp = t1;
t1 = t2;
t2 = tTemp;
}
if (t1 > tNear)
tNear = t1;
if (t2 < tFar)
tFar = t2;
if (tNear > tFar)
return false;
if (tFar < 0D)
return false;
}
if (yD == 0D) {
if (y0 < y1 || y0 > yH)
return false;
} else {
double t1 = (y1 - y0) / yD;
double t2 = (yH - y0) / yD;
if (t1 > t2) {
final double tTemp = t1;
t1 = t2;
t2 = tTemp;
}
if (t1 > tNear)
tNear = t1;
if (t2 < tFar)
tFar = t2;
if (tNear > tFar)
return false;
if (tFar < 0D)
return false;
}
if (zD == 0D) {
if (z0 < z1 || z0 > zH)
return false;
} else {
double t1 = (z1 - z0) / zD;
double t2 = (zH - z0) / zD;
if (t1 > t2) {
final double tTemp = t1;
t1 = t2;
t2 = tTemp;
}
if (t1 > tNear)
tNear = t1;
if (t2 < tFar)
tFar = t2;
if (tNear > tFar)
return false;
if (tFar < 0D)
return false;
}
return true;
}
/**
* Return if the two Strings are similar based on the given threshold.
*