Revised passable, corrected + simplified.

Hopefully :) [missing: survivalfly does not estimate a player to be on
ground if fully stuck]
This commit is contained in:
asofold 2012-11-25 23:25:51 +01:00
parent d5136dc788
commit ba1954025d

View File

@ -4,7 +4,6 @@ import java.util.Map;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.Check;
@ -21,72 +20,68 @@ public class Passable extends Check {
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
{ {
// Simple check. // Simple check (only from, to, player.getLocation).
if (!to.isPassable()) {
Location loc = null; // players location if should be used. // TODO: account for actual bounding box.
// Allow moving into the same block.
if (from.isSameBlock(to)) { if (to.isPassable()){
if (!from.isPassable()) { // Quick return.
final double eyeY = to.getY() + player.getEyeHeight(); // (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...)
final int eyeBlockY = Location.locToBlock(eyeY);
if (eyeBlockY != to.getBlockY()) {
if (BlockProperties.isPassable(to.getBlockAccess(), to.getX(), eyeY, to.getZ(), to.getTypeId(to.getBlockX(), eyeBlockY, to.getBlockZ()))) {
// Allow moving inside the same block if head is
// free.
return null;
}
}
// Only allow moving further out of the block (still allows
// going round in circles :p)
// TODO: account for actual bounding box.
final Vector blockMiddle = new Vector(0.5 + from.getBlockX(), 0.5 + from.getBlockY(), 0.5 + from.getBlockZ());
// TODO: Allow moving out of one block towards non-solid
// blocks (closest only ?).
// TODO: Allow moving out of half steps ?
// TODO: Allow moving towards non solid blocks.
if (blockMiddle.distanceSquared(from.getVector()) < blockMiddle.distanceSquared(to.getVector())) {
// Further check for the players location as possible
// set back.
loc = player.getLocation();
if (to.isSamePos(loc)) {
loc = null;
} else if (!BlockProperties.isPassable(from.getBlockAccess(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()))) {
// Allow the move
return null;
}
// else is passable: use the location instead of from.
}
}
}
// Prefer the set-back location from the data.
if (data.setBack != null && BlockProperties.isPassable(from.getBlockAccess(), data.setBack)) loc = data.setBack;
// Return the reset position.
data.passableVL += 1d;
final ViolationData vd = new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
if (vd.needsParameters()) vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
if (executeActions(vd)) {
// TODO: Consider another set back position for this, also
// keeping track of players moving around in blocks.
final Location newTo;
if (loc == null && !from.isPassable()) {
// Check if passable.
loc = player.getLocation();
if (to.isSamePos(loc) || !BlockProperties.isPassable(from.getBlockAccess(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(from.getBlockX(), from.getBlockY(), from.getBlockZ()))) {
loc = null;
}
}
if (loc != null) newTo = loc;
else newTo = from.getLocation();
newTo.setYaw(to.getYaw());
newTo.setPitch(to.getPitch());
return newTo;
}
} else {
data.passableVL *= 0.99; data.passableVL *= 0.99;
return null;
}
// Moving into a block, possibly a violation.
// Check the players location if different from others.
// (It provides a better set-back for some exploits.)
Location loc = player.getLocation();
final int lbX = loc.getBlockX();
final int lbY = loc.getBlockY();
final int lbZ = loc.getBlockZ();
// First check if the player is moving from a passable location.
// If not, the move might still be allowed, if moving inside of the same block, or from and to have head position passable.
if (from.isPassable()){
// From should be the set-back.
loc = null;
} else if (BlockProperties.isPassable(from.getBlockAccess(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))){
// (Mind that this can be the case on the same block theoretically.)
// Keep loc as set-back.
}
else if (!from.isSameBlock(lbX, lbY, lbZ)){
// Otherwise keep loc as set-back.
}
else if (!from.isSameBlock(to)){
// Otherwise keep from as set-back.
loc = null;
}
else{
// All blocks are the same, allow the move.
return null;
}
// Prefer the set-back location from the data.
if (data.setBack != null && BlockProperties.isPassable(from.getBlockAccess(), data.setBack)) loc = data.setBack;
// TODO: set data.set-back ? or something: still some aji here.
// Return the reset position.
data.passableVL += 1d;
final ViolationData vd = new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
if (cc.debug || vd.needsParameters()) vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
if (executeActions(vd)) {
// TODO: Consider another set back position for this, also keeping track of players moving around in blocks.
final Location newTo;
if (loc != null) newTo = loc;
else newTo = from.getLocation();
newTo.setYaw(to.getYaw());
newTo.setPitch(to.getPitch());
return newTo;
}
else{
// No cancel action set.
return null;
} }
return null;
} }
@Override @Override