diff --git a/Instructions.txt b/Instructions.txt
index 3d658564..1e24c974 100644
--- a/Instructions.txt
+++ b/Instructions.txt
@@ -598,6 +598,12 @@
swimming speed of players at all (NoCheatPlus knows when players sprint,
use Swiftness potions etc and will already adapt the speed based on
that data).
+
+ maxcooldown:
+ How much time the player can spend in the air if his velocity has been
+ modified by an external plugin (PreciousStones for example). The default
+ delay is 10 seconds because it sounds like a player won't spend more
+ than 10 seconds in the air.
allowfastsneaking:
Should sneaking players be allowed to move as fast as normal players.
diff --git a/plugin.yml b/plugin.yml
index c3338d84..0c0bd9d8 100644
--- a/plugin.yml
+++ b/plugin.yml
@@ -3,7 +3,7 @@ version: ${project.version}
description: ${project.description}
author: NeatMonster
-authors: [Eventprime, Juliui]
+authors: [Evenprime, Juliui, craftingmania]
website: ${project.url}
main: me.neatmonster.nocheatplus.NoCheatPlus
diff --git a/pom.xml b/pom.xml
index e6f6b69c..eaeeeb96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
NoCheatPlus
- 3.5.5_4
+ 3.5.5_5
Detect and fight the exploitation of various flaws/bugs in Minecraft.
http://dev.bukkit.org/server-mods/nocheatplus
diff --git a/src/me/neatmonster/nocheatplus/checks/chat/ChatCheckListener.java b/src/me/neatmonster/nocheatplus/checks/chat/ChatCheckListener.java
index a71acd8e..7dc26c2a 100644
--- a/src/me/neatmonster/nocheatplus/checks/chat/ChatCheckListener.java
+++ b/src/me/neatmonster/nocheatplus/checks/chat/ChatCheckListener.java
@@ -98,7 +98,10 @@ public class ChatCheckListener implements Listener, EventManager {
if ((event.getMessage().equalsIgnoreCase("/plugins")
|| event.getMessage().toLowerCase().startsWith("/plugins ")
|| event.getMessage().equalsIgnoreCase("/pl") || event.getMessage().toLowerCase().startsWith("/pl "))
- && Bukkit.getPluginManager().getPlugin("PluginList") == null && cc.hideNoCheatPlus) {
+ // Exception for 'PluginList'...
+ && Bukkit.getPluginManager().getPlugin("PluginList") == null
+ // ...and CommandHelper
+ && Bukkit.getPluginManager().getPlugin("CommandHelper") == null && cc.hideNoCheatPlus) {
// If the player isn't allowed to use this command
if (!event.getPlayer().hasPermission("bukkit.command.plugins"))
// Fake the permissions error message
@@ -111,7 +114,7 @@ public class ChatCheckListener implements Listener, EventManager {
final Plugin[] plugins = Bukkit.getPluginManager().getPlugins();
for (final Plugin plugin : plugins) {
- // But make sure to hide NoCheatPlus
+ // But make sure to hide NoCheatPlus from the plugins list
if (plugin.getName().equals("NoCheatPlus"))
continue;
if (pluginList.length() > 0) {
@@ -126,6 +129,7 @@ public class ChatCheckListener implements Listener, EventManager {
// Of course decrease the number of plugins
event.getPlayer().sendMessage("Plugins (" + (plugins.length - 1) + "): " + pluginList.toString());
}
+
// Cancel the event, we have already replied to the player
event.setCancelled(true);
}
diff --git a/src/me/neatmonster/nocheatplus/checks/moving/FlyingCheck.java b/src/me/neatmonster/nocheatplus/checks/moving/FlyingCheck.java
index 123aa11b..d520946d 100644
--- a/src/me/neatmonster/nocheatplus/checks/moving/FlyingCheck.java
+++ b/src/me/neatmonster/nocheatplus/checks/moving/FlyingCheck.java
@@ -106,7 +106,7 @@ public class FlyingCheck extends MovingCheck {
result = resultHoriz + resultVert;
// The player went to far, either horizontal or vertical
- if (result > 0) {
+ if (result > 0 && !data.velocityChanged) {
// Increment violation counter and statistics
data.runflyVL += result;
diff --git a/src/me/neatmonster/nocheatplus/checks/moving/MovingCheckListener.java b/src/me/neatmonster/nocheatplus/checks/moving/MovingCheckListener.java
index 77be9ec1..3afd5c2e 100644
--- a/src/me/neatmonster/nocheatplus/checks/moving/MovingCheckListener.java
+++ b/src/me/neatmonster/nocheatplus/checks/moving/MovingCheckListener.java
@@ -169,6 +169,8 @@ public class MovingCheckListener implements Listener, EventManager {
s.add("moving.sneaking");
if (m.nofallCheck)
s.add("moving.nofall");
+ if (m.trackerCheck)
+ s.add("moving.tracker");
if (m.waterWalkCheck)
s.add("moving.waterwalk");
} else
@@ -245,6 +247,16 @@ public class MovingCheckListener implements Listener, EventManager {
data.lastSafeLocations[1] = event.getFrom();
}
+ // Check if the player is on/in the ground
+ final int toType = CheckUtil.evaluateLocation(event.getPlayer().getWorld(), data.to);
+ if (data.velocityChanged
+ && (System.currentTimeMillis() - data.velocityChangedSince > 500L
+ && (CheckUtil.isOnGround(toType) || CheckUtil.isInGround(toType)) || cc.maxCooldown != -1
+ && System.currentTimeMillis() - data.velocityChangedSince > cc.maxCooldown)) {
+ data.velocityChanged = false;
+ data.velocityChangedSince = 0L;
+ }
+
PreciseLocation newTo = null;
/** RUNFLY CHECK SECTION **/
@@ -457,8 +469,9 @@ public class MovingCheckListener implements Listener, EventManager {
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()));
- // Reset the tracker's data
- data.fallingSince = 0L;
+ // Remeber that a plugin changed the player's velocity
+ data.velocityChanged = true;
+ data.velocityChangedSince = System.currentTimeMillis();
final Vector v = event.getVelocity();
diff --git a/src/me/neatmonster/nocheatplus/checks/moving/MovingConfig.java b/src/me/neatmonster/nocheatplus/checks/moving/MovingConfig.java
index 5ca0fc6d..5dba39f3 100644
--- a/src/me/neatmonster/nocheatplus/checks/moving/MovingConfig.java
+++ b/src/me/neatmonster/nocheatplus/checks/moving/MovingConfig.java
@@ -21,9 +21,10 @@ public class MovingConfig implements ConfigItem {
public final double swimmingSpeedLimit;
public final boolean sneakingCheck;
public final double sneakingSpeedLimit;
+ public final int maxCooldown;
public final ActionList actions;
- public final boolean tracker;
+ public final boolean trackerCheck;
public final ActionList trackerActions;
public final boolean allowFlying;
@@ -64,9 +65,10 @@ public class MovingConfig implements ConfigItem {
jumpheight = 135 / 100D;
sneakingCheck = !data.getBoolean(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING);
+ maxCooldown = data.getInt(ConfPaths.MOVING_RUNFLY_MAXCOOLDOWN);
actions = data.getActionList(ConfPaths.MOVING_RUNFLY_ACTIONS, Permissions.MOVING_RUNFLY);
- tracker = data.getBoolean(ConfPaths.MOVING_RUNFLY_TRACKER_CHECK);
+ trackerCheck = data.getBoolean(ConfPaths.MOVING_RUNFLY_TRACKER_CHECK);
trackerActions = data.getActionList(ConfPaths.MOVING_RUNFLY_TRACKER_ACTIONS, Permissions.MOVING_FLYING);
allowFlying = data.getBoolean(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWALWAYS);
diff --git a/src/me/neatmonster/nocheatplus/checks/moving/MovingData.java b/src/me/neatmonster/nocheatplus/checks/moving/MovingData.java
index 66ff83c7..501dd66c 100644
--- a/src/me/neatmonster/nocheatplus/checks/moving/MovingData.java
+++ b/src/me/neatmonster/nocheatplus/checks/moving/MovingData.java
@@ -48,6 +48,12 @@ public class MovingData implements DataItem {
// Keep in mind since when the player in falling/jumping
public long fallingSince = 0L;
+ // Is the player flying because of a plugin has modified his velocity
+ public boolean velocityChanged = false;
+
+ // If yes, since when?
+ public long velocityChangedSince = 0L;
+
// Remember if the player has already been on the ground
public boolean hasAlreadyBeenOnTheGround = false;
diff --git a/src/me/neatmonster/nocheatplus/checks/moving/RunningCheck.java b/src/me/neatmonster/nocheatplus/checks/moving/RunningCheck.java
index f756f63e..30f6d23b 100644
--- a/src/me/neatmonster/nocheatplus/checks/moving/RunningCheck.java
+++ b/src/me/neatmonster/nocheatplus/checks/moving/RunningCheck.java
@@ -77,7 +77,7 @@ public class RunningCheck extends MovingCheck {
data.runflyVL *= 0.95;
// Did the player move in unexpected ways?
- if (result > 0) {
+ if (result > 0 && !data.velocityChanged) {
// Increment violation counter
data.runflyVL += result;
diff --git a/src/me/neatmonster/nocheatplus/checks/moving/TrackerCheck.java b/src/me/neatmonster/nocheatplus/checks/moving/TrackerCheck.java
index 47eb74cf..b0867119 100644
--- a/src/me/neatmonster/nocheatplus/checks/moving/TrackerCheck.java
+++ b/src/me/neatmonster/nocheatplus/checks/moving/TrackerCheck.java
@@ -35,7 +35,7 @@ public class TrackerCheck extends MovingCheck {
// Do not do the check if it's disabled, if flying is allowed, if the player is
// allowed to fly because of its game mode, if he has the required permission,
// if he is in water, on a ladder or in vines.
- if (!cc.tracker || cc.allowFlying || player.getPlayer().getGameMode() == GameMode.CREATIVE
+ if (!cc.trackerCheck || cc.allowFlying || player.getPlayer().getGameMode() == GameMode.CREATIVE
|| player.getPlayer().getAllowFlight() || player.getPlayer().hasPermission(Permissions.MOVING_RUNFLY)
|| player.getPlayer().hasPermission(Permissions.MOVING_FLYING) || isLiquid
|| player.getPlayer().getLocation().getBlock().getType() == Material.LADDER
@@ -46,7 +46,7 @@ public class TrackerCheck extends MovingCheck {
}
// If the player isn't static or jumping
- if (Math.abs(player.getPlayer().getVelocity().getY()) > 0.1D) {
+ if (Math.abs(player.getPlayer().getVelocity().getY()) > 0.1D && !data.velocityChanged) {
// Only do something if the player has already been on the ground
if (!data.hasAlreadyBeenOnTheGround)
diff --git a/src/me/neatmonster/nocheatplus/command/CommandHandler.java b/src/me/neatmonster/nocheatplus/command/CommandHandler.java
index cb28d046..5e7a72f2 100644
--- a/src/me/neatmonster/nocheatplus/command/CommandHandler.java
+++ b/src/me/neatmonster/nocheatplus/command/CommandHandler.java
@@ -8,6 +8,9 @@ import java.util.Map;
import java.util.Map.Entry;
import me.neatmonster.nocheatplus.NoCheatPlus;
+import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
+import me.neatmonster.nocheatplus.checks.chat.ChatCheck;
+import me.neatmonster.nocheatplus.checks.chat.ChatConfig;
import me.neatmonster.nocheatplus.config.Permissions;
import org.bukkit.command.Command;
@@ -63,10 +66,15 @@ public class CommandHandler {
public boolean handleCommand(final NoCheatPlus plugin, final CommandSender sender, final Command command,
final String label, final String[] args) {
- // Hide NoCheatPlus's commands if the player doesn't have the required permission
- if (sender instanceof Player && !sender.hasPermission("nocheatplus.admin.commands")) {
- sender.sendMessage("Unknown command. Type \"help\" for help.");
- return true;
+ if (sender instanceof Player) {
+ final NoCheatPlusPlayer player = plugin.getPlayer((Player) sender);
+ final ChatConfig cc = ChatCheck.getConfig(player);
+
+ // Hide NoCheatPlus's commands if the player doesn't have the required permission
+ if (!sender.hasPermission("nocheatplus.admin.commands") && cc.hideNoCheatPlus) {
+ sender.sendMessage("Unknown command. Type \"help\" for help.");
+ return true;
+ }
}
boolean result = false;
diff --git a/src/me/neatmonster/nocheatplus/config/ConfPaths.java b/src/me/neatmonster/nocheatplus/config/ConfPaths.java
index 6600fd51..93e19d87 100644
--- a/src/me/neatmonster/nocheatplus/config/ConfPaths.java
+++ b/src/me/neatmonster/nocheatplus/config/ConfPaths.java
@@ -51,6 +51,7 @@ public abstract class ConfPaths {
public final static String MOVING_RUNFLY_SPRINTSPEED = MOVING_RUNFLY + "sprintspeed";
public final static String MOVING_RUNFLY_ALLOWFASTSNEAKING = MOVING_RUNFLY + "allowfastsneaking";
+ public final static String MOVING_RUNFLY_MAXCOOLDOWN = MOVING_RUNFLY + "maxcooldown";
public final static String MOVING_RUNFLY_ACTIONS = MOVING_RUNFLY + "actions";
public final static String MOVING_RUNFLY_CHECKNOFALL = MOVING_RUNFLY + "checknofall";
diff --git a/src/me/neatmonster/nocheatplus/config/DefaultConfiguration.java b/src/me/neatmonster/nocheatplus/config/DefaultConfiguration.java
index cc4d71c9..f628c1b6 100644
--- a/src/me/neatmonster/nocheatplus/config/DefaultConfiguration.java
+++ b/src/me/neatmonster/nocheatplus/config/DefaultConfiguration.java
@@ -46,6 +46,7 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
set(ConfPaths.MOVING_RUNFLY_CHECK, true);
set(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING, false);
+ set(ConfPaths.MOVING_RUNFLY_MAXCOOLDOWN, 10000);
set(ConfPaths.MOVING_RUNFLY_ACTIONS,
"log:moveshort:3:5:f cancel vl>100 log:moveshort:0:5:if cancel vl>400 log:movelong:0:5:cif cancel");