+ Added the "MorePacketsVehicule" check

+ Added a simple check against the "safe-respawn" exploit
+ Added a permission to disable boat placement on the ground
= Fixed the issue with the FastBreak check and the enchantment
= Fixed the issue with the WaterWalk check and the step/stairs
= Fixed the inversion of Rei's Minimap permission
- Removed some useless code
This commit is contained in:
NeatMonster 2012-04-07 23:53:25 +02:00
parent 7211f2cc4d
commit dbfe983c1e
16 changed files with 635 additions and 95 deletions

View File

@ -199,6 +199,20 @@
Allows players to make a lot more movements than normally possible. Doing
more movements will result in faster overall movement speed and causes the
server to spend a lot of additional time for processing these movements.
- nocheatplus.checks.moving.morepacketsvehicle
Allows players to make a lot more movements (while being in a vehicule) than
normally possible. Doing more movements will result in faster overall movement
speed and causes the server to spent a lot of additional time for processing
these movements.
- nocheatplus.checks.moving.boatonground
Allows players to place boats on the ground (and not only on the water).
- nocheatplus.checks.moving.respawntrick
Allows player to respawn on top if they are blocked by a gravel or a sand
block (instead of removing the blocks blocking them). This is usually used
by players to go quickly to the surface when they are in their mines).
-------------------- BLOCKBREAK Permissions for CHECKS -------------------------
@ -640,9 +654,29 @@
more steps per second than normal. Default is to log messages and
teleport the player back to a location where he was ~1 second before
("cancel" his movement). The Violation Level VL is the number of
packets that the player sent beyond the expected amount
packets that the player sent beyond the expected amount.
3) MOREPACKETSVEHICULE:
The morepacketsvehicule check is complementary to the "morepackets" check.
While the "morepacket" check limit the number of player-move packets send
per second, this "morepacketsvehicle" limit the number of vehicule-move
packets sent per second. A normal value is 20 packets per second.
active:
Should players be checked for this kind of cheating. If you are not
interested in players that cheat that way, set this to false. It is a
good idea to have this active, because players that cheat by sending
more packets than normally allowed may lag the server (each of those
packets has to be processed, after all).
actions:
What should happen if a player is considered to be cheating by taking
more steps per second than normal. Default is to log messages and break
the boat the player is using. The Violation Level VL is the number of
packets that the player sent beyond the expected amount.
3) WATERWALK:
4) WATERWALK:
The waterwalk check is used to prevent players from walking on water using
a client dedicated to griefing (this mode is usually called Jesus mod).

View File

@ -47,6 +47,12 @@ permissions:
description: Allow a player to cheat and not take fall damage at all
nocheatplus.checks.moving.morepackets:
description: Allow a player to send more move-event-packets than normal, causing him to move faster than normal
nocheatplus.checks.moving.morepacketsvehicle:
description: Allow a player to send more vehicule-move-event-packets than normal, causing him to move faster than normal
nocheatplus.checks.moving.boatonground:
description: Allow a player to place a boat on the ground (not only on the water)
nocheatplus.checks.moving.respawntrick:
description: Allow a player to respawn on top if blocked by gravel or sand (instead of removing the blocks)
nocheatplus.checks.blockbreak:
description: Allow the player to bypass all blockbreak checks
children:

View File

@ -4,7 +4,7 @@
<!-- Informations -->
<name>NoCheatPlus</name>
<version>3.5.2</version>
<version>3.5.3</version>
<description>Detect and fight the exploitation of various flaws/bugs in Minecraft.</description>
<url>http://dev.bukkit.org/server-mods/nocheatplus</url>

View File

@ -211,10 +211,10 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
if (!player.hasPermission(Permissions.CJB_MINIMAP))
message = message + "§3 §9 §2 §0 §0 §3";
// Disable Rei's Minimap's cave mode
if (!player.hasPermission(Permissions.REI_CAVE))
if (player.hasPermission(Permissions.REI_CAVE))
message = message + "§0§0§1§e§f";
// Disable Rei's Minimap's radar
if (!player.hasPermission(Permissions.REI_RADAR))
if (player.hasPermission(Permissions.REI_RADAR))
message = message + "§0§0§2§3§4§5§6§7§e§f";
// Disable Minecraft AutoMap's cheats
if (!player.hasPermission(Permissions.MC_AUTOMAP))

View File

@ -101,17 +101,6 @@ public class CheckUtil {
// nonsolid too
types[Material.STONE_PLATE.getId()] = SOLID | NONSOLID;
types[Material.WOOD_PLATE.getId()] = SOLID | NONSOLID;
/*
* for(int i = 0; i < 256; i++) {
* if(Block.byId[i] != null) {
* System.out.println(Material.getMaterial(i) +
* (isSolid(types[i]) ? " solid " : "") + (isNonSolid(types[i])
* ? " nonsolid " : "") + (isLiquid(types[i]) ? " liquid " :
* ""));
* }
* }
*/
}
/**

View File

@ -15,7 +15,6 @@ import me.neatmonster.nocheatplus.config.Permissions;
public class BlockBreakConfig implements ConfigItem {
public final boolean fastBreakCheck;
public final int fastBreakInterval;
public final ActionList fastBreakActions;
public final boolean reachCheck;
@ -33,7 +32,6 @@ public class BlockBreakConfig implements ConfigItem {
public BlockBreakConfig(final NoCheatPlusConfiguration data) {
fastBreakCheck = data.getBoolean(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK);
fastBreakInterval = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVAL);
fastBreakActions = data.getActionList(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, Permissions.BLOCKBREAK_FASTBREAK);
reachCheck = data.getBoolean(ConfPaths.BLOCKBREAK_REACH_CHECK);
reachDistance = 535D / 100D;

View File

@ -7,6 +7,10 @@ import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.actions.ParameterName;
import me.neatmonster.nocheatplus.data.Statistics.Id;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
public class FastBreakCheck extends BlockBreakCheck {
public FastBreakCheck(final NoCheatPlus plugin) {
@ -15,15 +19,38 @@ public class FastBreakCheck extends BlockBreakCheck {
public boolean check(final NoCheatPlusPlayer player, final BlockBreakData data, final BlockBreakConfig cc) {
int level = 0;
// Get the player's item in hand material
Material tool = player.getPlayer().getItemInHand() == null ? null : player.getPlayer().getItemInHand()
.getType();
if (isTool(tool))
// It's a tool, let's check its enchantment level
level = player.getPlayer().getItemInHand().getEnchantmentLevel(Enchantment.DIG_SPEED);
else
// It's not a tool but something else
tool = null;
// Get the block's material
final Material block = player.getPlayer().getWorld()
.getBlockAt(data.brokenBlockLocation.x, data.brokenBlockLocation.y, data.brokenBlockLocation.z)
.getType();
// Default break time value (creative mode minimum break time)
long breakTime = 145L;
if (player.getPlayer().getGameMode() == GameMode.SURVIVAL)
breakTime = Math.round(getBreakTime(level, tool, block));
// Elapsed time since the previous block was broken
final long elapsedTime = Math.round((System.nanoTime() - data.lastBreakTime) / Math.pow(10, 6));
boolean cancel = false;
// Has the player broke blocks too quickly
if (data.lastBreakTime != 0 && System.currentTimeMillis() - data.lastBreakTime < cc.fastBreakInterval) {
if (data.lastBreakTime != 0 && elapsedTime < breakTime) {
// He failed, increase vl and statistics
data.fastBreakVL += cc.fastBreakInterval - System.currentTimeMillis() + data.lastBreakTime;
incrementStatistics(player, Id.BB_FASTBREAK, cc.fastBreakInterval - System.currentTimeMillis()
+ data.lastBreakTime);
data.fastBreakVL += breakTime - elapsedTime;
incrementStatistics(player, Id.BB_FASTBREAK, breakTime - elapsedTime);
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, cc.fastBreakActions, data.fastBreakVL);
@ -31,12 +58,258 @@ public class FastBreakCheck extends BlockBreakCheck {
// Reward with lowering of the violation level
data.fastBreakVL *= 0.90D;
data.lastBreakTime = System.currentTimeMillis();
data.lastBreakTime = System.nanoTime();
return cancel;
}
private double getBreakTime(final int level, final Material tool, final Material block) {
double breakTime = -1D;
/** SHOVEL **/
if (block == Material.CLAY || block == Material.GRASS || block == Material.GRAVEL || block == Material.MYCEL) {
if (tool == null)
breakTime = 900D;
else if (isWood(tool))
breakTime = 450D;
else if (isStone(tool))
breakTime = 250D;
else if (isIron(tool) || isDiamond(tool))
breakTime = 150D;
else if (isGold(tool))
breakTime = 100D;
} else if (block == Material.DIRT || block == Material.SAND || block == Material.SOUL_SAND) {
if (tool == null)
breakTime = 750D;
else if (isWood(tool))
breakTime = 400D;
else if (isStone(tool))
breakTime = 200D;
else if (isIron(tool))
breakTime = 150D;
else if (isDiamond(tool) || isGold(tool))
breakTime = 100D;
} else if (block == Material.SNOW_BLOCK) {
if (tool == null)
breakTime = 1000D;
else if (isWood(tool))
breakTime = 150D;
else if (isStone(tool))
breakTime = 100D;
else if (isIron(tool) || isDiamond(tool) || isGold(tool))
breakTime = 50D;
} else if (block == Material.SNOW) {
if (tool == null)
breakTime = 500D;
else if (isWood(tool))
breakTime = 100D;
else if (isStone(tool) || isIron(tool) || isDiamond(tool) || isGold(tool))
breakTime = 50D;
}
/** AXE **/
else if (block == Material.CHEST) {
if (tool == null)
breakTime = 3750D;
else if (isWood(tool))
breakTime = 1900D;
else if (isStone(tool))
breakTime = 950D;
else if (isIron(tool))
breakTime = 650D;
else if (isDiamond(tool))
breakTime = 500D;
else if (isGold(tool))
breakTime = 350D;
} else if (block == Material.LOG || block == Material.WOOD) {
if (tool == null)
breakTime = 3000D;
else if (isStone(tool))
breakTime = 1500D;
else if (isStone(tool))
breakTime = 750D;
else if (isIron(tool))
breakTime = 500D;
else if (isDiamond(tool))
breakTime = 400D;
else if (isGold(tool))
breakTime = 250D;
} else if (block == Material.BOOKSHELF) {
if (tool == null)
breakTime = 2250D;
else if (isWood(tool))
breakTime = 1150D;
else if (isStone(tool))
breakTime = 600D;
else if (isIron(tool))
breakTime = 400D;
else if (isDiamond(tool))
breakTime = 300D;
else if (isGold(tool))
breakTime = 200D;
}
/** PICKAXE **/
else if (block == Material.OBSIDIAN) {
if (tool == null)
breakTime = 250000D;
else if (isWood(tool) || isStone(tool) || isIron(tool) || isGold(tool))
breakTime = 50000D;
else if (isDiamond(tool))
breakTime = 10000D;
} else if (block == Material.IRON_DOOR || block == Material.MOB_SPAWNER) {
if (tool == null)
breakTime = 25000D;
else if (isWood(tool) || isStone(tool) || isIron(tool) || isGold(tool) || isDiamond(tool))
breakTime = 75000D;
} else if (block == Material.DIAMOND_BLOCK) {
if (tool == null || isWood(tool) || isStone(tool) || isGold(tool))
breakTime = 25000D;
else if (isIron(tool))
breakTime = 1250D;
else if (isDiamond(tool))
breakTime = 850D;
} else if (block == Material.IRON_BLOCK) {
if (tool == null || isWood(tool) || isGold(tool))
breakTime = 25000D;
else if (isStone(tool))
breakTime = 2500D;
else if (isIron(tool))
breakTime = 1250D;
else if (isDiamond(tool))
breakTime = 950D;
} else if (block == Material.DISPENSER || block == Material.FURNACE) {
if (tool == null)
breakTime = 17500D;
else if (isStone(tool) || isWood(tool) || isGold(tool) || isIron(tool) || isDiamond(tool))
breakTime = 5250D;
} else if (block == Material.COAL_ORE) {
if (tool == null)
breakTime = 15000D;
else if (isWood(tool))
breakTime = 2250D;
else if (isStone(tool))
breakTime = 1150D;
else if (isIron(tool))
breakTime = 750D;
else if (isDiamond(tool))
breakTime = 600D;
else if (isGold(tool))
breakTime = 400D;
} else if (block == Material.DIAMOND_ORE || block == Material.GOLD_ORE || block == Material.REDSTONE_ORE
|| block == Material.GOLD_BLOCK) {
if (tool == null || isWood(tool) || isStone(tool) || isGold(tool))
breakTime = 15000D;
else if (isIron(tool))
breakTime = 750D;
else if (isDiamond(tool))
breakTime = 600D;
} else if (block == Material.IRON_ORE || block == Material.LAPIS_ORE || block == Material.LAPIS_BLOCK) {
if (tool == null || isWood(tool) || isGold(tool))
breakTime = 15000D;
else if (isStone(tool))
breakTime = 1150D;
else if (isIron(tool))
breakTime = 750D;
else if (isDiamond(tool))
breakTime = 600D;
} else if (block == Material.BRICK || block == Material.NETHER_BRICK || block == Material.WOOD_STAIRS
|| block == Material.COBBLESTONE_STAIRS || block == Material.BRICK_STAIRS
|| block == Material.SMOOTH_STAIRS || block == Material.NETHER_BRICK_STAIRS) {
if (tool == null)
breakTime = 10000D;
else if (isStone(tool) || isWood(tool) || isGold(tool) || isIron(tool) || isDiamond(tool))
breakTime = 3000D;
} else if (block == Material.COBBLESTONE || block == Material.MOSSY_COBBLESTONE || block == Material.STEP) {
if (tool == null)
breakTime = 10000D;
else if (isWood(tool))
breakTime = 1500D;
else if (isStone(tool))
breakTime = 750D;
else if (isIron(tool))
breakTime = 500D;
else if (isDiamond(tool))
breakTime = 400D;
else if (isGold(tool))
breakTime = 250D;
} else if (block == Material.STONE || block == Material.GLOWSTONE) {
if (tool == null)
breakTime = 7500D;
else if (isWood(tool))
breakTime = 1150D;
else if (isStone(tool))
breakTime = 600D;
else if (isIron(tool))
breakTime = 400D;
else if (isDiamond(tool))
breakTime = 300D;
else if (isGold(tool))
breakTime = 200D;
} else if (block == Material.SANDSTONE) {
if (tool == null)
breakTime = 4000D;
else if (isWood(tool))
breakTime = 600D;
else if (isStone(tool))
breakTime = 300D;
else if (isIron(tool))
breakTime = 200D;
else if (isDiamond(tool))
breakTime = 150D;
else if (isGold(tool))
breakTime = 100D;
} else if (block == Material.ICE) {
if (tool == null)
breakTime = 1000D;
else if (isWood(tool))
breakTime = 400D;
else if (isStone(tool))
breakTime = 200D;
else if (isIron(tool))
breakTime = 150D;
else if (isDiamond(tool) || isGold(tool))
breakTime = 100D;
} else if (block == Material.WOOD_PLATE || block == Material.STONE_PLATE) {
if (tool == null)
breakTime = 2500D;
else if (isWood(tool) || isStone(tool) || isIron(tool) || isDiamond(tool) || isGold(tool))
breakTime = 750D;
} else if (block == Material.NETHERRACK) {
if (tool == null)
breakTime = 2000D;
else if (isWood(tool))
breakTime = 300D;
else if (isStone(tool))
breakTime = 150D;
else if (isIron(tool))
breakTime = 100D;
else if (isDiamond(tool))
breakTime = 100D;
else if (isGold(tool))
breakTime = 50D;
} else if (block == Material.MONSTER_EGGS)
if (tool == null || isStone(tool) || isWood(tool) || isGold(tool) || isIron(tool) || isDiamond(tool))
breakTime = 3000D;
// If we haven't any data for the current block, just apply the default value
if (breakTime == -1D)
return 45D;
// Adjust break time if the tool is enchanted
for (int i = level; i > 0; i--)
breakTime = breakTime -= 0.25D * breakTime;
// Set a minimum value for the break time
if (breakTime < 50D)
return 45D;
// Subtract 5 ms (margin of error)
return breakTime - 5D;
}
@Override
public String getParameter(final ParameterName wildcard, final NoCheatPlusPlayer player) {
@ -46,4 +319,33 @@ public class FastBreakCheck extends BlockBreakCheck {
return super.getParameter(wildcard, player);
}
private boolean isDiamond(final Material tool) {
return tool == Material.DIAMOND_AXE || tool == Material.DIAMOND_PICKAXE || tool == Material.DIAMOND_SPADE
|| tool == Material.DIAMOND_SWORD;
}
private boolean isGold(final Material tool) {
return tool == Material.GOLD_AXE || tool == Material.GOLD_PICKAXE || tool == Material.GOLD_SPADE
|| tool == Material.GOLD_SWORD;
}
private boolean isIron(final Material tool) {
return tool == Material.IRON_AXE || tool == Material.IRON_PICKAXE || tool == Material.IRON_SPADE
|| tool == Material.IRON_SWORD;
}
private boolean isStone(final Material tool) {
return tool == Material.STONE_AXE || tool == Material.STONE_PICKAXE || tool == Material.STONE_SPADE
|| tool == Material.STONE_SWORD;
}
private boolean isTool(final Material tool) {
return isWood(tool) || isStone(tool) || isIron(tool) || isDiamond(tool) || isGold(tool);
}
private boolean isWood(final Material tool) {
return tool == Material.WOOD_AXE || tool == Material.WOOD_PICKAXE || tool == Material.WOOD_SPADE
|| tool == Material.WOOD_SWORD;
}
}

View File

@ -0,0 +1,84 @@
package me.neatmonster.nocheatplus.checks.moving;
import java.util.Locale;
import me.neatmonster.nocheatplus.NoCheatPlus;
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
import me.neatmonster.nocheatplus.actions.ParameterName;
import me.neatmonster.nocheatplus.data.Statistics.Id;
public class MorePacketsVehicleCheck extends MovingCheck {
// 20 would be for perfect internet connections, 22 is good enough
private final static int packetsPerTimeframe = 22;
public MorePacketsVehicleCheck(final NoCheatPlus plugin) {
super(plugin, "moving.morepacketsvehicle");
}
/**
* 1. Players get assigned a certain amount of "free" packets as a limit initially
* 2. Every move packet reduces that limit by 1
* 3. If more than 1 second of time passed, the limit gets increased
* by 22 * time in seconds, up to 50 and he gets a new "setback" location
* 4. If the player reaches limit = 0 -> teleport him back to "setback"
* 5. If there was a long pause (maybe lag), limit may be up to 100
*
*/
public boolean check(final NoCheatPlusPlayer player, final MovingData data, final MovingConfig cc) {
boolean cancel = false;
final long time = System.currentTimeMillis();
// Take a packet from the buffer
data.morePacketsVehicleBuffer--;
// Player used up buffer, he fails the check
if (data.morePacketsVehicleBuffer < 0) {
data.morePacketsVehicleVL = -data.morePacketsVehicleBuffer;
incrementStatistics(player, Id.MOV_MOREPACKETSVEHICLE, 1);
data.packetsVehicle = -data.morePacketsVehicleBuffer;
// Execute whatever actions are associated with this check and the
// violation level and find out if we should cancel the event
cancel = executeActions(player, cc.morePacketsVehicleActions, data.morePacketsVehicleVL);
}
if (data.morePacketsVehicleLastTime + 1000 < time) {
// More than 1 second elapsed, but how many?
final double seconds = (time - data.morePacketsVehicleLastTime) / 1000D;
// For each second, fill the buffer
data.morePacketsVehicleBuffer += packetsPerTimeframe * seconds;
// If there was a long pause (maybe server lag?)
// Allow buffer to grow up to 100
if (seconds > 2) {
if (data.morePacketsVehicleBuffer > 100)
data.morePacketsVehicleBuffer = 100;
} else if (data.morePacketsVehicleBuffer > 50)
data.morePacketsVehicleBuffer = 50;
// Set the new "last" time
data.morePacketsVehicleLastTime = time;
} else if (data.morePacketsVehicleLastTime > time)
// Security check, maybe system time changed
data.morePacketsVehicleLastTime = time;
return cancel;
}
@Override
public String getParameter(final ParameterName wildcard, final NoCheatPlusPlayer player) {
if (wildcard == ParameterName.VIOLATIONS)
return String.format(Locale.US, "%d", (int) getData(player).morePacketsVehicleVL);
else if (wildcard == ParameterName.PACKETS)
return String.format(Locale.US, "%d", getData(player).packetsVehicle);
else
return super.getParameter(wildcard, player);
}
}

View File

@ -12,17 +12,24 @@ import me.neatmonster.nocheatplus.config.Permissions;
import me.neatmonster.nocheatplus.data.PreciseLocation;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerVelocityEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
/**
@ -32,18 +39,20 @@ import org.bukkit.util.Vector;
*/
public class MovingCheckListener implements Listener, EventManager {
private final MorePacketsCheck morePacketsCheck;
private final FlyingCheck flyingCheck;
private final RunningCheck runningCheck;
private final WaterWalkCheck waterWalkCheck;
private final MorePacketsCheck morePacketsCheck;
private final MorePacketsVehicleCheck morePacketsVehicleCheck;
private final FlyingCheck flyingCheck;
private final RunningCheck runningCheck;
private final WaterWalkCheck waterWalkCheck;
private final NoCheatPlus plugin;
private final NoCheatPlus plugin;
public MovingCheckListener(final NoCheatPlus plugin) {
flyingCheck = new FlyingCheck(plugin);
runningCheck = new RunningCheck(plugin);
morePacketsCheck = new MorePacketsCheck(plugin);
morePacketsVehicleCheck = new MorePacketsVehicleCheck(plugin);
waterWalkCheck = new WaterWalkCheck(plugin);
this.plugin = plugin;
@ -201,6 +210,24 @@ public class MovingCheckListener implements Listener, EventManager {
}
}
/**
* If a player tries to place a boat on the ground, the event
* will be cancelled.
*
* @param event
* The PlayerInteractEvent
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteract(final PlayerInteractEvent event) {
if (!event.getPlayer().hasPermission(Permissions.MOVING_BOATONGROUND)
&& event.getAction() == Action.RIGHT_CLICK_BLOCK
&& event.getPlayer().getItemInHand().getType() == Material.BOAT
&& event.getClickedBlock().getType() != Material.WATER
&& event.getClickedBlock().getType() != Material.STATIONARY_WATER)
event.setCancelled(true);
}
/**
* When a player uses a portal, all information related to the
* moving checks becomes invalid.
@ -215,6 +242,22 @@ public class MovingCheckListener implements Listener, EventManager {
data.clearRunFlyData();
}
/**
* This events listener fixes the exploitation of the safe
* respawn location (usually exploited with gravel or sand).
*
* @param event
*/
@EventHandler
public void quit(final PlayerQuitEvent event) {
if (!event.getPlayer().hasPermission(Permissions.MOVING_RESPAWNTRICK)
&& (event.getPlayer().getLocation().getBlock().getType() == Material.GRAVEL || event.getPlayer()
.getLocation().getBlock().getType() == Material.SAND)) {
event.getPlayer().getLocation().getBlock().setType(Material.AIR);
event.getPlayer().getLocation().add(0, 1, 0).getBlock().setType(Material.AIR);
}
}
/**
* When a player respawns, all information related to the
* moving checks becomes invalid.
@ -288,6 +331,53 @@ public class MovingCheckListener implements Listener, EventManager {
data.vertFreedom *= 0.93;
}
/**
* When an vehicle moves, it will be checked for various
* suspicious behaviour.
*
* @param event
* The VehicleMoveEvent
*/
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void vehicleMove(final VehicleMoveEvent event) {
// Don't care for vehicles without passenger
if (event.getVehicle().getPassenger() == null || !(event.getVehicle().getPassenger() instanceof Player))
return;
// Don't care for movements that are very high distance or to another
// world (such that it is very likely the event data was modified by
// another plugin before we got it)
if (!event.getFrom().getWorld().equals(event.getTo().getWorld())
|| event.getFrom().distanceSquared(event.getTo()) > 400)
return;
final NoCheatPlusPlayer player = plugin.getPlayer((Player) event.getVehicle().getPassenger());
final MovingConfig cc = MovingCheck.getConfig(player);
final MovingData data = MovingCheck.getData(player);
// Remember locations
data.fromVehicle.set(event.getFrom());
final Location to = event.getTo();
data.toVehicle.set(to);
if (cc.morePacketsVehicleCheck && !player.hasPermission(Permissions.MOVING_MOREPACKETSVEHICLE)
&& morePacketsVehicleCheck.check(player, data, cc)) {
// Drop the usual items
event.getVehicle().getWorld()
.dropItemNaturally(event.getVehicle().getLocation(), new ItemStack(Material.WOOD, 3));
event.getVehicle().getWorld()
.dropItemNaturally(event.getVehicle().getLocation(), new ItemStack(Material.STICK, 2));
// Remove the passenger
if (event.getVehicle().getPassenger() != null)
event.getVehicle().setPassenger(null);
// Destroy the vehicle
event.getVehicle().remove();
}
}
/**
* Player got a velocity packet. The server can't keep track
* of actual velocity values (by design), so we have to try

View File

@ -35,6 +35,9 @@ public class MovingConfig implements ConfigItem {
public final boolean morePacketsCheck;
public final ActionList morePacketsActions;
public final boolean morePacketsVehicleCheck;
public final ActionList morePacketsVehicleActions;
public final boolean waterWalkCheck;
public final ActionList waterWalkActions;
@ -73,6 +76,10 @@ public class MovingConfig implements ConfigItem {
morePacketsCheck = data.getBoolean(ConfPaths.MOVING_MOREPACKETS_CHECK);
morePacketsActions = data.getActionList(ConfPaths.MOVING_MOREPACKETS_ACTIONS, Permissions.MOVING_MOREPACKETS);
morePacketsVehicleCheck = data.getBoolean(ConfPaths.MOVING_MOREPACKETSVEHICLE_CHECK);
morePacketsVehicleActions = data.getActionList(ConfPaths.MOVING_MOREPACKETSVEHICLE_ACTIONS,
Permissions.MOVING_MOREPACKETS);
waterWalkCheck = data.getBoolean(ConfPaths.MOVING_WATERWALK_CHECK);
waterWalkActions = data.getActionList(ConfPaths.MOVING_WATERWALK_ACTIONS, Permissions.MOVING_WATERWALK);
}

View File

@ -13,6 +13,7 @@ public class MovingData implements DataItem {
public double runflyVL;
public double nofallVL;
public double morePacketsVL;
public double morePacketsVehicleVL;
public double waterWalkVL;
// Count how long a player is in the air
@ -26,7 +27,7 @@ public class MovingData implements DataItem {
public int onIce;
// Where should a player be teleported back to when failing the check
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
// Some values for estimating movement freedom
public double vertFreedom;
@ -45,25 +46,33 @@ public class MovingData implements DataItem {
// a player sent and may send before failing the check
public long morePacketsLastTime;
public int packets;
public int morePacketsBuffer = 50;
public int morePacketsBuffer = 50;
// Where to teleport the player that fails the "morepackets" check
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
// Keep track of when "morePacketsVehicle" last time checked an how much
// packets a vehicle sent and may send before failing the check
public long morePacketsVehicleLastTime;
public int packetsVehicle;
public int morePacketsVehicleBuffer = 50;
// When NoCheatPlus does teleport the player, remember the target location to
// be able to distinguish "our" teleports from teleports of others
public final PreciseLocation teleportTo = new PreciseLocation();
public final PreciseLocation teleportTo = new PreciseLocation();
// For logging and convenience, make copies of the events locations
public final PreciseLocation from = new PreciseLocation();
public final PreciseLocation to = new PreciseLocation();
public final PreciseLocation from = new PreciseLocation();
public final PreciseLocation fromVehicle = new PreciseLocation();
public final PreciseLocation to = new PreciseLocation();
public final PreciseLocation toVehicle = new PreciseLocation();
// For convenience, remember if the locations are considered "on ground"
// by NoCheatPlus
public boolean fromOnOrInGround;
public boolean toOnOrInGround;
public Id statisticCategory = Id.MOV_RUNNING;
public Id statisticCategory = Id.MOV_RUNNING;
public void clearMorePacketsData() {
morePacketsSetbackPoint.reset();

View File

@ -11,6 +11,7 @@ import me.neatmonster.nocheatplus.data.PreciseLocation;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
public class WaterWalkCheck extends MovingCheck {
@ -36,13 +37,24 @@ public class WaterWalkCheck extends MovingCheck {
final boolean toLiquid = CheckUtil.isLiquid(toType);
final boolean upLiquid = CheckUtil.isLiquid(upType);
// Make sure the block where the player comes is a stationary liquid block
boolean fromBukkitLiquid = false;
final Block fromBlock = new Location(player.getPlayer().getWorld(), from.x, from.y, from.z).getBlock();
// Handle the issue with water streams
boolean waterStreamsFix = false;
if (fromBlock.getType() == Material.STATIONARY_WATER || fromBlock.getType() == Material.STATIONARY_LAVA
|| (fromBlock.getType() == Material.WATER || fromBlock.getType() == Material.LAVA)
&& fromBlock.getData() == 0x0)
fromBukkitLiquid = true;
waterStreamsFix = true;
// Handle the issue with slabs/stairs
boolean slabsStairsFix = false;
for (final BlockFace blockFace : BlockFace.values()) {
final Material material = fromBlock.getRelative(blockFace).getType();
if (material == Material.STEP || material == Material.WOOD_STAIRS
|| material == Material.COBBLESTONE_STAIRS || material == Material.BRICK_STAIRS
|| material == Material.SMOOTH_STAIRS || material == Material.NETHER_BRICK_STAIRS)
slabsStairsFix = true;
}
// Calculate some distances
final double deltaX = Math.abs(Math.round(to.x) - to.x);
@ -57,7 +69,7 @@ public class WaterWalkCheck extends MovingCheck {
// Slowly reduce the level with each event
data.waterWalkVL *= 0.95;
if (fromLiquid && toLiquid && !upLiquid && deltaY == 0D && deltaWithSurface < 0.8D) {
if (!slabsStairsFix && fromLiquid && toLiquid && !upLiquid && deltaY == 0D && deltaWithSurface < 0.8D) {
// If the player is trying to move while being in water
// Increment violation counter
data.waterWalkVL += resultY;
@ -69,7 +81,7 @@ public class WaterWalkCheck extends MovingCheck {
// Was one of the actions a cancel? Then do it
if (cancel)
newToLocation = from;
} else if (fromLiquid && fromBukkitLiquid && !toLiquid && (deltaX < 0.28D || deltaX > 0.31D)
} else if (waterStreamsFix && fromLiquid && !toLiquid && (deltaX < 0.28D || deltaX > 0.31D)
&& (deltaZ < 0.28D || deltaZ > 0.31D)) {
// If the player is trying to jump while being in water
// Increment violation counter

View File

@ -72,6 +72,10 @@ public abstract class ConfPaths {
public final static String MOVING_MOREPACKETS_CHECK = MOVING_MOREPACKETS + "active";
public final static String MOVING_MOREPACKETS_ACTIONS = MOVING_MOREPACKETS + "actions";
private final static String MOVING_MOREPACKETSVEHICLE = MOVING + "morepacketsvehicle.";
public final static String MOVING_MOREPACKETSVEHICLE_CHECK = MOVING_MOREPACKETSVEHICLE + "active";
public final static String MOVING_MOREPACKETSVEHICLE_ACTIONS = MOVING_MOREPACKETSVEHICLE + "actions";
private final static String MOVING_WATERWALK = MOVING + "waterwalk.";
public final static String MOVING_WATERWALK_CHECK = MOVING_WATERWALK + "active";
public final static String MOVING_WATERWALK_ACTIONS = MOVING_WATERWALK + "actions";
@ -80,7 +84,6 @@ public abstract class ConfPaths {
private final static String BLOCKBREAK_FASTBREAK = BLOCKBREAK + "fastbreak.";
public final static String BLOCKBREAK_FASTBREAK_CHECK = BLOCKBREAK_FASTBREAK + "active";
public final static String BLOCKBREAK_FASTBREAK_INTERVAL = BLOCKBREAK_FASTBREAK + "interval";
public final static String BLOCKBREAK_FASTBREAK_ACTIONS = BLOCKBREAK_FASTBREAK + "actions";
private final static String BLOCKBREAK_REACH = BLOCKBREAK + "reach.";

View File

@ -64,6 +64,9 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
set(ConfPaths.MOVING_MOREPACKETS_CHECK, true);
set(ConfPaths.MOVING_MOREPACKETS_ACTIONS, "log:morepackets:3:2:if cancel vl>20 log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_MOREPACKETSVEHICLE_CHECK, true);
set(ConfPaths.MOVING_MOREPACKETSVEHICLE_ACTIONS, "log:morepackets:0:2:if cancel");
set(ConfPaths.MOVING_WATERWALK_CHECK, true);
set(ConfPaths.MOVING_WATERWALK_ACTIONS,
"log:waterwalk:3:5:f cancel vl>100 log:waterwalk:0:5:if cancel vl>400 log:waterwalk:0:5:cif cancel");
@ -71,9 +74,8 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
/*** BLOCKBREAK ***/
set(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK, true);
set(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVAL, 145);
set(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS,
"cancel vl>1000 log:bbfastbreak:3:5:cif cancel vl>4000 log:waterwalk:3:5:cif cmd:kick cancel");
"vl>200 cancel vl> 1000 log:bbfastbreak:2:5:cif cancel vl>400 log:bbfastbreak:3:5:cif cmd:kick cancel");
set(ConfPaths.BLOCKBREAK_REACH_CHECK, true);
set(ConfPaths.BLOCKBREAK_REACH_ACTIONS, "cancel vl>5 log:bbreach:0:2:if cancel");
@ -91,7 +93,7 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
set(ConfPaths.BLOCKPLACE_FASTPLACE_CHECK, true);
set(ConfPaths.BLOCKPLACE_FASTPLACE_INTERVAL, 145);
set(ConfPaths.BLOCKPLACE_FASTPLACE_ACTIONS,
"cancel vl>100 log:bpfastplace:3:5:cif cancel vl>2000 log:waterwalk:3:5:cif cmd:kick cancel");
"cancel vl>100 log:bpfastplace:3:5:cif cancel vl>2000 log:bpfastplace:3:5:cif cmd:kick cancel");
set(ConfPaths.BLOCKPLACE_REACH_CHECK, true);
set(ConfPaths.BLOCKPLACE_REACH_ACTIONS, "cancel vl>5 log:bpreach:0:2:if cancel");

View File

@ -6,70 +6,73 @@ package me.neatmonster.nocheatplus.config;
*/
public class Permissions {
private static final String NOCHEATPLUS = "nocheatplus";
private static final String ADMIN = NOCHEATPLUS + ".admin";
private static final String CHECKS = NOCHEATPLUS + ".checks";
private static final String MODS = NOCHEATPLUS + ".mods";
private static final String NOCHEATPLUS = "nocheatplus";
private static final String ADMIN = NOCHEATPLUS + ".admin";
private static final String CHECKS = NOCHEATPLUS + ".checks";
private static final String MODS = NOCHEATPLUS + ".mods";
/** ADMIN **/
public static final String ADMIN_CHATLOG = ADMIN + ".chatlog";
public static final String ADMIN_COMMANDS = ADMIN + ".commands";
public static final String ADMIN_RELOAD = ADMIN + ".reload";
public static final String ADMIN_CHATLOG = ADMIN + ".chatlog";
public static final String ADMIN_COMMANDS = ADMIN + ".commands";
public static final String ADMIN_RELOAD = ADMIN + ".reload";
/** CHECKS **/
private static final String BLOCKBREAK = CHECKS + ".blockbreak";
public static final String BLOCKBREAK_FASTBREAK = BLOCKBREAK + ".fastbreak";
public static final String BLOCKBREAK_REACH = BLOCKBREAK + ".reach";
public static final String BLOCKBREAK_DIRECTION = BLOCKBREAK + ".direction";
public static final String BLOCKBREAK_NOSWING = BLOCKBREAK + ".noswing";
private static final String BLOCKBREAK = CHECKS + ".blockbreak";
public static final String BLOCKBREAK_FASTBREAK = BLOCKBREAK + ".fastbreak";
public static final String BLOCKBREAK_REACH = BLOCKBREAK + ".reach";
public static final String BLOCKBREAK_DIRECTION = BLOCKBREAK + ".direction";
public static final String BLOCKBREAK_NOSWING = BLOCKBREAK + ".noswing";
private static final String BLOCKPLACE = CHECKS + ".blockplace";
public static final String BLOCKPLACE_FASTPLACE = BLOCKPLACE + ".fastplace";
public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach";
public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction";
private static final String BLOCKPLACE = CHECKS + ".blockplace";
public static final String BLOCKPLACE_FASTPLACE = BLOCKPLACE + ".fastplace";
public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach";
public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction";
private static final String CHAT = CHECKS + ".chat";
public static final String CHAT_SPAM = CHAT + ".spam";
public static final String CHAT_COLOR = CHAT + ".color";
private static final String CHAT = CHECKS + ".chat";
public static final String CHAT_SPAM = CHAT + ".spam";
public static final String CHAT_COLOR = CHAT + ".color";
private static final String FIGHT = CHECKS + ".fight";
public static final String FIGHT_DIRECTION = FIGHT + ".direction";
public static final String FIGHT_NOSWING = FIGHT + ".noswing";
public static final String FIGHT_REACH = FIGHT + ".reach";
public static final String FIGHT_SPEED = FIGHT + ".speed";
public static final String FIGHT_GODMODE = FIGHT + ".godmode";
public static final String FIGHT_INSTANTHEAL = FIGHT + ".instantheal";
private static final String FIGHT = CHECKS + ".fight";
public static final String FIGHT_DIRECTION = FIGHT + ".direction";
public static final String FIGHT_NOSWING = FIGHT + ".noswing";
public static final String FIGHT_REACH = FIGHT + ".reach";
public static final String FIGHT_SPEED = FIGHT + ".speed";
public static final String FIGHT_GODMODE = FIGHT + ".godmode";
public static final String FIGHT_INSTANTHEAL = FIGHT + ".instantheal";
private static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow";
public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat";
private static final String INVENTORY = CHECKS + ".inventory";
public static final String INVENTORY_DROP = INVENTORY + ".drop";
public static final String INVENTORY_INSTANTBOW = INVENTORY + ".instantbow";
public static final String INVENTORY_INSTANTEAT = INVENTORY + ".instanteat";
private static final String MOVING = CHECKS + ".moving";
public static final String MOVING_RUNFLY = MOVING + ".runfly";
public static final String MOVING_SWIMMING = MOVING + ".swimming";
public static final String MOVING_SNEAKING = MOVING + ".sneaking";
public static final String MOVING_FLYING = MOVING + ".flying";
public static final String MOVING_NOFALL = MOVING + ".nofall";
public static final String MOVING_MOREPACKETS = MOVING + ".morepackets";
public static final String MOVING_WATERWALK = MOVING + ".waterwalk";
private static final String MOVING = CHECKS + ".moving";
public static final String MOVING_RUNFLY = MOVING + ".runfly";
public static final String MOVING_SWIMMING = MOVING + ".swimming";
public static final String MOVING_SNEAKING = MOVING + ".sneaking";
public static final String MOVING_FLYING = MOVING + ".flying";
public static final String MOVING_NOFALL = MOVING + ".nofall";
public static final String MOVING_MOREPACKETS = MOVING + ".morepackets";
public static final String MOVING_MOREPACKETSVEHICLE = MOVING + ".morepacketsvehicle";
public static final String MOVING_BOATONGROUND = MOVING + ".boatonground";
public static final String MOVING_WATERWALK = MOVING + ".waterwalk";
public static final String MOVING_RESPAWNTRICK = MOVING + ".respawntrick";
/** MODS **/
private static final String CJB = MODS + ".cjb";
public static final String CJB_FLY = CJB + ".fly";
public static final String CJB_XRAY = CJB + ".xray";
public static final String CJB_MINIMAP = CJB + ".minimap";
private static final String CJB = MODS + ".cjb";
public static final String CJB_FLY = CJB + ".fly";
public static final String CJB_XRAY = CJB + ".xray";
public static final String CJB_MINIMAP = CJB + ".minimap";
public static final String MC_AUTOMAP = MODS + ".mcautomap";
public static final String MC_AUTOMAP = MODS + ".mcautomap";
private static final String REI = MODS + ".rei";
public static final String REI_CAVE = REI + ".cave";
public static final String REI_RADAR = REI + ".radar";
private static final String REI = MODS + ".rei";
public static final String REI_CAVE = REI + ".cave";
public static final String REI_RADAR = REI + ".radar";
private static final String ZOMBE = MODS + ".zombe";
public static final String ZOMBE_FLY = ZOMBE + ".fly";
public static final String ZOMBE_NOCLIP = ZOMBE + ".noclip";
public static final String ZOMBE_CHEATS = ZOMBE + ".cheats";
private static final String ZOMBE = MODS + ".zombe";
public static final String ZOMBE_FLY = ZOMBE + ".fly";
public static final String ZOMBE_NOCLIP = ZOMBE + ".noclip";
public static final String ZOMBE_CHEATS = ZOMBE + ".cheats";
private Permissions() {}
}

View File

@ -28,6 +28,7 @@ public class Statistics {
MOV_RUNNING("moving.running"),
MOV_FLYING("moving.flying"),
MOV_MOREPACKETS("moving.morepackets"),
MOV_MOREPACKETSVEHICLE("moving.morepacketsvehicle"),
MOV_NOFALL("moving.nofall"),
MOV_SNEAKING("moving.sneaking"),
MOV_SWIMMING("moving.swimming"),