diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightData.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightData.java index bb512eba..dcdb1a96 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightData.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightData.java @@ -85,6 +85,7 @@ public class FightData extends ACheckData { public double lastAttackedX = Integer.MAX_VALUE; public double lastAttackedY; public double lastAttackedZ; + public long regainHealthTime = 0; // public double lastAttackedDist = 0.0; public long damageTakenByEntityTick; diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java index e1f8403a..3e6d7ccf 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java @@ -318,13 +318,16 @@ public class FightListener extends CheckListener { if (event.isSprinting()) FightData.getData(event.getPlayer()).knockbackSprintTime = System.currentTimeMillis(); } - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityRegainHealth(final EntityRegainHealthEvent event){ final Entity entity = event.getEntity(); if (!(entity instanceof Player)) return; final Player player = (Player) entity; final FightData data = FightData.getData(player); - // Set health to maximum. + // Remember the time. + data.regainHealthTime = System.currentTimeMillis(); + // Set god-mode health to maximum. data.godModeHealth = Math.max(data.godModeHealth, player.getHealth() + event.getAmount()); + } } diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java index df5534af..3bb8b3d4 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java @@ -7,6 +7,10 @@ import org.bukkit.entity.Vehicle; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.util.Vector; +import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakData; +import fr.neatmonster.nocheatplus.checks.combined.CombinedData; +import fr.neatmonster.nocheatplus.checks.fight.FightData; +import fr.neatmonster.nocheatplus.checks.inventory.InventoryData; import fr.neatmonster.nocheatplus.checks.moving.MovingConfig; import fr.neatmonster.nocheatplus.checks.moving.MovingData; import fr.neatmonster.nocheatplus.logging.LogUtil; @@ -284,4 +288,37 @@ public class CheckUtils { System.out.println(player.getName() + " vehicle set back: " + location); } } + + /** + * Guess some last-action time, likely to be replaced with centralized PlayerData use. + * @param player + * @param Timestamp of the moment of calling this. + * @param maxAge Maximum age in milliseconds. + * @return Return timestamp or Long.MIN_VALUE if not possible or beyond maxAge. + */ + public static final long guessKeepAliveTime(final Player player, final long now, final long maxAge){ + final int tick = TickTask.getTick(); + long ref = Long.MIN_VALUE; + // Estimate last fight action time (important for gode modes). + final FightData fData = FightData.getData(player); + ref = Math.max(ref, fData.speedBuckets.lastAccess()); + ref = Math.max(ref, now - 50L * (tick - fData.lastAttackTick)); // Ignore lag. + // Health regain (not unimportant). + ref = Math.max(ref, fData.regainHealthTime); + // Move time. + ref = Math.max(ref, CombinedData.getData(player).lastMoveTime); + // Inventory. + final InventoryData iData = InventoryData.getData(player); + ref = Math.max(ref, iData.fastClickLastTime); + ref = Math.max(ref, iData.instantEatInteract); + // BlcokBreak/interact. + final BlockBreakData bbData = BlockBreakData.getData(player); + ref = Math.max(ref, bbData.frequencyBuckets.lastAccess()); + ref = Math.max(ref, bbData.fastBreakfirstDamage); + // TODO: More, less ... + if (ref > now || ref < now - maxAge){ + return Long.MIN_VALUE; + } + return ref; + } }