From 9bd7745690ab5e62bb5544e9bd0bfa0d43c55242 Mon Sep 17 00:00:00 2001 From: asofold Date: Fri, 25 Jan 2013 22:12:40 +0100 Subject: [PATCH] Change the way morepackets(vehicle) teleports player and vehicle. Player gets ejected, then both teleport then re-enter. Includes some sanity checks. Also should work for players exiting vehicles. Might conflict with Worldguard region flags and similar. [Missing: proper treatment of vehicle-enter/exit.] --- .../checks/moving/MorePacketsVehicle.java | 7 ++++ .../nocheatplus/checks/moving/MovingData.java | 5 ++- .../checks/moving/MovingListener.java | 34 ++++++++++++------- .../nocheatplus/utilities/CheckUtils.java | 33 ++++++++++++++++++ 4 files changed, 66 insertions(+), 13 deletions(-) diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MorePacketsVehicle.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MorePacketsVehicle.java index 5e6adb0a..da5003df 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MorePacketsVehicle.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MorePacketsVehicle.java @@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.checks.moving; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -70,10 +71,16 @@ public class MorePacketsVehicle extends Check { if (!data.hasMorePacketsVehicleSetBack()){ // TODO: Check if other set-back is appropriate or if to set on other events. data.setMorePacketsVehicleSetBack(from); + if (data.morePacketsVehicleTaskId != -1) Bukkit.getScheduler().cancelTask(data.morePacketsVehicleTaskId); } // Take a packet from the buffer. data.morePacketsVehicleBuffer--; + + if (data.morePacketsVehicleTaskId != -1){ + // Short version ! + return data.getMorePacketsVehicleSetBack(); + } // Player used up buffer, he fails the check. if (data.morePacketsVehicleBuffer < 0) { diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java index 738b67fd..76ec7ea3 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java @@ -105,6 +105,9 @@ public class MovingData extends ACheckData { public long morePacketsVehicleLastTime; public int morePacketsVehiclePackets; private Location morePacketsVehicleSetback; + /** Task id of the morepackets set-back task. */ + public int morePacketsVehicleTaskId = -1; + // Data of the no fall check. public float noFallFallDistance; @@ -144,7 +147,7 @@ public class MovingData extends ACheckData { // Locations shared between all checks. private Location setBack; private Location teleported; - + /** * Clear the data of the fly checks (not more-packets). */ diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index 21338f34..4d31b9a3 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -863,34 +863,44 @@ public class MovingListener extends CheckListener implements TickListener, IRemo final Player player = (Player) passenger; Location newTo = null; - - if (morePacketsVehicle.isEnabled(player)) + final MovingData data = MovingData.getData(player); + if (morePacketsVehicle.isEnabled(player)){ // If the player is handled by the more packets vehicle check, execute it. newTo = morePacketsVehicle.check(player, from, to); - else + } + else{ // Otherwise we need to clear his data. - MovingData.getData(player).clearMorePacketsData(); + data.clearMorePacketsData(); + } // Did one of the checks decide we need a new "to"-location? - if (newTo != null) - // Yes, so schedule a delayed task to teleport back the vehicle (this event isn't cancellable and we can't - // teleport the vehicle within the event). - // TODO: cleanup? - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + if (newTo != null && data.morePacketsVehicleTaskId != -1){ + // Schedule a delayed task to teleport back the vehicle with the player. + // (Only schedule if not already scheduled.) + data.morePacketsVehicleTaskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { private Vehicle vehicle; + private Player player; private Location location; @Override public void run() { - vehicle.teleport(location, TeleportCause.PLUGIN); + data.morePacketsVehicleTaskId = -1; + try{ + CheckUtils.teleport(vehicle, player, location); + } + catch(Throwable t){ + LogUtil.logSevere(t); + } } - public Runnable set(final Vehicle vehicle, final Location location) { + public Runnable set(final Vehicle vehicle, final Player player, final Location location) { this.vehicle = vehicle; + this.player = player; this.location = location; return this; } - }.set(vehicle, newTo), 1L); + }.set(vehicle, player, newTo), 1L); + } } @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) diff --git a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java index b0bf8c00..2811f215 100644 --- a/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java +++ b/NCPPlugin/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java @@ -1,9 +1,13 @@ package fr.neatmonster.nocheatplus.utilities; import org.bukkit.Location; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.util.Vector; +import fr.neatmonster.nocheatplus.checks.moving.MovingData; import fr.neatmonster.nocheatplus.logging.LogUtil; /** @@ -206,4 +210,33 @@ public class CheckUtils { player.kickPlayer("Illegal move."); LogUtil.logWarning("[NCP] Disconnect " + player.getName() + " due to illegal move!"); } + + /** + * Teleport the player with vehicle, temporarily eject the passenger and set teleported in MovingData. + * @param vehicle + * @param player + * @param location + */ + public static void teleport(final Vehicle vehicle, final Player player, final Location location) { + // TODO: This handling could conflict with WorldGuard region flags. + final Entity passenger = vehicle.getPassenger(); + final boolean vehicleTeleported; + final boolean playerIsPassenger = player.equals(passenger); + if (playerIsPassenger && !vehicle.isDead()){ // && vehicle.equals(player.getVehicle). + vehicle.eject(); + vehicleTeleported = vehicle.teleport(location, TeleportCause.PLUGIN); + + } + else if (passenger == null && !vehicle.isDead()){ + vehicleTeleported = vehicle.teleport(location, TeleportCause.PLUGIN); + } + else vehicleTeleported = false; + final MovingData data = MovingData.getData(player); + data.setTeleported(location); + final boolean playerTeleported = player.teleport(location); + if (playerIsPassenger && playerTeleported && vehicleTeleported && player.getLocation().distance(vehicle.getLocation()) < 1.0){ + // Somewhat check against tp showing something wrong (< 1.0). + vehicle.setPassenger(player); + } + } }