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 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) {

View File

@ -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).
*/

View File

@ -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)

View File

@ -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);
}
}
}