(Hacky) Fix for detecting and handling teleporting between worlds with

the /world command from "Essentials"
This commit is contained in:
Evenprime 2011-03-20 15:17:39 +01:00
parent 53c9dd50f1
commit c655086b4e
4 changed files with 55 additions and 22 deletions

View File

@ -3,7 +3,7 @@ name: NoCheatPlugin
author: Evenprime
main: cc.co.evenprime.bukkit.nocheat.NoCheatPlugin
version: 0.7.1
version: 0.7.2
commands:
nocheat:

View File

@ -1,6 +1,7 @@
package cc.co.evenprime.bukkit.nocheat;
import org.bukkit.Location;
import org.bukkit.World;
/**
* Storage for data persistence between events
@ -19,6 +20,7 @@ public class NoCheatData {
public int movingMinorViolationsInARow = 0;
public int movingNormalViolationsInARow = 0;
public int movingHeavyViolationsInARow = 0;
public World movingLastWorld = null;
public boolean reset = false;
@ -29,6 +31,7 @@ public class NoCheatData {
public Location speedhackSetBackPoint = null;
public int speedhackEventsSinceLastCheck = 0; // used to identify speedhacks
public int speedhackViolationsInARow = 0;
public Location movingLocation = null;
NoCheatData() { }
}

View File

@ -136,34 +136,62 @@ public class MovingCheck {
// Should we check at all
if(NoCheatPlugin.hasPermission(event.getPlayer(), "nocheat.moving"))
return;
return;
// Get the player-specific data
NoCheatData data = NoCheatPlugin.getPlayerData(event.getPlayer());
// Notice to myself: How world changes with e.g. command /world work:
// 1. TeleportEvent from the players current position to another position in the _same_ world
// 2. MoveEvent(s) (yes, multiple events can be triggered) from that position in the _new_ world
// to the actual target position in the new world
// strange...
// I've no real way to get informed about a world change, therefore I have to
// store the "lastWorld" and compare it to the world of the next event
// Fun fact: Move event locations always have the same world in from/to, therefore
// it doesn't matter which one I use
if(data.movingLastWorld != event.getFrom().getWorld()) {
data.movingLastWorld = event.getFrom().getWorld();
// "Forget" previous setback points
data.movingSetBackPoint = null;
data.speedhackSetBackPoint = null;
// Store the destination that this move goes to for later use
data.movingLocation = event.getTo();
// the world changed since our last check, therefore I can't check anything
// for this event (reliably)
return;
}
if(data.movingLocation != null && data.movingLocation.equals(event.getTo())) {
// If we are still trying to reach that location, accept the move
return;
}
else if(data.movingLocation != null) {
// If we try to go somewhere else, delete the location. It is no longer needed
data.movingLocation = null;
}
// The actual movingCheck starts here
// Get the player-specific data
NoCheatData data = NoCheatPlugin.getPlayerData(event.getPlayer());
// Get the two locations of the event
Location from = event.getFrom();
Location to = event.getTo();
if(from.getWorld() != to.getWorld()) {
// Moving between different worlds is considered ok
// Also prevent accidential back teleporting by discarding old-world coordinates
data.movingSetBackPoint = null;
data.speedhackSetBackPoint = null;
return;
}
// First check the distance the player has moved horizontally
// TODO: Make this check much more precise
double xDistance = Math.abs(from.getX() - to.getX());
double zDistance = Math.abs(from.getZ() - to.getZ());
double combined = xDistance * xDistance + zDistance * zDistance;
// If the target is a bed and distance not too big, allow it
if(to.getWorld().getBlockTypeIdAt(to) == Material.BED_BLOCK.getId() && xDistance < 5.0D && zDistance < 5.0D) {
return; // players are allowed to "teleport" into a bed over short distances
}
Level vl = null; // The violation level (none, minor, normal, heavy)
// How far are we off?

View File

@ -13,14 +13,16 @@ public class NoCheatPlayerListenerMonitor extends PlayerListener {
NoCheatData data = NoCheatPlugin.getPlayerData(event.getPlayer());
if(data.reset) { // My plugin requested this teleport, so we allow it
if(data.reset) { // My plugin requested this teleport, so we don't do anything
data.reset = false;
}
else if(!event.isCancelled()) {
// If it wasn't our plugin that ordered the teleport, forget all our information and start from scratch at the new location
data.speedhackSetBackPoint = event.getTo().clone();
data.movingSetBackPoint = event.getTo().clone();
data.movingJumpPhase = 0;
else {
if(!event.isCancelled()) {
// If it wasn't our plugin that ordered the teleport, forget all our information and start from scratch at the new location
data.speedhackSetBackPoint = event.getTo().clone();
data.movingSetBackPoint = event.getTo().clone();
data.movingJumpPhase = 0;
}
}
}
}