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.entity.Player;
import org.bukkit.util.Vector;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check;
@ -21,73 +20,69 @@ public class Passable extends Check {
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
{
// Simple check.
if (!to.isPassable()) {
Location loc = null; // players location if should be used.
// Allow moving into the same block.
if (from.isSameBlock(to)) {
if (!from.isPassable()) {
final double eyeY = to.getY() + player.getEyeHeight();
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)
// Simple check (only from, to, player.getLocation).
// 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
if (to.isPassable()){
// Quick return.
// (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...)
data.passableVL *= 0.99;
return null;
}
// else is passable: use the location instead of from.
// 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 (vd.needsParameters()) vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
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.
// 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;
}
else{
// No cancel action set.
return null;
}
}
@Override
protected Map<ParameterName, String> getParameterMap(final ViolationData violationData)