mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-03-02 10:31:25 +01:00
Fixed teleports (for real this time) by completely rewriting how they
are handled.
This commit is contained in:
parent
c3b6148245
commit
272f2d410c
@ -3,7 +3,7 @@ name: NoCheat
|
|||||||
author: Evenprime
|
author: Evenprime
|
||||||
|
|
||||||
main: cc.co.evenprime.bukkit.nocheat.NoCheat
|
main: cc.co.evenprime.bukkit.nocheat.NoCheat
|
||||||
version: 1.07
|
version: 1.07a
|
||||||
|
|
||||||
softdepend: [ Permissions, CraftIRC ]
|
softdepend: [ Permissions, CraftIRC ]
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
package cc.co.evenprime.bukkit.nocheat.checks;
|
package cc.co.evenprime.bukkit.nocheat.checks;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -102,7 +103,7 @@ public class MovingCheck extends Check {
|
|||||||
// Get the player-specific data
|
// Get the player-specific data
|
||||||
final MovingData data = MovingData.get(player);
|
final MovingData data = MovingData.get(player);
|
||||||
|
|
||||||
|
|
||||||
// Get the two locations of the event
|
// Get the two locations of the event
|
||||||
final Location to = event.getTo();
|
final Location to = event.getTo();
|
||||||
|
|
||||||
@ -117,9 +118,6 @@ public class MovingCheck extends Check {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(to.distanceSquared(data.lastLocation) < to.distanceSquared(from)) {
|
|
||||||
from = data.lastLocation;
|
|
||||||
}
|
|
||||||
/**** Horizontal movement check START ****/
|
/**** Horizontal movement check START ****/
|
||||||
|
|
||||||
// First check the distance the player has moved horizontally
|
// First check the distance the player has moved horizontally
|
||||||
@ -386,25 +384,31 @@ public class MovingCheck extends Check {
|
|||||||
*/
|
*/
|
||||||
private boolean shouldBeIgnored(final Player player, final MovingData data, final Location from, final Location to) {
|
private boolean shouldBeIgnored(final Player player, final MovingData data, final Location from, final Location to) {
|
||||||
|
|
||||||
// First the simple yes/no checks
|
// Now it gets complicated: (a friendly reminder to myself why this actually works in CB 950+)
|
||||||
if(data.insideVehicle || player.isInsideVehicle()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!from.getWorld().equals(data.lastLocation.getWorld())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data.teleportTo != null && from.getX() == data.teleportTo.getX() && from.getY() == data.teleportTo.getY() && from.getZ() == data.teleportTo.getZ()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final double x = from.getX();
|
// data.teleportTo gets a location assigned if a teleport event is successfully executed.
|
||||||
final double y = from.getY();
|
// But there is a delay between the serverside execution of the teleport (instantly) and
|
||||||
final double z = from.getZ();
|
// the execution on the client side (may take an arbitrary time). During that time, the
|
||||||
|
// client may send new move events relative to his old location. These events get treated
|
||||||
// Player didn't move at all
|
// by bukkit as PLAYER_MOVE events, despite the server not accepting them (the players
|
||||||
if(x == to.getX() && z == to.getZ() && y == to.getY() ) {
|
// serverside location won't get updated). Therefore comparing the teleport destination
|
||||||
|
// with the servers location of the player (which is almost the same as the "from" location
|
||||||
|
// in the move event) tells us if the server is still waiting for the clientside teleporting
|
||||||
|
// to be executed. We are only interested in client's move events after it executed the
|
||||||
|
// teleport, therefore just ignore all events before that.
|
||||||
|
if(data.teleportTo != null && data.teleportTo.distanceSquared(from) < 0.01D) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.teleportTo = null;
|
||||||
|
}
|
||||||
|
// Dead or in vehicles -> I don't care
|
||||||
|
if(player.isDead() || data.insideVehicle || player.isInsideVehicle()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// If the player moved between worlds between events, don't check (wouldn't make sense
|
||||||
|
// to check coordinates between different worlds...)
|
||||||
|
if(!from.getWorld().equals(data.lastLocation)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,16 +457,18 @@ public class MovingCheck extends Check {
|
|||||||
|
|
||||||
MovingData data = MovingData.get(event.getPlayer());
|
MovingData data = MovingData.get(event.getPlayer());
|
||||||
|
|
||||||
// We can enforce a teleport, if that flag is explicitly set
|
// We can enforce a teleport, if that flag is explicitly set (but I'd rather have other plugins
|
||||||
if(event.isCancelled() && enforceTeleport && event.getTo().equals(data.teleportTo)) {
|
// not arbitrarily cancel teleport events in the first place...
|
||||||
|
if(data.teleportInitializedByMe != null && event.isCancelled() && enforceTeleport && event.getTo().equals(data.teleportInitializedByMe)) {
|
||||||
event.setCancelled(false);
|
event.setCancelled(false);
|
||||||
|
data.teleportInitializedByMe = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!event.isCancelled()) {
|
if(!event.isCancelled()) {
|
||||||
data.jumpPhase = 0;
|
data.jumpPhase = 0;
|
||||||
data.teleportTo = event.getTo().clone();
|
data.teleportTo = event.getTo().clone();
|
||||||
data.lastLocation = event.getTo().clone();
|
|
||||||
data.setBackPoint = event.getTo().clone();
|
data.setBackPoint = event.getTo().clone();
|
||||||
|
//data.lastLocation = event.getTo().clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,8 +477,8 @@ public class MovingCheck extends Check {
|
|||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
public void respawned(PlayerRespawnEvent event) {
|
public void respawned(PlayerRespawnEvent event) {
|
||||||
MovingData data = MovingData.get(event.getPlayer());
|
//MovingData data = MovingData.get(event.getPlayer());
|
||||||
data.setBackPoint = event.getRespawnLocation().clone();
|
//data.setBackPoint = event.getRespawnLocation().clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -536,9 +542,9 @@ public class MovingCheck extends Check {
|
|||||||
data.setBackPoint.setY(y);
|
data.setBackPoint.setY(y);
|
||||||
|
|
||||||
// Remember the location we send the player to, to identify teleports that were started by us
|
// Remember the location we send the player to, to identify teleports that were started by us
|
||||||
data.teleportTo = new Location(data.setBackPoint.getWorld(), data.setBackPoint.getX(), y, data.setBackPoint.getZ(), event.getTo().getYaw(), event.getTo().getPitch());
|
data.teleportInitializedByMe = new Location(data.setBackPoint.getWorld(), data.setBackPoint.getX(), y, data.setBackPoint.getZ(), event.getTo().getYaw(), event.getTo().getPitch());
|
||||||
|
|
||||||
event.setTo(data.teleportTo);
|
event.setTo(data.teleportInitializedByMe);
|
||||||
|
|
||||||
cancelled = true; // just prevent us from treating more than one "cancel" action, which would make no sense
|
cancelled = true; // just prevent us from treating more than one "cancel" action, which would make no sense
|
||||||
}
|
}
|
||||||
@ -739,7 +745,6 @@ public class MovingCheck extends Check {
|
|||||||
pm.registerEvent(Event.Type.PLAYER_MOVE, new MovingPlayerListener(this), Priority.Lowest, plugin);
|
pm.registerEvent(Event.Type.PLAYER_MOVE, new MovingPlayerListener(this), Priority.Lowest, plugin);
|
||||||
pm.registerEvent(Event.Type.PLAYER_INTERACT, movingPlayerMonitor, Priority.Monitor, plugin);
|
pm.registerEvent(Event.Type.PLAYER_INTERACT, movingPlayerMonitor, Priority.Monitor, plugin);
|
||||||
pm.registerEvent(Event.Type.PLAYER_MOVE, movingPlayerMonitor, Priority.Monitor, plugin);
|
pm.registerEvent(Event.Type.PLAYER_MOVE, movingPlayerMonitor, Priority.Monitor, plugin);
|
||||||
pm.registerEvent(Event.Type.PLAYER_RESPAWN, movingPlayerMonitor, Priority.Monitor, plugin);
|
|
||||||
pm.registerEvent(Event.Type.ENTITY_DAMAGE, new MovingEntityListener(this), Priority.Monitor, plugin);
|
pm.registerEvent(Event.Type.ENTITY_DAMAGE, new MovingEntityListener(this), Priority.Monitor, plugin);
|
||||||
pm.registerEvent(Event.Type.PLAYER_TELEPORT, new MovingPlayerMonitor(this), Priority.Monitor, plugin);
|
pm.registerEvent(Event.Type.PLAYER_TELEPORT, new MovingPlayerMonitor(this), Priority.Monitor, plugin);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import net.minecraft.server.Block;
|
|||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
|
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
|
||||||
@ -31,9 +32,11 @@ public class MovingData {
|
|||||||
|
|
||||||
public boolean insideVehicle = false;
|
public boolean insideVehicle = false;
|
||||||
|
|
||||||
// WORKAROUND for changed PLAYER_MOVE logic
|
// Use to determine if an move event should be handled
|
||||||
public Location teleportTo = null;
|
public Location teleportTo = null;
|
||||||
public Location lastLocation = null;
|
|
||||||
|
// Use to track the world the player is in
|
||||||
|
public World lastLocation = null;
|
||||||
|
|
||||||
public Location teleportInitializedByMe = null;
|
public Location teleportInitializedByMe = null;
|
||||||
|
|
||||||
@ -81,7 +84,7 @@ public class MovingData {
|
|||||||
|
|
||||||
if(data.moving == null) {
|
if(data.moving == null) {
|
||||||
data.moving = new MovingData();
|
data.moving = new MovingData();
|
||||||
data.moving.lastLocation = p.getLocation();
|
data.moving.lastLocation = p.getLocation().getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.moving;
|
return data.moving;
|
||||||
|
@ -3,7 +3,6 @@ package cc.co.evenprime.bukkit.nocheat.listeners;
|
|||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.event.player.PlayerListener;
|
import org.bukkit.event.player.PlayerListener;
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
|
||||||
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
|
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
|
||||||
@ -22,16 +21,11 @@ public class MovingPlayerMonitor extends PlayerListener {
|
|||||||
this.check = check;
|
this.check = check;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlayerRespawn(PlayerRespawnEvent event) {
|
|
||||||
check.respawned(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||||
check.teleported(event);
|
check.teleported(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
check.updateVelocity(event.getPlayer().getVelocity(), MovingData.get(event.getPlayer()));
|
check.updateVelocity(event.getPlayer().getVelocity(), MovingData.get(event.getPlayer()));
|
||||||
@ -41,8 +35,8 @@ public class MovingPlayerMonitor extends PlayerListener {
|
|||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
if(!event.isCancelled()) {
|
if(!event.isCancelled()) {
|
||||||
MovingData data = MovingData.get(event.getPlayer());
|
MovingData data = MovingData.get(event.getPlayer());
|
||||||
data.lastLocation = event.getTo();
|
data.lastLocation = event.getPlayer().getLocation().getWorld();
|
||||||
if(event.getPlayer().isInsideVehicle()) {
|
if( event.getPlayer().isInsideVehicle()) {
|
||||||
data.setBackPoint = event.getTo();
|
data.setBackPoint = event.getTo();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
Reference in New Issue
Block a user