Better compatibility with Essentials "jail" plus big performance

improvements
This commit is contained in:
Evenprime 2011-04-15 19:57:28 +02:00
parent 05db6c58af
commit f75a7ecaa1
9 changed files with 220 additions and 156 deletions

View File

@ -3,7 +3,7 @@ name: NoCheat
author: Evenprime
main: cc.co.evenprime.bukkit.nocheat.NoCheat
version: 0.8.4a
version: 0.8.5
commands:
nocheat:

View File

@ -1,8 +1,6 @@
package cc.co.evenprime.bukkit.nocheat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -60,9 +58,6 @@ public class NoCheat extends JavaPlugin {
// CraftIRC 2.x, if available
private CraftIRC irc;
// Store data between Events
private final Map<Player, NoCheatData> playerData = new HashMap<Player, NoCheatData>();
public NoCheat() {
movingCheck = new MovingCheck(this);
bedteleportCheck = new BedteleportCheck(this);
@ -73,52 +68,11 @@ public class NoCheat extends JavaPlugin {
setupConfig();
}
/**
* Main access to data that needs to be stored between different events.
* Always returns a NoCheatData object, because if there isn't one
* for the specified player, one will be created.
*
* @param p
* @return
*/
public NoCheatData getPlayerData(Player p) {
NoCheatData data = null;
if((data = playerData.get(p)) == null ) {
synchronized(playerData) {
data = playerData.get(p);
if(data == null) {
// If we have no data for the player, create some
data = new NoCheatData();
playerData.put(p, data);
}
}
}
return data;
}
/**
* Go through the playerData HashMap and remove players that are no longer online
* from the map. This should be called in long, regular intervals (e.g. every 10 minutes)
* to keep the memory footprint of the plugin low
*/
public void cleanPlayerDataCollection() {
synchronized(playerData) {
Iterator<Map.Entry<Player, NoCheatData>> it = playerData.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Player, NoCheatData> pairs = (Map.Entry<Player, NoCheatData>)it.next();
if(!pairs.getKey().isOnline())
it.remove();
}
}
}
@Override
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args)
{
if(sender instanceof Player) {
if(!hasPermission((Player)sender, "nocheat.p")) {
if(!hasPermission((Player)sender, NoCheatData.PERMISSION_P)) {
sender.sendMessage("NC: You are not allowed to use this command.");
return false;
}
@ -161,10 +115,10 @@ public class NoCheat extends JavaPlugin {
public void onDisable() {
PluginDescriptionFile pdfFile = this.getDescription();
if(config != null)
config.cleanup();
Logger.getLogger("Minecraft").info( "[NoCheat] version [" + pdfFile.getVersion() + "] is disabled.");
}
@ -181,8 +135,9 @@ public class NoCheat extends JavaPlugin {
pm.registerEvent(Event.Type.PLAYER_TELEPORT, new MovingMonitor(movingCheck), Priority.Monitor, this);
pm.registerEvent(Event.Type.PLAYER_INTERACT, new MovingMonitor(movingCheck), Priority.Monitor, this);
pm.registerEvent(Event.Type.PLAYER_MOVE, new MovingMonitor(movingCheck), Priority.Monitor, this);
pm.registerEvent(Event.Type.PLAYER_RESPAWN, new MovingMonitor(movingCheck), Priority.Monitor, this);
pm.registerEvent(Event.Type.ENTITY_DAMAGE, new MovingEntityListener(movingCheck), Priority.Monitor, this);
// Register listeners for speedhack check
pm.registerEvent(Event.Type.PLAYER_MOVE, new SpeedhackListener(speedhackCheck), Priority.High, this);
@ -215,7 +170,7 @@ public class NoCheat extends JavaPlugin {
@Override
public void run() {
cleanPlayerDataCollection();
NoCheatData.cleanPlayerDataCollection();
}
}, 5000, 5000);
@ -284,7 +239,7 @@ public class NoCheat extends JavaPlugin {
private void logToChat(Level l, String message) {
if(config.chatLevel.intValue() <= l.intValue()) {
for(Player player : getServer().getOnlinePlayers()) {
if(hasPermission(player, "nocheat.notify")) {
if(hasPermission(player, NoCheatData.PERMISSION_NOTIFY)) {
player.sendMessage("["+l.getName()+"] " + message);
}
}
@ -304,18 +259,23 @@ public class NoCheat extends JavaPlugin {
}
public boolean hasPermission(Player player, String permission) {
if(player == null || permission == null) {
public boolean hasPermission(Player player, int permission) {
if(player == null) {
return false;
}
try {
if(permissions != null && permissions.has(player, permission))
return true;
else if(permissions == null && player.isOp())
return true;
else
return false;
if(permissions == null)
return player.isOp();
else {
NoCheatData data = NoCheatData.getPlayerData(player);
if(data.permissionsLastUpdate + 10000 < System.currentTimeMillis()) {
data.permissionsLastUpdate = System.currentTimeMillis();
updatePermissions(player, data);
}
return data.permissionsCache[permission];
}
}
catch(Throwable e) {
if(!this.exceptionWithPermissions) {
@ -332,6 +292,18 @@ public class NoCheat extends JavaPlugin {
}
}
private void updatePermissions(Player player, NoCheatData data) {
data.permissionsCache[NoCheatData.PERMISSION_AIRBUILD] = permissions.has(player, "nocheat.airbuild");
data.permissionsCache[NoCheatData.PERMISSION_BEDTELEPORT] = permissions.has(player, "nocheat.bedteleport");
data.permissionsCache[NoCheatData.PERMISSION_FLYING] = permissions.has(player, "nocheat.flying");
data.permissionsCache[NoCheatData.PERMISSION_MOVING] = permissions.has(player, "nocheat.moving");
data.permissionsCache[NoCheatData.PERMISSION_P] = permissions.has(player, "nocheat.p");
data.permissionsCache[NoCheatData.PERMISSION_SPEEDHACK] = permissions.has(player, "nocheat.speedhack");
data.permissionsCache[NoCheatData.PERMISSION_NOTIFY] = permissions.has(player, "nocheat.notify");
}
/**
* Read the config file
*/
@ -353,12 +325,12 @@ public class NoCheat extends JavaPlugin {
private String getPermissionsForPlayerAsString(Player p) {
return (!movingCheck.isActive() ? movingCheck.getName() + "* " : (hasPermission(p, "nocheat.moving") ? movingCheck.getName() + " " : "") +
(!movingCheck.isActive() || movingCheck.allowFlying ? "flying* " : (hasPermission(p, "nocheat.flying") ? "flying " : "")) +
(!speedhackCheck.isActive() ? speedhackCheck.getName() + "* " : (hasPermission(p, "nocheat.speedhack") ? speedhackCheck.getName() + " " : "")) +
(!airbuildCheck.isActive() ? airbuildCheck.getName() + "* " : (hasPermission(p, "nocheat.airbuild") ? airbuildCheck.getName() + " " : "")) +
(!bedteleportCheck.isActive() ? bedteleportCheck.getName() + "* " : (hasPermission(p, "nocheat.bedteleport") ? bedteleportCheck.getName() + " " : "")) +
(hasPermission(p, "nocheat.notify") ? "notify " : ""));
return (!movingCheck.isActive() ? movingCheck.getName() + "* " : (hasPermission(p, NoCheatData.PERMISSION_MOVING) ? movingCheck.getName() + " " : "") +
(!movingCheck.isActive() || movingCheck.allowFlying ? "flying* " : (hasPermission(p, NoCheatData.PERMISSION_FLYING) ? "flying " : "")) +
(!speedhackCheck.isActive() ? speedhackCheck.getName() + "* " : (hasPermission(p, NoCheatData.PERMISSION_SPEEDHACK) ? speedhackCheck.getName() + " " : "")) +
(!airbuildCheck.isActive() ? airbuildCheck.getName() + "* " : (hasPermission(p, NoCheatData.PERMISSION_AIRBUILD) ? airbuildCheck.getName() + " " : "")) +
(!bedteleportCheck.isActive() ? bedteleportCheck.getName() + "* " : (hasPermission(p, NoCheatData.PERMISSION_BEDTELEPORT) ? bedteleportCheck.getName() + " " : "")) +
(hasPermission(p, NoCheatData.PERMISSION_NOTIFY) ? "notify " : ""));
}
public void handleCustomAction(Action a, Player player) {

View File

@ -1,8 +1,12 @@
package cc.co.evenprime.bukkit.nocheat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.entity.Player;
/**
* Storage for data persistence between events
@ -25,11 +29,13 @@ public class NoCheatData {
public Location movingSetBackPoint = null;
public Runnable movingSummaryTask = null;
public Level movingHighestLogLevel = null;
// WORKAROUND for changed PLAYER_MOVE logic
public Location movingTeleportTo = null;
public Location reset = null;
public boolean reset = false;
public Location respawned = null;
public long speedhackLastCheck = System.currentTimeMillis(); // timestamp of last check for speedhacks
public Location speedhackSetBackPoint = null;
@ -40,5 +46,59 @@ public class NoCheatData {
public Runnable airbuildSummaryTask = null;
public double maxYVelocity = 0.0D;
public NoCheatData() { }
public long permissionsLastUpdate = 0;
public boolean permissionsCache[] = new boolean[7];
public static final int PERMISSION_MOVING = 0;
public static final int PERMISSION_FLYING = 1;
public static final int PERMISSION_SPEEDHACK = 2;
public static final int PERMISSION_AIRBUILD = 3;
public static final int PERMISSION_BEDTELEPORT = 4;
public static final int PERMISSION_P = 5;
public static final int PERMISSION_NOTIFY = 6;
// Store data between Events
private static final Map<Player, NoCheatData> playerData = new HashMap<Player, NoCheatData>();
/**
* Main access to data that needs to be stored between different events.
* Always returns a NoCheatData object, because if there isn't one
* for the specified player, one will be created.
*
* @param p
* @return
*/
public static NoCheatData getPlayerData(Player p) {
NoCheatData data = null;
if((data = playerData.get(p)) == null ) {
synchronized(playerData) {
data = playerData.get(p);
if(data == null) {
// If we have no data for the player, create some
data = new NoCheatData();
playerData.put(p, data);
}
}
}
return data;
}
/**
* Go through the playerData HashMap and remove players that are no longer online
* from the map. This should be called in long, regular intervals (e.g. every 10 minutes)
* to keep the memory footprint of the plugin low
*/
public static void cleanPlayerDataCollection() {
synchronized(playerData) {
Iterator<Map.Entry<Player, NoCheatData>> it = playerData.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Player, NoCheatData> pairs = (Map.Entry<Player, NoCheatData>)it.next();
if(!pairs.getKey().isOnline())
it.remove();
}
}
}
}

View File

@ -37,12 +37,12 @@ public class AirbuildCheck extends Check {
public void check(BlockPlaceEvent event) {
// Should we check at all?
if(plugin.hasPermission(event.getPlayer(), "nocheat.airbuild"))
if(plugin.hasPermission(event.getPlayer(), NoCheatData.PERMISSION_AIRBUILD))
return;
// Are all 6 sides "air-blocks" -> cancel the event
if(event.getBlockAgainst().getType() == Material.AIR) {
final NoCheatData data = plugin.getPlayerData(event.getPlayer());
final NoCheatData data = NoCheatData.getPlayerData(event.getPlayer());
final Player p = event.getPlayer();
if(data.airbuildSummaryTask == null) {
@ -81,7 +81,7 @@ public class AirbuildCheck extends Check {
private void action(Action actions[], BlockPlaceEvent event, boolean loggingAllowed) {
if(actions == null) return;
boolean cancelled = false;
// Prepare log message if needed

View File

@ -3,6 +3,7 @@ package cc.co.evenprime.bukkit.nocheat.checks;
import org.bukkit.event.player.PlayerMoveEvent;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
/**
*
@ -20,7 +21,7 @@ public class BedteleportCheck extends Check {
public void check(PlayerMoveEvent event) {
// Should we check at all?
if(plugin.hasPermission(event.getPlayer(), "nocheat.bedteleport"))
if(plugin.hasPermission(event.getPlayer(), NoCheatData.PERMISSION_BEDTELEPORT))
return;
if(event.getPlayer().isSleeping())

View File

@ -7,6 +7,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.Vector;
@ -41,14 +42,13 @@ public class MovingCheck extends Check {
private final double stepWidth = 0.6D;
private final double sneakStepWidth = 0.25D;
// Limits
public final double moveLimits[] = { 0.0D, 0.5D, 2.0D };
public final double sneakLimits[] = { 0.0D, 0.5D, 2.0D };
public final double heightLimits[] = { 0.0D, 0.5D, 2.0D };
public int ticksBeforeSummary = 100;
public long statisticElapsedTimeNano = 0;
public boolean allowFlying = false;
@ -170,11 +170,24 @@ public class MovingCheck extends Check {
long startTime = System.nanoTime();
boolean canFly = false;
boolean stopEarly = false;
final Player player = event.getPlayer();
// Should we check at all
if(plugin.hasPermission(player, NoCheatData.PERMISSION_MOVING)) {
statisticElapsedTimeNano += System.nanoTime() - startTime;
statisticTotalEvents++;
return;
}
// Get the player-specific data
final NoCheatData data = plugin.getPlayerData(event.getPlayer());
final NoCheatData data = NoCheatData.getPlayerData(player);
if(data.respawned != null && data.respawned.equals(event.getTo()))
return;
else
data.respawned = null;
updateVelocity(player.getVelocity(), data);
// Get the two locations of the event
final Location to = event.getTo();
@ -182,45 +195,42 @@ public class MovingCheck extends Check {
// WORKAROUND for changed PLAYER_MOVE logic
final Location from = data.movingTeleportTo == null ? event.getFrom() : data.movingTeleportTo;
data.movingTeleportTo = null;
// Should we check at all
if(plugin.hasPermission(event.getPlayer(), "nocheat.moving"))
stopEarly = true;
else if(allowFlying || plugin.hasPermission(event.getPlayer(), "nocheat.flying"))
canFly = true;
// vehicles are a special case, I ignore them because the server controls them
if(!stopEarly && event.getPlayer().isInsideVehicle()) {
resetData(data, event.getTo());
stopEarly = true;
}
// The actual movingCheck starts here
// First check the distance the player has moved horizontally
double xDistance = Math.abs(from.getX()-to.getX());
double zDistance = Math.abs(from.getZ()-to.getZ());
double combined = Math.sqrt((xDistance*xDistance + zDistance*zDistance));
// If the target is a bed and distance not too big, allow it
// Bukkit prevents using blocks behind walls already, so I don't have to check for that
if(to.getWorld().getBlockTypeIdAt(to) == Material.BED_BLOCK.getId() && combined < 8.0D) {
stopEarly = true; // players are allowed to "teleport" into a bed over "short" distances
}
updateVelocity(event.getPlayer());
if(stopEarly) {
if(player.isInsideVehicle()) {
resetData(data, to);
statisticElapsedTimeNano += System.nanoTime() - startTime;
statisticTotalEvents++;
return;
}
boolean canFly = false;
if(allowFlying || plugin.hasPermission(player, NoCheatData.PERMISSION_FLYING))
canFly = true;
// The actual movingCheck starts here
// First check the distance the player has moved horizontally
final double xDistance = Math.abs(from.getX()-to.getX());
final double zDistance = Math.abs(from.getZ()-to.getZ());
final double combined = Math.sqrt((xDistance*xDistance + zDistance*zDistance));
// If the target is a bed and distance not too big, allow it
// Bukkit prevents using blocks behind walls already, so I don't have to check for that
if(to.getWorld().getBlockTypeIdAt(to) == Material.BED_BLOCK.getId() && combined < 8.0D) {
statisticElapsedTimeNano += System.nanoTime() - startTime;
statisticTotalEvents++;
return;
}
/**** Horizontal movement check START ****/
int vl1 = -1;
if(event.getPlayer().isSneaking())
//if(player.isSneaking())
if(false) // Currently disabled, still needs some additional work
vl1 = limitCheck(combined - (data.movingHorizFreedom + sneakStepWidth), moveLimits);
else
vl1 = limitCheck(combined - (data.movingHorizFreedom + stepWidth), moveLimits);
@ -354,7 +364,7 @@ public class MovingCheck extends Check {
action(event, event.getPlayer(), from, to, actions[vl], log, data);
}
statisticElapsedTimeNano += System.nanoTime() - startTime;
statisticTotalEvents++;
}
@ -384,6 +394,14 @@ public class MovingCheck extends Check {
}
}
public void respawned(PlayerRespawnEvent event) {
NoCheatData data = NoCheatData.getPlayerData(event.getPlayer());
data.respawned = event.getRespawnLocation();
}
/**
* Call this when a player got successfully teleported with the corresponding event to set new "setback" points
* and reset data (if necessary)
@ -391,31 +409,34 @@ public class MovingCheck extends Check {
* @param event
*/
public void teleported(PlayerTeleportEvent event) {
NoCheatData data = plugin.getPlayerData(event.getPlayer());
if(data.reset) { // My plugin requested this teleport while handling another event
data.reset = false;
NoCheatData data = NoCheatData.getPlayerData(event.getPlayer());
if(event.getTo().equals(data.reset)) { // My plugin requested this teleport while handling another event
// DANGEROUS, but I have no real choice on that one thanks to Essentials jail simply blocking ALL kinds of teleports
// even the respawn teleport, the player moved wrongly teleport, the "get player out of the void" teleport", ...
// TODO: Make this optional OR detect Essentials and make this dependent on essential
event.setCancelled(false);
}
else {
if(!event.isCancelled()) {
// If it wasn't our plugin that ordered the teleport, forget (almost) all our information and start from scratch
resetData(data, event.getTo());
}
else if(!event.isCancelled()) {
data.reset = null;
// If it wasn't our plugin that ordered the teleport, forget (almost) all our information and start from scratch
resetData(data, event.getTo());
}
// WORKAROUND for changed PLAYER_MOVE logic - I need to remember the "to" location of teleports and use it as a from-Location
// for the move event that comes next
data.movingTeleportTo = event.getTo();
if(!event.isCancelled()) {
// WORKAROUND for changed PLAYER_MOVE logic - I need to remember the "to" location of teleports and use it as a from-Location
// for the move event that comes next
data.movingTeleportTo = event.getTo();
}
}
public void updateVelocity(Player player) {
NoCheatData data = plugin.getPlayerData(player);
Vector v = player.getVelocity();
public static void updateVelocity(Vector v, NoCheatData data) {
// Compare the velocity vector to the existing movement freedom that we've from previous events
double tmp = Math.abs(v.getX()*2D) + Math.abs(v.getZ()*2D);
double tmp = (Math.abs(v.getX()) + Math.abs(v.getZ())) * 2D;
if(tmp > data.movingHorizFreedom)
data.movingHorizFreedom = tmp;
@ -474,7 +495,7 @@ public class MovingCheck extends Check {
*/
private void resetPlayer(PlayerMoveEvent event, Location from) {
NoCheatData data = plugin.getPlayerData(event.getPlayer());
NoCheatData data = NoCheatData.getPlayerData(event.getPlayer());
// Reset the jumpphase. We choose the setback-point such that it should be
// on solid ground, but in case it isn't (maybe the ground is gone now) we
@ -483,16 +504,21 @@ public class MovingCheck extends Check {
if(data.movingSetBackPoint == null) data.movingSetBackPoint = from.clone();
// Set a flag that gets used while handling teleport events
data.reset = true;
// Set a flag that gets used while handling teleport events (to determine if
// it was my teleport or someone else'
data.reset = data.movingSetBackPoint;
resetData(data, data.movingSetBackPoint);
// Put the player back to the chosen location
event.setFrom(data.movingSetBackPoint.clone());
event.setTo(data.movingSetBackPoint.clone());
event.getPlayer().teleport(data.movingSetBackPoint.clone());
event.setCancelled(true);
// Only reset player and cancel event if teleport is successful
if(event.getPlayer().teleport(data.movingSetBackPoint)) {
// Put the player back to the chosen location
event.setFrom(data.movingSetBackPoint);
event.setTo(data.movingSetBackPoint);
event.setCancelled(true);
}
}
@ -588,4 +614,6 @@ public class MovingCheck extends Check {
public String getName() {
return "moving";
}
}

View File

@ -1,6 +1,5 @@
package cc.co.evenprime.bukkit.nocheat.checks;
import org.bukkit.Location;
import org.bukkit.event.player.PlayerMoveEvent;
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
@ -40,11 +39,11 @@ public class SpeedhackCheck extends Check {
public void check(PlayerMoveEvent event) {
// Should we check at all?
if(plugin.hasPermission(event.getPlayer(), "nocheat.speedhack"))
if(plugin.hasPermission(event.getPlayer(), NoCheatData.PERMISSION_SPEEDHACK))
return;
// Get the player-specific data
NoCheatData data = plugin.getPlayerData(event.getPlayer());
NoCheatData data = NoCheatData.getPlayerData(event.getPlayer());
// Ignore events if the player has positive y-Velocity (these can be the cause of event spam between server and client)
if(event.getPlayer().getVelocity().getY() > 0.0D) {
@ -117,21 +116,16 @@ public class SpeedhackCheck extends Check {
private static void resetPlayer(PlayerMoveEvent event, NoCheatData data) {
Location l = data.speedhackSetBackPoint;
if(data.speedhackSetBackPoint == null) data.speedhackSetBackPoint = event.getFrom().clone();
data.reset = true;
data.reset = data.speedhackSetBackPoint;
// If we have stored a location for the player, we put him back there
if(l != null) {
event.setFrom(l);
event.setTo(l);
if(event.getPlayer().teleport(data.speedhackSetBackPoint)) {
event.setFrom(data.speedhackSetBackPoint);
event.setTo(data.speedhackSetBackPoint);
event.setCancelled(true);
event.getPlayer().teleport(l);
}
else {
event.setFrom(event.getFrom());
event.setTo(event.getFrom().clone());
event.setCancelled(true);
event.getPlayer().teleport(event.getFrom());
}
}

View File

@ -4,6 +4,8 @@ import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityListener;
import cc.co.evenprime.bukkit.nocheat.NoCheat;
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
public class MovingEntityListener extends EntityListener {
@ -18,7 +20,7 @@ public class MovingEntityListener extends EntityListener {
@Override
public void onEntityDamage(EntityDamageEvent event) {
if(event.getEntity() instanceof Player) {
check.updateVelocity((Player)event.getEntity());
MovingCheck.updateVelocity(event.getEntity().getVelocity(), NoCheatData.getPlayerData((Player)event.getEntity()));
}
}

View File

@ -3,8 +3,10 @@ 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.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import cc.co.evenprime.bukkit.nocheat.NoCheatData;
import cc.co.evenprime.bukkit.nocheat.checks.MovingCheck;
/**
@ -20,6 +22,11 @@ public class MovingMonitor extends PlayerListener {
this.check = check;
}
@Override
public void onPlayerRespawn(PlayerRespawnEvent event) {
check.respawned(event);
}
@Override
public void onPlayerTeleport(PlayerTeleportEvent event) {
check.teleported(event);
@ -27,11 +34,11 @@ public class MovingMonitor extends PlayerListener {
@Override
public void onPlayerInteract(PlayerInteractEvent event) {
check.updateVelocity(event.getPlayer());
MovingCheck.updateVelocity(event.getPlayer().getVelocity(), NoCheatData.getPlayerData(event.getPlayer()));
}
@Override
public void onPlayerMove(PlayerMoveEvent event) {
check.updateVelocity(event.getPlayer());
MovingCheck.updateVelocity(event.getPlayer().getVelocity(), NoCheatData.getPlayerData(event.getPlayer()));
}
}