Skip to content

Commit

Permalink
More to vehicle internals.
Browse files Browse the repository at this point in the history
Set-back handling:
* Make the VehicleSetBack a class in the moving package.
* For set-backs use the debug flag from the time of checking.

Debugging:
* Alter debug output for moves slightly (differing locations).
* Add debug output for vehicle moves with players involved.

Note on 1.6:
* Not even PlayerMove is fired for pigs and horses, so no tracking.
  • Loading branch information
asofold committed Jul 16, 2013
1 parent f556422 commit 2b4a1f2
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 48 deletions.
Expand Up @@ -11,7 +11,7 @@ public class LocUtil {
* @param loc
* @return
*/
static final Location clone(final Location loc){
public static final Location clone(final Location loc){
return new Location(loc.getWorld(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
}

Expand All @@ -22,7 +22,7 @@ static final Location clone(final Location loc){
* @param pitch
* @return
*/
static final Location clone(final Location loc, final float yaw, final float pitch){
public static final Location clone(final Location loc, final float yaw, final float pitch){
return new Location(loc.getWorld(), loc.getX(), loc.getY(), loc.getZ(), yaw, pitch);
}

Expand All @@ -32,7 +32,7 @@ static final Location clone(final Location loc, final float yaw, final float pit
* @param ref
* @return
*/
static final Location clone(final Location setBack, final Location ref) {
public static final Location clone(final Location setBack, final Location ref) {
if (setBack == null){
return clone(ref);
}
Expand All @@ -41,7 +41,7 @@ static final Location clone(final Location setBack, final Location ref) {
}
}

static final Location clone(final Location setBack, final PlayerLocation ref) {
public static final Location clone(final Location setBack, final PlayerLocation ref) {
if (setBack == null) return ref.getLocation();
else{
return clone(setBack, ref.getYaw(), ref.getPitch());
Expand All @@ -53,7 +53,7 @@ static final Location clone(final Location setBack, final PlayerLocation ref) {
* @param setBack
* @param loc
*/
static final void set(final Location setBack, final Location loc) {
public static final void set(final Location setBack, final Location loc) {
setBack.setWorld(loc.getWorld());
setBack.setX(loc.getX());
setBack.setY(loc.getY());
Expand All @@ -62,7 +62,7 @@ static final void set(final Location setBack, final Location loc) {
setBack.setPitch(loc.getPitch());
}

static final void set(final Location setBack, final PlayerLocation loc) {
public static final void set(final Location setBack, final PlayerLocation loc) {
setBack.setWorld(loc.getWorld());
setBack.setX(loc.getX());
setBack.setY(loc.getY());
Expand Down
Expand Up @@ -71,7 +71,10 @@ public Location check(final Player player, final Location from, final Location t
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);
if (data.morePacketsVehicleTaskId != -1) {
// TODO: Set back outdated or not?
Bukkit.getScheduler().cancelTask(data.morePacketsVehicleTaskId);
}
}

// Take a packet from the buffer.
Expand Down
Expand Up @@ -69,7 +69,6 @@
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
import fr.neatmonster.nocheatplus.utilities.TeleportUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
import fr.neatmonster.nocheatplus.utilities.build.BuildParameters;
Expand Down Expand Up @@ -418,10 +417,9 @@ public void onPlayerMove(final PlayerMoveEvent event) {

// Ignore players in vehicles.
if (player.isInsideVehicle()){
// Workaround for pigs and other!

// 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;
Expand Down Expand Up @@ -1099,6 +1097,11 @@ public void onVehicleMove(final Entity vehicle, final Location from, final Locat
data.clearNoFallData();
}

if (cc.debug) {
// Log move.
DebugUtil.outputDebugVehicleMove(player, vehicle, from, to, fake);
}

if (morePacketsVehicle.isEnabled(player)){
// If the player is handled by the more packets vehicle check, execute it.
newTo = morePacketsVehicle.check(player, from, to, data, cc);
Expand All @@ -1107,37 +1110,16 @@ public void onVehicleMove(final Entity vehicle, final Location from, final Locat
// Otherwise we need to clear his data.
data.clearMorePacketsData();
}

// Did one of the checks decide we need a new "to"-location?
// Schedule a set-back?
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 Entity vehicle;
private Player player;
private Location location;

@Override
public void run() {
data.morePacketsVehicleTaskId = -1;
try{
MovingData.getData(player).setTeleported(location);
TeleportUtil.teleport(vehicle, player, location, MovingConfig.getConfig(player).debug);
}
catch(Throwable t){
LogUtil.logSevere(t);
}
}

public Runnable set(final Entity vehicle, final Player player, final Location location) {
this.vehicle = vehicle;
this.player = player;
this.location = location;
return this;
}
}.set(vehicle, player, newTo), 1L);
// TODO: Might log debug if skipping.
// TODO: Problem: scheduling allows a lot of things to happen until the task is run. Thus control about some things might be necessary.
// TODO: Reset on world changes or not?
data.morePacketsVehicleTaskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new VehicleSetBack(vehicle, player, newTo, cc.debug));
}
// TODO: Log this one too if debug set.
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false)
Expand Down
@@ -0,0 +1,41 @@
package fr.neatmonster.nocheatplus.checks.moving;

import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.utilities.TeleportUtil;

/**
* Task for scheduling a vehicle set back. Resets the morePacketsVehicleTaskId in the MovingData for the player.
* @author mc_dev
*
*/
public class VehicleSetBack implements Runnable{
private final Entity vehicle;
private final Player player;
private final Location location;
private final boolean debug;

public VehicleSetBack(Entity vehicle, Player player, Location location, boolean debug) {
this.vehicle = vehicle;
this.player = player;
this.location = location;
this.debug = debug;
}

@Override
public void run() {
final MovingData data = MovingData.getData(player);
data.morePacketsVehicleTaskId = -1;
try{
data.setTeleported(location);
TeleportUtil.teleport(vehicle, player, location, debug);
}
catch(Throwable t){
LogUtil.logSevere(t);
}
}

}
Expand Up @@ -3,6 +3,7 @@
import java.util.Arrays;

import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;

import fr.neatmonster.nocheatplus.compat.MCAccess;
Expand All @@ -17,20 +18,88 @@
*
*/
public class DebugUtil {

public static boolean isSamePos(final double x1, final double y1, final double z1, final double x2, final double y2, final double z2){
return x1 == x2 && y1 == y2 && z1 == z2;
}

public static boolean isSamePos(final Location loc1, final Location loc2){
return isSamePos(loc1.getX(), loc1.getY(), loc1.getZ(), loc2.getX(), loc2.getY(), loc2.getZ());
}

public static void addLocation(final double x, final double y, final double z, final StringBuilder builder){
builder.append(x + ", " + y + ", " + z);
}

public static void addLocation(final Location loc, final StringBuilder builder){
addLocation(loc.getX(), loc.getY(), loc.getZ(), builder);
}

public static void addLocation(final PlayerLocation loc, final StringBuilder builder){
addLocation(loc.getX(), loc.getY(), loc.getZ(), builder);
}

public static void addFormattedLocation(final double x, final double y, final double z, final StringBuilder builder){
builder.append(StringUtil.fdec3.format(x) + ", " + StringUtil.fdec3.format(y) + ", " + StringUtil.fdec3.format(z));
}

public static void addFormattedLocation(final Location loc, final StringBuilder builder){
addFormattedLocation(loc.getX(), loc.getY(), loc.getZ(), builder);
}

public static void addFormattedLocation(final PlayerLocation loc, final StringBuilder builder){
addFormattedLocation(loc.getX(), loc.getY(), loc.getZ(), builder);
}


/**
* With line break between from and to.
* @param fromX
* @param fromY
* @param fromZ
* @param toX
* @param toY
* @param toZ
* @param builder
*/
public static void addMove(final double fromX, final double fromY, final double fromZ, final double toX, final double toY, final double toZ, final StringBuilder builder){
builder.append("from: ");
addLocation(fromX, fromY, fromZ, builder);
builder.append("\nto: ");
addLocation(toX, toY, toZ, builder);
}

/**
* No line breaks, max. 3 digits after comma.
* @param fromX
* @param fromY
* @param fromZ
* @param toX
* @param toY
* @param toZ
* @param builder
*/
public static void addFormattedMove(final double fromX, final double fromY, final double fromZ, final double toX, final double toY, final double toZ, final StringBuilder builder){
addFormattedLocation(fromX, fromY, fromZ, builder);
builder.append(" -> ");
addFormattedLocation(toX, toY, toZ, builder);
}

/**
* 3 decimal digits after comma (StringUtil.fdec3). No leading new line.
* @param from
* @param to
* @param loc Reference location for from, usually Player.getLocation().
* @param loc Reference location for from, usually Player.getLocation(). May be null.
* @param builder
* @return
*/
public static void addFormattedMove(final PlayerLocation from, final PlayerLocation to, final Location loc, final StringBuilder builder){
builder.append(StringUtil.fdec3.format(from.getX()) + (from.getX() == loc.getX() ? "" : ("(" + StringUtil.fdec3.format(loc.getX()) + ")")));
builder.append(", " + StringUtil.fdec3.format(from.getY()) + (from.getY() == loc.getY() ? "" : ("(" + StringUtil.fdec3.format(loc.getY()) + ")")));
builder.append(", " + StringUtil.fdec3.format(from.getZ()) + (from.getZ() == loc.getZ() ? "" : ("(" + StringUtil.fdec3.format(loc.getZ()) + ")")));
builder.append(" -> " + StringUtil.fdec3.format(to.getX()) + ", " + StringUtil.fdec3.format(to.getY()) + ", " + StringUtil.fdec3.format(to.getZ()));
if (loc != null && !from.isSamePos(loc)){
builder.append("(");
addFormattedLocation(loc, builder);
builder.append(") ");
}
addFormattedMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder);
}

/**
Expand All @@ -41,10 +110,44 @@ public static void addFormattedMove(final PlayerLocation from, final PlayerLocat
* @param builder
*/
public static void addMove(final PlayerLocation from, final PlayerLocation to, final Location loc, final StringBuilder builder){
builder.append("from: " + from.getX() + (from.getX() == loc.getX() ? "" : ("(" + loc.getX() + ")")));
builder.append(", " + from.getY() + (from.getY() == loc.getY() ? "" : ("(" + loc.getY() + ")")));
builder.append(", " + from.getZ() + (from.getZ() == loc.getZ() ? "" : ("(" + loc.getZ() + ")")));
builder.append("\nto: " + to.getX() + ", " + to.getY() + ", " + to.getZ());
if (loc != null && !from.isSamePos(loc)){
builder.append("Location: ");
addLocation(loc, builder);
builder.append("\n");
}
addMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder);
}

/**
* 3 decimal digits after comma (StringUtil.fdec3). No leading new line.
* @param from
* @param to
* @param loc Reference location for from, usually Player.getLocation().
* @param builder
* @return
*/
public static void addFormattedMove(final Location from, final Location to, final Location loc, final StringBuilder builder){
if (loc != null && !isSamePos(from, loc)){
builder.append("(");
addFormattedLocation(loc, builder);
builder.append(") ");
}
addFormattedMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder); }

/**
* Add exact coordinates, multiple lines. No leading new line.
* @param from
* @param to
* @param loc Reference location for from, usually Player.getLocation().
* @param builder
*/
public static void addMove(final Location from, final Location to, final Location loc, final StringBuilder builder){
if (loc != null && !isSamePos(from, loc)){
builder.append("Location: ");
addLocation(loc, builder);
builder.append("\n");
}
addMove(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), builder);
}

/**
Expand Down Expand Up @@ -111,4 +214,34 @@ public static void addBlockInfo(final StringBuilder builder, final PlayerLocati
builder.append(tag + " id=" + loc.getTypeId() + " data=" + loc.getData() + " shape=" + Arrays.toString(loc.getBlockCache().getBounds(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())));
}

public static void outputDebugVehicleMove(final Player player, final Entity vehicle, final Location from, final Location to, final boolean fake) {
// TODO: log move + player name, vehicle type, if vehicle matches the players vehicle / inconsistencies.
final StringBuilder builder = new StringBuilder(250);
final Location vLoc = vehicle.getLocation();
final Location loc = player.getLocation();
// TODO: Differentiate debug levels (needs setting up some policy + document in BuildParamteres)?
// TODO: Might use more appropriate methods (distinct "player location: ...")
final Entity actualVehicle = player.getVehicle();
final boolean wrongVehicle = actualVehicle == null || actualVehicle.getEntityId() != vehicle.getEntityId();
if (BuildParameters.debugLevel > 0) {
builder.append("\n-------------- VEHICLE MOVE " + (fake ? "(fake)" : "") + "--------------\n");
builder.append(player.getName() + " " + from.getWorld().getName() + ":\n");
addMove(from, to, null, builder);
builder.append("\n Vehicle: ");
addLocation(vLoc, builder);
builder.append("\n Player: ");
addLocation(loc, builder);
}
else {
builder.append(player.getName() + " " + from.getWorld().getName() + "veh." + (fake ? "(fake)" : "") + " ");
addFormattedMove(from, to, null, builder);
builder.append("\n Vehicle: ");
addFormattedLocation(vLoc, builder);
builder.append(" Player: ");
addFormattedLocation(loc, builder);
}
builder.append("\n Vehicle type: " + vehicle.getType() + (wrongVehicle ? (actualVehicle == null ? " (exited?)" : " actual: " + actualVehicle.getType()) : ""));
System.out.print(builder.toString());
}

}
Expand Up @@ -15,7 +15,7 @@ public class TeleportUtil {
*/
public static void teleport(final Entity vehicle, final Player player, final Location location, final boolean debug) {
// TODO: This handling could conflict with WorldGuard region flags.
// TODO: Account for nested passengers.
// TODO: Account for nested passengers and inconsistencies.
final Entity passenger = vehicle.getPassenger();
final boolean vehicleTeleported;
final boolean playerIsPassenger = player.equals(passenger);
Expand Down

0 comments on commit 2b4a1f2

Please sign in to comment.