Updated for CB #1046. Use new PlayerVelocity event + adapt to new

player move events + use new method to find out if "allow-flight" was
set.
This commit is contained in:
Evenprime 2011-08-09 08:32:37 +02:00
parent 91c77a1aab
commit 33e9c46716
7 changed files with 362 additions and 421 deletions

View File

@ -3,7 +3,7 @@ name: NoCheat
author: Evenprime
main: cc.co.evenprime.bukkit.nocheat.NoCheat
version: 1.11d
version: 1.12
softdepend: [ Permissions, CraftIRC ]

View File

@ -1,8 +1,6 @@
package cc.co.evenprime.bukkit.nocheat;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -66,7 +64,6 @@ public class NoCheat extends JavaPlugin {
// CraftIRC, if available
private CraftIRC irc;
private boolean allowFlightSet;
private Level chatLevel;
private Level ircLevel;
@ -85,7 +82,7 @@ public class NoCheat extends JavaPlugin {
public String[] getMessagesOfTheDay() {
return new String[] {"NoCheat now supports the new Bukkit-Permission system. You can activate it in the config file.", "There will be a change in the near future to how movement in CraftBukkit works, which will break NoCheats moving-check(s) completely, causing tons of false positives. Be careful if you tend to run bleeding edge builds of CraftBukkit.", "This version of NoCheat was written for CraftBukkit RB 1000, but may still work for some older or newer versions.", "You can find detailed information about all configuration options of NoCheat in the file \"descriptions.txt\" in your \"plugins/NoCheat\" folder", "You can deactivate these Messages in the config file, if they annoy you."};
return new String[] {"This version of NoCheat was written for CraftBukkit CB #1046, it will NOT work on older versions.", "NoCheat supports the new SuperPerms system. You can activate it in the config file.", "You can find detailed information about all configuration options of NoCheat in the file \"descriptions.txt\" in your \"plugins/NoCheat\" folder", "You can deactivate these Messages in the config file, if they annoy you."};
}
@Override
@ -153,7 +150,7 @@ public class NoCheat extends JavaPlugin {
// just for convenience
checks = new Check[] {movingCheck, speedhackCheck, airbuildCheck, bogusitemsCheck, nukeCheck};
if(!allowFlightSet && movingCheck.isActive()) {
if(!this.getServer().getAllowFlight() && movingCheck.isActive()) {
Logger.getLogger("Minecraft").warning("[NoCheat] you have set \"allow-flight=false\" in your server.properties file. That builtin anti-flying-mechanism will likely conflict with this plugin. Please consider deactivating it by setting it to \"true\"");
}
@ -385,24 +382,6 @@ public class NoCheat extends JavaPlugin {
e.printStackTrace();
this.setEnabled(false);
}
try {
BufferedReader reader = new BufferedReader(new FileReader(new File("server.properties")));
allowFlightSet = true;
String s = null;
while((s = reader.readLine()) != null) {
if(s.startsWith("allow-flight=false")) {
allowFlightSet = false;
}
}
} catch(Exception e) {
e.printStackTrace();
// ignore errors
}
}
private String getActiveChecksAsString() {

View File

@ -88,18 +88,12 @@ public class FlyingCheck {
// its movement, plus additional events if the "velocity" was big and can cause longer flights
// The server sent the player a "velocity" packet a short time ago
if(data.maxYVelocity > 0.0D) {
data.vertFreedomCounter = 30;
// Be generous with the height limit for the client
data.vertFreedom += data.maxYVelocity*2D;
data.maxYVelocity = 0.0D;
}
// consume a counter for this client
if(data.vertFreedomCounter > 0) {
data.vertFreedomCounter--;
data.vertFreedom += data.maxYVelocity*2D;
data.maxYVelocity *= 0.90D;
}
final double limit = data.vertFreedom;

View File

@ -23,7 +23,6 @@ import cc.co.evenprime.bukkit.nocheat.actions.LogAction;
import cc.co.evenprime.bukkit.nocheat.config.NoCheatConfiguration;
import cc.co.evenprime.bukkit.nocheat.data.MovingData;
import cc.co.evenprime.bukkit.nocheat.data.PermissionData;
import cc.co.evenprime.bukkit.nocheat.listeners.MovingEntityListener;
import cc.co.evenprime.bukkit.nocheat.listeners.MovingPlayerListener;
import cc.co.evenprime.bukkit.nocheat.listeners.MovingPlayerMonitor;
@ -35,392 +34,390 @@ import cc.co.evenprime.bukkit.nocheat.listeners.MovingPlayerMonitor;
*/
public class MovingCheck extends Check {
public MovingCheck(NoCheat plugin, NoCheatConfiguration config) {
super(plugin, "moving", PermissionData.PERMISSION_MOVING, config);
helper = new MovingEventHelper();
flyingCheck = new FlyingCheck();
runningCheck = new RunningCheck();
}
public MovingCheck(NoCheat plugin, NoCheatConfiguration config) {
super(plugin, "moving", PermissionData.PERMISSION_MOVING, config);
private int ticksBeforeSummary;
helper = new MovingEventHelper();
flyingCheck = new FlyingCheck();
runningCheck = new RunningCheck();
}
public long statisticElapsedTimeNano = 0;
private int ticksBeforeSummary;
public boolean allowFlying;
public boolean allowFakeSneak;
public boolean allowFastSwim;
public long statisticElapsedTimeNano = 0;
public double stepWidth;
public double sneakWidth;
public double swimWidth;
private boolean waterElevators;
public boolean allowFlying;
public boolean allowFakeSneak;
public boolean allowFastSwim;
private String logMessage;
private String summaryMessage;
public double stepWidth;
public double sneakWidth;
public double swimWidth;
// How should moving violations be treated?
private Action actions[][];
private boolean waterElevators;
public long statisticTotalEvents = 1; // Prevent accidental division by 0 at some point
private String logMessage;
private String summaryMessage;
private boolean enforceTeleport;
// How should moving violations be treated?
private Action actions[][];
private final MovingEventHelper helper;
private final FlyingCheck flyingCheck;
private final RunningCheck runningCheck;
public long statisticTotalEvents = 1; // Prevent accidental division by 0 at some point
/**
* The actual check.
* First find out if the event needs to be handled at all
* Second check if the player moved too far horizontally
* Third check if the player moved too high vertically
* Fourth treat any occured violations as configured
* @param event
*/
private boolean enforceTeleport;
public Location check(Player player, Location from, Location to,
MovingData data) {
updateVelocity(player.getVelocity(), data);
Location newToLocation = null;
final long startTime = System.nanoTime();
/************* DECIDE WHICH CHECKS NEED TO BE RUN *************/
final boolean flyCheck = !allowFlying && !plugin.hasPermission(player, PermissionData.PERMISSION_FLYING, checkOPs);
final boolean runCheck = true;
private final MovingEventHelper helper;
private final FlyingCheck flyingCheck;
private final RunningCheck runningCheck;
/***************** REFINE EVENT DATA FOR CHECKS ***************/
/**
* The actual check.
* First find out if the event needs to be handled at all
* Second check if the player moved too far horizontally
* Third check if the player moved too high vertically
* Fourth treat any occured violations as configured
* @param event
*/
if(flyCheck || runCheck) {
// In both cases it will be interesting to know the type of underground the player
// is in or goes to
final int fromType = helper.isLocationOnGround(from.getWorld(), from.getX(), from.getY(), from.getZ(), waterElevators);
final int toType = helper.isLocationOnGround(to.getWorld(), to.getX(), to.getY(),to.getZ(), waterElevators);
public Location check(Player player, Location from, Location to,
MovingData data) {
final boolean fromOnGround = fromType != MovingEventHelper.NONSOLID;
final boolean toOnGround = toType != MovingEventHelper.NONSOLID;
Location newToLocation = null;
// Distribute data to checks in the form needed by the checks
final long startTime = System.nanoTime();
/********************* EXECUTE THE CHECKS ********************/
double result = 0.0D;
/************* DECIDE WHICH CHECKS NEED TO BE RUN *************/
final boolean flyCheck = !allowFlying && !plugin.hasPermission(player, PermissionData.PERMISSION_FLYING, checkOPs);
final boolean runCheck = true;
if(flyCheck) {
result += Math.max(0D, flyingCheck.check(player, from, fromOnGround, to, toOnGround, data));
}
else
{
// If players are allowed to fly, there's no need to remember the last location on ground
data.setBackPoint = from;
}
/***************** REFINE EVENT DATA FOR CHECKS ***************/
if(runCheck) {
result += Math.max(0D, runningCheck.check(from, to,
!allowFakeSneak && player.isSneaking(), !allowFastSwim && (fromType & toType & MovingEventHelper.LIQUID) > 0, data, this));
}
/********* HANDLE/COMBINE THE RESULTS OF THE CHECKS ***********/
if(flyCheck || runCheck) {
data.jumpPhase++;
if(fromOnGround) {
// In both cases it will be interesting to know the type of underground the player
// is in or goes to
final int fromType = helper.isLocationOnGround(from.getWorld(), from.getX(), from.getY(), from.getZ(), waterElevators);
final int toType = helper.isLocationOnGround(to.getWorld(), to.getX(), to.getY(),to.getZ(), waterElevators);
final boolean fromOnGround = fromType != MovingEventHelper.NONSOLID;
final boolean toOnGround = toType != MovingEventHelper.NONSOLID;
// Distribute data to checks in the form needed by the checks
/********************* EXECUTE THE CHECKS ********************/
double result = 0.0D;
if(flyCheck) {
result += Math.max(0D, flyingCheck.check(player, from, fromOnGround, to, toOnGround, data));
}
else
{
// If players are allowed to fly, there's no need to remember the last location on ground
data.setBackPoint = from;
}
if(runCheck) {
result += Math.max(0D, runningCheck.check(from, to,
!allowFakeSneak && player.isSneaking(), !allowFastSwim && (fromType & toType & MovingEventHelper.LIQUID) > 0, data, this));
}
/********* HANDLE/COMBINE THE RESULTS OF THE CHECKS ***********/
data.jumpPhase++;
if(fromOnGround) {
data.setBackPoint = from;
data.jumpPhase = 0;
}
else if(result <= 0 && toOnGround) {
data.jumpPhase = 0;
}
if(result > 0) {
// Increment violation counter
data.violationLevel += result;
if(data.setBackPoint == null) data.setBackPoint = from;
}
if(result > 0 && data.violationLevel > 1) {
setupSummaryTask(player, data);
if(result > 0) {
// Increment violation counter
data.violationLevel += result;
if(data.setBackPoint == null) data.setBackPoint = from;
}
int level = limitCheck(data.violationLevel-1);
data.violationsInARow[level]++;
if(result > 0 && data.violationLevel > 1) {
newToLocation = action(player, from, to, actions[level], data.violationsInARow[level], data, helper);
}
}
// Slowly reduce the level with each event
data.violationLevel *= 0.97;
data.horizFreedom *= 0.97;
statisticElapsedTimeNano += System.nanoTime() - startTime;
statisticTotalEvents++;
return newToLocation;
}
setupSummaryTask(player, data);
/**
* Various corner cases that would cause this check to fail or require special treatment
* @param player
* @param data
* @param from
* @param to
* @return
*/
public boolean shouldBeApplied(final Player player, final MovingData data, final Location from, final Location to) {
int level = limitCheck(data.violationLevel-1);
if(player.isDead() || player.isInsideVehicle()) return false;
data.violationsInARow[level]++;
if(data.wasTeleported) {
// Remember this location
data.teleportedTo = from.clone();
data.wasTeleported = false;
data.jumpPhase = 0;
}
newToLocation = action(player, from, to, actions[level], data.violationsInARow[level], data, helper);
}
}
if(data.teleportedTo != null && data.teleportedTo.getWorld().equals(from.getWorld())) {
// As long as the from-Location doesn't change, the player didn't accept the teleport
if(data.teleportedTo.distanceSquared(from) < 0.01D) {
// Event after Teleport ignored
return false;
}
else {
// The player finally accepted the teleport with the previous event
data.teleportedTo = null;
}
}
// Slowly reduce the level with each event
data.violationLevel *= 0.97;
data.horizFreedom *= 0.97;
return true;
}
statisticElapsedTimeNano += System.nanoTime() - startTime;
statisticTotalEvents++;
/**
* Register a task with bukkit that will be run a short time from now, displaying how many
* violations happened in that timeframe
* @param p
* @param data
*/
private void setupSummaryTask(final Player p, final MovingData data) {
// Setup task to display summary later
if(data.summaryTask == -1) {
Runnable r = new Runnable() {
return newToLocation;
}
@Override
public void run() {
try {
if(data.highestLogLevel != null) {
String logString = String.format(summaryMessage, p.getName(), ticksBeforeSummary/20, data.violationsInARow[0], data.violationsInARow[1],data.violationsInARow[2]);
plugin.log(data.highestLogLevel, logString);
data.highestLogLevel = Level.ALL;
}
// deleting its own reference
data.summaryTask = -1;
/**
* Various corner cases that would cause this check to fail or require special treatment
* @param player
* @param data
* @param from
* @param to
* @return
*/
public boolean shouldBeApplied(final Player player, final MovingData data, final Location from, final Location to) {
data.violationsInARow[0] = 0;
data.violationsInARow[1] = 0;
data.violationsInARow[2] = 0;
}
catch(Exception e) { }
}
};
if(player.isDead() || player.isInsideVehicle()) return false;
// Give a summary in x ticks. 20 ticks ~ 1 second
data.summaryTask = plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, r, ticksBeforeSummary);
}
}
if(data.wasTeleported) {
// Remember this location
data.teleportedTo = from.clone();
data.wasTeleported = false;
data.jumpPhase = 0;
}
/**
* Call this when a player got successfully teleported with the corresponding event to adjust stored
* data to the new situation
*
* @param event
*/
public void teleported(PlayerTeleportEvent event) {
if(data.teleportedTo != null && data.teleportedTo.getWorld().equals(from.getWorld())) {
// As long as the from-Location doesn't change, the player didn't accept the teleport
if(data.teleportedTo.distanceSquared(from) < 0.01D) {
// Event after Teleport ignored
return false;
}
else {
// The player finally accepted the teleport with the previous event
data.teleportedTo = null;
}
}
MovingData data = plugin.getDataManager().getMovingData(event.getPlayer());
// We can enforce a teleport, if that flag is explicitly set (but I'd rather have other plugins
// not arbitrarily cancel teleport events in the first place...
if(data.teleportInitializedByMe != null && event.isCancelled() && enforceTeleport && event.getTo().equals(data.teleportInitializedByMe)) {
event.setCancelled(false);
data.teleportInitializedByMe = null;
}
if(!event.isCancelled()) {
data.wasTeleported = true;
data.setBackPoint = event.getTo().clone();
//data.lastLocation = event.getTo().clone();
}
// reset anyway - if another plugin cancelled our teleport it's no use to try and be precise
data.jumpPhase = 0;
}
/**
* Update the cached values for players velocity to be prepared to
* give them additional movement freedom in their next move events
* @param v
* @param data
*/
public void updateVelocity(Vector v, MovingData data) {
// Compare the velocity vector to the existing movement freedom that we've from previous events
double tmp = (Math.abs(v.getX()) + Math.abs(v.getZ())) * 3D;
if(tmp > data.horizFreedom)
data.horizFreedom = tmp;
if(v.getY() > data.maxYVelocity) {
data.maxYVelocity = v.getY();
}
}
/**
* Perform actions that were specified in the config file
* @param event
* @param action
* @return
*/
private Location action( Player player, Location from, Location to, Action[] actions, int violations, MovingData data, MovingEventHelper helper) {
return true;
}
Location newToLocation = null;
if(actions == null) return newToLocation;
boolean cancelled = false;
/**
* Register a task with bukkit that will be run a short time from now, displaying how many
* violations happened in that timeframe
* @param p
* @param data
*/
private void setupSummaryTask(final Player p, final MovingData data) {
// Setup task to display summary later
if(data.summaryTask == -1) {
Runnable r = new Runnable() {
for(Action a : actions) {
if(a.firstAfter <= violations) {
if(a.firstAfter == violations || a.repeat) {
if(a instanceof LogAction) {
// prepare log message if necessary
String log = String.format(Locale.US, logMessage, player.getName(), from.getWorld().getName(), to.getWorld().getName(), from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), Math.abs(from.getX()-to.getX()),to.getY()-from.getY(), Math.abs(from.getZ()-to.getZ()));
@Override
public void run() {
plugin.log(((LogAction)a).level, log);
try {
if(data.highestLogLevel != null) {
String logString = String.format(summaryMessage, p.getName(), ticksBeforeSummary/20, data.violationsInARow[0], data.violationsInARow[1],data.violationsInARow[2]);
plugin.log(data.highestLogLevel, logString);
// Remember the highest log level we encountered to determine what level the summary log message should have
if(data.highestLogLevel == null) data.highestLogLevel = Level.ALL;
if(data.highestLogLevel.intValue() < ((LogAction)a).level.intValue()) data.highestLogLevel = ((LogAction)a).level;
}
else if(!cancelled && a instanceof CancelAction) {
// Make a modified copy of the setBackPoint to prevent other plugins from accidentally modifying it
// and keep the current pitch and yaw (setbacks "feel" better that way). Plus try to adapt the Y-coord
// to place the player close to ground
data.highestLogLevel = Level.ALL;
}
// deleting its own reference
data.summaryTask = -1;
double y = data.setBackPoint.getY();
data.violationsInARow[0] = 0;
data.violationsInARow[1] = 0;
data.violationsInARow[2] = 0;
}
catch(Exception e) { }
}
};
// search for the first solid block up to 5 blocks below the setbackpoint and teleport the player there
int i = 0;
for(; i < 20; i++) {
if(helper.isLocationOnGround(data.setBackPoint.getWorld(), data.setBackPoint.getX(), data.setBackPoint.getY() - 0.5*i, data.setBackPoint.getZ(), waterElevators) != MovingData.NONSOLID) {
break;
}
}
y -= 0.5*i;
// Give a summary in x ticks. 20 ticks ~ 1 second
data.summaryTask = plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, r, ticksBeforeSummary);
}
}
data.setBackPoint.setY(y);
/**
* Call this when a player got successfully teleported with the corresponding event to adjust stored
* data to the new situation
*
* @param event
*/
public void teleported(PlayerTeleportEvent event) {
// Remember the location we send the player to, to identify teleports that were started by us
data.teleportInitializedByMe = new Location(data.setBackPoint.getWorld(), data.setBackPoint.getX(), y, data.setBackPoint.getZ(), to.getYaw(), to.getPitch());
MovingData data = plugin.getDataManager().getMovingData(event.getPlayer());
newToLocation = data.teleportInitializedByMe;
// We can enforce a teleport, if that flag is explicitly set (but I'd rather have other plugins
// not arbitrarily cancel teleport events in the first place...
if(data.teleportInitializedByMe != null && event.isCancelled() && enforceTeleport && event.getTo().equals(data.teleportInitializedByMe)) {
event.setCancelled(false);
data.teleportInitializedByMe = null;
}
cancelled = true; // just prevent us from treating more than one "cancel" action, which would make no sense
}
else if(a instanceof CustomAction)
plugin.handleCustomAction((CustomAction)a, player);
}
}
}
return newToLocation;
}
if(!event.isCancelled()) {
data.wasTeleported = true;
data.setBackPoint = event.getTo().clone();
//data.lastLocation = event.getTo().clone();
}
/**
* Check a value against an array of sorted values to find out
* where it fits in
* @param value
* @param limits
* @return
*/
private static int limitCheck(final double value) {
// reset anyway - if another plugin cancelled our teleport it's no use to try and be precise
data.jumpPhase = 0;
}
if(value > 0.0D) {
if(value > 0.5D) {
if(value > 2.0D)
return 2;
return 1; }
return 0; }
return -1;
}
@Override
public void configure(NoCheatConfiguration config) {
/**
* Update the cached values for players velocity to be prepared to
* give them additional movement freedom in their next move events
* @param v
* @param data
*/
public void updateVelocity(Vector v, MovingData data) {
try {
allowFlying = config.getBooleanValue("moving.allowflying");
allowFakeSneak = config.getBooleanValue("moving.allowfakesneak");
allowFastSwim = config.getBooleanValue("moving.allowfastswim");
// Compare the velocity vector to the existing movement freedom that we've from previous events
double tmp = (Math.abs(v.getX()) + Math.abs(v.getZ())) * 3D;
if(tmp > data.horizFreedom)
data.horizFreedom = tmp;
waterElevators = config.getBooleanValue("moving.waterelevators");
if(v.getY() > 0.0D) {
data.vertFreedomCounter = 50;
data.maxYVelocity += v.getY();
}
}
checkOPs = config.getBooleanValue("moving.checkops");
logMessage = config.getStringValue("moving.logmessage").
replace("[player]", "%1$s").
replace("[world]", "%2$s").
replace("[from]", "(%4$.1f, %5$.1f, %6$.1f)").
replace("[to]", "(%7$.1f, %8$.1f, %9$.1f)").
replace("[distance]", "(%10$.1f, %11$.1f, %12$.1f)");
/**
* Perform actions that were specified in the config file
* @param event
* @param action
* @return
*/
private Location action( Player player, Location from, Location to, Action[] actions, int violations, MovingData data, MovingEventHelper helper) {
summaryMessage = config.getStringValue("moving.summarymessage").
replace("[timeframe]", "%2$d").
replace("[player]", "%1$s").
replace("[violations]", "(%3$d,%4$d,%5$d)");
ticksBeforeSummary = config.getIntegerValue("moving.summaryafter")*20;
actions = new Action[3][];
Location newToLocation = null;
actions[0] = config.getActionValue("moving.action.low");
actions[1] = config.getActionValue("moving.action.med");
actions[2] = config.getActionValue("moving.action.high");
if(actions == null) return newToLocation;
boolean cancelled = false;
setActive(config.getBooleanValue("active.moving"));
for(Action a : actions) {
if(a.firstAfter <= violations) {
if(a.firstAfter == violations || a.repeat) {
if(a instanceof LogAction) {
// prepare log message if necessary
String log = String.format(Locale.US, logMessage, player.getName(), from.getWorld().getName(), to.getWorld().getName(), from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ(), Math.abs(from.getX()-to.getX()),to.getY()-from.getY(), Math.abs(from.getZ()-to.getZ()));
enforceTeleport = config.getBooleanValue("moving.enforceteleport");
stepWidth = ((double)config.getIntegerValue("moving.limits.walking")) /100D;
sneakWidth = ((double)config.getIntegerValue("moving.limits.sneaking"))/100D;
swimWidth = ((double)config.getIntegerValue("moving.limits.swimming"))/100D;
plugin.log(((LogAction)a).level, log);
} catch (ConfigurationException e) {
setActive(false);
e.printStackTrace();
}
// Remember the highest log level we encountered to determine what level the summary log message should have
if(data.highestLogLevel == null) data.highestLogLevel = Level.ALL;
if(data.highestLogLevel.intValue() < ((LogAction)a).level.intValue()) data.highestLogLevel = ((LogAction)a).level;
}
else if(!cancelled && a instanceof CancelAction) {
// Make a modified copy of the setBackPoint to prevent other plugins from accidentally modifying it
// and keep the current pitch and yaw (setbacks "feel" better that way). Plus try to adapt the Y-coord
// to place the player close to ground
}
double y = data.setBackPoint.getY();
@Override
protected void registerListeners() {
PluginManager pm = Bukkit.getServer().getPluginManager();
// search for the first solid block up to 5 blocks below the setbackpoint and teleport the player there
int i = 0;
for(; i < 20; i++) {
if(helper.isLocationOnGround(data.setBackPoint.getWorld(), data.setBackPoint.getX(), data.setBackPoint.getY() - 0.5*i, data.setBackPoint.getZ(), waterElevators) != MovingData.NONSOLID) {
break;
}
}
y -= 0.5*i;
Listener movingPlayerMonitor = new MovingPlayerMonitor(plugin.getDataManager(), this);
data.setBackPoint.setY(y);
// Register listeners for moving check
pm.registerEvent(Event.Type.PLAYER_MOVE, new MovingPlayerListener(plugin.getDataManager(), this), Priority.Lowest, 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.ENTITY_DAMAGE, new MovingEntityListener(plugin.getDataManager(), this), Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_TELEPORT, movingPlayerMonitor, Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_PORTAL, movingPlayerMonitor, Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_RESPAWN, movingPlayerMonitor, Priority.Monitor, plugin);
}
// Remember the location we send the player to, to identify teleports that were started by us
data.teleportInitializedByMe = new Location(data.setBackPoint.getWorld(), data.setBackPoint.getX(), y, data.setBackPoint.getZ(), to.getYaw(), to.getPitch());
newToLocation = data.teleportInitializedByMe;
cancelled = true; // just prevent us from treating more than one "cancel" action, which would make no sense
}
else if(a instanceof CustomAction)
plugin.handleCustomAction((CustomAction)a, player);
}
}
}
return newToLocation;
}
/**
* Check a value against an array of sorted values to find out
* where it fits in
* @param value
* @param limits
* @return
*/
private static int limitCheck(final double value) {
if(value > 0.0D) {
if(value > 0.5D) {
if(value > 2.0D)
return 2;
return 1; }
return 0; }
return -1;
}
@Override
public void configure(NoCheatConfiguration config) {
try {
allowFlying = config.getBooleanValue("moving.allowflying");
allowFakeSneak = config.getBooleanValue("moving.allowfakesneak");
allowFastSwim = config.getBooleanValue("moving.allowfastswim");
waterElevators = config.getBooleanValue("moving.waterelevators");
checkOPs = config.getBooleanValue("moving.checkops");
logMessage = config.getStringValue("moving.logmessage").
replace("[player]", "%1$s").
replace("[world]", "%2$s").
replace("[from]", "(%4$.1f, %5$.1f, %6$.1f)").
replace("[to]", "(%7$.1f, %8$.1f, %9$.1f)").
replace("[distance]", "(%10$.1f, %11$.1f, %12$.1f)");
summaryMessage = config.getStringValue("moving.summarymessage").
replace("[timeframe]", "%2$d").
replace("[player]", "%1$s").
replace("[violations]", "(%3$d,%4$d,%5$d)");
ticksBeforeSummary = config.getIntegerValue("moving.summaryafter")*20;
actions = new Action[3][];
actions[0] = config.getActionValue("moving.action.low");
actions[1] = config.getActionValue("moving.action.med");
actions[2] = config.getActionValue("moving.action.high");
setActive(config.getBooleanValue("active.moving"));
enforceTeleport = config.getBooleanValue("moving.enforceteleport");
stepWidth = ((double)config.getIntegerValue("moving.limits.walking")) /100D;
sneakWidth = ((double)config.getIntegerValue("moving.limits.sneaking"))/100D;
swimWidth = ((double)config.getIntegerValue("moving.limits.swimming"))/100D;
} catch (ConfigurationException e) {
setActive(false);
e.printStackTrace();
}
}
@Override
protected void registerListeners() {
PluginManager pm = Bukkit.getServer().getPluginManager();
Listener movingPlayerMonitor = new MovingPlayerMonitor(plugin.getDataManager(), this);
// Register listeners for moving check
pm.registerEvent(Event.Type.PLAYER_MOVE, new MovingPlayerListener(plugin.getDataManager(), this), Priority.Lowest, plugin);
pm.registerEvent(Event.Type.PLAYER_MOVE, movingPlayerMonitor, Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_TELEPORT, movingPlayerMonitor, Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_PORTAL, movingPlayerMonitor, Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_RESPAWN, movingPlayerMonitor, Priority.Monitor, plugin);
pm.registerEvent(Event.Type.PLAYER_VELOCITY, movingPlayerMonitor, Priority.Monitor, plugin);
}
}

View File

@ -1,26 +0,0 @@
package cc.co.evenprime.bukkit.nocheat.listeners;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityListener;
import cc.co.evenprime.bukkit.nocheat.DataManager;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
public class MovingEntityListener extends EntityListener {
private final MovingCheck check;
private final DataManager dataManager;
public MovingEntityListener(DataManager dataManager, MovingCheck check) {
this.dataManager = dataManager;
this.check = check;
}
@Override
public void onEntityDamage(EntityDamageEvent event) {
if(event.getEntity() instanceof Player) {
check.updateVelocity(event.getEntity().getVelocity(), dataManager.getMovingData((Player)event.getEntity()));
}
}
}

View File

@ -37,7 +37,7 @@ public class MovingPlayerListener extends PlayerListener {
if(!check.skipCheck(player)) {
final MovingData data = dataManager.getMovingData(player);
final Location from = event.getFrom();
final Location from = player.getLocation();
final Location to = event.getTo();
Location newTo = null;

View File

@ -1,11 +1,11 @@
package cc.co.evenprime.bukkit.nocheat.listeners;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerVelocityEvent;
import cc.co.evenprime.bukkit.nocheat.DataManager;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
@ -18,48 +18,45 @@ import cc.co.evenprime.bukkit.nocheat.data.MovingData;
*/
public class MovingPlayerMonitor extends PlayerListener {
private final MovingCheck check;
private final DataManager dataManager;
private final MovingCheck check;
private final DataManager dataManager;
public MovingPlayerMonitor(DataManager dataManager, MovingCheck check) {
this.dataManager = dataManager;
this.check = check;
}
public MovingPlayerMonitor(DataManager dataManager, MovingCheck check) {
this.dataManager = dataManager;
this.check = check;
}
@Override
public void onPlayerRespawn(PlayerRespawnEvent event) {
MovingData data = dataManager.getMovingData(event.getPlayer());
data.wasTeleported = true;
data.setBackPoint = null;
data.jumpPhase = 0;
}
@Override
public void onPlayerRespawn(PlayerRespawnEvent event) {
MovingData data = dataManager.getMovingData(event.getPlayer());
data.wasTeleported = true;
data.setBackPoint = null;
data.jumpPhase = 0;
}
@Override
public void onPlayerPortal(PlayerPortalEvent event) {
check.teleported(event);
}
@Override
public void onPlayerPortal(PlayerPortalEvent event) {
check.teleported(event);
}
@Override
public void onPlayerTeleport(PlayerTeleportEvent event) {
check.teleported(event);
}
@Override
public void onPlayerTeleport(PlayerTeleportEvent event) {
check.teleported(event);
}
@Override
public void onPlayerVelocity(PlayerVelocityEvent event) {
check.updateVelocity(event.getVelocity(), dataManager.getMovingData(event.getPlayer()));
}
@Override
public void onPlayerMove(PlayerMoveEvent event) {
@Override
public void onPlayerInteract(PlayerInteractEvent event) {
check.updateVelocity(event.getPlayer().getVelocity(), dataManager.getMovingData(event.getPlayer()));
}
@Override
public void onPlayerMove(PlayerMoveEvent event) {
MovingData data = dataManager.getMovingData(event.getPlayer());
check.updateVelocity(event.getPlayer().getVelocity(), data);
if(!event.isCancelled()) {
if( event.getPlayer().isInsideVehicle()) {
data.setBackPoint = event.getTo();
}
}
}
if(!event.isCancelled()) {
if( event.getPlayer().isInsideVehicle()) {
MovingData data = dataManager.getMovingData(event.getPlayer());
data.setBackPoint = event.getTo();
}
}
}
}