[BLEEDING] Add simple hover check.

This commit is contained in:
asofold 2013-01-14 18:49:49 +01:00
parent 91420f9edf
commit 9850a0e3bb
6 changed files with 183 additions and 5 deletions

View File

@ -99,6 +99,11 @@ public class MovingConfig extends ACheckConfig {
public final long survivalFlyVLFreeze;
public final ActionList survivalFlyActions;
public final boolean sfHoverCheck;
public final int sfHoverTicks;
public final boolean sfHoverFallDamage;
public final double sfHoverViolation;
// Special tolerance values:
public final double noFallyOnGround;
public final double yOnGround;
@ -151,6 +156,11 @@ public class MovingConfig extends ACheckConfig {
survivalFlyVLFreeze = data.getLong(ConfPaths.MOVING_SURVIVALFLY_VLFREEZE, 2000L);
survivalFlyActions = data.getOptimizedActionList(ConfPaths.MOVING_SURVIVALFLY_ACTIONS, Permissions.MOVING_SURVIVALFLY);
sfHoverCheck = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_HOVER_CHECK);
sfHoverTicks = data.getInt(ConfPaths.MOVING_SURVIVALFLY_HOVER_TICKS);
sfHoverFallDamage = data.getBoolean(ConfPaths.MOVING_SURVIVALFLY_HOVER_FALLDAMAGE);
sfHoverViolation = data.getDouble(ConfPaths.MOVING_SURVIVALFLY_HOVER_SFVIOLATION);
yOnGround = data.getDouble(ConfPaths.MOVING_YONGROUND, 0.001, 2.0, 0.0626); // sqrt(1/256), see: NetServerHandler.
noFallyOnGround = data.getDouble(ConfPaths.MOVING_NOFALL_YONGROUND, 0.001, 2.0, 0.3);
// ystep is set to 0.45 by default, for stairs / steps.

View File

@ -127,6 +127,8 @@ public class MovingData extends ACheckData {
* Last valid y distance covered by a move. Integer.MAX_VALUE indicates "not set".
*/
public double sfLastYDist = Double.MAX_VALUE;
/** A value <0 means not hovering at all. */
public int sfHoverTicks = -1;
public int sfFlyOnIce;
public long sfCobwebTime;
public double sfCobwebVL;
@ -157,6 +159,7 @@ public class MovingData extends ACheckData {
clearNoFallData();
sfHorizontalBuffer = 0;
toWasReset = fromWasReset = false; // TODO: true maybe
sfHoverTicks = -1;
}
/**
@ -182,6 +185,7 @@ public class MovingData extends ACheckData {
// keep jump phase.
sfHorizontalBuffer = Math.min(0, sfHorizontalBuffer);
toWasReset = fromWasReset = false; // TODO: true maybe
sfHoverTicks = -1;
}
/**

View File

@ -2,13 +2,16 @@ package fr.neatmonster.nocheatplus.checks.moving;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
@ -42,6 +45,10 @@ import fr.neatmonster.nocheatplus.checks.combined.BedLeave;
import fr.neatmonster.nocheatplus.checks.combined.Combined;
import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.components.IData;
import fr.neatmonster.nocheatplus.components.IHaveCheckType;
import fr.neatmonster.nocheatplus.components.IRemoveData;
import fr.neatmonster.nocheatplus.components.TickListener;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.BlockCache;
@ -73,7 +80,7 @@ import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
*
* @see MovingEvent
*/
public class MovingListener extends CheckListener{
public class MovingListener extends CheckListener implements TickListener, IRemoveData, IHaveCheckType{
private static final class MoveInfo{
public final BlockCache cache;
@ -144,6 +151,8 @@ public class MovingListener extends CheckListener{
*/
private final Map<String, PlayerMoveEvent> processingEvents = new HashMap<String, PlayerMoveEvent>();
private final Set<String> hoverTicks = new LinkedHashSet<String>(30);
public MovingListener() {
super(CheckType.MOVING);
}
@ -351,7 +360,8 @@ public class MovingListener extends CheckListener{
final Player player = event.getPlayer();
// Store the event for monitor level checks.
processingEvents.put(player.getName(), event);
final String playerName = player.getName();
processingEvents.put(playerName, event);
// Ignore players in vehicles.
if (player.isInsideVehicle()) return;
@ -445,6 +455,16 @@ public class MovingListener extends CheckListener{
&& cc.survivalFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_SURVIVALFLY) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY)){
// If he is handled by the survival fly check, execute it.
newTo = survivalFly.check(player, pFrom, pTo, data, cc);
if (newTo == null){
if (cc.sfHoverCheck && !data.toWasReset && !pTo.isOnGround()){
// Start counting ticks.
hoverTicks.add(playerName);
data.sfHoverTicks = 0;
}
else{
data.sfHoverTicks = -1;
}
}
// Check NoFall if no reset is done.
if (cc.noFallCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_NOFALL) && !player.hasPermission(Permissions.MOVING_NOFALL)) {
if (passableTo != null){
@ -466,10 +486,15 @@ public class MovingListener extends CheckListener{
else if (cc.creativeFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_CREATIVEFLY)){
// If the player is handled by the creative fly check, execute it.
newTo = creativeFly.check(player, pFrom, pTo, data, cc);
data.sfHoverTicks = -1;
}
else{
data.clearFlyData();
}
else data.clearFlyData();
}
else data.clearFlyData();
else{
data.clearFlyData();
}
if (newTo == null && cc.morePacketsCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_MOREPACKETS) && !player.hasPermission(Permissions.MOVING_MOREPACKETS)) {
// If he hasn't been stopped by any other check and is handled by the more packets check, execute it.
@ -751,6 +776,7 @@ public class MovingListener extends CheckListener{
Combined.resetYawRate(player, ref.getYaw(), System.currentTimeMillis(), true);
data.resetTeleported();
processingEvents.remove(player.getName());
hoverTicks.remove(player.getName());
}
/**
@ -924,6 +950,15 @@ public class MovingListener extends CheckListener{
// TODO: re-think: more fine grained reset?
data.resetPositions(loc);
}
// Reset hover ticks until a better method is used.
if (MovingConfig.getConfig(player).sfHoverCheck){
// Start as if hovering already.
data.sfHoverTicks = 0;
hoverTicks.add(player.getName());
}
else{
data.sfHoverTicks = -1;
}
}
@EventHandler(priority = EventPriority.MONITOR)
@ -975,4 +1010,85 @@ public class MovingListener extends CheckListener{
public void onPlayerToggleSneak(final PlayerToggleSneakEvent event){
survivalFly.setReallySneaking(event.getPlayer(), event.isSneaking());
}
@Override
public final void onTick(final int tick, final long timeLast) {
// Hover checks !
if (hoverTicks.isEmpty()) return; // Seldom or not ?
final Server server = Bukkit.getServer();
final MoveInfo info;
if (parkedInfo.isEmpty()) info = new MoveInfo(mcAccess);
else info = parkedInfo.remove(parkedInfo.size() - 1);
final List<String> rem = new ArrayList<String>(hoverTicks.size()); // Pessimistic.
for (final String playerName : hoverTicks){
final Player player = server.getPlayerExact(playerName);
if (player == null || !player.isOnline()){
rem.add(playerName);
continue;
}
final MovingData data = MovingData.getData(player);
if (data.sfHoverTicks < 0){
rem.add(playerName);
continue;
}
if (checkHover(player, data, info)){
rem.add(playerName);
}
}
parkedInfo.add(info);
hoverTicks.removeAll(rem);
rem.clear();
}
private final boolean checkHover(final Player player, final MovingData data, final MoveInfo info) {
final MovingConfig cc = MovingConfig.getConfig(player);
// Check if enabled at all.
if (!cc.sfHoverCheck) return true;
// Check if player is on ground.
final Location loc = player.getLocation();
info.set(player, loc, null, cc.yOnGround);
final boolean res;
if (info.from.isOnGround() || info.from.isResetCond() || info.from.isAboveLadder() || info.from.isAboveStairs()){
res = true;
}
else{
data.sfHoverTicks ++;
if (data.sfHoverTicks > cc.sfHoverTicks){
handleHoverViolation(player, loc, cc, data);
// Assume the player might still be hovering.
res = false;
data.sfHoverTicks = 0;
}
else res = false;
}
info.cleanup();
return res;
}
private final void handleHoverViolation(final Player player, final Location loc, final MovingConfig cc, final MovingData data) {
// Check nofall damage (!).
if (cc.sfHoverFallDamage && noFall.isEnabled(player)){
// Consider adding 3/3.5 to fall distance if fall distance > 0?
noFall.checkDamage(player, data, loc.getY());
}
// Delegate violation handling.
survivalFly.handleHoverViolation(player, loc, cc, data);
}
@Override
public CheckType getCheckType() {
// TODO: this is for the hover check only...
return CheckType.MOVING_SURVIVALFLY;
}
@Override
public IData removeData(String playerName) {
hoverTicks.remove(playerName);
return null;
}
@Override
public void removeAllData() {
hoverTicks.clear();
}
}

View File

@ -489,6 +489,40 @@ public class SurvivalFly extends Check {
return null;
}
}
protected final void handleHoverViolation(final Player player, final Location loc, final MovingConfig cc, final MovingData data) {
data.survivalFlyVL += cc.sfHoverViolation;
// TODO: Extra options for set-back / kick, like vl?
data.sfVLTime = System.currentTimeMillis();
final ViolationData vd = new ViolationData(this, player, data.survivalFlyVL, cc.sfHoverViolation, cc.survivalFlyActions);
if (vd.needsParameters()) {
vd.setParameter(ParameterName.LOCATION_FROM, String.format(Locale.US, "%.2f, %.2f, %.2f", loc.getX(), loc.getY(), loc.getZ()));
vd.setParameter(ParameterName.LOCATION_TO, "(HOVER)");
vd.setParameter(ParameterName.DISTANCE, "0.0(HOVER)");
vd.setParameter(ParameterName.TAGS, "hover");
}
if (executeActions(vd)) {
// Set-back or kick.
if (data.hasSetBack()){
data.clearAccounting();
data.sfJumpPhase = 0;
data.sfLastYDist = Double.MAX_VALUE;
data.toWasReset = false;
data.fromWasReset = false;
player.teleport(data.getSetBack(loc));
}
else{
// Solve by extra actions ? Special case (probably never happens)?
player.kickPlayer("Hovering?");
}
}
else{
// Ignore.
}
}
/**
* First split-off. Not strictly accounting only, actually.<br>

View File

@ -496,6 +496,12 @@ public abstract class ConfPaths {
public static final String MOVING_SURVIVALFLY_EXTENDED_VACC = MOVING_SURVIVALFLY_EXTENDED + "vertical-accounting";
public static final String MOVING_SURVIVALFLY_VLFREEZE = MOVING_SURVIVALFLY + "vlfreeze";
public static final String MOVING_SURVIVALFLY_ACTIONS = MOVING_SURVIVALFLY + "actions";
private static final String MOVING_SURVIVALFLY_HOVER = MOVING_SURVIVALFLY + "hover.";
public static final String MOVING_SURVIVALFLY_HOVER_CHECK = MOVING_SURVIVALFLY_HOVER + "active";
public static final String MOVING_SURVIVALFLY_HOVER_TICKS = MOVING_SURVIVALFLY_HOVER + "ticks";
public static final String MOVING_SURVIVALFLY_HOVER_FALLDAMAGE = MOVING_SURVIVALFLY_HOVER + "falldamage";
public static final String MOVING_SURVIVALFLY_HOVER_SFVIOLATION = MOVING_SURVIVALFLY_HOVER + "sfviolation";
// Special (to be sorted in or factored out).
public static final String MOVING_NOFALL_YONGROUND = MOVING_NOFALL + "yonground";

View File

@ -25,7 +25,9 @@ public class DefaultConfig extends ConfigFile {
* NCP build needed for this config.
* (Should only increment with changing or removing paths.)
*/
public static final int buildNumber = 314;
public static final int buildNumber = 315; // TODO: Check jenkins...
// TODO: auto input full version or null to an extra variable or several [fail safe for other syntax checking]?
/**
* Instantiates a new default configuration.
@ -387,6 +389,12 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MOVING_SURVIVALFLY_ACTIONS,
"log:flyshort:3:5:f cancel vl>100 log:flyshort:0:5:if cancel vl>400 log:flylong:0:5:cif cancel vl>1000 log:flylong:0:5:cif cancel cmd:kickfly");
// sf / hover check.
set(ConfPaths.MOVING_SURVIVALFLY_HOVER_CHECK, true);
set(ConfPaths.MOVING_SURVIVALFLY_HOVER_TICKS, 80);
set(ConfPaths.MOVING_SURVIVALFLY_HOVER_FALLDAMAGE, true);
set(ConfPaths.MOVING_SURVIVALFLY_HOVER_SFVIOLATION, 500);
/*
* dP"8 d8 ,e,
* C8b Y d88 888,8, " 888 8e e88 888 dP"Y