Bleeding: Sharpen NoFall.

New attempts to reduce fall damage by stopping in mid air and letting
MC deal fall damage (send ground), then regenerate health and/or fall
the last 3 blocks without damage are prevented by this (mostly).
Hopefully few to none false positives.
This commit is contained in:
asofold 2012-12-04 04:41:50 +01:00
parent 14b0700259
commit 2d1beaf3a9
6 changed files with 53 additions and 24 deletions

View File

@ -3,6 +3,7 @@ package fr.neatmonster.nocheatplus.checks.blockbreak;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.Check;
@ -98,9 +99,15 @@ public class FastBreak extends Check {
} }
// Send info about current break: // Send info about current break:
final int blockId = block.getTypeId(); final int blockId = block.getTypeId();
final boolean isValidTool = BlockProperties.isValidTool(blockId, player.getItemInHand()); final ItemStack stack = player.getItemInHand();
final boolean isValidTool = BlockProperties.isValidTool(blockId, stack);
String msg = (isInstaBreak ? "[Insta]" : "[Normal]") + "[" + blockId + "] "+ elapsedTime + "u / " + breakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")"; String msg = (isInstaBreak ? "[Insta]" : "[Normal]") + "[" + blockId + "] "+ elapsedTime + "u / " + breakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")";
player.sendMessage(msg); player.sendMessage(msg);
// net.minecraft.server.Item mcItem = net.minecraft.server.Item.byId[stack.getTypeId()];
// if (mcItem != null){
// double x = mcItem.getDestroySpeed(((CraftItemStack) stack).getHandle(), net.minecraft.server.Block.byId[blockId]);
// player.sendMessage("mc speed: " + x);
// }
} }
// (The break time is set in the listener). // (The break time is set in the listener).

View File

@ -80,7 +80,7 @@ public class MovingConfig extends ACheckConfig {
public final boolean noFallCheck; public final boolean noFallCheck;
public final boolean noFallDealDamage; public final boolean noFallDealDamage;
// public final ActionList noFallActions; public final ActionList noFallActions;
public final boolean passableCheck; public final boolean passableCheck;
public final ActionList passableActions; public final ActionList passableActions;
@ -130,7 +130,7 @@ public class MovingConfig extends ACheckConfig {
noFallCheck = data.getBoolean(ConfPaths.MOVING_NOFALL_CHECK); noFallCheck = data.getBoolean(ConfPaths.MOVING_NOFALL_CHECK);
noFallDealDamage = data.getBoolean(ConfPaths.MOVING_NOFALL_DEALDAMAGE); noFallDealDamage = data.getBoolean(ConfPaths.MOVING_NOFALL_DEALDAMAGE);
// noFallActions = data.getActionList(ConfPaths.MOVING_NOFALL_ACTIONS, Permissions.MOVING_NOFALL); noFallActions = data.getOptimizedActionList(ConfPaths.MOVING_NOFALL_ACTIONS, Permissions.MOVING_NOFALL);
passableCheck = data.getBoolean(ConfPaths.MOVING_PASSABLE_CHECK); passableCheck = data.getBoolean(ConfPaths.MOVING_PASSABLE_CHECK);
passableActions = data.getOptimizedActionList(ConfPaths.MOVING_PASSABLE_ACTIONS, Permissions.MOVING_PASSABLE); passableActions = data.getOptimizedActionList(ConfPaths.MOVING_PASSABLE_ACTIONS, Permissions.MOVING_PASSABLE);

View File

@ -113,7 +113,8 @@ public class MovingData extends ACheckData {
public double noFallMaxY; public double noFallMaxY;
/** Indicate that NoFall should assume the player to be on ground. */ /** Indicate that NoFall should assume the player to be on ground. */
public boolean noFallAssumeGround; public boolean noFallAssumeGround;
/** Indicate that NoFall is not to use next damage event for checking on-ground properties. */
public boolean noFallSkipAirCheck = false;
// Passable check. // Passable check.
public double passableVL; public double passableVL;
@ -201,6 +202,7 @@ public class MovingData extends ACheckData {
// noFallOnGround = noFallWasOnGround = true; // noFallOnGround = noFallWasOnGround = true;
noFallFallDistance = 0; noFallFallDistance = 0;
noFallMaxY = 0D; noFallMaxY = 0D;
noFallSkipAirCheck = false;
} }
public void resetPositions(final Location loc){ public void resetPositions(final Location loc){

View File

@ -31,6 +31,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerVelocityEvent; import org.bukkit.event.player.PlayerVelocityEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.vehicle.VehicleMoveEvent; import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -77,12 +78,21 @@ public class MovingListener extends CheckListener{
public final PlayerLocation from = new PlayerLocation(); public final PlayerLocation from = new PlayerLocation();
public final PlayerLocation to = new PlayerLocation(); public final PlayerLocation to = new PlayerLocation();
public final BlockCache cache = new BlockCache(); public final BlockCache cache = new BlockCache();
/**
* Demands at least setting from.
* @param player
* @param from
* @param to
* @param yOnGround
*/
public final void set(final Player player, final Location from, final Location to, final double yOnGround){ public final void set(final Player player, final Location from, final Location to, final double yOnGround){
this.from.set(from, player, yOnGround); this.from.set(from, player, yOnGround);
this.to.set(to, player, yOnGround);
this.cache.setAccess(this.from.getWorldServer()); this.cache.setAccess(this.from.getWorldServer());
this.from.setBlockCache(cache); this.from.setBlockCache(cache);
this.to.setBlockCache(cache); if (to != null){
this.to.set(to, player, yOnGround);
this.to.setBlockCache(cache);
}
} }
public final void cleanup(){ public final void cleanup(){
from.cleanup(); from.cleanup();
@ -237,7 +247,7 @@ public class MovingListener extends CheckListener{
} }
// Teleport. // Teleport.
data.teleported = target; data.teleported = target;
player.teleport(target);// TODO: schedule / other measures ? player.teleport(target, TeleportCause.PLUGIN);// TODO: schedule / other measures ?
} }
} }
} }
@ -751,7 +761,7 @@ public class MovingListener extends CheckListener{
@Override @Override
public void run() { public void run() {
vehicle.teleport(location); vehicle.teleport(location, TeleportCause.PLUGIN);
} }
public Runnable set(final Vehicle vehicle, final Location location) { public Runnable set(final Vehicle vehicle, final Location location) {
@ -774,9 +784,29 @@ public class MovingListener extends CheckListener{
data.clearNoFallData(); data.clearNoFallData();
return; return;
} }
final Location loc = player.getLocation();
boolean allowReset = true;
if (!data.noFallSkipAirCheck){
final MoveInfo moveInfo;
if (parkedInfo.isEmpty()) moveInfo = new MoveInfo();
else moveInfo = parkedInfo.remove(parkedInfo.size() - 1);
moveInfo.set(player, loc, null, cc.noFallyOnGround);
// NOTE: No isIllegal check here.
moveInfo.from.collectBlockFlags(cc.noFallyOnGround);
if (!moveInfo.from.isOnGround() && !moveInfo.from.isResetCond()){
// Likely a new style no-fall bypass (damage in mid-air).
data.noFallVL += 1.0;
if (noFall.executeActions(player, data.noFallVL, 1.0, cc.noFallActions, true) && data.setBack != null){
// Cancel the event and restore fall distance.
// NoFall data will not be reset
allowReset = false;
}
}
moveInfo.cleanup();
}
final float fallDistance = player.getFallDistance(); final float fallDistance = player.getFallDistance();
final int damage = event.getDamage(); final int damage = event.getDamage();
final float yDiff = (float) (data.noFallMaxY - player.getLocation().getY()); final float yDiff = (float) (data.noFallMaxY - loc.getY());
if (cc.debug) System.out.println(player.getName() + " damage(FALL): " + damage + " / dist=" + player.getFallDistance() + " nf=" + data.noFallFallDistance + " yDiff=" + yDiff); if (cc.debug) System.out.println(player.getName() + " damage(FALL): " + damage + " / dist=" + player.getFallDistance() + " nf=" + data.noFallFallDistance + " yDiff=" + yDiff);
// Fall-back check. // Fall-back check.
final int maxD = NoFall.getDamage(Math.max(yDiff, Math.max(data.noFallFallDistance, fallDistance))); final int maxD = NoFall.getDamage(Math.max(yDiff, Math.max(data.noFallFallDistance, fallDistance)));
@ -785,7 +815,7 @@ public class MovingListener extends CheckListener{
event.setDamage(maxD); event.setDamage(maxD);
if (cc.debug) System.out.println(player.getName() + " Adjust fall damage to: " + maxD); if (cc.debug) System.out.println(player.getName() + " Adjust fall damage to: " + maxD);
} }
data.clearNoFallData(); if (allowReset) data.clearNoFallData();
// Entity fall-distance should be reset elsewhere. // Entity fall-distance should be reset elsewhere.
} }

View File

@ -1,8 +1,5 @@
package fr.neatmonster.nocheatplus.checks.moving; package fr.neatmonster.nocheatplus.checks.moving;
import java.util.Locale;
import java.util.Map;
import net.minecraft.server.DamageSource; import net.minecraft.server.DamageSource;
import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityPlayer;
@ -12,10 +9,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import fr.neatmonster.nocheatplus.actions.ParameterName;
import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.Check;
import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.utilities.CheckUtils; import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation; import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
@ -65,6 +60,8 @@ public class NoFall extends Check {
// Damage to be dealt. // Damage to be dealt.
// TODO: more effects like sounds, maybe use custom event with violation added. // TODO: more effects like sounds, maybe use custom event with violation added.
if (cc.debug) System.out.println(mcPlayer.name + " NoFall deal damage" + (reallyOnGround ? "" : "violation") + ": " + maxD); if (cc.debug) System.out.println(mcPlayer.name + " NoFall deal damage" + (reallyOnGround ? "" : "violation") + ": " + maxD);
// TODO: might not be necessary: if (mcPlayer.invulnerableTicks <= 0) [no damage event for resetting]
data.noFallSkipAirCheck = true;
dealFallDamage(mcPlayer, maxD); dealFallDamage(mcPlayer, maxD);
} }
else data.clearNoFallData(); else data.clearNoFallData();
@ -189,13 +186,6 @@ public class NoFall extends Check {
} }
} }
@Override
protected Map<ParameterName, String> getParameterMap(final ViolationData violationData) {
final Map<ParameterName, String> parameters = super.getParameterMap(violationData);
parameters.put(ParameterName.FALL_DISTANCE, String.format(Locale.US, "%.2f", MovingData.getData(violationData.player).noFallFallDistance));
return parameters;
}
/** /**
* This is called if a player fails a check and gets set back, to avoid using that to avoid fall damage the player might be dealt damage here. * This is called if a player fails a check and gets set back, to avoid using that to avoid fall damage the player might be dealt damage here.
* @param player * @param player

View File

@ -364,7 +364,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MOVING_NOFALL_CHECK, true); set(ConfPaths.MOVING_NOFALL_CHECK, true);
set(ConfPaths.MOVING_NOFALL_DEALDAMAGE, true); set(ConfPaths.MOVING_NOFALL_DEALDAMAGE, true);
// set(ConfPaths.MOVING_NOFALL_ACTIONS, "cancel vl>0 log:nofall:0:5:if cancel vl>6 log:nofall:0:5:icf cancel"); set(ConfPaths.MOVING_NOFALL_ACTIONS, "log:nofall:0:5:if cancel vl>30 log:nofall:0:5:icf cancel");
set(ConfPaths.MOVING_PASSABLE_CHECK, true); set(ConfPaths.MOVING_PASSABLE_CHECK, true);
set(ConfPaths.MOVING_PASSABLE_ACTIONS, "cancel vl>10 log:passable:0:5:if cancel vl>50 log:passable:0:5:icf cancel"); set(ConfPaths.MOVING_PASSABLE_ACTIONS, "cancel vl>10 log:passable:0:5:if cancel vl>50 log:passable:0:5:icf cancel");
@ -442,7 +442,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.STRINGS + ".kickwb", "ncp kick [player] Block breaking out of sync!"); set(ConfPaths.STRINGS + ".kickwb", "ncp kick [player] Block breaking out of sync!");
set(ConfPaths.STRINGS + ".knockback", start + "tried to do a knockback but wasn't technically sprinting" + end); set(ConfPaths.STRINGS + ".knockback", start + "tried to do a knockback but wasn't technically sprinting" + end);
set(ConfPaths.STRINGS + ".morepackets", start + "sent [packets] more packet(s) than expected" + end); set(ConfPaths.STRINGS + ".morepackets", start + "sent [packets] more packet(s) than expected" + end);
set(ConfPaths.STRINGS + ".nofall", start + "tried to avoid fall damage for ~[falldistance] block(s)" + end); set(ConfPaths.STRINGS + ".nofall", start + "tried to avoid fall damage" + end);
set(ConfPaths.STRINGS + ".chatfast", start + "acted like spamming (IP: [ip])" + end); set(ConfPaths.STRINGS + ".chatfast", start + "acted like spamming (IP: [ip])" + end);
set(ConfPaths.STRINGS + ".noswing", start + "didn't swing arm" + end); set(ConfPaths.STRINGS + ".noswing", start + "didn't swing arm" + end);
set(ConfPaths.STRINGS + ".passable", start + "moved into a block ([blockid])" + end); set(ConfPaths.STRINGS + ".passable", start + "moved into a block ([blockid])" + end);