From 7b51b1ae43547167c4f6b7eae0787b271a509c30 Mon Sep 17 00:00:00 2001 From: asofold Date: Fri, 5 Dec 2014 11:47:34 +0100 Subject: [PATCH] Add depth strider support. --- NCPCore/pom.xml | 2 +- .../checks/moving/SurvivalFly.java | 35 +- .../nocheatplus/compat/BridgeEnchant.java | 32 ++ .../nocheatplus/logging/DebugUtil.java | 476 +++++++++--------- 4 files changed, 298 insertions(+), 247 deletions(-) create mode 100644 NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeEnchant.java diff --git a/NCPCore/pom.xml b/NCPCore/pom.xml index ea491af8..c0ed3f66 100644 --- a/NCPCore/pom.xml +++ b/NCPCore/pom.xml @@ -17,7 +17,7 @@ org.bukkit bukkit - 1.7.9-R0.2 + 1.8-R0.1-SNAPSHOT fr.neatmonster diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java index 42afb1ba..49324b21 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java @@ -14,6 +14,7 @@ import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.ViolationData; +import fr.neatmonster.nocheatplus.compat.BridgeEnchant; import fr.neatmonster.nocheatplus.logging.Streams; import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.utilities.ActionAccumulator; @@ -33,18 +34,24 @@ public class SurvivalFly extends Check { // Tags private static final String DOUBLE_BUNNY = "doublebunny"; - // Horizontal speeds/modifiers. - public static final double walkSpeed = 0.221D; + // Horizontal speeds/modifiers/factors (modifier: speed = walkspeed * modX, factors: speed *= fY). + public static final double walkSpeed = 0.221D; - public static final double modSneak = 0.13D / walkSpeed; - public static final double modSprint = 0.29D / walkSpeed; // TODO: without bunny 0.29 / practical is 0.35 + public static final double modSneak = 0.13D / walkSpeed; + public static final double modSprint = 0.29D / walkSpeed; // TODO: without bunny 0.29 / practical is 0.35 - public static final double modBlock = 0.16D / walkSpeed; - public static final double modSwim = 0.115D / walkSpeed; + public static final double modBlock = 0.16D / walkSpeed; + public static final double modSwim = 0.115D / walkSpeed; + public static final double[] fDepthStrider = new double[] { + 1.0, + 0.1645 / modSwim / walkSpeed, + 0.1995 / modSwim / walkSpeed, + 1.0 / modSwim, // Results in walkspeed. + }; - public static final double modWeb = 0.105D / walkSpeed; // TODO: walkingSpeed * 0.15D; <- does not work + public static final double modWeb = 0.105D / walkSpeed; // TODO: walkingSpeed * 0.15D; <- does not work - public static final double modIce = 2.5D; + public static final double fIce = 2.5D; // /** Faster moving down stream (water mainly). */ public static final double modDownStream = 0.19 / (walkSpeed * modSwim); @@ -519,10 +526,14 @@ public class SurvivalFly extends Check { hAllowedDistance = modWeb * walkSpeed * cc.survivalFlyWalkingSpeed / 100D; } else if (from.isInLiquid() && to.isInLiquid()) { // Check all liquids (lava might demand even slower speed though). - // TODO: too many false positives with just checking from ? + // TODO: Test how to go with only checking from (less dolphins). // TODO: Sneaking and blocking applies to when in water ! hAllowedDistance = modSwim * walkSpeed * cc.survivalFlySwimmingSpeed / 100D; - // TODO: Depth strider. + final int level = BridgeEnchant.getDepthStriderLevel(player); + if (level > 0) { + // The hard way. + hAllowedDistance *= fDepthStrider[level]; + } } else if (!sfDirty && player.isSneaking() && reallySneaking.contains(player.getName()) && (!checkPermissions || !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SNEAKING))) { hAllowedDistance = modSneak * walkSpeed * cc.survivalFlySneakingSpeed / 100D; } @@ -556,9 +567,9 @@ public class SurvivalFly extends Check { // If the player is on ice, give them a higher maximum speed. if (data.sfOnIce > 0) { - hAllowedDistance *= modIce; + hAllowedDistance *= fIce; } - + // TODO: Attributes // Speed amplifier. diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeEnchant.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeEnchant.java new file mode 100644 index 00000000..596f964f --- /dev/null +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeEnchant.java @@ -0,0 +1,32 @@ +package fr.neatmonster.nocheatplus.compat; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public final class BridgeEnchant { + + private static Enchantment DEPTH_STRIDER = null; + + static { + try { + DEPTH_STRIDER = Enchantment.DEPTH_STRIDER; + } catch (Throwable t) {} + } + + public static int getDepthStriderLevel(Player player) { + if (DEPTH_STRIDER != null) { + final ItemStack boots = player.getInventory().getBoots(); + if (boots != null && boots.getType() != Material.AIR) { + return Math.min(3, boots.getEnchantmentLevel(BridgeEnchant.DEPTH_STRIDER)); + } + } + return 0; + } + + public static boolean hasDepthStrider() { + return DEPTH_STRIDER != null; + } + +} diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/DebugUtil.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/DebugUtil.java index 2e3a7e5d..3ad43b84 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/DebugUtil.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/DebugUtil.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import org.bukkit.util.Vector; import fr.neatmonster.nocheatplus.NCPAPIProvider; +import fr.neatmonster.nocheatplus.compat.BridgeEnchant; import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.utilities.BlockProperties; import fr.neatmonster.nocheatplus.utilities.PlayerLocation; @@ -20,9 +21,9 @@ import fr.neatmonster.nocheatplus.utilities.build.BuildParameters; * */ public class DebugUtil { - - // TODO: Add useLoc1 and useLoc2. - + + // TODO: Add useLoc1 and useLoc2. + /** * Just the coordinates. * @param loc @@ -33,7 +34,7 @@ public class DebugUtil { addLocation(loc, b); return b.toString(); } - + /** * Just the coordinates. * @param from @@ -45,241 +46,248 @@ public class DebugUtil { DebugUtil.addMove(from, to, null, builder); return builder.toString(); } - - public static boolean isSamePos(final double x1, final double y1, final double z1, final double x2, final double y2, final double z2){ - return x1 == x2 && y1 == y2 && z1 == z2; - } - - public static boolean isSamePos(final Location loc1, final Location loc2){ - return isSamePos(loc1.getX(), loc1.getY(), loc1.getZ(), loc2.getX(), loc2.getY(), loc2.getZ()); - } - - public static void addLocation(final double x, final double y, final double z, final StringBuilder builder){ - builder.append(x + ", " + y + ", " + z); - } - - public static void addLocation(final Location loc, final StringBuilder builder){ - addLocation(loc.getX(), loc.getY(), loc.getZ(), builder); - } - - public static void addLocation(final PlayerLocation loc, final StringBuilder builder){ - addLocation(loc.getX(), loc.getY(), loc.getZ(), builder); - } - - public static void addFormattedLocation(final double x, final double y, final double z, final StringBuilder builder){ - builder.append(StringUtil.fdec3.format(x) + ", " + StringUtil.fdec3.format(y) + ", " + StringUtil.fdec3.format(z)); - } - - public static void addFormattedLocation(final Location loc, final StringBuilder builder){ - addFormattedLocation(loc.getX(), loc.getY(), loc.getZ(), builder); - } - - public static void addFormattedLocation(final PlayerLocation loc, final StringBuilder builder){ - addFormattedLocation(loc.getX(), loc.getY(), loc.getZ(), builder); - } - - /** - * With line break between from and to. - * @param fromX - * @param fromY - * @param fromZ - * @param toX - * @param toY - * @param toZ - * @param builder - */ - public static void addMove(final double fromX, final double fromY, final double fromZ, final double toX, final double toY, final double toZ, final StringBuilder builder){ - builder.append("from: "); - addLocation(fromX, fromY, fromZ, builder); - builder.append("\nto: "); - addLocation(toX, toY, toZ, builder); - } - - /** - * No line breaks, max. 3 digits after comma. - * @param fromX - * @param fromY - * @param fromZ - * @param toX - * @param toY - * @param toZ - * @param builder - */ - public static void addFormattedMove(final double fromX, final double fromY, final double fromZ, final double toX, final double toY, final double toZ, final StringBuilder builder){ - addFormattedLocation(fromX, fromY, fromZ, builder); - builder.append(" -> "); - addFormattedLocation(toX, toY, toZ, builder); - } + public static boolean isSamePos(final double x1, final double y1, final double z1, final double x2, final double y2, final double z2){ + return x1 == x2 && y1 == y2 && z1 == z2; + } - /** - * 3 decimal digits after comma (StringUtil.fdec3). No leading new line. - * @param from - * @param to - * @param loc Reference location for from, usually Player.getLocation(). May be null. - * @param builder - * @return - */ - public static void addFormattedMove(final PlayerLocation from, final PlayerLocation to, final Location loc, final StringBuilder builder){ - if (loc != null && !from.isSamePos(loc)){ - builder.append("("); - addFormattedLocation(loc, builder); - builder.append(") "); - } - addFormattedMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); - } - - /** - * Add exact coordinates, multiple lines. No leading new line. - * @param from - * @param to - * @param loc Reference location for from, usually Player.getLocation(). - * @param builder - */ - public static void addMove(final PlayerLocation from, final PlayerLocation to, final Location loc, final StringBuilder builder){ - if (loc != null && !from.isSamePos(loc)){ - builder.append("Location: "); - addLocation(loc, builder); - builder.append("\n"); - } - addMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); - } - - /** - * 3 decimal digits after comma (StringUtil.fdec3). No leading new line. - * @param from - * @param to - * @param loc Reference location for from, usually Player.getLocation(). - * @param builder - * @return - */ - public static void addFormattedMove(final Location from, final Location to, final Location loc, final StringBuilder builder){ - if (loc != null && !isSamePos(from, loc)){ - builder.append("("); - addFormattedLocation(loc, builder); - builder.append(") "); - } - addFormattedMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); } - - /** - * Add exact coordinates, multiple lines. No leading new line. - * @param from - * @param to - * @param loc Reference location for from, usually Player.getLocation(). - * @param builder - */ - public static void addMove(final Location from, final Location to, final Location loc, final StringBuilder builder){ - if (loc != null && !isSamePos(from, loc)){ - builder.append("Location: "); - addLocation(loc, builder); - builder.append("\n"); - } - addMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); - } + public static boolean isSamePos(final Location loc1, final Location loc2){ + return isSamePos(loc1.getX(), loc1.getY(), loc1.getZ(), loc2.getX(), loc2.getY(), loc2.getZ()); + } - /** - * Output information specific to player-move events. - * @param player - * @param from - * @param to - * @param mcAccess - */ - public static void outputMoveDebug(final Player player, final PlayerLocation from, final PlayerLocation to, final double maxYOnGround, final MCAccess mcAccess) { - final StringBuilder builder = new StringBuilder(250); - final Location loc = player.getLocation(); - // TODO: Differentiate debug levels (needs setting up some policy + document in BuildParamteres)? - if (BuildParameters.debugLevel > 0) { - builder.append("\n-------------- MOVE --------------\n"); - builder.append(player.getName() + " " + from.getWorld().getName() + ":\n"); - addMove(from, to, loc, builder); - } - else { - builder.append(player.getName() + " " + from.getWorld().getName() + " "); - addFormattedMove(from, to, loc, builder); - } - final double jump = mcAccess.getJumpAmplifier(player); - final double speed = mcAccess.getFasterMovementAmplifier(player); - if (BuildParameters.debugLevel > 0){ - try{ - // TODO: Check backwards compatibility (1.4.2). Remove try-catch - builder.append("\n(walkspeed=" + player.getWalkSpeed() + " flyspeed=" + player.getFlySpeed() + ")"); - } catch (Throwable t){} - final Vector v = player.getVelocity(); - builder.append("(svel=" + v.getX() + "," + v.getY() + "," + v.getZ() + ")"); - if (player.isSprinting()){ - builder.append("(sprinting)"); - } - if (player.isSneaking()){ - builder.append("(sneaking)"); - } - } - if (speed != Double.NEGATIVE_INFINITY || jump != Double.NEGATIVE_INFINITY){ - builder.append(" (" + (speed != Double.NEGATIVE_INFINITY ? ("e_speed=" + (speed + 1)) : "") + (jump != Double.NEGATIVE_INFINITY ? ("e_jump=" + (jump + 1)) : "") + ")"); - } - // Print basic info first in order - NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString()); - // Extended info. - if (BuildParameters.debugLevel > 0){ - builder.setLength(0); - // Note: the block flags are for normal on-ground checking, not with yOnGrond set to 0.5. - from.collectBlockFlags(maxYOnGround); - if (from.getBlockFlags() != 0) builder.append("\nfrom flags: " + StringUtil.join(BlockProperties.getFlagNames(from.getBlockFlags()), "+")); - if (from.getTypeId() != 0) addBlockInfo(builder, from, "\nfrom"); - if (from.getTypeIdBelow() != 0) addBlockBelowInfo(builder, from, "\nfrom"); - if (!from.isOnGround() && from.isOnGround(0.5)) builder.append(" (ground within 0.5)"); - to.collectBlockFlags(maxYOnGround); - if (to.getBlockFlags() != 0) builder.append("\nto flags: " + StringUtil.join(BlockProperties.getFlagNames(to.getBlockFlags()), "+")); - if (to.getTypeId() != 0) addBlockInfo(builder, to, "\nto"); - if (to.getTypeIdBelow() != 0) addBlockBelowInfo(builder, to, "\nto"); - if (!to.isOnGround() && to.isOnGround(0.5)) builder.append(" (ground within 0.5)"); - NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString()); - } - - } + public static void addLocation(final double x, final double y, final double z, final StringBuilder builder){ + builder.append(x + ", " + y + ", " + z); + } - public static void addBlockBelowInfo(final StringBuilder builder, final PlayerLocation loc, final String tag) { - builder.append(tag + " below id=" + loc.getTypeIdBelow() + " data=" + loc.getData(loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ()) + " shape=" + Arrays.toString(loc.getBlockCache().getBounds(loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ()))); - } + public static void addLocation(final Location loc, final StringBuilder builder){ + addLocation(loc.getX(), loc.getY(), loc.getZ(), builder); + } - public static void addBlockInfo(final StringBuilder builder, final PlayerLocation loc, final String tag) { - builder.append(tag + " id=" + loc.getTypeId() + " data=" + loc.getData() + " shape=" + Arrays.toString(loc.getBlockCache().getBounds(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()))); - } + public static void addLocation(final PlayerLocation loc, final StringBuilder builder){ + addLocation(loc.getX(), loc.getY(), loc.getZ(), builder); + } - /** - * Intended for vehicle-move events. - * - * @param player - * @param vehicle - * @param from - * @param to - * @param fake true if the event was not fired by an external source (just gets noted). - */ - public static void outputDebugVehicleMove(final Player player, final Entity vehicle, final Location from, final Location to, final boolean fake) { - final StringBuilder builder = new StringBuilder(250); - final Location vLoc = vehicle.getLocation(); - final Location loc = player.getLocation(); - // TODO: Differentiate debug levels (needs setting up some policy + document in BuildParamteres)? - final Entity actualVehicle = player.getVehicle(); - final boolean wrongVehicle = actualVehicle == null || actualVehicle.getEntityId() != vehicle.getEntityId(); - if (BuildParameters.debugLevel > 0) { - builder.append("\n-------------- VEHICLE MOVE " + (fake ? "(fake)" : "") + "--------------\n"); - builder.append(player.getName() + " " + from.getWorld().getName() + ":\n"); - addMove(from, to, null, builder); - builder.append("\n Vehicle: "); - addLocation(vLoc, builder); - builder.append("\n Player: "); - addLocation(loc, builder); - } - else { - builder.append(player.getName() + " " + from.getWorld().getName() + "veh." + (fake ? "(fake)" : "") + " "); - addFormattedMove(from, to, null, builder); - builder.append("\n Vehicle: "); - addFormattedLocation(vLoc, builder); - builder.append(" Player: "); - addFormattedLocation(loc, builder); - } - builder.append("\n Vehicle type: " + vehicle.getType() + (wrongVehicle ? (actualVehicle == null ? " (exited?)" : " actual: " + actualVehicle.getType()) : "")); - NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString()); - } + public static void addFormattedLocation(final double x, final double y, final double z, final StringBuilder builder){ + builder.append(StringUtil.fdec3.format(x) + ", " + StringUtil.fdec3.format(y) + ", " + StringUtil.fdec3.format(z)); + } + + public static void addFormattedLocation(final Location loc, final StringBuilder builder){ + addFormattedLocation(loc.getX(), loc.getY(), loc.getZ(), builder); + } + + public static void addFormattedLocation(final PlayerLocation loc, final StringBuilder builder){ + addFormattedLocation(loc.getX(), loc.getY(), loc.getZ(), builder); + } + + + /** + * With line break between from and to. + * @param fromX + * @param fromY + * @param fromZ + * @param toX + * @param toY + * @param toZ + * @param builder + */ + public static void addMove(final double fromX, final double fromY, final double fromZ, final double toX, final double toY, final double toZ, final StringBuilder builder){ + builder.append("from: "); + addLocation(fromX, fromY, fromZ, builder); + builder.append("\nto: "); + addLocation(toX, toY, toZ, builder); + } + + /** + * No line breaks, max. 3 digits after comma. + * @param fromX + * @param fromY + * @param fromZ + * @param toX + * @param toY + * @param toZ + * @param builder + */ + public static void addFormattedMove(final double fromX, final double fromY, final double fromZ, final double toX, final double toY, final double toZ, final StringBuilder builder){ + addFormattedLocation(fromX, fromY, fromZ, builder); + builder.append(" -> "); + addFormattedLocation(toX, toY, toZ, builder); + } + + /** + * 3 decimal digits after comma (StringUtil.fdec3). No leading new line. + * @param from + * @param to + * @param loc Reference location for from, usually Player.getLocation(). May be null. + * @param builder + * @return + */ + public static void addFormattedMove(final PlayerLocation from, final PlayerLocation to, final Location loc, final StringBuilder builder){ + if (loc != null && !from.isSamePos(loc)){ + builder.append("("); + addFormattedLocation(loc, builder); + builder.append(") "); + } + addFormattedMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); + } + + /** + * Add exact coordinates, multiple lines. No leading new line. + * @param from + * @param to + * @param loc Reference location for from, usually Player.getLocation(). + * @param builder + */ + public static void addMove(final PlayerLocation from, final PlayerLocation to, final Location loc, final StringBuilder builder){ + if (loc != null && !from.isSamePos(loc)){ + builder.append("Location: "); + addLocation(loc, builder); + builder.append("\n"); + } + addMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); + } + + /** + * 3 decimal digits after comma (StringUtil.fdec3). No leading new line. + * @param from + * @param to + * @param loc Reference location for from, usually Player.getLocation(). + * @param builder + * @return + */ + public static void addFormattedMove(final Location from, final Location to, final Location loc, final StringBuilder builder){ + if (loc != null && !isSamePos(from, loc)){ + builder.append("("); + addFormattedLocation(loc, builder); + builder.append(") "); + } + addFormattedMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); } + + /** + * Add exact coordinates, multiple lines. No leading new line. + * @param from + * @param to + * @param loc Reference location for from, usually Player.getLocation(). + * @param builder + */ + public static void addMove(final Location from, final Location to, final Location loc, final StringBuilder builder){ + if (loc != null && !isSamePos(from, loc)){ + builder.append("Location: "); + addLocation(loc, builder); + builder.append("\n"); + } + addMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); + } + + /** + * Output information specific to player-move events. + * @param player + * @param from + * @param to + * @param mcAccess + */ + public static void outputMoveDebug(final Player player, final PlayerLocation from, final PlayerLocation to, final double maxYOnGround, final MCAccess mcAccess) { + final StringBuilder builder = new StringBuilder(250); + final Location loc = player.getLocation(); + // TODO: Differentiate debug levels (needs setting up some policy + document in BuildParamteres)? + if (BuildParameters.debugLevel > 0) { + builder.append("\n-------------- MOVE --------------\n"); + builder.append(player.getName() + " " + from.getWorld().getName() + ":\n"); + addMove(from, to, loc, builder); + } + else { + builder.append(player.getName() + " " + from.getWorld().getName() + " "); + addFormattedMove(from, to, loc, builder); + } + final double jump = mcAccess.getJumpAmplifier(player); + final double speed = mcAccess.getFasterMovementAmplifier(player); + final double strider = BridgeEnchant.getDepthStriderLevel(player); + if (BuildParameters.debugLevel > 0){ + try{ + // TODO: Check backwards compatibility (1.4.2). Remove try-catch + builder.append("\n(walkspeed=" + player.getWalkSpeed() + " flyspeed=" + player.getFlySpeed() + ")"); + } catch (Throwable t){} + final Vector v = player.getVelocity(); + builder.append("(svel=" + v.getX() + "," + v.getY() + "," + v.getZ() + ")"); + if (player.isSprinting()){ + builder.append("(sprinting)"); + } + if (player.isSneaking()){ + builder.append("(sneaking)"); + } + } + if (speed != Double.NEGATIVE_INFINITY){ + builder.append("(e_speed=" + (speed + 1) + ")"); + } + if (jump != Double.NEGATIVE_INFINITY){ + builder.append("(e_jump=" + (jump + 1) + ")"); + } + if (strider != 0){ + builder.append("(e_depth_strider=" + strider + ")"); + } + // Print basic info first in order + NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString()); + // Extended info. + if (BuildParameters.debugLevel > 0){ + builder.setLength(0); + // Note: the block flags are for normal on-ground checking, not with yOnGrond set to 0.5. + from.collectBlockFlags(maxYOnGround); + if (from.getBlockFlags() != 0) builder.append("\nfrom flags: " + StringUtil.join(BlockProperties.getFlagNames(from.getBlockFlags()), "+")); + if (from.getTypeId() != 0) addBlockInfo(builder, from, "\nfrom"); + if (from.getTypeIdBelow() != 0) addBlockBelowInfo(builder, from, "\nfrom"); + if (!from.isOnGround() && from.isOnGround(0.5)) builder.append(" (ground within 0.5)"); + to.collectBlockFlags(maxYOnGround); + if (to.getBlockFlags() != 0) builder.append("\nto flags: " + StringUtil.join(BlockProperties.getFlagNames(to.getBlockFlags()), "+")); + if (to.getTypeId() != 0) addBlockInfo(builder, to, "\nto"); + if (to.getTypeIdBelow() != 0) addBlockBelowInfo(builder, to, "\nto"); + if (!to.isOnGround() && to.isOnGround(0.5)) builder.append(" (ground within 0.5)"); + NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString()); + } + + } + + public static void addBlockBelowInfo(final StringBuilder builder, final PlayerLocation loc, final String tag) { + builder.append(tag + " below id=" + loc.getTypeIdBelow() + " data=" + loc.getData(loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ()) + " shape=" + Arrays.toString(loc.getBlockCache().getBounds(loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ()))); + } + + public static void addBlockInfo(final StringBuilder builder, final PlayerLocation loc, final String tag) { + builder.append(tag + " id=" + loc.getTypeId() + " data=" + loc.getData() + " shape=" + Arrays.toString(loc.getBlockCache().getBounds(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()))); + } + + /** + * Intended for vehicle-move events. + * + * @param player + * @param vehicle + * @param from + * @param to + * @param fake true if the event was not fired by an external source (just gets noted). + */ + public static void outputDebugVehicleMove(final Player player, final Entity vehicle, final Location from, final Location to, final boolean fake) { + final StringBuilder builder = new StringBuilder(250); + final Location vLoc = vehicle.getLocation(); + final Location loc = player.getLocation(); + // TODO: Differentiate debug levels (needs setting up some policy + document in BuildParamteres)? + final Entity actualVehicle = player.getVehicle(); + final boolean wrongVehicle = actualVehicle == null || actualVehicle.getEntityId() != vehicle.getEntityId(); + if (BuildParameters.debugLevel > 0) { + builder.append("\n-------------- VEHICLE MOVE " + (fake ? "(fake)" : "") + "--------------\n"); + builder.append(player.getName() + " " + from.getWorld().getName() + ":\n"); + addMove(from, to, null, builder); + builder.append("\n Vehicle: "); + addLocation(vLoc, builder); + builder.append("\n Player: "); + addLocation(loc, builder); + } + else { + builder.append(player.getName() + " " + from.getWorld().getName() + "veh." + (fake ? "(fake)" : "") + " "); + addFormattedMove(from, to, null, builder); + builder.append("\n Vehicle: "); + addFormattedLocation(vLoc, builder); + builder.append(" Player: "); + addFormattedLocation(loc, builder); + } + builder.append("\n Vehicle type: " + vehicle.getType() + (wrongVehicle ? (actualVehicle == null ? " (exited?)" : " actual: " + actualVehicle.getType()) : "")); + NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString()); + } }