[BLEEDING] Load chunks for vehicles too.

This commit is contained in:
asofold 2016-06-12 20:21:07 +02:00
parent 245f5389a0
commit 5e15dc8c9b
3 changed files with 110 additions and 89 deletions

View File

@ -309,7 +309,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Location loc = player.getLocation(useLoc);
data.setSetBack(loc);
if (cc.loadChunksOnWorldChange) {
ensureChunksLoaded(player, loc, "world change", data, cc);
MovingUtil.ensureChunksLoaded(player, loc, "world change", data, cc);
}
aux.resetPositionsAndMediumProperties(player, loc, data, cc);
data.resetTrace(loc, TickTask.getTick(), cc);
@ -427,7 +427,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Location loc = player.getLocation(moveInfo.useLoc);
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
if (cc.loadChunksOnMove) {
ensureChunksLoaded(player, from, to, lastMove, data, cc);
MovingUtil.ensureChunksLoaded(player, from, to, lastMove, "move", data, cc);
}
// TODO: On pistons pulling the player back: -1.15 yDistance for split move 1 (untracked position > 0.5 yDistance!).
if (
@ -469,89 +469,6 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
aux.returnPlayerMoveInfo(moveInfo);
}
/**
* Ensure chunks are loaded so that the move can be processed at all. Assume
* too big moves to be cancelled anyway and/or passable accounting for chunk
* load.
*
* @param from
* @param to
* @param lastMove
* @param data
* @param cc
*/
private void ensureChunksLoaded(final Player player, final Location from, final Location to, final PlayerMoveData lastMove,
final MovingData data, final MovingConfig cc) {
// (Worlds must be equal. Ensured in player move handling.)
final double x0 = from.getX();
final double z0 = from.getZ();
final double x1 = to.getX();
final double z1 = to.getZ();
if (TrigUtil.distanceSquared(x0, z0, x1, z1) > 2.0 * Magic.CHUNK_LOAD_MARGIN_MIN) {
// Assume extreme move to trigger.
return;
}
boolean loadFrom = true;
boolean loadTo = true;
double margin = Magic.CHUNK_LOAD_MARGIN_MIN;
// Heuristic for if loading may be necessary at all.
if (lastMove.toIsValid && lastMove.to.extraPropertiesValid) {
if (TrigUtil.distanceSquared(lastMove.to, x0, z0) < 1.0) {
loadFrom = false;
}
if (TrigUtil.distanceSquared(lastMove.to, x1, z1) < 1.0) {
loadTo = false;
}
}
else if (lastMove.valid && lastMove.from.extraPropertiesValid
&& cc.loadChunksOnJoin) {
// TODO: Might need to distinguish join/teleport/world-change later.
if (TrigUtil.distanceSquared(lastMove.from, x0, z0) < 1.0) {
loadFrom = false;
}
if (TrigUtil.distanceSquared(lastMove.from, x1, z1) < 1.0) {
loadTo = false;
}
}
int loaded = 0;
if (loadFrom) {
loaded += BlockCache.ensureChunksLoaded(from.getWorld(), x0, z0, margin);
if (TrigUtil.distanceSquared(x0, z0, x1, z1) < 1.0) {
loadTo = false;
}
}
if (loadTo) {
loaded += BlockCache.ensureChunksLoaded(to.getWorld(), x1, z1, margin);
}
if (loaded > 0 && data.debug) {
StaticLog.logInfo("Player move: Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + from.getWorld().getName() + " for player: " + player.getName());
}
}
private void ensureChunksLoaded(final Player player, final Location loc, final String tag,
final MovingData data, final MovingConfig cc) {
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
final double x0 = loc.getX();
final double z0 = loc.getZ();
// Heuristic for if loading may be necessary at all.
if (lastMove.toIsValid && lastMove.to.extraPropertiesValid) {
if (TrigUtil.distanceSquared(lastMove.to, x0, z0) < 1.0) {
return;
}
}
else if (lastMove.valid && lastMove.from.extraPropertiesValid
&& cc.loadChunksOnJoin) {
// TODO: Might need to distinguish join/teleport/world-change later.
if (TrigUtil.distanceSquared(lastMove.from, x0, z0) < 1.0) {
return;
}
}
int loaded = BlockCache.ensureChunksLoaded(loc.getWorld(), loc.getX(), loc.getZ(), Magic.CHUNK_LOAD_MARGIN_MIN);
if (loaded > 0 && data.debug) {
StaticLog.logInfo("Player " + tag + ": Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " for player: " + player.getName());
}
}
/**
*
* @param player
@ -1329,7 +1246,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Attempt to prevent teleporting to players inside of blocks at untracked coordinates.
if (cc.passableUntrackedTeleportCheck) {
if (cc.loadChunksOnTeleport) {
ensureChunksLoaded(player, to, "teleport", data, cc);
MovingUtil.ensureChunksLoaded(player, to, "teleport", data, cc);
}
if (cc.passableUntrackedTeleportCheck && MovingUtil.shouldCheckUntrackedLocation(player, to)) {
final Location newTo = MovingUtil.checkUntrackedLocation(to);
@ -1435,7 +1352,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
moveInfo.set(player, teleported, null, cc.yOnGround);
if (cc.loadChunksOnTeleport) {
ensureChunksLoaded(player, teleported, "teleport", data, cc);
MovingUtil.ensureChunksLoaded(player, teleported, "teleport", data, cc);
}
data.onSetBack(moveInfo.from);
aux.returnPlayerMoveInfo(moveInfo);
@ -1476,7 +1393,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
data.setSetBack(to);
data.sfHoverTicks = -1; // Important against concurrent modification exception.
if (cc.loadChunksOnTeleport) {
ensureChunksLoaded(player, to, "teleport", data, cc);
MovingUtil.ensureChunksLoaded(player, to, "teleport", data, cc);
}
aux.resetPositionsAndMediumProperties(player, to, data, cc);
// TODO: Decide to remove the LiftOffEnvelope thing completely.

View File

@ -27,6 +27,7 @@ import fr.neatmonster.nocheatplus.NCPAPIProvider;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
import fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
@ -36,6 +37,7 @@ import fr.neatmonster.nocheatplus.components.IDebugPlayer;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.BlockCache;
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
@ -285,4 +287,101 @@ public class MovingUtil {
thisMove.setExtraProperties(from, to);
}
/**
* Ensure nearby chunks are loaded so that the move can be processed at all.
* Assume too big moves to be cancelled anyway and/or checks like passable
* accounting for chunk load. Further skip chunk loading if the latest
* stored past move has extra properties set and is close by.
*
* @param from
* @param to
* @param lastMove
* @param tag
* The type of context/event for debug logging.
* @param data
* @param cc
*/
public static void ensureChunksLoaded(final Player player, final Location from, final Location to, final PlayerMoveData lastMove,
final String tag, final MovingData data, final MovingConfig cc) {
// (Worlds must be equal. Ensured in player move handling.)
final double x0 = from.getX();
final double z0 = from.getZ();
final double x1 = to.getX();
final double z1 = to.getZ();
if (TrigUtil.distanceSquared(x0, z0, x1, z1) > 2.0 * Magic.CHUNK_LOAD_MARGIN_MIN) {
// Assume extreme move to trigger.
return;
}
boolean loadFrom = true;
boolean loadTo = true;
double margin = Magic.CHUNK_LOAD_MARGIN_MIN;
// Heuristic for if loading may be necessary at all.
if (lastMove.toIsValid && lastMove.to.extraPropertiesValid) {
if (TrigUtil.distanceSquared(lastMove.to, x0, z0) < 1.0) {
loadFrom = false;
}
if (TrigUtil.distanceSquared(lastMove.to, x1, z1) < 1.0) {
loadTo = false;
}
}
else if (lastMove.valid && lastMove.from.extraPropertiesValid
&& cc.loadChunksOnJoin) {
// TODO: Might need to distinguish join/teleport/world-change later.
if (TrigUtil.distanceSquared(lastMove.from, x0, z0) < 1.0) {
loadFrom = false;
}
if (TrigUtil.distanceSquared(lastMove.from, x1, z1) < 1.0) {
loadTo = false;
}
}
int loaded = 0;
if (loadFrom) {
loaded += BlockCache.ensureChunksLoaded(from.getWorld(), x0, z0, margin);
if (TrigUtil.distanceSquared(x0, z0, x1, z1) < 1.0) {
loadTo = false;
}
}
if (loadTo) {
loaded += BlockCache.ensureChunksLoaded(to.getWorld(), x1, z1, margin);
}
if (loaded > 0 && data.debug) {
StaticLog.logInfo("Player " + tag + ": Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + from.getWorld().getName() + " for player: " + player.getName());
}
}
/**
* Ensure nearby chunks are loaded. Further skip chunk loading if the latest
* stored past move has extra properties set and is close by.
*
* @param player
* @param loc
* @param tag
* The type of context/event for debug logging.
* @param data
* @param cc
*/
public static void ensureChunksLoaded(final Player player, final Location loc, final String tag,
final MovingData data, final MovingConfig cc) {
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
final double x0 = loc.getX();
final double z0 = loc.getZ();
// Heuristic for if loading may be necessary at all.
if (lastMove.toIsValid && lastMove.to.extraPropertiesValid) {
if (TrigUtil.distanceSquared(lastMove.to, x0, z0) < 1.0) {
return;
}
}
else if (lastMove.valid && lastMove.from.extraPropertiesValid
&& cc.loadChunksOnJoin) {
// TODO: Might need to distinguish join/teleport/world-change later.
if (TrigUtil.distanceSquared(lastMove.from, x0, z0) < 1.0) {
return;
}
}
int loaded = BlockCache.ensureChunksLoaded(loc.getWorld(), loc.getX(), loc.getZ(), Magic.CHUNK_LOAD_MARGIN_MIN);
if (loaded > 0 && data.debug) {
StaticLog.logInfo("Player " + tag + ": Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " for player: " + player.getName());
}
}
}

View File

@ -240,6 +240,7 @@ public class VehicleChecks extends CheckListener {
return null;
}
} else {
// (Skip chunk loading here.)
aux.resetPositionsAndMediumProperties(player, vLoc, data, cc);
return null;
}
@ -346,7 +347,9 @@ public class VehicleChecks extends CheckListener {
if (!firstPastMove.valid) {
// Determine the best location to use as past move.
// TODO: Could also check the set-backs for plausible entries, however that would lead to a violation by default. Could use an indicator.
aux.resetVehiclePositions(vehicle, from == null ? vehicleLocation : from, data, cc);
final Location refLoc = from == null ? vehicleLocation : from;
MovingUtil.ensureChunksLoaded(player, refLoc, "vehicle move (no past move)", data, cc);
aux.resetVehiclePositions(vehicle, refLoc, data, cc);
if (data.debug) {
// TODO: Might warn instead.
debug(player, "Missing past move data, set to: " + firstPastMove.from);
@ -356,6 +359,8 @@ public class VehicleChecks extends CheckListener {
// (Currently always use firstPastMove and vehicleLocation.)
final Location useFrom = LocUtil.set(useLoc1, world, firstPastMove.toIsValid ? firstPastMove.to : firstPastMove.from);
final Location useTo = vehicleLocation;
// Ensure chunks are loaded.
MovingUtil.ensureChunksLoaded(player, useFrom, useTo, firstPastMove, "vehicle move", data, cc);
// Initialize moveInfo.
if (vehicleType == EntityType.PIG) {
// TODO: Special cases by config rather.