diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Direction.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Direction.java
index fc48fc33..bf6f7421 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Direction.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Direction.java
@@ -117,21 +117,17 @@ public class Direction extends Check {
*/
public DirectionContext getContext(final Player player, final Location loc,
final Entity damaged, final boolean damagedIsFake, final Location damagedLoc,
- final FightData data, final FightConfig cc, final SharedContext sharedContext) {
+ final FightData data, final FightConfig cc) {
final DirectionContext context = new DirectionContext();
// Find out how wide the entity is.
if (damagedIsFake) {
// Assume player / default.
context.damagedComplex = false; // Later prefer bukkit based provider.
- context.damagedWidth = 0.6;
}
else {
final MCAccess mcAccess = this.mcAccess.getHandle();
context.damagedComplex = mcAccess.isComplexPart(damaged);
- context.damagedWidth = mcAccess.getWidth(damaged);
}
- // entity.height is broken and will always be 0, therefore. Calculate height instead based on boundingBox.
- context.damagedHeight = sharedContext.damagedHeight;
context.direction = loc.getDirection();
context.lengthDirection = context.direction.length();
return context;
@@ -161,19 +157,20 @@ public class Direction extends Check {
// How far "off" is the player with their aim. We calculate from the players eye location and view direction to
// the center of the target entity. If the line of sight is more too far off, "off" will be bigger than 0.
-
+ final double damagedBoxMarginHorizontal = dLoc.getBoxMarginHorizontal();
+ final double damagedBoxMarginVertical = dLoc.getBoxMarginVertical();
final double off;
if (cc.directionStrict){
- off = TrigUtil.combinedDirectionCheck(loc, player.getEyeHeight(), context.direction, dLoc.getX(), dLoc.getY() + context.damagedHeight / 2D, dLoc.getZ(), context.damagedWidth, context.damagedHeight, TrigUtil.DIRECTION_LOOP_PRECISION, 80.0);
+ off = TrigUtil.combinedDirectionCheck(loc, player.getEyeHeight(), context.direction, dLoc.getX(), dLoc.getY() + damagedBoxMarginVertical / 2D, dLoc.getZ(), damagedBoxMarginHorizontal * 2.0, damagedBoxMarginVertical, TrigUtil.DIRECTION_LOOP_PRECISION, 80.0);
}
else{
// Also take into account the angle.
- off = TrigUtil.directionCheck(loc, player.getEyeHeight(), context.direction, dLoc.getX(), dLoc.getY() + context.damagedHeight / 2D, dLoc.getZ(), context.damagedWidth, context.damagedHeight, TrigUtil.DIRECTION_LOOP_PRECISION);
+ off = TrigUtil.directionCheck(loc, player.getEyeHeight(), context.direction, dLoc.getX(), dLoc.getY() + damagedBoxMarginVertical / 2D, dLoc.getZ(), damagedBoxMarginHorizontal * 2.0, damagedBoxMarginVertical, TrigUtil.DIRECTION_LOOP_PRECISION);
}
if (off > 0.1) {
// Player failed the check. Let's try to guess how far they were from looking directly to the entity...
- final Vector blockEyes = new Vector(dLoc.getX() - loc.getX(), dLoc.getY() + context.damagedHeight / 2D - loc.getY() - player.getEyeHeight(), dLoc.getZ() - loc.getZ());
+ final Vector blockEyes = new Vector(dLoc.getX() - loc.getX(), dLoc.getY() + damagedBoxMarginVertical / 2D - loc.getY() - player.getEyeHeight(), dLoc.getZ() - loc.getZ());
final double distance = blockEyes.crossProduct(context.direction).length() / context.lengthDirection;
context.minViolation = Math.min(context.minViolation, distance);
cancel = true;
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/DirectionContext.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/DirectionContext.java
index cb152733..47156d61 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/DirectionContext.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/DirectionContext.java
@@ -18,14 +18,13 @@ import org.bukkit.util.Vector;
/**
* Context data for the direction check, for repeated use within a loop.
- * @author mc_dev
+ *
+ * @author asofold
*
*/
public class DirectionContext {
public boolean damagedComplex;
- public double damagedWidth;
- public double damagedHeight;
public Vector direction = null;
public double lengthDirection;
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java
index 6bf4ce5f..ba303510 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java
@@ -200,7 +200,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// Get+update the damaged players.
// TODO: Problem with NPCs: data stays (not a big problem).
// (This is done even if the event has already been cancelled, to keep track, if the player is on a horse.)
- damagedTrace = MovingData.getData(damagedPlayer).updateTrace(damagedPlayer, damagedLoc, tick);
+ damagedTrace = MovingData.getData(damagedPlayer).updateTrace(damagedPlayer, damagedLoc, tick, damagedIsFake ? null : mcAccess.getHandle());
}
else {
damagedPlayer = null; // TODO: This is a temporary workaround.
@@ -410,9 +410,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
boolean cancelled = false;
// (Might pass generic context to factories, for shared + heavy properties.)
- final SharedContext sharedContext = new SharedContext(damaged, damagedIsFake, mcAccess.getHandle());
- final ReachContext reachContext = reachEnabled ? reach.getContext(player, loc, damaged, damagedLoc, data, cc, sharedContext) : null;
- final DirectionContext directionContext = directionEnabled ? direction.getContext(player, loc, damaged, damagedIsFake, damagedLoc, data, cc, sharedContext) : null;
+ final ReachContext reachContext = reachEnabled ? reach.getContext(player, loc, damaged, damagedLoc, data, cc) : null;
+ final DirectionContext directionContext = directionEnabled ? direction.getContext(player, loc, damaged, damagedIsFake, damagedLoc, data, cc) : null;
final long traceOldest = tick - cc.loopMaxLatencyTicks; // TODO: Set by latency-window.
// TODO: Iterating direction, which, static/dynamic choice.
@@ -424,6 +423,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// TODO: Maintain a latency estimate + max diff and invalidate completely (i.e. iterate from latest NEXT time)], or just max latency.
// TODO: Consider a max-distance to "now", for fast invalidation.
long latencyEstimate = -1;
+ ITraceEntry successEntry = null;
while (traceIt.hasNext()) {
final ITraceEntry entry = traceIt.next();
// Simplistic just check both until end or hit.
@@ -450,6 +450,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// TODO: Log/set estimated latency.
violation = false;
latencyEstimate = now - entry.getTime();
+ successEntry = entry;
break;
}
}
@@ -458,7 +459,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
// TODO: violation vs. reachPassed + directionPassed (current: fail one = fail all).
if (reachEnabled) {
// TODO: Might ignore if already cancelled by mixed/silent cancel.
- if (reach.loopFinish(player, loc, damaged, reachContext, violation, data, cc)) {
+ if (reach.loopFinish(player, loc, damaged, reachContext, successEntry, violation, data, cc)) {
cancelled = true;
}
}
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Reach.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Reach.java
index b5871f28..ffecdb34 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Reach.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/Reach.java
@@ -162,11 +162,10 @@ public class Reach extends Check {
* @param cc
* @return
*/
- public ReachContext getContext(final Player player, final Location pLoc, final Entity damaged, final Location damagedLoc, final FightData data, final FightConfig cc, final SharedContext sharedContext) {
+ public ReachContext getContext(final Player player, final Location pLoc, final Entity damaged, final Location damagedLoc, final FightData data, final FightConfig cc) {
final ReachContext context = new ReachContext();
context.distanceLimit = player.getGameMode() == GameMode.CREATIVE ? CREATIVE_DISTANCE : cc.reachSurvivalDistance + getDistMod(damaged);
context.distanceMin = (context.distanceLimit - cc.reachReduceDistance) / context.distanceLimit;
- context.damagedHeight = sharedContext.damagedHeight;
//context.eyeHeight = player.getEyeHeight();
context.pY = pLoc.getY() + player.getEyeHeight();
return context;
@@ -183,7 +182,9 @@ public class Reach extends Check {
* @param cc
* @return
*/
- public boolean loopCheck(final Player player, final Location pLoc, final Entity damaged, final ITraceEntry dRef, final ReachContext context, final FightData data, final FightConfig cc) {
+ public boolean loopCheck(final Player player, final Location pLoc, final Entity damaged,
+ final ITraceEntry dRef, final ReachContext context,
+ final FightData data, final FightConfig cc) {
boolean cancel = false;
// Refine y position.
@@ -193,8 +194,8 @@ public class Reach extends Check {
if (context.pY <= dY) {
// Keep the foot level y.
}
- else if (context.pY >= dY + context.damagedHeight) {
- y = dY + context.damagedHeight; // Highest ref y.
+ else if (context.pY >= dY + dRef.getBoxMarginVertical()) {
+ y = dY + dRef.getBoxMarginVertical(); // Highest ref y.
}
else {
y = context.pY; // Level with damaged.
@@ -230,7 +231,9 @@ public class Reach extends Check {
* @param cc
* @return
*/
- public boolean loopFinish(final Player player, final Location pLoc, final Entity damaged, final ReachContext context, final boolean forceViolation, final FightData data, final FightConfig cc) {
+ public boolean loopFinish(final Player player, final Location pLoc, final Entity damaged,
+ final ReachContext context, final ITraceEntry traceEntry, final boolean forceViolation,
+ final FightData data, final FightConfig cc) {
final double lenpRel = forceViolation && context.minViolation != Double.MAX_VALUE ? context.minViolation : context.minResult;
if (lenpRel == Double.MAX_VALUE) {
return false;
@@ -281,7 +284,8 @@ public class Reach extends Check {
}
if (data.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
- player.sendMessage("NC+: Attack/reach " + damaged.getType()+ " height="+ StringUtil.fdec3.format(context.damagedHeight) + " dist=" + StringUtil.fdec3.format(lenpRel) +" @" + StringUtil.fdec3.format(data.reachMod));
+ // TODO: Height: remember successful ITraceEntry
+ player.sendMessage("NC+: Attack/reach " + damaged.getType()+ (traceEntry == null ? "" : (" height=" + traceEntry.getBoxMarginVertical())) + " dist=" + StringUtil.fdec3.format(lenpRel) +" @" + StringUtil.fdec3.format(data.reachMod));
}
return cancel;
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/ReachContext.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/ReachContext.java
index f9645c38..e6caef66 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/ReachContext.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/ReachContext.java
@@ -16,16 +16,16 @@ package fr.neatmonster.nocheatplus.checks.fight;
/**
* Context data for the reach check, for repeated use within a loop.
- * @author mc_dev
+ *
+ * @author asofold
*
*/
public class ReachContext {
public double distanceLimit;
public double distanceMin;
- public double damagedHeight;
-// /** Attacking player. */
-// public double eyeHeight;
+ // /** Attacking player. */
+ // public double eyeHeight;
/** Eye location y of the attacking player. */
public double pY;
/** Minimum value of lenpRel that was a violation. */
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/SharedContext.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/SharedContext.java
deleted file mode 100644
index 68d34693..00000000
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/SharedContext.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package fr.neatmonster.nocheatplus.checks.fight;
-
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.LivingEntity;
-
-import fr.neatmonster.nocheatplus.compat.MCAccess;
-
-public class SharedContext {
- public final double damagedHeight;
-
- public SharedContext(Entity damaged, boolean damagedIsFake, MCAccess mcAccess) {
- if (damagedIsFake) {
- // Assume something lenient then.
- damagedHeight = damaged instanceof LivingEntity ? ((LivingEntity) damaged).getEyeHeight() : 1.75;
- }
- else {
- this.damagedHeight = mcAccess.getHeight(damaged);
- }
- }
-}
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java
index 99b2584c..4f8bfe5e 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java
@@ -43,6 +43,7 @@ import fr.neatmonster.nocheatplus.checks.moving.velocity.FrictionAxisVelocity;
import fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleAxisVelocity;
import fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleEntry;
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
+import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.compat.blocks.BlockChangeTracker.BlockChangeEntry;
import fr.neatmonster.nocheatplus.compat.blocks.BlockChangeTracker.BlockChangeReference;
import fr.neatmonster.nocheatplus.components.data.ICanHandleTimeRunningBackwards;
@@ -1062,36 +1063,39 @@ public class MovingData extends ACheckData {
}
/**
- * Convenience method to add a location to the trace, creates the trace if necessary.
+ * Convenience method to add a location to the trace, creates the trace if
+ * necessary.
+ *
* @param player
* @param loc
* @param time
- * @return Updated LocationTrace instance, for convenient use, without sticking too much to MovingData.
+ * @param mcAccess
+ * If null getEyeHeight and 0.3 are used (assume fake player).
+ * @return Updated LocationTrace instance, for convenient use, without
+ * sticking too much to MovingData.
*/
- public LocationTrace updateTrace(final Player player, final Location loc, final long time) {
+ public LocationTrace updateTrace(final Player player, final Location loc, final long time,
+ final MCAccess mcAccess) {
final LocationTrace trace = getTrace(player);
- trace.addEntry(time, loc.getX(), loc.getY(), loc.getZ());
+ if (mcAccess == null) {
+ // TODO: 0.3 from bukkit based default heights (needs extra registered classes).
+ trace.addEntry(time, loc.getX(), loc.getY(), loc.getZ(), 0.3, player.getEyeHeight());
+ }
+ else {
+ trace.addEntry(time, loc.getX(), loc.getY(), loc.getZ(), mcAccess.getWidth(player) / 2.0, Math.max(player.getEyeHeight(), mcAccess.getHeight(player)));
+ }
return trace;
}
- /**
- * Convenience
- * @param player
- * @param loc
- */
- public void resetTrace(final Player player, final Location loc, final long time) {
- final MovingConfig cc = MovingConfig.getConfig(player);
- resetTrace(loc, time, cc);
- }
-
/**
* Convenience.
* @param loc
* @param time
* @param cc
*/
- public void resetTrace(final Location loc, final long time, final MovingConfig cc) {
- resetTrace(loc, time, cc.traceMaxAge, cc.traceMaxSize);
+ public void resetTrace(final Player player, final Location loc, final long time,
+ final MCAccess mcAccess, final MovingConfig cc) {
+ resetTrace(player, loc, time, cc.traceMaxAge, cc.traceMaxSize, mcAccess);
}
/**
@@ -1101,11 +1105,13 @@ public class MovingData extends ACheckData {
* @param mergeDist
* @param traceMergeDist
*/
- public void resetTrace(final Location loc, final long time, final int maxAge, final int maxSize) {
+ public void resetTrace(final Player player, final Location loc, final long time,
+ final int maxAge, final int maxSize, final MCAccess mcAccess) {
if (trace != null) {
trace.reset();
}
- getTrace(maxAge, maxSize).addEntry(time, loc.getX(), loc.getY(), loc.getZ());
+ getTrace(maxAge, maxSize).addEntry(time, loc.getX(), loc.getY(), loc.getZ(),
+ mcAccess.getWidth(player) / 2.0, Math.max(player.getEyeHeight(), mcAccess.getHeight(player)));
}
/**
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java
index 8266e04b..26501796 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java
@@ -313,7 +313,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
MovingUtil.ensureChunksLoaded(player, loc, "world change", data, cc);
}
aux.resetPositionsAndMediumProperties(player, loc, data, cc);
- data.resetTrace(loc, TickTask.getTick(), cc);
+ data.resetTrace(player, loc, TickTask.getTick(), mcAccess.getHandle(), cc);
if (cc.enforceLocation) {
// Just in case.
playersEnforce.add(player.getName());
@@ -1109,7 +1109,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// TODO: teleported + other resetting ?
Combined.feedYawRate(player, from.getYaw(), now, from.getWorld().getName(), data);
aux.resetPositionsAndMediumProperties(player, from, mData, mCc);
- mData.resetTrace(player, from, tick); // TODO: Should probably leave this to the teleport event!
+ mData.resetTrace(player, from, tick, mcAccess.getHandle(), mCc); // TODO: Should probably leave this to the teleport event!
if (((NetConfig) CheckType.NET_FLYINGFREQUENCY.getConfigFactory().getConfig(player)).flyingFrequencyActive) {
((NetData) CheckType.NET_FLYINGFREQUENCY.getDataFactory().getData(player)).teleportQueue.onTeleportEvent(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch());
}
@@ -1135,12 +1135,12 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Location ref = player.getVehicle().getLocation(useLoc);
aux.resetPositionsAndMediumProperties(player, ref, mData, mCc); // TODO: Consider using to and intercept cheat attempts in another way.
useLoc.setWorld(null);
- mData.updateTrace(player, to, tick); // TODO: Can you become invincible by sending special moves?
+ mData.updateTrace(player, to, tick, mcAccess.getHandle()); // TODO: Can you become invincible by sending special moves?
}
else if (!from.getWorld().getName().equals(toWorldName)) {
// A teleport event should follow.
aux.resetPositionsAndMediumProperties(player, to, mData, mCc);
- mData.resetTrace(player, to, tick);
+ mData.resetTrace(player, to, tick, mcAccess.getHandle(), mCc);
}
else {
// TODO: Detect differing location (a teleport event would follow).
@@ -1152,7 +1152,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
else {
// Normal move, nothing to do.
}
- mData.updateTrace(player, to, tick);
+ mData.updateTrace(player, to, tick, mcAccess.getHandle());
}
}
@@ -1610,7 +1610,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
data.clearVehicleData(); // TODO: Uncertain here, what to check.
data.clearAllMorePacketsData();
data.removeAllVelocity();
- data.resetTrace(loc, tick, cc); // Might reset to loc instead of set-back ?
+ data.resetTrace(player, loc, tick, mcAccess.getHandle(), cc); // Might reset to loc instead of set-back ?
// More resetting.
data.vDistAcc.clear();
diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/location/tracking/LocationTrace.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/location/tracking/LocationTrace.java
index c16f1838..20395c87 100644
--- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/location/tracking/LocationTrace.java
+++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/location/tracking/LocationTrace.java
@@ -18,6 +18,7 @@ import java.util.Iterator;
import fr.neatmonster.nocheatplus.components.location.IGetPosition;
import fr.neatmonster.nocheatplus.components.pool.AbstractPool;
+import fr.neatmonster.nocheatplus.utilities.RichBoundsLocation;
/**
* This class is meant to record locations for players moving, in order to allow
@@ -45,18 +46,22 @@ public class LocationTrace {
public static interface ITraceEntry extends IGetPosition {
+ public double getBoxMarginHorizontal();
+
+ public double getBoxMarginVertical();
+
public long getTime();
}
public static class TraceEntry implements ITraceEntry {
-
+
// TODO: Consider using a simple base implementation for IGetSetPosiotion.
/** We keep it open, if ticks or ms are used. */
private long time;
/** Coordinates. */
- private double x, y, z;
+ private double x, y, z, boxMarginHorizontal, boxMarginVertical;
/** Older/next. */
private TraceEntry next;
@@ -71,10 +76,13 @@ public class LocationTrace {
* @param y
* @param z
*/
- public void set(long time, double x, double y, double z) {
+ public void set(long time, double x, double y, double z,
+ double boxMarginHorizontal, double boxMarginVertical) {
this.x = x;
this.y = y;
this.z = z;
+ this.boxMarginHorizontal = boxMarginHorizontal;
+ this.boxMarginVertical = boxMarginVertical;
this.time = time;
}
@@ -93,6 +101,14 @@ public class LocationTrace {
return z;
}
+ public double getBoxMarginHorizontal() {
+ return boxMarginHorizontal;
+ }
+
+ public double getBoxMarginVertical() {
+ return boxMarginVertical;
+ }
+
@Override
public long getTime() {
return time;
@@ -192,16 +208,35 @@ public class LocationTrace {
this.maxSize = maxSize;
}
- public final void addEntry(final long time, final double x, final double y, final double z) {
+ public final void addEntry(final long time, final RichBoundsLocation loc) {
+ addEntry(time, loc.getX(), loc.getY(), loc.getZ(), loc.getBoxMarginHorizontal(), loc.getBoxMarginVertical());
+ }
+
+ /**
+ *
+ * @param time
+ * @param x
+ * @param y
+ * @param z
+ * @param boxMarginHorizontal
+ * Margin from the foot position to the side(s) of the box.
+ * @param boxMarginVertical
+ * Margin from the foot position to the top of the box.
+ */
+ public final void addEntry(final long time, final double x, final double y, final double z,
+ final double boxMarginHorizontal, final double boxMarginVertical) {
if (size > 0) {
- if (x == firstEntry.x && y == firstEntry.y && z == firstEntry.z) {
+ // TODO: Might update box to bigger or remove margins ?
+ if (x == firstEntry.x && y == firstEntry.y && z == firstEntry.z
+ && boxMarginHorizontal == firstEntry.boxMarginHorizontal
+ && boxMarginVertical == firstEntry.boxMarginVertical) {
// (No update of time. firstEntry ... now always counts.)
return;
}
}
// Add a new entry.
final TraceEntry newEntry = pool.getInstance();
- newEntry.set(time, x, y, z);
+ newEntry.set(time, x, y, z, boxMarginHorizontal, boxMarginVertical);
setFirst(newEntry);
// Remove the last entry, if maxSize is exceeded.
if (size > maxSize) {
diff --git a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestLocationTrace.java b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestLocationTrace.java
index 5db9ed8b..809ea135 100644
--- a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestLocationTrace.java
+++ b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestLocationTrace.java
@@ -76,14 +76,14 @@ public class TestLocationTrace {
}
// Adding up to size elements.
for (int i = 0; i < size ; i++) {
- trace.addEntry(i, i, i, i);
+ trace.addEntry(i, i, i, i, 0, 0);
if (trace.size() != i + 1) {
fail("Wrong size, expect " + (i + 1) + ", got instead: " + trace.size());
}
}
// Adding a lot of elements.
for (int i = 0; i < 1000; i ++) {
- trace.addEntry(i + size, i, i, i);
+ trace.addEntry(i + size, i, i, i, 0, 0);
if (trace.size() != size) {
fail("Wrong size, expect " + size + ", got instead: " + trace.size());
}
@@ -95,7 +95,7 @@ public class TestLocationTrace {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
for (int i = 0; i < 1000; i ++) {
- trace.addEntry(i + size, 0 , 0, 0);
+ trace.addEntry(i + size, 0 , 0, 0, 0, 0);
if (trace.size() != 1) {
fail("Wrong size, expect 1, got instead: " + trace.size());
}
@@ -133,13 +133,13 @@ public class TestLocationTrace {
LocationTrace trace = new LocationTrace(size, size, pool);
// Adding up to size elements.
for (int i = 0; i < size; i++) {
- trace.addEntry(i, i, i, i);
+ trace.addEntry(i, i, i, i, 0, 0);
}
// Test size with one time filled up.
testIteratorSizeAndOrder(trace, 80);
// Add size / 2 elements, to test cross-boundary iteration.
for (int i = 0; i < size / 2; i++) {
- trace.addEntry(i + size, i, i, i);
+ trace.addEntry(i + size, i, i, i, 0, 0);
}
// Test size again.
testIteratorSizeAndOrder(trace, 80);
@@ -195,7 +195,7 @@ public class TestLocationTrace {
LocationTrace trace = new LocationTrace(size, size, pool);
// Adding up to size elements.
for (int i = 0; i < size; i++) {
- trace.addEntry(i, i, i, i);
+ trace.addEntry(i, i, i, i, 0, 0);
}
for (int i = 0; i < size; i++) {
Iterator it = trace.maxAgeIterator(i);
@@ -218,11 +218,11 @@ public class TestLocationTrace {
public void testMaxAgeFirstElementAnyway() {
int size = 80;
LocationTrace trace = new LocationTrace(size, size, pool);
- trace.addEntry(0, 0, 0, 0);
+ trace.addEntry(0, 0, 0, 0, 0, 0);
if (!trace.maxAgeIterator(1000).hasNext()) {
fail("Expect iterator (maxAge) to always contain the latest element.");
}
- trace.addEntry(1, 0, 0, 0);
+ trace.addEntry(1, 0, 0, 0, 0, 0);
final Iterator it = trace.maxAgeIterator(2);
if (!it.hasNext()) {
fail("Expect iterator (maxAge) to always contain the latest element.");