mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-27 09:51:32 +01:00
Better compatibility with Essentials "jail" plus big performance
improvements
This commit is contained in:
parent
05db6c58af
commit
f75a7ecaa1
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user