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());
+ }
}