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.]
This commit is contained in:
asofold 2013-01-25 22:12:40 +01:00
parent ed56c3458f
commit 9bd7745690
4 changed files with 66 additions and 13 deletions

View File

@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.checks.moving;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -70,10 +71,16 @@ public class MorePacketsVehicle extends Check {
if (!data.hasMorePacketsVehicleSetBack()){ if (!data.hasMorePacketsVehicleSetBack()){
// TODO: Check if other set-back is appropriate or if to set on other events. // TODO: Check if other set-back is appropriate or if to set on other events.
data.setMorePacketsVehicleSetBack(from); data.setMorePacketsVehicleSetBack(from);
if (data.morePacketsVehicleTaskId != -1) Bukkit.getScheduler().cancelTask(data.morePacketsVehicleTaskId);
} }
// Take a packet from the buffer. // Take a packet from the buffer.
data.morePacketsVehicleBuffer--; data.morePacketsVehicleBuffer--;
if (data.morePacketsVehicleTaskId != -1){
// Short version !
return data.getMorePacketsVehicleSetBack();
}
// Player used up buffer, he fails the check. // Player used up buffer, he fails the check.
if (data.morePacketsVehicleBuffer < 0) { if (data.morePacketsVehicleBuffer < 0) {

View File

@ -105,6 +105,9 @@ public class MovingData extends ACheckData {
public long morePacketsVehicleLastTime; public long morePacketsVehicleLastTime;
public int morePacketsVehiclePackets; public int morePacketsVehiclePackets;
private Location morePacketsVehicleSetback; private Location morePacketsVehicleSetback;
/** Task id of the morepackets set-back task. */
public int morePacketsVehicleTaskId = -1;
// Data of the no fall check. // Data of the no fall check.
public float noFallFallDistance; public float noFallFallDistance;
@ -144,7 +147,7 @@ public class MovingData extends ACheckData {
// Locations shared between all checks. // Locations shared between all checks.
private Location setBack; private Location setBack;
private Location teleported; private Location teleported;
/** /**
* Clear the data of the fly checks (not more-packets). * Clear the data of the fly checks (not more-packets).
*/ */

View File

@ -863,34 +863,44 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Player player = (Player) passenger; final Player player = (Player) passenger;
Location newTo = null; Location newTo = null;
final MovingData data = MovingData.getData(player);
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); newTo = morePacketsVehicle.check(player, from, to);
else }
else{
// Otherwise we need to clear his data. // 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? // Did one of the checks decide we need a new "to"-location?
if (newTo != null) if (newTo != null && data.morePacketsVehicleTaskId != -1){
// Yes, so schedule a delayed task to teleport back the vehicle (this event isn't cancellable and we can't // Schedule a delayed task to teleport back the vehicle with the player.
// teleport the vehicle within the event). // (Only schedule if not already scheduled.)
// TODO: cleanup? data.morePacketsVehicleTaskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
private Vehicle vehicle; private Vehicle vehicle;
private Player player;
private Location location; private Location location;
@Override @Override
public void run() { 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.vehicle = vehicle;
this.player = player;
this.location = location; this.location = location;
return this; return this;
} }
}.set(vehicle, newTo), 1L); }.set(vehicle, player, newTo), 1L);
}
} }
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)

View File

@ -1,9 +1,13 @@
package fr.neatmonster.nocheatplus.utilities; package fr.neatmonster.nocheatplus.utilities;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.logging.LogUtil; import fr.neatmonster.nocheatplus.logging.LogUtil;
/** /**
@ -206,4 +210,33 @@ public class CheckUtils {
player.kickPlayer("Illegal move."); player.kickPlayer("Illegal move.");
LogUtil.logWarning("[NCP] Disconnect " + player.getName() + " due to 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);
}
}
} }