mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-12-27 19:07:45 +01:00
[BLEEDING/INCOMPLETE] More strict go on vehicles.
Roughly this line of develpment has to do with: * Prevent destroying ones own vehicle [INCOMPLETE: conflict with older MC versions.]. * More careful set-back handling. * Reset the players position to that of the vehicle if the player moves too far off (likely does not have effect, needs more testing). In principle this is intended to trigger a teleport, the normal player is intended to not notice, but no guarantees yet. Not configurable yet, might not work 100%, yet.
This commit is contained in:
parent
ae6510aaa0
commit
f597f8bded
@ -76,7 +76,7 @@ public class MovingData extends ACheckData {
|
|||||||
return playersMap.remove(playerName);
|
return playersMap.remove(playerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clear(){
|
public static void clear() {
|
||||||
playersMap.clear();
|
playersMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,9 @@ public class MovingData extends ACheckData {
|
|||||||
* Clear data related to the given world.
|
* Clear data related to the given world.
|
||||||
* @param world The world that gets unloaded.
|
* @param world The world that gets unloaded.
|
||||||
*/
|
*/
|
||||||
public static void onWorldUnload(final World world){
|
public static void onWorldUnload(final World world) {
|
||||||
final String worldName = world.getName();
|
final String worldName = world.getName();
|
||||||
for (final MovingData data : playersMap.values()){
|
for (final MovingData data : playersMap.values()) {
|
||||||
data.onWorldUnload(worldName);
|
data.onWorldUnload(worldName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +263,7 @@ public class MovingData extends ACheckData {
|
|||||||
/**
|
/**
|
||||||
* Move event: Mildly reset some data, prepare setting a new to-Location.
|
* Move event: Mildly reset some data, prepare setting a new to-Location.
|
||||||
*/
|
*/
|
||||||
public void prepareSetBack(final Location loc){
|
public void prepareSetBack(final Location loc) {
|
||||||
clearAccounting();
|
clearAccounting();
|
||||||
sfJumpPhase = 0;
|
sfJumpPhase = 0;
|
||||||
sfLastYDist = sfLastHDist = Double.MAX_VALUE;
|
sfLastYDist = sfLastHDist = Double.MAX_VALUE;
|
||||||
@ -278,7 +278,7 @@ public class MovingData extends ACheckData {
|
|||||||
* Just reset the "last locations" references.
|
* Just reset the "last locations" references.
|
||||||
* @param loc
|
* @param loc
|
||||||
*/
|
*/
|
||||||
public void resetPositions(final Location loc){
|
public void resetPositions(final Location loc) {
|
||||||
if (loc == null) resetPositions(Double.MAX_VALUE, 0, 0);
|
if (loc == null) resetPositions(Double.MAX_VALUE, 0, 0);
|
||||||
else resetPositions(loc.getX(), loc.getY(), loc.getZ());
|
else resetPositions(loc.getX(), loc.getY(), loc.getZ());
|
||||||
}
|
}
|
||||||
@ -323,6 +323,7 @@ public class MovingData extends ACheckData {
|
|||||||
public void clearMorePacketsData() {
|
public void clearMorePacketsData() {
|
||||||
morePacketsSetback = null;
|
morePacketsSetback = null;
|
||||||
morePacketsVehicleSetback = null;
|
morePacketsVehicleSetback = null;
|
||||||
|
// TODO: Also reset other data ?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -338,8 +339,8 @@ public class MovingData extends ACheckData {
|
|||||||
* Set the set-back location, this will also adjust the y-coordinate for some block types (at least air).
|
* Set the set-back location, this will also adjust the y-coordinate for some block types (at least air).
|
||||||
* @param loc
|
* @param loc
|
||||||
*/
|
*/
|
||||||
public void setSetBack(final PlayerLocation loc){
|
public void setSetBack(final PlayerLocation loc) {
|
||||||
if (setBack == null){
|
if (setBack == null) {
|
||||||
setBack = loc.getLocation();
|
setBack = loc.getLocation();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -352,8 +353,8 @@ public class MovingData extends ACheckData {
|
|||||||
* Convenience method.
|
* Convenience method.
|
||||||
* @param loc
|
* @param loc
|
||||||
*/
|
*/
|
||||||
public void setSetBack(final Location loc){
|
public void setSetBack(final Location loc) {
|
||||||
if (setBack == null){
|
if (setBack == null) {
|
||||||
setBack = LocUtil.clone(loc);
|
setBack = LocUtil.clone(loc);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -366,7 +367,7 @@ public class MovingData extends ACheckData {
|
|||||||
* @param ref
|
* @param ref
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Location getSetBack(final Location ref){
|
public Location getSetBack(final Location ref) {
|
||||||
return LocUtil.clone(setBack, ref);
|
return LocUtil.clone(setBack, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +410,7 @@ public class MovingData extends ACheckData {
|
|||||||
* Return a copy of the teleported-to Location.
|
* Return a copy of the teleported-to Location.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public final Location getTeleported(){
|
public final Location getTeleported() {
|
||||||
// TODO: here a reference might do.
|
// TODO: here a reference might do.
|
||||||
return teleported == null ? teleported : LocUtil.clone(teleported);
|
return teleported == null ? teleported : LocUtil.clone(teleported);
|
||||||
}
|
}
|
||||||
@ -489,7 +490,7 @@ public class MovingData extends ACheckData {
|
|||||||
/**
|
/**
|
||||||
* Currently only applies to horizontal velocity.
|
* Currently only applies to horizontal velocity.
|
||||||
*/
|
*/
|
||||||
public void removeAllVelocity(){
|
public void removeAllVelocity() {
|
||||||
hVelActive.clear();
|
hVelActive.clear();
|
||||||
hVelQueued.clear();
|
hVelQueued.clear();
|
||||||
}
|
}
|
||||||
@ -504,20 +505,20 @@ public class MovingData extends ACheckData {
|
|||||||
Iterator<Velocity> it;
|
Iterator<Velocity> it;
|
||||||
// Active.
|
// Active.
|
||||||
it = hVelActive.iterator();
|
it = hVelActive.iterator();
|
||||||
while (it.hasNext()){
|
while (it.hasNext()) {
|
||||||
final Velocity vel = it.next();
|
final Velocity vel = it.next();
|
||||||
// TODO: 0.001 can be stretched somewhere else, most likely...
|
// TODO: 0.001 can be stretched somewhere else, most likely...
|
||||||
// TODO: Somehow use tick here too (actCount, valCount)?
|
// TODO: Somehow use tick here too (actCount, valCount)?
|
||||||
if (vel.valCount <= 0 || vel.value <= 0.001){
|
if (vel.valCount <= 0 || vel.value <= 0.001) {
|
||||||
// System.out.prsintln("Invalidate active: " + vel);
|
// System.out.prsintln("Invalidate active: " + vel);
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Queued.
|
// Queued.
|
||||||
it = hVelQueued.iterator();
|
it = hVelQueued.iterator();
|
||||||
while (it.hasNext()){
|
while (it.hasNext()) {
|
||||||
final Velocity vel = it.next();
|
final Velocity vel = it.next();
|
||||||
if (vel.actCount <= 0 || vel.tick < tick){
|
if (vel.actCount <= 0 || vel.tick < tick) {
|
||||||
// System.out.println("Invalidate queued: " + vel);
|
// System.out.println("Invalidate queued: " + vel);
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
@ -527,12 +528,12 @@ public class MovingData extends ACheckData {
|
|||||||
/**
|
/**
|
||||||
* Called for moving events, increase age of velocity, decrease amounts, check which entries are invalid. Both horizontal and vertical.
|
* Called for moving events, increase age of velocity, decrease amounts, check which entries are invalid. Both horizontal and vertical.
|
||||||
*/
|
*/
|
||||||
public void velocityTick(){
|
public void velocityTick() {
|
||||||
// Horizontal velocity (intermediate concept).
|
// Horizontal velocity (intermediate concept).
|
||||||
// Decrease counts for active.
|
// Decrease counts for active.
|
||||||
// TODO: Actual friction. Could pass as an argument (special value for not to be used).
|
// TODO: Actual friction. Could pass as an argument (special value for not to be used).
|
||||||
// TODO: Consider removing already invalidated here.
|
// TODO: Consider removing already invalidated here.
|
||||||
for (final Velocity vel : hVelActive){
|
for (final Velocity vel : hVelActive) {
|
||||||
vel.valCount --;
|
vel.valCount --;
|
||||||
vel.sum += vel.value;
|
vel.sum += vel.value;
|
||||||
vel.value *= 0.93; // vel.frictionFactor;
|
vel.value *= 0.93; // vel.frictionFactor;
|
||||||
@ -540,12 +541,12 @@ public class MovingData extends ACheckData {
|
|||||||
}
|
}
|
||||||
// Decrease counts for queued.
|
// Decrease counts for queued.
|
||||||
final Iterator<Velocity> it = hVelQueued.iterator();
|
final Iterator<Velocity> it = hVelQueued.iterator();
|
||||||
while (it.hasNext()){
|
while (it.hasNext()) {
|
||||||
it.next().actCount --;
|
it.next().actCount --;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical velocity (old concept).
|
// Vertical velocity (old concept).
|
||||||
if (verticalVelocity <= 0.09D){
|
if (verticalVelocity <= 0.09D) {
|
||||||
verticalVelocityUsed ++;
|
verticalVelocityUsed ++;
|
||||||
verticalVelocityCounter--;
|
verticalVelocityCounter--;
|
||||||
}
|
}
|
||||||
@ -554,8 +555,8 @@ public class MovingData extends ACheckData {
|
|||||||
verticalFreedom += verticalVelocity;
|
verticalFreedom += verticalVelocity;
|
||||||
verticalVelocity = Math.max(0.0, verticalVelocity -0.09);
|
verticalVelocity = Math.max(0.0, verticalVelocity -0.09);
|
||||||
// TODO: Consider using up counter ? / better use velocity entries / even better use x,y,z entries right away .
|
// TODO: Consider using up counter ? / better use velocity entries / even better use x,y,z entries right away .
|
||||||
} else if (verticalFreedom > 0.001D){
|
} else if (verticalFreedom > 0.001D) {
|
||||||
if (verticalVelocityUsed == 1 && verticalVelocity > 1.0){
|
if (verticalVelocityUsed == 1 && verticalVelocity > 1.0) {
|
||||||
// Workarounds.
|
// Workarounds.
|
||||||
verticalVelocityUsed = 0;
|
verticalVelocityUsed = 0;
|
||||||
verticalVelocity = 0;
|
verticalVelocity = 0;
|
||||||
@ -576,7 +577,7 @@ public class MovingData extends ACheckData {
|
|||||||
public double getHorizontalFreedom() {
|
public double getHorizontalFreedom() {
|
||||||
// TODO: model/calculate it as accurate as possible...
|
// TODO: model/calculate it as accurate as possible...
|
||||||
double f = 0;
|
double f = 0;
|
||||||
for (final Velocity vel : hVelActive){
|
for (final Velocity vel : hVelActive) {
|
||||||
f += vel.value;
|
f += vel.value;
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
@ -593,12 +594,12 @@ public class MovingData extends ACheckData {
|
|||||||
public double useHorizontalVelocity(final double amount) {
|
public double useHorizontalVelocity(final double amount) {
|
||||||
final Iterator<Velocity> it = hVelQueued.iterator();
|
final Iterator<Velocity> it = hVelQueued.iterator();
|
||||||
double used = 0;
|
double used = 0;
|
||||||
while (it.hasNext()){
|
while (it.hasNext()) {
|
||||||
final Velocity vel = it.next();
|
final Velocity vel = it.next();
|
||||||
used += vel.value;
|
used += vel.value;
|
||||||
hVelActive.add(vel);
|
hVelActive.add(vel);
|
||||||
it.remove();
|
it.remove();
|
||||||
if (used >= amount){
|
if (used >= amount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -612,10 +613,10 @@ public class MovingData extends ACheckData {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isSetBack(final Location loc) {
|
public boolean isSetBack(final Location loc) {
|
||||||
if (loc == null || setBack == null){
|
if (loc == null || setBack == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!loc.getWorld().getName().equals(setBack.getWorld().getName())){
|
if (!loc.getWorld().getName().equals(setBack.getWorld().getName())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return loc.getX() == setBack.getX() && loc.getY() == setBack.getY() && loc.getZ() == setBack.getZ();
|
return loc.getX() == setBack.getX() && loc.getY() == setBack.getY() && loc.getZ() == setBack.getZ();
|
||||||
@ -632,15 +633,15 @@ public class MovingData extends ACheckData {
|
|||||||
* Clean up data related to worlds with the given name (not case-sensitive).
|
* Clean up data related to worlds with the given name (not case-sensitive).
|
||||||
* @param worldName
|
* @param worldName
|
||||||
*/
|
*/
|
||||||
public void onWorldUnload(final String worldName){
|
public void onWorldUnload(final String worldName) {
|
||||||
// TODO: Unlink world references.
|
// TODO: Unlink world references.
|
||||||
if (teleported != null && worldName.equalsIgnoreCase(teleported.getWorld().getName())){
|
if (teleported != null && worldName.equalsIgnoreCase(teleported.getWorld().getName())) {
|
||||||
resetTeleported();
|
resetTeleported();
|
||||||
}
|
}
|
||||||
if (setBack != null && worldName.equalsIgnoreCase(setBack.getWorld().getName())){
|
if (setBack != null && worldName.equalsIgnoreCase(setBack.getWorld().getName())) {
|
||||||
clearFlyData();
|
clearFlyData();
|
||||||
}
|
}
|
||||||
if (morePacketsSetback != null && worldName.equalsIgnoreCase(morePacketsSetback.getWorld().getName()) || morePacketsVehicleSetback != null && worldName.equalsIgnoreCase(morePacketsVehicleSetback.getWorld().getName())){
|
if (morePacketsSetback != null && worldName.equalsIgnoreCase(morePacketsSetback.getWorld().getName()) || morePacketsVehicleSetback != null && worldName.equalsIgnoreCase(morePacketsVehicleSetback.getWorld().getName())) {
|
||||||
clearMorePacketsData();
|
clearMorePacketsData();
|
||||||
clearNoFallData(); // just in case.
|
clearNoFallData(); // just in case.
|
||||||
}
|
}
|
||||||
@ -650,7 +651,7 @@ public class MovingData extends ACheckData {
|
|||||||
if (walkSpeed > this.walkSpeed) {
|
if (walkSpeed > this.walkSpeed) {
|
||||||
this.walkSpeed = walkSpeed;
|
this.walkSpeed = walkSpeed;
|
||||||
this.speedTick = tick;
|
this.speedTick = tick;
|
||||||
} else if (walkSpeed < this.walkSpeed){
|
} else if (walkSpeed < this.walkSpeed) {
|
||||||
if (tick - this.speedTick > speedGrace) {
|
if (tick - this.speedTick > speedGrace) {
|
||||||
this.walkSpeed = walkSpeed;
|
this.walkSpeed = walkSpeed;
|
||||||
this.speedTick = tick;
|
this.speedTick = tick;
|
||||||
@ -664,7 +665,7 @@ public class MovingData extends ACheckData {
|
|||||||
if (flySpeed > this.flySpeed) {
|
if (flySpeed > this.flySpeed) {
|
||||||
this.flySpeed = flySpeed;
|
this.flySpeed = flySpeed;
|
||||||
this.speedTick = tick;
|
this.speedTick = tick;
|
||||||
} else if (flySpeed < this.flySpeed){
|
} else if (flySpeed < this.flySpeed) {
|
||||||
if (tick - this.speedTick > speedGrace) {
|
if (tick - this.speedTick > speedGrace) {
|
||||||
this.flySpeed = flySpeed;
|
this.flySpeed = flySpeed;
|
||||||
this.speedTick = tick;
|
this.speedTick = tick;
|
||||||
|
@ -106,7 +106,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
* @param cc
|
* @param cc
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static final boolean shouldCheckSurvivalFly(final Player player, final MovingData data, final MovingConfig cc){
|
public static final boolean shouldCheckSurvivalFly(final Player player, final MovingData data, final MovingConfig cc) {
|
||||||
return cc.survivalFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_SURVIVALFLY) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY) &&
|
return cc.survivalFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_SURVIVALFLY) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY) &&
|
||||||
(cc.ignoreCreative || player.getGameMode() != GameMode.CREATIVE) && !player.isFlying() && (cc.ignoreAllowFlight || !player.getAllowFlight());
|
(cc.ignoreCreative || player.getGameMode() != GameMode.CREATIVE) && !player.isFlying() && (cc.ignoreAllowFlight || !player.getAllowFlight());
|
||||||
}
|
}
|
||||||
@ -127,14 +127,14 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
if (!restored && data.hasSetBack()) {
|
if (!restored && data.hasSetBack()) {
|
||||||
final Location setBack = data.getSetBack(loc);
|
final Location setBack = data.getSetBack(loc);
|
||||||
pLoc.set(setBack, player);
|
pLoc.set(setBack, player);
|
||||||
if (!pLoc.isIllegal()){
|
if (!pLoc.isIllegal()) {
|
||||||
event.setFrom(setBack);
|
event.setFrom(setBack);
|
||||||
event.setTo(setBack);
|
event.setTo(setBack);
|
||||||
restored = true;
|
restored = true;
|
||||||
}
|
}
|
||||||
else data.resetSetBack();
|
else data.resetSetBack();
|
||||||
}
|
}
|
||||||
if (!restored){
|
if (!restored) {
|
||||||
pLoc.set(loc, player);
|
pLoc.set(loc, player);
|
||||||
if (!pLoc.isIllegal()) {
|
if (!pLoc.isIllegal()) {
|
||||||
event.setFrom(loc);
|
event.setFrom(loc);
|
||||||
@ -143,7 +143,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pLoc.cleanup();
|
pLoc.cleanup();
|
||||||
if (!restored && MovingConfig.getConfig(player).tempKickIllegal){
|
if (!restored && MovingConfig.getConfig(player).tempKickIllegal) {
|
||||||
// TODO: correct the location ?
|
// TODO: correct the location ?
|
||||||
NCPAPIProvider.getNoCheatPlusAPI().denyLogin(player.getName(), 24L * 60L * 60L * 1000L);
|
NCPAPIProvider.getNoCheatPlusAPI().denyLogin(player.getName(), 24L * 60L * 60L * 1000L);
|
||||||
LogUtil.logSevere("[NCP] could not restore location for " + player.getName() + " deny login for 24 hours");
|
LogUtil.logSevere("[NCP] could not restore location for " + player.getName() + " deny login for 24 hours");
|
||||||
@ -255,7 +255,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
* @param id
|
* @param id
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static boolean canJumpOffTop(final int id){
|
private static boolean canJumpOffTop(final int id) {
|
||||||
// TODO: Test if this can be removed!
|
// TODO: Test if this can be removed!
|
||||||
return BlockProperties.isGround(id) || BlockProperties.isSolid(id);
|
return BlockProperties.isGround(id) || BlockProperties.isSolid(id);
|
||||||
}
|
}
|
||||||
@ -308,13 +308,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
Location target = null;
|
Location target = null;
|
||||||
final boolean sfCheck = shouldCheckSurvivalFly(player, data, cc);
|
final boolean sfCheck = shouldCheckSurvivalFly(player, data, cc);
|
||||||
if (sfCheck) target = data.getSetBack(loc);
|
if (sfCheck) target = data.getSetBack(loc);
|
||||||
if (target == null){
|
if (target == null) {
|
||||||
// TODO: Add something to guess the best set back location (possibly data.guessSetBack(Location)).
|
// TODO: Add something to guess the best set back location (possibly data.guessSetBack(Location)).
|
||||||
target = loc;
|
target = loc;
|
||||||
}
|
}
|
||||||
if (target != null){
|
if (target != null) {
|
||||||
// Actually this should not possibly be null, this is a block for "future" purpose, feel free to criticize it.
|
// Actually this should not possibly be null, this is a block for "future" purpose, feel free to criticize it.
|
||||||
if (sfCheck && cc.sfFallDamage && noFall.isEnabled(player)){
|
if (sfCheck && cc.sfFallDamage && noFall.isEnabled(player)) {
|
||||||
// Check if to deal damage.
|
// Check if to deal damage.
|
||||||
double y = loc.getY();
|
double y = loc.getY();
|
||||||
if (data.hasSetBack()) y = Math.min(y, data.getSetBackY());
|
if (data.hasSetBack()) y = Math.min(y, data.getSetBackY());
|
||||||
@ -381,10 +381,11 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
* \____|_| |_|\__,_|_| |_|\__, |\___|
|
* \____|_| |_|\__,_|_| |_|\__, |\___|
|
||||||
* |___/
|
* |___/
|
||||||
*/
|
*/
|
||||||
if (event.getPlayer().getGameMode() == GameMode.CREATIVE || event.getNewGameMode() == GameMode.CREATIVE){
|
if (event.getPlayer().getGameMode() == GameMode.CREATIVE || event.getNewGameMode() == GameMode.CREATIVE) {
|
||||||
final MovingData data = MovingData.getData(event.getPlayer());
|
final MovingData data = MovingData.getData(event.getPlayer());
|
||||||
data.clearFlyData();
|
data.clearFlyData();
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
|
// TODO: Set new set-back if any fly check is activated.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,59 +417,53 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
|
|
||||||
final MovingData data = MovingData.getData(player);
|
final MovingData data = MovingData.getData(player);
|
||||||
|
|
||||||
// TODO: Check illegal moves here anyway (!).
|
|
||||||
|
|
||||||
// Ignore players in vehicles.
|
|
||||||
if (player.isInsideVehicle()){
|
|
||||||
// Workaround for pigs and other (1.5.x and before)!
|
|
||||||
// Note that with 1.6 not even PlayerMove fires for horses and pigs.
|
|
||||||
// (isInsideVehicle is the faster check without object creation, do re-check though, if it changes to only check for Vehicle instances.)
|
|
||||||
final Entity vehicle = CheckUtils.getLastNonPlayerVehicle(player);
|
|
||||||
data.wasInVehicle = true;
|
|
||||||
data.sfHoverTicks = -1;
|
|
||||||
data.removeAllVelocity();
|
|
||||||
data.sfLowJump = false;
|
|
||||||
if (vehicle != null){
|
|
||||||
final Location vLoc = vehicle.getLocation();
|
|
||||||
// (Auto detection of missing events, might fire one time too many per plugin run.)
|
|
||||||
if (!normalVehicles.contains(vehicle.getType())) {
|
|
||||||
onVehicleMove(vehicle, vLoc, vLoc, true);
|
|
||||||
} else {
|
|
||||||
data.vehicleConsistency = MoveConsistency.getConsistency(event.getFrom(), event.getTo(), vLoc);
|
|
||||||
// TODO: Consider TeleportUtil.forceMount or similar.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore dead players.
|
|
||||||
if (player.isDead()){
|
|
||||||
data.sfHoverTicks = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore sleeping players.
|
|
||||||
if (player.isSleeping()){
|
|
||||||
data.sfHoverTicks = -1;
|
|
||||||
// TODO: check (which cb!) System.out.println("-> " + player.isSleepingIgnored());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Location from = event.getFrom();
|
final Location from = event.getFrom();
|
||||||
final Location to = event.getTo();
|
final Location to = event.getTo();
|
||||||
|
Location newTo = null;
|
||||||
|
|
||||||
// Ignore changing worlds.
|
// TODO: Check illegal moves here anyway (!).
|
||||||
if (!from.getWorld().equals(to.getWorld())){
|
// TODO: Check if vehicle move logs correctly (fake).
|
||||||
|
|
||||||
|
// Early return checks (no full processing).
|
||||||
|
final boolean earlyReturn;
|
||||||
|
if (player.isInsideVehicle()) {
|
||||||
|
// No full processing for players in vehicles.
|
||||||
|
newTo = onPlayerMoveVehicle(player, from, to, data);
|
||||||
|
earlyReturn = true;
|
||||||
|
} else if (player.isDead() || player.isSleeping()) {
|
||||||
|
// Ignore dead players.
|
||||||
|
data.sfHoverTicks = -1;
|
||||||
|
earlyReturn = true;
|
||||||
|
} else if (player.isSleeping()) {
|
||||||
|
// Ignore sleeping playerrs.
|
||||||
|
// TODO: sleeping: (which cb!) System.out.println("-> " + player.isSleepingIgnored());
|
||||||
|
data.sfHoverTicks = -1;
|
||||||
|
earlyReturn = true;
|
||||||
|
} else if (!from.getWorld().equals(to.getWorld())) {
|
||||||
// Keep hover ticks.
|
// Keep hover ticks.
|
||||||
|
// Ignore changing worlds.
|
||||||
|
earlyReturn = true;
|
||||||
|
} else {
|
||||||
|
// COntinue with full processing.
|
||||||
|
earlyReturn = false;
|
||||||
|
}
|
||||||
|
// TODO: Might log base parts here (+extras).
|
||||||
|
if (earlyReturn) {
|
||||||
|
// TODO: Log "early return: " + tags.
|
||||||
|
if (newTo != null) {
|
||||||
|
event.setTo(newTo);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Order this to above "early return"?
|
||||||
// Set up data / caching.
|
// Set up data / caching.
|
||||||
final MoveInfo moveInfo;
|
final MoveInfo moveInfo;
|
||||||
if (parkedInfo.isEmpty()) moveInfo = new MoveInfo(mcAccess);
|
if (parkedInfo.isEmpty()) moveInfo = new MoveInfo(mcAccess);
|
||||||
else moveInfo = parkedInfo.remove(parkedInfo.size() - 1);
|
else moveInfo = parkedInfo.remove(parkedInfo.size() - 1);
|
||||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
moveInfo.set(player, from, to, cc.yOnGround);
|
moveInfo.set(player, from, to, cc.yOnGround);
|
||||||
|
// TODO: Data resetting above ?
|
||||||
data.noFallAssumeGround = false;
|
data.noFallAssumeGround = false;
|
||||||
data.resetTeleported();
|
data.resetTeleported();
|
||||||
// Debug.
|
// Debug.
|
||||||
@ -484,12 +479,12 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
final long time = System.currentTimeMillis();
|
final long time = System.currentTimeMillis();
|
||||||
if (player.isSprinting()){
|
if (player.isSprinting()) {
|
||||||
//
|
//
|
||||||
if (player.getFoodLevel() > 5){
|
if (player.getFoodLevel() > 5) {
|
||||||
data.timeSprinting = time;
|
data.timeSprinting = time;
|
||||||
}
|
}
|
||||||
else if (time < data.timeSprinting){
|
else if (time < data.timeSprinting) {
|
||||||
data.timeSprinting = 0;
|
data.timeSprinting = 0;
|
||||||
}
|
}
|
||||||
// else: keep sprinting time.
|
// else: keep sprinting time.
|
||||||
@ -506,17 +501,8 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
pTo = moveInfo.to;
|
pTo = moveInfo.to;
|
||||||
|
|
||||||
// HOT FIX - for VehicleLeaveEvent missing.
|
// HOT FIX - for VehicleLeaveEvent missing.
|
||||||
if (data.wasInVehicle){
|
if (data.wasInVehicle) {
|
||||||
if (cc.debug){
|
onVehicleLeaveMiss(player, data, cc);
|
||||||
LogUtil.logWarning("[NoCheatPlus] VehicleExitEvent missing for: " + player.getName());
|
|
||||||
}
|
|
||||||
onPlayerVehicleLeave(player, null);
|
|
||||||
// if (BlockProperties.isRails(pFrom.getTypeId())){
|
|
||||||
// Always clear no fall data, let Minecraft do fall damage.
|
|
||||||
data.noFallSkipAirCheck = true; // Might allow one time cheat.
|
|
||||||
data.sfLowJump = false;
|
|
||||||
data.clearNoFallData();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Potion effect "Jump".
|
// Potion effect "Jump".
|
||||||
@ -536,15 +522,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
// TODO: Change to getLocation(moveInfo.loc) once 1.4.5 support is dropped.
|
// TODO: Change to getLocation(moveInfo.loc) once 1.4.5 support is dropped.
|
||||||
final Location loc = (cc.noFallCheck || cc.passableCheck) ? player.getLocation() : null;
|
final Location loc = (cc.noFallCheck || cc.passableCheck) ? player.getLocation() : null;
|
||||||
|
|
||||||
Location newTo = null;
|
|
||||||
|
|
||||||
// Check passable first to prevent set-back override.
|
// Check passable first to prevent set-back override.
|
||||||
// TODO: Redesign to set set-backs later (queue + invalidate).
|
// TODO: Redesign to set set-backs later (queue + invalidate).
|
||||||
boolean mightSkipNoFall = false; // If to skip nofall check (mainly on violation of other checks).
|
boolean mightSkipNoFall = false; // If to skip nofall check (mainly on violation of other checks).
|
||||||
if (newTo == null && cc.passableCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_PASSABLE) && !player.hasPermission(Permissions.MOVING_PASSABLE)) {
|
if (newTo == null && cc.passableCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_PASSABLE) && !player.hasPermission(Permissions.MOVING_PASSABLE)) {
|
||||||
// Passable is checked first to get the original set-back locations from the other checks, if needed.
|
// Passable is checked first to get the original set-back locations from the other checks, if needed.
|
||||||
newTo = passable.check(player, loc, pFrom, pTo, data, cc);
|
newTo = passable.check(player, loc, pFrom, pTo, data, cc);
|
||||||
if (newTo != null){
|
if (newTo != null) {
|
||||||
// Check if to skip the nofall check.
|
// Check if to skip the nofall check.
|
||||||
mightSkipNoFall = true;
|
mightSkipNoFall = true;
|
||||||
}
|
}
|
||||||
@ -553,13 +537,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
// Check which fly check to use.
|
// Check which fly check to use.
|
||||||
final boolean checkCf;
|
final boolean checkCf;
|
||||||
final boolean checkSf;
|
final boolean checkSf;
|
||||||
if (shouldCheckSurvivalFly(player, data, cc)){
|
if (shouldCheckSurvivalFly(player, data, cc)) {
|
||||||
checkCf = false;
|
checkCf = false;
|
||||||
checkSf = true;
|
checkSf = true;
|
||||||
data.adjustWalkSpeed(player.getWalkSpeed(), tick, cc.speedGrace);
|
data.adjustWalkSpeed(player.getWalkSpeed(), tick, cc.speedGrace);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (cc.creativeFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_CREATIVEFLY) && !player.hasPermission(Permissions.MOVING_CREATIVEFLY)){
|
else if (cc.creativeFlyCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_CREATIVEFLY) && !player.hasPermission(Permissions.MOVING_CREATIVEFLY)) {
|
||||||
checkCf = true;
|
checkCf = true;
|
||||||
checkSf = false;
|
checkSf = false;
|
||||||
data.adjustFlySpeed(player.getFlySpeed(), tick, cc.speedGrace);
|
data.adjustFlySpeed(player.getFlySpeed(), tick, cc.speedGrace);
|
||||||
@ -570,14 +554,14 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Flying checks.
|
// Flying checks.
|
||||||
if (checkSf){
|
if (checkSf) {
|
||||||
// SurvivalFly
|
// SurvivalFly
|
||||||
|
|
||||||
// Collect block flags.
|
// Collect block flags.
|
||||||
// TODO: Could further differentiate if really needed to (newTo / NoFall).
|
// TODO: Could further differentiate if really needed to (newTo / NoFall).
|
||||||
final double maxYNoFall = Math.max(cc.noFallyOnGround, cc.yOnGround);
|
final double maxYNoFall = Math.max(cc.noFallyOnGround, cc.yOnGround);
|
||||||
pFrom.collectBlockFlags(maxYNoFall);
|
pFrom.collectBlockFlags(maxYNoFall);
|
||||||
if (pFrom.isSamePos(pTo)){
|
if (pFrom.isSamePos(pTo)) {
|
||||||
// TODO: Could consider pTo = pFrom, set pitch / yaw elsewhere.
|
// TODO: Could consider pTo = pFrom, set pitch / yaw elsewhere.
|
||||||
// Sets all properties, but only once.
|
// Sets all properties, but only once.
|
||||||
pTo.prepare(pFrom);
|
pTo.prepare(pFrom);
|
||||||
@ -588,15 +572,15 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actual check.
|
// Actual check.
|
||||||
if (newTo == null){
|
if (newTo == null) {
|
||||||
// Only check if passable has not already set back.
|
// Only check if passable has not already set back.
|
||||||
newTo = survivalFly.check(player, pFrom, pTo, data, cc, time);
|
newTo = survivalFly.check(player, pFrom, pTo, data, cc, time);
|
||||||
}
|
}
|
||||||
final boolean checkNf = cc.noFallCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_NOFALL) && !player.hasPermission(Permissions.MOVING_NOFALL);
|
final boolean checkNf = cc.noFallCheck && !NCPExemptionManager.isExempted(player, CheckType.MOVING_NOFALL) && !player.hasPermission(Permissions.MOVING_NOFALL);
|
||||||
if (newTo == null){
|
if (newTo == null) {
|
||||||
// Hover.
|
// Hover.
|
||||||
// TODO: Could reset for from-on-ground as well, for not too big moves.
|
// TODO: Could reset for from-on-ground as well, for not too big moves.
|
||||||
if (cc.sfHoverCheck && !data.toWasReset && !pTo.isOnGround()){
|
if (cc.sfHoverCheck && !data.toWasReset && !pTo.isOnGround()) {
|
||||||
// Start counting ticks.
|
// Start counting ticks.
|
||||||
hoverTicks.add(playerName);
|
hoverTicks.add(playerName);
|
||||||
data.sfHoverTicks = 0;
|
data.sfHoverTicks = 0;
|
||||||
@ -605,34 +589,34 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
data.sfHoverTicks = -1;
|
data.sfHoverTicks = -1;
|
||||||
}
|
}
|
||||||
// NoFall.
|
// NoFall.
|
||||||
if (checkNf){
|
if (checkNf) {
|
||||||
noFall.check(player, loc, pFrom, pTo, data, cc);
|
noFall.check(player, loc, pFrom, pTo, data, cc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (checkNf && cc.sfFallDamage){
|
if (checkNf && cc.sfFallDamage) {
|
||||||
if (mightSkipNoFall){
|
if (mightSkipNoFall) {
|
||||||
// Check if to really skip.
|
// Check if to really skip.
|
||||||
if (!pFrom.isOnGround() && !pFrom.isResetCond()){
|
if (!pFrom.isOnGround() && !pFrom.isResetCond()) {
|
||||||
mightSkipNoFall = false;
|
mightSkipNoFall = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mightSkipNoFall){
|
if (!mightSkipNoFall) {
|
||||||
noFall.checkDamage(player, data, Math.min(Math.min(from.getY(), to.getY()), loc.getY()));
|
noFall.checkDamage(player, data, Math.min(Math.min(from.getY(), to.getY()), loc.getY()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (checkCf){
|
else if (checkCf) {
|
||||||
// CreativeFly
|
// CreativeFly
|
||||||
if (newTo == null){
|
if (newTo == null) {
|
||||||
newTo = creativeFly.check(player, pFrom, pTo, data, cc, time);
|
newTo = creativeFly.check(player, pFrom, pTo, data, cc, time);
|
||||||
}
|
}
|
||||||
data.sfHoverTicks = -1;
|
data.sfHoverTicks = -1;
|
||||||
data.sfLowJump = false;
|
data.sfLowJump = false;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// No fly :).
|
// No fly checking :(.
|
||||||
data.clearFlyData();
|
data.clearFlyData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,8 +631,8 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset jump amplifier if needed.
|
// Reset jump amplifier if needed.
|
||||||
if ((checkSf || checkCf) && jumpAmplifier != data.jumpAmplifier){
|
if ((checkSf || checkCf) && jumpAmplifier != data.jumpAmplifier) {
|
||||||
if (data.noFallAssumeGround || pFrom.isOnGround() || pTo.isOnGround()){
|
if (data.noFallAssumeGround || pFrom.isOnGround() || pTo.isOnGround()) {
|
||||||
data.jumpAmplifier = jumpAmplifier;
|
data.jumpAmplifier = jumpAmplifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +648,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
event.setTo(newTo);
|
event.setTo(newTo);
|
||||||
|
|
||||||
// Debug.
|
// Debug.
|
||||||
if (cc.debug){
|
if (cc.debug) {
|
||||||
System.out.println(player.getName() + " set back to: " + newTo.getWorld() + StringUtil.fdec3.format(newTo.getX()) + ", " + StringUtil.fdec3.format(newTo.getY()) + ", " + StringUtil.fdec3.format(newTo.getZ()));
|
System.out.println(player.getName() + " set back to: " + newTo.getWorld() + StringUtil.fdec3.format(newTo.getX()) + ", " + StringUtil.fdec3.format(newTo.getY()) + ", " + StringUtil.fdec3.format(newTo.getZ()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -683,46 +667,76 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
parkedInfo.add(moveInfo);
|
parkedInfo.add(moveInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * A workaround for cancelled PlayerMoveEvents.
|
* Called from player-move checking, if the player is inside of a vehicle.
|
||||||
// *
|
* @param player
|
||||||
// * @param event
|
* @param from
|
||||||
// * the event
|
* @param to
|
||||||
// */
|
* @param data
|
||||||
// @EventHandler(priority = EventPriority.HIGHEST)
|
*/
|
||||||
// public void onPlayerMoveHighest(final PlayerMoveEvent event) {
|
private Location onPlayerMoveVehicle(final Player player, final Location from, final Location to, final MovingData data) {
|
||||||
// /*
|
// Workaround for pigs and other (1.5.x and before)!
|
||||||
// * _____ _ __ __
|
// Note that with 1.6 not even PlayerMove fires for horses and pigs.
|
||||||
// * | __ \| | | \/ |
|
// (isInsideVehicle is the faster check without object creation, do re-check though, if it changes to only check for Vehicle instances.)
|
||||||
// * | |__) | | __ _ _ _ ___ _ __ | \ / | _____ _____
|
final Entity vehicle = CheckUtils.getLastNonPlayerVehicle(player);
|
||||||
// * | ___/| |/ _` | | | |/ _ \ '__| | |\/| |/ _ \ \ / / _ \
|
data.wasInVehicle = true;
|
||||||
// * | | | | (_| | |_| | __/ | | | | | (_) \ V / __/
|
data.sfHoverTicks = -1;
|
||||||
// * |_| |_|\__,_|\__, |\___|_| |_| |_|\___/ \_/ \___|
|
data.removeAllVelocity();
|
||||||
// * __/ |
|
data.sfLowJump = false;
|
||||||
// * |___/
|
// TODO: What with processingEvents.remove(player.getName());
|
||||||
// */
|
if (vehicle != null) {
|
||||||
// // No typo here. I really only handle cancelled events and ignore others.
|
final Location vLoc = vehicle.getLocation();
|
||||||
// if (!event.isCancelled() || event.getPlayer().isDead())
|
// (Auto detection of missing events, might fire one time too many per plugin run.)
|
||||||
// return;
|
if (!normalVehicles.contains(vehicle.getType())) {
|
||||||
//
|
onVehicleMove(vehicle, vLoc, vLoc, true);
|
||||||
// // Fix a common mistake that other developers make (cancelling move events is crazy, rather set the target
|
return null;
|
||||||
// // location to the from location).
|
} else {
|
||||||
// event.setCancelled(false);
|
data.vehicleConsistency = MoveConsistency.getConsistency(from, to, vLoc);
|
||||||
// event.setTo(event.getFrom()); // TODO: revise this (old!) strategy, cancelled events just teleport to from, basically.
|
// TODO: Consider TeleportUtil.forceMount or similar.
|
||||||
|
if (data.vehicleConsistency == MoveConsistency.INCONSISTENT) {
|
||||||
|
return vLoc;
|
||||||
|
} else {
|
||||||
|
data.resetPositions(vLoc);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from player-move checking, if vehicle-leave has not been called after entering, but the player is not inside of a vehicle anymore.
|
||||||
|
* @param player
|
||||||
|
* @param data
|
||||||
|
* @param cc
|
||||||
|
*/
|
||||||
|
private void onVehicleLeaveMiss(final Player player, final MovingData data, final MovingConfig cc) {
|
||||||
|
if (cc.debug) {
|
||||||
|
LogUtil.logWarning("[NoCheatPlus] VehicleExitEvent missing for: " + player.getName());
|
||||||
|
}
|
||||||
|
onPlayerVehicleLeave(player, null);
|
||||||
|
// if (BlockProperties.isRails(pFrom.getTypeId())) {
|
||||||
|
// Always clear no fall data, let Minecraft do fall damage.
|
||||||
|
data.noFallSkipAirCheck = true; // Might allow one time cheat.
|
||||||
|
data.sfLowJump = false;
|
||||||
|
data.clearNoFallData();
|
||||||
|
// TODO: What with processingEvents.remove(player.getName());
|
||||||
// }
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor level PlayerMoveEvent.
|
* Monitor level PlayerMoveEvent.
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled = false)
|
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled = false)
|
||||||
public void onPlayerMoveMonitor(final PlayerMoveEvent event){
|
public void onPlayerMoveMonitor(final PlayerMoveEvent event) {
|
||||||
// TODO: revise: cancelled events.
|
// TODO: revise: cancelled events.
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
|
|
||||||
if (processingEvents.remove(player.getName()) == null){
|
if (processingEvents.remove(player.getName()) == null) {
|
||||||
// This means moving data has been reset by a teleport.
|
// This means moving data has been reset by a teleport.
|
||||||
|
// TODO: vehicles, cancelled, ...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,12 +750,16 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final String fromWorldName = from.getWorld().getName();
|
final String fromWorldName = from.getWorld().getName();
|
||||||
|
|
||||||
// Feed yawrate and reset moving data positions if necessary.
|
// Feed yawrate and reset moving data positions if necessary.
|
||||||
if (!event.isCancelled()){
|
if (!event.isCancelled()) {
|
||||||
final Location to = event.getTo();
|
final Location to = event.getTo();
|
||||||
final String toWorldName = to.getWorld().getName();
|
final String toWorldName = to.getWorld().getName();
|
||||||
Combined.feedYawRate(player, to.getYaw(), now, toWorldName, data);
|
Combined.feedYawRate(player, to.getYaw(), now, toWorldName, data);
|
||||||
// TODO: maybe even not count vehicles at all ?
|
// TODO: maybe even not count vehicles at all ?
|
||||||
if (player.isInsideVehicle() || !fromWorldName.equals(toWorldName)){
|
if (player.isInsideVehicle()) {
|
||||||
|
// TODO: refine (!).
|
||||||
|
MovingData.getData(player).resetPositions(player.getVehicle().getLocation());
|
||||||
|
}
|
||||||
|
else if (!fromWorldName.equals(toWorldName)) {
|
||||||
MovingData.getData(player).resetPositions(to);
|
MovingData.getData(player).resetPositions(to);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -776,6 +794,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final MovingData data = MovingData.getData(event.getPlayer());
|
final MovingData data = MovingData.getData(event.getPlayer());
|
||||||
data.clearFlyData();
|
data.clearFlyData();
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
|
// TODO: This event might be redundant (!).
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -799,12 +818,12 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final MovingData data = MovingData.getData(player);
|
final MovingData data = MovingData.getData(player);
|
||||||
data.clearFlyData();
|
data.clearFlyData();
|
||||||
data.clearMorePacketsData();
|
data.clearMorePacketsData();
|
||||||
data.resetSetBack();
|
data.setSetBack(event.getRespawnLocation());
|
||||||
// TODO: consider data.resetPositions(data.setBack);
|
// TODO: consider data.resetPositions(data.setBack);
|
||||||
// (Not putting hover in at respawn due to chunk sending.)
|
// (Not putting hover in at respawn due to chunk sending.)
|
||||||
// TODO: Might use grace ticks for this too (and bigger teleports).
|
// TODO: Might use grace ticks for this too (and bigger teleports).
|
||||||
// final MovingConfig cc = MovingConfig.getConfig(player);
|
// final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
// if (cc.sfHoverCheck){
|
// if (cc.sfHoverCheck) {
|
||||||
// // Assume the player might be hovering.
|
// // Assume the player might be hovering.
|
||||||
// data.sfHoverTicks = 0;
|
// data.sfHoverTicks = 0;
|
||||||
// hoverTicks.add(player.getName());
|
// hoverTicks.add(player.getName());
|
||||||
@ -869,7 +888,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
} else {
|
} else {
|
||||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
// Only if it wasn't NoCheatPlus, drop data from more packets check.
|
// Only if it wasn't NoCheatPlus, drop data from more packets check.
|
||||||
if (to != null && !event.isCancelled()){
|
if (to != null && !event.isCancelled()) {
|
||||||
// Normal teleport.
|
// Normal teleport.
|
||||||
|
|
||||||
// Detect small distance teleports.
|
// Detect small distance teleports.
|
||||||
@ -882,22 +901,22 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
|
|
||||||
|
|
||||||
final TeleportCause cause = event.getCause();
|
final TeleportCause cause = event.getCause();
|
||||||
if (cause == TeleportCause.UNKNOWN){
|
if (cause == TeleportCause.UNKNOWN) {
|
||||||
// Check special small range teleports (moved too quickly).
|
// Check special small range teleports (moved too quickly).
|
||||||
if (from != null && from.getWorld().equals(to.getWorld())){
|
if (from != null && from.getWorld().equals(to.getWorld())) {
|
||||||
if (TrigUtil.distance(from, to) < margin){
|
if (TrigUtil.distance(from, to) < margin) {
|
||||||
smallRange = true;
|
smallRange = true;
|
||||||
}
|
}
|
||||||
else if (data.toX != Double.MAX_VALUE && data.hasSetBack()){
|
else if (data.toX != Double.MAX_VALUE && data.hasSetBack()) {
|
||||||
final Location setBack = data.getSetBack(to);
|
final Location setBack = data.getSetBack(to);
|
||||||
if (TrigUtil.distance(to.getX(), to.getY(), to.getZ(), setBack.getX(), setBack.getY(), setBack.getZ()) < margin){
|
if (TrigUtil.distance(to.getX(), to.getY(), to.getZ(), setBack.getX(), setBack.getY(), setBack.getZ()) < margin) {
|
||||||
smallRange = true;
|
smallRange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cause == TeleportCause.ENDER_PEARL){
|
else if (cause == TeleportCause.ENDER_PEARL) {
|
||||||
if (CombinedConfig.getConfig(player). enderPearlCheck && !BlockProperties.isPassable(to)){ // || !BlockProperties.isOnGroundOrResetCond(player, to, 1.0)){
|
if (CombinedConfig.getConfig(player). enderPearlCheck && !BlockProperties.isPassable(to)) { // || !BlockProperties.isOnGroundOrResetCond(player, to, 1.0)) {
|
||||||
// Not check on-ground: Check the second throw.
|
// Not check on-ground: Check the second throw.
|
||||||
cancel = true;
|
cancel = true;
|
||||||
}
|
}
|
||||||
@ -906,13 +925,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (pass){
|
// if (pass) {
|
||||||
// ref = to;
|
// ref = to;
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
if (cancel){
|
if (cancel) {
|
||||||
// Cancel!
|
// Cancel!
|
||||||
if (data.hasSetBack() && !data.hasSetBackWorldChanged(to)){
|
if (data.hasSetBack() && !data.hasSetBackWorldChanged(to)) {
|
||||||
ref = data.getSetBack(to);
|
ref = data.getSetBack(to);
|
||||||
event.setTo(ref);
|
event.setTo(ref);
|
||||||
}
|
}
|
||||||
@ -921,15 +940,15 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (smallRange){
|
else if (smallRange) {
|
||||||
// Very small range teleport, keep set back etc.
|
// Very small range teleport, keep set back etc.
|
||||||
ref = to;
|
ref = to;
|
||||||
// if (data.hasSetBack() && !data.hasSetBackWorldChanged(to)){
|
// if (data.hasSetBack() && !data.hasSetBackWorldChanged(to)) {
|
||||||
// final Location setBack = data.getSetBack(from);
|
// final Location setBack = data.getSetBack(from);
|
||||||
// Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() {
|
// Bukkit.getScheduler().scheduleSyncDelayedTask(this.plugin, new Runnable() {
|
||||||
// @Override
|
// @Override
|
||||||
// public void run() {
|
// public void run() {
|
||||||
// if (!data.hasSetBackWorldChanged(setBack)){ // && data.isSetBack(setBack)){
|
// if (!data.hasSetBackWorldChanged(setBack)) { // && data.isSetBack(setBack)) {
|
||||||
// player.sendMessage("SETBACK FROM MC DERP.");
|
// player.sendMessage("SETBACK FROM MC DERP.");
|
||||||
// player.teleport(setBack);
|
// player.teleport(setBack);
|
||||||
// }
|
// }
|
||||||
@ -952,21 +971,21 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
data.setSetBack(to);
|
data.setSetBack(to);
|
||||||
// TODO: How to account for plugins that reset the fall distance here?
|
// TODO: How to account for plugins that reset the fall distance here?
|
||||||
if (fallDistance > 1.0 && fallDistance - player.getFallDistance() > 0.0){
|
if (fallDistance > 1.0 && fallDistance - player.getFallDistance() > 0.0) {
|
||||||
// Reset fall distance if set so in the config.
|
// Reset fall distance if set so in the config.
|
||||||
if (!cc.noFallTpReset){
|
if (!cc.noFallTpReset) {
|
||||||
// (Set fall distance if set to not reset.)
|
// (Set fall distance if set to not reset.)
|
||||||
player.setFallDistance((float) fallDistance);
|
player.setFallDistance((float) fallDistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event.getCause() == TeleportCause.ENDER_PEARL){
|
if (event.getCause() == TeleportCause.ENDER_PEARL) {
|
||||||
// Prevent NoFall violations for ender-pearls.
|
// Prevent NoFall violations for ender-pearls.
|
||||||
data.noFallSkipAirCheck = true;
|
data.noFallSkipAirCheck = true;
|
||||||
}
|
}
|
||||||
data.sfHoverTicks = -1; // Important against concurrent modification exception.
|
data.sfHoverTicks = -1; // Important against concurrent modification exception.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc.debug && BuildParameters.debugLevel > 0){
|
if (cc.debug && BuildParameters.debugLevel > 0) {
|
||||||
System.out.println(player.getName() + " TP" + (smallRange ? " (small-range)" : "") + (cancel ? " (cancelled)" : "") + ": " + to);
|
System.out.println(player.getName() + " TP" + (smallRange ? " (small-range)" : "") + (cancel ? " (cancelled)" : "") + ": " + to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -974,7 +993,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
// Cancelled, not a set back, ignore it, basically.
|
// Cancelled, not a set back, ignore it, basically.
|
||||||
// Better reset teleported (compatibility). Might have drawbacks.
|
// Better reset teleported (compatibility). Might have drawbacks.
|
||||||
data.resetTeleported();
|
data.resetTeleported();
|
||||||
if (cc.debug && BuildParameters.debugLevel > 0){
|
if (cc.debug && BuildParameters.debugLevel > 0) {
|
||||||
System.out.println(player.getName() + " TP (cancelled): " + to);
|
System.out.println(player.getName() + " TP (cancelled): " + to);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -1009,7 +1028,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
final MovingData data = MovingData.getData(player);
|
final MovingData data = MovingData.getData(player);
|
||||||
// Ignore velocity if inside of vehicles.
|
// Ignore velocity if inside of vehicles.
|
||||||
if (player.isInsideVehicle()){
|
if (player.isInsideVehicle()) {
|
||||||
data.removeAllVelocity();
|
data.removeAllVelocity();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1021,7 +1040,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
|
|
||||||
final Vector velocity = event.getVelocity();
|
final Vector velocity = event.getVelocity();
|
||||||
|
|
||||||
if (cc.debug){
|
if (cc.debug) {
|
||||||
System.out.println(event.getPlayer().getName() + " new velocity: " + velocity);
|
System.out.println(event.getPlayer().getName() + " new velocity: " + velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,7 +1048,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
boolean used = false;
|
boolean used = false;
|
||||||
if (newVal >= 0D) {
|
if (newVal >= 0D) {
|
||||||
used = true;
|
used = true;
|
||||||
if (data.verticalFreedom <= 0.001 && data.verticalVelocityCounter >= 0){
|
if (data.verticalFreedom <= 0.001 && data.verticalVelocityCounter >= 0) {
|
||||||
data.verticalVelocity = 0;
|
data.verticalVelocity = 0;
|
||||||
}
|
}
|
||||||
data.verticalVelocity += newVal;
|
data.verticalVelocity += newVal;
|
||||||
@ -1049,7 +1068,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set dirty flag here.
|
// Set dirty flag here.
|
||||||
if (used){
|
if (used) {
|
||||||
data.sfDirty = true;
|
data.sfDirty = true;
|
||||||
data.sfNoLowJump = true;
|
data.sfNoLowJump = true;
|
||||||
}
|
}
|
||||||
@ -1068,16 +1087,16 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
public void onVehicleMove(final VehicleMoveEvent event) {
|
public void onVehicleMove(final VehicleMoveEvent event) {
|
||||||
final Vehicle vehicle = event.getVehicle();
|
final Vehicle vehicle = event.getVehicle();
|
||||||
final EntityType entityType = vehicle.getType();
|
final EntityType entityType = vehicle.getType();
|
||||||
if (!normalVehicles.contains(entityType)){
|
if (!normalVehicles.contains(entityType)) {
|
||||||
// A little extra sweep to check for debug flags.
|
// A little extra sweep to check for debug flags.
|
||||||
normalVehicles.add(entityType);
|
normalVehicles.add(entityType);
|
||||||
if (MovingConfig.getConfig(vehicle.getWorld().getName()).debug){
|
if (MovingConfig.getConfig(vehicle.getWorld().getName()).debug) {
|
||||||
System.out.println("[NoCheatPlus] VehicleMoveEvent fired for: " + entityType);
|
System.out.println("[NoCheatPlus] VehicleMoveEvent fired for: " + entityType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Might account for the case of a player letting the vehicle move but not himself (do mind latency).
|
// TODO: Might account for the case of a player letting the vehicle move but not himself (do mind latency).
|
||||||
// Mind that players could be riding horses inside of minecarts etc.
|
// Mind that players could be riding horses inside of minecarts etc.
|
||||||
if (vehicle.getVehicle() != null){
|
if (vehicle.getVehicle() != null) {
|
||||||
// Do ignore events for vehicles inside of other vehicles.
|
// Do ignore events for vehicles inside of other vehicles.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1088,7 +1107,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
public void onVehicleMove(final Entity vehicle, final Location from, final Location to, final boolean fake) {
|
public void onVehicleMove(final Entity vehicle, final Location from, final Location to, final boolean fake) {
|
||||||
// (No re-check for vehicles that have vehicles, pre condition is that this has already been checked.)
|
// (No re-check for vehicles that have vehicles, pre condition is that this has already been checked.)
|
||||||
final Player player = CheckUtils.getFirstPlayerPassenger(vehicle);
|
final Player player = CheckUtils.getFirstPlayerPassenger(vehicle);
|
||||||
if (player == null){
|
if (player == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vehicle.isDead() || !vehicle.isValid()) {
|
if (vehicle.isDead() || !vehicle.isValid()) {
|
||||||
@ -1106,6 +1125,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
break;
|
break;
|
||||||
case INCONSISTENT:
|
case INCONSISTENT:
|
||||||
// TODO: Any exploits exist? -> TeleportUtil.forceMount(player, vehicle)
|
// TODO: Any exploits exist? -> TeleportUtil.forceMount(player, vehicle)
|
||||||
|
// TODO: Test with latency.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1113,7 +1133,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
data.sfNoLowJump = true;
|
data.sfNoLowJump = true;
|
||||||
|
|
||||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
if (cc.noFallVehicleReset){
|
if (cc.noFallVehicleReset) {
|
||||||
// Reset noFall data.
|
// Reset noFall data.
|
||||||
data.noFallSkipAirCheck = true; // Might allow one time cheat.
|
data.noFallSkipAirCheck = true; // Might allow one time cheat.
|
||||||
data.sfLowJump = false;
|
data.sfLowJump = false;
|
||||||
@ -1125,7 +1145,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
DebugUtil.outputDebugVehicleMove(player, vehicle, from, to, fake);
|
DebugUtil.outputDebugVehicleMove(player, vehicle, from, to, fake);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (morePacketsVehicle.isEnabled(player)){
|
if (morePacketsVehicle.isEnabled(player)) {
|
||||||
// If the player is handled by the more packets vehicle check, execute it.
|
// If the player is handled by the more packets vehicle check, execute it.
|
||||||
newTo = morePacketsVehicle.check(player, from, to, data, cc);
|
newTo = morePacketsVehicle.check(player, from, to, data, cc);
|
||||||
}
|
}
|
||||||
@ -1135,7 +1155,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Schedule a set-back?
|
// Schedule a set-back?
|
||||||
if (newTo != null && data.morePacketsVehicleTaskId == -1){
|
if (newTo != null && data.morePacketsVehicleTaskId == -1) {
|
||||||
// Schedule a delayed task to teleport back the vehicle with the player.
|
// Schedule a delayed task to teleport back the vehicle with the player.
|
||||||
// (Only schedule if not already scheduled.)
|
// (Only schedule if not already scheduled.)
|
||||||
// TODO: Might log debug if skipping.
|
// TODO: Might log debug if skipping.
|
||||||
@ -1146,20 +1166,20 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
|
||||||
public void onEntityDamage(final EntityDamageEvent event){
|
public void onEntityDamage(final EntityDamageEvent event) {
|
||||||
if (event.getCause() != DamageCause.FALL) return;
|
if (event.getCause() != DamageCause.FALL) return;
|
||||||
final Entity entity = event.getEntity();
|
final Entity entity = event.getEntity();
|
||||||
if (!(entity instanceof Player)) return;
|
if (!(entity instanceof Player)) return;
|
||||||
final Player player = (Player) entity;
|
final Player player = (Player) entity;
|
||||||
final MovingData data = MovingData.getData(player);
|
final MovingData data = MovingData.getData(player);
|
||||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
if (event.isCancelled() || !shouldCheckSurvivalFly(player, data, cc) || !noFall.isEnabled(player)){
|
if (event.isCancelled() || !shouldCheckSurvivalFly(player, data, cc) || !noFall.isEnabled(player)) {
|
||||||
data.clearNoFallData();
|
data.clearNoFallData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Location loc = player.getLocation();
|
final Location loc = player.getLocation();
|
||||||
boolean allowReset = true;
|
boolean allowReset = true;
|
||||||
if (!data.noFallSkipAirCheck){
|
if (!data.noFallSkipAirCheck) {
|
||||||
final MoveInfo moveInfo;
|
final MoveInfo moveInfo;
|
||||||
if (parkedInfo.isEmpty()) moveInfo = new MoveInfo(mcAccess);
|
if (parkedInfo.isEmpty()) moveInfo = new MoveInfo(mcAccess);
|
||||||
else moveInfo = parkedInfo.remove(parkedInfo.size() - 1);
|
else moveInfo = parkedInfo.remove(parkedInfo.size() - 1);
|
||||||
@ -1170,10 +1190,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
// Be sure not to lose that block.
|
// Be sure not to lose that block.
|
||||||
data.noFallFallDistance += 1.0;
|
data.noFallFallDistance += 1.0;
|
||||||
// TODO: Accound for liquid too?
|
// TODO: Accound for liquid too?
|
||||||
if (!pLoc.isOnGround(1.0, 0.3, 0.1) && !pLoc.isResetCond() && !pLoc.isAboveLadder() && !pLoc.isAboveStairs()){
|
if (!pLoc.isOnGround(1.0, 0.3, 0.1) && !pLoc.isResetCond() && !pLoc.isAboveLadder() && !pLoc.isAboveStairs()) {
|
||||||
// Likely a new style no-fall bypass (damage in mid-air).
|
// Likely a new style no-fall bypass (damage in mid-air).
|
||||||
data.noFallVL += 1.0;
|
data.noFallVL += 1.0;
|
||||||
if (noFall.executeActions(player, data.noFallVL, 1.0, cc.noFallActions, true) && data.hasSetBack()){
|
if (noFall.executeActions(player, data.noFallVL, 1.0, cc.noFallActions, true) && data.hasSetBack()) {
|
||||||
// Cancel the event and restore fall distance.
|
// Cancel the event and restore fall distance.
|
||||||
// NoFall data will not be reset
|
// NoFall data will not be reset
|
||||||
allowReset = false;
|
allowReset = false;
|
||||||
@ -1191,30 +1211,30 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final float fallDistance = player.getFallDistance();
|
final float fallDistance = player.getFallDistance();
|
||||||
final double damage = BridgeHealth.getDamage(event);
|
final double damage = BridgeHealth.getDamage(event);
|
||||||
final float yDiff = (float) (data.noFallMaxY - loc.getY());
|
final float yDiff = (float) (data.noFallMaxY - loc.getY());
|
||||||
if (cc.debug){
|
if (cc.debug) {
|
||||||
System.out.println(player.getName() + " damage(FALL): " + damage + " / dist=" + player.getFallDistance() + " nf=" + data.noFallFallDistance + " yDiff=" + yDiff);
|
System.out.println(player.getName() + " damage(FALL): " + damage + " / dist=" + player.getFallDistance() + " nf=" + data.noFallFallDistance + " yDiff=" + yDiff);
|
||||||
}
|
}
|
||||||
// Fall-back check.
|
// Fall-back check.
|
||||||
final double maxD = NoFall.getDamage(Math.max(yDiff, Math.max(data.noFallFallDistance, fallDistance))) + (allowReset ? 0.0 : 3.0);
|
final double maxD = NoFall.getDamage(Math.max(yDiff, Math.max(data.noFallFallDistance, fallDistance))) + (allowReset ? 0.0 : 3.0);
|
||||||
if (maxD > damage){
|
if (maxD > damage) {
|
||||||
// TODO: respect dealDamage ?
|
// TODO: respect dealDamage ?
|
||||||
BridgeHealth.setDamage(event, maxD);
|
BridgeHealth.setDamage(event, maxD);
|
||||||
if (cc.debug){
|
if (cc.debug) {
|
||||||
System.out.println(player.getName() + " Adjust fall damage to: " + maxD);
|
System.out.println(player.getName() + " Adjust fall damage to: " + maxD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allowReset){
|
if (allowReset) {
|
||||||
// Normal fall damage, reset data.
|
// Normal fall damage, reset data.
|
||||||
data.clearNoFallData();
|
data.clearNoFallData();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
// Minecraft/NCP bug or cheating.
|
// Minecraft/NCP bug or cheating.
|
||||||
// (Do not cancel the event, otherwise: "moved too quickly exploit".)
|
// (Do not cancel the event, otherwise: "moved too quickly exploit".)
|
||||||
if (cc.noFallViolationReset){
|
if (cc.noFallViolationReset) {
|
||||||
data.clearNoFallData();
|
data.clearNoFallData();
|
||||||
}
|
}
|
||||||
// Add player to hover checks.
|
// Add player to hover checks.
|
||||||
if (cc.sfHoverCheck && data.sfHoverTicks < 0){
|
if (cc.sfHoverCheck && data.sfHoverTicks < 0) {
|
||||||
data.sfHoverTicks = 0;
|
data.sfHoverTicks = 0;
|
||||||
hoverTicks.add(player.getName());
|
hoverTicks.add(player.getName());
|
||||||
}
|
}
|
||||||
@ -1231,19 +1251,19 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final Location loc = player.getLocation();
|
final Location loc = player.getLocation();
|
||||||
|
|
||||||
// Correct set-back on world changes.
|
// Correct set-back on world changes.
|
||||||
if (loc == null){
|
if (loc == null) {
|
||||||
// Bug on server side ?
|
// Bug on server side ?
|
||||||
data.clearFlyData();
|
data.clearFlyData();
|
||||||
}
|
}
|
||||||
else if (!data.hasSetBack()){
|
else if (!data.hasSetBack()) {
|
||||||
// TODO: Might consider something else like with respawn. Check if it is passable ?
|
// TODO: Might consider something else like with respawn. Check if it is passable ?
|
||||||
data.setSetBack(loc);
|
data.setSetBack(loc);
|
||||||
}
|
}
|
||||||
else if (data.hasSetBackWorldChanged(loc)){
|
else if (data.hasSetBackWorldChanged(loc)) {
|
||||||
data.clearFlyData();
|
data.clearFlyData();
|
||||||
data.setSetBack(loc);
|
data.setSetBack(loc);
|
||||||
}
|
}
|
||||||
if (data.fromX == Double.MAX_VALUE && data.toX == Double.MAX_VALUE){
|
if (data.fromX == Double.MAX_VALUE && data.toX == Double.MAX_VALUE) {
|
||||||
// TODO: re-think: more fine grained reset?
|
// TODO: re-think: more fine grained reset?
|
||||||
data.resetPositions(loc);
|
data.resetPositions(loc);
|
||||||
}
|
}
|
||||||
@ -1256,7 +1276,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
// Hover.
|
// Hover.
|
||||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
// Reset hover ticks until a better method is used.
|
// Reset hover ticks until a better method is used.
|
||||||
if (cc.sfHoverCheck){
|
if (cc.sfHoverCheck) {
|
||||||
// Start as if hovering already.
|
// Start as if hovering already.
|
||||||
// Could check shouldCheckSurvivalFly(player, data, cc), but this should be more sharp (gets checked on violation).
|
// Could check shouldCheckSurvivalFly(player, data, cc), but this should be more sharp (gets checked on violation).
|
||||||
data.sfHoverTicks = 0;
|
data.sfHoverTicks = 0;
|
||||||
@ -1269,9 +1289,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check loaded chunks.
|
// Check loaded chunks.
|
||||||
if (cc.loadChunksOnJoin){
|
if (cc.loadChunksOnJoin) {
|
||||||
final int loaded = BlockCache.ensureChunksLoaded(loc.getWorld(), loc.getX(), loc.getZ(), 3.0);
|
final int loaded = BlockCache.ensureChunksLoaded(loc.getWorld(), loc.getX(), loc.getZ(), 3.0);
|
||||||
if (loaded > 0 && cc.debug && BuildParameters.debugLevel > 0){
|
if (loaded > 0 && cc.debug && BuildParameters.debugLevel > 0) {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
LogUtil.logInfo("[NoCheatPlus] Player join: Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " for player: " + player.getName());
|
LogUtil.logInfo("[NoCheatPlus] Player join: Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " for player: " + player.getName());
|
||||||
}
|
}
|
||||||
@ -1289,20 +1309,20 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onWorldunload(final WorldUnloadEvent event){
|
public void onWorldunload(final WorldUnloadEvent event) {
|
||||||
// TODO: Consider removing the world-related data anyway (even if the event is cancelled).
|
// TODO: Consider removing the world-related data anyway (even if the event is cancelled).
|
||||||
MovingData.onWorldUnload(event.getWorld());
|
MovingData.onWorldUnload(event.getWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onVehicleExit(final VehicleExitEvent event){
|
public void onVehicleExit(final VehicleExitEvent event) {
|
||||||
final Entity entity = event.getExited();
|
final Entity entity = event.getExited();
|
||||||
if (!(entity instanceof Player)) return;
|
if (!(entity instanceof Player)) return;
|
||||||
onPlayerVehicleLeave((Player) entity, event.getVehicle());
|
onPlayerVehicleLeave((Player) entity, event.getVehicle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||||
public void onVehicleDestroyLowest(final VehicleDestroyEvent event){
|
public void onVehicleDestroyLowest(final VehicleDestroyEvent event) {
|
||||||
// Prevent destroying ones own vehicle.
|
// Prevent destroying ones own vehicle.
|
||||||
final Entity attacker = event.getAttacker();
|
final Entity attacker = event.getAttacker();
|
||||||
if (!(attacker instanceof Player)) {
|
if (!(attacker instanceof Player)) {
|
||||||
@ -1321,16 +1341,16 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onVehicleDestroy(final VehicleDestroyEvent event){
|
public void onVehicleDestroy(final VehicleDestroyEvent event) {
|
||||||
final Entity entity = event.getVehicle().getPassenger();
|
final Entity entity = event.getVehicle().getPassenger();
|
||||||
if (!(entity instanceof Player)) return;
|
if (!(entity instanceof Player)) return;
|
||||||
onPlayerVehicleLeave((Player) entity, event.getVehicle());
|
onPlayerVehicleLeave((Player) entity, event.getVehicle());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onPlayerVehicleEnter(final VehicleEnterEvent event){
|
public void onPlayerVehicleEnter(final VehicleEnterEvent event) {
|
||||||
final Entity entity = event.getEntered();
|
final Entity entity = event.getEntered();
|
||||||
if (!(entity instanceof Player)){
|
if (!(entity instanceof Player)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Player player = (Player) entity;
|
final Player player = (Player) entity;
|
||||||
@ -1346,10 +1366,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
* @param player
|
* @param player
|
||||||
* @param vehicle May be null in case of "not possible to determine".
|
* @param vehicle May be null in case of "not possible to determine".
|
||||||
*/
|
*/
|
||||||
private void onPlayerVehicleLeave(final Player player, final Entity vehicle){
|
private void onPlayerVehicleLeave(final Player player, final Entity vehicle) {
|
||||||
final MovingData data = MovingData.getData(player);
|
final MovingData data = MovingData.getData(player);
|
||||||
data.wasInVehicle = false;
|
data.wasInVehicle = false;
|
||||||
// if (data.morePacketsVehicleTaskId != -1){
|
// if (data.morePacketsVehicleTaskId != -1) {
|
||||||
// // Await set-back.
|
// // Await set-back.
|
||||||
// // TODO: might still set ordinary set-backs ?
|
// // TODO: might still set ordinary set-backs ?
|
||||||
// return;
|
// return;
|
||||||
@ -1364,7 +1384,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
if (vehicle != null) {
|
if (vehicle != null) {
|
||||||
final Location vLoc = vehicle.getLocation();
|
final Location vLoc = vehicle.getLocation();
|
||||||
// Workaround for some entities/animals that don't fire VehicleMoveEventS.
|
// Workaround for some entities/animals that don't fire VehicleMoveEventS.
|
||||||
if (!normalVehicles.contains(vehicle.getType()) || cc.noFallVehicleReset){
|
if (!normalVehicles.contains(vehicle.getType()) || cc.noFallVehicleReset) {
|
||||||
data.noFallSkipAirCheck = true; // Might allow one time cheat.
|
data.noFallSkipAirCheck = true; // Might allow one time cheat.
|
||||||
data.clearNoFallData();
|
data.clearNoFallData();
|
||||||
}
|
}
|
||||||
@ -1387,7 +1407,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adjust loc if in liquid (meant for boats !?).
|
// Adjust loc if in liquid (meant for boats !?).
|
||||||
if (BlockProperties.isLiquid(loc.getBlock().getTypeId())){
|
if (BlockProperties.isLiquid(loc.getBlock().getTypeId())) {
|
||||||
loc.setY(Location.locToBlock(loc.getY()) + 1.25);
|
loc.setY(Location.locToBlock(loc.getY()) + 1.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1406,13 +1426,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onPlayerToggleSneak(final PlayerToggleSneakEvent event){
|
public void onPlayerToggleSneak(final PlayerToggleSneakEvent event) {
|
||||||
survivalFly.setReallySneaking(event.getPlayer(), event.isSneaking());
|
survivalFly.setReallySneaking(event.getPlayer(), event.isSneaking());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void onPlayerToggleSprint(final PlayerToggleSprintEvent event){
|
public void onPlayerToggleSprint(final PlayerToggleSprintEvent event) {
|
||||||
if (!event.isSprinting()){
|
if (!event.isSprinting()) {
|
||||||
MovingData.getData(event.getPlayer()).timeSprinting = 0;
|
MovingData.getData(event.getPlayer()).timeSprinting = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1420,7 +1440,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
@Override
|
@Override
|
||||||
public void onTick(final int tick, final long timeLast) {
|
public void onTick(final int tick, final long timeLast) {
|
||||||
// Hover checks !
|
// Hover checks !
|
||||||
if (tick % hoverTicksStep != 0){
|
if (tick % hoverTicksStep != 0) {
|
||||||
// Only check every so and so ticks.
|
// Only check every so and so ticks.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1428,43 +1448,43 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
if (parkedInfo.isEmpty()) info = new MoveInfo(mcAccess);
|
if (parkedInfo.isEmpty()) info = new MoveInfo(mcAccess);
|
||||||
else info = parkedInfo.remove(parkedInfo.size() - 1);
|
else info = parkedInfo.remove(parkedInfo.size() - 1);
|
||||||
final List<String> rem = new ArrayList<String>(hoverTicks.size()); // Pessimistic.
|
final List<String> rem = new ArrayList<String>(hoverTicks.size()); // Pessimistic.
|
||||||
for (final String playerName : hoverTicks){
|
for (final String playerName : hoverTicks) {
|
||||||
// TODO: put players into the set (+- one tick would not matter ?)
|
// TODO: put players into the set (+- one tick would not matter ?)
|
||||||
// TODO: might add an online flag to data !
|
// TODO: might add an online flag to data !
|
||||||
final Player player = DataManager.getPlayerExact(playerName);
|
final Player player = DataManager.getPlayerExact(playerName);
|
||||||
if (player == null || !player.isOnline()){
|
if (player == null || !player.isOnline()) {
|
||||||
rem.add(playerName);
|
rem.add(playerName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final MovingData data = MovingData.getData(player);
|
final MovingData data = MovingData.getData(player);
|
||||||
if (player.isDead() || player.isSleeping() || player.isInsideVehicle()){
|
if (player.isDead() || player.isSleeping() || player.isInsideVehicle()) {
|
||||||
data.sfHoverTicks = -1;
|
data.sfHoverTicks = -1;
|
||||||
// (Removed below.)
|
// (Removed below.)
|
||||||
}
|
}
|
||||||
if (data.sfHoverTicks < 0){
|
if (data.sfHoverTicks < 0) {
|
||||||
data.sfHoverLoginTicks = 0;
|
data.sfHoverLoginTicks = 0;
|
||||||
rem.add(playerName);
|
rem.add(playerName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (data.sfHoverLoginTicks > 0){
|
else if (data.sfHoverLoginTicks > 0) {
|
||||||
// Additional "grace period".
|
// Additional "grace period".
|
||||||
data.sfHoverLoginTicks --;
|
data.sfHoverLoginTicks --;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||||
// Check if enabled at all.
|
// Check if enabled at all.
|
||||||
if (!cc.sfHoverCheck){
|
if (!cc.sfHoverCheck) {
|
||||||
rem.add(playerName);
|
rem.add(playerName);
|
||||||
data.sfHoverTicks = -1;
|
data.sfHoverTicks = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Increase ticks here.
|
// Increase ticks here.
|
||||||
data.sfHoverTicks += hoverTicksStep;
|
data.sfHoverTicks += hoverTicksStep;
|
||||||
if (data.sfHoverTicks < cc.sfHoverTicks){
|
if (data.sfHoverTicks < cc.sfHoverTicks) {
|
||||||
// Don't do the heavier checking here, let moving checks reset these.
|
// Don't do the heavier checking here, let moving checks reset these.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (checkHover(player, data, cc, info)){
|
if (checkHover(player, data, cc, info)) {
|
||||||
rem.add(playerName);
|
rem.add(playerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1489,18 +1509,18 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
final boolean res;
|
final boolean res;
|
||||||
// TODO: Collect flags, more margin ?
|
// TODO: Collect flags, more margin ?
|
||||||
final int loaded = info.from.ensureChunksLoaded();
|
final int loaded = info.from.ensureChunksLoaded();
|
||||||
if (loaded > 0 && cc.debug && BuildParameters.debugLevel > 0){
|
if (loaded > 0 && cc.debug && BuildParameters.debugLevel > 0) {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
LogUtil.logInfo("[NoCheatPlus] Hover check: Needed to load " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " around " + loc.getBlockX() + "," + loc.getBlockZ() + " in order to check player: " + player.getName());
|
LogUtil.logInfo("[NoCheatPlus] Hover check: Needed to load " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " around " + loc.getBlockX() + "," + loc.getBlockZ() + " in order to check player: " + player.getName());
|
||||||
}
|
}
|
||||||
if (info.from.isOnGround() || info.from.isResetCond() || info.from.isAboveLadder() || info.from.isAboveStairs()){
|
if (info.from.isOnGround() || info.from.isResetCond() || info.from.isAboveLadder() || info.from.isAboveStairs()) {
|
||||||
res = true;
|
res = true;
|
||||||
data.sfHoverTicks = 0;
|
data.sfHoverTicks = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (data.sfHoverTicks > cc.sfHoverTicks){
|
if (data.sfHoverTicks > cc.sfHoverTicks) {
|
||||||
// Re-Check if survivalfly can apply at all.
|
// Re-Check if survivalfly can apply at all.
|
||||||
if (shouldCheckSurvivalFly(player, data, cc)){
|
if (shouldCheckSurvivalFly(player, data, cc)) {
|
||||||
handleHoverViolation(player, loc, cc, data);
|
handleHoverViolation(player, loc, cc, data);
|
||||||
// Assume the player might still be hovering.
|
// Assume the player might still be hovering.
|
||||||
res = false;
|
res = false;
|
||||||
@ -1520,7 +1540,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
|
|
||||||
private void handleHoverViolation(final Player player, final Location loc, final MovingConfig cc, final MovingData data) {
|
private void handleHoverViolation(final Player player, final Location loc, final MovingConfig cc, final MovingData data) {
|
||||||
// Check nofall damage (!).
|
// Check nofall damage (!).
|
||||||
if (cc.sfHoverFallDamage && noFall.isEnabled(player)){
|
if (cc.sfHoverFallDamage && noFall.isEnabled(player)) {
|
||||||
// Consider adding 3/3.5 to fall distance if fall distance > 0?
|
// Consider adding 3/3.5 to fall distance if fall distance > 0?
|
||||||
noFall.checkDamage(player, data, loc.getY());
|
noFall.checkDamage(player, data, loc.getY());
|
||||||
}
|
}
|
||||||
@ -1548,7 +1568,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReload() {
|
public void onReload() {
|
||||||
for (final MoveInfo info : parkedInfo){
|
for (final MoveInfo info : parkedInfo) {
|
||||||
// Just in case.
|
// Just in case.
|
||||||
info.cleanup();
|
info.cleanup();
|
||||||
}
|
}
|
||||||
|
@ -23,29 +23,29 @@ public class Passable extends Check {
|
|||||||
|
|
||||||
public Location check(final Player player, Location loc, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
|
public Location check(final Player player, Location loc, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
|
||||||
{
|
{
|
||||||
// TODO: if (!from.isSameCoords(loc)){...check passable for loc -> from !?... + sf etc too?}
|
// TODO: if (!from.isSameCoords(loc)) {...check passable for loc -> from !?... + sf etc too?}
|
||||||
// TODO: Future: Account for the players bounding box? [test very-strict setting for at least the end points...]
|
// TODO: Future: Account for the players bounding box? [test very-strict setting for at least the end points...]
|
||||||
String tags = "";
|
String tags = "";
|
||||||
// Block distances (sum, max) for from-to (not for loc!).
|
// Block distances (sum, max) for from-to (not for loc!).
|
||||||
final int manhattan = from.manhattan(to);
|
final int manhattan = from.manhattan(to);
|
||||||
// Skip moves inside of ignored blocks right away.
|
// Skip moves inside of ignored blocks right away.
|
||||||
if (manhattan == 0 && (BlockProperties.getBlockFlags(from.getTypeId()) & BlockProperties.F_IGN_PASSABLE) != 0){
|
if (manhattan == 0 && (BlockProperties.getBlockFlags(from.getTypeId()) & BlockProperties.F_IGN_PASSABLE) != 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
boolean toPassable = to.isPassable();
|
boolean toPassable = to.isPassable();
|
||||||
// General condition check for using ray-tracing.
|
// General condition check for using ray-tracing.
|
||||||
if (toPassable && cc.passableRayTracingCheck && (!cc.passableRayTracingVclipOnly || from.getY() != to.getY()) && (!cc.passableRayTracingBlockChangeOnly || manhattan > 0)){
|
if (toPassable && cc.passableRayTracingCheck && (!cc.passableRayTracingVclipOnly || from.getY() != to.getY()) && (!cc.passableRayTracingBlockChangeOnly || manhattan > 0)) {
|
||||||
rayTracing.set(from, to);
|
rayTracing.set(from, to);
|
||||||
rayTracing.loop();
|
rayTracing.loop();
|
||||||
if (rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps()){
|
if (rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps()) {
|
||||||
final int maxBlockDist = manhattan <= 1 ? manhattan : from.maxBlockDist(to);
|
final int maxBlockDist = manhattan <= 1 ? manhattan : from.maxBlockDist(to);
|
||||||
if (maxBlockDist <= 1 && rayTracing.getStepsDone() == 1 && !from.isPassable()){
|
if (maxBlockDist <= 1 && rayTracing.getStepsDone() == 1 && !from.isPassable()) {
|
||||||
// Redo ray-tracing for moving out of blocks.
|
// Redo ray-tracing for moving out of blocks.
|
||||||
if (collidesIgnoreFirst(from, to)){
|
if (collidesIgnoreFirst(from, to)) {
|
||||||
toPassable = false;
|
toPassable = false;
|
||||||
tags = "raytracing_2x_";
|
tags = "raytracing_2x_";
|
||||||
}
|
}
|
||||||
else if (cc.debug){
|
else if (cc.debug) {
|
||||||
System.out.println(player.getName() + " passable: allow moving out of a block.");
|
System.out.println(player.getName() + " passable: allow moving out of a block.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ public class Passable extends Check {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Checking order: If loc is not the same as from, a quick return here might not be wanted.
|
// TODO: Checking order: If loc is not the same as from, a quick return here might not be wanted.
|
||||||
if (toPassable){
|
if (toPassable) {
|
||||||
// Quick return.
|
// Quick return.
|
||||||
// (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...)
|
// (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...)
|
||||||
data.passableVL *= 0.99;
|
data.passableVL *= 0.99;
|
||||||
@ -82,11 +82,11 @@ public class Passable extends Check {
|
|||||||
final int lbZ = loc.getBlockZ();
|
final int lbZ = loc.getBlockZ();
|
||||||
// First check if the player is moving from a passable location.
|
// First check if the player is moving from a passable location.
|
||||||
// If not, the move might still be allowed, if moving inside of the same block, or from and to have head position passable.
|
// If not, the move might still be allowed, if moving inside of the same block, or from and to have head position passable.
|
||||||
if (from.isPassable()){
|
if (from.isPassable()) {
|
||||||
// Put one workaround for 1.5 high blocks here:
|
// Put one workaround for 1.5 high blocks here:
|
||||||
if (from.isBlockAbove(to) && (BlockProperties.getBlockFlags(to.getTypeId()) & BlockProperties.F_HEIGHT150) != 0){
|
if (from.isBlockAbove(to) && (BlockProperties.getBlockFlags(to.getTypeId()) & BlockProperties.F_HEIGHT150) != 0) {
|
||||||
// Check if the move went from inside of the block.
|
// Check if the move went from inside of the block.
|
||||||
if (BlockProperties.collidesBlock(to.getBlockCache(), from.getX(), from.getY(), from.getZ(), from.getX(), from.getY(), from.getZ(), to.getBlockX(), to.getBlockY(), to.getBlockZ(), to.getTypeId())){
|
if (BlockProperties.collidesBlock(to.getBlockCache(), from.getX(), from.getY(), from.getZ(), from.getX(), from.getY(), from.getZ(), to.getBlockX(), to.getBlockY(), to.getBlockZ(), to.getTypeId())) {
|
||||||
// Allow moving inside of 1.5 high blocks.
|
// Allow moving inside of 1.5 high blocks.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -94,23 +94,23 @@ public class Passable extends Check {
|
|||||||
// From should be the set-back.
|
// From should be the set-back.
|
||||||
loc = null;
|
loc = null;
|
||||||
tags += "into";
|
tags += "into";
|
||||||
} else if (BlockProperties.isPassable(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))){
|
} else if (BlockProperties.isPassable(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
|
||||||
tags += "into_shift";
|
tags += "into_shift";
|
||||||
}
|
}
|
||||||
// } else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))){
|
// } else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
|
||||||
// (Mind that this can be the case on the same block theoretically.)
|
// (Mind that this can be the case on the same block theoretically.)
|
||||||
// Keep loc as set-back.
|
// Keep loc as set-back.
|
||||||
// }
|
// }
|
||||||
else if (!from.isSameBlock(lbX, lbY, lbZ)){
|
else if (!from.isSameBlock(lbX, lbY, lbZ)) {
|
||||||
// Otherwise keep loc as set-back.
|
// Otherwise keep loc as set-back.
|
||||||
tags += "cross_shift";
|
tags += "cross_shift";
|
||||||
}
|
}
|
||||||
else if (manhattan == 1 && to.isBlockAbove(from) && BlockProperties.isPassable(from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))){
|
else if (manhattan == 1 && to.isBlockAbove(from) && BlockProperties.isPassable(from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))) {
|
||||||
// else if (to.isBlockAbove(from) && BlockProperties.isPassableExact(from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))){
|
// else if (to.isBlockAbove(from) && BlockProperties.isPassableExact(from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))) {
|
||||||
// Allow the move up if the head is free.
|
// Allow the move up if the head is free.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if (manhattan > 0){
|
else if (manhattan > 0) {
|
||||||
// Otherwise keep from as set-back.
|
// Otherwise keep from as set-back.
|
||||||
loc = null;
|
loc = null;
|
||||||
tags += "cross";
|
tags += "cross";
|
||||||
@ -127,14 +127,16 @@ public class Passable extends Check {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prefer the set-back location from the data.
|
// Prefer the set-back location from the data.
|
||||||
if (data.hasSetBack()){
|
if (data.hasSetBack()) {
|
||||||
final Location ref = data.getSetBack(to);
|
final Location ref = data.getSetBack(to);
|
||||||
if (BlockProperties.isPassable(from.getBlockCache(), ref) || loc != null && TrigUtil.distance(from, loc) > 0.13){
|
if (BlockProperties.isPassable(from.getBlockCache(), ref) || loc == null || TrigUtil.distance(from, loc) > 0.13) {
|
||||||
// if (BlockProperties.isPassableExact(from.getBlockCache(), ref)){
|
// if (BlockProperties.isPassableExact(from.getBlockCache(), ref)) {
|
||||||
loc = ref;
|
loc = ref;
|
||||||
if (cc.debug) {
|
if (cc.debug) {
|
||||||
System.out.println(player.getName() + " Using set-back location for passable.");
|
System.out.println(player.getName() + " Using set-back location for passable.");
|
||||||
}
|
}
|
||||||
|
} else if (cc.debug) {
|
||||||
|
System.out.println(player.getName() + " Ignorng set-back for passable.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,9 +145,9 @@ public class Passable extends Check {
|
|||||||
// Return the reset position.
|
// Return the reset position.
|
||||||
data.passableVL += 1d;
|
data.passableVL += 1d;
|
||||||
final ViolationData vd = new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
|
final ViolationData vd = new ViolationData(this, player, data.passableVL, 1, cc.passableActions);
|
||||||
if (cc.debug || vd.needsParameters()){
|
if (cc.debug || vd.needsParameters()) {
|
||||||
vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
|
vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId());
|
||||||
if (!tags.isEmpty()){
|
if (!tags.isEmpty()) {
|
||||||
vd.setParameter(ParameterName.TAGS, tags);
|
vd.setParameter(ParameterName.TAGS, tags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,9 +156,7 @@ public class Passable extends Check {
|
|||||||
final Location newTo;
|
final Location newTo;
|
||||||
if (loc != null) {
|
if (loc != null) {
|
||||||
newTo = loc;
|
newTo = loc;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// TODO: Consider logging this one.
|
|
||||||
newTo = from.getLocation();
|
newTo = from.getLocation();
|
||||||
if (cc.debug) {
|
if (cc.debug) {
|
||||||
System.out.println(player.getName() + " Using from location for passable.");
|
System.out.println(player.getName() + " Using from location for passable.");
|
||||||
@ -194,7 +194,7 @@ public class Passable extends Check {
|
|||||||
*/
|
*/
|
||||||
private boolean allowsSplitMove(final PlayerLocation from, final PlayerLocation to, int manhattan) {
|
private boolean allowsSplitMove(final PlayerLocation from, final PlayerLocation to, int manhattan) {
|
||||||
final double yDiff = to.getY() - from.getY() ;
|
final double yDiff = to.getY() - from.getY() ;
|
||||||
if (manhattan <= 3 && yDiff > 0.0 && Math.abs(yDiff) < 1.0){
|
if (manhattan <= 3 && yDiff > 0.0 && Math.abs(yDiff) < 1.0) {
|
||||||
// Workaround for client-side calculations not being possible (y vs. horizontal move).
|
// Workaround for client-side calculations not being possible (y vs. horizontal move).
|
||||||
// TODO: Alternative: Test if "real" ray-tracing would fix it (might not!).
|
// TODO: Alternative: Test if "real" ray-tracing would fix it (might not!).
|
||||||
if (yDiff > 0.0) {
|
if (yDiff > 0.0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user